diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/logger/vo/loginlog/SysLoginLogCreateReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/logger/vo/loginlog/SysLoginLogCreateReqVO.java deleted file mode 100644 index ab0644a94..000000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/logger/vo/loginlog/SysLoginLogCreateReqVO.java +++ /dev/null @@ -1,19 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.system.controller.logger.vo.loginlog; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -@ApiModel(value = "登录日志创建 Request VO", - description = "暂时提供给前端,仅仅后端记录登录日志时,进行使用") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class SysLoginLogCreateReqVO extends SysLoginLogBaseVO { - - @ApiModelProperty(value = "用户编号", example = "1") - private Long userId; - -} \ No newline at end of file diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/convert/logger/SysLoginLogConvert.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/convert/logger/SysLoginLogConvert.java index 7c31fe3ae..93e083687 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/convert/logger/SysLoginLogConvert.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/convert/logger/SysLoginLogConvert.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.adminserver.modules.system.convert.logger; +import cn.iocoder.yudao.adminserver.modules.system.service.logger.dto.SysLoginLogCreateReqDTO; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.adminserver.modules.system.controller.logger.vo.loginlog.SysLoginLogCreateReqVO; import cn.iocoder.yudao.adminserver.modules.system.controller.logger.vo.loginlog.SysLoginLogExcelVO; import cn.iocoder.yudao.adminserver.modules.system.controller.logger.vo.loginlog.SysLoginLogRespVO; import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.logger.SysLoginLogDO; @@ -15,7 +15,7 @@ public interface SysLoginLogConvert { SysLoginLogConvert INSTANCE = Mappers.getMapper(SysLoginLogConvert.class); - SysLoginLogDO convert(SysLoginLogCreateReqVO bean); + SysLoginLogDO convert(SysLoginLogCreateReqDTO bean); PageResult convertPage(PageResult page); diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/dataobject/auth/SysUserSessionDO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/dataobject/auth/SysUserSessionDO.java index 8aa25a5b3..03fc65881 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/dataobject/auth/SysUserSessionDO.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/dataobject/auth/SysUserSessionDO.java @@ -38,6 +38,12 @@ public class SysUserSessionDO extends BaseDO { * 关联 {@link SysUserDO#getId()} */ private Long userId; + /** + * 用户类型 + * + * 枚举 {@link UserTypeEnum} + */ + private Integer userType; /** * 用户账号 diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/dataobject/logger/SysLoginLogDO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/dataobject/logger/SysLoginLogDO.java index 8bb80aa7a..0e4a00322 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/dataobject/logger/SysLoginLogDO.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/dataobject/logger/SysLoginLogDO.java @@ -14,7 +14,7 @@ import lombok.ToString; * * 注意,包括登录和登出两种行为 * - * @author ruoyi + * @author 芋道源码 */ @TableName("sys_login_log") @Data diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/SysErrorCodeConstants.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/SysErrorCodeConstants.java index e7388cca8..72f6ac671 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/SysErrorCodeConstants.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/SysErrorCodeConstants.java @@ -1,8 +1,6 @@ package cn.iocoder.yudao.adminserver.modules.system.enums; -import cn.iocoder.yudao.adminserver.modules.tool.framework.errorcode.config.ErrorCodeConfiguration; import cn.iocoder.yudao.framework.common.exception.ErrorCode; -import org.springframework.validation.Errors; /** * System 错误码枚举类 @@ -14,7 +12,7 @@ public interface SysErrorCodeConstants { // ========== AUTH 模块 1002000000 ========== ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1002000000, "登录失败,账号密码不正确"); ErrorCode AUTH_LOGIN_USER_DISABLED = new ErrorCode(1002000001, "登录失败,账号被禁用"); - ErrorCode AUTH_LOGIN_FAIL_UNKNOWN = new ErrorCode(1002000002, "登录失败"); // 登录失败的兜底,位置原因 + ErrorCode AUTH_LOGIN_FAIL_UNKNOWN = new ErrorCode(1002000002, "登录失败"); // 登录失败的兜底,未知原因 ErrorCode AUTH_LOGIN_CAPTCHA_NOT_FOUND = new ErrorCode(1002000003, "验证码不存在"); ErrorCode AUTH_LOGIN_CAPTCHA_CODE_ERROR = new ErrorCode(1002000004, "验证码不正确"); ErrorCode AUTH_THIRD_LOGIN_NOT_BIND = new ErrorCode(1002000005, "未绑定账号,需要进行绑定"); diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/logger/SysLoginLogTypeEnum.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/logger/SysLoginLogTypeEnum.java index 3b56f2f08..40f18e867 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/logger/SysLoginLogTypeEnum.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/logger/SysLoginLogTypeEnum.java @@ -13,6 +13,8 @@ public enum SysLoginLogTypeEnum { LOGIN_USERNAME(100), // 使用账号登录 LOGIN_SOCIAL(101), // 使用社交登录 LOGIN_MOCK(102), // 使用 Mock 登录 + LOGIN_MOBILE(103), // 使用手机登陆 + LOGIN_SMS(104), // 使用短信登陆 LOGOUT_SELF(200), // 自己主动登出 LOGOUT_TIMEOUT(201), // 超时登出 diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/logger/SysLoginResultEnum.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/logger/SysLoginResultEnum.java index e1bdeb955..218b2d97f 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/logger/SysLoginResultEnum.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/enums/logger/SysLoginResultEnum.java @@ -13,8 +13,8 @@ public enum SysLoginResultEnum { SUCCESS(0), // 成功 BAD_CREDENTIALS(10), // 账号或密码不正确 USER_DISABLED(20), // 用户被禁用 - CAPTCHA_NOT_FOUND(30), // 验证码不存在 - CAPTCHA_CODE_ERROR(31), // 验证码不正确 + CAPTCHA_NOT_FOUND(30), // 图片验证码不存在 + CAPTCHA_CODE_ERROR(31), // 图片验证码不正确 UNKNOWN_ERROR(100), // 未知异常 ; diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/SysUserSessionService.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/SysUserSessionService.java index 900ed1c0a..533c83753 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/SysUserSessionService.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/SysUserSessionService.java @@ -45,13 +45,6 @@ public interface SysUserSessionService { */ LoginUser getLoginUser(String sessionId); - /** - * 获取当前登录用户信息 - * @param username 用户名称 - * @return 在线用户 - */ - String getSessionId(String username); - /** * 获得 Session 超时时间,单位:毫秒 * diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java index 14c7c9846..d1f06816b 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java @@ -5,7 +5,6 @@ import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAu import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthSocialBindReqVO; import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthSocialLogin2ReqVO; import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.auth.SysAuthSocialLoginReqVO; -import cn.iocoder.yudao.adminserver.modules.system.controller.logger.vo.loginlog.SysLoginLogCreateReqVO; import cn.iocoder.yudao.adminserver.modules.system.convert.auth.SysAuthConvert; import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.social.SysSocialUserDO; import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.user.SysUserDO; @@ -15,6 +14,7 @@ import cn.iocoder.yudao.adminserver.modules.system.service.auth.SysAuthService; import cn.iocoder.yudao.adminserver.modules.system.service.auth.SysUserSessionService; import cn.iocoder.yudao.adminserver.modules.system.service.common.SysCaptchaService; import cn.iocoder.yudao.adminserver.modules.system.service.logger.SysLoginLogService; +import cn.iocoder.yudao.adminserver.modules.system.service.logger.dto.SysLoginLogCreateReqDTO; import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService; import cn.iocoder.yudao.adminserver.modules.system.service.social.SysSocialService; import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService; @@ -158,20 +158,20 @@ public class SysAuthServiceImpl implements SysAuthService { // 获得用户 SysUserDO user = userService.getUserByUsername(username); // 插入登录日志 - SysLoginLogCreateReqVO reqVO = new SysLoginLogCreateReqVO(); - reqVO.setLogType(logTypeEnum.getType()); - reqVO.setTraceId(TracerUtils.getTraceId()); + SysLoginLogCreateReqDTO reqDTO = new SysLoginLogCreateReqDTO(); + reqDTO.setLogType(logTypeEnum.getType()); + reqDTO.setTraceId(TracerUtils.getTraceId()); if (user != null) { - reqVO.setUserId(user.getId()); + reqDTO.setUserId(user.getId()); } - reqVO.setUsername(username); - reqVO.setUserAgent(ServletUtils.getUserAgent()); - reqVO.setUserIp(ServletUtils.getClientIP()); - reqVO.setResult(loginResult.getResult()); - loginLogService.createLoginLog(reqVO); + reqDTO.setUsername(username); + reqDTO.setUserAgent(ServletUtils.getUserAgent()); + reqDTO.setUserIp(ServletUtils.getClientIP()); + reqDTO.setResult(loginResult.getResult()); + loginLogService.createLoginLog(reqDTO); // 更新最后登录时间 if (user != null && Objects.equals(SysLoginResultEnum.SUCCESS.getResult(), loginResult.getResult())) { - + userService.updateUserLogin(user.getId(), ServletUtils.getClientIP()); } } @@ -258,14 +258,14 @@ public class SysAuthServiceImpl implements SysAuthService { } private void createLogoutLog(String username) { - SysLoginLogCreateReqVO reqVO = new SysLoginLogCreateReqVO(); - reqVO.setLogType(SysLoginLogTypeEnum.LOGOUT_SELF.getType()); - reqVO.setTraceId(TracerUtils.getTraceId()); - reqVO.setUsername(username); - reqVO.setUserAgent(ServletUtils.getUserAgent()); - reqVO.setUserIp(ServletUtils.getClientIP()); - reqVO.setResult(SysLoginResultEnum.SUCCESS.getResult()); - loginLogService.createLoginLog(reqVO); + SysLoginLogCreateReqDTO reqDTO = new SysLoginLogCreateReqDTO(); + reqDTO.setLogType(SysLoginLogTypeEnum.LOGOUT_SELF.getType()); + reqDTO.setTraceId(TracerUtils.getTraceId()); + reqDTO.setUsername(username); + reqDTO.setUserAgent(ServletUtils.getUserAgent()); + reqDTO.setUserIp(ServletUtils.getClientIP()); + reqDTO.setResult(SysLoginResultEnum.SUCCESS.getResult()); + loginLogService.createLoginLog(reqDTO); } @Override diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysUserSessionServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysUserSessionServiceImpl.java index a715971d8..fc73cb875 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysUserSessionServiceImpl.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysUserSessionServiceImpl.java @@ -3,12 +3,7 @@ package cn.iocoder.yudao.adminserver.modules.system.service.auth.impl; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.StrUtil; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.security.config.SecurityProperties; -import cn.iocoder.yudao.framework.security.core.LoginUser; -import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils; import cn.iocoder.yudao.adminserver.modules.system.controller.auth.vo.session.SysUserSessionPageReqVO; -import cn.iocoder.yudao.adminserver.modules.system.controller.logger.vo.loginlog.SysLoginLogCreateReqVO; import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.auth.SysUserSessionDO; import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.user.SysUserDO; import cn.iocoder.yudao.adminserver.modules.system.dal.mysql.auth.SysUserSessionMapper; @@ -17,10 +12,13 @@ import cn.iocoder.yudao.adminserver.modules.system.enums.logger.SysLoginLogTypeE import cn.iocoder.yudao.adminserver.modules.system.enums.logger.SysLoginResultEnum; import cn.iocoder.yudao.adminserver.modules.system.service.auth.SysUserSessionService; import cn.iocoder.yudao.adminserver.modules.system.service.logger.SysLoginLogService; +import cn.iocoder.yudao.adminserver.modules.system.service.logger.dto.SysLoginLogCreateReqDTO; import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService; -import com.baomidou.mybatisplus.core.conditions.Wrapper; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils; +import cn.iocoder.yudao.framework.security.config.SecurityProperties; +import cn.iocoder.yudao.framework.security.core.LoginUser; import com.google.common.collect.Lists; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -62,7 +60,8 @@ public class SysUserSessionServiceImpl implements SysUserSessionService { loginUserRedisDAO.set(sessionId, loginUser); // 写入 DB 中 SysUserSessionDO userSession = SysUserSessionDO.builder().id(sessionId) - .userId(loginUser.getId()).userIp(userIp).userAgent(userAgent).username(loginUser.getUsername()) + .userId(loginUser.getId()).userType(UserTypeEnum.ADMIN.getValue()) + .userIp(userIp).userAgent(userAgent).username(loginUser.getUsername()) .sessionTimeout(addTime(Duration.ofMillis(getSessionTimeoutMillis()))) .build(); userSessionMapper.insert(userSession); @@ -96,15 +95,6 @@ public class SysUserSessionServiceImpl implements SysUserSessionService { return loginUserRedisDAO.get(sessionId); } - @Override - public String getSessionId(String username) { - QueryWrapper wrapper = new QueryWrapper<>(); - wrapper.eq("username", username); - wrapper.orderByDesc("create_time"); - SysUserSessionDO sysUserSessionDO = userSessionMapper.selectOne(wrapper); - return sysUserSessionDO.getId(); - } - @Override public Long getSessionTimeoutMillis() { return securityProperties.getSessionTimeout().toMillis(); @@ -142,14 +132,14 @@ public class SysUserSessionServiceImpl implements SysUserSessionService { private void createTimeoutLogoutLog(Collection timeoutSessionDOS) { for (SysUserSessionDO timeoutSessionDO : timeoutSessionDOS) { - SysLoginLogCreateReqVO reqVO = new SysLoginLogCreateReqVO(); - reqVO.setLogType(SysLoginLogTypeEnum.LOGOUT_TIMEOUT.getType()); - reqVO.setTraceId(TracerUtils.getTraceId()); - reqVO.setUsername(timeoutSessionDO.getUsername()); - reqVO.setUserAgent(timeoutSessionDO.getUserAgent()); - reqVO.setUserIp(timeoutSessionDO.getUserIp()); - reqVO.setResult(SysLoginResultEnum.SUCCESS.getResult()); - loginLogService.createLoginLog(reqVO); + SysLoginLogCreateReqDTO reqDTO = new SysLoginLogCreateReqDTO(); + reqDTO.setLogType(SysLoginLogTypeEnum.LOGOUT_TIMEOUT.getType()); + reqDTO.setTraceId(TracerUtils.getTraceId()); + reqDTO.setUsername(timeoutSessionDO.getUsername()); + reqDTO.setUserAgent(timeoutSessionDO.getUserAgent()); + reqDTO.setUserIp(timeoutSessionDO.getUserIp()); + reqDTO.setResult(SysLoginResultEnum.SUCCESS.getResult()); + loginLogService.createLoginLog(reqDTO); } } diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/logger/SysLoginLogService.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/logger/SysLoginLogService.java index fd4ad6658..bfa36221e 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/logger/SysLoginLogService.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/logger/SysLoginLogService.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.adminserver.modules.system.service.logger; +import cn.iocoder.yudao.adminserver.modules.system.service.logger.dto.SysLoginLogCreateReqDTO; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.adminserver.modules.system.controller.logger.vo.loginlog.SysLoginLogCreateReqVO; import cn.iocoder.yudao.adminserver.modules.system.controller.logger.vo.loginlog.SysLoginLogExportReqVO; import cn.iocoder.yudao.adminserver.modules.system.controller.logger.vo.loginlog.SysLoginLogPageReqVO; import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.logger.SysLoginLogDO; @@ -16,9 +16,9 @@ public interface SysLoginLogService { /** * 创建登录日志 * - * @param reqVO 日志信息 + * @param reqDTO 日志信息 */ - void createLoginLog(SysLoginLogCreateReqVO reqVO); + void createLoginLog(SysLoginLogCreateReqDTO reqDTO); /** * 获得登录日志分页 diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/logger/dto/SysLoginLogCreateReqDTO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/logger/dto/SysLoginLogCreateReqDTO.java new file mode 100644 index 000000000..d715d4979 --- /dev/null +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/logger/dto/SysLoginLogCreateReqDTO.java @@ -0,0 +1,57 @@ +package cn.iocoder.yudao.adminserver.modules.system.service.logger.dto; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +/** + * 登录日志创建 Request DTO + * + * @author 芋道源码 + */ +@Data +public class SysLoginLogCreateReqDTO { + + /** + * 日志类型 + */ + @NotNull(message = "日志类型不能为空") + private Integer logType; + /** + * 链路追踪编号 + */ + @NotEmpty(message = "链路追踪编号不能为空") + private String traceId; + + /** + * 用户编号 + */ + private Long userId; + /** + * 用户账号 + */ + @NotBlank(message = "用户账号不能为空") + @Size(max = 30, message = "用户账号长度不能超过30个字符") + private String username; + + /** + * 登录结果 + */ + @NotNull(message = "登录结果不能为空") + private Integer result; + + /** + * 用户 IP + */ + @NotEmpty(message = "用户 IP 不能为空") + private String userIp; + /** + * 浏览器 UserAgent + */ + @NotEmpty(message = "浏览器 UserAgent 不能为空") + private String userAgent; + +} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/logger/impl/SysLoginLogServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/logger/impl/SysLoginLogServiceImpl.java index 811b51677..c2f9c009f 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/logger/impl/SysLoginLogServiceImpl.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/logger/impl/SysLoginLogServiceImpl.java @@ -1,16 +1,14 @@ package cn.iocoder.yudao.adminserver.modules.system.service.logger.impl; -import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.user.SysUserDO; -import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService; -import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.adminserver.modules.system.controller.logger.vo.loginlog.SysLoginLogCreateReqVO; import cn.iocoder.yudao.adminserver.modules.system.controller.logger.vo.loginlog.SysLoginLogExportReqVO; import cn.iocoder.yudao.adminserver.modules.system.controller.logger.vo.loginlog.SysLoginLogPageReqVO; import cn.iocoder.yudao.adminserver.modules.system.convert.logger.SysLoginLogConvert; import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.logger.SysLoginLogDO; import cn.iocoder.yudao.adminserver.modules.system.dal.mysql.logger.SysLoginLogMapper; import cn.iocoder.yudao.adminserver.modules.system.service.logger.SysLoginLogService; +import cn.iocoder.yudao.adminserver.modules.system.service.logger.dto.SysLoginLogCreateReqDTO; +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import org.springframework.stereotype.Service; import javax.annotation.Resource; @@ -26,8 +24,8 @@ public class SysLoginLogServiceImpl implements SysLoginLogService { private SysLoginLogMapper loginLogMapper; @Override - public void createLoginLog(SysLoginLogCreateReqVO reqVO) { - SysLoginLogDO loginLog = SysLoginLogConvert.INSTANCE.convert(reqVO); + public void createLoginLog(SysLoginLogCreateReqDTO reqDTO) { + SysLoginLogDO loginLog = SysLoginLogConvert.INSTANCE.convert(reqDTO); loginLog.setUserType(UserTypeEnum.ADMIN.getValue()); // 插入 loginLogMapper.insert(loginLog); diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/user/SysUserService.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/user/SysUserService.java index 91d9b5a76..cea841e1f 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/user/SysUserService.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/user/SysUserService.java @@ -41,6 +41,14 @@ public interface SysUserService { */ void updateUser(SysUserUpdateReqVO reqVO); + /** + * 更新用户的最后登陆信息 + * + * @param id 用户编号 + * @param loginIp 登陆 IP + */ + void updateUserLogin(Long id, String loginIp); + /** * 修改用户个人信息 * diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/user/impl/SysUserServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/user/impl/SysUserServiceImpl.java index ff3e098dc..e31cc0d36 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/user/impl/SysUserServiceImpl.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/user/impl/SysUserServiceImpl.java @@ -84,6 +84,11 @@ public class SysUserServiceImpl implements SysUserService { userMapper.updateById(updateObj); } + @Override + public void updateUserLogin(Long id, String loginIp) { + userMapper.updateById(new SysUserDO().setId(id).setLoginIp(loginIp).setLoginDate(new Date())); + } + @Override public void updateUserProfile(Long id, SysUserProfileUpdateReqVO reqVO) { // 校验正确性 diff --git a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/logger/SysLoginLogServiceImplTest.java b/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/logger/SysLoginLogServiceImplTest.java index d6a921fe1..d087037bb 100644 --- a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/logger/SysLoginLogServiceImplTest.java +++ b/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/logger/SysLoginLogServiceImplTest.java @@ -2,9 +2,9 @@ package cn.iocoder.yudao.adminserver.modules.system.service.logger; import cn.hutool.core.util.RandomUtil; import cn.iocoder.yudao.adminserver.BaseDbUnitTest; +import cn.iocoder.yudao.adminserver.modules.system.service.logger.dto.SysLoginLogCreateReqDTO; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils; -import cn.iocoder.yudao.adminserver.modules.system.controller.logger.vo.loginlog.SysLoginLogCreateReqVO; import cn.iocoder.yudao.adminserver.modules.system.controller.logger.vo.loginlog.SysLoginLogExportReqVO; import cn.iocoder.yudao.adminserver.modules.system.controller.logger.vo.loginlog.SysLoginLogPageReqVO; import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.logger.SysLoginLogDO; @@ -36,7 +36,7 @@ public class SysLoginLogServiceImplTest extends BaseDbUnitTest { @Test public void testCreateLoginLog() { String traceId = TracerUtils.getTraceId(); - SysLoginLogCreateReqVO reqVO = RandomUtils.randomPojo(SysLoginLogCreateReqVO.class, vo -> { + SysLoginLogCreateReqDTO reqDTO = RandomUtils.randomPojo(SysLoginLogCreateReqDTO.class, vo -> { // 指定随机的范围,避免超出范围入库失败 vo.setLogType(RandomUtil.randomEle(SysLoginLogTypeEnum.values()).getType()); vo.setResult(RandomUtil.randomEle(SysLoginResultEnum.values()).getResult()); @@ -45,11 +45,11 @@ public class SysLoginLogServiceImplTest extends BaseDbUnitTest { }); // 执行service方法 - sysLoginLogService.createLoginLog(reqVO); + sysLoginLogService.createLoginLog(reqDTO); // 断言,忽略基本字段 SysLoginLogDO sysLoginLogDO = loginLogMapper.selectOne(null); - assertPojoEquals(reqVO, sysLoginLogDO); + assertPojoEquals(reqDTO, sysLoginLogDO); } diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/convert/package-info.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/convert/package-info.java index 57ebab78c..5877b74c1 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/convert/package-info.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/convert/package-info.java @@ -1 +1,6 @@ -package cn.iocoder.yudao.userserver.modules.member.convert; \ No newline at end of file +/** + * 提供 POJO 类的实体转换 + * + * 目前使用 MapStruct 框架 + */ +package cn.iocoder.yudao.userserver.modules.member.convert; diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md new file mode 100644 index 000000000..8153487b7 --- /dev/null +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md @@ -0,0 +1 @@ + diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/enums/MbrErrorCodeConstants.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/enums/MbrErrorCodeConstants.java new file mode 100644 index 000000000..c8e94afb6 --- /dev/null +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/enums/MbrErrorCodeConstants.java @@ -0,0 +1,17 @@ +package cn.iocoder.yudao.userserver.modules.member.enums; + +import cn.iocoder.yudao.framework.common.exception.ErrorCode; + +/** + * Member 错误码枚举类 + * + * member 系统,使用 1-004-000-000 段 + */ +public interface MbrErrorCodeConstants { + + // ========== AUTH 模块 1004000000 ========== + ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1004000000, "登录失败,账号密码不正确"); + ErrorCode AUTH_LOGIN_USER_DISABLED = new ErrorCode(1004000001, "登录失败,账号被禁用"); + ErrorCode AUTH_LOGIN_FAIL_UNKNOWN = new ErrorCode(1004000002, "登录失败"); // 登录失败的兜底,未知原因 + +} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/auth/impl/MbrAuthServiceImpl.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/auth/impl/MbrAuthServiceImpl.java index 0dfce16ec..dc47b326a 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/auth/impl/MbrAuthServiceImpl.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/auth/impl/MbrAuthServiceImpl.java @@ -1,20 +1,40 @@ package cn.iocoder.yudao.userserver.modules.member.service.auth.impl; +import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils; +import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; import cn.iocoder.yudao.framework.security.core.LoginUser; import cn.iocoder.yudao.userserver.modules.member.controller.auth.vo.MbrAuthLoginReqVO; import cn.iocoder.yudao.userserver.modules.member.convert.user.MbrAuthConvert; import cn.iocoder.yudao.userserver.modules.member.dal.dataobject.user.MbrUserDO; +import cn.iocoder.yudao.userserver.modules.member.enums.MbrErrorCodeConstants; import cn.iocoder.yudao.userserver.modules.member.service.auth.MbrAuthService; import cn.iocoder.yudao.userserver.modules.member.service.user.MbrUserService; +import cn.iocoder.yudao.userserver.modules.system.enums.logger.SysLoginLogTypeEnum; +import cn.iocoder.yudao.userserver.modules.system.enums.logger.SysLoginResultEnum; +import cn.iocoder.yudao.userserver.modules.system.service.auth.SysUserSessionService; +import cn.iocoder.yudao.userserver.modules.system.service.logger.SysLoginLogService; +import cn.iocoder.yudao.userserver.modules.system.service.logger.dto.SysLoginLogCreateReqDTO; +import cn.iocoder.yudao.userserver.modules.system.service.logger.impl.SysLoginLogServiceImpl; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Lazy; import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.DisabledException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; +import org.springframework.util.Assert; import javax.annotation.Resource; +import java.util.Objects; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.userserver.modules.member.enums.MbrErrorCodeConstants.*; + /** * Auth Service 实现类 * @@ -30,6 +50,10 @@ public class MbrAuthServiceImpl implements MbrAuthService { @Resource private MbrUserService userService; + @Resource + private SysLoginLogService loginLogService; + @Resource + private SysUserSessionService userSessionService; @Override public UserDetails loadUserByUsername(String mobile) throws UsernameNotFoundException { @@ -44,7 +68,57 @@ public class MbrAuthServiceImpl implements MbrAuthService { @Override public String login(MbrAuthLoginReqVO reqVO, String userIp, String userAgent) { - return null; + // 使用手机 + 密码,进行登录。 + LoginUser loginUser = this.login0(reqVO.getMobile(), reqVO.getPassword()); + + // 缓存登录用户到 Redis 中,返回 sessionId 编号 + return userSessionService.createUserSession(loginUser, userIp, userAgent); + } + + private LoginUser login0(String username, String password) { + final SysLoginLogTypeEnum logTypeEnum = SysLoginLogTypeEnum.LOGIN_USERNAME; + // 用户验证 + Authentication authentication; + try { + // 调用 Spring Security 的 AuthenticationManager#authenticate(...) 方法,使用账号密码进行认证 + // 在其内部,会调用到 loadUserByUsername 方法,获取 User 信息 + authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password)); + } catch (BadCredentialsException badCredentialsException) { + this.createLoginLog(username, logTypeEnum, SysLoginResultEnum.BAD_CREDENTIALS); + throw exception(AUTH_LOGIN_BAD_CREDENTIALS); + } catch (DisabledException disabledException) { + this.createLoginLog(username, logTypeEnum, SysLoginResultEnum.USER_DISABLED); + throw exception(AUTH_LOGIN_USER_DISABLED); + } catch (AuthenticationException authenticationException) { + log.error("[login0][username({}) 发生未知异常]", username, authenticationException); + this.createLoginLog(username, logTypeEnum, SysLoginResultEnum.UNKNOWN_ERROR); + throw exception(AUTH_LOGIN_FAIL_UNKNOWN); + } + // 登录成功的日志 + Assert.notNull(authentication.getPrincipal(), "Principal 不会为空"); + this.createLoginLog(username, logTypeEnum, SysLoginResultEnum.SUCCESS); + return (LoginUser) authentication.getPrincipal(); + } + + private void createLoginLog(String mobile, SysLoginLogTypeEnum logTypeEnum, SysLoginResultEnum loginResult) { + // 获得用户 + MbrUserDO user = userService.getUserByMobile(mobile); + // 插入登录日志 + SysLoginLogCreateReqDTO reqDTO = new SysLoginLogCreateReqDTO(); + reqDTO.setLogType(logTypeEnum.getType()); + reqDTO.setTraceId(TracerUtils.getTraceId()); + if (user != null) { + reqDTO.setUserId(user.getId()); + } + reqDTO.setUsername(mobile); + reqDTO.setUserAgent(ServletUtils.getUserAgent()); + reqDTO.setUserIp(ServletUtils.getClientIP()); + reqDTO.setResult(loginResult.getResult()); + loginLogService.createLoginLog(reqDTO); + // 更新最后登录时间 + if (user != null && Objects.equals(SysLoginResultEnum.SUCCESS.getResult(), loginResult.getResult())) { + userService.updateUserLogin(user.getId(), ServletUtils.getClientIP()); + } } @Override diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/MbrUserService.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/MbrUserService.java index 6949248ad..a716b3649 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/MbrUserService.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/MbrUserService.java @@ -17,4 +17,12 @@ public interface MbrUserService { */ MbrUserDO getUserByMobile(String mobile); + /** + * 更新用户的最后登陆信息 + * + * @param id 用户编号 + * @param loginIp 登陆 IP + */ + void updateUserLogin(Long id, String loginIp); + } diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/impl/MbrUserServiceImpl.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/impl/MbrUserServiceImpl.java index 1be87d01b..2270ac9d1 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/impl/MbrUserServiceImpl.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/impl/MbrUserServiceImpl.java @@ -8,6 +8,7 @@ import org.springframework.stereotype.Service; import javax.annotation.Resource; import javax.validation.Valid; +import java.util.Date; /** * User Service 实现类 @@ -27,4 +28,9 @@ public class MbrUserServiceImpl implements MbrUserService { return userMapper.selectByMobile(mobile); } + @Override + public void updateUserLogin(Long id, String loginIp) { + userMapper.updateById(new MbrUserDO().setId(id).setLoginIp(loginIp).setLoginDate(new Date())); + } + } diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/convert/logger/SysLoginLogConvert.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/convert/logger/SysLoginLogConvert.java new file mode 100644 index 000000000..45e49e416 --- /dev/null +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/convert/logger/SysLoginLogConvert.java @@ -0,0 +1,15 @@ +package cn.iocoder.yudao.userserver.modules.system.convert.logger; + +import cn.iocoder.yudao.userserver.modules.system.dal.mysql.logger.SysLoginLogDO; +import cn.iocoder.yudao.userserver.modules.system.service.logger.dto.SysLoginLogCreateReqDTO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface SysLoginLogConvert { + + SysLoginLogConvert INSTANCE = Mappers.getMapper(SysLoginLogConvert.class); + + SysLoginLogDO convert(SysLoginLogCreateReqDTO bean); + +} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/convert/package-info.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/convert/package-info.java index 65ad8dc88..d7da621f0 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/convert/package-info.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/convert/package-info.java @@ -1 +1,6 @@ +/** + * 提供 POJO 类的实体转换 + * + * 目前使用 MapStruct 框架 + */ package cn.iocoder.yudao.userserver.modules.system.convert; diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md new file mode 100644 index 000000000..8153487b7 --- /dev/null +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md @@ -0,0 +1 @@ + diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/dataobject/logger/SysLoginLogMapper.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/dataobject/logger/SysLoginLogMapper.java new file mode 100644 index 000000000..0a6f31413 --- /dev/null +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/dataobject/logger/SysLoginLogMapper.java @@ -0,0 +1,10 @@ +package cn.iocoder.yudao.userserver.modules.system.dal.dataobject.logger; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.userserver.modules.system.dal.mysql.logger.SysLoginLogDO; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface SysLoginLogMapper extends BaseMapperX { + +} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/mysql/logger/SysLoginLogDO.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/mysql/logger/SysLoginLogDO.java new file mode 100644 index 000000000..3f7f5d52f --- /dev/null +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/mysql/logger/SysLoginLogDO.java @@ -0,0 +1,70 @@ +package cn.iocoder.yudao.userserver.modules.system.dal.mysql.logger; + +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.userserver.modules.system.enums.logger.SysLoginLogTypeEnum; +import cn.iocoder.yudao.userserver.modules.system.enums.logger.SysLoginResultEnum; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +/** + * 登录日志表 + * + * 注意,包括登录和登出两种行为 + * + * @author 芋道源码 + */ +@TableName("sys_login_log") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class SysLoginLogDO extends BaseDO { + + /** + * 日志主键 + */ + private Long id; + /** + * 日志类型 + * + * 枚举 {@link SysLoginLogTypeEnum} + */ + private Integer logType; + /** + * 链路追踪编号 + */ + private String traceId; + /** + * 用户编号 + */ + private Long userId; + /** + * 用户类型 + * + * 枚举 {@link UserTypeEnum} + */ + private Integer userType; + /** + * 用户账号 + * + * 冗余,因为账号可以变更 + */ + private String username; + /** + * 登录结果 + * + * 枚举 {@link SysLoginResultEnum} + */ + private Integer result; + /** + * 用户 IP + */ + private String userIp; + /** + * 浏览器 UA + */ + private String userAgent; + +} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/mysql/package-info.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/mysql/package-info.java deleted file mode 100644 index a1bdeadcd..000000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/dal/mysql/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.system.dal.mysql; diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/logger/SysLoginLogTypeEnum.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/logger/SysLoginLogTypeEnum.java new file mode 100644 index 000000000..76fd54e83 --- /dev/null +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/logger/SysLoginLogTypeEnum.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.userserver.modules.system.enums.logger; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 登录日志的类型枚举 + */ +@Getter +@AllArgsConstructor +public enum SysLoginLogTypeEnum { + + LOGIN_USERNAME(100), // 使用账号登录 + LOGIN_SOCIAL(101), // 使用社交登录 + LOGIN_MOCK(102), // 使用 Mock 登录 + LOGIN_MOBILE(103), // 使用手机登陆 + LOGIN_SMS(104), // 使用短信登陆 + + LOGOUT_SELF(200), // 自己主动登出 + LOGOUT_TIMEOUT(201), // 超时登出 + LOGOUT_DELETE(202), // 强制退出 + ; + + /** + * 日志类型 + */ + private final Integer type; + +} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/logger/SysLoginResultEnum.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/logger/SysLoginResultEnum.java new file mode 100644 index 000000000..e36515f9e --- /dev/null +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/logger/SysLoginResultEnum.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.userserver.modules.system.enums.logger; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 登录结果的枚举类 + */ +@Getter +@AllArgsConstructor +public enum SysLoginResultEnum { + + SUCCESS(0), // 成功 + BAD_CREDENTIALS(10), // 账号或密码不正确 + USER_DISABLED(20), // 用户被禁用 + CAPTCHA_NOT_FOUND(30), // 图片验证码不存在 + CAPTCHA_CODE_ERROR(31), // 图片验证码不正确 + + UNKNOWN_ERROR(100), // 未知异常 + ; + + /** + * 结果 + */ + private final Integer result; + +} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/package-info.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/package-info.java new file mode 100644 index 000000000..2e5e53beb --- /dev/null +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/enums/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.yudao.userserver.modules.system.enums; diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/SysUserSessionService.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/SysUserSessionService.java new file mode 100644 index 000000000..d2f8ffae5 --- /dev/null +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/SysUserSessionService.java @@ -0,0 +1,59 @@ +package cn.iocoder.yudao.userserver.modules.system.service.auth; + +import cn.iocoder.yudao.framework.security.core.LoginUser; + +/** + * 在线用户 Session Service 接口 + * + * @author 芋道源码 + */ +public interface SysUserSessionService { + + /** + * 创建在线用户 Session + * + * @param loginUser 登录用户 + * @param userIp 用户 IP + * @param userAgent 用户 UA + * @return Session 编号 + */ + String createUserSession(LoginUser loginUser, String userIp, String userAgent); + + /** + * 刷新在线用户 Session 的更新时间 + * + * @param sessionId Session 编号 + * @param loginUser 登录用户 + */ + void refreshUserSession(String sessionId, LoginUser loginUser); + + /** + * 删除在线用户 Session + * + * @param sessionId Session 编号 + */ + void deleteUserSession(String sessionId); + + /** + * 获得 Session 编号对应的在线用户 + * + * @param sessionId Session 编号 + * @return 在线用户 + */ + LoginUser getLoginUser(String sessionId); + + /** + * 获取当前登录用户信息 + * @param username 用户名称 + * @return 在线用户 + */ + String getSessionId(String username); + + /** + * 获得 Session 超时时间,单位:毫秒 + * + * @return 超时时间 + */ + Long getSessionTimeoutMillis(); + +} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/impl/SysUserSessionServiceImpl.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/impl/SysUserSessionServiceImpl.java new file mode 100644 index 000000000..d7e686c0a --- /dev/null +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/impl/SysUserSessionServiceImpl.java @@ -0,0 +1,47 @@ +package cn.iocoder.yudao.userserver.modules.system.service.auth.impl; + +import cn.iocoder.yudao.framework.security.core.LoginUser; +import cn.iocoder.yudao.userserver.modules.system.service.auth.SysUserSessionService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +/** + * 在线用户 Session Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Slf4j +public class SysUserSessionServiceImpl implements SysUserSessionService { + + @Override + public String createUserSession(LoginUser loginUser, String userIp, String userAgent) { + return null; + } + + @Override + public void refreshUserSession(String sessionId, LoginUser loginUser) { + + } + + @Override + public void deleteUserSession(String sessionId) { + + } + + @Override + public LoginUser getLoginUser(String sessionId) { + return null; + } + + @Override + public String getSessionId(String username) { + return null; + } + + @Override + public Long getSessionTimeoutMillis() { + return null; + } + +} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/logger/SysLoginLogService.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/logger/SysLoginLogService.java new file mode 100644 index 000000000..92a570085 --- /dev/null +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/logger/SysLoginLogService.java @@ -0,0 +1,17 @@ +package cn.iocoder.yudao.userserver.modules.system.service.logger; + +import cn.iocoder.yudao.userserver.modules.system.service.logger.dto.SysLoginLogCreateReqDTO; + +/** + * 登录日志 Service 接口 + */ +public interface SysLoginLogService { + + /** + * 创建登录日志 + * + * @param reqDTO 日志信息 + */ + void createLoginLog(SysLoginLogCreateReqDTO reqDTO); + +} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/logger/dto/SysLoginLogCreateReqDTO.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/logger/dto/SysLoginLogCreateReqDTO.java new file mode 100644 index 000000000..fc23fb3db --- /dev/null +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/logger/dto/SysLoginLogCreateReqDTO.java @@ -0,0 +1,57 @@ +package cn.iocoder.yudao.userserver.modules.system.service.logger.dto; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +/** + * 登录日志创建 Request DTO + * + * @author 芋道源码 + */ +@Data +public class SysLoginLogCreateReqDTO { + + /** + * 日志类型 + */ + @NotNull(message = "日志类型不能为空") + private Integer logType; + /** + * 链路追踪编号 + */ + @NotEmpty(message = "链路追踪编号不能为空") + private String traceId; + + /** + * 用户编号 + */ + private Long userId; + /** + * 用户账号 + */ + @NotBlank(message = "用户账号不能为空") + @Size(max = 30, message = "用户账号长度不能超过30个字符") + private String username; + + /** + * 登录结果 + */ + @NotNull(message = "登录结果不能为空") + private Integer result; + + /** + * 用户 IP + */ + @NotEmpty(message = "用户 IP 不能为空") + private String userIp; + /** + * 浏览器 UserAgent + */ + @NotEmpty(message = "浏览器 UserAgent 不能为空") + private String userAgent; + +} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/logger/impl/SysLoginLogServiceImpl.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/logger/impl/SysLoginLogServiceImpl.java new file mode 100644 index 000000000..a2e31851d --- /dev/null +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/logger/impl/SysLoginLogServiceImpl.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.userserver.modules.system.service.logger.impl; + +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; +import cn.iocoder.yudao.userserver.modules.system.convert.logger.SysLoginLogConvert; +import cn.iocoder.yudao.userserver.modules.system.dal.dataobject.logger.SysLoginLogMapper; +import cn.iocoder.yudao.userserver.modules.system.dal.mysql.logger.SysLoginLogDO; +import cn.iocoder.yudao.userserver.modules.system.service.logger.SysLoginLogService; +import cn.iocoder.yudao.userserver.modules.system.service.logger.dto.SysLoginLogCreateReqDTO; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * 登录日志 Service 实现 + */ +@Service +public class SysLoginLogServiceImpl implements SysLoginLogService { + + @Resource + private SysLoginLogMapper loginLogMapper; + + @Override + public void createLoginLog(SysLoginLogCreateReqDTO reqDTO) { + SysLoginLogDO loginLog = SysLoginLogConvert.INSTANCE.convert(reqDTO); + loginLog.setUserType(UserTypeEnum.MEMBER.getValue()); + // 插入 + loginLogMapper.insert(loginLog); + } + +}