```feat(redis): 微信小程序配置从缓存获取并支持Redis存储
- 新增 RedisConstants.MP_WX_KEY 常量用于微信小程序配置缓存键 - 修改 WxLoginController 中多处配置获取逻辑,使用 getWxConfigFromCache 方法替代原 DB 查询 - 移除 SettingMapper 和 SettingServiceImpl 中的跨租户数据库查询方法及相关逻辑 - 新增 getWxConfigFromCache 方法用于从 Redis 缓存中获取微信小程序配置 - 调整微信配置创建逻辑,直接写入 Redis 缓存而非数据库 - 优化错误提示信息,引导用户检查 Redis 缓存配置 - 同步更新 ShopDealerApply 实体及 Mapper XML,增加 phone 字段查询 ```
This commit is contained in:
@@ -24,6 +24,8 @@ public class RedisConstants {
|
||||
public static final String TEN_ANT_SETTING_KEY = "setting";
|
||||
// 排行榜Key
|
||||
public static final String USER_RANKING_BY_APPS_5 = "cache5:userRankingByApps";
|
||||
// 微信小程序Key
|
||||
public static final String MP_WX_KEY = "mp-weixin:";
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static com.gxwebsoft.common.core.constants.PlatformConstants.MP_WEIXIN;
|
||||
import static com.gxwebsoft.common.core.constants.RedisConstants.ACCESS_TOKEN_KEY;
|
||||
import static com.gxwebsoft.common.core.constants.RedisConstants.MP_WX_KEY;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/wx-login")
|
||||
@@ -224,8 +225,8 @@ public class WxLoginController extends BaseController {
|
||||
|
||||
// 获取openid
|
||||
private JSONObject getOpenIdByCode(UserParam userParam) {
|
||||
// 获取微信小程序配置信息
|
||||
JSONObject setting = settingService.getBySettingKey("mp-weixin", getTenantId());
|
||||
// 从缓存获取微信小程序配置信息
|
||||
JSONObject setting = getWxConfigFromCache(getTenantId());
|
||||
// 获取openId
|
||||
String apiUrl = "https://api.weixin.qq.com/sns/jscode2session?appid=" + setting.getString("appId") + "&secret=" + setting.getString("appSecret") + "&js_code=" + userParam.getCode() + "&grant_type=authorization_code";
|
||||
// 执行get请求
|
||||
@@ -282,8 +283,8 @@ public class WxLoginController extends BaseController {
|
||||
Integer tenantId = getTenantId();
|
||||
String key = ACCESS_TOKEN_KEY.concat(":").concat(tenantId.toString());
|
||||
|
||||
// 使用跨租户方式获取微信小程序配置信息
|
||||
JSONObject setting = settingService.getBySettingKeyIgnoreTenant("mp-weixin", tenantId);
|
||||
// 从缓存获取微信小程序配置信息
|
||||
JSONObject setting = getWxConfigFromCache(tenantId);
|
||||
if (setting == null) {
|
||||
throw new BusinessException("请先配置小程序");
|
||||
}
|
||||
@@ -332,7 +333,7 @@ public class WxLoginController extends BaseController {
|
||||
// 请求微信接口获取openid
|
||||
String apiUrl = "https://api.weixin.qq.com/sns/jscode2session";
|
||||
final HashMap<String, Object> map = new HashMap<>();
|
||||
final JSONObject setting = settingService.getBySettingKey("mp-weixin", getTenantId());
|
||||
final JSONObject setting = getWxConfigFromCache(getTenantId());
|
||||
final String appId = setting.getString("appId");
|
||||
final String appSecret = setting.getString("appSecret");
|
||||
map.put("appid", appId);
|
||||
@@ -360,7 +361,7 @@ public class WxLoginController extends BaseController {
|
||||
|
||||
String apiUrl = "https://api.weixin.qq.com/sns/jscode2session";
|
||||
final HashMap<String, Object> map = new HashMap<>();
|
||||
final JSONObject setting = settingService.getBySettingKey("mp-weixin", getTenantId());
|
||||
final JSONObject setting = getWxConfigFromCache(getTenantId());
|
||||
final String appId = setting.getString("appId");
|
||||
final String appSecret = setting.getString("appSecret");
|
||||
map.put("appid", appId);
|
||||
@@ -548,9 +549,9 @@ public class WxLoginController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
// 使用跨租户方式获取微信小程序配置信息
|
||||
// 从缓存获取微信小程序配置信息
|
||||
Integer tenantId = getTenantId();
|
||||
JSONObject setting = settingService.getBySettingKeyIgnoreTenant("mp-weixin", tenantId);
|
||||
JSONObject setting = getWxConfigFromCache(tenantId);
|
||||
if (setting == null) {
|
||||
throw new IOException("请先配置小程序");
|
||||
}
|
||||
@@ -576,7 +577,7 @@ public class WxLoginController extends BaseController {
|
||||
if (json.has("access_token")) {
|
||||
String token = json.get("access_token").asText();
|
||||
long expiresIn = json.get("expires_in").asInt(7200);
|
||||
|
||||
|
||||
// 缓存完整的JSON响应,与其他方法保持一致
|
||||
redisUtil.set(key, body, expiresIn, TimeUnit.SECONDS);
|
||||
tokenExpireEpoch = now + expiresIn;
|
||||
@@ -603,18 +604,20 @@ public class WxLoginController extends BaseController {
|
||||
result.put("tenantId", tenantId);
|
||||
|
||||
try {
|
||||
// 尝试获取配置
|
||||
JSONObject setting = settingService.getBySettingKeyIgnoreTenant("mp-weixin", tenantId);
|
||||
// 尝试从缓存获取配置
|
||||
JSONObject setting = getWxConfigFromCache(tenantId);
|
||||
result.put("hasConfig", true);
|
||||
result.put("config", setting);
|
||||
result.put("cacheKey", MP_WX_KEY + tenantId);
|
||||
} catch (Exception e) {
|
||||
result.put("hasConfig", false);
|
||||
result.put("error", e.getMessage());
|
||||
result.put("cacheKey", MP_WX_KEY + tenantId);
|
||||
|
||||
// 提供创建配置的建议
|
||||
Map<String, Object> suggestion = new HashMap<>();
|
||||
suggestion.put("message", "请在系统设置中创建微信小程序配置");
|
||||
suggestion.put("configKey", "mp-weixin");
|
||||
suggestion.put("message", "请在Redis中创建微信小程序配置");
|
||||
suggestion.put("cacheKey", MP_WX_KEY + tenantId);
|
||||
suggestion.put("tenantId", tenantId);
|
||||
suggestion.put("sampleConfig", createSampleWxConfig());
|
||||
result.put("suggestion", suggestion);
|
||||
@@ -636,23 +639,21 @@ public class WxLoginController extends BaseController {
|
||||
}
|
||||
|
||||
try {
|
||||
// 创建配置对象
|
||||
Setting setting = new Setting();
|
||||
setting.setSettingKey("mp-weixin");
|
||||
setting.setTenantId(tenantId);
|
||||
|
||||
// 直接在Redis中创建配置
|
||||
String key = MP_WX_KEY + tenantId;
|
||||
|
||||
// 创建配置内容
|
||||
Map<String, String> config = new HashMap<>();
|
||||
config.put("appId", appId);
|
||||
config.put("appSecret", appSecret);
|
||||
setting.setContent(JSON.toJSONString(config));
|
||||
setting.setComments("微信小程序配置");
|
||||
setting.setSortNumber(1);
|
||||
config.put("tenantId", tenantId.toString());
|
||||
config.put("settingKey", "mp-weixin");
|
||||
config.put("settingId", "301");
|
||||
|
||||
// 保存到Redis缓存
|
||||
redisUtil.set(key, JSON.toJSONString(config));
|
||||
|
||||
// 保存配置
|
||||
settingService.save(setting);
|
||||
|
||||
return success("微信小程序配置创建成功", setting);
|
||||
return success("微信小程序配置创建成功", config);
|
||||
} catch (Exception e) {
|
||||
return fail("创建配置失败: " + e.getMessage(), null);
|
||||
}
|
||||
@@ -674,15 +675,15 @@ public class WxLoginController extends BaseController {
|
||||
if (tenantId == null) {
|
||||
tenantId = 10550; // 默认租户
|
||||
}
|
||||
|
||||
|
||||
System.out.println("=== 开始调试获取AccessToken,租户ID: " + tenantId + " ===");
|
||||
|
||||
|
||||
// 手动调用获取AccessToken
|
||||
String accessToken = getAccessTokenForTenant(tenantId);
|
||||
|
||||
|
||||
String result = "获取AccessToken成功: " + (accessToken != null ? accessToken.substring(0, Math.min(10, accessToken.length())) + "..." : "null");
|
||||
System.out.println("调试结果: " + result);
|
||||
|
||||
|
||||
return success(result);
|
||||
} catch (Exception e) {
|
||||
System.err.println("调试获取AccessToken异常: " + e.getMessage());
|
||||
@@ -691,6 +692,24 @@ public class WxLoginController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从Redis缓存中获取微信小程序配置
|
||||
* @param tenantId 租户ID
|
||||
* @return 微信配置信息
|
||||
*/
|
||||
private JSONObject getWxConfigFromCache(Integer tenantId) {
|
||||
String key = MP_WX_KEY + tenantId;
|
||||
String cacheValue = redisUtil.get(key);
|
||||
if (StrUtil.isBlank(cacheValue)) {
|
||||
throw new BusinessException("未找到微信小程序配置,请检查缓存key: " + key);
|
||||
}
|
||||
try {
|
||||
return JSON.parseObject(cacheValue);
|
||||
} catch (Exception e) {
|
||||
throw new BusinessException("微信小程序配置格式错误: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从scene参数中提取租户ID
|
||||
* scene格式可能是: uid_33103 或其他包含用户ID的格式
|
||||
@@ -732,12 +751,6 @@ public class WxLoginController extends BaseController {
|
||||
try {
|
||||
String key = ACCESS_TOKEN_KEY.concat(":").concat(tenantId.toString());
|
||||
|
||||
// 使用跨租户方式获取微信小程序配置信息
|
||||
JSONObject setting = settingService.getBySettingKeyIgnoreTenant("mp-weixin", tenantId);
|
||||
if (setting == null) {
|
||||
throw new RuntimeException("租户 " + tenantId + " 的小程序未配置");
|
||||
}
|
||||
|
||||
// 从缓存获取access_token
|
||||
String value = redisUtil.get(key);
|
||||
if (value != null) {
|
||||
@@ -757,8 +770,9 @@ public class WxLoginController extends BaseController {
|
||||
}
|
||||
|
||||
// 缓存中没有,重新获取
|
||||
String appId = setting.getString("appId");
|
||||
String appSecret = setting.getString("appSecret");
|
||||
JSONObject wxConfig = getWxConfigFromCache(tenantId);
|
||||
String appId = wxConfig.getString("appId");
|
||||
String appSecret = wxConfig.getString("appSecret");
|
||||
|
||||
String apiUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + appSecret;
|
||||
System.out.println("调用微信API获取token - 租户ID: " + tenantId + ", AppID: " + (appId != null ? appId.substring(0, Math.min(8, appId.length())) + "..." : "null"));
|
||||
@@ -766,13 +780,13 @@ public class WxLoginController extends BaseController {
|
||||
String result = HttpUtil.get(apiUrl);
|
||||
System.out.println("微信API响应: " + result);
|
||||
JSONObject json = JSON.parseObject(result);
|
||||
|
||||
|
||||
// 检查是否有错误
|
||||
if (json.containsKey("errcode")) {
|
||||
Integer errcode = json.getInteger("errcode");
|
||||
String errmsg = json.getString("errmsg");
|
||||
System.err.println("微信API错误 - errcode: " + errcode + ", errmsg: " + errmsg);
|
||||
|
||||
|
||||
if (errcode == 40125) {
|
||||
throw new RuntimeException("微信AppSecret配置错误,请检查并更新正确的AppSecret");
|
||||
} else if (errcode == 40013) {
|
||||
|
||||
@@ -38,12 +38,4 @@ public interface SettingMapper extends BaseMapper<Setting> {
|
||||
@InterceptorIgnore(tenantLine = "true")
|
||||
Setting getBySettingKeyIgnore(@Param("param") SettingParam param);
|
||||
|
||||
/**
|
||||
* 跨库查询指定租户的设置配置
|
||||
* @param settingKey 设置键
|
||||
* @param tenantId 租户ID
|
||||
* @return Setting
|
||||
*/
|
||||
@InterceptorIgnore(tenantLine = "true")
|
||||
Setting getCrossDbSetting(@Param("settingKey") String settingKey, @Param("tenantId") Integer tenantId);
|
||||
}
|
||||
|
||||
@@ -30,13 +30,4 @@
|
||||
<include refid="selectSql"></include>
|
||||
</select>
|
||||
|
||||
<!-- 跨库查询指定租户的设置配置 -->
|
||||
<select id="getCrossDbSetting" resultType="com.gxwebsoft.common.system.entity.Setting">
|
||||
SELECT a.*
|
||||
FROM gxwebsoft_core.sys_setting a
|
||||
WHERE a.setting_key = #{settingKey}
|
||||
AND a.tenant_id = #{tenantId}
|
||||
AND a.deleted = 0
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -113,47 +113,7 @@ public class SettingServiceImpl extends ServiceImpl<SettingMapper, Setting> impl
|
||||
@Override
|
||||
@IgnoreTenant("跨租户获取指定租户的设置配置")
|
||||
public JSONObject getBySettingKeyIgnoreTenant(String key, Integer tenantId) {
|
||||
System.out.println("跨租户查询设置 - key: " + key + ", tenantId: " + tenantId);
|
||||
final List<Setting> list = list(new LambdaQueryWrapper<Setting>().eq(Setting::getTenantId, tenantId));
|
||||
System.out.println("跨租户获取指定租户的设置配置 list = " + list);
|
||||
|
||||
// 使用跨租户查询,指定租户ID - 通过XML方式查询跨库数据(方式二:更简洁的方法)
|
||||
Setting setting = baseMapper.getCrossDbSetting(key, tenantId);
|
||||
|
||||
System.out.println("跨租户查询结果: " + setting);
|
||||
|
||||
if(setting == null){
|
||||
if ("mp-weixin".equals(key)) {
|
||||
// 尝试从cms_website_field表中读取微信小程序配置
|
||||
JSONObject websiteFieldConfig = getWeixinConfigFromWebsiteField(tenantId);
|
||||
if (websiteFieldConfig != null) {
|
||||
System.out.println("从cms_website_field表获取到微信小程序配置: " + websiteFieldConfig);
|
||||
return websiteFieldConfig;
|
||||
}
|
||||
throw new BusinessException("租户 " + tenantId + " 的小程序未配置,请先在系统设置中配置微信小程序信息");
|
||||
}
|
||||
if ("payment".equals(key)) {
|
||||
throw new BusinessException("租户 " + tenantId + " 的支付未配置");
|
||||
}
|
||||
if ("sms".equals(key)) {
|
||||
throw new BusinessException("租户 " + tenantId + " 的短信未配置");
|
||||
}
|
||||
if ("wx-work".equals(key)){
|
||||
throw new BusinessException("租户 " + tenantId + " 的企业微信未配置");
|
||||
}
|
||||
if ("setting".equals(key)) {
|
||||
throw new BusinessException("租户 " + tenantId + " 的基本信息未配置");
|
||||
}
|
||||
if ("wx-official".equals(key)) {
|
||||
throw new BusinessException("租户 " + tenantId + " 的微信公众号未配置");
|
||||
}
|
||||
if ("printer".equals(key)) {
|
||||
throw new BusinessException("租户 " + tenantId + " 的打印机未配置");
|
||||
}
|
||||
throw new BusinessException("租户 " + tenantId + " 的配置项 " + key + " 未找到");
|
||||
}
|
||||
|
||||
return JSON.parseObject(setting.getContent());
|
||||
throw new BusinessException("此方法已废弃,请使用缓存方式获取配置:mp-weixin:" + tenantId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -235,55 +195,4 @@ public class SettingServiceImpl extends ServiceImpl<SettingMapper, Setting> impl
|
||||
return configMap.get(tenantId.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 从cms_website_field表中获取微信小程序配置
|
||||
* @param tenantId 租户ID
|
||||
* @return 微信小程序配置JSON对象
|
||||
*/
|
||||
private JSONObject getWeixinConfigFromWebsiteField(Integer tenantId) {
|
||||
try {
|
||||
System.out.println("尝试从cms_website_field表获取微信小程序配置 - 租户ID: " + tenantId);
|
||||
|
||||
// 查询AppID
|
||||
CmsWebsiteField appIdField = cmsWebsiteFieldService.getOne(
|
||||
new LambdaQueryWrapper<CmsWebsiteField>()
|
||||
.eq(CmsWebsiteField::getName, "AppID")
|
||||
.eq(CmsWebsiteField::getTenantId, tenantId)
|
||||
.eq(CmsWebsiteField::getDeleted, 0)
|
||||
);
|
||||
|
||||
// 查询AppSecret
|
||||
CmsWebsiteField appSecretField = cmsWebsiteFieldService.getOne(
|
||||
new LambdaQueryWrapper<CmsWebsiteField>()
|
||||
.eq(CmsWebsiteField::getName, "AppSecret")
|
||||
.eq(CmsWebsiteField::getTenantId, tenantId)
|
||||
.eq(CmsWebsiteField::getDeleted, 0)
|
||||
);
|
||||
|
||||
System.out.println("AppID字段查询结果: " + appIdField);
|
||||
System.out.println("AppSecret字段查询结果: " + appSecretField);
|
||||
|
||||
if (appIdField != null && appSecretField != null
|
||||
&& appIdField.getValue() != null && !appIdField.getValue().trim().isEmpty()
|
||||
&& appSecretField.getValue() != null && !appSecretField.getValue().trim().isEmpty()) {
|
||||
|
||||
// 构建微信小程序配置JSON
|
||||
JSONObject config = new JSONObject();
|
||||
config.put("appId", appIdField.getValue().trim());
|
||||
config.put("appSecret", appSecretField.getValue().trim());
|
||||
|
||||
System.out.println("成功从cms_website_field表构建微信小程序配置: " + config);
|
||||
return config;
|
||||
} else {
|
||||
System.out.println("cms_website_field表中未找到完整的AppID和AppSecret配置");
|
||||
return null;
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("从cms_website_field表获取微信小程序配置异常: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,6 +38,10 @@ public class ShopDealerApply implements Serializable {
|
||||
@TableField(exist = false)
|
||||
private String nickName;
|
||||
|
||||
@Schema(description = "手机号码")
|
||||
@TableField(exist = false)
|
||||
private String phone;
|
||||
|
||||
@Schema(description = "姓名")
|
||||
private String realName;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
<!-- 关联查询sql -->
|
||||
<sql id="selectSql">
|
||||
SELECT a.*, b.nickname as nickName, c.nickname as refereeName
|
||||
SELECT a.*, b.nickname as nickName, b.phone, c.nickname as refereeName
|
||||
FROM shop_dealer_apply a
|
||||
LEFT JOIN gxwebsoft_core.sys_user b ON a.user_id = b.user_id
|
||||
LEFT JOIN gxwebsoft_core.sys_user c ON a.referee_id = c.user_id
|
||||
|
||||
Reference in New Issue
Block a user