Kaynağa Gözat

微信客服代码修改

wks 1 yıl önce
ebeveyn
işleme
df6a804c6d
18 değiştirilmiş dosya ile 625 ekleme ve 51 silme
  1. 66 8
      src/main/java/com/ydtech/modules/admin/components/WechatCustomerComponents.java
  2. 37 0
      src/main/java/com/ydtech/modules/admin/components/wechat/customer/request/CustomerAddContactWayRequest.java
  3. 19 0
      src/main/java/com/ydtech/modules/admin/components/wechat/customer/request/CustomerBaseRequest.java
  4. 3 5
      src/main/java/com/ydtech/modules/admin/components/wechat/customer/request/CustomerGetTokenRequest.java
  5. 33 0
      src/main/java/com/ydtech/modules/admin/components/wechat/customer/request/CustomerListRequest.java
  6. 55 0
      src/main/java/com/ydtech/modules/admin/components/wechat/customer/request/CustomerSendMsgOnEventRequest.java
  7. 31 0
      src/main/java/com/ydtech/modules/admin/components/wechat/customer/request/CustomerSyncMsgRequest.java
  8. 30 0
      src/main/java/com/ydtech/modules/admin/components/wechat/customer/response/CustomerAddContactWayResponse.java
  9. 36 0
      src/main/java/com/ydtech/modules/admin/components/wechat/customer/response/CustomerBaseResponse.java
  10. 1 3
      src/main/java/com/ydtech/modules/admin/components/wechat/customer/response/CustomerGetTokenResponse.java
  11. 55 0
      src/main/java/com/ydtech/modules/admin/components/wechat/customer/response/CustomerListResponse.java
  12. 42 0
      src/main/java/com/ydtech/modules/admin/components/wechat/customer/response/CustomerSendMsgOnEventResponse.java
  13. 78 0
      src/main/java/com/ydtech/modules/admin/components/wechat/customer/response/CustomerSyncMsgResponse.java
  14. 0 35
      src/main/java/com/ydtech/modules/admin/controller/WechatController.java
  15. 37 0
      src/main/java/com/ydtech/modules/admin/controller/wechat/WechatCustomerController.java
  16. 23 0
      src/main/java/com/ydtech/modules/admin/service/WechatCustomerService.java
  17. 75 0
      src/main/java/com/ydtech/modules/admin/service/impl/WechatCustomerServiceImpl.java
  18. 4 0
      src/main/java/com/ydtech/modules/order/components/InsCrawlerOrderComponents.java

+ 66 - 8
src/main/java/com/ydtech/modules/admin/components/WechatCustomerComponents.java

@@ -2,19 +2,27 @@ package com.ydtech.modules.admin.components;
 
 
 import com.ydtech.config.properties.WechatCustomerProperties;
-import com.ydtech.modules.admin.components.wechat.customer.request.CustomerGetTokenRequest;
-import com.ydtech.modules.admin.components.wechat.customer.response.CustomerGetTokenResponse;
+import com.ydtech.modules.admin.components.wechat.customer.request.*;
+import com.ydtech.modules.admin.components.wechat.customer.response.*;
 import com.ydtech.modules.admin.constants.WechatCustomerEnum;
+import com.ydtech.modules.order.components.InsCrawlerOrderComponents;
 import com.ydtech.modules.order.constants.OrderCacheConstant;
 import com.ydtech.modules.protocol.utils.AssertionUtils;
 import com.ydtech.utils.cache.BaseCacheConfig;
 import com.ydtech.utils.cache.RedissonUtils;
 import lombok.RequiredArgsConstructor;
+import me.chanjar.weixin.common.util.crypto.WxCryptUtil;
+import org.springframework.http.HttpHeaders;
 import org.springframework.stereotype.Component;
 import org.springframework.web.client.RestTemplate;
 
 import java.util.concurrent.TimeUnit;
 
