|  | @@ -12,8 +12,9 @@ import cn.hutool.core.collection.CollUtil;
 | 
	
		
			
				|  |  |  import cn.hutool.core.lang.Assert;
 | 
	
		
			
				|  |  |  import cn.hutool.core.util.ObjUtil;
 | 
	
		
			
				|  |  |  import cn.hutool.core.util.ReflectUtil;
 | 
	
		
			
				|  |  | +import com.binarywang.spring.starter.wxjava.miniapp.properties.WxMaProperties;
 | 
	
		
			
				|  |  | +import com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties;
 | 
	
		
			
				|  |  |  import com.citu.framework.common.enums.CommonStatusEnum;
 | 
	
		
			
				|  |  | -import com.citu.framework.common.enums.UserTypeEnum;
 | 
	
		
			
				|  |  |  import com.citu.framework.common.pojo.PageResult;
 | 
	
		
			
				|  |  |  import com.citu.framework.common.util.cache.CacheUtils;
 | 
	
		
			
				|  |  |  import com.citu.framework.common.util.http.HttpUtils;
 | 
	
	
		
			
				|  | @@ -26,8 +27,6 @@ import com.citu.module.system.dal.dataobject.social.SocialClientDO;
 | 
	
		
			
				|  |  |  import com.citu.module.system.dal.mysql.social.SocialClientMapper;
 | 
	
		
			
				|  |  |  import com.citu.module.system.dal.redis.RedisKeyConstants;
 | 
	
		
			
				|  |  |  import com.citu.module.system.enums.social.SocialTypeEnum;
 | 
	
		
			
				|  |  | -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;
 | 
	
	
		
			
				|  | @@ -59,7 +58,6 @@ import java.util.Map;
 | 
	
		
			
				|  |  |  import java.util.Objects;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import static com.citu.framework.common.exception.util.ServiceExceptionUtil.exception;
 | 
	
		
			
				|  |  | -import static com.citu.framework.common.util.cache.CacheUtils.buildAsyncReloadingCache;
 | 
	
		
			
				|  |  |  import static com.citu.framework.common.util.collection.MapUtils.findAndThen;
 | 
	
		
			
				|  |  |  import static com.citu.framework.common.util.json.JsonUtils.toJsonString;
 | 
	
		
			
				|  |  |  import static com.citu.module.system.enums.ErrorCodeConstants.*;
 | 
	
	
		
			
				|  | @@ -72,10 +70,10 @@ import static com.citu.module.system.enums.ErrorCodeConstants.*;
 | 
	
		
			
				|  |  |  @Service
 | 
	
		
			
				|  |  |  @Slf4j
 | 
	
		
			
				|  |  |  public class SocialClientServiceImpl implements SocialClientService {
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  |       * 小程序码要打开的小程序版本
 | 
	
		
			
				|  |  | -     *
 | 
	
		
			
				|  |  | +     * <p>
 | 
	
		
			
				|  |  |       * 1. release:正式版
 | 
	
		
			
				|  |  |       * 2. trial:体验版
 | 
	
		
			
				|  |  |       * 3. develop:开发版
 | 
	
	
		
			
				|  | @@ -84,7 +82,7 @@ public class SocialClientServiceImpl implements SocialClientService {
 | 
	
		
			
				|  |  |      public String envVersion;
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  |       * 订阅消息跳转小程序类型
 | 
	
		
			
				|  |  | -     *
 | 
	
		
			
				|  |  | +     * <p>
 | 
	
		
			
				|  |  |       * 1. developer:开发版
 | 
	
		
			
				|  |  |       * 2. trial:体验版
 | 
	
		
			
				|  |  |       * 3. formal:正式版
 | 
	
	
		
			
				|  | @@ -103,10 +101,10 @@ public class SocialClientServiceImpl implements SocialClientService {
 | 
	
		
			
				|  |  |      private StringRedisTemplate stringRedisTemplate; // WxMpService 需要使用到,所以在 Service 注入了它
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  |       * 缓存 WxMpService 对象
 | 
	
		
			
				|  |  | -     *
 | 
	
		
			
				|  |  | +     * <p>
 | 
	
		
			
				|  |  |       * key:使用微信公众号的 appId + secret 拼接,即 {@link SocialClientDO} 的 clientId 和 clientSecret 属性。
 | 
	
		
			
				|  |  |       * 为什么 key 使用这种格式?因为 {@link SocialClientDO} 在管理后台可以变更,通过这个 key 存储它的单例。
 | 
	
		
			
				|  |  | -     *
 | 
	
		
			
				|  |  | +     * <p>
 | 
	
		
			
				|  |  |       * 为什么要做 WxMpService 缓存?因为 WxMpService 构建成本比较大,所以尽量保证它是单例。
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  |      private final LoadingCache<String, WxMpService> wxMpServiceCache = CacheUtils.buildAsyncReloadingCache(
 | 
	
	
		
			
				|  | @@ -127,7 +125,7 @@ public class SocialClientServiceImpl implements SocialClientService {
 | 
	
		
			
				|  |  |      private WxMaProperties wxMaProperties;
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  |       * 缓存 WxMaService 对象
 | 
	
		
			
				|  |  | -     *
 | 
	
		
			
				|  |  | +     * <p>
 | 
	
		
			
				|  |  |       * 说明同 {@link #wxMpServiceCache} 变量
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  |      private final LoadingCache<String, WxMaService> wxMaServiceCache = CacheUtils.buildAsyncReloadingCache(
 | 
	
	
		
			
				|  | @@ -146,18 +144,18 @@ public class SocialClientServiceImpl implements SocialClientService {
 | 
	
		
			
				|  |  |      private SocialClientMapper socialClientMapper;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  | -    public String getAuthorizeUrl(Integer socialType, Integer userType, String redirectUri) {
 | 
	
		
			
				|  |  | +    public String getAuthorizeUrl(String application, Integer socialType, Integer userType, String redirectUri) {
 | 
	
		
			
				|  |  |          // 获得对应的 AuthRequest 实现
 | 
	
		
			
				|  |  | -        AuthRequest authRequest = buildAuthRequest(socialType, userType);
 | 
	
		
			
				|  |  | +        AuthRequest authRequest = buildAuthRequest(application, socialType, userType);
 | 
	
		
			
				|  |  |          // 生成跳转地址
 | 
	
		
			
				|  |  |          String authorizeUri = authRequest.authorize(AuthStateUtils.createState());
 | 
	
		
			
				|  |  |          return HttpUtils.replaceUrlQuery(authorizeUri, "redirect_uri", redirectUri);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  | -    public AuthUser getAuthUser(Integer socialType, Integer userType, String code, String state) {
 | 
	
		
			
				|  |  | +    public AuthUser getAuthUser(String application, Integer socialType, Integer userType, String code, String state) {
 | 
	
		
			
				|  |  |          // 构建请求
 | 
	
		
			
				|  |  | -        AuthRequest authRequest = buildAuthRequest(socialType, userType);
 | 
	
		
			
				|  |  | +        AuthRequest authRequest = buildAuthRequest(application, socialType, userType);
 | 
	
		
			
				|  |  |          AuthCallback authCallback = AuthCallback.builder().code(code).state(state).build();
 | 
	
		
			
				|  |  |          // 执行请求
 | 
	
		
			
				|  |  |          AuthResponse<?> authResponse = authRequest.login(authCallback);
 | 
	
	
		
			
				|  | @@ -173,16 +171,16 @@ public class SocialClientServiceImpl implements SocialClientService {
 | 
	
		
			
				|  |  |       * 构建 AuthRequest 对象,支持多租户配置
 | 
	
		
			
				|  |  |       *
 | 
	
		
			
				|  |  |       * @param socialType 社交类型
 | 
	
		
			
				|  |  | -     * @param userType 用户类型
 | 
	
		
			
				|  |  | +     * @param userType   用户类型
 | 
	
		
			
				|  |  |       * @return AuthRequest 对象
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  |      @VisibleForTesting
 | 
	
		
			
				|  |  | -    AuthRequest buildAuthRequest(Integer socialType, Integer userType) {
 | 
	
		
			
				|  |  | +    AuthRequest buildAuthRequest(String application, Integer socialType, Integer userType) {
 | 
	
		
			
				|  |  |          // 1. 先查找默认的配置项,从 application-*.yaml 中读取
 | 
	
		
			
				|  |  |          AuthRequest request = authRequestFactory.get(SocialTypeEnum.valueOfType(socialType).getSource());
 | 
	
		
			
				|  |  |          Assert.notNull(request, String.format("社交平台(%d) 不存在", socialType));
 | 
	
		
			
				|  |  |          // 2. 查询 DB 的配置项,如果存在则进行覆盖
 | 
	
		
			
				|  |  | -        SocialClientDO client = socialClientMapper.selectBySocialTypeAndUserType(socialType, userType);
 | 
	
		
			
				|  |  | +        SocialClientDO client = socialClientMapper.selectBySocialApplicationAndTypeAndUserType(application, socialType, userType);
 | 
	
		
			
				|  |  |          if (client != null && Objects.equals(client.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
 | 
	
		
			
				|  |  |              // 2.1 构造新的 AuthConfig 对象
 | 
	
		
			
				|  |  |              AuthConfig authConfig = (AuthConfig) ReflectUtil.getFieldValue(request, "config");
 | 
	
	
		
			
				|  | @@ -204,8 +202,8 @@ public class SocialClientServiceImpl implements SocialClientService {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      @SneakyThrows
 | 
	
		
			
				|  |  | -    public WxJsapiSignature createWxMpJsapiSignature(Integer userType, String url) {
 | 
	
		
			
				|  |  | -        WxMpService service = getWxMpService(userType);
 | 
	
		
			
				|  |  | +    public WxJsapiSignature createWxMpJsapiSignature(String application, Integer userType, String url) {
 | 
	
		
			
				|  |  | +        WxMpService service = getWxMpService(application, userType);
 | 
	
		
			
				|  |  |          return service.createJsapiSignature(url);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -216,9 +214,9 @@ public class SocialClientServiceImpl implements SocialClientService {
 | 
	
		
			
				|  |  |       * @return WxMpService 对象
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  |      @VisibleForTesting
 | 
	
		
			
				|  |  | -    WxMpService getWxMpService(Integer userType) {
 | 
	
		
			
				|  |  | +    WxMpService getWxMpService(String application, Integer userType) {
 | 
	
		
			
				|  |  |          // 第一步,查询 DB 的配置项,获得对应的 WxMpService 对象
 | 
	
		
			
				|  |  | -        SocialClientDO client = socialClientMapper.selectBySocialTypeAndUserType(
 | 
	
		
			
				|  |  | +        SocialClientDO client = socialClientMapper.selectBySocialApplicationAndTypeAndUserType(application,
 | 
	
		
			
				|  |  |                  SocialTypeEnum.WECHAT_MP.getType(), userType);
 | 
	
		
			
				|  |  |          if (client != null && Objects.equals(client.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
 | 
	
		
			
				|  |  |              return wxMpServiceCache.getUnchecked(client.getClientId() + ":" + client.getClientSecret());
 | 
	
	
		
			
				|  | @@ -230,7 +228,7 @@ public class SocialClientServiceImpl implements SocialClientService {
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  |       * 创建 clientId + clientSecret 对应的 WxMpService 对象
 | 
	
		
			
				|  |  |       *
 | 
	
		
			
				|  |  | -     * @param clientId 微信公众号 appId
 | 
	
		
			
				|  |  | +     * @param clientId     微信公众号 appId
 | 
	
		
			
				|  |  |       * @param clientSecret 微信公众号 secret
 | 
	
		
			
				|  |  |       * @return WxMpService 对象
 | 
	
		
			
				|  |  |       */
 | 
	
	
		
			
				|  | @@ -251,8 +249,8 @@ public class SocialClientServiceImpl implements SocialClientService {
 | 
	
		
			
				|  |  |      // =================== 微信小程序独有 ===================
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  | -    public WxMaPhoneNumberInfo getWxMaPhoneNumberInfo(Integer userType, String phoneCode) {
 | 
	
		
			
				|  |  | -        WxMaService service = getWxMaService(userType);
 | 
	
		
			
				|  |  | +    public WxMaPhoneNumberInfo getWxMaPhoneNumberInfo(String application, Integer userType, String phoneCode) {
 | 
	
		
			
				|  |  | +        WxMaService service = getWxMaService(application, userType);
 | 
	
		
			
				|  |  |          try {
 | 
	
		
			
				|  |  |              return service.getUserService().getPhoneNoInfo(phoneCode);
 | 
	
		
			
				|  |  |          } catch (WxErrorException e) {
 | 
	
	
		
			
				|  | @@ -263,7 +261,7 @@ public class SocialClientServiceImpl implements SocialClientService {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      public byte[] getWxaQrcode(SocialWxQrcodeReqDTO reqVO) {
 | 
	
		
			
				|  |  | -        WxMaService service = getWxMaService(UserTypeEnum.MEMBER.getValue());
 | 
	
		
			
				|  |  | +        WxMaService service = getWxMaService(reqVO.getApplication(), reqVO.getUserType());
 | 
	
		
			
				|  |  |          try {
 | 
	
		
			
				|  |  |              return service.getQrcodeService().createWxaCodeUnlimitBytes(
 | 
	
		
			
				|  |  |                      ObjUtil.defaultIfEmpty(reqVO.getScene(), SocialWxQrcodeReqDTO.SCENE),
 | 
	
	
		
			
				|  | @@ -281,10 +279,10 @@ public class SocialClientServiceImpl implements SocialClientService {
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  | -    @Cacheable(cacheNames = RedisKeyConstants.WXA_SUBSCRIBE_TEMPLATE, key = "#userType",
 | 
	
		
			
				|  |  | +    @Cacheable(cacheNames = RedisKeyConstants.WXA_SUBSCRIBE_TEMPLATE, key = "#application+':'+#userType",
 | 
	
		
			
				|  |  |              unless = "#result == null")
 | 
	
		
			
				|  |  | -    public List<TemplateInfo> getSubscribeTemplateList(Integer userType) {
 | 
	
		
			
				|  |  | -        WxMaService service = getWxMaService(userType);
 | 
	
		
			
				|  |  | +    public List<TemplateInfo> getSubscribeTemplateList(String application, Integer userType) {
 | 
	
		
			
				|  |  | +        WxMaService service = getWxMaService(application, userType);
 | 
	
		
			
				|  |  |          try {
 | 
	
		
			
				|  |  |              WxMaSubscribeService subscribeService = service.getSubscribeService();
 | 
	
		
			
				|  |  |              return subscribeService.getTemplateList();
 | 
	
	
		
			
				|  | @@ -296,7 +294,7 @@ public class SocialClientServiceImpl implements SocialClientService {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      public void sendSubscribeMessage(SocialWxaSubscribeMessageSendReqDTO reqDTO, String templateId, String openId) {
 | 
	
		
			
				|  |  | -        WxMaService service = getWxMaService(reqDTO.getUserType());
 | 
	
		
			
				|  |  | +        WxMaService service = getWxMaService(reqDTO.getApplication(), reqDTO.getUserType());
 | 
	
		
			
				|  |  |          try {
 | 
	
		
			
				|  |  |              WxMaSubscribeService subscribeService = service.getSubscribeService();
 | 
	
		
			
				|  |  |              subscribeService.sendSubscribeMsg(buildMessageSendReqDTO(reqDTO, templateId, openId));
 | 
	
	
		
			
				|  | @@ -335,9 +333,9 @@ public class SocialClientServiceImpl implements SocialClientService {
 | 
	
		
			
				|  |  |       * @return WxMpService 对象
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  |      @VisibleForTesting
 | 
	
		
			
				|  |  | -    WxMaService getWxMaService(Integer userType) {
 | 
	
		
			
				|  |  | +    WxMaService getWxMaService(String application, Integer userType) {
 | 
	
		
			
				|  |  |          // 第一步,查询 DB 的配置项,获得对应的 WxMaService 对象
 | 
	
		
			
				|  |  | -        SocialClientDO client = socialClientMapper.selectBySocialTypeAndUserType(
 | 
	
		
			
				|  |  | +        SocialClientDO client = socialClientMapper.selectBySocialApplicationAndTypeAndUserType(application,
 | 
	
		
			
				|  |  |                  SocialTypeEnum.WECHAT_MINI_APP.getType(), userType);
 | 
	
		
			
				|  |  |          if (client != null && Objects.equals(client.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
 | 
	
		
			
				|  |  |              return wxMaServiceCache.getUnchecked(client.getClientId() + ":" + client.getClientSecret());
 | 
	
	
		
			
				|  | @@ -349,7 +347,7 @@ public class SocialClientServiceImpl implements SocialClientService {
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  |       * 创建 clientId + clientSecret 对应的 WxMaService 对象
 | 
	
		
			
				|  |  |       *
 | 
	
		
			
				|  |  | -     * @param clientId 微信小程序 appId
 | 
	
		
			
				|  |  | +     * @param clientId     微信小程序 appId
 | 
	
		
			
				|  |  |       * @param clientSecret 微信小程序 secret
 | 
	
		
			
				|  |  |       * @return WxMaService 对象
 | 
	
		
			
				|  |  |       */
 | 
	
	
		
			
				|  | @@ -372,7 +370,7 @@ public class SocialClientServiceImpl implements SocialClientService {
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      public Long createSocialClient(SocialClientSaveReqVO createReqVO) {
 | 
	
		
			
				|  |  |          // 校验重复
 | 
	
		
			
				|  |  | -        validateSocialClientUnique(null, createReqVO.getUserType(), createReqVO.getSocialType());
 | 
	
		
			
				|  |  | +        validateSocialClientUnique(null, createReqVO.getApplication(), createReqVO.getUserType(), createReqVO.getSocialType());
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // 插入
 | 
	
		
			
				|  |  |          SocialClientDO client = BeanUtils.toBean(createReqVO, SocialClientDO.class);
 | 
	
	
		
			
				|  | @@ -385,7 +383,7 @@ public class SocialClientServiceImpl implements SocialClientService {
 | 
	
		
			
				|  |  |          // 校验存在
 | 
	
		
			
				|  |  |          validateSocialClientExists(updateReqVO.getId());
 | 
	
		
			
				|  |  |          // 校验重复
 | 
	
		
			
				|  |  | -        validateSocialClientUnique(updateReqVO.getId(), updateReqVO.getUserType(), updateReqVO.getSocialType());
 | 
	
		
			
				|  |  | +        validateSocialClientUnique(updateReqVO.getId(), updateReqVO.getApplication(), updateReqVO.getUserType(), updateReqVO.getSocialType());
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // 更新
 | 
	
		
			
				|  |  |          SocialClientDO updateObj = BeanUtils.toBean(updateReqVO, SocialClientDO.class);
 | 
	
	
		
			
				|  | @@ -407,17 +405,24 @@ public class SocialClientServiceImpl implements SocialClientService {
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  | -     * 校验社交应用是否重复,需要保证 userType + socialType 唯一
 | 
	
		
			
				|  |  | +     * 校验社交应用是否重复,需要保证 application + userType + socialType 唯一
 | 
	
		
			
				|  |  | +     * <p>
 | 
	
		
			
				|  |  | +     * 原因是,不同端(userType)选择某个社交登录(socialType)时,需要通过 {@link #buildAuthRequest(String, Integer, Integer)} 构建对应的请求
 | 
	
		
			
				|  |  |       *
 | 
	
		
			
				|  |  | -     * 原因是,不同端(userType)选择某个社交登录(socialType)时,需要通过 {@link #buildAuthRequest(Integer, Integer)} 构建对应的请求
 | 
	
		
			
				|  |  | -     *
 | 
	
		
			
				|  |  | -     * @param id 编号
 | 
	
		
			
				|  |  | -     * @param userType 用户类型
 | 
	
		
			
				|  |  | +     * @param id         编号
 | 
	
		
			
				|  |  | +     * @param userType   用户类型
 | 
	
		
			
				|  |  |       * @param socialType 社交类型
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  | -    private void validateSocialClientUnique(Long id, Integer userType, Integer socialType) {
 | 
	
		
			
				|  |  | -        SocialClientDO client = socialClientMapper.selectBySocialTypeAndUserType(
 | 
	
		
			
				|  |  | -                socialType, userType);
 | 
	
		
			
				|  |  | +    private void validateSocialClientUnique(Long id, String application, Integer userType, Integer socialType) {
 | 
	
		
			
				|  |  | +        SocialClientDO exist = socialClientMapper.selectByApplication(application);
 | 
	
		
			
				|  |  | +        if (null == id && null != exist) {
 | 
	
		
			
				|  |  | +            // 重复的application
 | 
	
		
			
				|  |  | +            throw exception(SOCIAL_CLIENT_UNIQUE);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if (null != exist && ObjUtil.notEqual(id, exist.getId())) {
 | 
	
		
			
				|  |  | +            throw exception(SOCIAL_CLIENT_UNIQUE);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        SocialClientDO client = socialClientMapper.selectBySocialApplicationAndTypeAndUserType(application, socialType, userType);
 | 
	
		
			
				|  |  |          if (client == null) {
 | 
	
		
			
				|  |  |              return;
 | 
	
		
			
				|  |  |          }
 | 
	
	
		
			
				|  | @@ -425,6 +430,7 @@ public class SocialClientServiceImpl implements SocialClientService {
 | 
	
		
			
				|  |  |                  || ObjUtil.notEqual(id, client.getId())) { // 更新时,如果 id 不一致,说明重复
 | 
	
		
			
				|  |  |              throw exception(SOCIAL_CLIENT_UNIQUE);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
	
		
			
				|  | @@ -432,6 +438,11 @@ public class SocialClientServiceImpl implements SocialClientService {
 | 
	
		
			
				|  |  |          return socialClientMapper.selectById(id);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    public SocialClientDO getSocialClientByApplication(String application) {
 | 
	
		
			
				|  |  | +        return socialClientMapper.selectByApplication(application);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      public PageResult<SocialClientDO> getSocialClientPage(SocialClientPageReqVO pageReqVO) {
 | 
	
		
			
				|  |  |          return socialClientMapper.selectPage(pageReqVO);
 |