diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml
index fc1edce..6bdd852 100644
--- a/ruoyi-admin/pom.xml
+++ b/ruoyi-admin/pom.xml
@@ -70,6 +70,11 @@
com.ruoyi
ruoyi-generator
+
+ com.github.binarywang
+ weixin-java-common
+ 4.6.0
+
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/WxApi.java b/ruoyi-admin/src/main/java/com/ruoyi/api/WxApi.java
index 4e476f4..8e47a00 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/api/WxApi.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/api/WxApi.java
@@ -2,22 +2,15 @@ package com.ruoyi.api;
import cn.hutool.json.JSONObject;
-import cn.hutool.json.JSONUtil;
import com.ruoyi.busi.utils.WeChatUtils;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.GzhLoginBody;
-import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.member.service.IMemberUserService;
-import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
-import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.security.GeneralSecurityException;
import java.util.HashMap;
import java.util.Map;
@@ -30,13 +23,12 @@ public class WxApi {
private IMemberUserService memberUserService;
-
@GetMapping("/getCodeUrl")
@Anonymous
- public Map getCodeUrl(String userType,String url) {
+ public Map getCodeUrl(String userType, String url) {
Map res = new HashMap<>();
- res.put("codeUrl", weChatUtils.getCodeUrl("https://www.ddtg.site/#/"+url, userType));
- return res;
+ res.put("codeUrl", weChatUtils.getCodeUrl("https://www.ddtg.site/#/" + url, userType));
+ return res;
}
@GetMapping("/getWebAccessTokenAndOpenid")
@@ -47,15 +39,13 @@ public class WxApi {
@PostMapping("/gzhLogin")
@Anonymous
- public AjaxResult gzhLogin(@RequestBody GzhLoginBody gzhLoginBody)
- {
+ public AjaxResult gzhLogin(@RequestBody GzhLoginBody gzhLoginBody) {
JSONObject userInfo = weChatUtils.getUserInfo(gzhLoginBody.getAccess_token(), gzhLoginBody.getOpenid());
//如果解析成功,获取token
- String token = memberUserService.gzhLogin(gzhLoginBody.getOpenid(),userInfo);
+ String token = memberUserService.gzhLogin(gzhLoginBody.getOpenid(), userInfo);
AjaxResult ajax = AjaxResult.success();
ajax.put(Constants.TOKEN, token);
return ajax;
-
}
}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/WxMsgApi.java b/ruoyi-admin/src/main/java/com/ruoyi/api/WxMsgApi.java
new file mode 100644
index 0000000..01ae65c
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/api/WxMsgApi.java
@@ -0,0 +1,58 @@
+package com.ruoyi.api;
+
+import com.ruoyi.api.domain.WeChatMessage;
+import com.ruoyi.api.service.IWeChatMessageService;
+import com.ruoyi.busi.utils.WeChatUtils;
+import com.ruoyi.common.annotation.Anonymous;
+import com.wechat.pay.java.core.http.HttpMethod;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+@RestController
+@RequestMapping("/wxMsgApi")
+public class WxMsgApi {
+ @Autowired
+ private WeChatUtils weChatUtils;
+ @Resource
+ private IWeChatMessageService weChatMessageService;
+
+ /**
+ * 校验签名
+ *
+ * @param message {@link WeChatMessage}
+ * @param request {@link HttpServletRequest}
+ * @return java.lang.Object
+ * @author PQZ
+ * @date 12:17 2025/4/25
+ **/
+ @RequestMapping("/message")
+ @Anonymous
+ public void register(WeChatMessage message, HttpServletRequest request, HttpServletResponse response) throws IOException {
+ String method = request.getMethod();
+ if (HttpMethod.GET.name().equalsIgnoreCase(method)) {
+ String echostr = weChatMessageService.checkSignature(message);
+ response.getOutputStream().write(echostr.getBytes());
+ } else if (HttpMethod.POST.name().equalsIgnoreCase(method)) {
+ // 进入POST聊天处理
+ // 将请求、响应的编码均设置为UTF-8(防止中文乱码)
+ request.setCharacterEncoding("UTF-8");
+ response.setCharacterEncoding("UTF-8");
+ // 接收消息并返回消息
+ String result = weChatMessageService.acceptMessage(request, response);
+ // 响应消息
+ PrintWriter out = response.getWriter();
+ out.print(result);
+ out.close();
+ }
+ }
+
+
+}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/domain/WeChatMessage.java b/ruoyi-admin/src/main/java/com/ruoyi/api/domain/WeChatMessage.java
new file mode 100644
index 0000000..5d03c97
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/api/domain/WeChatMessage.java
@@ -0,0 +1,37 @@
+package com.ruoyi.api.domain;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class WeChatMessage {
+
+
+ /**
+ * 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数
+ */
+ private String signature;
+
+ /**
+ * 时间戳
+ */
+ private String timestamp;
+
+ /**
+ * 随机数
+ */
+ private String nonce;
+
+ /**
+ * 随机字符串
+ */
+ private String echostr;
+
+
+}
+
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/service/IWeChatMessageService.java b/ruoyi-admin/src/main/java/com/ruoyi/api/service/IWeChatMessageService.java
new file mode 100644
index 0000000..3b2b3c8
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/api/service/IWeChatMessageService.java
@@ -0,0 +1,37 @@
+package com.ruoyi.api.service;
+
+import com.ruoyi.api.domain.WeChatMessage;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * 微信消息自动回复Service
+ *
+ * @author vinjor-m
+ * @date 2025-03-17
+ */
+public interface IWeChatMessageService {
+ /**
+ * 校验签名
+ *
+ * @param message {@link WeChatMessage}
+ * @return java.lang.String
+ * @author PQZ
+ * @date 12:08 2025/4/25
+ **/
+ String checkSignature(WeChatMessage message);
+
+ /**
+ * 发送消息返回
+ *
+ * @param request {@link HttpServletRequest}
+ * @param response {@link HttpServletResponse}
+ * @return java.lang.String
+ * @author PQZ
+ * @date 12:52 2025/4/25
+ **/
+ String acceptMessage(HttpServletRequest request, HttpServletResponse response);
+
+
+}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/WeChatMessageServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/WeChatMessageServiceImpl.java
new file mode 100644
index 0000000..0b26f95
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/WeChatMessageServiceImpl.java
@@ -0,0 +1,194 @@
+package com.ruoyi.api.service.impl;
+
+import cn.hutool.crypto.SecureUtil;
+import cn.hutool.json.JSONArray;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.google.gson.JsonArray;
+import com.ruoyi.api.domain.WeChatMessage;
+import com.ruoyi.api.service.IWeChatMessageService;
+import com.ruoyi.api.util.HttpUtils;
+import com.ruoyi.api.util.MessageUtil;
+import com.ruoyi.base.domain.BaseConfig;
+import com.ruoyi.base.service.IBaseConfigService;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.http.HttpMethod;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * 会员卡Service业务层处理
+ *
+ * @author vinjor-m
+ * @date 2025-03-17
+ */
+@Service
+public class WeChatMessageServiceImpl implements IWeChatMessageService {
+
+
+ @Value("${wx-app.appId}")
+ private String appId;
+
+ @Value("${wx-app.appSecret}")
+ private String appSecret;
+
+ @Value("${wx-app.token}")
+ private String token;
+
+ @Resource
+ private IBaseConfigService configService;
+
+ /**发送消息url*/
+ private static String SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/custom/send";
+
+ /**获取accessTokenUrl*/
+ private String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
+
+
+
+ /**
+ * 校验签名
+ *
+ * @param message {@link WeChatMessage}
+ * @return java.lang.String
+ * @author PQZ
+ * @date 12:08 2025/4/25
+ **/
+ @Override
+ public String checkSignature(WeChatMessage message) {
+ String signature = message.getSignature();
+ String timestamp = message.getTimestamp();
+ String nonce = message.getNonce();
+ //必须与请求参数中的token一致
+ List list = new ArrayList<>();
+ list.add(token);
+ list.add(timestamp);
+ list.add(nonce);
+ // 排序跟使用hutool工具类 进行字典排序跟加密
+ String str = list.stream().sorted().collect(Collectors.joining());
+ String tmpStr = SecureUtil.sha1(str);
+ if (signature.equals(tmpStr)) {
+ return message.getEchostr();
+ } else {
+ return "shibai";
+ }
+ }
+
+ /**
+ * 发送消息返回
+ *
+ * @param request {@link HttpServletRequest}
+ * @param response {@link HttpServletResponse}
+ * @return java.lang.String
+ * @author PQZ
+ * @date 12:52 2025/4/25
+ **/
+ @Override
+ public String acceptMessage(HttpServletRequest request, HttpServletResponse response) {
+ //返回值
+ String result = "success";
+ try {
+ request.setCharacterEncoding("UTF-8");
+ response.setCharacterEncoding("UTF-8");
+ Map requestMap = MessageUtil.parseXml(request);
+ // 发送者的openid
+ String fromUserName = requestMap.get("FromUserName");
+ // 小程序的原始ID
+ String toUserName = requestMap.get("ToUserName");
+ // 消息类型
+ String msgType = requestMap.get("MsgType");
+ // 文本消息内容
+ String content = requestMap.get("Content");
+ // 事件类型
+ String event = requestMap.get("Event");
+ StringBuilder contentMessage = new StringBuilder();
+ String contentStr = "嗨,欢迎加入通告快捷,您想咨询那个问题,请点击选择";
+ String jqHtml = "1111";
+ String xsHtml = "1111";
+ String tgzHtml = "https://www.ddtg.site/#/pages/mine/member/member-card?userType=01";
+ String bzHtml = "https://www.ddtg.site/#/pages/mine/member/member-card?userType=02";
+ String jqStr = "1、进群";
+ String xsStr = "2、新手教程";
+ String tgzStr = "3、通告主卡";
+ String bzStr = "4、博主VIP";
+ contentMessage.append(contentStr).append("\n")
+ .append(jqStr).append("\n")
+ .append(xsStr).append("\n")
+ .append(tgzStr).append("\n")
+ .append(bzStr).append("\n");
+ if (msgType.equals("event")) {
+ sendCustomerTextMessage(fromUserName, contentMessage.toString(), getAccessToken());
+ } else if (msgType.equals("text")) {
+ if (content.equals("0")) {
+ return switchCustomerService(fromUserName, toUserName);
+ } else {
+ sendCustomerTextMessage(fromUserName, contentMessage.toString(), getAccessToken());
+ }
+ } else {
+ sendCustomerTextMessage(fromUserName, contentMessage.toString(), getAccessToken());
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return result;
+ }
+
+ private void sendCustomerTextMessage(String openid, String text, String accessToken) throws IOException {
+ HashMap map_content = new HashMap<>();
+ map_content.put("content", text);
+ HashMap map = new HashMap<>();
+ map.put("touser", openid);
+ map.put("msgtype", "text");
+ map.put("text", map_content);
+ String content = JSON.toJSONString(map);
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.APPLICATION_JSON);
+ HttpEntity httpEntity = new HttpEntity(map, headers);
+ HttpUtils.sendPostRequest(SEND_URL + "?access_token=" + accessToken, HttpMethod.POST, httpEntity);
+ }
+
+ /**
+ * 人工服务
+ *
+ * @param fromUserName
+ * @param toUserName
+ * @return
+ */
+ public String switchCustomerService(String fromUserName, String toUserName) {
+ return "\n" +
+ " \n" +
+ " \n" +
+ " " + System.currentTimeMillis() / 1000 + "\n" +
+ " \n" +
+ "";
+ }
+
+ /**
+ * 获取accessToken
+ * @author PQZ
+ * @date 16:12 2025/4/25
+ * @return java.lang.String
+ **/
+ public String getAccessToken() {
+ //拼接url【传入appId和secret】
+ url = url.replace("APPID", appId).replace("APPSECRET", appSecret);
+ String str = HttpUtils.sendGetRequest(url);
+ JSONObject jsonObject = JSONObject.parseObject(str);
+ return jsonObject.getString("access_token");
+ }
+
+
+}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/util/HttpUtils.java b/ruoyi-admin/src/main/java/com/ruoyi/api/util/HttpUtils.java
new file mode 100644
index 0000000..32334dd
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/api/util/HttpUtils.java
@@ -0,0 +1,36 @@
+package com.ruoyi.api.util;
+
+
+import org.springframework.http.HttpEntity;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.http.HttpMethod;
+
+import java.util.Map;
+
+/**
+ * 客服功能 - 消息发送请求工具类
+ * Created by Lance on 2020/10/10 17:52
+ */
+public class HttpUtils {
+
+ /**
+ * Get 发送的请求
+ * @param url
+ * @return
+ */
+ public static String sendGetRequest(String url) {
+ RestTemplate restTemplate = new RestTemplate();
+ return restTemplate.getForObject(url, String.class);
+ }
+
+ public static String sendPostRequest(String url, HttpMethod method, HttpEntity