# Conflicts:
#	yudao-dependencies/pom.xml
#	yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientService.java
#	yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientServiceImpl.java
#	yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImpl.java
#	yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/social/SocialClientServiceImplTest.java
#	yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImplTest.java
pull/180/MERGE
YunaiV 2025-04-30 11:27:57 +08:00
commit d4f1971acd
18 changed files with 422 additions and 69 deletions

View File

@ -81,7 +81,8 @@
<commons-io.version>2.17.0</commons-io.version>
<commons-compress.version>1.27.1</commons-compress.version>
<awssdk.version>2.30.14</awssdk.version>
<justauth.version>1.0.8</justauth.version>
<justauth.version>1.16.7</justauth.version>
<justauth-starter.version>1.4.0</justauth-starter.version>
<jimureport.version>1.7.8</jimureport.version>
<weixin-java.version>4.7.2.B</weixin-java.version>
<!-- 专属于 JDK8 安全漏洞升级 -->
@ -582,22 +583,6 @@
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>cn.smallbun.screw</groupId>
<artifactId>screw-core</artifactId> <!-- 实现数据库文档 -->
<version>${screw.version}</version>
<exclusions>
<exclusion>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId> <!-- 移除 Freemarker 依赖,采用 Velocity 作为模板引擎 -->
</exclusion>
<exclusion>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId> <!-- 最新版screw-core1.0.5依赖fastjson1.2.73存在漏洞,移除。 -->
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
@ -669,15 +654,14 @@
</dependency>
<dependency>
<groupId>com.xingyuv</groupId>
<artifactId>spring-boot-starter-justauth</artifactId> <!-- 社交登陆(例如说,个人微信、企业微信等等) -->
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId> <!-- 社交登陆(例如说,个人微信、企业微信等等) -->
<version>${justauth.version}</version>
<exclusions>
<exclusion>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.xkcoding.justauth</groupId>
<artifactId>justauth-spring-boot-starter</artifactId>
<version>${justauth-starter.version}</version>
</dependency>
<!-- 积木报表-->

View File

@ -135,7 +135,7 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService {
private Long createPayTransfer(BrokerageWithdrawDO withdraw) {
// 1.1 获取微信 openid
SocialUserRespDTO socialUser = socialUserApi.getSocialUserByUserId(
UserTypeEnum.MEMBER.getValue(), withdraw.getUserId(), SocialTypeEnum.WECHAT_MINI_APP.getType()).getCheckedData();
UserTypeEnum.MEMBER.getValue(), withdraw.getUserId(), SocialTypeEnum.WECHAT_MINI_PROGRAM.getType()).getCheckedData();
// TODO @luchi这里需要校验非空。如果空的话要有业务异常哈
// 1.2 构建请求
PayTransferCreateReqDTO payTransferCreateReqDTO = new PayTransferCreateReqDTO()

View File

@ -146,7 +146,7 @@ public class MemberAuthServiceImpl implements MemberAuthService {
// 绑定社交用户
String openid = socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(),
SocialTypeEnum.WECHAT_MINI_APP.getType(), reqVO.getLoginCode(), reqVO.getState())).getCheckedData();
SocialTypeEnum.WECHAT_MINI_PROGRAM.getType(), reqVO.getLoginCode(), reqVO.getState())).getCheckedData();
// 创建 Token 令牌,记录登录日志
return createTokenAfterLoginSuccess(user, user.getMobile(), LoginLogTypeEnum.LOGIN_SOCIAL, openid);

View File

