dangsn
2024-06-14 df2181e8f201f48c57e29cf247b81e85189f7f73
Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/service/impl/LoginServiceImpl.java
@@ -1,8 +1,12 @@
package com.vci.web.service.impl;
import com.vci.client.logon.base.LogonHandler;
import com.vci.client.mw.ClientSessionUtility;
import com.vci.corba.common.PLException;
import com.vci.corba.common.data.InvocationInfo;
import com.vci.corba.framework.data.DeptInfo;
import com.vci.corba.framework.data.LoginResult;
import com.vci.corba.framework.data.LoginState;
import com.vci.corba.framework.data.MachineInfo;
import com.vci.frameworkcore.ajaxTask.SmUserUnLockTask;
import com.vci.frameworkcore.ajaxTask.SmUserUnLockTaskManager;
import com.vci.frameworkcore.compatibility.ISmFunctionQueryService;
@@ -13,16 +17,12 @@
import com.vci.starter.web.annotation.bus.VciLoginAfter;
import com.vci.starter.web.annotation.bus.VciLogoutBefore;
import com.vci.starter.web.annotation.bus.VciLogoutPlugin;
import com.vci.starter.web.constant.TokenKeyConstant;
import com.vci.starter.web.exception.VciBaseException;
import com.vci.starter.web.interceptor.VciSessionForLoginI;
import com.vci.starter.web.pagemodel.RequestClientInfo;
import com.vci.starter.web.pagemodel.SessionInfo;
import com.vci.starter.web.pagemodel.TokenVO;
import com.vci.starter.web.util.ApplicationContextProvider;
import com.vci.starter.web.util.JwtUtils;
import com.vci.starter.web.util.Md5;
import com.vci.starter.web.util.VciBaseUtil;
import com.vci.starter.web.util.*;
import com.vci.web.bo.LoginResultBO;
import com.vci.web.constant.CacheNameConstant;
import com.vci.web.dto.LoginUserDTO;
@@ -33,16 +33,14 @@
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import static com.vci.frameworkcore.constant.FrameWorkBusLangCodeConstant.*;
@@ -142,15 +140,17 @@
        }
        //需要看看是否已经登录了
        String loginKey = CacheNameConstant.cacheKey(CacheNameConstant.VCI_USER_LOGIN, userDTO.getUserId());
        if(redisService.hasKey(loginKey) && !userDTO.isForceLogin() && securityManageProperties.isUserOneLogin()){
        String userIdTokenKey = CacheNameConstant.cacheKey(CacheNameConstant.USERID_TOKEN_KEY, userDTO.getUserId().trim());
        if(redisService.hasKey(userIdTokenKey) && !userDTO.isForceLogin() && securityManageProperties.isUserOneLogin()){
            loginResult.setFailCode(USER_IS_LOGINED);
            loginResult.setFailMsg("当前用户已经在其他地方登录!");
            return loginResult;
        }
        //说明已经登录了,那应该取消原来的登录
        if (redisService.hasKey(loginKey) && userDTO.isForceLogin() && securityManageProperties.isUserOneLogin()) {
            redisService.deleteObject(CacheNameConstant.VCI_USER_LOGIN);
        if (redisService.hasKey(userIdTokenKey) && userDTO.isForceLogin() && securityManageProperties.isUserOneLogin()) {
            String tokenKey = redisService.getCacheObject(userIdTokenKey);
            redisService.deleteObject(tokenKey);
            redisService.deleteObject(userIdTokenKey);
        }
        //2.获取用户的对象.
@@ -172,16 +172,28 @@
        }
        //4、调用平台登录接口,进行登录
        LogonHandler handler = new LogonHandler();
        MachineInfo machine = getMachieInfo(clientInfo);
        machine.country = clientInfo.getCountry();
        machine.language = clientInfo.getLanguage();
        machine.osUser = clientInfo.getOsUser();
        machine.machine = clientInfo.getMachine();
        String token = null;
        try {
            LoginResult chkRes = handler.checkLogin(userDTO.getUserId(), userDTO.getPassword());
            LoginResult chkRes = platformClientUtil.getFrameworkService().checkLogin(userDTO.getUserId(),userDTO.getPassword(), machine);
            loginResult.setFailCode(getErrorCode(chkRes));
            loginResult.setFailMsgArray(new String[]{userDTO.getUserId(), String.valueOf(chkRes.auxInfo)});
            if(chkRes.state == LoginState.Error || chkRes.state == LoginState.Locked || chkRes.state == LoginState.Freeze){
                return loginResult;
            }
            token = chkRes.token;
        } catch (Exception e) {
            loginResult.setFailCode(SYSTEM_ERROR);
            loginResult.setFailMsgArray(new String[]{userDTO.getUserId()});
            return loginResult;
        }
        if(StringUtils.isBlank(token)){
            loginResult.setFailMsg(TOKEN_EMPTY);
            loginResult.setFailMsgArray(new String[]{userDTO.getUserId()});
            return loginResult;
        }
@@ -284,10 +296,25 @@
        user.setPwdWrongCount(0);
        SessionInfo sessionInfo = new SessionInfo();
        sessionInfo.setToken(token);
        //初始化平台的token
        sessionForLogin.initInvocationInfo(sessionInfo);
        //拷贝用户的新到session会话中
        copyUser2SessionInfo(user, sessionInfo, userDTO.getLangCode());
        //拷贝请求信息到session会话中
        copyRequest2SessionInfo(clientInfo, sessionInfo);
        //获取人员所属的部门信息
        try {
            DeptInfo deptInfo = platformClientUtil.getFrameworkService().fetchDeptByUserId(user.getOid());
            sessionInfo.setDeptOid(deptInfo.id);
            sessionInfo.setDeptName(deptInfo.name);
            sessionInfo.setDeptNum(deptInfo.num);
        } catch (PLException e) {
            throw new VciBaseException("获取用户所属部门失败:"+e.getMessage());
        }
        /** //查询所有的角色
        List<SmRoleVO> roleVOList = roleQueryService.listRoleByUserOid(user.getOid(), null);
@@ -306,14 +333,21 @@
            sessionInfo.setFunctionOids(new ArrayList());
        }*/
        loginResult.setSuccess(true);
        sessionInfo.setToken(Md5.md5(VciBaseUtil.getPk() + "_" + user.getId()));
        loginResult.setSessionInfo(sessionInfo);
        //添加到会话信息
        saveSessionInfo(sessionInfo);
        TokenVO tokenVO = saveSessionInfo(sessionInfo);
        loginResult.setTokenVO(tokenVO);
        loginResult.setSuccess(true);
        return loginResult;
    }
    private MachineInfo getMachieInfo(RequestClientInfo clientInfo) {
        MachineInfo machine = new MachineInfo();
        machine.country = clientInfo.getCountry();
        machine.language = clientInfo.getLanguage();
        machine.osUser = clientInfo.getOsUser();
        machine.machine = clientInfo.getMachine();
        return machine;
    }
    /**
@@ -322,14 +356,7 @@
     * @Return com.vci.frameworkcore.pagemodel.SmUserVO
     */
    private SmUserVO getUserByUserId(String userId) {
        String userKey = CacheNameConstant.cacheKey(CacheNameConstant.VCI_USER,userId);
        String userOid = redisService.getCacheObject(userKey);
        String oidKey = CacheNameConstant.cacheKey(CacheNameConstant.VCI_USER_OID, userOid);
        SmUserVO userVO = redisService.getCacheObject(oidKey);
        if(userVO == null || StringUtils.isBlank(userVO.getOid())){
            userVO = userQueryService.getUserByUserId(userId);
        }
        return userVO;
        return userQueryService.getUserByUserId(userId);
    }
