he2802 1 рік тому
батько
коміт
4e03bf98c9

+ 42 - 0
zhongzheng-admin-business/src/main/java/com/zhongzheng/controller/common/LoginController.java

@@ -0,0 +1,42 @@
+package com.zhongzheng.controller.common;
+
+import com.zhongzheng.common.core.controller.BaseController;
+import com.zhongzheng.common.core.domain.AjaxResult;
+import com.zhongzheng.modules.company.bo.UserBsAccountLoginBo;
+import com.zhongzheng.modules.company.service.ICompanyUserService;
+import com.zhongzheng.modules.user.bo.*;
+import com.zhongzheng.modules.user.service.IUserService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Map;
+
+/**
+ * 客户端用户Controller
+ *
+ * @author hjl
+ * @date 2021-06-08
+ */
+@Api(value = "登录控制器", tags = {"登录控制器"})
+@RequiredArgsConstructor(onConstructor_ = @Autowired)
+@RestController
+@RequestMapping("/bs/common/")
+public class LoginController extends BaseController {
+
+    private final ICompanyUserService iCompanyUserService;
+
+
+    @ApiOperation("账号登录")
+    @PostMapping("/account_login")
+    public AjaxResult account_login(@RequestBody UserBsAccountLoginBo bo) {
+        Map<String,Object> map = iCompanyUserService.accountLogin(bo);
+        return AjaxResult.success(map);
+    }
+
+}

+ 2 - 13
zhongzheng-admin-business/src/main/java/com/zhongzheng/controller/company/CompanyUserController.java

@@ -30,7 +30,7 @@ import io.swagger.annotations.ApiOperation;
 
 /**
  * 企业用户Controller
- * 
+ *
  * @author ruoyi
  * @date 2024-03-19
  */
@@ -54,18 +54,7 @@ public class CompanyUserController extends BaseController {
         return getDataTable(list);
     }
 
