Browse Source

消息模板免密登录

Yangzw 7 months ago
parent
commit
ad5929d8a0
22 changed files with 318 additions and 19 deletions
  1. 6 0
      feifan-module-distri/feifan-module-distri-biz/src/main/java/cn/newfeifan/mall/module/distri/controller/admin/duser/vo/DuserInfoVO.java
  2. 8 0
      feifan-module-distri/feifan-module-distri-biz/src/main/java/cn/newfeifan/mall/module/distri/service/duser/DuserServiceImpl.java
  3. 9 0
      feifan-module-mall/feifan-module-sale-biz/src/main/java/cn/newfeifan/mall/module/sale/dal/redis/ShopMessage.java
  4. 25 0
      feifan-module-mall/feifan-module-sale-biz/src/main/java/cn/newfeifan/mall/module/sale/login/LoginConsumer.java
  5. 14 0
      feifan-module-mall/feifan-module-sale-biz/src/main/java/cn/newfeifan/mall/module/sale/service/merchant/MerchantService.java
  6. 66 0
      feifan-module-mall/feifan-module-sale-biz/src/main/java/cn/newfeifan/mall/module/sale/service/merchant/MerchantServiceImpl.java
  7. 3 0
      feifan-module-mall/feifan-module-sale-biz/src/main/java/cn/newfeifan/mall/module/sale/service/shop/ShopService.java
  8. 11 0
      feifan-module-mall/feifan-module-sale-biz/src/main/java/cn/newfeifan/mall/module/sale/service/shop/ShopServiceImpl.java
  9. 22 5
      feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/utils/wechat/WcChatMessageUtils.java
  10. 1 0
      feifan-module-member/feifan-module-member-api/src/main/java/cn/newfeifan/mall/module/member/enums/ErrorCodeConstants.java
  11. 7 0
      feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/controller/app/auth/AppAuthController.java
  12. 6 0
      feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/service/auth/MemberAuthService.java
  13. 42 5
      feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/service/auth/MemberAuthServiceImpl.java
  14. 10 3
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/dal/dataobject/oauth2/OAuth2AccessTokenDO.java
  15. 4 3
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/dal/dataobject/user/AdminUserDO.java
  16. 17 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/mq/message/login/LoginSendMessage.java
  17. 28 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/mq/producer/login/LoginProducer.java
  18. 11 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/auth/AdminAuthService.java
  19. 1 1
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/auth/AdminAuthServiceImpl.java
  20. 5 1
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/oauth2/OAuth2TokenServiceImpl.java
  21. 8 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/user/AdminUserService.java
  22. 14 1
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/user/AdminUserServiceImpl.java

+ 6 - 0
feifan-module-distri/feifan-module-distri-biz/src/main/java/cn/newfeifan/mall/module/distri/controller/admin/duser/vo/DuserInfoVO.java

@@ -42,4 +42,10 @@ public class DuserInfoVO {
     @Schema(description = "是否签到")
     private Boolean isSign;
 
+    @Schema(description = "是否是平台用户")
+    private Boolean isPtSystemUser;
+
+    @Schema(description = "是否是商户用户")
+    private Boolean isShSystemUser;
+
 }

+ 8 - 0
feifan-module-distri/feifan-module-distri-biz/src/main/java/cn/newfeifan/mall/module/distri/service/duser/DuserServiceImpl.java

@@ -18,6 +18,7 @@ import cn.newfeifan.mall.module.distri.service.socialstatuschangelog.SocialStatu
 import cn.newfeifan.mall.module.member.dal.dataobject.user.MemberUserDO;
 import cn.newfeifan.mall.module.member.service.signin.MemberSignInRecordService;
 import cn.newfeifan.mall.module.member.service.user.MemberUserService;
