1
This commit is contained in:
@@ -3,6 +3,7 @@ package com.ruoyi.web.controller.jarvis;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.jarvis.domain.dto.WeComInboundRequest;
|
||||
import com.ruoyi.jarvis.service.IWeComInboundService;
|
||||
import com.ruoyi.jarvis.service.IWeComInboundTraceService;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@@ -25,6 +26,8 @@ public class WeComInboundController {
|
||||
|
||||
@Resource
|
||||
private IWeComInboundService weComInboundService;
|
||||
@Resource
|
||||
private IWeComInboundTraceService weComInboundTraceService;
|
||||
|
||||
@PostMapping("/inbound")
|
||||
public AjaxResult inbound(
|
||||
@@ -33,7 +36,9 @@ public class WeComInboundController {
|
||||
if (!StringUtils.hasText(inboundSecret) || !inboundSecret.equals(secret)) {
|
||||
return AjaxResult.error("拒绝访问");
|
||||
}
|
||||
String reply = weComInboundService.handleInbound(body != null ? body : new WeComInboundRequest());
|
||||
WeComInboundRequest req = body != null ? body : new WeComInboundRequest();
|
||||
String reply = weComInboundService.handleInbound(req);
|
||||
weComInboundTraceService.recordInbound(req, reply);
|
||||
Map<String, Object> data = new HashMap<>(2);
|
||||
data.put("reply", reply != null ? reply : "");
|
||||
return AjaxResult.success(data);
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.ruoyi.web.controller.jarvis;
|
||||
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.jarvis.domain.WeComInboundTrace;
|
||||
import com.ruoyi.jarvis.service.IWeComInboundTraceService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 企微 inbound 消息追踪查询
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/jarvis/wecom/inboundTrace")
|
||||
public class WeComInboundTraceController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
private IWeComInboundTraceService weComInboundTraceService;
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('jarvis:wecom:inboundTrace:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(WeComInboundTrace query) {
|
||||
startPage();
|
||||
List<WeComInboundTrace> list = weComInboundTraceService.selectWeComInboundTraceList(query);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('jarvis:wecom:inboundTrace:list')")
|
||||
@GetMapping("/{id}")
|
||||
public AjaxResult getInfo(@PathVariable Long id) {
|
||||
return success(weComInboundTraceService.selectWeComInboundTraceById(id));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('jarvis:wecom:inboundTrace:remove')")
|
||||
@Log(title = "企微消息跟踪", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
public AjaxResult remove(@PathVariable Long[] ids) {
|
||||
return toAjax(weComInboundTraceService.deleteWeComInboundTraceByIds(ids));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
package com.ruoyi.jarvis.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.ruoyi.common.annotation.Excel;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 企微 inbound 消息追踪 wecom_inbound_trace
|
||||
*/
|
||||
public class WeComInboundTrace extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Long id;
|
||||
|
||||
@Excel(name = "消息ID")
|
||||
private String msgId;
|
||||
|
||||
@Excel(name = "AgentID")
|
||||
private String agentId;
|
||||
|
||||
@Excel(name = "CorpId")
|
||||
private String corpId;
|
||||
|
||||
@Excel(name = "发送人UserID")
|
||||
private String fromUserName;
|
||||
|
||||
private String content;
|
||||
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@Excel(name = "微信发送时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date wxMsgTime;
|
||||
|
||||
private String replyContent;
|
||||
|
||||
@Excel(name = "会话进行中", readConverterExp = "0=否,1=是")
|
||||
private Integer sessionActive;
|
||||
|
||||
@Excel(name = "会话场景")
|
||||
private String sessionScene;
|
||||
|
||||
@Excel(name = "会话步骤")
|
||||
private String sessionStep;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getMsgId() {
|
||||
return msgId;
|
||||
}
|
||||
|
||||
public void setMsgId(String msgId) {
|
||||
this.msgId = msgId;
|
||||
}
|
||||
|
||||
public String getAgentId() {
|
||||
return agentId;
|
||||
}
|
||||
|
||||
public void setAgentId(String agentId) {
|
||||
this.agentId = agentId;
|
||||
}
|
||||
|
||||
public String getCorpId() {
|
||||
return corpId;
|
||||
}
|
||||
|
||||
public void setCorpId(String corpId) {
|
||||
this.corpId = corpId;
|
||||
}
|
||||
|
||||
public String getFromUserName() {
|
||||
return fromUserName;
|
||||
}
|
||||
|
||||
public void setFromUserName(String fromUserName) {
|
||||
this.fromUserName = fromUserName;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public Date getWxMsgTime() {
|
||||
return wxMsgTime;
|
||||
}
|
||||
|
||||
public void setWxMsgTime(Date wxMsgTime) {
|
||||
this.wxMsgTime = wxMsgTime;
|
||||
}
|
||||
|
||||
public String getReplyContent() {
|
||||
return replyContent;
|
||||
}
|
||||
|
||||
public void setReplyContent(String replyContent) {
|
||||
this.replyContent = replyContent;
|
||||
}
|
||||
|
||||
public Integer getSessionActive() {
|
||||
return sessionActive;
|
||||
}
|
||||
|
||||
public void setSessionActive(Integer sessionActive) {
|
||||
this.sessionActive = sessionActive;
|
||||
}
|
||||
|
||||
public String getSessionScene() {
|
||||
return sessionScene;
|
||||
}
|
||||
|
||||
public void setSessionScene(String sessionScene) {
|
||||
this.sessionScene = sessionScene;
|
||||
}
|
||||
|
||||
public String getSessionStep() {
|
||||
return sessionStep;
|
||||
}
|
||||
|
||||
public void setSessionStep(String sessionStep) {
|
||||
this.sessionStep = sessionStep;
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,8 @@ public class WeComInboundRequest {
|
||||
private String toUserName;
|
||||
private String agentId;
|
||||
private String msgId;
|
||||
/** 企微 XML CreateTime,秒级 Unix 时间戳(wxSend 传入) */
|
||||
private Long wxCreateTime;
|
||||
|
||||
public String getFromUserName() {
|
||||
return fromUserName;
|
||||
@@ -55,4 +57,12 @@ public class WeComInboundRequest {
|
||||
public void setMsgId(String msgId) {
|
||||
this.msgId = msgId;
|
||||
}
|
||||
|
||||
public Long getWxCreateTime() {
|
||||
return wxCreateTime;
|
||||
}
|
||||
|
||||
public void setWxCreateTime(Long wxCreateTime) {
|
||||
this.wxCreateTime = wxCreateTime;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.ruoyi.jarvis.mapper;
|
||||
|
||||
import com.ruoyi.jarvis.domain.WeComInboundTrace;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface WeComInboundTraceMapper {
|
||||
|
||||
int insertWeComInboundTrace(WeComInboundTrace trace);
|
||||
|
||||
WeComInboundTrace selectWeComInboundTraceById(Long id);
|
||||
|
||||
List<WeComInboundTrace> selectWeComInboundTraceList(WeComInboundTrace query);
|
||||
|
||||
int deleteWeComInboundTraceByIds(Long[] ids);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.ruoyi.jarvis.service;
|
||||
|
||||
import com.ruoyi.jarvis.domain.WeComInboundTrace;
|
||||
import com.ruoyi.jarvis.domain.dto.WeComInboundRequest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IWeComInboundTraceService {
|
||||
|
||||
void recordInbound(WeComInboundRequest request, String reply);
|
||||
|
||||
WeComInboundTrace selectWeComInboundTraceById(Long id);
|
||||
|
||||
List<WeComInboundTrace> selectWeComInboundTraceList(WeComInboundTrace query);
|
||||
|
||||
int deleteWeComInboundTraceByIds(Long[] ids);
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.ruoyi.jarvis.service.impl;
|
||||
|
||||
import com.ruoyi.jarvis.domain.WeComInboundTrace;
|
||||
import com.ruoyi.jarvis.domain.dto.WeComChatSession;
|
||||
import com.ruoyi.jarvis.domain.dto.WeComInboundRequest;
|
||||
import com.ruoyi.jarvis.mapper.WeComInboundTraceMapper;
|
||||
import com.ruoyi.jarvis.service.IWeComChatSessionService;
|
||||
import com.ruoyi.jarvis.service.IWeComInboundTraceService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class WeComInboundTraceServiceImpl implements IWeComInboundTraceService {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(WeComInboundTraceServiceImpl.class);
|
||||
|
||||
@Resource
|
||||
private WeComInboundTraceMapper weComInboundTraceMapper;
|
||||
@Resource
|
||||
private IWeComChatSessionService weComChatSessionService;
|
||||
|
||||
@Override
|
||||
public void recordInbound(WeComInboundRequest request, String reply) {
|
||||
if (request == null || !StringUtils.hasText(request.getFromUserName())) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
String from = request.getFromUserName().trim();
|
||||
WeComInboundTrace trace = new WeComInboundTrace();
|
||||
trace.setMsgId(request.getMsgId());
|
||||
trace.setAgentId(request.getAgentId());
|
||||
trace.setCorpId(request.getToUserName());
|
||||
trace.setFromUserName(from);
|
||||
trace.setContent(request.getContent());
|
||||
Long wxSec = request.getWxCreateTime();
|
||||
if (wxSec != null && wxSec > 0) {
|
||||
trace.setWxMsgTime(new Date(wxSec * 1000L));
|
||||
}
|
||||
trace.setReplyContent(reply != null ? reply : "");
|
||||
|
||||
WeComChatSession session = weComChatSessionService.get(from);
|
||||
trace.setSessionActive(session != null ? 1 : 0);
|
||||
if (session != null) {
|
||||
trace.setSessionScene(session.getScene());
|
||||
trace.setSessionStep(session.getStep());
|
||||
}
|
||||
weComInboundTraceMapper.insertWeComInboundTrace(trace);
|
||||
} catch (Exception e) {
|
||||
log.warn("企微消息追踪落库失败: {}", e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public WeComInboundTrace selectWeComInboundTraceById(Long id) {
|
||||
return weComInboundTraceMapper.selectWeComInboundTraceById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WeComInboundTrace> selectWeComInboundTraceList(WeComInboundTrace query) {
|
||||
return weComInboundTraceMapper.selectWeComInboundTraceList(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int deleteWeComInboundTraceByIds(Long[] ids) {
|
||||
return weComInboundTraceMapper.deleteWeComInboundTraceByIds(ids);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.ruoyi.jarvis.mapper.WeComInboundTraceMapper">
|
||||
|
||||
<resultMap id="WeComInboundTraceResult" type="WeComInboundTrace">
|
||||
<id property="id" column="id"/>
|
||||
<result property="msgId" column="msg_id"/>
|
||||
<result property="agentId" column="agent_id"/>
|
||||
<result property="corpId" column="corp_id"/>
|
||||
<result property="fromUserName" column="from_user_name"/>
|
||||
<result property="content" column="content"/>
|
||||
<result property="wxMsgTime" column="wx_msg_time"/>
|
||||
<result property="replyContent" column="reply_content"/>
|
||||
<result property="sessionActive" column="session_active"/>
|
||||
<result property="sessionScene" column="session_scene"/>
|
||||
<result property="sessionStep" column="session_step"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectVo">
|
||||
select id, msg_id, agent_id, corp_id, from_user_name, content, wx_msg_time,
|
||||
reply_content, session_active, session_scene, session_step, create_time
|
||||
from wecom_inbound_trace
|
||||
</sql>
|
||||
|
||||
<insert id="insertWeComInboundTrace" parameterType="WeComInboundTrace" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into wecom_inbound_trace (
|
||||
msg_id, agent_id, corp_id, from_user_name, content, wx_msg_time,
|
||||
reply_content, session_active, session_scene, session_step
|
||||
) values (
|
||||
#{msgId}, #{agentId}, #{corpId}, #{fromUserName}, #{content}, #{wxMsgTime},
|
||||
#{replyContent}, #{sessionActive}, #{sessionScene}, #{sessionStep}
|
||||
)
|
||||
</insert>
|
||||
|
||||
<select id="selectWeComInboundTraceById" resultMap="WeComInboundTraceResult">
|
||||
<include refid="selectVo"/>
|
||||
where id = #{id}
|
||||
</select>
|
||||
|
||||
<select id="selectWeComInboundTraceList" parameterType="WeComInboundTrace" resultMap="WeComInboundTraceResult">
|
||||
<include refid="selectVo"/>
|
||||
<where>
|
||||
<if test="msgId != null and msgId != ''">and msg_id = #{msgId}</if>
|
||||
<if test="fromUserName != null and fromUserName != ''">and from_user_name like concat('%', #{fromUserName}, '%')</if>
|
||||
<if test="agentId != null and agentId != ''">and agent_id = #{agentId}</if>
|
||||
<if test="sessionActive != null">and session_active = #{sessionActive}</if>
|
||||
<if test="params.beginTime != null and params.beginTime != ''">
|
||||
and create_time >= #{params.beginTime}
|
||||
</if>
|
||||
<if test="params.endTime != null and params.endTime != ''">
|
||||
and create_time <= concat(#{params.endTime}, ' 23:59:59')
|
||||
</if>
|
||||
</where>
|
||||
order by id desc
|
||||
</select>
|
||||
|
||||
<delete id="deleteWeComInboundTraceByIds" parameterType="Long">
|
||||
delete from wecom_inbound_trace where id in
|
||||
<foreach collection="array" item="id" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</delete>
|
||||
</mapper>
|
||||
33
sql/wecom_inbound_trace.sql
Normal file
33
sql/wecom_inbound_trace.sql
Normal file
@@ -0,0 +1,33 @@
|
||||
-- 企业微信桥接消息追踪(Jarvis 落库,供后台查看)
|
||||
DROP TABLE IF EXISTS `wecom_inbound_trace`;
|
||||
CREATE TABLE `wecom_inbound_trace` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`msg_id` varchar(64) DEFAULT NULL COMMENT '企微消息 MsgId',
|
||||
`agent_id` varchar(32) DEFAULT NULL COMMENT '应用 AgentID',
|
||||
`corp_id` varchar(64) DEFAULT NULL COMMENT '企业 CorpId(XML ToUserName)',
|
||||
`from_user_name` varchar(128) NOT NULL COMMENT '发送人成员 UserID(FromUserName)',
|
||||
`content` mediumtext COMMENT '用户发送内容',
|
||||
`wx_msg_time` datetime DEFAULT NULL COMMENT '微信侧 CreateTime(秒级时间戳转换)',
|
||||
`reply_content` mediumtext COMMENT 'Jarvis 返回给 wxSend 的回复文本',
|
||||
`session_active` tinyint(4) NOT NULL DEFAULT 0 COMMENT '处理完成后是否存在多轮会话:0否 1是',
|
||||
`session_scene` varchar(64) DEFAULT NULL COMMENT '会话场景(如 JD_LOGISTICS_SHARE)',
|
||||
`session_step` varchar(64) DEFAULT NULL COMMENT '会话步骤(如 WAIT_REMARK)',
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '服务端接收处理时间',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_from_user` (`from_user_name`),
|
||||
KEY `idx_msg_id` (`msg_id`),
|
||||
KEY `idx_create_time` (`create_time`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='企微 inbound 消息追踪';
|
||||
|
||||
-- 菜单:挂在「系统监控」下,与日志文件类似;执行后请给需要角色分配该菜单权限
|
||||
INSERT INTO sys_menu VALUES (
|
||||
2090, '企微消息跟踪', 2, 8, 'wecomInboundTrace', 'jarvis/wecomInboundTrace/index', '', '', 1, 0, 'C', '0', '0',
|
||||
'jarvis:wecom:inboundTrace:list', 'wechat', 'admin', sysdate(), '', NULL, '企微回调经 Jarvis 处理记录'
|
||||
);
|
||||
INSERT INTO sys_menu VALUES (
|
||||
2092, '删除', 2090, 1, '', '', '', '', 1, 0, 'F', '0', '0',
|
||||
'jarvis:wecom:inboundTrace:remove', '#', 'admin', sysdate(), '', NULL, ''
|
||||
);
|
||||
|
||||
-- 若需超级管理员角色默认拥有(role_id 按实际调整,常见管理员为 1)
|
||||
-- INSERT INTO sys_role_menu (role_id, menu_id) VALUES (1, 2090), (1, 2092);
|
||||
Reference in New Issue
Block a user