# 系统有效时间功能移植说明 ## 功能概述 从 `xinli` 借鉴项目移植了系统有效时间控制功能。该功能通过在参数设置表中配置系统有效时间,当系统超过有效时间后,普通用户将无法登录系统,但系统管理员不受此限制。 ## 移植内容 ### 1. 代码实现 **文件位置:** `ry-study-framework/src/main/java/com/ddnai/framework/web/service/SysLoginService.java` #### 1.1 新增导入 添加了以下导入语句: - `java.util.Date` - 用于日期时间处理 - `org.slf4j.Logger` 和 `org.slf4j.LoggerFactory` - 用于日志记录 - `com.ddnai.common.core.domain.entity.SysUser` - 用于用户对象判断 #### 1.2 新增 Logger 字段 在类中添加了日志记录器: ```java private static final Logger log = LoggerFactory.getLogger(SysLoginService.class); ``` #### 1.3 新增方法:`validateSystemExpireTime` **功能说明:** - 检查 `system.top` 参数配置 - 如果配置存在且截止时间小于当前时间,则阻止登录 - 系统管理员(用户ID=1)不受此限制 **实现逻辑:** 1. 首先判断用户是否为系统管理员: - 如果提供了用户ID,使用 `SecurityUtils.isAdmin(userId)` 判断 - 如果只提供了用户名,通过 `userService.selectUserByUserName(username)` 查找用户,然后使用 `user.isAdmin()` 判断 - 系统管理员直接返回,跳过检查 2. 从配置服务获取 `system.top` 配置值 3. 解析日期时间(支持两种格式): - `yyyy-MM-dd`:自动转换为当天的 23:59:59 - `yyyy-MM-dd HH:mm:ss`:使用配置的精确时间 4. 比较当前时间与过期时间: - 如果当前时间在过期时间之后,抛出 `ServiceException("系统出现问题,请联系管理员")` - 记录登录失败日志 **关键代码位置:** 第 175-258 行 #### 1.4 登录前置校验集成 **文件位置:** `SysLoginService.java` 的 `loginPreCheck` 方法 **修改内容:** 在第 144-145 行添加了系统有效时间检查调用: ```java // 检查系统有效时间(系统管理员不受限制) validateSystemExpireTime(username, null); ``` **执行时机:** 在验证码校验之后、用户名密码校验之前执行 ### 2. 数据库初始化脚本 **文件位置:** `database_init_system_expire_time.sql` **功能说明:** - 在 `sys_config` 表中初始化 `system.top` 配置项 - 配置项默认值为空(不限制) - 支持 `ON DUPLICATE KEY UPDATE`,可以重复执行 **配置项说明:** - **配置键:** `system.top` - **配置名称:** 系统有效时间 - **配置值格式:** - `yyyy-MM-dd`(日期格式,系统在该日期的 23:59:59 之前可登录) - `yyyy-MM-dd HH:mm:ss`(日期时间格式,系统在该时间之前可登录) - 空值(不限制,系统永久可用) - **配置类型:** Y(是/否类型) ## 功能特性 ### 1. 系统管理员豁免 - 系统管理员(用户ID=1)不受系统有效时间限制 - 即使系统已过期,系统管理员仍可正常登录 - 判断方式: - 通过用户ID判断:`SecurityUtils.isAdmin(userId)` - 通过用户对象判断:`user.isAdmin()` ### 2. 日期格式支持 - **日期格式(yyyy-MM-dd):** 自动转换为当天的 23:59:59,确保当天仍可登录 - **日期时间格式(yyyy-MM-dd HH:mm:ss):** 使用精确的过期时间 ### 3. 错误处理 - 日期解析失败时,记录警告日志但不阻止登录(容错处理) - 用户查找失败时,继续执行系统有效时间检查 - 系统过期时,记录登录失败日志并抛出明确的异常信息 ### 4. 提示信息 - 当系统过期时,提示信息为:"系统出现问题,请联系管理员" - 登录日志中记录:"系统有效时间已过期" ## 使用方法 ### 1. 执行数据库初始化脚本 ```sql -- 执行初始化脚本 source database_init_system_expire_time.sql; -- 或者直接在数据库中执行脚本内容 ``` ### 2. 配置系统有效时间 **方式一:通过系统管理界面** 1. 登录系统(需要系统管理员权限) 2. 进入"系统管理" -> "参数设置" 3. 找到"系统有效时间"配置项(config_key: `system.top`) 4. 设置有效时间: - 日期格式:`2024-12-31`(表示 2024年12月31日 23:59:59 之前可登录) - 日期时间格式:`2024-12-31 23:59:59`(表示该时间之前可登录) - 清空值:不限制系统有效时间 **方式二:直接执行 SQL** ```sql -- 设置系统有效时间为 2024年12月31日 UPDATE sys_config SET config_value = '2024-12-31', update_time = NOW() WHERE config_key = 'system.top'; -- 设置系统有效时间为 2024年12月31日 23:59:59 UPDATE sys_config SET config_value = '2024-12-31 23:59:59', update_time = NOW() WHERE config_key = 'system.top'; -- 取消限制(清空配置值) UPDATE sys_config SET config_value = '', update_time = NOW() WHERE config_key = 'system.top'; ``` ### 3. 验证功能 1. **测试普通用户登录:** - 设置一个已过期的日期(如:`2020-01-01`) - 使用普通用户尝试登录 - 应该看到提示:"系统出现问题,请联系管理员" 2. **测试系统管理员登录:** - 保持过期日期设置 - 使用系统管理员(用户ID=1)登录 - 应该可以正常登录 3. **测试正常情况:** - 设置一个未来的日期(如:`2099-12-31`) - 普通用户应该可以正常登录 ## 技术细节 ### 依赖的方法和类 1. **SecurityUtils.isAdmin(Long userId)** - 位置:`com.ddnai.common.utils.SecurityUtils` - 功能:判断用户ID是否为系统管理员(用户ID=1) 2. **SysUser.isAdmin()** - 位置:`com.ddnai.common.core.domain.entity.SysUser` - 功能:判断用户对象是否为系统管理员 3. **ISysConfigService.selectConfigByKey(String key)** - 位置:`com.ddnai.system.service.ISysConfigService` - 功能:根据配置键获取配置值 4. **ISysUserService.selectUserByUserName(String username)** - 位置:`com.ddnai.system.service.ISysUserService` - 功能:根据用户名查找用户 5. **DateUtils.parseDate(String dateStr)** - 位置:`com.ddnai.common.utils.DateUtils` - 功能:解析日期字符串 6. **DateUtils.getNowDate()** - 位置:`com.ddnai.common.utils.DateUtils` - 功能:获取当前日期时间 ### 异常处理 - **ServiceException:** 当系统过期时抛出,包含提示信息"系统出现问题,请联系管理员" - **日期解析异常:** 捕获但不阻止登录,仅记录警告日志 ## 注意事项 1. **配置为空时不限制:** 如果 `system.top` 配置值为空或不存在,系统不进行有效时间检查 2. **系统管理员豁免:** 系统管理员(用户ID=1)始终不受限制,即使系统已过期 3. **日期格式:** 建议使用 `yyyy-MM-dd` 格式,系统会自动处理为当天的结束时间 4. **时区问题:** 系统使用服务器时区进行时间比较 5. **配置缓存:** 如果使用了配置缓存,修改配置后可能需要清除缓存才能生效 ## 移植对比 ### 借鉴项目(xinli)实现 - **文件位置:** `ry-xinli-framework/src/main/java/com/ddnai/framework/web/service/SysLoginService.java` - **配置键:** `system.top` - **功能:** 完整实现系统有效时间检查,系统管理员豁免 ### 当前项目(Study-Vue-redis)实现 - **文件位置:** `ry-study-framework/src/main/java/com/ddnai/framework/web/service/SysLoginService.java` - **配置键:** `system.top` - **功能:** 完整移植,与借鉴项目实现完全一致 ## 移植状态 ✅ **代码实现:** 已完成(与 xinli 项目完全一致) ✅ **数据库脚本:** 已创建 ✅ **功能测试:** 需要手动验证 ## 移植总结 本次移植从 `xinli` 借鉴项目中完整移植了系统有效时间控制功能,包括: 1. **核心方法:** `validateSystemExpireTime` 方法完整移植 2. **集成点:** 在 `loginPreCheck` 方法中调用系统有效时间检查 3. **依赖导入:** 添加了必要的导入语句和日志记录器 4. **数据库配置:** 创建了 SQL 初始化脚本 功能已完整移植,可以直接使用。建议执行数据库初始化脚本后,通过系统管理界面配置系统有效时间进行测试。