+import cn.newfeifan.mall.module.system.service.user.AdminUserService;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
@@ -70,6 +71,9 @@ public class DuserServiceImpl implements DuserService {
     @Resource
     private MemberSignInRecordService memberSignInRecordService;
 
+    @Resource
+    private AdminUserService adminUserService;
+
     @Override
     public Long createDuser(DuserSaveReqVO createReqVO) {
         // 插入
@@ -166,6 +170,8 @@ public class DuserServiceImpl implements DuserService {
         }
 
         Boolean isSign = memberSignInRecordService.isSignIn();
+        Boolean isPtSystemUser = adminUserService.isSystemUser(duser.getMobile(), true);
+        Boolean isShSystemUser = adminUserService.isSystemUser(duser.getMobile(), false);
 
         return duserInfoVOBuilder
                 .descPrice(Long.parseLong(yesterday))
@@ -176,6 +182,8 @@ public class DuserServiceImpl implements DuserService {
                 .socialStatusLevel(socialStatus.getLevel())
                 .socialStatusLevelName(socialStatus.getName())
                 .isSign(isSign)
+                .isPtSystemUser(isPtSystemUser)
+                .isShSystemUser(isShSystemUser)
                 .build();
 
     }

+ 9 - 0
feifan-module-mall/feifan-module-sale-biz/src/main/java/cn/newfeifan/mall/module/sale/dal/redis/ShopMessage.java

@@ -0,0 +1,9 @@
+package cn.newfeifan.mall.module.sale.dal.redis;
+
+import lombok.Data;
+
+@Data
+public class ShopMessage {
+    private Long shopId;
+    private Long merId;
+}

+ 25 - 0
feifan-module-mall/feifan-module-sale-biz/src/main/java/cn/newfeifan/mall/module/sale/login/LoginConsumer.java

@@ -0,0 +1,25 @@
+package cn.newfeifan.mall.module.sale.login;
+
+import cn.newfeifan.mall.module.sale.service.merchant.MerchantService;
+import cn.newfeifan.mall.module.system.mq.message.login.LoginSendMessage;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.event.EventListener;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+@Component
+@Slf4j
+public class LoginConsumer {
+    @Resource
+    private MerchantService mailSendService;
+
+    @EventListener
+    @Async // Spring Event 默认在 Producer 发送的线程,通过 @Async 实现异步
+    public void onMessage(LoginSendMessage message) {
+        log.info("[onMessage][消息内容({})]", message);
+        mailSendService.doSendMail(message);
+    }
+
+}

+ 14 - 0
feifan-module-mall/feifan-module-sale-biz/src/main/java/cn/newfeifan/mall/module/sale/service/merchant/MerchantService.java

@@ -0,0 +1,14 @@
+package cn.newfeifan.mall.module.sale.service.merchant;
+
+import cn.newfeifan.mall.module.system.mq.message.login.LoginSendMessage;
+
+/**
+ * 商户 Service 接口
+ *
+ * @author 非繁人
+ */
+public interface MerchantService {
+
+    void doSendMail(LoginSendMessage message);
+
+}

+ 66 - 0
feifan-module-mall/feifan-module-sale-biz/src/main/java/cn/newfeifan/mall/module/sale/service/merchant/MerchantServiceImpl.java

@@ -0,0 +1,66 @@
+package cn.newfeifan.mall.module.sale.service.merchant;
+
+import cn.newfeifan.mall.framework.common.util.json.JsonUtils;
+import cn.newfeifan.mall.module.sale.controller.app.shop.vo.ShopRespVO;
+import cn.newfeifan.mall.module.sale.service.shop.ShopService;
+import cn.newfeifan.mall.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
+import cn.newfeifan.mall.module.system.dal.dataobject.user.AdminUserDO;
+import cn.newfeifan.mall.module.system.dal.mysql.user.AdminUserMapper;
+import cn.newfeifan.mall.module.system.mq.message.login.LoginSendMessage;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+import cn.newfeifan.mall.module.sale.dal.redis.ShopMessage;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+
+/**
+ * 商户 Service 实现类
+ *
+ * @author 非繁人
+ */
+@Service
+@Validated
+public class MerchantServiceImpl implements MerchantService {
+
+    @Resource
+    private StringRedisTemplate stringRedisTemplate;
+    @Resource
+    private AdminUserMapper userMapper;
+    @Resource
+    private ShopService shopService;
+    @Override
+    public void doSendMail(LoginSendMessage message) {
+
+        // 查询用户的商户信息,并且缓存到redis中
+        OAuth2AccessTokenDO oAuth2AccessTokenDO = message.getOAuth2AccessTokenDO();
+        ShopMessage shopMessage = JsonUtils.parseObject(stringRedisTemplate.opsForValue().get("shop:" + message.getOAuth2AccessTokenDO().getUserId()), ShopMessage.class);
+        if (shopMessage != null) {
+            // 刷新时间
+            stringRedisTemplate.opsForValue().set("shop:" + oAuth2AccessTokenDO.getUserId(), JsonUtils.toJsonString(shopMessage), 3600 * 24, TimeUnit.SECONDS);
+        } else {
+            // 查询数据库
+            AdminUserDO adminUserDO = userMapper.selectById(message.getOAuth2AccessTokenDO().getUserId());
+            if (adminUserDO.getShopId() != null) {
+                ShopMessage addRedis = new ShopMessage().setShopId(adminUserDO.getShopId()).setMerId(adminUserDO.getMerchantId());
+                stringRedisTemplate.opsForValue().set("shop:" + oAuth2AccessTokenDO.getUserId(), JsonUtils.toJsonString(addRedis), 3600 * 24, TimeUnit.SECONDS);
+            } else {
+                // 获取随机店铺
+                List<ShopRespVO> merchantAllShop = shopService.getMerchantAllShop(adminUserDO.getMerchantId());
+                oAuth2AccessTokenDO.setMerchantId(adminUserDO.getMerchantId());
+                Long shopId = null;
+                if (merchantAllShop.size() > 0) {
+                    shopId = merchantAllShop.get(0).getId();
+                    oAuth2AccessTokenDO.setShopId(shopId);
+                }
+                //存储redis
+                ShopMessage addRedis = new ShopMessage().setShopId(shopId).setMerId(adminUserDO.getMerchantId());
+                stringRedisTemplate.opsForValue().set("shop:" + oAuth2AccessTokenDO.getUserId(), JsonUtils.toJsonString(addRedis), 3600 * 24, TimeUnit.SECONDS);
+            }
+        }
+    }
+
+}

+ 3 - 0
feifan-module-mall/feifan-module-sale-biz/src/main/java/cn/newfeifan/mall/module/sale/service/shop/ShopService.java

@@ -5,6 +5,8 @@ import cn.newfeifan.mall.module.sale.controller.app.shop.vo.*;
 import cn.newfeifan.mall.module.sale.dal.dataobject.shop.ShopDO;
 import cn.newfeifan.mall.framework.common.pojo.PageResult;
 
+import java.util.List;
+
 /**
  * 店铺 Service 接口
  *
@@ -50,4 +52,5 @@ public interface ShopService {
      */
     PageResult<ShopDO> getShopPage(ShopPageReqVO pageReqVO);
 
+    List<ShopRespVO> getMerchantAllShop(Long merchantId);
 }

+ 11 - 0
feifan-module-mall/feifan-module-sale-biz/src/main/java/cn/newfeifan/mall/module/sale/service/shop/ShopServiceImpl.java

@@ -11,6 +11,9 @@ import cn.newfeifan.mall.framework.common.util.object.BeanUtils;
 
 import cn.newfeifan.mall.module.sale.dal.mysql.shop.ShopMapper;
 
+import java.util.List;
+import java.util.stream.Collectors;
+
 import static cn.newfeifan.mall.framework.common.exception.util.ServiceExceptionUtil.exception;
 
 /**
@@ -67,4 +70,12 @@ public class ShopServiceImpl implements ShopService {
         return shopMapper.selectPage(pageReqVO);
     }
 
+    @Override
+    public List<ShopRespVO> getMerchantAllShop(Long merId) {
+        List<ShopDO> shopDOS = shopMapper.selectList();
+        // 筛选
+        shopDOS = shopDOS.stream().filter(k -> k.getMerchantId() != null && k.getMerchantId().equals(merId)).collect(Collectors.toList());
+        return BeanUtils.toBean(shopDOS, ShopRespVO.class);
+    }
+
 }

+ 22 - 5
feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/utils/wechat/WcChatMessageUtils.java

@@ -6,11 +6,16 @@ import cn.hutool.http.HttpUtil;
 import cn.hutool.json.JSONUtil;
 import cn.newfeifan.mall.module.member.dal.dataobject.user.MemberUserDO;
 import cn.newfeifan.mall.module.member.service.user.MemberUserService;
+import cn.newfeifan.mall.module.system.controller.admin.auth.vo.AuthLoginRespVO;
 import cn.newfeifan.mall.module.system.dal.dataobject.config.SystemConfigDO;
+import cn.newfeifan.mall.module.system.dal.dataobject.user.AdminUserDO;
 import cn.newfeifan.mall.module.system.dal.dataobject.wechatmsgtemplate.WechatMsgTemplateDO;
+import cn.newfeifan.mall.module.system.enums.logger.LoginLogTypeEnum;
+import cn.newfeifan.mall.module.system.service.auth.AdminAuthService;
 import cn.newfeifan.mall.module.system.service.config.SystemConfigService;
 import cn.newfeifan.mall.module.system.service.permission.PermissionService;
 import cn.newfeifan.mall.module.system.service.social.SocialUserService;
+import cn.newfeifan.mall.module.system.service.user.AdminUserService;
 import cn.newfeifan.mall.module.system.service.wechatmsgtemplate.WechatMsgTemplateService;
 import cn.newfeifan.mall.module.trade.controller.admin.messagelog.vo.MessageLogSaveReqVO;
 import cn.newfeifan.mall.module.trade.enums.wxmessage.WcChatMessageTemplateIdEnum;
@@ -56,6 +61,10 @@ public class WcChatMessageUtils {
     private PermissionService permissionService;
     @Resource
     private MemberUserService memberUserService;
+    @Resource
+    private AdminAuthService authService;
+    @Resource
+    private AdminUserService adminUserService;
 
     /**
      * 获取微信的accessToken
@@ -96,7 +105,7 @@ public class WcChatMessageUtils {
      */
     private void sendWxgMessage(Long userId, JsonObject data, String wechatMsgTemplateId, Long systemUserId, Long objectId, String userOpenId) {
         String templateId = getTemplateId(wechatMsgTemplateId).getWechatMsgTemplateId(); // 模板id
-        String url = getDoMain(wechatMsgTemplateId, objectId);       // 跳转路径(小程序之外)
+        String url = getDoMain(wechatMsgTemplateId, objectId, systemUserId);       // 跳转路径(小程序之外)
         String client_msg_id = UUID.randomUUID().toString();  // 防重入id
 
 
@@ -238,7 +247,7 @@ public class WcChatMessageUtils {
      * @param templateId 自定义模板id
      * @return 域名加路径
      */
-    public String getDoMain(String templateId, Long objectId) {
+    public String getDoMain(String templateId, Long objectId, Long systemUserId) {
         SystemConfigDO redisConfig = configService.getRedisConfig();
         if (templateId.equals(WcChatMessageTemplateIdEnum.ORDER_DELIVERY2.getTemplateId())) {
             //订单已发货
@@ -248,13 +257,21 @@ public class WcChatMessageUtils {
             return redisConfig.getMallDomain() + "/#/pages/order/aftersale/detail?id=" + objectId;
         } else if (templateId.equals(WcChatMessageTemplateIdEnum.AFTER_SALE_NO_CHECK2.getTemplateId())) {
             //售后订单待审核
-            return redisConfig.getMerchantDomain() + "/after-sale";
+            AdminUserDO systemUser = adminUserService.getUser(systemUserId);
+            AuthLoginRespVO token = authService.createTokenAfterLoginSuccess(systemUser.getId(), systemUser.getUsername(), LoginLogTypeEnum.LOGIN_USERNAME);
+//            return redisConfig.getMerchantDomain() + "/after-sale";
+            return redisConfig.getMerchantDomain() + "/login" + "?accessToken=" + token.getAccessToken() + "&refreshToken=" + token.getRefreshToken();
         } else if (templateId.equals(WcChatMessageTemplateIdEnum.ORDER_NO_DELIVERY2.getTemplateId())) {
             //订单待发货
-            return redisConfig.getMerchantDomain() + "/order";
+            AdminUserDO systemUser = adminUserService.getUser(systemUserId);
+            AuthLoginRespVO token = authService.createTokenAfterLoginSuccess(systemUser.getId(), systemUser.getUsername(), LoginLogTypeEnum.LOGIN_USERNAME);
+//            return redisConfig.getMerchantDomain() + "/order";
+            return redisConfig.getMerchantDomain() + "/login" + "?accessToken=" + token.getAccessToken() + "&refreshToken=" + token.getRefreshToken();
         } else if(templateId.equals(WcChatMessageTemplateIdEnum.MERCHANT_APPLY_CHECK.getTemplateId())){
             // 商户入驻申请审批通知
-            return redisConfig.getPlatformDomain();
+            AdminUserDO systemUser = adminUserService.getUser(systemUserId);
+            AuthLoginRespVO token = authService.createTokenAfterLoginSuccess(systemUser.getId(), systemUser.getUsername(), LoginLogTypeEnum.LOGIN_USERNAME);
+            return redisConfig.getPlatformDomain() + "/login" + "?accessToken=" + token.getAccessToken() + "&refreshToken=" + token.getRefreshToken();
         } else if(templateId.equals(WcChatMessageTemplateIdEnum.MERCHANT_APPLY_CHECK_RESULT.getTemplateId())){
             // 商户入驻审核结果通知
             return redisConfig.getMallDomain() + "/#/pages/public/merchant";

+ 1 - 0
feifan-module-member/feifan-module-member-api/src/main/java/cn/newfeifan/mall/module/member/enums/ErrorCodeConstants.java

@@ -62,5 +62,6 @@ public interface ErrorCodeConstants {
     ErrorCode AUTH_SOCIAL_USER_BIND_MAX = new ErrorCode(1_004_012_004, "此微信号已经到达绑定的上限了");
     ErrorCode LINK_ID_IS_NOT_EXISTS = new ErrorCode(1_004_012_005, "只能通过分享注册");
     ErrorCode RELOAD_REGISTER = new ErrorCode(1_004_012_006, "本次注册账号失败,请退出当前页面重新扫描分享二维码注册");
+    ErrorCode MEMBER_USER_NOT_BINDING_SYSTEM_USER = new ErrorCode(1_004_012_007, "跳转失败,会员用户没有绑定系统用户");
 
 }

+ 7 - 0
feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/controller/app/auth/AppAuthController.java

@@ -5,6 +5,7 @@ import cn.newfeifan.mall.framework.common.enums.UserTypeEnum;
 import cn.newfeifan.mall.framework.common.pojo.CommonResult;
 import cn.newfeifan.mall.framework.operatelog.core.annotations.OperateLog;
 import cn.newfeifan.mall.framework.security.config.SecurityProperties;
+import cn.newfeifan.mall.framework.security.core.annotations.PreAuthenticated;
 import cn.newfeifan.mall.framework.security.core.util.SecurityFrameworkUtils;
 import cn.newfeifan.mall.module.member.controller.app.auth.vo.*;
 import cn.newfeifan.mall.module.member.convert.auth.AuthConvert;
@@ -162,5 +163,11 @@ public class AppAuthController {
         return success(AuthConvert.INSTANCE.convert(signature));
     }
 
+    @GetMapping("/redirectLogin")
+    @Operation(summary = "重定向登录")
+    @PreAuthenticated
+    public CommonResult<String> redirectLogin() {
+        return success(authService.redirectLogin());
+    }
 
 }

+ 6 - 0
feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/service/auth/MemberAuthService.java

@@ -97,4 +97,10 @@ public interface MemberAuthService {
     AppAuthLoginRespVO socialLogin(AppAuthSocialLoginReqVO reqVO);
 
     AppAuthLoginRespVO selectUsernameLogin(AppAuthSelectUsernameLoginReqVO reqVO);
+
+    /**
+     * 跳转登录
+     * @return 跳转登录
+     */
+    String redirectLogin();
 }

+ 42 - 5
feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/service/auth/MemberAuthServiceImpl.java

@@ -22,11 +22,17 @@ import cn.newfeifan.mall.module.system.api.social.SocialUserApi;
 import cn.newfeifan.mall.module.system.api.social.dto.SocialUserBindReqDTO;
 import cn.newfeifan.mall.module.system.api.social.dto.SocialUserRespDTO;
 import cn.newfeifan.mall.module.system.api.social.dto.SocialWxPhoneNumberInfoRespDTO;
+import cn.newfeifan.mall.module.system.controller.admin.auth.vo.AuthLoginRespVO;
+import cn.newfeifan.mall.module.system.dal.dataobject.config.SystemConfigDO;
+import cn.newfeifan.mall.module.system.dal.dataobject.user.AdminUserDO;
 import cn.newfeifan.mall.module.system.enums.logger.LoginLogTypeEnum;
 import cn.newfeifan.mall.module.system.enums.logger.LoginResultEnum;
 import cn.newfeifan.mall.module.system.enums.oauth2.OAuth2ClientConstants;
 import cn.newfeifan.mall.module.system.enums.sms.SmsSceneEnum;
 import cn.newfeifan.mall.module.system.enums.social.SocialTypeEnum;
+import cn.newfeifan.mall.module.system.service.auth.AdminAuthService;
+import cn.newfeifan.mall.module.system.service.config.SystemConfigService;
+import cn.newfeifan.mall.module.system.service.user.AdminUserService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -38,6 +44,7 @@ import java.util.stream.Collectors;
 
 import static cn.newfeifan.mall.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.newfeifan.mall.framework.common.util.servlet.ServletUtils.getClientIP;
+import static cn.newfeifan.mall.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 import static cn.newfeifan.mall.framework.web.core.util.WebFrameworkUtils.getTerminal;
 import static cn.newfeifan.mall.module.member.enums.DictTypeConstants.*;
 import static cn.newfeifan.mall.module.member.enums.ErrorCodeConstants.*;
@@ -63,6 +70,12 @@ public class MemberAuthServiceImpl implements MemberAuthService {
     private SocialClientApi socialClientApi;
     @Resource
     private OAuth2TokenApi oauth2TokenApi;
+    @Resource
+    private AdminAuthService authService;
+    @Resource
+    private SystemConfigService configService;
+    @Resource
+    private AdminUserService adminUserService;
 
     @Override
     public AppAuthLoginRespVO login(AppAuthLoginReqVO reqVO) {
@@ -89,7 +102,7 @@ public class MemberAuthServiceImpl implements MemberAuthService {
 
         // 获得获得注册用户
         MemberUserDO user = userService.createUserIfAbsent(reqVO.getMobile(), reqVO.getUsername(), userIp, getTerminal());
-        if(user == null){
+        if (user == null) {
             throw exception(USER_MOBILE_NOT_EXISTS);
         }
 
@@ -125,7 +138,7 @@ public class MemberAuthServiceImpl implements MemberAuthService {
         verifyMobileIsMaximize(phone);
 
         //微信能绑定的账号上限校验
-        if(socialUserApi.wxBindIsMax(socialUser.getId())){
+        if (socialUserApi.wxBindIsMax(socialUser.getId())) {
             throw exception(AUTH_SOCIAL_USER_BIND_MAX);
         }
 
@@ -184,6 +197,29 @@ public class MemberAuthServiceImpl implements MemberAuthService {
         return createTokenAfterLoginSuccess(user, user.getMobile(), LoginLogTypeEnum.LOGIN_SOCIAL, reqVO.getOpenId());
     }
 
+    @Override
+    public String redirectLogin() {
+
+        MemberUserDO user = userService.getUser(getLoginUserId());
+        AdminUserDO systemUser = adminUserService.getUser(user.getSystemUsersId());
+        // 判断是否绑定系统用户
+        if (systemUser == null) {
+            throw exception(MEMBER_USER_NOT_BINDING_SYSTEM_USER);
+        }
+
+        // 系统url配置
+        SystemConfigDO redisConfig = configService.getRedisConfig();
+        AuthLoginRespVO token = authService.createTokenAfterLoginSuccess(systemUser.getId(), systemUser.getUsername(), LoginLogTypeEnum.LOGIN_USERNAME);
+
+        // 跳转地址
+        String url = redisConfig.getPlatformDomain();
+        if (!systemUser.getCategoryId().equals(1L)) {
+            url = redisConfig.getMerchantDomain();
+        }
+
+        return url + "/login" + "?accessToken=" + token.getAccessToken() + "&refreshToken=" + token.getRefreshToken();
+    }
+
     @Override
     public AppAuthLoginRespVO weixinMiniAppLogin(AppAuthWeixinMiniAppLoginReqVO reqVO) {
         // 获得对应的手机号信息
@@ -274,14 +310,14 @@ public class MemberAuthServiceImpl implements MemberAuthService {
     public void sendSmsCode(Long userId, AppAuthSmsSendReqVO reqVO) {
         // 情况 1:如果是修改手机场景,需要校验新手机号是否已经注册,说明不能使用该手机了
         if (Objects.equals(reqVO.getScene(), SmsSceneEnum.MEMBER_UPDATE_MOBILE.getScene())) {
-            MemberUserDO user = userService.getUserByMobile(reqVO.getMobile(),userId);
+            MemberUserDO user = userService.getUserByMobile(reqVO.getMobile(), userId);
             if (user == null) {
                 throw exception(USER_MOBILE_IS_ERROR);
             }
         }
         // 情况 2:如果是重置密码场景,需要校验手机号是存在的
         if (Objects.equals(reqVO.getScene(), SmsSceneEnum.MEMBER_RESET_PASSWORD.getScene())) {
-            MemberUserDO user = userService.getUserByMobile(reqVO.getMobile(),userId);
+            MemberUserDO user = userService.getUserByMobile(reqVO.getMobile(), userId);
             if (user == null) {
                 throw exception(USER_MOBILE_NOT_EXISTS);
             }
@@ -293,7 +329,7 @@ public class MemberAuthServiceImpl implements MemberAuthService {
             reqVO.setMobile(user.getMobile());
         }
         //情况 4:如果是修改手机号时,输入新的手机号,需要校验手机号是否绑定上限
-        if(Objects.equals(reqVO.getScene(), SmsSceneEnum.MEMBER_UPDATE_NEW_MOBILE.getScene())){
+        if (Objects.equals(reqVO.getScene(), SmsSceneEnum.MEMBER_UPDATE_NEW_MOBILE.getScene())) {
             verifyMobileIsMaximize(reqVO.getMobile());
         }
 
@@ -333,6 +369,7 @@ public class MemberAuthServiceImpl implements MemberAuthService {
 
     /**
      * 校验手机号是否达到上限
+     *
      * @param mobile 手机号
      */
     private void verifyMobileIsMaximize(String mobile) {

+ 10 - 3
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/dal/dataobject/oauth2/OAuth2AccessTokenDO.java

@@ -15,7 +15,6 @@ import java.util.List;
 
 /**
  * OAuth2 访问令牌 DO
- *
  * 如下字段,暂时未使用,暂时不支持:
  * user_name、authentication(用户信息)
  *
@@ -46,13 +45,11 @@ public class OAuth2AccessTokenDO extends TenantBaseDO {
     private Long userId;
     /**
      * 用户类型
-     *
      * 枚举 {@link UserTypeEnum}
      */
     private Integer userType;
     /**
      * 客户端编号
-     *
      * 关联 {@link OAuth2ClientDO#getId()}
      */
     private String clientId;
@@ -66,4 +63,14 @@ public class OAuth2AccessTokenDO extends TenantBaseDO {
      */
     private LocalDateTime expiresTime;
 
+    /**
+     * 当前用户商户
+     */
+    private Long shopId;
+
+    /**
+     * 当期用户店铺
+     */
+    private Long merchantId;
+
 }

+ 4 - 3
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/dal/dataobject/user/AdminUserDO.java

@@ -39,7 +39,6 @@ public class AdminUserDO extends TenantBaseDO {
     private String username;
     /**
      * 加密后的密码
-     *
      * 因为目前使用 {@link BCryptPasswordEncoder} 加密器,所以无需自己处理 salt 盐
      */
     private String password;
@@ -70,7 +69,6 @@ public class AdminUserDO extends TenantBaseDO {
     private String mobile;
     /**
      * 用户性别
-     *
      * 枚举类 {@link SexEnum}
      */
     private Integer sex;
@@ -80,7 +78,6 @@ public class AdminUserDO extends TenantBaseDO {
     private String avatar;
     /**
      * 帐号状态
-     *
      * 枚举 {@link CommonStatusEnum}
      */
     private Integer status;
@@ -92,6 +89,10 @@ public class AdminUserDO extends TenantBaseDO {
      * 最后登录时间
      */
     private LocalDateTime loginDate;
+    /**
+     * 用户类型
+     */
+    private Long categoryId;
 
     /**
      * 店铺id

+ 17 - 0
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/mq/message/login/LoginSendMessage.java

@@ -0,0 +1,17 @@
+package cn.newfeifan.mall.module.system.mq.message.login;
+
+import cn.newfeifan.mall.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+public class LoginSendMessage {
+
+    /**
+     * 当前登录信息
+     */
+    @NotNull(message = "当前登录信息")
+    private OAuth2AccessTokenDO oAuth2AccessTokenDO;
+
+}

+ 28 - 0
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/mq/producer/login/LoginProducer.java

@@ -0,0 +1,28 @@
+package cn.newfeifan.mall.module.system.mq.producer.login;
+
+import cn.newfeifan.mall.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
+import cn.newfeifan.mall.module.system.mq.message.login.LoginSendMessage;
+import cn.newfeifan.mall.module.system.mq.message.mail.MailSendMessage;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.ApplicationContext;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+@Slf4j
+@Component
+public class LoginProducer {
+    @Resource
+    private ApplicationContext applicationContext;
+
+    /**
+     * 发送 {@link MailSendMessage} 消息
+     *
+     * @param oAuth2AccessTokenDO 当前登录信息
+     */
+    public void sendLoginMessage(OAuth2AccessTokenDO oAuth2AccessTokenDO) {
+        LoginSendMessage message = new LoginSendMessage()
+                .setOAuth2AccessTokenDO(oAuth2AccessTokenDO);
+        applicationContext.publishEvent(message);
+    }
+}

+ 11 - 0
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/auth/AdminAuthService.java

@@ -2,6 +2,7 @@ package cn.newfeifan.mall.module.system.service.auth;
 
 import cn.newfeifan.mall.module.system.controller.admin.auth.vo.*;
 import cn.newfeifan.mall.module.system.dal.dataobject.user.AdminUserDO;
+import cn.newfeifan.mall.module.system.enums.logger.LoginLogTypeEnum;
 
 import javax.validation.Valid;
 
@@ -70,4 +71,14 @@ public interface AdminAuthService {
      */
     AuthLoginRespVO refreshToken(String refreshToken);
 
+    /**
+     * 创建访问令牌,使用账号密码
+     *
+     * @param userId 用户编号
+     * @param username 用户账号
+     * @param logType 日志类型
+     * @return 访问令牌
+     */
+    AuthLoginRespVO createTokenAfterLoginSuccess(Long userId, String username, LoginLogTypeEnum logType);
+
 }

+ 1 - 1
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/auth/AdminAuthServiceImpl.java

@@ -191,7 +191,7 @@ public class AdminAuthServiceImpl implements AdminAuthService {
         }
     }
 
-    private AuthLoginRespVO createTokenAfterLoginSuccess(Long userId, String username, LoginLogTypeEnum logType) {
+    public AuthLoginRespVO createTokenAfterLoginSuccess(Long userId, String username, LoginLogTypeEnum logType) {
         // 插入登陆日志
         createLoginLog(userId, username, logType, LoginResultEnum.SUCCESS);
         // 创建访问令牌

+ 5 - 1
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/oauth2/OAuth2TokenServiceImpl.java

@@ -14,12 +14,12 @@ import cn.newfeifan.mall.module.system.dal.dataobject.oauth2.OAuth2RefreshTokenD
 import cn.newfeifan.mall.module.system.dal.mysql.oauth2.OAuth2AccessTokenMapper;
 import cn.newfeifan.mall.module.system.dal.mysql.oauth2.OAuth2RefreshTokenMapper;
 import cn.newfeifan.mall.module.system.dal.redis.oauth2.OAuth2AccessTokenRedisDAO;
+import cn.newfeifan.mall.module.system.mq.producer.login.LoginProducer;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
 import java.time.LocalDateTime;
-import java.util.Calendar;
 import java.util.List;
 
 import static cn.newfeifan.mall.framework.common.exception.util.ServiceExceptionUtil.exception0;
@@ -43,6 +43,8 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService {
 
     @Resource
     private OAuth2ClientService oauth2ClientService;
+    @Resource
+    private LoginProducer loginProducer;
 
     @Override
     @Transactional
@@ -143,6 +145,8 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService {
         oauth2AccessTokenMapper.insert(accessTokenDO);
         // 记录到 Redis 中
         oauth2AccessTokenRedisDAO.set(accessTokenDO);
+        // 发送消息, 更新用户的商户更店铺信息
+        loginProducer.sendLoginMessage(accessTokenDO);
         return accessTokenDO;
     }
 

+ 8 - 0
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/user/AdminUserService.java

@@ -215,4 +215,12 @@ public interface AdminUserService {
      */
     List<Long> getUserIdsByShop(Long shopId);
 
+    /**
+     * 判断是否是系统用户
+     *
+     * @param mobile         手机号
+     * @param isPtSystemUser 是否是pt系统用户
+     * @return 是否是系统用户
+     */
+    Boolean isSystemUser(String mobile, boolean isPtSystemUser);
 }

+ 14 - 1
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/user/AdminUserServiceImpl.java

@@ -284,6 +284,7 @@ public class AdminUserServiceImpl implements AdminUserService {
 
     /**
      * 获得部门条件:查询指定部门的子部门编号们,包括自身
+     *
      * @param deptId 部门编号
      * @return 部门编号集合
      */
@@ -382,6 +383,7 @@ public class AdminUserServiceImpl implements AdminUserService {
 
     /**
      * 校验旧密码
+     *
      * @param id          用户 id
      * @param oldPassword 旧密码
      */
@@ -457,7 +459,7 @@ public class AdminUserServiceImpl implements AdminUserService {
 
     @Override
     public List<Long> getUserIdsByShop(Long shopId) {
-        if(shopId != null){
+        if (shopId != null) {
             List<AdminUserDO> adminUserDOS = userMapper.selectList(new LambdaQueryWrapper<AdminUserDO>()
                     .eq(AdminUserDO::getShopId, shopId)
             );
@@ -466,6 +468,17 @@ public class AdminUserServiceImpl implements AdminUserService {
         return null;
     }
 
+    @Override
+    public Boolean isSystemUser(String mobile, boolean isPtSystemUser) {
+        // 判断是否是平台系统用户
+        if (isPtSystemUser) {
+            return userMapper.selectOne(AdminUserDO::getMobile, mobile, AdminUserDO::getCategoryId, 1) != null;
+        } else {
+            // 判断是否是商户系统用户
+            return userMapper.selectOne(AdminUserDO::getMobile, mobile, AdminUserDO::getCategoryId, 3) != null;
+        }
+    }
+
     /**
      * 对密码进行加密
      *