-    /**
-     * 导出企业用户列表
-     */
-    @ApiOperation("导出企业用户列表")
-    @PreAuthorize("@ss.hasPermi('system:user:export')")
-    @Log(title = "企业用户", businessType = BusinessType.EXPORT)
-    @GetMapping("/export")
-    public AjaxResult<CompanyUserVo> export(CompanyUserQueryBo bo) {
-        List<CompanyUserVo> list = iCompanyUserService.queryList(bo);
-        ExcelUtil<CompanyUserVo> util = new ExcelUtil<CompanyUserVo>(CompanyUserVo.class);
-        return util.exportExcel(list, "企业用户");
-    }
+
 
     /**
      * 获取企业用户详细信息

+ 7 - 0
zhongzheng-common/src/main/java/com/zhongzheng/common/constant/Constants.java

@@ -64,6 +64,8 @@ public class Constants
 
     public static final String WX_LOGIN_TOKEN_KEY = "wx_login_tokens:";
 
+    public static final String BS_LOGIN_TOKEN_KEY = "bs_login_tokens:";
+
 
     /**
      * 防重提交 redis key
@@ -98,6 +100,9 @@ public class Constants
     public static final String WX_TOKEN_PREFIX = "WX ";
 
 
+    public static final String BS_TOKEN_PREFIX = "BS ";
+
+
     public static final String REGISTER_SMS = "REGISTER-";
     public static final String FORGET_SMS = "FORGET-";
     public static final String LOGIN_SMS = "LOGIN-";
@@ -112,6 +117,8 @@ public class Constants
 
     public static final String WX_LOGIN_USER_KEY = "wx_login_user_key";
 
+    public static final String BS_LOGIN_USER_KEY = "bs_login_user_key";
+
 
 
 

+ 28 - 9
zhongzheng-framework/src/main/java/com/zhongzheng/framework/security/filter/JwtAuthenticationTokenFilter.java

@@ -5,7 +5,9 @@ import cn.hutool.http.HttpStatus;
 import com.zhongzheng.common.core.domain.AjaxResult;
 import com.zhongzheng.common.core.domain.model.TopLoginUser;
 import com.zhongzheng.common.exception.CustomException;
+import com.zhongzheng.framework.web.service.BsTokenService;
 import com.zhongzheng.framework.web.service.TopTokenService;
+import com.zhongzheng.modules.company.entity.ClientBsLoginUser;
 import com.zhongzheng.modules.user.entity.ClientLoginSeller;
 import com.zhongzheng.modules.user.entity.ClientLoginUser;
 import com.zhongzheng.common.core.domain.model.LoginUser;
@@ -44,6 +46,9 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter
     @Autowired
     private TopTokenService topTokenService;
 
+    @Autowired
+    private BsTokenService bsTokenService;
+
     @Value("${mybatis-plus.tenant.enabled-tenant:true}")
     private boolean enabledTenant;
 
@@ -78,18 +83,32 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter
                         SecurityContextHolder.getContext().setAuthentication(authenticationToken);
                     }
                 }else{
-                    //子系统
-                    LoginUser loginUser = null;
+                    String bsToken = bsTokenService.getToken(request);
+                    if(Validator.isNotEmpty(bsToken)){
+                        ClientBsLoginUser clientBsLoginUser = bsTokenService.getLoginUser(request);
+                        if (Validator.isNotNull(clientBsLoginUser) && Validator.isNull(SecurityUtils.getAuthentication()))
+                        {
+                            bsTokenService.verifyToken(clientBsLoginUser);
+                            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(clientBsLoginUser, null, null);
+                            authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
+                            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
+                        }
 
-                    loginUser = tokenService.getLoginUser(request);
+                    }else{
+                        //子系统
+                        LoginUser loginUser = null;
 
-                    if (Validator.isNotNull(loginUser) && Validator.isNull(SecurityUtils.getAuthentication()))
-                    {
-                        tokenService.verifyToken(loginUser);
-                        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
-                        authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
-                        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
+                        loginUser = tokenService.getLoginUser(request);
+
+                        if (Validator.isNotNull(loginUser) && Validator.isNull(SecurityUtils.getAuthentication()))
+                        {
+                            tokenService.verifyToken(loginUser);
+                            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
+                            authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
+                            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
+                        }
                     }
+
                 }
             }
         }catch (Exception e){

+ 260 - 0
zhongzheng-framework/src/main/java/com/zhongzheng/framework/web/service/BsTokenService.java

@@ -0,0 +1,260 @@
+package com.zhongzheng.framework.web.service;
+
+import cn.hutool.core.lang.Validator;
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.http.useragent.UserAgent;
+import cn.hutool.http.useragent.UserAgentUtil;
+import com.zhongzheng.common.constant.Constants;
+import com.zhongzheng.common.core.redis.RedisCache;
+import com.zhongzheng.common.utils.ServletUtils;
+import com.zhongzheng.common.utils.ip.AddressUtils;
+import com.zhongzheng.common.utils.ip.IpUtils;
+import com.zhongzheng.modules.company.entity.ClientBsLoginUser;
+import com.zhongzheng.modules.user.bo.UserLoginKeyAddBo;
+import com.zhongzheng.modules.user.domain.User;
+import com.zhongzheng.modules.user.entity.ClientLoginUser;
+import com.zhongzheng.modules.user.service.IUserLoginKeyService;
+import com.zhongzheng.modules.user.service.IUserService;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * token验证处理
+ *
+ * @author zhongzheng
+ */
+@Component
+public class BsTokenService
+{
+    // 令牌自定义标识
+    @Value("${token.header}")
+    private String header;
+
+    // 令牌秘钥
+    @Value("${token.secret}")
+    private String secret;
+
+    // 令牌有效期(默认30分钟)
+    @Value("${token.expireTime}")
+    private int expireTime;
+
+    protected static final long MILLIS_SECOND = 1000;
+
+    protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;
+
+    private static final Long MILLIS_MINUTE_TEN = 20 * 60 * 1000L;
+
+    @Autowired
+    private RedisCache redisCache;
+
+
+    @Autowired
+    private IUserLoginKeyService iUserLoginKeyService;
+
+    @Resource
+    private AuthenticationManager authenticationManager;
+
+    /**
+     * 获取用户身份信息
+     *
+     * @return 用户信息
+     */
+    public ClientBsLoginUser getLoginUser(HttpServletRequest request) {
+        //测试用户
+        String test_token = request.getHeader("X-Auth-Token");
+        if("test".equals(test_token)){
+            return getTestUser();
+        }
+        // 获取请求携带的令牌
+        String token = getToken(request);
+        if (Validator.isNotEmpty(token))
+        {
+            Claims claims = parseToken(token);
+            // 解析对应的权限以及用户信息
+            String uuid = (String) claims.get(Constants.BS_LOGIN_USER_KEY);
+            if(!iUserLoginKeyService.queryByUserKey(uuid)){
+                ClientBsLoginUser errorUser =  new ClientBsLoginUser();
+                return errorUser;
+            }
+            String userKey = getTokenKey(uuid);
+            ClientBsLoginUser user = redisCache.getCacheObject(userKey);
+            return user;
+        }
+        return null;
+    }
+
+    private ClientBsLoginUser getTestUser(){
+
+        return null;
+    }
+
+    /**
+     * 设置用户身份信息
+     */
+    public void setLoginUser(ClientBsLoginUser loginUser)
+    {
+        if (Validator.isNotNull(loginUser) && Validator.isNotEmpty(loginUser.getToken()))
+        {
+            refreshToken(loginUser);
+        }
+    }
+
+    /**
+     * 删除用户身份信息
+     */
+    public void delLoginUser(String token)
+    {
+        if (Validator.isNotEmpty(token))
+        {
+            String userKey = getTokenKey(token);
+            redisCache.deleteObject(userKey);
+        }
+    }
+
+    /**
+     * 创建令牌
+     *
+     * @param loginUser 用户信息
+     * @return 令牌
+     */
+    public String createToken(ClientBsLoginUser loginUser)
+    {
+        String token = IdUtil.simpleUUID();
+        loginUser.setToken(token);
+        setUserAgent(loginUser);
+        refreshToken(loginUser);
+        Map<String, Object> claims = new HashMap<>();
+        claims.put(Constants.BS_LOGIN_USER_KEY, token);
+        String secret = createToken(claims);
+        if(Validator.isNotEmpty(token)){
+            UserLoginKeyAddBo addBo = new UserLoginKeyAddBo();
+            addBo.setUserId(loginUser.getUser().getUserId());
+            addBo.setUserKey(token);
+            addBo.setIp(loginUser.getIpaddr());
+            addBo.setBrowser(loginUser.getBrowser());
+            addBo.setSecret(secret);
+            iUserLoginKeyService.insertByAddBo(addBo);
+        }
+        return secret;
+    }
+
+    /**
+     * 验证令牌有效期,相差不足20分钟,自动刷新缓存
+     *
+     * @param loginUser
+     * @return 令牌
+     */
+    public void verifyToken(ClientBsLoginUser loginUser)
+    {
+        long expireTime = loginUser.getExpireTime();
+        long currentTime = System.currentTimeMillis();
+        if (expireTime - currentTime <= MILLIS_MINUTE_TEN)
+        {
+            refreshToken(loginUser);
+        }
+    }
+
+    /**
+     * 刷新令牌有效期
+     *
+     * @param loginUser 登录信息
+     */
+    public void refreshToken(ClientBsLoginUser loginUser)
+    {
+        loginUser.setLoginTime(System.currentTimeMillis());
+        loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
+        // 根据uuid将loginUser缓存
+        String userKey = getTokenKey(loginUser.getToken());
+        redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
+    }
+
+    /**
+     * 设置用户代理信息
+     *
+     * @param loginUser 登录信息
+     */
+    public void setUserAgent(ClientBsLoginUser loginUser)
+    {
+        UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent"));
+        String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
+        loginUser.setIpaddr(ip);
+        loginUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip));
+        loginUser.setBrowser(userAgent.getBrowser().getName());
+        loginUser.setOs(userAgent.getOs().getName());
+    }
+
+    /**
+     * 从数据声明生成令牌
+     *
+     * @param claims 数据声明
+     * @return 令牌
+     */
+    private String createToken(Map<String, Object> claims)
+    {
+        String token = Jwts.builder()
+                .setClaims(claims)
+                .signWith(SignatureAlgorithm.HS512, secret).compact();
+        return token;
+    }
+
+    /**
+     * 从令牌中获取数据声明
+     *
+     * @param token 令牌
+     * @return 数据声明
+     */
+    private Claims parseToken(String token)
+    {
+        return Jwts.parser()
+                .setSigningKey(secret)
+                .parseClaimsJws(token)
+                .getBody();
+    }
+
+    /**
+     * 从令牌中获取用户名
+     *
+     * @param token 令牌
+     * @return 用户名
+     */
+    public String getUsernameFromToken(String token)
+    {
+        Claims claims = parseToken(token);
+        return claims.getSubject();
+    }
+
+    /**
+     * 获取请求token
+     *
+     * @param request
+     * @return token
+     */
+    public String getToken(HttpServletRequest request)
+    {
+        String token = request.getHeader(header);
+        if (Validator.isNotEmpty(token) && token.startsWith(Constants.BS_TOKEN_PREFIX))
+        {
+            token = token.replace(Constants.BS_TOKEN_PREFIX, "");
+            return token;
+        }else{
+            return null;
+        }
+
+    }
+
+    private String getTokenKey(String uuid)
+    {
+        return Constants.BS_LOGIN_TOKEN_KEY + uuid;
+    }
+}

