|
|
@@ -1,6 +1,8 @@
|
|
|
package com.sckw.system.service;
|
|
|
|
|
|
import cn.hutool.core.collection.CollUtil;
|
|
|
+import cn.hutool.http.useragent.UserAgent;
|
|
|
+import cn.hutool.http.useragent.UserAgentUtil;
|
|
|
import com.alibaba.fastjson.JSON;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.sckw.core.common.enums.enums.DictEnum;
|
|
|
@@ -12,33 +14,39 @@ import com.sckw.core.model.enums.ClientTypeEnum;
|
|
|
import com.sckw.core.model.enums.SystemTypeEnum;
|
|
|
import com.sckw.core.utils.*;
|
|
|
import com.sckw.core.web.constant.HttpStatus;
|
|
|
+import com.sckw.core.web.constant.RequestConstant;
|
|
|
import com.sckw.core.web.context.LoginUserHolder;
|
|
|
+import com.sckw.core.web.model.LoginUserInfo;
|
|
|
+import com.sckw.core.web.request.RequestUtil;
|
|
|
import com.sckw.excel.utils.ExcelUtil;
|
|
|
import com.sckw.redis.constant.RedisConstant;
|
|
|
import com.sckw.redis.utils.RedissonUtils;
|
|
|
import com.sckw.system.api.model.dto.req.RegisterReqDto;
|
|
|
import com.sckw.system.api.model.dto.req.UpdatePasswordReqDto;
|
|
|
import com.sckw.system.api.model.dto.res.AreaTreeFrontResDto;
|
|
|
+import com.sckw.system.api.model.dto.res.EntCacheResDto;
|
|
|
import com.sckw.system.api.model.dto.res.KwsUserResDto;
|
|
|
import com.sckw.system.api.model.dto.res.RegisterResDto;
|
|
|
import com.sckw.system.api.model.dto.res.SysDictResDto;
|
|
|
import com.sckw.system.dao.*;
|
|
|
import com.sckw.system.dubbo.RemoteSystemServiceImpl;
|
|
|
import com.sckw.system.model.*;
|
|
|
+import com.sckw.system.model.LoginLogs;
|
|
|
import com.sckw.system.api.model.dto.res.RoleInfoDto;
|
|
|
import com.sckw.system.model.report.KwsUserExcel;
|
|
|
import com.sckw.system.model.vo.req.*;
|
|
|
-import com.sckw.system.model.vo.res.KwsUserResVo;
|
|
|
-import com.sckw.system.model.vo.res.KwsUserSystemTypeVo;
|
|
|
-import com.sckw.system.model.vo.res.SalesResp;
|
|
|
+import com.sckw.system.model.vo.res.*;
|
|
|
import com.sckw.system.repository.KwsRoleRepository;
|
|
|
import com.sckw.system.repository.KwsUserRepository;
|
|
|
import com.sckw.system.repository.KwsUserRoleRepository;
|
|
|
+import com.sckw.system.repository.LoginLogsService;
|
|
|
import com.sckw.transport.api.dubbo.TransportRemoteStatisticsService;
|
|
|
+import jakarta.servlet.http.HttpServletRequest;
|
|
|
import jakarta.servlet.http.HttpServletResponse;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.apache.dubbo.config.annotation.DubboReference;
|
|
|
+import org.jetbrains.annotations.NotNull;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
@@ -96,6 +104,8 @@ public class KwsUserService {
|
|
|
|
|
|
private final KwsUserRepository kwsUserRepository;
|
|
|
|
|
|
+ private final LoginLogsService loginLogsService;
|
|
|
+
|
|
|
@DubboReference(version = "1.0.0", group = "design", check = false)
|
|
|
private TransportRemoteStatisticsService transportStatisticsService;
|
|
|
|
|
|
@@ -816,4 +826,470 @@ public class KwsUserService {
|
|
|
return kwsUserResVo;
|
|
|
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据用户ID查询用户信息(头像、姓名、电话、角色、账号状态)
|
|
|
+ *
|
|
|
+ * @param userId 用户ID
|
|
|
+ * @return UserInfoResVo
|
|
|
+ */
|
|
|
+ public UserInfoResVo getUserInfoById(Long userId) {
|
|
|
+ log.info("查询用户信息,用户ID: {}", userId);
|
|
|
+
|
|
|
+ // 1. 查询用户基本信息
|
|
|
+ KwsUser kwsUser = kwsUserRepository.getById(userId);
|
|
|
+ if (Objects.isNull(kwsUser) || kwsUser.getDelFlag() != Global.NO) {
|
|
|
+ throw new SystemException(HttpStatus.QUERY_FAIL_CODE, "用户不存在或已删除");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 查询用户角色信息
|
|
|
+ List<RoleInfoDto> roleInfoList = kwsUserRoleDao.queryRoleList(userId);
|
|
|
+ String roleName = "";
|
|
|
+ if (CollUtil.isNotEmpty(roleInfoList)) {
|
|
|
+ // 获取第一个角色名称,如有多个角色可用逗号分隔
|
|
|
+ roleName = roleInfoList.stream()
|
|
|
+ .map(RoleInfoDto::getRoleName)
|
|
|
+ .collect(Collectors.joining(","));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 组装返回结果
|
|
|
+ String statusDesc = kwsUser.getStatus() != null && kwsUser.getStatus() == Global.YES ? "锁定" : "正常";
|
|
|
+
|
|
|
+ return UserInfoResVo.builder()
|
|
|
+ .userId(kwsUser.getId())
|
|
|
+ .photo(kwsUser.getPhoto())
|
|
|
+ .name(kwsUser.getName())
|
|
|
+ .phone(kwsUser.getPhone())
|
|
|
+ .roleName(roleName)
|
|
|
+ .status(kwsUser.getStatus())
|
|
|
+ .statusDesc(statusDesc)
|
|
|
+ .build();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 修改密码(叉车APP)
|
|
|
+ *
|
|
|
+ * @param userId 用户ID
|
|
|
+ * @param oldPassword 旧密码
|
|
|
+ * @param newPassword 新密码
|
|
|
+ */
|
|
|
+ public void updatePasswordForApp(Long userId, String oldPassword, String newPassword,
|
|
|
+ String clientType, Integer systemType, String deviceId) {
|
|
|
+ log.info("修改密码,用户ID: {}", userId);
|
|
|
+
|
|
|
+ // 1. 查询用户信息
|
|
|
+ KwsUser kwsUser = checkUserBase(userId);
|
|
|
+
|
|
|
+ // 2. 校验旧密码
|
|
|
+ String account = kwsUser.getAccount();
|
|
|
+ String currentPwd = kwsUser.getPassword();
|
|
|
+ String salt = kwsUser.getSalt();
|
|
|
+ oldPassword = PasswordUtils.md5(oldPassword);
|
|
|
+ checkPassword(account, oldPassword, currentPwd, salt);
|
|
|
+
|
|
|
+ // 3. 校验新密码是否与旧密码相同
|
|
|
+ if (PasswordUtils.validatePassword(kwsUser.getAccount() + newPassword, currentPwd, kwsUser.getSalt())) {
|
|
|
+ throw new SystemException(HttpStatus.CODE_10301, "新密码不能与旧密码相同");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 修改密码
|
|
|
+ updatePwd(newPassword, kwsUser);
|
|
|
+ // 5. 清除当前登录用户的token缓存
|
|
|
+ clearCurrentUserToken(deviceId,kwsUser);
|
|
|
+ log.info("密码修改成功,用户ID: {}", userId);
|
|
|
+ }
|
|
|
+ private void clearCurrentUserToken(String deviceId, KwsUser kwsUser) {
|
|
|
+ try {
|
|
|
+ if (kwsUser.getId()!= null) {
|
|
|
+ for (ClientTypeEnum clientTypeEnum : ClientTypeEnum.values()) {
|
|
|
+ // 清除当前用户的refreshToken
|
|
|
+ String refreshTokenKey = Global.getFullRefreshTokenKey(clientTypeEnum.getValue(), kwsUser.getId(), deviceId);
|
|
|
+ RedissonUtils.delete(refreshTokenKey);
|
|
|
+ }
|
|
|
+
|
|
|
+ for (SystemTypeEnum systemTypeEnum : SystemTypeEnum.values()) {
|
|
|
+ // 清除当前用户的登录信息缓存
|
|
|
+ String loginKey = Global.getFullUserLoginKey(systemTypeEnum.getCode(), kwsUser.getId());
|
|
|
+ RedissonUtils.delete(loginKey);
|
|
|
+ }
|
|
|
+ log.info("已清除当前用户token缓存,userId:{}", kwsUser.getId());
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("清除当前用户token缓存失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 用户登录(叉车APP)
|
|
|
+ *
|
|
|
+ * @param account 账号
|
|
|
+ * @param password 密码
|
|
|
+ * @param systemType 系统类型
|
|
|
+ * @param request HTTP请求(用于记录登录日志)
|
|
|
+ * @return LoginResVo
|
|
|
+ */
|
|
|
+ public LoginResVo login(String account, String password, Integer systemType, HttpServletRequest request) {
|
|
|
+ log.info("用户登录,账号: {}, 系统类型: {}", account, systemType);
|
|
|
+
|
|
|
+ // 1. 查询用户信息
|
|
|
+ KwsUser kwsUser = getKwsUser(account, systemType);
|
|
|
+ password= PasswordUtils.md5(password);
|
|
|
+ // 3. 校验密码
|
|
|
+ checkPassword(account, password, kwsUser.getPassword(), kwsUser.getSalt());
|
|
|
+
|
|
|
+ // 4. 查询用户角色
|
|
|
+ List<RoleInfoDto> roleInfoList = kwsUserRoleDao.queryRoleList(kwsUser.getId());
|
|
|
+ if (CollUtil.isEmpty(roleInfoList)){
|
|
|
+ throw new SystemException(HttpStatus.CODE_60603, "该用户没有分配角色");
|
|
|
+ }
|
|
|
+ List<String> roleNames = Arrays.asList("铲车司机", "门卫");
|
|
|
+ roleInfoList = roleInfoList.stream().filter(x -> roleNames.contains(x.getRoleName()))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ if (CollUtil.isEmpty(roleInfoList)) {
|
|
|
+ throw new SystemException(HttpStatus.CODE_60603, "你没有登录该系统权限");
|
|
|
+ }
|
|
|
+
|
|
|
+ String roleName = roleInfoList.stream()
|
|
|
+ .map(RoleInfoDto::getRoleName)
|
|
|
+ .collect(Collectors.joining(","));
|
|
|
+ Long roleId = roleInfoList.get(0).getRoleId();
|
|
|
+
|
|
|
+ // 5. 获取客户端类型
|
|
|
+ String clientType = request != null ? request.getHeader(RequestConstant.CLIENT_TYPE) : null;
|
|
|
+ if (StringUtils.isBlank(clientType)) {
|
|
|
+ clientType = ClientTypeEnum.app.getValue(); // 默认使用app
|
|
|
+ }
|
|
|
+
|
|
|
+ // 6. 生成token并缓存
|
|
|
+
|
|
|
+ String token = generateToken(kwsUser.getId(), account, clientType, systemType);
|
|
|
+ log.info("生成token成功,用户ID: {}, token: {}", kwsUser.getId(), token);
|
|
|
+ // 7. 缓存用户登录信息
|
|
|
+ saveUserToCache(kwsUser, systemType, clientType, roleId);
|
|
|
+
|
|
|
+ // 8. 缓存企业信息
|
|
|
+ KwsEnterprise kwsEnterprise = null;
|
|
|
+ if ( kwsUser.getEntId() != null) {
|
|
|
+ kwsEnterprise = saveEntToCache(kwsUser.getEntId());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 9. 缓存菜单权限
|
|
|
+ List<KwsMenuResVo> kwsMenuResVos = saveMenusToCache(kwsUser.getId(), systemType, roleId);
|
|
|
+
|
|
|
+ // 10. 组装返回结果
|
|
|
+ LoginResVo result = LoginResVo.builder()
|
|
|
+ .userId(kwsUser.getId())
|
|
|
+ .name(kwsUser.getName())
|
|
|
+ .account(kwsUser.getAccount())
|
|
|
+ .phone(kwsUser.getPhone())
|
|
|
+ .photo(kwsUser.getPhoto())
|
|
|
+ .roleId(roleId)
|
|
|
+ .roleName(roleName)
|
|
|
+ .token(token)
|
|
|
+ .entId(kwsUser.getEntId())
|
|
|
+ .enterpriseName(Optional.ofNullable(kwsEnterprise).map(KwsEnterprise::getFirmName).orElse(""))
|
|
|
+ .menuList(kwsMenuResVos)
|
|
|
+ .systemType(kwsUser.getSystemType())
|
|
|
+ .build();
|
|
|
+
|
|
|
+ // 11. 记录登录日志(首次登录)
|
|
|
+ if (request != null) {
|
|
|
+ saveLoginLogs(kwsUser.getId(), request, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("登录成功,用户ID: {}", kwsUser.getId());
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 切换账号(叉车APP)
|
|
|
+ *
|
|
|
+ * @param account 账号
|
|
|
+ * @param password 密码
|
|
|
+ * @param systemType 系统类型
|
|
|
+ * @param request HTTP请求(可选,用于记录登录日志)
|
|
|
+ * @return SwitchAccountResVo
|
|
|
+ */
|
|
|
+ public SwitchAccountResVo switchAccount(String account, String password, Integer systemType, HttpServletRequest request) {
|
|
|
+ log.info("切换账号,账号: {}, 系统类型: {}", account, systemType);
|
|
|
+
|
|
|
+ // 1. 查询用户信息
|
|
|
+ KwsUser kwsUser = getKwsUser(account, systemType);
|
|
|
+
|
|
|
+ // 3. 校验密码
|
|
|
+ password = PasswordUtils.md5(password);
|
|
|
+ checkPassword(account, password, kwsUser.getPassword(), kwsUser.getSalt());
|
|
|
+
|
|
|
+ // 4. 查询用户角色
|
|
|
+ List<RoleInfoDto> roleInfoList = kwsUserRoleDao.queryRoleList(kwsUser.getId());
|
|
|
+ if (CollUtil.isEmpty(roleInfoList)){
|
|
|
+ throw new SystemException(HttpStatus.CODE_60603, "该用户没有分配角色");
|
|
|
+ }
|
|
|
+ List<String> roleNames = Arrays.asList("铲车司机", "门卫");
|
|
|
+ roleInfoList = roleInfoList.stream().filter(x -> roleNames.contains(x.getRoleName()))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ if (CollUtil.isEmpty(roleInfoList)) {
|
|
|
+ throw new SystemException(HttpStatus.CODE_60603, "你没有登录该系统权限");
|
|
|
+ }
|
|
|
+
|
|
|
+ String roleName = roleInfoList.stream()
|
|
|
+ .map(RoleInfoDto::getRoleName)
|
|
|
+ .collect(Collectors.joining(","));
|
|
|
+ Long roleId = roleInfoList.get(0).getRoleId();
|
|
|
+
|
|
|
+
|
|
|
+ // 5. 获取客户端类型
|
|
|
+ String clientType = request != null ? request.getHeader(RequestConstant.CLIENT_TYPE) : null;
|
|
|
+ if (StringUtils.isBlank(clientType)) {
|
|
|
+ // 默认使用app
|
|
|
+ clientType = ClientTypeEnum.app.getValue();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 6. 生成token并缓存
|
|
|
+ String token = generateToken(kwsUser.getId(), account, clientType, systemType);
|
|
|
+ log.info("生成token成功,用户ID: {}, token: {}", kwsUser.getId(), token);
|
|
|
+
|
|
|
+ // 7. 缓存用户登录信息
|
|
|
+ saveUserToCache(kwsUser, systemType, clientType, roleId);
|
|
|
+
|
|
|
+ // 8. 缓存企业信息
|
|
|
+ KwsEnterprise kwsEnterprise = null;
|
|
|
+ if ( kwsUser.getEntId() != null) {
|
|
|
+ kwsEnterprise = saveEntToCache(kwsUser.getEntId());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 9. 缓存菜单权限
|
|
|
+ List<KwsMenuResVo> kwsMenuResVos = saveMenusToCache(kwsUser.getId(), systemType, roleId);
|
|
|
+
|
|
|
+ // 10. 组装返回结果
|
|
|
+ SwitchAccountResVo result = SwitchAccountResVo.builder()
|
|
|
+ .userId(kwsUser.getId())
|
|
|
+ .name(kwsUser.getName())
|
|
|
+ .account(kwsUser.getAccount())
|
|
|
+ .phone(kwsUser.getPhone())
|
|
|
+ .photo(kwsUser.getPhoto())
|
|
|
+ .roleId(roleId)
|
|
|
+ .roleName(roleName)
|
|
|
+ .token(token)
|
|
|
+ .entId(kwsUser.getEntId())
|
|
|
+ .enterpriseName(Optional.ofNullable(kwsEnterprise).map(KwsEnterprise::getFirmName).orElse(""))
|
|
|
+ .menuList(kwsMenuResVos)
|
|
|
+ .systemType(kwsUser.getSystemType())
|
|
|
+ .build();
|
|
|
+
|
|
|
+ // 11. 记录切换账号登录日志
|
|
|
+ if (request != null) {
|
|
|
+ saveLoginLogs(kwsUser.getId(), request, 2);
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("切换账号成功,用户ID: {}", kwsUser.getId());
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ @NotNull
|
|
|
+ private KwsUser getKwsUser(String account, Integer systemType) {
|
|
|
+ KwsUser kwsUser = getUserByAccount(account, systemType);
|
|
|
+ if (Objects.isNull(kwsUser)) {
|
|
|
+ throw new SystemException(HttpStatus.QUERY_FAIL_CODE, "账号不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 检查用户状态
|
|
|
+ if (kwsUser.getStatus() != null && kwsUser.getStatus() == Global.YES) {
|
|
|
+ throw new SystemException(HttpStatus.CODE_10301, "账号已被锁定");
|
|
|
+ }
|
|
|
+ return kwsUser;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 退出登录(叉车APP)
|
|
|
+ *
|
|
|
+ * @param userId 用户ID
|
|
|
+ */
|
|
|
+ public void logout(Long userId) {
|
|
|
+ log.info("退出登录,用户ID: {}", userId);
|
|
|
+
|
|
|
+ // 1. 校验用户是否存在
|
|
|
+ KwsUser kwsUser = kwsUserRepository.getById(userId);
|
|
|
+ if (Objects.isNull(kwsUser)) {
|
|
|
+ throw new SystemException(HttpStatus.QUERY_FAIL_CODE, "用户不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 清除所有客户端类型的 Token
|
|
|
+ for (ClientTypeEnum value : ClientTypeEnum.values()) {
|
|
|
+ String fullUserTokenKey = Global.getFullUserTokenKey(value.getValue(), userId);
|
|
|
+ RedissonUtils.delete(fullUserTokenKey);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 清除用户登录信息
|
|
|
+ for (SystemTypeEnum systemTypeEnum : SystemTypeEnum.values()) {
|
|
|
+ String fullUserLoginKey = Global.getFullUserLoginKey(systemTypeEnum.getCode(), userId);
|
|
|
+ RedissonUtils.remove(fullUserLoginKey);
|
|
|
+ }
|
|
|
+
|
|
|
+ //4.清除企业缓存
|
|
|
+ String key = Global.getFullUserEntKey(kwsUser.getEntId());
|
|
|
+ RedissonUtils.remove(key);
|
|
|
+ //5.清除菜单缓存
|
|
|
+ String menuKey = Global.REDIS_SYS_MENU_PREFIX + userId;
|
|
|
+ RedissonUtils.remove(menuKey);
|
|
|
+
|
|
|
+ log.info("退出登录成功,用户ID: {}", userId);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成token并缓存
|
|
|
+ *
|
|
|
+ * @param userId 用户ID
|
|
|
+ * @param account 账号
|
|
|
+ * @param clientType 客户端类型
|
|
|
+ * @param systemType 系统类型
|
|
|
+ */
|
|
|
+ private String generateToken(Long userId, String account, String clientType, Integer systemType) {
|
|
|
+ Map<String, Object> info = new HashMap<>(Global.NUMERICAL_SIXTEEN);
|
|
|
+ info.put("userId", userId);
|
|
|
+ info.put("account", account);
|
|
|
+ info.put("clientType", clientType);
|
|
|
+ info.put("systemType", systemType);
|
|
|
+ String key = Global.getFullUserTokenKey(clientType, userId);
|
|
|
+ String token = EncryUtil.encryV1(Global.PRI_KEY, JSON.toJSONString(info));
|
|
|
+ int expireTime = ClientTypeEnum.expireTime(clientType);
|
|
|
+ RedissonUtils.putString(key, token, expireTime);
|
|
|
+ return token;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 缓存用户登录信息
|
|
|
+ * @param kwsUser 用户信息
|
|
|
+ * @param systemType 系统类型
|
|
|
+ * @param clientType 客户端类型
|
|
|
+ * @param roleId 角色ID
|
|
|
+ */
|
|
|
+ private void saveUserToCache(KwsUser kwsUser, Integer systemType, String clientType, Long roleId) {
|
|
|
+ try {
|
|
|
+ LoginUserInfo loginUserInfo = new LoginUserInfo();
|
|
|
+ loginUserInfo.setId(kwsUser.getId());
|
|
|
+ loginUserInfo.setSystemType(systemType);
|
|
|
+ loginUserInfo.setClientType(clientType);
|
|
|
+ loginUserInfo.setAccount(kwsUser.getAccount());
|
|
|
+ loginUserInfo.setUserName(kwsUser.getName());
|
|
|
+ loginUserInfo.setPhone(kwsUser.getPhone());
|
|
|
+ loginUserInfo.setStatus(kwsUser.getStatus());
|
|
|
+ loginUserInfo.setIsMain(kwsUser.getIsMain() != null ? kwsUser.getIsMain() : Global.NO);
|
|
|
+ loginUserInfo.setEntId(kwsUser.getEntId());
|
|
|
+ loginUserInfo.setUseRoleId(roleId);
|
|
|
+ loginUserInfo.setUseEntId(kwsUser.getEntId());
|
|
|
+
|
|
|
+ // 查询企业信息
|
|
|
+ if (kwsUser.getEntId() != null) {
|
|
|
+ EntCacheResDto enterprise = remoteSystemService.queryEntDetails(kwsUser.getEntId());
|
|
|
+ if (enterprise != null) {
|
|
|
+ loginUserInfo.setEntName(enterprise.getFirmName());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询数据权限(暂时不实现,需要时可以通过RemoteUserService调用)
|
|
|
+ // 如果需要数据权限,可以通过Dubbo调用RemoteUserService.queryAuthUserList
|
|
|
+
|
|
|
+ String key = Global.getFullUserLoginKey(systemType, kwsUser.getId());
|
|
|
+ RedissonUtils.putString(key, JSON.toJSONString(loginUserInfo), Global.APP_TOKEN_EXPIRE);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("缓存用户登录信息失败,用户ID: {}", kwsUser.getId(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 缓存企业信息
|
|
|
+ * @param entId 企业ID
|
|
|
+ */
|
|
|
+ private KwsEnterprise saveEntToCache(Long entId) {
|
|
|
+ try {
|
|
|
+ //企业信息
|
|
|
+ KwsEnterprise enterprise = kwsEnterpriseDao.selectByKey(entId);
|
|
|
+ if (enterprise != null) {
|
|
|
+ String key = Global.getFullUserEntKey(entId);
|
|
|
+ RedissonUtils.putString(key, JSON.toJSONString(enterprise), Global.APP_TOKEN_EXPIRE);
|
|
|
+ }
|
|
|
+ return enterprise;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("缓存企业信息失败,企业ID: {}", entId, e);
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 缓存菜单权限
|
|
|
+ * @param userId 用户ID
|
|
|
+ * @param systemType 系统类型
|
|
|
+ * @param roleId 角色ID
|
|
|
+ */
|
|
|
+ private List<KwsMenuResVo> saveMenusToCache(Long userId, Integer systemType, Long roleId) {
|
|
|
+ if (Objects.isNull(roleId)){
|
|
|
+ return List.of();
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ // 使用本地服务查询菜单
|
|
|
+ com.sckw.system.model.pojo.FindMenuTreePojo findMenuTreePojo = new com.sckw.system.model.pojo.FindMenuTreePojo();
|
|
|
+ findMenuTreePojo.setRoleIds(Collections.singletonList(roleId));
|
|
|
+
|
|
|
+ List<KwsMenuResVo> kwsMenuResVos = kwsMenuService.findList(findMenuTreePojo);
|
|
|
+ if (CollectionUtils.isEmpty(kwsMenuResVos)) {
|
|
|
+ RedissonUtils.delete(Global.REDIS_SYS_MENU_PREFIX + systemType + Global.COLON + userId);
|
|
|
+ log.warn("未查询到角色{}的菜单权限", roleId);
|
|
|
+ return List.of();
|
|
|
+ }
|
|
|
+
|
|
|
+ List<String> menus = new ArrayList<>();
|
|
|
+ for (KwsMenuResVo menuResVo : kwsMenuResVos) {
|
|
|
+ String links = menuResVo.getLinks();
|
|
|
+ if (StringUtils.isNotBlank(links)) {
|
|
|
+ menus.addAll(Arrays.asList(links.split(",")));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ RedissonUtils.putSet(Global.REDIS_SYS_MENU_PREFIX + userId, menus);
|
|
|
+ return kwsMenuResVos;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("缓存菜单权限失败,用户ID: {}, 角色ID: {}", userId, roleId, e);
|
|
|
+ }
|
|
|
+ return List.of();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 保存登录日志
|
|
|
+ * @param userId 用户ID
|
|
|
+ * @param request HTTP请求
|
|
|
+ * @param loginType 登录类型: 1-首次登录, 2-切换账号登录
|
|
|
+ */
|
|
|
+ public void saveLoginLogs(Long userId, HttpServletRequest request, Integer loginType) {
|
|
|
+ try {
|
|
|
+ // 获取登录IP
|
|
|
+ String loginIp = RequestUtil.getClientIp(request);
|
|
|
+
|
|
|
+ // 获取设备信息
|
|
|
+ String userAgentStr = request.getHeader("User-Agent");
|
|
|
+ String deviceInfo = "";
|
|
|
+ if (userAgentStr != null && !userAgentStr.isEmpty()) {
|
|
|
+ try {
|
|
|
+ UserAgent userAgent = UserAgentUtil.parse(userAgentStr);
|
|
|
+ String browser = userAgent.getBrowser().getName();
|
|
|
+ String browserVersion = userAgent.getVersion();
|
|
|
+ String os = userAgent.getOs().getName();
|
|
|
+ String device = userAgent.getPlatform().getName();
|
|
|
+ deviceInfo = String.format("%s %s / %s / %s", browser, browserVersion, os, device);
|
|
|
+ } catch (Exception e) {
|
|
|
+ deviceInfo = userAgentStr.length() > 100 ? userAgentStr.substring(0, 100) : userAgentStr;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ LoginLogs loginLogs = new LoginLogs();
|
|
|
+ loginLogs.setId(new IdWorker(1).nextId());
|
|
|
+ loginLogs.setUserId(userId);
|
|
|
+ loginLogs.setLoginIp(loginIp != null ? loginIp : "");
|
|
|
+ loginLogs.setDeviceInfo(deviceInfo);
|
|
|
+ loginLogs.setLoginType(loginType);
|
|
|
+ loginLogs.setLoginTime(new Date());
|
|
|
+ loginLogsService.save(loginLogs);
|
|
|
+ } catch (Exception e) {
|
|
|
+ // 记录日志失败不影响主流程
|
|
|
+ log.error("保存登录日志失败,用户ID: {}", userId, e);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|