|
|
@@ -21,6 +21,9 @@ import shop.alien.mapper.LifeFeedbackMapper;
|
|
|
import shop.alien.mapper.LifeLogMapper;
|
|
|
import shop.alien.mapper.LifeNoticeMapper;
|
|
|
import shop.alien.mapper.StoreUserMapper;
|
|
|
+import shop.alien.mapper.LifeSysMapper;
|
|
|
+import shop.alien.entity.store.LifeSys;
|
|
|
+import shop.alien.store.util.ai.AiFeedbackAssignUtils;
|
|
|
import shop.alien.entity.store.LifeNotice;
|
|
|
import shop.alien.entity.store.StoreUser;
|
|
|
import shop.alien.entity.store.vo.WebSocketVo;
|
|
|
@@ -29,6 +32,7 @@ import shop.alien.store.service.LifeFeedbackService;
|
|
|
import shop.alien.store.service.LifeFeedbackReplyService;
|
|
|
import shop.alien.store.service.LifeImgService;
|
|
|
import com.alibaba.fastjson2.JSONObject;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
|
|
|
import java.util.Date;
|
|
|
import java.util.List;
|
|
|
@@ -50,6 +54,8 @@ public class LifeFeedbackServiceImpl extends ServiceImpl<LifeFeedbackMapper, Lif
|
|
|
private final LifeNoticeMapper lifeNoticeMapper;
|
|
|
private final StoreUserMapper storeUserMapper;
|
|
|
private final WebSocketProcess webSocketProcess;
|
|
|
+ private final AiFeedbackAssignUtils aiFeedbackAssignUtils;
|
|
|
+ private final LifeSysMapper lifeSysMapper;
|
|
|
|
|
|
@Override
|
|
|
public R<String> submitFeedback(LifeFeedbackDto dto) {
|
|
|
@@ -155,6 +161,27 @@ public class LifeFeedbackServiceImpl extends ServiceImpl<LifeFeedbackMapper, Lif
|
|
|
// 4. 记录日志(只记录详细内容)
|
|
|
saveLog(feedback.getId(), feedback.getContent(), "0");
|
|
|
|
|
|
+ // 5. 调用AI分配跟踪人员
|
|
|
+ // 根据AI接口文档:用户端和商户端反馈都需要分配跟踪人员
|
|
|
+ // AI返回的 staff_id 对应 life_sys 表的 id
|
|
|
+ Integer assignedStaffId = assignStaffByAI(feedback);
|
|
|
+ if (assignedStaffId != null) {
|
|
|
+ // 更新反馈记录的跟踪人员(虽然AI接口会自动更新,但本地也需要同步更新)
|
|
|
+ feedback.setStaffId(assignedStaffId);
|
|
|
+ this.updateById(feedback);
|
|
|
+
|
|
|
+ // 记录分配跟踪人员日志
|
|
|
+ saveLog(feedback.getId(), "已分配跟踪人员,ID: " + assignedStaffId + " (life_sys)", "1");
|
|
|
+
|
|
|
+ // 发送分配跟踪人员通知给中台(平台端跟踪人员)
|
|
|
+ sendStaffAssignmentNotice(feedback, assignedStaffId);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 6. 发送提交反馈工单通知到中台(需要已分配跟踪人员)
|
|
|
+ if (feedback.getStaffId() != null) {
|
|
|
+ sendFeedbackSubmittedNoticeToPlatform(feedback);
|
|
|
+ }
|
|
|
+
|
|
|
return R.success("提交成功");
|
|
|
} catch (Exception e) {
|
|
|
log.error("提交反馈失败", e);
|
|
|
@@ -340,6 +367,9 @@ public class LifeFeedbackServiceImpl extends ServiceImpl<LifeFeedbackMapper, Lif
|
|
|
// 4. 记录日志(只记录内容)
|
|
|
saveLog(dto.getFeedbackId(), dto.getContent(), "2");
|
|
|
|
|
|
+ // 5. 发送用户回复通知给平台端(跟踪人员)
|
|
|
+ sendUserReplyNoticeToPlatform(originalFeedback, dto.getContent());
|
|
|
+
|
|
|
return R.success("回复成功");
|
|
|
} catch (Exception e) {
|
|
|
log.error("用户回复失败", e);
|
|
|
@@ -701,5 +731,270 @@ public class LifeFeedbackServiceImpl extends ServiceImpl<LifeFeedbackMapper, Lif
|
|
|
log.error("发送平台回复通知异常,feedbackId={}, error={}", feedback.getId(), e.getMessage(), e);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 调用AI分配跟踪人员
|
|
|
+ * @param feedback 反馈记录
|
|
|
+ * @return 分配的跟踪人员ID(对应life_sys表的id),失败返回null
|
|
|
+ */
|
|
|
+ private Integer assignStaffByAI(LifeFeedback feedback) {
|
|
|
+ try {
|
|
|
+ // 调用AI工具类分配跟踪人员(只需要feedback_id)
|
|
|
+ return aiFeedbackAssignUtils.assignStaffByAI(feedback);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("调用AI分配跟踪人员失败,feedbackId={}, error={}", feedback.getId(), e.getMessage(), e);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 发送分配跟踪人员通知给中台(平台端)
|
|
|
+ *
|
|
|
+ * 根据AI接口文档:
|
|
|
+ * - staff_id 对应 life_sys 表的 id
|
|
|
+ * - 用户端和商户端反馈都需要发送通知
|
|
|
+ *
|
|
|
+ * @param feedback 反馈记录
|
|
|
+ * @param staffId 跟踪人员ID(对应life_sys表的id)
|
|
|
+ */
|
|
|
+ private void sendStaffAssignmentNotice(LifeFeedback feedback, Integer staffId) {
|
|
|
+ try {
|
|
|
+ // 如果没有分配跟踪人员,则无法发送通知
|
|
|
+ if (staffId == null) {
|
|
|
+ log.warn("未分配跟踪人员,无法发送通知,feedbackId={}", feedback.getId());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询跟踪人员信息(从life_sys表查询)
|
|
|
+ LifeSys staff = lifeSysMapper.selectById(staffId);
|
|
|
+ if (staff == null) {
|
|
|
+ log.warn("未找到跟踪人员信息(life_sys),无法发送通知,staffId={}, feedbackId={}",
|
|
|
+ staffId, feedback.getId());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 平台端接收者ID格式:staff_{staffId}(与用户回复通知保持一致)
|
|
|
+ String receiverId = "staff_" + staffId;
|
|
|
+
|
|
|
+ // 获取用户信息(用于显示在通知中)
|
|
|
+ String userName = "用户";
|
|
|
+ if (feedback.getUserId() != null) {
|
|
|
+ StoreUser storeUser = storeUserMapper.selectById(feedback.getUserId());
|
|
|
+ if (storeUser != null && storeUser.getPhone() != null) {
|
|
|
+ userName = storeUser.getPhone();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取反馈来源名称
|
|
|
+ String sourceName = feedback.getFeedbackSource() != null && feedback.getFeedbackSource() == 1 ? "商户" : "用户";
|
|
|
+
|
|
|
+ // 构建通知消息
|
|
|
+ JSONObject messageJson = new JSONObject();
|
|
|
+ messageJson.put("feedbackId", feedback.getId());
|
|
|
+ messageJson.put("staffId", staffId);
|
|
|
+ messageJson.put("staffName", staff.getUserName()); // life_sys表使用userName字段
|
|
|
+ messageJson.put("userId", feedback.getUserId());
|
|
|
+ messageJson.put("userName", userName);
|
|
|
+ messageJson.put("feedbackSource", feedback.getFeedbackSource());
|
|
|
+ messageJson.put("feedbackContent", feedback.getContent());
|
|
|
+ messageJson.put("message", "您已被分配处理" + sourceName + "反馈工单,反馈内容:" + feedback.getContent());
|
|
|
+
|
|
|
+ // 创建通知记录
|
|
|
+ LifeNotice lifeNotice = new LifeNotice();
|
|
|
+ lifeNotice.setReceiverId(receiverId);
|
|
|
+ lifeNotice.setContext(messageJson.toJSONString());
|
|
|
+ lifeNotice.setTitle("反馈工单分配通知");
|
|
|
+ lifeNotice.setSenderId("system");
|
|
|
+ lifeNotice.setIsRead(0);
|
|
|
+ lifeNotice.setNoticeType(1); // 1-系统通知
|
|
|
+ lifeNotice.setBusinessId(feedback.getId());
|
|
|
+
|
|
|
+ // 保存通知
|
|
|
+ lifeNoticeMapper.insert(lifeNotice);
|
|
|
+
|
|
|
+ // 通过WebSocket发送实时通知
|
|
|
+ WebSocketVo webSocketVo = new WebSocketVo();
|
|
|
+ webSocketVo.setSenderId("system");
|
|
|
+ webSocketVo.setReceiverId(receiverId);
|
|
|
+ webSocketVo.setCategory("notice");
|
|
|
+ webSocketVo.setNoticeType("1");
|
|
|
+ webSocketVo.setIsRead(0);
|
|
|
+ webSocketVo.setText(JSONObject.toJSONString(lifeNotice));
|
|
|
+
|
|
|
+ try {
|
|
|
+ webSocketProcess.sendMessage(receiverId, JSONObject.toJSONString(webSocketVo));
|
|
|
+ log.info("分配跟踪人员通知发送成功(中台),feedbackId={}, receiverId={}, staffId={}, staffName={}",
|
|
|
+ feedback.getId(), receiverId, staffId, staff.getUserName());
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("发送WebSocket通知失败,feedbackId={}, receiverId={}, error={}",
|
|
|
+ feedback.getId(), receiverId, e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("发送分配跟踪人员通知异常(中台),feedbackId={}, error={}", feedback.getId(), e.getMessage(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 发送提交反馈工单通知到中台
|
|
|
+ *
|
|
|
+ * 根据AI接口文档:
|
|
|
+ * - staff_id 对应 life_sys 表的 id
|
|
|
+ * - 用户端和商户端反馈都会发送通知
|
|
|
+ *
|
|
|
+ * @param feedback 反馈记录
|
|
|
+ */
|
|
|
+ private void sendFeedbackSubmittedNoticeToPlatform(LifeFeedback feedback) {
|
|
|
+ try {
|
|
|
+ // 如果没有分配跟踪人员,则无法发送通知到中台
|
|
|
+ if (feedback.getStaffId() == null) {
|
|
|
+ log.warn("反馈未分配跟踪人员,无法发送提交通知到中台,feedbackId={}", feedback.getId());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询跟踪人员信息(从life_sys表查询)
|
|
|
+ LifeSys staff = lifeSysMapper.selectById(feedback.getStaffId());
|
|
|
+ if (staff == null) {
|
|
|
+ log.warn("未找到跟踪人员信息(life_sys),无法发送通知,staffId={}, feedbackId={}",
|
|
|
+ feedback.getStaffId(), feedback.getId());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取用户信息(用于显示在通知中)
|
|
|
+ String userName = "用户";
|
|
|
+ if (feedback.getUserId() != null) {
|
|
|
+ StoreUser storeUser = storeUserMapper.selectById(feedback.getUserId());
|
|
|
+ if (storeUser != null && storeUser.getPhone() != null) {
|
|
|
+ userName = storeUser.getPhone();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取反馈来源名称
|
|
|
+ String sourceName = feedback.getFeedbackSource() != null && feedback.getFeedbackSource() == 1 ? "商户" : "用户";
|
|
|
+
|
|
|
+ // 中台接收者ID格式:staff_{staffId}
|
|
|
+ String receiverId = "staff_" + feedback.getStaffId();
|
|
|
+
|
|
|
+ // 构建通知消息
|
|
|
+ JSONObject messageJson = new JSONObject();
|
|
|
+ messageJson.put("feedbackId", feedback.getId());
|
|
|
+ messageJson.put("staffId", feedback.getStaffId());
|
|
|
+ messageJson.put("staffName", staff.getUserName()); // life_sys表使用userName字段
|
|
|
+ messageJson.put("userId", feedback.getUserId());
|
|
|
+ messageJson.put("userName", userName);
|
|
|
+ messageJson.put("feedbackSource", feedback.getFeedbackSource());
|
|
|
+ messageJson.put("feedbackContent", feedback.getContent());
|
|
|
+ messageJson.put("message", sourceName + "提交了新的反馈工单,反馈内容:" + feedback.getContent());
|
|
|
+
|
|
|
+ // 创建通知记录
|
|
|
+ LifeNotice lifeNotice = new LifeNotice();
|
|
|
+ lifeNotice.setReceiverId(receiverId);
|
|
|
+ lifeNotice.setContext(messageJson.toJSONString());
|
|
|
+ lifeNotice.setTitle("反馈工单提交通知");
|
|
|
+ lifeNotice.setSenderId("system");
|
|
|
+ lifeNotice.setIsRead(0);
|
|
|
+ lifeNotice.setNoticeType(1); // 1-系统通知
|
|
|
+ lifeNotice.setBusinessId(feedback.getId());
|
|
|
+
|
|
|
+ // 保存通知
|
|
|
+ lifeNoticeMapper.insert(lifeNotice);
|
|
|
+
|
|
|
+ // 通过WebSocket发送实时通知
|
|
|
+ WebSocketVo webSocketVo = new WebSocketVo();
|
|
|
+ webSocketVo.setSenderId("system");
|
|
|
+ webSocketVo.setReceiverId(receiverId);
|
|
|
+ webSocketVo.setCategory("notice");
|
|
|
+ webSocketVo.setNoticeType("1");
|
|
|
+ webSocketVo.setIsRead(0);
|
|
|
+ webSocketVo.setText(JSONObject.toJSONString(lifeNotice));
|
|
|
+
|
|
|
+ try {
|
|
|
+ webSocketProcess.sendMessage(receiverId, JSONObject.toJSONString(webSocketVo));
|
|
|
+ log.info("{}提交反馈工单通知发送成功(中台),feedbackId={}, receiverId={}, staffId={}",
|
|
|
+ sourceName, feedback.getId(), receiverId, feedback.getStaffId());
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("发送WebSocket通知失败,feedbackId={}, receiverId={}, error={}",
|
|
|
+ feedback.getId(), receiverId, e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("发送提交反馈工单通知异常(中台),feedbackId={}, error={}", feedback.getId(), e.getMessage(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 发送用户回复通知给平台端(跟踪人员)
|
|
|
+ *
|
|
|
+ * 根据AI接口文档:
|
|
|
+ * - staff_id 对应 life_sys 表的 id
|
|
|
+ *
|
|
|
+ * @param feedback 反馈记录
|
|
|
+ * @param replyContent 用户回复内容
|
|
|
+ */
|
|
|
+ private void sendUserReplyNoticeToPlatform(LifeFeedback feedback, String replyContent) {
|
|
|
+ try {
|
|
|
+ // 如果反馈没有分配跟踪人员,则无法发送通知
|
|
|
+ if (feedback.getStaffId() == null) {
|
|
|
+ log.warn("反馈未分配跟踪人员,无法发送用户回复通知,feedbackId={}", feedback.getId());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询跟踪人员信息(从life_sys表查询)
|
|
|
+ LifeSys staff = lifeSysMapper.selectById(feedback.getStaffId());
|
|
|
+ if (staff == null) {
|
|
|
+ log.warn("未找到跟踪人员信息(life_sys),无法发送通知,staffId={}, feedbackId={}",
|
|
|
+ feedback.getStaffId(), feedback.getId());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取反馈来源名称
|
|
|
+ String sourceName = feedback.getFeedbackSource() != null && feedback.getFeedbackSource() == 1 ? "商户" : "用户";
|
|
|
+
|
|
|
+ // 构建接收者ID(平台端跟踪人员,使用staff_前缀)
|
|
|
+ String receiverId = "staff_" + feedback.getStaffId();
|
|
|
+
|
|
|
+ // 构建通知消息
|
|
|
+ JSONObject messageJson = new JSONObject();
|
|
|
+ messageJson.put("feedbackId", feedback.getId());
|
|
|
+ messageJson.put("staffId", feedback.getStaffId());
|
|
|
+ messageJson.put("staffName", staff.getUserName()); // life_sys表使用userName字段
|
|
|
+ messageJson.put("feedbackSource", feedback.getFeedbackSource());
|
|
|
+ messageJson.put("message", sourceName + "已回复您的意见反馈:" + replyContent);
|
|
|
+
|
|
|
+ // 创建通知记录
|
|
|
+ LifeNotice lifeNotice = new LifeNotice();
|
|
|
+ lifeNotice.setReceiverId(receiverId);
|
|
|
+ lifeNotice.setContext(messageJson.toJSONString());
|
|
|
+ lifeNotice.setTitle(sourceName + "回复通知");
|
|
|
+ lifeNotice.setSenderId("system");
|
|
|
+ lifeNotice.setIsRead(0);
|
|
|
+ lifeNotice.setNoticeType(1); // 1-系统通知
|
|
|
+ lifeNotice.setBusinessId(feedback.getId());
|
|
|
+
|
|
|
+ // 保存通知
|
|
|
+ lifeNoticeMapper.insert(lifeNotice);
|
|
|
+
|
|
|
+ // 通过WebSocket发送实时通知
|
|
|
+ WebSocketVo webSocketVo = new WebSocketVo();
|
|
|
+ webSocketVo.setSenderId("system");
|
|
|
+ webSocketVo.setReceiverId(receiverId);
|
|
|
+ webSocketVo.setCategory("notice");
|
|
|
+ webSocketVo.setNoticeType("1");
|
|
|
+ webSocketVo.setIsRead(0);
|
|
|
+ webSocketVo.setText(JSONObject.toJSONString(lifeNotice));
|
|
|
+
|
|
|
+ try {
|
|
|
+ webSocketProcess.sendMessage(receiverId, JSONObject.toJSONString(webSocketVo));
|
|
|
+ log.info("{}回复通知发送成功,feedbackId={}, receiverId={}, staffId={}",
|
|
|
+ sourceName, feedback.getId(), receiverId, feedback.getStaffId());
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("发送WebSocket通知失败,feedbackId={}, receiverId={}, error={}",
|
|
|
+ feedback.getId(), receiverId, e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("发送用户回复通知异常,feedbackId={}, error={}", feedback.getId(), e.getMessage(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|