pom.xml
@@ -337,11 +337,11 @@ <version>${revision}</version> </dependency> <!-- <dependency>--> <!-- <groupId>org.ruoyi</groupId>--> <!-- <artifactId>ruoyi-demo</artifactId>--> <!-- <version>${revision}</version>--> <!-- </dependency>--> <dependency> <groupId>org.ruoyi</groupId> <artifactId>ruoyi-wechat</artifactId> <version>${revision}</version> </dependency> </dependencies> </dependencyManagement> ruoyi-admin/pom.xml
@@ -57,6 +57,10 @@ <artifactId>ruoyi-generator</artifactId> </dependency> <dependency> <groupId>org.ruoyi</groupId> <artifactId>ruoyi-wechat</artifactId> </dependency> </dependencies> ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/service/SysLoginService.java
@@ -19,12 +19,10 @@ import org.ruoyi.common.core.domain.dto.RoleDTO; import org.ruoyi.common.core.domain.model.LoginUser; import org.ruoyi.common.core.domain.model.VisitorLoginBody; import org.ruoyi.common.core.domain.model.VisitorLoginUser; import org.ruoyi.common.core.enums.*; import org.ruoyi.common.core.exception.user.CaptchaException; import org.ruoyi.common.core.exception.user.CaptchaExpireException; import org.ruoyi.common.core.exception.user.UserException; import org.ruoyi.common.core.service.ConfigService; import org.ruoyi.common.core.utils.*; import org.ruoyi.common.log.event.LogininforEvent; import org.ruoyi.common.redis.utils.RedisUtils; @@ -32,8 +30,7 @@ import org.ruoyi.common.tenant.exception.TenantException; import org.ruoyi.common.tenant.helper.TenantHelper; import org.ruoyi.system.domain.SysUser; import org.ruoyi.system.domain.bo.SysUserBo; import org.ruoyi.system.domain.vo.LoginVo; import org.ruoyi.system.domain.vo.SysTenantVo; import org.ruoyi.system.domain.vo.SysUserVo; import org.ruoyi.system.mapper.SysUserMapper; @@ -43,7 +40,6 @@ import java.time.Duration; import java.util.Date; import java.util.List; import java.util.UUID; import java.util.function.Supplier; /** @@ -60,8 +56,6 @@ private final WxMaService wxMaService; private final ISysPermissionService permissionService; private final ISysTenantService tenantService; private final ISysUserService userService; private final ConfigService configService; @Value("${user.password.maxRetryCount}") private Integer maxRetryCount; @@ -69,7 +63,7 @@ private Integer lockTime; /** * è·å微信 * è·å微信code * @param xcxCode è·åxcxCode */ public String getOpenidFromCode(String xcxCode) { @@ -137,9 +131,8 @@ return StpUtil.getTokenValue(); } /** * 游客ç»å½ * 微信å°ç¨åºç»å½ * * @param loginBody * @return String @@ -163,57 +156,6 @@ } } } public LoginVo mpLogin(String openid) { // ä½¿ç¨ openid æ¥è¯¢ç»å®ç¨æ· 妿ªç»å®ç¨æ· åæ ¹æ®ä¸å¡èªè¡å¤ç ä¾å¦ å建é»è®¤ç¨æ· SysUserVo user = userService.selectUserByOpenId(openid); VisitorLoginUser loginUser = new VisitorLoginUser(); if (ObjectUtil.isNull(user)) { SysUserBo sysUser = new SysUserBo(); // æ¹ä¸ºèªå¢ String name = "ç¨æ·" + UUID.randomUUID().toString().replace("-", ""); // 设置é»è®¤ç¨æ·å sysUser.setUserName(name); // 设置é»è®¤æµç§° sysUser.setNickName(name); // 设置é»è®¤å¯ç sysUser.setPassword(BCrypt.hashpw("123456")); // 设置微信openId sysUser.setOpenId(openid); String configValue = configService.getConfigValue("mail", "amount"); // 设置é»è®¤ä½é¢ sysUser.setUserBalance(NumberUtils.toDouble(configValue, 1)); // 注åç¨æ·,设置é»è®¤ç§æ·ä¸º0 SysUser registerUser = userService.registerUser(sysUser, "0"); // æå»ºç»å½ç¨æ·ä¿¡æ¯ loginUser.setTenantId("0"); loginUser.setUserId(registerUser.getUserId()); loginUser.setUsername(registerUser.getUserName()); loginUser.setUserType(UserType.APP_USER.getUserType()); loginUser.setOpenid(openid); loginUser.setNickName(registerUser.getNickName()); } else { // æ¤å¤å¯æ ¹æ®ç»å½ç¨æ·çæ°æ®ä¸å èªè¡å建 loginUser loginUser.setTenantId(user.getTenantId()); loginUser.setUserId(user.getUserId()); loginUser.setUsername(user.getUserName()); loginUser.setUserType(user.getUserType()); loginUser.setNickName(user.getNickName()); loginUser.setAvatar(user.getWxAvatar()); loginUser.setOpenid(openid); } // çætoken LoginHelper.loginByDevice(loginUser, DeviceType.XCX); recordLogininfor(loginUser.getTenantId(), loginUser.getUsername(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")); LoginVo loginVo = new LoginVo(); // çæä»¤ç loginVo.setToken(StpUtil.getTokenValue()); loginVo.setUserInfo(loginUser); return loginVo; } /** * éåºç»å½ ruoyi-modules/ruoyi-wechat/pom.xml
@@ -23,6 +23,10 @@ <groupId>org.ruoyi</groupId> <artifactId>ruoyi-chat-api</artifactId> </dependency> <dependency> <groupId>org.ruoyi</groupId> <artifactId>ruoyi-system-api</artifactId> </dependency> </dependencies> </project> ruoyi-modules/ruoyi-wechat/src/main/java/org/ruoyi/config/WxCpProperties.java
@@ -3,12 +3,15 @@ import lombok.Data; import lombok.Getter; import lombok.Setter; import org.springframework.boot.context.properties.ConfigurationProperties; import java.util.List; /** * @author <a href="https://github.com/binarywang">Binary Wang</a> */ @Data @ConfigurationProperties(prefix = "wechat.cp") public class WxCpProperties { /** * 设置ä¼ä¸å¾®ä¿¡çcorpId ruoyi-modules/ruoyi-wechat/src/main/java/org/ruoyi/controller/WeixinServerController.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,48 @@ package org.ruoyi.controller; import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.ruoyi.service.WeixinUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; /** * @author https://www.wdbyte.com */ @Slf4j @RestController public class WeixinServerController { @Autowired private WeixinUserService weixinUserService; @GetMapping(value = "/weixin/check") public String weixinCheck(HttpServletRequest request) { String signature = request.getParameter("signature"); String timestamp = request.getParameter("timestamp"); String nonce = request.getParameter("nonce"); String echostr = request.getParameter("echostr"); if (StringUtils.isEmpty(signature) || StringUtils.isEmpty(timestamp) || StringUtils.isEmpty(nonce)) { return ""; } weixinUserService.checkSignature(signature, timestamp, nonce); return echostr; } @PostMapping(value = "/weixin/check") public String weixinMsg(@RequestBody String requestBody, @RequestParam("signature") String signature, @RequestParam("timestamp") String timestamp, @RequestParam("nonce") String nonce) { log.debug("requestBody:{}", requestBody); log.debug("signature:{}", signature); log.debug("timestamp:{}", timestamp); log.debug("nonce:{}", nonce); weixinUserService.checkSignature(signature, timestamp, nonce); return weixinUserService.handleWeixinMsg(requestBody); } } ruoyi-modules/ruoyi-wechat/src/main/java/org/ruoyi/controller/WeixinUserController.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,52 @@ package org.ruoyi.controller; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.ruoyi.common.core.domain.R; import org.ruoyi.domin.WeixinQrCode; import org.ruoyi.service.VxLoginService; import org.ruoyi.system.domain.vo.LoginVo; import org.ruoyi.util.WeixinApiUtil; import org.ruoyi.util.WeixinQrCodeCacheUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; /** * @author https://www.wdbyte.com */ @Slf4j @RestController public class WeixinUserController { @Autowired private WeixinApiUtil weixinApiUtil; @Autowired private VxLoginService loginService; @GetMapping(value = "/user/qrcode") public R<WeixinQrCode> getQrCode() { WeixinQrCode qrCode = weixinApiUtil.getQrCode(); qrCode.setUrl(null); qrCode.setExpireSeconds(null); return R.ok(qrCode); } /** * æ ¡éªæ¯å¦æ«æå®æ * 宿ï¼è¿å JWT * æªå®æï¼è¿å check failed */ @GetMapping(value = "/user/login/qrcode") public R<LoginVo> userLogin(String ticket) { String openId = WeixinQrCodeCacheUtil.get(ticket); if (StringUtils.isNotEmpty(openId)) { log.info("login success,open id:{}", openId); LoginVo loginVo = loginService.mpLogin(openId); return R.ok(loginVo); } log.info("login error,ticket:{}", ticket); return R.fail("check failed"); } } ruoyi-modules/ruoyi-wechat/src/main/java/org/ruoyi/controller/WxPortalController.java
ÎļþÃû´Ó ruoyi-modules/ruoyi-wechat/src/main/java/org/ruoyi/controller/wxcplogin/WxPortalController.java ÐÞ¸Ä @@ -1,4 +1,4 @@ package org.ruoyi.controller.wxcplogin; package org.ruoyi.controller; import lombok.extern.slf4j.Slf4j; import me.chanjar.weixin.cp.api.WxCpService; ruoyi-modules/ruoyi-wechat/src/main/java/org/ruoyi/domin/ReceiveMessage.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,58 @@ package org.ruoyi.domin; import lombok.Data; @Data public class ReceiveMessage { /** * å¼åè å¾®ä¿¡å· */ private String toUserName; /** * åéæ¹è´¦å·(ä¸ä¸ªopenidï¼ */ private String fromUserName; /** * æ¶æ¯å建æ¶é´ï¼æ´å½¢ï¼ */ private String createTime; /** * æ¶æ¯ç±»å */ private String msgType; /** * ææ¬æ¶æ¯å 容 */ private String content; /** * æ¶æ¯ID 64ä½ */ String msgId; /** * æ¶æ¯çæ°æ®ID æ¶æ¯æ¥èªæç« ææ */ private String msgDataId; /** * å¤å¾ææ¶ç¬¬å ç¯æç« ï¼ä»1å¼å§ æ¶æ¯å¦ææ¥èªæç« ææ */ private String idx; /** * 订é äºä»¶ subscribe 订é unsbscribe åæ¶è®¢é */ private String event; /** * æ«ç - ticket */ private String ticket; public String getReplyTextMsg(String msg) { String xml = "<xml>\n" + " <ToUserName><![CDATA[" + getFromUserName() + "]]></ToUserName>\n" + " <FromUserName><![CDATA[" + getToUserName() + "]]></FromUserName>\n" + " <CreateTime>" + System.currentTimeMillis() + "</CreateTime>\n" + " <MsgType><![CDATA[text]]></MsgType>\n" + " <Content><![CDATA[" + msg + "]]></Content>\n" + " </xml>"; return xml; } } ruoyi-modules/ruoyi-wechat/src/main/java/org/ruoyi/domin/WeixinQrCode.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,15 @@ package org.ruoyi.domin; import lombok.Data; /** * @author https://www.wdbyte.com */ @Data public class WeixinQrCode { private String ticket; private Long expireSeconds; private String url; private String qrCodeUrl; } ruoyi-modules/ruoyi-wechat/src/main/java/org/ruoyi/service/VxLoginService.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,108 @@ package org.ruoyi.service; import cn.dev33.satoken.secure.BCrypt; import cn.dev33.satoken.stp.StpUtil; import cn.hutool.core.util.ObjectUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.math.NumberUtils; import org.ruoyi.common.core.constant.Constants; import org.ruoyi.common.core.domain.model.VisitorLoginUser; import org.ruoyi.common.core.enums.DeviceType; import org.ruoyi.common.core.enums.UserType; import org.ruoyi.common.core.service.ConfigService; import org.ruoyi.common.core.utils.MessageUtils; import org.ruoyi.common.core.utils.ServletUtils; import org.ruoyi.common.core.utils.SpringUtils; import org.ruoyi.common.log.event.LogininforEvent; import org.ruoyi.common.satoken.utils.LoginHelper; import org.ruoyi.system.domain.SysUser; import org.ruoyi.system.domain.bo.SysUserBo; import org.ruoyi.system.domain.vo.LoginVo; import org.ruoyi.system.domain.vo.SysUserVo; import org.ruoyi.system.service.ISysUserService; import org.springframework.stereotype.Service; import java.util.UUID; /** * æè¿°ï¼å¾®ä¿¡å ¬ä¼å·ç»å½ * * @author ageerle@163.com * date 2025/4/30 */ @Slf4j @Service @RequiredArgsConstructor public class VxLoginService { private final ISysUserService userService; private final ConfigService configService; public LoginVo mpLogin(String openid) { // ä½¿ç¨ openid æ¥è¯¢ç»å®ç¨æ· 妿ªç»å®ç¨æ· åæ ¹æ®ä¸å¡èªè¡å¤ç ä¾å¦ å建é»è®¤ç¨æ· SysUserVo user = userService.selectUserByOpenId(openid); VisitorLoginUser loginUser = new VisitorLoginUser(); if (ObjectUtil.isNull(user)) { SysUserBo sysUser = new SysUserBo(); String name = "ç¨æ·" + UUID.randomUUID().toString().replace("-", ""); // 设置é»è®¤ç¨æ·å sysUser.setUserName(name); // 设置é»è®¤æµç§° sysUser.setNickName(name); // 设置é»è®¤å¯ç sysUser.setPassword(BCrypt.hashpw("123456")); // 设置微信openId sysUser.setOpenId(openid); String configValue = configService.getConfigValue("mail", "amount"); // 设置é»è®¤ä½é¢ sysUser.setUserBalance(NumberUtils.toDouble(configValue, 1)); // 注åç¨æ·,设置é»è®¤ç§æ·ä¸º0 SysUser registerUser = userService.registerUser(sysUser, "0"); // æå»ºç»å½ç¨æ·ä¿¡æ¯ loginUser.setTenantId("0"); loginUser.setUserId(registerUser.getUserId()); loginUser.setUsername(registerUser.getUserName()); loginUser.setUserType(UserType.APP_USER.getUserType()); loginUser.setOpenid(openid); loginUser.setNickName(registerUser.getNickName()); } else { // æ¤å¤å¯æ ¹æ®ç»å½ç¨æ·çæ°æ®ä¸å èªè¡å建 loginUser loginUser.setTenantId(user.getTenantId()); loginUser.setUserId(user.getUserId()); loginUser.setUsername(user.getUserName()); loginUser.setUserType(user.getUserType()); loginUser.setNickName(user.getNickName()); loginUser.setAvatar(user.getWxAvatar()); loginUser.setOpenid(openid); } // çætoken LoginHelper.loginByDevice(loginUser, DeviceType.XCX); recordLogininfor(loginUser.getTenantId(), loginUser.getUsername(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")); LoginVo loginVo = new LoginVo(); // çæä»¤ç loginVo.setToken(StpUtil.getTokenValue()); loginVo.setUserInfo(loginUser); return loginVo; } /** * è®°å½ç»å½ä¿¡æ¯ * * @param tenantId ç§æ·ID * @param username ç¨æ·å * @param status ç¶æ * @param message æ¶æ¯å 容 */ private void recordLogininfor(String tenantId, String username, String status, String message) { LogininforEvent logininforEvent = new LogininforEvent(); logininforEvent.setTenantId(tenantId); logininforEvent.setUsername(username); logininforEvent.setStatus(status); logininforEvent.setMessage(message); logininforEvent.setRequest(ServletUtils.getRequest()); SpringUtils.context().publishEvent(logininforEvent); } } ruoyi-modules/ruoyi-wechat/src/main/java/org/ruoyi/service/WeixinUserService.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,10 @@ package org.ruoyi.service; public interface WeixinUserService { void checkSignature(String signature, String timestamp, String nonce); String handleWeixinMsg(String body); } ruoyi-modules/ruoyi-wechat/src/main/java/org/ruoyi/service/impl/WeixinUserServiceImpl.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,65 @@ package org.ruoyi.service.impl; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.digest.DigestUtils; import org.ruoyi.domin.ReceiveMessage; import org.ruoyi.service.WeixinUserService; import org.ruoyi.util.WeixinMsgUtil; import org.ruoyi.util.WeixinQrCodeCacheUtil; import org.springframework.stereotype.Service; import java.util.Arrays; @Slf4j @Service public class WeixinUserServiceImpl implements WeixinUserService { private String token = "panda"; @Override public void checkSignature(String signature, String timestamp, String nonce) { String[] arr = new String[] {token, timestamp, nonce}; Arrays.sort(arr); StringBuilder content = new StringBuilder(); for (String str : arr) { content.append(str); } String tmpStr = DigestUtils.sha1Hex(content.toString()); if (tmpStr.equals(signature)) { log.info("check success"); return; } log.error("check fail"); throw new RuntimeException("check fail"); } @Override public String handleWeixinMsg(String requestBody) { ReceiveMessage receiveMessage = WeixinMsgUtil.msgToReceiveMessage(requestBody); // æ«ç ç»å½ if (WeixinMsgUtil.isScanQrCode(receiveMessage)) { return handleScanLogin(receiveMessage); } // å ³æ³¨ if (WeixinMsgUtil.isEventAndSubscribe(receiveMessage)) { return receiveMessage.getReplyTextMsg("æè°¢æ¨çå ³æ³¨ï¼"); } return receiveMessage.getReplyTextMsg("æ¶å°ï¼èªå¨åå¤ï¼"); } /** * å¤çæ«ç ç»å½ * * @param receiveMessage * @return */ private String handleScanLogin(ReceiveMessage receiveMessage) { String qrCodeTicket = WeixinMsgUtil.getQrCodeTicket(receiveMessage); if (WeixinQrCodeCacheUtil.get(qrCodeTicket) == null) { String openId = receiveMessage.getFromUserName(); WeixinQrCodeCacheUtil.put(qrCodeTicket, openId); } return receiveMessage.getReplyTextMsg("ä½ å·²æåç»å½ï¼"); } } ruoyi-modules/ruoyi-wechat/src/main/java/org/ruoyi/util/KeyUtils.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,24 @@ package org.ruoyi.util; import org.apache.commons.lang3.RandomStringUtils; import java.util.UUID; /** * @author https://www.wdbyte.com */ public class KeyUtils { public synchronized static String key6() { return RandomStringUtils.randomAlphanumeric(6); } public synchronized static String key16() { return RandomStringUtils.randomAlphanumeric(16); } public static String uuid32() { return UUID.randomUUID().toString().replace("-", ""); } } ruoyi-modules/ruoyi-wechat/src/main/java/org/ruoyi/util/WeixinApiUtil.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,81 @@ package org.ruoyi.util; import cn.hutool.http.HttpUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.ruoyi.common.core.service.ConfigService; import org.ruoyi.domin.WeixinQrCode; import org.springframework.stereotype.Component; import java.net.URI; import java.time.LocalDateTime; /** * @author https://www.wdbyte.com */ @Slf4j @Component @RequiredArgsConstructor public class WeixinApiUtil { private final ConfigService configService; private static String QR_CODE_URL_PREFIX = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket="; private static String ACCESS_TOKEN = null; private static LocalDateTime ACCESS_TOKEN_EXPIRE_TIME = null; /** * äºç»´ç Ticket è¿ææ¶é´ */ private static int QR_CODE_TICKET_TIMEOUT = 10 * 60; /** * è·å access token * * @return */ public synchronized String getAccessToken() { if (ACCESS_TOKEN != null && ACCESS_TOKEN_EXPIRE_TIME.isAfter(LocalDateTime.now())) { return ACCESS_TOKEN; } String api = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + getKey("appid") + "&secret=" + getKey("secret"); String result = HttpUtil.get(api); JSONObject jsonObject = JSON.parseObject(result); ACCESS_TOKEN = jsonObject.getString("access_token"); ACCESS_TOKEN_EXPIRE_TIME = LocalDateTime.now().plusSeconds(jsonObject.getLong("expires_in") - 10); return ACCESS_TOKEN; } /** * è·åäºç»´ç Ticket * * https://developers.weixin.qq.com/doc/offiaccount/Account_Management/Generating_a_Parametric_QR_Code.html * * @return */ public WeixinQrCode getQrCode() { String api = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" + getAccessToken(); String jsonBody = String.format("{\n" + " \"expire_seconds\": %d,\n" + " \"action_name\": \"QR_STR_SCENE\",\n" + " \"action_info\": {\n" + " \"scene\": {\n" + " \"scene_str\": \"%s\"\n" + " }\n" + " }\n" + "}", QR_CODE_TICKET_TIMEOUT, KeyUtils.uuid32()); String result = HttpUtil.post(api, jsonBody); log.info("get qr code params:{}", jsonBody); log.info("get qr code result:{}", result); WeixinQrCode weixinQrCode = JSON.parseObject(result, WeixinQrCode.class); weixinQrCode.setQrCodeUrl(QR_CODE_URL_PREFIX + URI.create(weixinQrCode.getTicket()).toASCIIString()); return weixinQrCode; } public String getKey(String key) { return configService.getConfigValue("weixin", key); } } ruoyi-modules/ruoyi-wechat/src/main/java/org/ruoyi/util/WeixinMsgUtil.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,66 @@ package org.ruoyi.util; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import org.apache.commons.lang3.StringUtils; import org.ruoyi.domin.ReceiveMessage; /** * @author https://www.wdbyte.com */ public class WeixinMsgUtil { // äºä»¶-å ³æ³¨ private static String EVENT_SUBSCRIBE = "subscribe"; /** * å¾®ä¿¡æ¶æ¯è½¬å¯¹è±¡ * * @param xml * @return */ public static ReceiveMessage msgToReceiveMessage(String xml) { JSONObject jsonObject = JSON.parseObject(XmlUtil.xml2json(xml)); ReceiveMessage receiveMessage = new ReceiveMessage(); receiveMessage.setToUserName(jsonObject.getString("ToUserName")); receiveMessage.setFromUserName(jsonObject.getString("FromUserName")); receiveMessage.setCreateTime(jsonObject.getString("CreateTime")); receiveMessage.setMsgType(jsonObject.getString("MsgType")); receiveMessage.setContent(jsonObject.getString("Content")); receiveMessage.setMsgId(jsonObject.getString("MsgId")); receiveMessage.setEvent(jsonObject.getString("Event")); receiveMessage.setTicket(jsonObject.getString("Ticket")); return receiveMessage; } /** * æ¯å¦æ¯è®¢é äºä»¶ * * @param receiveMessage * @return */ public static boolean isEventAndSubscribe(ReceiveMessage receiveMessage) { return StringUtils.equals(receiveMessage.getEvent(), EVENT_SUBSCRIBE); } /** * æ¯å¦æ¯äºç»´ç æ«æäºä»¶ * * @param receiveMessage * @return */ public static boolean isScanQrCode(ReceiveMessage receiveMessage) { return StringUtils.isNotEmpty(receiveMessage.getTicket()); } /** * è·åæ«æçäºç»´ç Ticket * * @param receiveMessage * @return */ public static String getQrCodeTicket(ReceiveMessage receiveMessage) { return receiveMessage.getTicket(); } } ruoyi-modules/ruoyi-wechat/src/main/java/org/ruoyi/util/WeixinQrCodeCacheUtil.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,34 @@ package org.ruoyi.util; import java.util.LinkedHashMap; /** * 微信äºç»´ç ç¼åå·¥å ·ç±» * * @author https://www.wdbyte.com */ public class WeixinQrCodeCacheUtil { private static long MAX_CACHE_SIZE = 10000; private static LinkedHashMap<String, String> QR_CODE_TICKET_MAP = new LinkedHashMap<>(); /** * å¢å ä¸ä¸ª Ticket * 馿¬¡ putï¼value 为 "" * 忬¡ put: value æ openIdï¼è¥openIdå·²ç»åå¨ï¼å已被æ«ç * * @param key * @param value */ public synchronized static void put(String key, String value) { QR_CODE_TICKET_MAP.put(key, value); if (QR_CODE_TICKET_MAP.size() > MAX_CACHE_SIZE) { String first = QR_CODE_TICKET_MAP.keySet().stream().findFirst().get(); QR_CODE_TICKET_MAP.remove(first); } } public synchronized static String get(String key) { return QR_CODE_TICKET_MAP.remove(key); } } ruoyi-modules/ruoyi-wechat/src/main/java/org/ruoyi/util/XmlUtil.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,28 @@ package org.ruoyi.util; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.xml.XmlMapper; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; /** * @author https://www.wdbyte.com */ @Slf4j public class XmlUtil { public static String xml2json(String requestBody) { requestBody = StringUtils.trim(requestBody); XmlMapper xmlMapper = new XmlMapper(); JsonNode node = null; try { node = xmlMapper.readTree(requestBody.getBytes()); ObjectMapper jsonMapper = new ObjectMapper(); return jsonMapper.writeValueAsString(node); } catch (Exception e) { log.error("xml 2 json error,msg:" + e.getMessage(), e); } return null; } }