Merge branch 'develop' of https://gitee.com/zhijiantianya/ruoyi-vue-pro
# Conflicts: # yudao-dependencies/pom.xml # yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/firmware/IotOtaFirmwareCreateReqVO.java # yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/firmware/IotOtaFirmwareUpdateReqVO.java # yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/upgrade/record/IotOtaUpgradeRecordPageReqVO.java # yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/ota/vo/upgrade/task/IotOtaUpgradeTaskPageReqVO.java # yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleServiceImpl.java # yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java # 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
This commit is contained in:
@@ -97,8 +97,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>
|
||||
|
@@ -84,7 +84,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;
|
||||
|
@@ -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
|
||||
|
@@ -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());
|
||||
}
|
||||
|
||||
}
|
@@ -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());
|
||||
}
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* justauth 三方登录的拓展
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
package cn.iocoder.yudao.module.system.framework.justauth;
|
@@ -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 接口
|
||||
*
|
||||
|
@@ -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());
|
||||
}
|
||||
|
@@ -6,21 +6,20 @@ import cn.iocoder.yudao.framework.common.exception.ServiceException;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO;
|
||||
import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO;
|
||||
import cn.iocoder.yudao.module.system.api.social.dto.SocialWxQrcodeReqDTO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.socail.vo.user.SocialUserPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserBindDO;
|
||||
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;
|
||||
|
||||
|
@@ -9,6 +9,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
|
||||
import cn.iocoder.yudao.framework.tenant.config.TenantProperties;
|
||||
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
||||
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
|
||||
@@ -96,6 +97,7 @@ public class TenantServiceImpl implements TenantService {
|
||||
|
||||
@Override
|
||||
@DSTransactional // 多数据源,使用 @DSTransactional 保证本地事务,以及数据源的切换
|
||||
@DataPermission(enable = false) // 参见 https://gitee.com/zhijiantianya/ruoyi-vue-pro/pulls/1154 说明
|
||||
public Long createTenant(TenantSaveReqVO createReqVO) {
|
||||
// 校验租户名称是否重复
|
||||
validTenantNameDuplicate(createReqVO.getName(), null);
|
||||
|
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.system.service.user;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.exception.ServiceException;
|
||||
@@ -61,6 +62,8 @@ public class AdminUserServiceImpl implements AdminUserService {
|
||||
|
||||
static final String USER_INIT_PASSWORD_KEY = "system.user.init-password";
|
||||
|
||||
static final String USER_REGISTER_ENABLED_KEY = "system.user.register-enabled";
|
||||
|
||||
@Resource
|
||||
private AdminUserMapper userMapper;
|
||||
|
||||
@@ -117,14 +120,18 @@ public class AdminUserServiceImpl implements AdminUserService {
|
||||
|
||||
@Override
|
||||
public Long registerUser(AuthRegisterReqVO registerReqVO) {
|
||||
// 1.1 校验账户配合
|
||||
// 1.1 校验是否开启注册
|
||||
if (ObjUtil.notEqual(configApi.getConfigValueByKey(USER_REGISTER_ENABLED_KEY), "true")) {
|
||||
throw exception(USER_REGISTER_DISABLED);
|
||||
}
|
||||
// 1.2 校验账户配合
|
||||
tenantService.handleTenantInfo(tenant -> {
|
||||
long count = userMapper.selectCount();
|
||||
if (count >= tenant.getAccountCount()) {
|
||||
throw exception(USER_COUNT_MAX, tenant.getAccountCount());
|
||||
}
|
||||
});
|
||||
// 1.2 校验正确性
|
||||
// 1.3 校验正确性
|
||||
validateUserForCreateOrUpdate(null, registerReqVO.getUsername(), null, null, null, null);
|
||||
|
||||
// 2. 插入用户
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -212,6 +212,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());
|
||||
});
|
||||
|
||||
// 调用
|
||||
|
Reference in New Issue
Block a user