+/**
+ * @description: 【微信客服】 发送请求实体
+ * @author: wenks
+ * @date: 2024/11/28 15:35
+ **/
 @Component
 @RequiredArgsConstructor
 public class WechatCustomerComponents {
@@ -25,24 +33,74 @@ public class WechatCustomerComponents {
 
     private final RedissonUtils redissonUtils;
 
+    private final InsCrawlerOrderComponents insCrawlerOrderComponents;
+
+    private <T, B extends CustomerBaseResponse> B request(WechatCustomerEnum wechatCustomer, T requestBody, Class<B> responseType, HttpHeaders httpHeaders) {
+        String token = getToken();
+        String url = WechatCustomerEnum.URL + wechatCustomer.getUri() + "?access_token=" + token;
+        return insCrawlerOrderComponents.request(url, "wechatCustomer", wechatCustomer.getDesc(), requestBody, responseType, httpHeaders);
+    }
+
+    public WxCryptUtil getWxCryptUtil(){
+        return new WxCryptUtil(wechatCustomerProperties.getToken(),  wechatCustomerProperties.getEncodingAesKey(), wechatCustomerProperties.getCorpId());
+    }
+
     /**
      * 获取调用凭证access_token
      *
      * @return access_token
      */
-    public String getToken() {
+    private String getToken() {
         return redissonUtils.getFromRedis(() -> {
             CustomerGetTokenRequest customerGetTokenRequest = new CustomerGetTokenRequest(wechatCustomerProperties.getCorpId(), wechatCustomerProperties.getSecret());
-            String url = WechatCustomerEnum.URL + customerGetTokenRequest;
+            String url = WechatCustomerEnum.URL + customerGetTokenRequest.getUrlParams();
             CustomerGetTokenResponse customerGetTokenResponse = restTemplate.getForObject(url, CustomerGetTokenResponse.class);
             AssertionUtils.isEmpty(customerGetTokenResponse, "获取调用凭证access_token异常");
             String accessToken = customerGetTokenResponse.getAccessToken();
-            return new BaseCacheConfig<String>()
-                    .setExpiresIn(customerGetTokenResponse.getExpiresIn())
-                    .setTimeUnit(TimeUnit.SECONDS)
-                    .setData(accessToken);
+            return new BaseCacheConfig<String>().setExpiresIn(customerGetTokenResponse.getExpiresIn()).setTimeUnit(TimeUnit.SECONDS).setData(accessToken);
         }, OrderCacheConstant.WECHAT_CUSTOMER_TOKEN);
     }
 
 
+
+    /**
+     * 获取客服账号列表
+     *
+     * @param customerListRequest 请求实体
+     * @return 客服账号列表
+     */
+    public CustomerListResponse list(CustomerListRequest customerListRequest) {
+        return request(WechatCustomerEnum.LIST, customerListRequest, CustomerListResponse.class, HttpHeaders.EMPTY);
+    }
+
+    /**
+     * 获取客服账号链接
+     *
+     * @param customerAddContactWayRequest 请求实体
+     * @return 客服账号链接
+     */
+    public CustomerAddContactWayResponse addContactWay(CustomerAddContactWayRequest customerAddContactWayRequest) {
+        return request(WechatCustomerEnum.ADD_CONTACT_WAY, customerAddContactWayRequest, CustomerAddContactWayResponse.class, HttpHeaders.EMPTY);
+    }
+
+    /**
+     * 获取消息
+     *
+     * @param customerSendMsgOnEventRequest 请求实体
+     * @return 消息信息
+     */
+    public CustomerSendMsgOnEventResponse sendMsgOnEvent(CustomerSendMsgOnEventRequest customerSendMsgOnEventRequest) {
+        return request(WechatCustomerEnum.LIST, customerSendMsgOnEventRequest, CustomerSendMsgOnEventResponse.class, HttpHeaders.EMPTY);
+    }
+
+    /**
+     * 发送客服欢迎语
+     *
+     * @param customerSyncMsgRequest 请求实体
+     * @return 成功失败
+     */
+    public CustomerSyncMsgResponse syncMsg(CustomerSyncMsgRequest customerSyncMsgRequest) {
+        return request(WechatCustomerEnum.SYNC_MSG, customerSyncMsgRequest, CustomerSyncMsgResponse.class, HttpHeaders.EMPTY);
+    }
+
 }

+ 37 - 0
src/main/java/com/ydtech/modules/admin/components/wechat/customer/request/CustomerAddContactWayRequest.java

@@ -0,0 +1,37 @@
+package com.ydtech.modules.admin.components.wechat.customer.request;
+
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+
+/**
+ * @description: 【微信客服】 获取客服账号链接
+ * @author: wenks
+ * @date: 2024/11/28 15:14
+ **/
+@EqualsAndHashCode(callSuper = true)
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class CustomerAddContactWayRequest extends CustomerBaseRequest {
+
+    /**
+     * 客服账号ID
+     */
+    @JsonProperty("open_kfid")
+    private String openKfid;
+
+    /**
+     * 场景值,字符串类型,由开发者自定义。
+     * 不多于32字节
+     * 字符串取值范围(正则表达式):[0-9a-zA-Z_-]*
+     */
+    @JsonProperty("scene")
+    private String scene;
+
+
+}

+ 19 - 0
src/main/java/com/ydtech/modules/admin/components/wechat/customer/request/CustomerBaseRequest.java

@@ -0,0 +1,19 @@
+package com.ydtech.modules.admin.components.wechat.customer.request;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+
+/**
+ * @description: 【微信客服】 请求基类
+ * @author: wenks
+ * @date: 2024/11/28 14:51
+ **/
+@Data
+@NoArgsConstructor
+public class CustomerBaseRequest {
+
+
+}

+ 3 - 5
src/main/java/com/ydtech/modules/admin/components/wechat/customer/request/CustomerGetTokenRequest.java

@@ -5,8 +5,7 @@ import lombok.Data;
 import lombok.NoArgsConstructor;
 
 /**
- * @version
- * @description: 微信客服 获取调用凭证access_token
+ * @description: 【微信客服】 获取调用凭证access_token
  * @author: wenks
  * @date: 2024/11/27 18:03
  **/
@@ -19,10 +18,9 @@ public class CustomerGetTokenRequest {
 
     private String corpSecret;
 
-    public String getUrlParams(){
-        return "corpid=" + corpId + "&corpsecret=" + corpSecret;
+    public String getUrlParams() {
+        return "?corpid=" + corpId + "&corpsecret=" + corpSecret;
     }
 
 
-
 }

+ 33 - 0
src/main/java/com/ydtech/modules/admin/components/wechat/customer/request/CustomerListRequest.java

@@ -0,0 +1,33 @@
+package com.ydtech.modules.admin.components.wechat.customer.request;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+
+/**
+ * @description: 【微信客服】 获取客服账号列表
+ * @author: wenks
+ * @date: 2024/11/28 15:15
+ **/
+@EqualsAndHashCode(callSuper = true)
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class CustomerListRequest extends CustomerBaseRequest {
+
+    /**
+     * 分页,偏移量, 默认为0
+     */
+    @JsonProperty("offset")
+    private Integer offset;
+
+    /**
+     * 分页,预期请求的数据量,默认为100,取值范围 1 ~ 100
+     */
+    @JsonProperty("limit")
+    private Integer limit;
+
+}

+ 55 - 0
src/main/java/com/ydtech/modules/admin/components/wechat/customer/request/CustomerSendMsgOnEventRequest.java

@@ -0,0 +1,55 @@
+package com.ydtech.modules.admin.components.wechat.customer.request;
+
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+
+/**
+ * @description: 【微信客服】 发送客服欢迎语
+ * @author: wenks
+ * @date: 2024/11/28 15:34
+ **/
+@EqualsAndHashCode(callSuper = true)
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class CustomerSendMsgOnEventRequest extends CustomerBaseRequest {
+
+    /**
+     * 事件响应消息对应的code。通过事件回调下发,仅可使用一次。
+     */
+    @JsonProperty("code")
+    private String code;
+
+    /**
+     * 消息ID。如果请求参数指定了msgid,则原样返回,否则系统自动生成并返回。
+     * 不多于32字节
+     * 字符串取值范围(正则表达式):[0-9a-zA-Z_-]*
+     */
+    @JsonProperty("msgid")
+    private String msgid;
+
+    /**
+     * 消息类型。对不同的msgtype,有相应的结构描述,详见消息类型
+     */
+    @JsonProperty("msgtype")
+    private String msgtype;
+
+    @JsonProperty("text")
+    private TextDTO text;
+
+    @NoArgsConstructor
+    @Data
+    @AllArgsConstructor
+    public static class TextDTO {
+
+        @JsonProperty("content")
+        private String content;
+
+    }
+
+}

+ 31 - 0
src/main/java/com/ydtech/modules/admin/components/wechat/customer/request/CustomerSyncMsgRequest.java

@@ -0,0 +1,31 @@
+package com.ydtech.modules.admin.components.wechat.customer.request;
+
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+@EqualsAndHashCode(callSuper = true)
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+public class CustomerSyncMsgRequest extends CustomerBaseRequest {
+
+    @JsonProperty("cursor")
+    private String cursor;
+
+    @JsonProperty("token")
+    private String token;
+
+    @JsonProperty("limit")
+    private Integer limit;
+
+    @JsonProperty("voice_format")
+    private Integer voiceFormat;
+
+    @JsonProperty("open_kfid")
+    private String openKfid;
+
+}

+ 30 - 0
src/main/java/com/ydtech/modules/admin/components/wechat/customer/response/CustomerAddContactWayResponse.java

@@ -0,0 +1,30 @@
+package com.ydtech.modules.admin.components.wechat.customer.response;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+
+/**
+ * @description: 【微信客服】 获取客服账号链接
+ * @author: wenks
+ * @date: 2024/11/28 15:14
+ **/
+@EqualsAndHashCode(callSuper = true)
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class CustomerAddContactWayResponse extends CustomerBaseResponse {
+
+    private static final long serialVersionUID = 3481360032833130444L;
+
+    /**
+     * 客服链接,开发者可将该链接嵌入到H5页面中,用户点击链接即可向对应
+     * 的微信客服账号发起咨询。开发者也可根据该url自行生成需要的二维码图片
+     */
+    @JsonProperty("url")
+    private String url;
+
+}

+ 36 - 0
src/main/java/com/ydtech/modules/admin/components/wechat/customer/response/CustomerBaseResponse.java

@@ -0,0 +1,36 @@
+package com.ydtech.modules.admin.components.wechat.customer.response;
+
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+
+/**
+ * @description: 【微信客服】 请求基类
+ * @author: wenks
+ * @date: 2024/11/28 14:54
+ **/
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class CustomerBaseResponse implements Serializable {
+
+    private static final long serialVersionUID = -3778665006292913282L;
+
+    /**
+     * 返回码
+     */
+    @JsonProperty("errcode")
+    private Integer errcode;
+
+    /**
+     * 错误码描述
+     */
+    @JsonProperty("errmsg")
+    private String errmsg;
+
+}

+ 1 - 3
src/main/java/com/ydtech/modules/admin/components/wechat/customer/response/CustomerGetTokenResponse.java

@@ -6,10 +6,8 @@ import lombok.Data;
 import lombok.NoArgsConstructor;
 
 
-
 /**
- * @version
- * @description: 微信客服 获取调用凭证access_token
+ * @description: 【微信客服】  获取调用凭证access_token
  * @author: wenks
  * @date: 2024/11/27 18:01
  **/

+ 55 - 0
src/main/java/com/ydtech/modules/admin/components/wechat/customer/response/CustomerListResponse.java

@@ -0,0 +1,55 @@
+package com.ydtech.modules.admin.components.wechat.customer.response;
+
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+
+/**
+ * @description: 【微信客服】 获取客服账号列表
+ * @author: wenks
+ * @date: 2024/11/28 15:36
+ **/
+@EqualsAndHashCode(callSuper = true)
+@NoArgsConstructor
+@AllArgsConstructor
+@Data
+public class CustomerListResponse extends CustomerBaseResponse {
+
+    private static final long serialVersionUID = -4750295003681323623L;
+
+    @JsonProperty("account_list")
+    private List<AccountListDTO> accountList;
+
+    @NoArgsConstructor
+    @Data
+    public static class AccountListDTO implements Serializable {
+
+        private static final long serialVersionUID = 1186740344093413070L;
+
+        /**
+         * 客服账号ID
+         */
+        @JsonProperty("open_kfid")
+        private String openKfid;
+
+        /**
+         * 客服账号名称
+         */
+        @JsonProperty("name")
+        private String name;
+
+        /**
+         * 客服头像URL
+         */
+        @JsonProperty("avatar")
+        private String avatar;
+
+    }
+}

+ 42 - 0
src/main/java/com/ydtech/modules/admin/components/wechat/customer/response/CustomerSendMsgOnEventResponse.java

@@ -0,0 +1,42 @@
+package com.ydtech.modules.admin.components.wechat.customer.response;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * @version
+ * @description: 【微信客服】 发送客服欢迎语
+ * @author: wenks
+ * @date: 2024/11/28 16:00
+ **/
+@EqualsAndHashCode(callSuper = true)
+@NoArgsConstructor
+@AllArgsConstructor
+@Data
+public class CustomerSendMsgOnEventResponse extends CustomerBaseResponse {
+
+    private static final long serialVersionUID = -3439241873552051173L;
+
+    @JsonProperty("code")
+    private String code;
+
+    @JsonProperty("msgid")
+    private String msgid;
+
+    @JsonProperty("msgtype")
+    private String msgtype;
+
+    @JsonProperty("text")
+    private TextDTO text;
+
+    @NoArgsConstructor
+    @Data
+    public static class TextDTO {
+        @JsonProperty("content")
+        private String content;
+    }
+
+}

+ 78 - 0
src/main/java/com/ydtech/modules/admin/components/wechat/customer/response/CustomerSyncMsgResponse.java

@@ -0,0 +1,78 @@
+package com.ydtech.modules.admin.components.wechat.customer.response;
+
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+/**
+ * @version
+ * @description: TODO
+ * @author: wenks
+ * @date: 2024/11/28 16:00
+ **/
+@EqualsAndHashCode(callSuper = true)
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+public class CustomerSyncMsgResponse extends CustomerBaseResponse{
+
+    private static final long serialVersionUID = 7675662937493615248L;
+
+
+    @JsonProperty("next_cursor")
+    private String nextCursor;
+
+    @JsonProperty("msg_list")
+    private List<MsgListDTO> msgList;
+
+    @JsonProperty("has_more")
+    private Integer hasMore;
+
+    @NoArgsConstructor
+    @Data
+    public static class MsgListDTO {
+        @JsonProperty("msgid")
+        private String msgid;
+
+        @JsonProperty("send_time")
+        private Integer sendTime;
+
+        @JsonProperty("origin")
+        private Integer origin;
+
+        @JsonProperty("msgtype")
+        private String msgtype;
+
+        @JsonProperty("event")
+        private EventDTO event;
+
+        @NoArgsConstructor
+        @Data
+        public static class EventDTO {
+
+            @JsonProperty("event_type")
+            private String eventType;
+
+            @JsonProperty("scene")
+            private String scene;
+
+            @JsonProperty("open_kfid")
+            private String openKfid;
+
+            @JsonProperty("external_userid")
+            private String externalUserid;
+
+            @JsonProperty("scene_param")
+            private String sceneParam;
+
+            @JsonProperty("welcome_code")
+            private String welcomeCode;
+
+        }
+    }
+}

+ 0 - 35
src/main/java/com/ydtech/modules/admin/controller/WechatController.java

@@ -65,39 +65,4 @@ public class WechatController extends BaseController {
         }
     }
 
-    @GetMapping(path = "/customer/callback")
-    @ApiOperation(value = "客服回调")
-    public String customerCallback(@RequestParam(value = "msg_signature") String msgSignature,
-                                               @RequestParam(value = "timestamp") String timestamp,
-                                               @RequestParam(value = "nonce") String nonce,
-                                               @RequestParam(value = "echostr") String echoStr) {
-        System.out.println(msgSignature + " " + timestamp + " " + nonce + " " + echoStr);
-        WxCryptUtil wxCryptUtil = new WxCryptUtil("HBme3ASL", "kv1XrZqTDUup27rVatFG3s04DSw2qEAvxg7k9euEROq", "wwfe67d19509d43ec5");
-        return wxCryptUtil.decryptContent(msgSignature, timestamp, nonce, echoStr);
-    }
-
-    @Autowired
-    public WxCpKfService wxCpKfService;
-
-    @PostMapping(path = "/customer/callback", consumes = MediaType.TEXT_XML_VALUE, produces = MediaType.TEXT_XML_VALUE)
-    @ApiOperation(value = "客服回调")
-    public HttpResult customerCallback(@RequestBody String wechatEncrypt) throws JsonProcessingException, WxErrorException {
-        XmlMapper xmlMapper = new XmlMapper();
-        WechatEncryptVo wechatEncryptVo = xmlMapper.readValue(wechatEncrypt, WechatEncryptVo.class);
-        WxCryptUtil wxCryptUtil = new WxCryptUtil("HBme3ASL", "kv1XrZqTDUup27rVatFG3s04DSw2qEAvxg7k9euEROq", "wwfe67d19509d43ec5");
-        String encrypt = wxCryptUtil.decrypt(wechatEncryptVo.getEncrypt());
-        WechatCustomerCallbackVo wechatCustomerCallbackVo = xmlMapper.readValue(encrypt, WechatCustomerCallbackVo.class);
-        WxCpKfMsgListResp wxCpKfMsgListResp = wxCpKfService.syncMsg("", wechatCustomerCallbackVo.getToken(), null, null, wechatCustomerCallbackVo.getOpenKfId());
-        WxCpKfMsgListResp.WxCpKfMsgItem wxCpKfMsgItem = wxCpKfMsgListResp.getMsgList().get(0);
-
-        WxCpKfMsgSendRequest wxCpKfMsgSendRequest = new WxCpKfMsgSendRequest();
-        wxCpKfMsgSendRequest.setMsgType("text");
-        wxCpKfMsgSendRequest.setMsgId(wxCpKfMsgItem.getMsgId());
-        wxCpKfMsgSendRequest.setCode(wxCpKfMsgItem.getEvent().getWelcomeCode());
-        wxCpKfService.sendMsgOnEvent(wxCpKfMsgSendRequest);
-
-        return HttpResult.ok(wxCpKfMsgListResp);
-    }
-
-
 }

+ 37 - 0
src/main/java/com/ydtech/modules/admin/controller/wechat/WechatCustomerController.java

@@ -0,0 +1,37 @@
+package com.ydtech.modules.admin.controller.wechat;
+
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.ydtech.modules.admin.service.WechatCustomerService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.*;
+
+@Api(tags = "微信业务")
+@Slf4j
+@RestController
+@RequestMapping("/wechat/customer")
+@RequiredArgsConstructor
+public class WechatCustomerController {
+
+    private final WechatCustomerService customerService;
+
+    @GetMapping(path = "/callback")
+    @ApiOperation(value = "客服回调")
+    public String customerCallback(@RequestParam(value = "msg_signature") String msgSignature,
+                                   @RequestParam(value = "timestamp") String timestamp,
+                                   @RequestParam(value = "nonce") String nonce,
+                                   @RequestParam(value = "echostr") String echoStr) {
+        return customerService.customerCallback(msgSignature, timestamp, nonce, echoStr);
+    }
+
+    @PostMapping(path = "/callback", consumes = MediaType.TEXT_XML_VALUE, produces = MediaType.TEXT_XML_VALUE)
+    @ApiOperation(value = "客服回调(处理事件发送欢迎语)")
+    public void customerCallback(@RequestBody String wechatEncrypt) throws JsonProcessingException {
+        customerService.callbackSendMsgOnEvent(wechatEncrypt);
+    }
+
+}

+ 23 - 0
src/main/java/com/ydtech/modules/admin/service/WechatCustomerService.java

@@ -0,0 +1,23 @@
+package com.ydtech.modules.admin.service;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+
+public interface WechatCustomerService {
+
+    /**
+     * 配置微信客服回调信息
+     *
+     * @param msgSignature
+     * @param timestamp 时间戳
+     * @param nonce
+     * @param echoStr 加密后的参数
+     * @return 校验参数
+     */
+    String customerCallback(String msgSignature, String timestamp, String nonce, String echoStr);
+
+    /**
+     * 回调事件
+     * @param wechatEncrypt
+     */
+    void callbackSendMsgOnEvent(String wechatEncrypt) throws JsonProcessingException;
+}

+ 75 - 0
src/main/java/com/ydtech/modules/admin/service/impl/WechatCustomerServiceImpl.java

@@ -0,0 +1,75 @@
+package com.ydtech.modules.admin.service.impl;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.dataformat.xml.XmlMapper;
+import com.ydtech.modules.admin.components.WechatCustomerComponents;
+import com.ydtech.modules.admin.components.wechat.customer.request.CustomerSendMsgOnEventRequest;
+import com.ydtech.modules.admin.components.wechat.customer.request.CustomerSyncMsgRequest;
+import com.ydtech.modules.admin.components.wechat.customer.response.CustomerSyncMsgResponse;
+import com.ydtech.modules.admin.model.SysDept;
+import com.ydtech.modules.admin.model.SysUser;
+import com.ydtech.modules.admin.model.vo.wechat.WechatCustomerCallbackVo;
+import com.ydtech.modules.admin.model.vo.wechat.WechatEncryptVo;
+import com.ydtech.modules.admin.service.SysDeptService;
+import com.ydtech.modules.admin.service.SysUserService;
+import com.ydtech.modules.admin.service.WechatCustomerService;
+import com.ydtech.utils.StringUtils;
+import lombok.RequiredArgsConstructor;
+import me.chanjar.weixin.common.util.crypto.WxCryptUtil;
+import me.chanjar.weixin.cp.bean.kf.WxCpKfMsgListResp;
+import me.chanjar.weixin.cp.bean.kf.WxCpKfMsgSendRequest;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor
+public class WechatCustomerServiceImpl implements WechatCustomerService {
+
+    private final WechatCustomerComponents wechatCustomerComponents;
+
+    private final SysUserService sysUserService;
+
+    private final SysDeptService sysDeptService;
+
+    @Override
+    public String customerCallback(String msgSignature, String timestamp, String nonce, String echoStr) {
+        System.out.println(msgSignature + " " + timestamp + " " + nonce + " " + echoStr);
+        WxCryptUtil wxCryptUtil = wechatCustomerComponents.getWxCryptUtil();
+        return wxCryptUtil.decrypt(echoStr);
+    }
+
+    @Override
+    public void callbackSendMsgOnEvent(String wechatEncrypt) throws JsonProcessingException {
+        XmlMapper xmlMapper = new XmlMapper();
+        WechatEncryptVo wechatEncryptVo = xmlMapper.readValue(wechatEncrypt, WechatEncryptVo.class);
+        WxCryptUtil wxCryptUtil = wechatCustomerComponents.getWxCryptUtil();
+        String encrypt = wxCryptUtil.decrypt(wechatEncryptVo.getEncrypt());
+        WechatCustomerCallbackVo wechatCustomerCallbackVo = xmlMapper.readValue(encrypt, WechatCustomerCallbackVo.class);
+
+        // 获取消息
+        CustomerSyncMsgRequest customerSyncMsgRequest = new CustomerSyncMsgRequest();
+        customerSyncMsgRequest.setToken(wechatCustomerCallbackVo.getToken());
+        customerSyncMsgRequest.setOpenKfid(wechatCustomerCallbackVo.getOpenKfId());
+        CustomerSyncMsgResponse customerSyncMsgResponse = wechatCustomerComponents.syncMsg(customerSyncMsgRequest);
+        List<CustomerSyncMsgResponse.MsgListDTO> msgList = customerSyncMsgResponse.getMsgList();
+        CustomerSyncMsgResponse.MsgListDTO msgListDTO = customerSyncMsgResponse.getMsgList().get(msgList.size() - 1);
+
+        CustomerSyncMsgResponse.MsgListDTO.EventDTO event = msgListDTO.getEvent();
+        String sceneParam = event.getSceneParam();
+        if (StringUtils.isEmpty(sceneParam)) {
+            return;
+        }
+
+        SysUser sysUser = sysUserService.getById(sceneParam);
+        String messages = "你好!" + sysUser.getName() + "(" + sysUser.getId() + ")" + "很高兴为你服务";
+
+        // 发送欢迎信息
+        CustomerSendMsgOnEventRequest customerSendMsgOnEventRequest = new CustomerSendMsgOnEventRequest();
+        customerSendMsgOnEventRequest.setMsgtype("text");
+        customerSendMsgOnEventRequest.setMsgid(msgListDTO.getMsgid());
+        customerSendMsgOnEventRequest.setCode(event.getWelcomeCode());
+        customerSendMsgOnEventRequest.setText(new CustomerSendMsgOnEventRequest.TextDTO(messages));
+        wechatCustomerComponents.sendMsgOnEvent(customerSendMsgOnEventRequest);
+    }
+}

+ 4 - 0
src/main/java/com/ydtech/modules/order/components/InsCrawlerOrderComponents.java

@@ -56,5 +56,9 @@ public class InsCrawlerOrderComponents {
         return this.post(url, insuranceEnum.getPinyin(), message, requestBody, responseType, httpHeaders);
     }
 
+    public <T, B> B request(String url, String logId, String message, T requestBody, Class<B> responseType, HttpHeaders httpHeaders) {
+        return this.post(url, logId, message, requestBody, responseType, httpHeaders);
+    }
+
 }