+ 62 - 7
zhongzheng-system/src/main/java/com/zhongzheng/modules/company/service/impl/CompanyUserServiceImpl.java → zhongzheng-framework/src/main/java/com/zhongzheng/framework/web/service/CompanyUserServiceImpl.java

@@ -1,24 +1,35 @@
-package com.zhongzheng.modules.company.service.impl;
+package com.zhongzheng.framework.web.service;
 
 import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.lang.Validator;
 import cn.hutool.core.util.StrUtil;
-import com.zhongzheng.common.utils.DateUtils;
-import org.springframework.stereotype.Service;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.github.pagehelper.Page;
+import com.zhongzheng.common.constant.Constants;
+import com.zhongzheng.common.enums.UserStatus;
+import com.zhongzheng.common.exception.CustomException;
+import com.zhongzheng.common.utils.AES;
+import com.zhongzheng.common.utils.DateUtils;
+import com.zhongzheng.common.utils.SecurityUtils;
 import com.zhongzheng.modules.company.bo.CompanyUserAddBo;
-import com.zhongzheng.modules.company.bo.CompanyUserQueryBo;
 import com.zhongzheng.modules.company.bo.CompanyUserEditBo;
+import com.zhongzheng.modules.company.bo.CompanyUserQueryBo;
+import com.zhongzheng.modules.company.bo.UserBsAccountLoginBo;
 import com.zhongzheng.modules.company.domain.CompanyUser;
