Kaynağa Gözat

update
1.微信客服支付回调接口

wks 11 ay önce
ebeveyn
işleme
a82926f3c8

+ 4 - 0
tenant/organization/pom.xml

@@ -56,6 +56,10 @@
             <groupId>com.github.binarywang</groupId>
             <artifactId>weixin-java-cp</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.dataformat</groupId>
+            <artifactId>jackson-dataformat-xml</artifactId>
+        </dependency>
 
     </dependencies>
     <build>

+ 6 - 0
tenant/organization/src/main/java/com/jzg/organization/config/WeComConfig.java

@@ -1,5 +1,6 @@
 package com.jzg.organization.config;
 
+import me.chanjar.weixin.common.util.crypto.WxCryptUtil;
 import me.chanjar.weixin.cp.api.*;
 import me.chanjar.weixin.cp.api.impl.*;
 import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl;
@@ -22,6 +23,11 @@ public class WeComConfig {
         return wxCpService;
     }
 
+    @Bean
+    public WxCryptUtil wxCryptUtil(){
+        return new WxCryptUtil("hGskYOrv1XnVFtooYsX8Q2PxN", "cYIzKkyIJQY6wFHUTtamtKiy2uxFynTZOx6VHnvC7vI", "wwfe67d19509d43ec5");
+    }
+
     @Bean
     public WxCpKfService wxCpKfService() {
         return new WxCpKfServiceImpl(wxCpService());

+ 1 - 1
tenant/organization/src/main/java/com/jzg/organization/controller/WechatCustomerServiceManageController.java

@@ -115,7 +115,7 @@ public class WechatCustomerServiceManageController {
 
     @PostMapping(path = "/callback", consumes = MediaType.TEXT_XML_VALUE, produces = MediaType.TEXT_XML_VALUE)
     @Operation(summary = "客服回调(处理事件发送欢迎语)", description = "客服回调(处理事件发送欢迎语)")
-    public HttpResult<String> customerCallback(@RequestBody WxCpXmlMessage wechatEncrypt) throws JsonProcessingException, WxErrorException {
+    public HttpResult<String> customerCallback(@RequestBody String wechatEncrypt) throws JsonProcessingException, WxErrorException {
         wechatCustomerServiceManageService.callbackSendMsgOnEvent(wechatEncrypt);
         return HttpResult.ok();
     }

+ 42 - 0
tenant/organization/src/main/java/com/jzg/organization/entity/vo/WechatCustomerCallbackVo.java

@@ -0,0 +1,42 @@
+package com.jzg.organization.entity.vo;
+
+
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @description: 微信客服 回调实体
+ * @author: wenks
+ * @date: 2024/11/26 10:37
+ **/
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+@JacksonXmlRootElement(localName = "xml")
+public class WechatCustomerCallbackVo {
+
+    @JacksonXmlProperty(localName = "ToUserName")
+    private String toUserName;
+
+    @JacksonXmlProperty(localName = "FromUserName")
+    private String fromUserName;
+
+    @JacksonXmlProperty(localName = "CreateTime")
+    private String createTime;
+
+    @JacksonXmlProperty(localName = "MsgType")
+    private String msgType;
+
+    @JacksonXmlProperty(localName = "Event")
+    private String event;
+
+    @JacksonXmlProperty(localName = "Token")
+    private String token;
+
+    @JacksonXmlProperty(localName = "OpenKfId")
+    private String openKfId;
+
+}

+ 24 - 0
tenant/organization/src/main/java/com/jzg/organization/entity/vo/WechatEncryptVo.java

@@ -0,0 +1,24 @@
+package com.jzg.organization.entity.vo;
+
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+@JacksonXmlRootElement(localName = "xml")
+public class WechatEncryptVo {
+
+    @JacksonXmlProperty(localName = "ToUserName")
+    private String toUserName;
+
+    @JacksonXmlProperty(localName = "Encrypt")
+    private String encrypt;
+
+    @JacksonXmlProperty(localName = "AgentID")
+    private String agentID;
+
+}

+ 6 - 3
tenant/organization/src/main/java/com/jzg/organization/service/WechatCustomerServiceManageService.java

@@ -1,6 +1,7 @@
 package com.jzg.organization.service;
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fasterxml.jackson.core.JsonProcessingException;
 import com.jzg.organization.entity.vo.*;
 import me.chanjar.weixin.common.error.WxErrorException;
 import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
@@ -76,9 +77,11 @@ public interface WechatCustomerServiceManageService {
     String getWeChatCustomer() throws WxErrorException;
 
     /**
-     * 客服事件回调
+     * 微信客服回调信息
      *
-     * @param wechatEncrypt 微信加密字符串
+     * @param wechatEncrypt 加密参数
+     * @throws JsonProcessingException
+     * @throws WxErrorException
      */
-    void callbackSendMsgOnEvent(WxCpXmlMessage wechatEncrypt);
+    void callbackSendMsgOnEvent(String wechatEncrypt) throws JsonProcessingException, WxErrorException;
 }

+ 83 - 57
tenant/organization/src/main/java/com/jzg/organization/service/impl/WechatCustomerServiceManageServiceImpl.java

@@ -1,9 +1,9 @@
 package com.jzg.organization.service.impl;
 
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.dataformat.xml.XmlMapper;
 import com.jzg.commons.core.base.BaseController;
 import com.jzg.commons.entity.po.SysUploadFiles;
-import com.jzg.commons.entity.vo.SysUserAccountVo;
 import com.jzg.commons.exception.SystemException;
 import com.jzg.commons.util.MinioUtils;
 import com.jzg.organization.entity.WechatCustomerService;
@@ -22,16 +22,14 @@ import me.chanjar.weixin.cp.bean.WxCpBaseResp;
 import me.chanjar.weixin.cp.bean.WxCpDepart;
 import me.chanjar.weixin.cp.bean.WxCpUser;
 import me.chanjar.weixin.cp.bean.kf.*;
-import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
-import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
-import me.chanjar.weixin.cp.message.WxCpMessageRouter;
+import me.chanjar.weixin.cp.bean.kf.msg.WxCpKfEventMsg;
+import me.chanjar.weixin.cp.bean.kf.msg.WxCpKfTextMsg;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.ObjectUtils;
 import org.springframework.util.StringUtils;
 
-import java.io.File;
 import java.io.InputStream;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
@@ -54,10 +52,6 @@ public class WechatCustomerServiceManageServiceImpl implements WechatCustomerSer
 
     private final SysUserService sysUserService;
 
-    private final WxCpService wxCpService;
-
-    private final WxCpMessageRouter wxCpMessageRouter;
-
     private final WxCpMediaService wxCpMediaService;
 
     private final WxCpKfService wxCpKfService;
@@ -70,6 +64,10 @@ public class WechatCustomerServiceManageServiceImpl implements WechatCustomerSer
 
     private final BaseController baseController;
 
+    private final XmlMapper xmlMapper = new XmlMapper();
+
+    private final WxCryptUtil wxCryptUtil;
+
     @Value("${minio.bucket-name}")
     private String bucketName;
 
@@ -190,16 +188,11 @@ public class WechatCustomerServiceManageServiceImpl implements WechatCustomerSer
     @Override
     public List<WeComDeptVo> getDeptByDeptId() throws WxErrorException {
         List<WxCpDepart> list = wxCpDepartmentService.list(null);
-        List<WeComDeptVo> deptVos = list.stream()
-                .map(WeComDeptVo::new)
-                .toList();
-        Map<String, List<WeComDeptVo>> parentGroup = deptVos.stream()
-                .collect(Collectors.groupingBy(WeComDeptVo::getParentId));
+        List<WeComDeptVo> deptVos = list.stream().map(WeComDeptVo::new).toList();
+        Map<String, List<WeComDeptVo>> parentGroup = deptVos.stream().collect(Collectors.groupingBy(WeComDeptVo::getParentId));
         List<String> collect = deptVos.stream().map(WeComDeptVo::getDeptId).toList();
         deptVos.forEach(node -> node.setChildDept(parentGroup.getOrDefault(node.getDeptId(), Collections.emptyList())));
-        return deptVos.stream()
-                .filter(node -> node.getParentId() != null && !collect.contains(node.getParentId()))
-                .collect(Collectors.toList());
+        return deptVos.stream().filter(node -> node.getParentId() != null && !collect.contains(node.getParentId())).collect(Collectors.toList());
     }
 
     @Override
@@ -214,30 +207,24 @@ public class WechatCustomerServiceManageServiceImpl implements WechatCustomerSer
     public void saveOrUpdateCustomerServiceDutyRules(WechatCustomerServiceDutyRulesVo sysWechatCustomerDutyRules) {
         // 删除之前的排班信息
         wechatCustomerServiceDutyService.clearCustomerDuty(sysWechatCustomerDutyRules.getCustomerId());
-        List<WechatCustomerServiceDuty> wechatCustomerServiceDuties = sysWechatCustomerDutyRules.getDutyList()
-                .stream()
-                .flatMap(duty -> duty.getDutyConfig().stream()
-                        .map(config -> {
-                            WechatCustomerServiceDuty dutyEntity = new WechatCustomerServiceDuty();
-                            dutyEntity.setCustomerServiceId(sysWechatCustomerDutyRules.getCustomerId());
-                            dutyEntity.setDutyCustomerServiceId(config.getDutyCustomerServiceId());
-                            dutyEntity.setDate(duty.getDutyDate());
-                            dutyEntity.setStartTime(config.getStartTime());
-                            dutyEntity.setEndTime(config.getEndTime());
-                            return dutyEntity;
-                        }))
-                .collect(Collectors.toList());
+        List<WechatCustomerServiceDuty> wechatCustomerServiceDuties = sysWechatCustomerDutyRules.getDutyList().stream().flatMap(duty -> duty.getDutyConfig().stream().map(config -> {
+            WechatCustomerServiceDuty dutyEntity = new WechatCustomerServiceDuty();
+            dutyEntity.setCustomerServiceId(sysWechatCustomerDutyRules.getCustomerId());
+            dutyEntity.setDutyCustomerServiceId(config.getDutyCustomerServiceId());
+            dutyEntity.setDate(duty.getDutyDate());
+            dutyEntity.setStartTime(config.getStartTime());
+            dutyEntity.setEndTime(config.getEndTime());
+            return dutyEntity;
+        })).collect(Collectors.toList());
         // 保存排班信息
         wechatCustomerServiceDutyService.saveBatch(wechatCustomerServiceDuties);
     }
 
     @Override
     public String getWeChatCustomer() throws WxErrorException {
-//        String userName = baseController.getUserName();
+        String userName = baseController.getUserName();
         WechatCustomerService wechatCustomerService = null;
-//        String leaderId = sysUserService.getLeaderId(userName);
-        String userName = "1930514052662677506";
-        String leaderId = "1930514052662677506";
+        String leaderId = sysUserService.getLeaderId(userName);
         if (StringUtils.hasLength(leaderId)) {
             wechatCustomerService = wechatCustomerServiceService.getByUserId(leaderId);
         }
@@ -245,23 +232,14 @@ public class WechatCustomerServiceManageServiceImpl implements WechatCustomerSer
         if (ObjectUtils.isEmpty(wechatCustomerService)) {
             // 获取最近一次的客服记录
             List<WechatCustomerService> sysWechatCustomerList = wechatCustomerServiceService.list();
-            List<Long> sysWechatCustomerIdList = sysWechatCustomerList.stream()
-                    .map(WechatCustomerService::getId)
-                    .collect(Collectors.toList());
-
-            WechatCustomerServiceRecording wechatCustomerServiceRecording = wechatCustomerServiceRecordingService.lambdaQuery()
-                    .in(!sysWechatCustomerIdList.isEmpty(), WechatCustomerServiceRecording::getCustomerServiceId, sysWechatCustomerIdList)
-                    .eq(WechatCustomerServiceRecording::getUserId, userName)
-                    .orderByDesc(WechatCustomerServiceRecording::getCreateTime)
-                    .last("limit 1")
-                    .one();
+            List<Long> sysWechatCustomerIdList = sysWechatCustomerList.stream().map(WechatCustomerService::getId).collect(Collectors.toList());
+
+            WechatCustomerServiceRecording wechatCustomerServiceRecording = wechatCustomerServiceRecordingService.lambdaQuery().in(!sysWechatCustomerIdList.isEmpty(), WechatCustomerServiceRecording::getCustomerServiceId, sysWechatCustomerIdList).eq(WechatCustomerServiceRecording::getUserId, userName).orderByDesc(WechatCustomerServiceRecording::getCreateTime).last("limit 1").one();
             if (ObjectUtils.isEmpty(wechatCustomerServiceRecording)) {
                 wechatCustomerService = wechatCustomerServiceService.getCacheCustomerId(wechatCustomerService);
             } else {
                 // 使用上一次的客服
-                wechatCustomerService = wechatCustomerServiceService.lambdaQuery()
-                        .eq(WechatCustomerService::getId, wechatCustomerServiceRecording.getCustomerServiceId())
-                        .one();
+                wechatCustomerService = wechatCustomerServiceService.lambdaQuery().eq(WechatCustomerService::getId, wechatCustomerServiceRecording.getCustomerServiceId()).one();
                 if (ObjectUtils.isEmpty(wechatCustomerService)) {
                     wechatCustomerService = wechatCustomerServiceService.getCacheCustomerId(wechatCustomerService);
                 }
@@ -272,12 +250,7 @@ public class WechatCustomerServiceManageServiceImpl implements WechatCustomerSer
             wechatCustomerServiceRecordingService.save(customerRecording);
         }
 
-        List<WechatCustomerServiceDuty> list = wechatCustomerServiceDutyService.lambdaQuery()
-                .eq(WechatCustomerServiceDuty::getDutyCustomerServiceId, wechatCustomerService.getId())
-                .eq(WechatCustomerServiceDuty::getDate, LocalDate.now())
-                .le(WechatCustomerServiceDuty::getStartTime, LocalTime.now())
-                .ge(WechatCustomerServiceDuty::getEndTime, LocalTime.now())
-                .list();
+        List<WechatCustomerServiceDuty> list = wechatCustomerServiceDutyService.lambdaQuery().eq(WechatCustomerServiceDuty::getDutyCustomerServiceId, wechatCustomerService.getId()).eq(WechatCustomerServiceDuty::getDate, LocalDate.now()).le(WechatCustomerServiceDuty::getStartTime, LocalTime.now()).ge(WechatCustomerServiceDuty::getEndTime, LocalTime.now()).list();
         if (list != null && !list.isEmpty()) {
             WechatCustomerServiceDuty wechatCustomerServiceDuty = list.get(0);
             wechatCustomerService = wechatCustomerServiceService.getById(wechatCustomerServiceDuty.getDutyCustomerServiceId());
@@ -295,9 +268,62 @@ public class WechatCustomerServiceManageServiceImpl implements WechatCustomerSer
         return accountLink.getUrl();
     }
 
+
     @Override
-    public void callbackSendMsgOnEvent(WxCpXmlMessage wechatEncrypt) {
-        WxCpXmlOutMessage route = wxCpMessageRouter.route(wechatEncrypt);
-        System.out.println(route.toString());
+    public void callbackSendMsgOnEvent(String wechatEncrypt) throws JsonProcessingException, WxErrorException {
+        log.info("回调参数为{}", wechatEncrypt);
+        WechatEncryptVo wechatEncryptVo = xmlMapper.readValue(wechatEncrypt, WechatEncryptVo.class);
+        log.info("解密参数为{}", wechatEncryptVo.getEncrypt());
+        String encrypt = wxCryptUtil.decrypt(wechatEncryptVo.getEncrypt());
+        log.info("解密后的参数为{}", encrypt);
+        WechatCustomerCallbackVo wechatCustomerCallbackVo = xmlMapper.readValue(encrypt, WechatCustomerCallbackVo.class);
+
+        // 获取消息
+        WxCpKfMsgListResp wxCpKfMsgListResp = wxCpKfService.syncMsg(null, wechatCustomerCallbackVo.getToken(), null, null, wechatCustomerCallbackVo.getOpenKfId());
+
+        while (wxCpKfMsgListResp.getHasMore() == 1) {
+            String nextCursor = wxCpKfMsgListResp.getNextCursor();
+            wxCpKfMsgListResp = wxCpKfService.syncMsg(nextCursor, wechatCustomerCallbackVo.getToken(), null, null, wechatCustomerCallbackVo.getOpenKfId());
+        }
+        List<WxCpKfMsgListResp.WxCpKfMsgItem> msgList = wxCpKfMsgListResp.getMsgList();
+        WxCpKfMsgListResp.WxCpKfMsgItem wxCpKfMsgItem = wxCpKfMsgListResp.getMsgList().get(msgList.size() - 1);
+
+        if (wxCpKfMsgItem.getOrigin() == 3) {
+            List<WxCpKfMsgListResp.WxCpKfMsgItem> msgListDTOList = msgList.stream().filter(x -> "event".equals(x.getMsgType())).toList();
+
+            msgListDTOList.forEach(x -> {
+                try {
+                    WxCpKfEventMsg xEvent = x.getEvent();
+                    WxCpKfServiceStateResp serviceState = wxCpKfService.getServiceState(xEvent.getOpenKfid(), xEvent.getExternalUserId());
+                    if (serviceState.getServiceState() == 0) {
+                        List<WechatCustomerService> list = wechatCustomerServiceService.lambdaQuery().eq(WechatCustomerService::getOpenKfId, xEvent.getOpenKfid()).list();
+                        wxCpKfService.transServiceState(xEvent.getOpenKfid(), xEvent.getExternalUserId(), 3, list.get(0).getReceptionistId());
+                    }
+                } catch (WxErrorException e) {
+                    throw new RuntimeException(e);
+                }
+            });
+        }
+
+        WxCpKfEventMsg event = wxCpKfMsgItem.getEvent();
+        if (ObjectUtils.isEmpty(event)) {
+            return;
+        }
+
+        String scene = event.getScene();
+        if (StringUtils.isEmpty(scene)) {
+            return;
+        }
+        if (wxCpKfMsgItem.getOrigin() == 4) {
+            String userName = new BaseController().getUserName();
+            WxCpKfMsgSendRequest wxCpKfMsgSendRequest = new WxCpKfMsgSendRequest();
+            String messages = "你好!" + userName + "(" + userName + ")" + "很高兴为你服务";
+            wxCpKfMsgSendRequest.setCode(event.getWelcomeCode());
+            WxCpKfTextMsg wxCpKfTextMsg = new WxCpKfTextMsg();
+            wxCpKfTextMsg.setContent(messages);
+            wxCpKfMsgSendRequest.setText(wxCpKfTextMsg);
+            wxCpKfService.sendMsgOnEvent(wxCpKfMsgSendRequest);
+        }
+
     }
 }