@ -52,7 +52,7 @@ public enum SocialTypeEnum implements ArrayValuable<Integer> {
*
* @see <a href="https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html"></a>
*/
WECHAT_MINI_APP(34, "WECHAT_MINI_APP"),
WECHAT_MINI_PROGRAM(34, "WECHAT_MINI_PROGRAM"),
;
public static final Integer[] ARRAYS = Arrays.stream(values()).map(SocialTypeEnum::getType).toArray(Integer[]::new);

View File

@ -129,8 +129,12 @@
<!-- 三方云服务相关 -->
<dependency>
<groupId>com.xingyuv</groupId>
<artifactId>spring-boot-starter-justauth</artifactId> <!-- 社交登陆(例如说,个人微信、企业微信等等) -->
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId> <!-- 社交登陆(例如说,个人微信、企业微信等等) -->
</dependency>
<dependency>
<groupId>com.xkcoding.justauth</groupId>
<artifactId>justauth-spring-boot-starter</artifactId>
</dependency>
<dependency>

View File

@ -85,7 +85,7 @@ public class SocialClientApiImpl implements SocialClientApi {
// 2. 获得社交用户
SocialUserRespDTO socialUser = socialUserService.getSocialUserByUserId(reqDTO.getUserType(), reqDTO.getUserId(),
SocialTypeEnum.WECHAT_MINI_APP.getType());
SocialTypeEnum.WECHAT_MINI_PROGRAM.getType());
if (StrUtil.isBlankIfStr(socialUser.getOpenid())) {
log.warn("[sendWxaSubscribeMessage][reqDTO({}) 发送订阅消息失败,原因:会员 openid 缺失]", reqDTO);
return success(false);

View File

@ -7,8 +7,8 @@ import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.xingyuv.jushauth.config.AuthConfig;
import lombok.*;
import me.zhyd.oauth.config.AuthConfig;
/**
* DO

View File

@ -0,0 +1,39 @@
package cn.iocoder.yudao.module.system.framework.justauth.config;
import cn.iocoder.yudao.module.system.framework.justauth.core.AuthRequestFactory;
import com.xkcoding.justauth.autoconfigure.JustAuthProperties;
import com.xkcoding.justauth.support.cache.RedisStateCache;
import me.zhyd.oauth.cache.AuthStateCache;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
/**
* JustAuth TODO justauth 1.4.1
*
* @author
*/
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties({JustAuthProperties.class})
public class YudaoJustAuthConfiguration {
@Bean
@ConditionalOnProperty(
prefix = "justauth",
value = {"enabled"},
havingValue = "true",
matchIfMissing = true
)
public AuthRequestFactory authRequestFactory(JustAuthProperties properties, AuthStateCache authStateCache) {
return new AuthRequestFactory(properties, authStateCache);
}
@Bean
public AuthStateCache authStateCache(RedisTemplate<String, String> justAuthRedisCacheTemplate,
JustAuthProperties justAuthProperties) {
return new RedisStateCache(justAuthRedisCacheTemplate, justAuthProperties.getCache());
}
}

View File

@ -0,0 +1,321 @@
/*
* Copyright (c) 2019-2029, xkcoding & Yangkai.Shen & (237497819@qq.com & xkcoding.com).
* <p>
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package cn.iocoder.yudao.module.system.framework.justauth.core;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.EnumUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.xkcoding.http.config.HttpConfig;
import com.xkcoding.justauth.autoconfigure.ExtendProperties;
import com.xkcoding.justauth.autoconfigure.JustAuthProperties;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.enums.AuthResponseStatus;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.request.*;
import org.springframework.util.CollectionUtils;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
// TODO @芋艿:等官方发布 1.4.1
/**
* <p>
* AuthRequest
* </p>
*
* @author yangkai.shen
* @date Created in 2019-07-22 14:21
*/
@Slf4j
@RequiredArgsConstructor
public class AuthRequestFactory {
private final JustAuthProperties properties;
private final AuthStateCache authStateCache;
/**
* Oauth
*
* @return Oauth
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public List<String> oauthList() {
// 默认列表
List<String> defaultList = new ArrayList<>(properties.getType().keySet());
// 扩展列表
List<String> extendList = new ArrayList<>();
ExtendProperties extend = properties.getExtend();
if (null != extend) {
Class enumClass = extend.getEnumClass();
List<String> names = EnumUtil.getNames(enumClass);
// 扩展列表
extendList = extend.getConfig()
.keySet()
.stream()
.filter(x -> names.contains(x.toUpperCase()))
.map(String::toUpperCase)
.collect(Collectors.toList());
}
// 合并
return (List<String>) CollUtil.addAll(defaultList, extendList);
}
/**
* AuthRequest
*
* @param source {@link AuthSource}
* @return {@link AuthRequest}
*/
public AuthRequest get(String source) {
if (StrUtil.isBlank(source)) {
throw new AuthException(AuthResponseStatus.NO_AUTH_SOURCE);
}
// 获取 JustAuth 中已存在的
AuthRequest authRequest = getDefaultRequest(source);
// 如果获取不到则尝试取自定义的
if (authRequest == null) {
authRequest = getExtendRequest(properties.getExtend().getEnumClass(), source);
}
if (authRequest == null) {
throw new AuthException(AuthResponseStatus.UNSUPPORTED);
}
return authRequest;
}
/**
* request
*
* @param clazz {@link AuthSource}
* @param source {@link AuthSource}
* @return {@link AuthRequest}
*/
@SuppressWarnings({"unchecked", "rawtypes"})
private AuthRequest getExtendRequest(Class clazz, String source) {
String upperSource = source.toUpperCase();
try {
EnumUtil.fromString(clazz, upperSource);
} catch (IllegalArgumentException e) {
// 无自定义匹配
return null;
}
Map<String, ExtendProperties.ExtendRequestConfig> extendConfig = properties.getExtend().getConfig();
// key 转大写
Map<String, ExtendProperties.ExtendRequestConfig> upperConfig = new HashMap<>(6);
extendConfig.forEach((k, v) -> upperConfig.put(k.toUpperCase(), v));
ExtendProperties.ExtendRequestConfig extendRequestConfig = upperConfig.get(upperSource);
if (extendRequestConfig != null) {
// 配置 http config
configureHttpConfig(upperSource, extendRequestConfig, properties.getHttpConfig());
Class<? extends AuthRequest> requestClass = extendRequestConfig.getRequestClass();
if (requestClass != null) {
// 反射获取 Request 对象,所以必须实现 2 个参数的构造方法
return ReflectUtil.newInstance(requestClass, (AuthConfig) extendRequestConfig, authStateCache);
}
}
return null;
}
/**
* Request
*
* @param source {@link AuthSource}
* @return {@link AuthRequest}
*/
private AuthRequest getDefaultRequest(String source) {
AuthDefaultSource authDefaultSource;
try {
authDefaultSource = EnumUtil.fromString(AuthDefaultSource.class, source.toUpperCase());
} catch (IllegalArgumentException e) {
// 无自定义匹配
return null;
}
AuthConfig config = properties.getType().get(authDefaultSource.name());
// 找不到对应关系,直接返回空
if (config == null) {
return null;
}
// 配置 http config
configureHttpConfig(authDefaultSource.name(), config, properties.getHttpConfig());
switch (authDefaultSource) {
case GITHUB:
return new AuthGithubRequest(config, authStateCache);
case WEIBO:
return new AuthWeiboRequest(config, authStateCache);
case GITEE:
return new AuthGiteeRequest(config, authStateCache);
case DINGTALK:
return new AuthDingTalkRequest(config, authStateCache);
case DINGTALK_V2:
return new AuthDingTalkV2Request(config, authStateCache);
case DINGTALK_ACCOUNT:
return new AuthDingTalkAccountRequest(config, authStateCache);
case BAIDU:
return new AuthBaiduRequest(config, authStateCache);
case CSDN:
return new AuthCsdnRequest(config, authStateCache);
case CODING:
return new AuthCodingRequest(config, authStateCache);
case OSCHINA:
return new AuthOschinaRequest(config, authStateCache);
case ALIPAY:
return new AuthAlipayRequest(config, authStateCache);
case QQ:
return new AuthQqRequest(config, authStateCache);
case WECHAT_OPEN:
return new AuthWeChatOpenRequest(config, authStateCache);
case WECHAT_MP:
return new AuthWeChatMpRequest(config, authStateCache);
case TAOBAO:
return new AuthTaobaoRequest(config, authStateCache);
case GOOGLE:
return new AuthGoogleRequest(config, authStateCache);
case FACEBOOK:
return new AuthFacebookRequest(config, authStateCache);
case DOUYIN:
return new AuthDouyinRequest(config, authStateCache);
case LINKEDIN:
return new AuthLinkedinRequest(config, authStateCache);
case MICROSOFT:
return new AuthMicrosoftRequest(config, authStateCache);
case MICROSOFT_CN:
return new AuthMicrosoftCnRequest(config, authStateCache);
case MI:
return new AuthMiRequest(config, authStateCache);
case TOUTIAO:
return new AuthToutiaoRequest(config, authStateCache);
case TEAMBITION:
return new AuthTeambitionRequest(config, authStateCache);
case RENREN:
return new AuthRenrenRequest(config, authStateCache);
case PINTEREST:
return new AuthPinterestRequest(config, authStateCache);
case STACK_OVERFLOW:
return new AuthStackOverflowRequest(config, authStateCache);
case HUAWEI:
return new AuthHuaweiRequest(config, authStateCache);
case HUAWEI_V3:
return new AuthHuaweiV3Request(config, authStateCache);
case WECHAT_ENTERPRISE:
return new AuthWeChatEnterpriseQrcodeRequest(config, authStateCache);
case WECHAT_ENTERPRISE_V2:
return new AuthWeChatEnterpriseQrcodeV2Request(config, authStateCache);
case WECHAT_ENTERPRISE_QRCODE_THIRD:
return new AuthWeChatEnterpriseThirdQrcodeRequest(config, authStateCache);
case WECHAT_ENTERPRISE_WEB:
return new AuthWeChatEnterpriseWebRequest(config, authStateCache);
case KUJIALE:
return new AuthKujialeRequest(config, authStateCache);
case GITLAB:
return new AuthGitlabRequest(config, authStateCache);
case MEITUAN:
return new AuthMeituanRequest(config, authStateCache);
case ELEME:
return new AuthElemeRequest(config, authStateCache);
case TWITTER:
return new AuthTwitterRequest(config, authStateCache);
case FEISHU:
return new AuthFeishuRequest(config, authStateCache);
case JD:
return new AuthJdRequest(config, authStateCache);
case ALIYUN:
return new AuthAliyunRequest(config, authStateCache);
case XMLY:
return new AuthXmlyRequest(config, authStateCache);
case AMAZON:
return new AuthAmazonRequest(config, authStateCache);
case SLACK:
return new AuthSlackRequest(config, authStateCache);
case LINE:
return new AuthLineRequest(config, authStateCache);
case OKTA:
return new AuthOktaRequest(config, authStateCache);
case PROGINN:
return new AuthProginnRequest(config,authStateCache);
case AFDIAN:
return new AuthAfDianRequest(config,authStateCache);
case APPLE:
return new AuthAppleRequest(config,authStateCache);
case FIGMA:
return new AuthFigmaRequest(config,authStateCache);
case WECHAT_MINI_PROGRAM:
config.setIgnoreCheckRedirectUri(true);
config.setIgnoreCheckState(true);
return new AuthWechatMiniProgramRequest(config, authStateCache);
case QQ_MINI_PROGRAM:
config.setIgnoreCheckRedirectUri(true);
config.setIgnoreCheckState(true);
return new AuthQQMiniProgramRequest(config, authStateCache);
default:
return null;
}
}
/**
* http
*
* @param authSource {@link AuthSource}
* @param authConfig {@link AuthConfig}
*/
private void configureHttpConfig(String authSource, AuthConfig authConfig, JustAuthProperties.JustAuthHttpConfig httpConfig) {
if (null == httpConfig) {
return;
}
Map<String, JustAuthProperties.JustAuthProxyConfig> proxyConfigMap = httpConfig.getProxy();
if (CollectionUtils.isEmpty(proxyConfigMap)) {
return;
}
JustAuthProperties.JustAuthProxyConfig proxyConfig = proxyConfigMap.get(authSource);
if (null == proxyConfig) {
return;
}
authConfig.setHttpConfig(HttpConfig.builder()
.timeout(httpConfig.getTimeout())
.proxy(new Proxy(Proxy.Type.valueOf(proxyConfig.getType()), new InetSocketAddress(proxyConfig.getHostname(), proxyConfig.getPort())))
.build());
}
}

View File

@ -0,0 +1,6 @@
/**
* justauth
*
* @author
*/
package cn.iocoder.yudao.module.system.framework.justauth;

View File

@ -8,14 +8,13 @@ import cn.iocoder.yudao.module.system.controller.admin.socail.vo.client.SocialCl
import cn.iocoder.yudao.module.system.controller.admin.socail.vo.client.SocialClientSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialClientDO;
import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
import com.xingyuv.jushauth.model.AuthUser;
import jakarta.validation.Valid;
import me.chanjar.weixin.common.bean.WxJsapiSignature;
import me.chanjar.weixin.common.bean.subscribemsg.TemplateInfo;
import me.zhyd.oauth.model.AuthUser;
import java.util.List;
import javax.validation.Valid;
/**
* Service
*

View File

@ -26,18 +26,13 @@ import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialClientDO;
import cn.iocoder.yudao.module.system.dal.mysql.social.SocialClientMapper;
import cn.iocoder.yudao.module.system.dal.redis.RedisKeyConstants;
import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
import cn.iocoder.yudao.module.system.framework.justauth.core.AuthRequestFactory;
import com.binarywang.spring.starter.wxjava.miniapp.properties.WxMaProperties;
import com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.xingyuv.jushauth.config.AuthConfig;
import com.xingyuv.jushauth.model.AuthCallback;
import com.xingyuv.jushauth.model.AuthResponse;
import com.xingyuv.jushauth.model.AuthUser;
import com.xingyuv.jushauth.request.AuthRequest;
import com.xingyuv.jushauth.utils.AuthStateUtils;
import com.xingyuv.justauth.AuthRequestFactory;
import jakarta.annotation.Resource;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.WxJsapiSignature;
@ -47,12 +42,17 @@ import me.chanjar.weixin.common.redis.RedisTemplateWxRedisOps;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.config.impl.WxMpRedisConfigImpl;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.time.Duration;
import java.util.List;
import java.util.Map;
@ -337,7 +337,7 @@ public class SocialClientServiceImpl implements SocialClientService {
WxMaService getWxMaService(Integer userType) {
// 第一步,查询 DB 的配置项,获得对应的 WxMaService 对象
SocialClientDO client = socialClientMapper.selectBySocialTypeAndUserType(
SocialTypeEnum.WECHAT_MINI_APP.getType(), userType);
SocialTypeEnum.WECHAT_MINI_PROGRAM.getType(), userType);
if (client != null && Objects.equals(client.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
return wxMaServiceCache.getUnchecked(client.getClientId() + ":" + client.getClientSecret());
}

View File

@ -12,14 +12,14 @@ import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO;
import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserBindMapper;
import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserMapper;
import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
import com.xingyuv.jushauth.model.AuthUser;
import jakarta.annotation.Resource;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.model.AuthUser;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.Collections;
import java.util.List;

View File

@ -169,7 +169,7 @@ justauth:
agent-id: 1000004
ignore-check-redirect-uri: true
# noinspection SpringBootApplicationYaml
WECHAT_MINI_APP: # 微信小程序
WECHAT_MINI_PROGRAM: # 微信小程序
client-id: ${wx.miniapp.appid}
client-secret: ${wx.miniapp.secret}
ignore-check-redirect-uri: true

View File

@ -160,10 +160,10 @@ wx:
# secret: 333ae72f41552af1e998fe1f54e1584a
# appid: wx63c280fe3248a3e7 # wenhualian的接口测试号
# secret: 6f270509224a7ae1296bbf1c8cb97aed
# appid: wxc4598c446f8a9cb3 # 测试号Kongdy 提供的)
# secret: 4a1a04e07f6a4a0751b39c3064a92c8b
appid: wx66186af0759f47c9 # 测试号puhui 提供的)
secret: 3218bcbd112cbc614c7264ceb20144ac
appid: wxc4598c446f8a9cb3 # 测试号Kongdy 提供的)
secret: 4a1a04e07f6a4a0751b39c3064a92c8b
# appid: wx66186af0759f47c9 # 测试号puhui 提供的)
# secret: 3218bcbd112cbc614c7264ceb20144ac
config-storage:
type: RedisTemplate # 采用 RedisTemplate 操作 Redis会自动从 Spring 中获取
key-prefix: wa # Redis Key 的前缀
@ -199,7 +199,7 @@ justauth:
agent-id: 1000004
ignore-check-redirect-uri: true
# noinspection SpringBootApplicationYaml
WECHAT_MINI_APP: # 微信小程序
WECHAT_MINI_PROGRAM: # 微信小程序
client-id: ${wx.miniapp.appid}
client-secret: ${wx.miniapp.secret}
ignore-check-redirect-uri: true

View File

@ -13,26 +13,25 @@ import cn.iocoder.yudao.module.system.controller.admin.socail.vo.client.SocialCl
import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialClientDO;
import cn.iocoder.yudao.module.system.dal.mysql.social.SocialClientMapper;
import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
import cn.iocoder.yudao.module.system.framework.justauth.core.AuthRequestFactory;
import com.binarywang.spring.starter.wxjava.miniapp.properties.WxMaProperties;
import com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties;
import com.xingyuv.jushauth.config.AuthConfig;
import com.xingyuv.jushauth.model.AuthResponse;
import com.xingyuv.jushauth.model.AuthUser;
import com.xingyuv.jushauth.request.AuthDefaultRequest;
import com.xingyuv.jushauth.request.AuthRequest;
import com.xingyuv.jushauth.utils.AuthStateUtils;
import com.xingyuv.justauth.AuthRequestFactory;
import jakarta.annotation.Resource;
import me.chanjar.weixin.common.bean.WxJsapiSignature;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.AuthDefaultRequest;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import;
import org.springframework.data.redis.core.StringRedisTemplate;
import javax.annotation.Resource;
import static cn.hutool.core.util.RandomUtil.randomEle;
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
@ -103,7 +102,7 @@ public class SocialClientServiceImplTest extends BaseDbUnitTest {
when(authRequestFactory.get(eq("WECHAT_MP"))).thenReturn(authRequest);
// mock 方法AuthResponse
AuthUser authUser = randomPojo(AuthUser.class);
AuthResponse<?> authResponse = new AuthResponse<>(2000, null, authUser);
AuthResponse<AuthUser> authResponse = new AuthResponse<>(2000, null, authUser);
when(authRequest.login(argThat(authCallback -> {
assertEquals(code, authCallback.getCode());
assertEquals(state, authCallback.getState());
@ -127,7 +126,7 @@ public class SocialClientServiceImplTest extends BaseDbUnitTest {
AuthRequest authRequest = mock(AuthRequest.class);
when(authRequestFactory.get(eq("WECHAT_MP"))).thenReturn(authRequest);
// mock 方法AuthResponse
AuthResponse<?> authResponse = new AuthResponse<>(0, "模拟失败", null);
AuthResponse<AuthUser> authResponse = new AuthResponse<>(0, "模拟失败", null);
when(authRequest.login(argThat(authCallback -> {
assertEquals(code, authCallback.getCode());
assertEquals(state, authCallback.getState());
@ -291,7 +290,7 @@ public class SocialClientServiceImplTest extends BaseDbUnitTest {
// mock 方法
WxMaUserService userService = mock(WxMaUserService.class);
when(wxMaService.getUserService()).thenReturn(userService);
WxErrorException wxErrorException = randomPojo(WxErrorException.class);
WxErrorException wxErrorException = new WxErrorException(new NullPointerException());
when(userService.getPhoneNoInfo(eq(phoneCode))).thenThrow(wxErrorException);
// 调用并断言异常
@ -317,7 +316,7 @@ public class SocialClientServiceImplTest extends BaseDbUnitTest {
Integer userType = randomPojo(UserTypeEnum.class).getValue();
// mock 数据
SocialClientDO client = randomPojo(SocialClientDO.class, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())
.setUserType(userType).setSocialType(SocialTypeEnum.WECHAT_MINI_APP.getType()));
.setUserType(userType).setSocialType(SocialTypeEnum.WECHAT_MINI_PROGRAM.getType()));
socialClientMapper.insert(client);
// 调用
@ -332,7 +331,7 @@ public class SocialClientServiceImplTest extends BaseDbUnitTest {
Integer userType = randomPojo(UserTypeEnum.class).getValue();
// mock 数据
SocialClientDO client = randomPojo(SocialClientDO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus())
.setUserType(userType).setSocialType(SocialTypeEnum.WECHAT_MINI_APP.getType()));
.setUserType(userType).setSocialType(SocialTypeEnum.WECHAT_MINI_PROGRAM.getType()));
socialClientMapper.insert(client);
// mock 方法
WxMaProperties.ConfigStorage configStorage = mock(WxMaProperties.ConfigStorage.class);

View File

@ -11,12 +11,12 @@ import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO;
import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserBindMapper;
import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserMapper;
import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
import com.xingyuv.jushauth.model.AuthUser;
import jakarta.annotation.Resource;
import me.zhyd.oauth.model.AuthUser;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import;
import javax.annotation.Resource;
import java.util.List;
import static cn.hutool.core.util.RandomUtil.randomEle;

View File

@ -213,6 +213,7 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest {
UserProfileUpdateReqVO reqVO = randomPojo(UserProfileUpdateReqVO.class, o -> {
o.setMobile(randomString());
o.setSex(RandomUtil.randomEle(SexEnum.values()).getSex());
o.setAvatar(randomURL());
});
// 调用