+import com.zhongzheng.modules.company.entity.ClientBsLoginUser;
 import com.zhongzheng.modules.company.mapper.CompanyUserMapper;
-import com.zhongzheng.modules.company.vo.CompanyUserVo;
 import com.zhongzheng.modules.company.service.ICompanyUserService;
+import com.zhongzheng.modules.company.vo.CompanyUserVo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
 
+import java.io.InputStream;
 import java.util.Collection;
-import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 
 /**
@@ -30,12 +41,56 @@ import java.util.stream.Collectors;
 @Service
 public class CompanyUserServiceImpl extends ServiceImpl<CompanyUserMapper, CompanyUser> implements ICompanyUserService {
 
+
+    @Autowired
+    private BsTokenService bsTokenService;
+
+
     @Override
     public CompanyUserVo queryById(Long userId){
         CompanyUser db = this.baseMapper.selectById(userId);
         return BeanUtil.toBean(db, CompanyUserVo.class);
     }
 
+    @Override
+    public Map<String, Object> accountLogin(UserBsAccountLoginBo bo) {
+        if(Validator.isEmpty(bo.getAccount())){
+            throw new CustomException("账号不能为空");
+        }
+        CompanyUser user = getOne(new LambdaQueryWrapper<CompanyUser>()
+                .eq(CompanyUser::getUsername, bo.getAccount()));
+        if(Validator.isEmpty(user)){
+            throw new CustomException("登录信息错误");
+        } else if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
+        {
+            throw new CustomException("对不起,您的账号:已停用");
+        }
+        String password = null;
+        if(bo.getPwd().length()>20){
+            String rsaPrivate = null;
+            try {
+                InputStream certStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("config/pri.key");
+                rsaPrivate = AES.getStringByInputStream_1(certStream);
+                certStream.close();
+                password = AES.decrypt(bo.getPwd(),rsaPrivate);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }else{
+            password = bo.getPwd();
+        }
+        if (!SecurityUtils.matchesPassword(password,user.getPassword()))
+        {
+            throw new CustomException("登录信息错误");
+        }
+        ClientBsLoginUser loginUser = new ClientBsLoginUser();
+        loginUser.setUser(user);
+        Map<String,Object> map = new HashMap<>();
+        map.put(Constants.TOKEN,bsTokenService.createToken(loginUser));
+        map.put("user_account",user.getUsername());
+        return map;
+    }
+
     @Override
     public List<CompanyUserVo> queryList(CompanyUserQueryBo bo) {
         LambdaQueryWrapper<CompanyUser> lqw = Wrappers.lambdaQuery();

+ 26 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/company/bo/UserBsAccountLoginBo.java

@@ -0,0 +1,26 @@
+package com.zhongzheng.modules.company.bo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+
+/**
+ * 客户端用户编辑对象 user
+ *
+ * @author ruoyi
+ * @date 2021-06-08
+ */
+@Data
+@ApiModel("客户端用户账号登录对象")
+public class UserBsAccountLoginBo {
+    @ApiModelProperty("手机号/身份证")
+    @NotNull(message = "账号不能为空")
+    private String account;
+    @ApiModelProperty("密码")
+    @NotNull(message = "密码不能为空")
+    private String pwd;
+
+}

