From 97b735757d67484cab28ddb3cddcb80bdd9ff0c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E5=BF=A0=E6=9E=97?= <170083662@qq.com> Date: Mon, 6 Apr 2026 21:54:14 +0800 Subject: [PATCH] =?UTF-8?q?refactor(wxOfficial):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E5=85=AC=E4=BC=97=E5=8F=B7=E9=85=8D=E7=BD=AE=E5=92=8Caccess=5F?= =?UTF-8?q?token=E8=8E=B7=E5=8F=96=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 增加SettingService和WxService注入,提高配置获取灵活性 - 将access_token获取方法重载,支持按租户动态读取 - 新增getOfficialToken、getOfficialEncodingAESKey、getOfficialAppId方法,从系统设置读取配置 - 解密消息时改用动态获取的token、EncodingAESKey和AppId - 微信用户信息请求改为支持按租户获取access_token - access_token获取失败时添加异常日志并回退到兼容逻辑 - 移除硬编码逻辑,增强配置读取的可扩展性与健壮性 --- .../controller/WxOfficialController.java | 61 ++++++++++++++++--- 1 file changed, 51 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/gxwebsoft/common/system/controller/WxOfficialController.java b/src/main/java/com/gxwebsoft/common/system/controller/WxOfficialController.java index 28afc25..4b1dedb 100644 --- a/src/main/java/com/gxwebsoft/common/system/controller/WxOfficialController.java +++ b/src/main/java/com/gxwebsoft/common/system/controller/WxOfficialController.java @@ -24,10 +24,12 @@ import com.gxwebsoft.common.system.entity.*; import com.gxwebsoft.common.system.param.RoleParam; import com.gxwebsoft.common.system.param.UserParam; import com.gxwebsoft.common.system.service.RoleService; +import com.gxwebsoft.common.system.service.SettingService; import com.gxwebsoft.common.system.service.UserOauthService; import com.gxwebsoft.common.system.service.UserRoleService; import com.gxwebsoft.common.system.service.UserService; import com.gxwebsoft.common.system.service.UserSyncService; +import com.gxwebsoft.common.system.service.WxService; import com.gxwebsoft.common.system.vo.WxOfficialButton; import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.Operation; @@ -88,6 +90,10 @@ public class WxOfficialController extends BaseController { @Resource private UserOauthService userOauthService; @Resource + private SettingService settingService; + @Resource + private WxService wxService; + @Resource private RedisUtil redisUtil; @Operation(summary = "验证微信服务器") @@ -98,7 +104,7 @@ public class WxOfficialController extends BaseController { if (tenantId == null) { return null; } - String token = TOKEN; + String token = getOfficialToken(); String[] array = new String[]{token, timestamp, nonce}; // 将token、timestamp、nonce三个参数进行字典序排序 Arrays.sort(array); @@ -133,7 +139,7 @@ public class WxOfficialController extends BaseController { // 如果有加密参数,进行解密 if (StrUtil.isNotBlank(msg_signature) && StrUtil.isNotBlank(xmlData) && xmlData.contains("Encrypt")) { try { - WXBizJsonMsgCrypt crypt = new WXBizJsonMsgCrypt(TOKEN, ENCODING_AES_KEY, ""); + WXBizJsonMsgCrypt crypt = new WXBizJsonMsgCrypt(getOfficialToken(), getOfficialEncodingAESKey(), getOfficialAppId(tenantId)); xmlData = crypt.DecryptMsg(msg_signature, timestamp, nonce, xmlData); System.out.println("解密后xmlData = " + xmlData); } catch (Exception e) { @@ -189,7 +195,7 @@ public class WxOfficialController extends BaseController { // 获取用户信息 if (StrUtil.isNotBlank(openId)) { // 获取用户基本信息(UnionID机制) - final String userStr = HttpUtil.get("https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + getAccessToken() + "&openid=" + openId + "&lang=zh_CN"); + final String userStr = HttpUtil.get("https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + getAccessToken(tenantId) + "&openid=" + openId + "&lang=zh_CN"); final JSONObject jsonObject = JSONObject.parseObject(userStr); final String unionid = jsonObject.getString("unionid"); final String subscribe = jsonObject.getString("subscribe"); @@ -451,30 +457,65 @@ public class WxOfficialController extends BaseController { // 调用接口凭证 private String getAccessToken() { + return getAccessToken(null); + } + + private String getAccessToken(Integer tenantId) { + try { + return wxService.getOfficialAccessToken(tenantId); + } catch (Exception ex) { + log.warn("从系统设置获取公众号access_token失败,回退到兼容逻辑: {}", ex.getMessage()); + } + String key = MP_OFFICIAL.concat(":access_token:5"); - // 从缓存获取access_token String value = redisUtil.get(key); if (value != null) { - // 解析access_token JSONObject response = JSON.parseObject(value); return response.getString("access_token"); } - // 微信获取凭证接口https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET + String apiUrl = "https://api.weixin.qq.com/cgi-bin/token"; - // 组装url参数 String url = apiUrl.concat("?grant_type=client_credential").concat("&appid=").concat(appid).concat("&secret=").concat(secret); - // 执行get请求 String result = HttpUtil.get(url); - // 解析access_token JSONObject response = JSON.parseObject(result); if (response.getString("access_token") != null) { - // 存入缓存 redisUtil.set(key, result, 7000L, TimeUnit.SECONDS); return response.getString("access_token"); } return null; } + private String getOfficialToken() { + try { + JSONObject config = settingService.getBySettingKey("wx-official"); + String token = config.getString("token"); + return StrUtil.isNotBlank(token) ? token : TOKEN; + } catch (Exception ex) { + log.warn("读取公众号token配置失败,回退到硬编码值: {}", ex.getMessage()); + return TOKEN; + } + } + + private String getOfficialEncodingAESKey() { + try { + JSONObject config = settingService.getBySettingKey("wx-official"); + String encodingAESKey = config.getString("encodingAESKey"); + return StrUtil.isNotBlank(encodingAESKey) ? encodingAESKey : ENCODING_AES_KEY; + } catch (Exception ex) { + log.warn("读取公众号EncodingAESKey配置失败,回退到硬编码值: {}", ex.getMessage()); + return ENCODING_AES_KEY; + } + } + + private String getOfficialAppId(Integer tenantId) { + try { + return wxService.getOfficialAppId(tenantId); + } catch (Exception ex) { + log.warn("读取公众号AppId配置失败,回退到硬编码值: {}", ex.getMessage()); + return appid; + } + } + @Operation(summary = "创建公众号菜单接口") @PostMapping("/createMenu") public ApiResult createMenu() {