@@ -403,16 +430,12 @@
     * 保存会话信息
     * @param sessionInfo 会话信息
     */
    private void saveSessionInfo(SessionInfo sessionInfo){
    private TokenVO saveSessionInfo(SessionInfo sessionInfo){
        if(sessionForLogin == null){
            throw new VciBaseException("没有配置会话存储的服务");
        }
        //将权限信息,放入redis缓存中。以防止session中的信息过多,存入数据库中出现错误
        redisService.setCacheList(sessionInfo.getToken(),sessionInfo.getFunctionOids());
        redisService.expire(sessionInfo.getToken(), 1, TimeUnit.HOURS);
        sessionInfo.setFunctionOids(new ArrayList<>());
        sessionForLogin.saveSessionInfo(sessionInfo);
        WebThreadLocalUtil.setCurrentUserSessionInfoInThread(sessionInfo);
        return sessionForLogin.createToken(sessionInfo);
    }
    /**
@@ -462,6 +485,7 @@
        sessionInfo.setRtxNo(user.getRtxNo());
        sessionInfo.setIMId(user.getIMNo());
        sessionInfo.setPortalId(user.getId());
        sessionInfo.setLastLoginTime(user.getLastLoginTime()!=null?user.getLastLoginTime().getTime(): VciDateUtil.getNowTime());
    }
    /**
@@ -494,69 +518,6 @@
     */
    private void updateUserForLoginSuccess(String userOid){
        userQueryService.updateUserLoginTime(userOid);
    }
    /**
     * 创建许可的信息
     *
     * @param sessionInfo session的信息
     * @return 许可信息
     */
    @Override
    public TokenVO createToken(SessionInfo sessionInfo) {
        return createToken(TokenKeyConstant.TOKEN_KEY_PREFIX_IN_REDIS, sessionInfo);
    }
    /**
     * 创建许可的信息
     * @param key token在redis中的key
     * @param sessionInfo session的信息
     * @return 许可信息
     */
    @Override
    public TokenVO createToken(String key, SessionInfo sessionInfo) {
        if(StringUtils.isBlank(sessionInfo.getToken())) {
            String token = Md5.md5(VciBaseUtil.getPk() + "_" + sessionInfo.getUserId());
            sessionInfo.setToken(token);
        }
        if(StringUtils.isBlank(key)){
            key = TokenKeyConstant.TOKEN_KEY_PREFIX_IN_REDIS;
        }
        refreshToken(key, sessionInfo);
        Map<String,Object> claimsMap = new HashMap<>();
        claimsMap.put(TokenKeyConstant.JWT_TOKEN_KEY,sessionInfo.getToken());
        claimsMap.put(TokenKeyConstant.JWT_USER_KEY,sessionInfo.getUserOid());
        claimsMap.put(TokenKeyConstant.JWT_USER_NAME_KEY,sessionInfo.getUserName());
        claimsMap.put(TokenKeyConstant.JWT_USER_CODE_KEY,sessionInfo.getUserId());
        TokenVO tokenVO = new TokenVO();
        tokenVO.setAccessToken(JwtUtils.createToken(claimsMap));
        tokenVO.setExpireTime(TokenKeyConstant.EXPIRATION);
        return tokenVO;
    }
    /**
     * 刷新token
     * @param sessionInfo session的信息
     */
    @Override
    public void refreshToken(SessionInfo sessionInfo) {
        refreshToken(TokenKeyConstant.TOKEN_KEY_PREFIX_IN_REDIS, sessionInfo);
    }
    /**
     * 刷新token
     * @param key token在redis中的key
     * @param sessionInfo session的信息
     */
    @Override
    public void refreshToken(String key, SessionInfo sessionInfo) {
        if(sessionInfo!=null && StringUtils.isNotBlank(sessionInfo.getToken())){
            if(StringUtils.isBlank(key)){
                key = TokenKeyConstant.TOKEN_KEY_PREFIX_IN_REDIS;
            }
            String redisKey = key + sessionInfo.getToken();
            redisService.setCacheObject(redisKey, sessionInfo, webProperties.getClientSessionAliveMax()!=0?webProperties.getClientSessionAliveMax(): TokenKeyConstant.EXPIRATION, TimeUnit.MINUTES);
        }
    }
    /**