+ 65 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/company/entity/ClientBsLoginUser.java

@@ -0,0 +1,65 @@
+package com.zhongzheng.modules.company.entity;
+
+import com.zhongzheng.modules.company.domain.CompanyUser;
+import com.zhongzheng.modules.user.domain.User;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+/**
+ * 登录用户身份权限
+ *
+ * @author zhongzheng
+ */
+
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+public class ClientBsLoginUser
+{
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 用户唯一标识
+     */
+    private String token;
+
+    /**
+     * 登录时间
+     */
+    private Long loginTime;
+
+    /**
+     * 过期时间
+     */
+    private Long expireTime;
+
+    /**
+     * 登录IP地址
+     */
+    private String ipaddr;
+
+    /**
+     * 登录地点
+     */
+    private String loginLocation;
+
+    /**
+     * 浏览器类型
+     */
+    private String browser;
+
+    /**
+     * 操作系统
+     */
+    private String os;
+
+
+    /**
+     * 用户信息
+     */
+    private CompanyUser user;
+
+
+
+}

+ 5 - 0
zhongzheng-system/src/main/java/com/zhongzheng/modules/company/service/ICompanyUserService.java

@@ -1,14 +1,17 @@
 package com.zhongzheng.modules.company.service;
 
+import com.zhongzheng.modules.company.bo.UserBsAccountLoginBo;
 import com.zhongzheng.modules.company.domain.CompanyUser;
 import com.zhongzheng.modules.company.vo.CompanyUserVo;
 import com.zhongzheng.modules.company.bo.CompanyUserQueryBo;
 import com.zhongzheng.modules.company.bo.CompanyUserAddBo;
 import com.zhongzheng.modules.company.bo.CompanyUserEditBo;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.zhongzheng.modules.user.bo.UserAppAccountLoginBo;
 
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 企业用户Service接口
@@ -23,6 +26,8 @@ public interface ICompanyUserService extends IService<CompanyUser> {
 	 */
 	CompanyUserVo queryById(Long userId);
 
+	Map<String,Object> accountLogin(UserBsAccountLoginBo bo);
+
 	/**
 	 * 查询列表
 	 */