登录成功

This commit is contained in:
2025-10-06 16:20:05 +08:00
parent a3e8687b31
commit a58f316703
54 changed files with 17818 additions and 622 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,27 +1,49 @@
17:57:55.998 [main] INFO org.xyzh.App - The following 1 profile is active: "dev" 16:15:13.942 [main] INFO org.xyzh.App - The following 1 profile is active: "dev"
17:57:57.330 [main] INFO org.apache.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8080"] 16:15:15.663 [main] INFO org.apache.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8080"]
17:57:57.332 [main] INFO org.apache.catalina.core.StandardService - Starting service [Tomcat] 16:15:15.666 [main] INFO org.apache.catalina.core.StandardService - Starting service [Tomcat]
17:57:57.333 [main] INFO org.apache.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/10.1.46] 16:15:15.666 [main] INFO org.apache.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/10.1.46]
17:57:57.390 [main] INFO org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext 16:15:15.724 [main] INFO org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/schoolNewsServ] - Initializing Spring embedded WebApplicationContext
17:57:57.719 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.DepartmentMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert] 16:15:16.106 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.DepartmentMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
17:57:57.744 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.DepartmentMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById] 16:15:16.133 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.DepartmentMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById]
17:57:57.757 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.DepartmentMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById] 16:15:16.139 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.DepartmentMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById]
17:57:57.780 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.MenuMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert] 16:15:16.160 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.MenuMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
17:57:57.797 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.MenuMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById] 16:15:16.174 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.MenuMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById]
17:57:57.802 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.MenuMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById] 16:15:16.177 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.MenuMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById]
17:57:57.820 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.PermissionMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert] 16:15:16.209 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.PermissionMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
17:57:57.835 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.PermissionMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById] 16:15:16.228 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.PermissionMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById]
17:57:57.841 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.PermissionMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById] 16:15:16.233 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.PermissionMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById]
17:57:57.858 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.RoleMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert] 16:15:16.257 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.RoleMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
17:57:57.871 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.RoleMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById] 16:15:16.273 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.RoleMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById]
17:57:57.876 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.RoleMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById] 16:15:16.277 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.RoleMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById]
17:57:57.893 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.UserMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert] 16:15:16.298 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.UserMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
17:57:57.904 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.UserMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById] 16:15:16.315 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.UserMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById]
17:57:57.916 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.UserMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById] 16:15:16.320 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.UserMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById]
17:57:58.013 [main] DEBUG org.xyzh.auth.filter.JwtAuthenticationFilter - Filter 'jwtAuthenticationFilter' configured for use 16:15:16.451 [main] DEBUG org.xyzh.auth.filter.JwtAuthenticationFilter - Filter 'jwtAuthenticationFilter' configured for use
17:57:58.644 [main] INFO com.baomidou.mybatisplus.extension.spring.MybatisPlusApplicationContextAware - Register ApplicationContext instances org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@5b3a7ef5 16:15:17.645 [main] INFO com.baomidou.mybatisplus.extension.spring.MybatisPlusApplicationContextAware - Register ApplicationContext instances org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@60bbacfc
17:57:58.721 [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting... 16:15:17.732 [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
17:57:58.919 [main] INFO com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Added connection com.mysql.cj.jdbc.ConnectionImpl@43cbafa6 16:15:17.905 [main] INFO com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Added connection com.mysql.cj.jdbc.ConnectionImpl@36e358de
17:57:58.921 [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed. 16:15:17.907 [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.
17:58:00.104 [main] INFO org.apache.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8080"] 16:15:18.131 [main] INFO org.apache.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8080"]
17:58:01.150 [main] INFO org.xyzh.App - Started App in 8.201 seconds (process running for 9.225) 16:15:18.216 [main] INFO org.xyzh.App - Started App in 5.44 seconds (process running for 6.491)
16:15:21.207 [http-nio-8080-exec-1] INFO org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/schoolNewsServ] - Initializing Spring DispatcherServlet 'dispatcherServlet'
16:15:21.344 [http-nio-8080-exec-1] INFO org.xyzh.system.user.service.impl.SysUserServiceImpl - 开始根据过滤条件查询用户TbSysUser{id=null, username='null', password='null', email='3223905473@qq.com', phone='null', wechatID='null', status=null, createTime=null, updateTime=null, deleteTime=null, deleted=false}
16:15:21.399 [http-nio-8080-exec-1] DEBUG org.xyzh.system.mapper.UserMapper.selectByFilter - ==> Preparing: SELECT id, username, password, email, phone, wechat_id, create_time, update_time, delete_time, deleted, status FROM tb_sys_user WHERE deleted = 0 AND email = ? LIMIT 1
16:15:21.424 [http-nio-8080-exec-1] DEBUG org.xyzh.system.mapper.UserMapper.selectByFilter - ==> Parameters: 3223905473@qq.com(String)
16:15:21.449 [http-nio-8080-exec-1] DEBUG org.xyzh.system.mapper.UserMapper.selectByFilter - <== Total: 1
16:15:21.452 [http-nio-8080-exec-1] INFO org.xyzh.system.user.service.impl.SysUserServiceImpl - 根据过滤条件查询用户完成TbSysUser{id=null, username='null', password='null', email='3223905473@qq.com', phone='null', wechatID='null', status=null, createTime=null, updateTime=null, deleteTime=null, deleted=false}
16:15:21.518 [http-nio-8080-exec-1] INFO org.xyzh.auth.strategy.impl.PasswordLoginStrategy - $2a$10$kxhNI7a89B6ODU/vxe9LseKEUgjtHwegZkQAjwjKr1Lv.M3s8t3iq
16:15:24.471 [http-nio-8080-exec-1] INFO org.xyzh.system.role.service.impl.SysRoleServiceImpl - 开始根据用户ID查询部门角色列表1
16:15:24.473 [http-nio-8080-exec-1] DEBUG org.xyzh.system.mapper.RoleMapper.selectDeptRolesByUserId - ==> Preparing: SELECT dr.id, dr.dept_id, dr.role_id, r.name as role_name, d.name as dept_name, r.description as role_description, d.description as dept_description, r.creator as role_creator, d.creator as dept_creator, r.updater as role_updater, d.updater as dept_updater, r.create_time as role_create_time, d.create_time as dept_create_time, r.update_time as role_update_time, d.update_time as dept_update_time, r.delete_time as role_delete_time, d.delete_time as dept_delete_time, r.deleted as role_deleted, d.deleted as dept_deleted FROM tb_sys_user_dept_role dr INNER JOIN tb_sys_role r ON r.role_id = dr.role_id INNER JOIN tb_sys_dept d ON d.dept_id = dr.dept_id WHERE dr.deleted = 0 AND dr.user_id = ? ORDER BY dr.create_time ASC
16:15:24.474 [http-nio-8080-exec-1] DEBUG org.xyzh.system.mapper.RoleMapper.selectDeptRolesByUserId - ==> Parameters: 1(String)
16:15:24.476 [http-nio-8080-exec-1] DEBUG org.xyzh.system.mapper.RoleMapper.selectDeptRolesByUserId - <== Total: 1
16:15:24.476 [http-nio-8080-exec-1] INFO org.xyzh.system.role.service.impl.SysRoleServiceImpl - 根据用户ID查询部门角色列表完成共找到1个部门角色
16:15:24.751 [http-nio-8080-exec-1] INFO org.xyzh.system.permission.service.impl.SysPermissionServiceImpl - 开始根据用户ID查询权限列表1
16:15:24.752 [http-nio-8080-exec-1] DEBUG org.xyzh.system.mapper.PermissionMapper.selectPermissionsByUserId - ==> Preparing: SELECT DISTINCT p.id, p.permission_id, p.name, p.code, p.description, p.creator, p.updater, p.create_time, p.update_time, p.delete_time, p.deleted FROM tb_sys_user_dept_role ur INNER JOIN tb_sys_role_permission rp ON rp.role_id = ur.role_id INNER JOIN tb_sys_permission p ON p.permission_id = rp.permission_id WHERE p.deleted = 0 AND rp.deleted = 0 AND ur.deleted = 0 AND ur.user_id = ? ORDER BY p.create_time ASC
16:15:24.753 [http-nio-8080-exec-1] DEBUG org.xyzh.system.mapper.PermissionMapper.selectPermissionsByUserId - ==> Parameters: 1(String)
16:15:24.756 [http-nio-8080-exec-1] DEBUG org.xyzh.system.mapper.PermissionMapper.selectPermissionsByUserId - <== Total: 4
16:15:24.756 [http-nio-8080-exec-1] INFO org.xyzh.system.permission.service.impl.SysPermissionServiceImpl - 根据用户ID查询权限列表完成共找到4个权限
16:15:25.107 [http-nio-8080-exec-1] INFO org.xyzh.system.menu.service.impl.SysMenuServiceImpl - 开始根据用户ID查询菜单列表1
16:15:25.108 [http-nio-8080-exec-1] DEBUG org.xyzh.system.mapper.MenuMapper.selectMenusByUserId - ==> Preparing: SELECT DISTINCT m.id, m.menu_id, m.name, m.parent_id, m.url, m.icon, m.order_num, m.type, m.creator, m.updater, m.create_time, m.update_time, m.delete_time, m.deleted FROM tb_sys_user_dept_role ur INNER JOIN tb_sys_role_permission rp ON rp.role_id = ur.role_id INNER JOIN tb_sys_menu_permission mp ON mp.permission_id = rp.permission_id INNER JOIN tb_sys_menu m ON m.menu_id = mp.menu_id WHERE m.deleted = 0 AND rp.deleted = 0 AND mp.deleted = 0 AND ur.deleted = 0 AND ur.user_id = ? ORDER BY m.create_time ASC
16:15:25.108 [http-nio-8080-exec-1] DEBUG org.xyzh.system.mapper.MenuMapper.selectMenusByUserId - ==> Parameters: 1(String)
16:15:25.111 [http-nio-8080-exec-1] DEBUG org.xyzh.system.mapper.MenuMapper.selectMenusByUserId - <== Total: 5
16:15:25.112 [http-nio-8080-exec-1] INFO org.xyzh.system.menu.service.impl.SysMenuServiceImpl - 根据用户ID查询菜单列表完成共找到5个菜单

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,11 @@
server: server:
port: 8080 port: 8080
servlet:
context-path: /schoolNewsServ
encoding:
charset: UTF-8
enabled: true
force: true
spring: spring:
application: application:
name: school-news-admin name: school-news-admin
@@ -17,6 +23,33 @@ spring:
idle-timeout: 600000 idle-timeout: 600000
max-lifetime: 1800000 max-lifetime: 1800000
# Redis配置
data:
redis:
# Redis服务器地址
host: localhost
# Redis服务器端口
port: 6379
# Redis密码如果没有设置密码可以留空或注释掉
password: 123456
# Redis数据库索引0-15默认为0
database: 0
# 连接超时时间(毫秒)
timeout: 10000
# Lettuce连接池配置
lettuce:
pool:
# 连接池最大连接数
max-active: 50
# 连接池最大阻塞等待时间(负值表示没有限制)
max-wait: 3000
# 连接池中的最大空闲连接
max-idle: 20
# 连接池中的最小空闲连接
min-idle: 5
# 关闭超时时间
shutdown-timeout: 100ms
# 认证配置 # 认证配置
school-news: school-news:
auth: auth:
@@ -71,11 +104,9 @@ mybatis-plus:
# 日志配置 # 日志配置
logging: logging:
config: classpath:log4j2-spring.xml config: classpath:log4j2-spring.xml
level: charset:
org.xyzh: DEBUG console: UTF-8
org.xyzh.auth: DEBUG file: UTF-8
org.xyzh.system: DEBUG
org.xyzh.news: DEBUG
# 管理端点配置 # 管理端点配置
management: management:
@@ -86,13 +117,4 @@ management:
endpoint: endpoint:
health: health:
show-details: when-authorized show-details: when-authorized
# 文档配置
springdoc:
api-docs:
path: /v3/api-docs
swagger-ui:
path: /swagger-ui.html
tags-sorter: alpha
operations-sorter: alpha
debug: true debug: true

View File

@@ -14,27 +14,32 @@
<property name="FILE_PATH" value="./logs" /> <property name="FILE_PATH" value="./logs" />
<!-- Admin模块日志文件名 --> <!-- Admin模块日志文件名 -->
<property name="FILE_NAME" value="school-news-admin" /> <property name="FILE_NAME" value="school-news-admin" />
<!-- 设置系统属性 -->
<property name="file.encoding" value="UTF-8" />
<property name="console.encoding" value="UTF-8" />
<property name="stdout.encoding" value="UTF-8" />
<property name="stderr.encoding" value="UTF-8" />
</Properties> </Properties>
<appenders> <appenders>
<console name="Console" target="SYSTEM_OUT"> <console name="Console" target="SYSTEM_OUT">
<!--输出日志的格式--> <!--输出日志的格式-->
<PatternLayout pattern="${LOG_PATTERN}"/> <PatternLayout pattern="${LOG_PATTERN}" charset="UTF-8"/>
<!--控制台输出level及其以上级别的信息onMatch其他的直接拒绝onMismatch--> <!--控制台输出debug及以上级别的信息-->
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/> <ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY"/>
</console> </console>
<!--文件会打印出所有信息这个log每次运行程序会自动清空由append属性决定适合临时测试用--> <!--文件会打印出所有信息这个log每次运行程序会自动清空由append属性决定适合临时测试用-->
<File name="Filelog" fileName="${FILE_PATH}/${FILE_NAME}-test.log" append="false"> <File name="Filelog" fileName="${FILE_PATH}/${FILE_NAME}-test.log" append="false">
<PatternLayout pattern="${LOG_PATTERN}"/> <PatternLayout pattern="${LOG_PATTERN}" charset="UTF-8"/>
</File> </File>
<!-- 这个会打印出所有的info及以下级别的信息每次大小超过size则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档--> <!-- 这个会打印出所有的info及以下级别的信息每次大小超过size则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
<RollingFile name="RollingFileInfo" fileName="${FILE_PATH}/${FILE_NAME}-info.log" filePattern="${FILE_PATH}/${FILE_NAME}-INFO-%d{yyyy-MM-dd}_%i.log.gz"> <RollingFile name="RollingFileInfo" fileName="${FILE_PATH}/${FILE_NAME}-info.log" filePattern="${FILE_PATH}/${FILE_NAME}-INFO-%d{yyyy-MM-dd}_%i.log.gz">
<!--控制台只输出level及以上级别的信息onMatch其他的直接拒绝onMismatch--> <!--控制台只输出level及以上级别的信息onMatch其他的直接拒绝onMismatch-->
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/> <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="${LOG_PATTERN}"/> <PatternLayout pattern="${LOG_PATTERN}" charset="UTF-8"/>
<Policies> <Policies>
<!--interval属性用来指定多久滚动一次默认是1 hour--> <!--interval属性用来指定多久滚动一次默认是1 hour-->
<TimeBasedTriggeringPolicy interval="1"/> <TimeBasedTriggeringPolicy interval="1"/>
@@ -48,7 +53,7 @@
<RollingFile name="RollingFileWarn" fileName="${FILE_PATH}/${FILE_NAME}-warn.log" filePattern="${FILE_PATH}/${FILE_NAME}-WARN-%d{yyyy-MM-dd}_%i.log.gz"> <RollingFile name="RollingFileWarn" fileName="${FILE_PATH}/${FILE_NAME}-warn.log" filePattern="${FILE_PATH}/${FILE_NAME}-WARN-%d{yyyy-MM-dd}_%i.log.gz">
<!--控制台只输出level及以上级别的信息onMatch其他的直接拒绝onMismatch--> <!--控制台只输出level及以上级别的信息onMatch其他的直接拒绝onMismatch-->
<ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/> <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="${LOG_PATTERN}"/> <PatternLayout pattern="${LOG_PATTERN}" charset="UTF-8"/>
<Policies> <Policies>
<!--interval属性用来指定多久滚动一次默认是1 hour--> <!--interval属性用来指定多久滚动一次默认是1 hour-->
<TimeBasedTriggeringPolicy interval="1"/> <TimeBasedTriggeringPolicy interval="1"/>
@@ -62,7 +67,7 @@
<RollingFile name="RollingFileError" fileName="${FILE_PATH}/${FILE_NAME}-error.log" filePattern="${FILE_PATH}/${FILE_NAME}-ERROR-%d{yyyy-MM-dd}_%i.log.gz"> <RollingFile name="RollingFileError" fileName="${FILE_PATH}/${FILE_NAME}-error.log" filePattern="${FILE_PATH}/${FILE_NAME}-ERROR-%d{yyyy-MM-dd}_%i.log.gz">
<!--控制台只输出level及以上级别的信息onMatch其他的直接拒绝onMismatch--> <!--控制台只输出level及以上级别的信息onMatch其他的直接拒绝onMismatch-->
<ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/> <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="${LOG_PATTERN}"/> <PatternLayout pattern="${LOG_PATTERN}" charset="UTF-8"/>
<Policies> <Policies>
<!--interval属性用来指定多久滚动一次默认是1 hour--> <!--interval属性用来指定多久滚动一次默认是1 hour-->
<TimeBasedTriggeringPolicy interval="1"/> <TimeBasedTriggeringPolicy interval="1"/>

View File

@@ -3,6 +3,8 @@ package org.xyzh.api.auth.login;
import org.xyzh.common.core.domain.LoginParam; import org.xyzh.common.core.domain.LoginParam;
import org.xyzh.common.core.domain.LoginDomain; import org.xyzh.common.core.domain.LoginDomain;
import org.xyzh.common.core.domain.ResultDomain; import org.xyzh.common.core.domain.ResultDomain;
import jakarta.servlet.http.HttpServletRequest;
/** /**
* @description LoginService.java文件描述 登录服务接口 * @description LoginService.java文件描述 登录服务接口
* @filename LoginService.java * @filename LoginService.java
@@ -15,11 +17,11 @@ public interface LoginService {
/** /**
* @description 登录 * @description 登录
* @param loginParam 登录参数 * @param loginParam 登录参数
* @return ResultDomain<String> 返回结果 * @return ResultDomain<LoginDomain> 返回结果
* @author yslg * @author yslg
* @since 2025-09-28 * @since 2025-09-28
*/ */
ResultDomain<String> login(LoginParam loginParam); ResultDomain<LoginDomain> login(LoginParam loginParam, HttpServletRequest request);
/** /**
* @description 退出登录 * @description 退出登录

View File

@@ -2,6 +2,7 @@ package org.xyzh.api.system.role;
import org.xyzh.common.core.domain.ResultDomain; import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.dto.role.TbSysRole; import org.xyzh.common.dto.role.TbSysRole;
import org.xyzh.common.vo.DeptRoleVO;
/** /**
@@ -31,13 +32,13 @@ public interface RoleService {
ResultDomain<TbSysRole> getRoleById(String roleId); ResultDomain<TbSysRole> getRoleById(String roleId);
/** /**
* @description 根据用户ID查询角色列表 * @description 根据用户ID查询部门角色列表
* @param userId 用户ID * @param userId 用户ID
* @return ResultDomain<TbSysRole> 角色列表 * @return ResultDomain<DeptRoleVO> 角色列表
* @author yslg * @author yslg
* @since 2025-09-28 * @since 2025-09-28
*/ */
ResultDomain<TbSysRole> getRolesByUserId(String userId); ResultDomain<DeptRoleVO> getDeptRolesByUserId(String userId);
/** /**
* @description 创建角色 * @description 创建角色

View File

@@ -5,6 +5,7 @@ import java.util.List;
import org.xyzh.common.core.domain.ResultDomain; import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.dto.user.TbSysUser; import org.xyzh.common.dto.user.TbSysUser;
import org.xyzh.common.dto.user.TbSysUserInfo;
/** /**
* @description UserRemoteService.java文件描述 用户远程服务接口 * @description UserRemoteService.java文件描述 用户远程服务接口
@@ -32,6 +33,15 @@ public interface UserService {
*/ */
ResultDomain<TbSysUser> getUserById(String userId); ResultDomain<TbSysUser> getUserById(String userId);
/**
* @description 根据用户ID查询用户信息
* @param userId 用户ID
* @return ResultDomain<TbSysUserInfo> 用户信息
* @author yslg
* @since 2025-10-06
*/
ResultDomain<TbSysUserInfo> getUserInfoById(String userId);
/** /**
* @description 根据用户名查询用户 * @description 根据用户名查询用户
* @param username 用户名 * @param username 用户名

View File

@@ -90,7 +90,6 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId> <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency> </dependency>
<!-- JWT 依赖 --> <!-- JWT 依赖 -->
<dependency> <dependency>
<groupId>io.jsonwebtoken</groupId> <groupId>io.jsonwebtoken</groupId>

View File

@@ -8,6 +8,8 @@ import org.xyzh.common.core.domain.LoginDomain;
import org.xyzh.common.core.domain.ResultDomain; import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.utils.IDUtils; import org.xyzh.common.utils.IDUtils;
import jakarta.servlet.http.HttpServletRequest;
/** /**
* @description AuthController.java文件描述 认证控制器 * @description AuthController.java文件描述 认证控制器
* @filename AuthController.java * @filename AuthController.java
@@ -25,13 +27,13 @@ public class AuthController {
/** /**
* @description 用户登录 * @description 用户登录
* @param loginParam 登录参数 * @param loginParam 登录参数
* @return ResultDomain<String> 登录结果 * @return ResultDomain<LoginDomain> 登录结果
* @author yslg * @author yslg
* @since 2025-09-28 * @since 2025-09-28
*/ */
@PostMapping("/login") @PostMapping("/login")
public ResultDomain<String> login(@RequestBody LoginParam loginParam) { public ResultDomain<LoginDomain> login(@RequestBody LoginParam loginParam, HttpServletRequest request) {
return loginService.login(loginParam); return loginService.login(loginParam, request);
} }
/** /**

View File

@@ -0,0 +1,48 @@
package org.xyzh.auth.security;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.xyzh.auth.util.JwtTokenUtil;
import org.xyzh.common.core.security.TokenParser;
/**
* @description JwtTokenParser.java文件描述 JWT令牌解析器实现类
* @filename JwtTokenParser.java
* @author yslg
* @copyright xyzh
* @since 2025-10-06
*/
@Component
public class JwtTokenParser implements TokenParser {
private final JwtTokenUtil jwtTokenUtil;
/**
* Spring会自动注入无需@Autowired注解
*/
public JwtTokenParser(JwtTokenUtil jwtTokenUtil) {
this.jwtTokenUtil = jwtTokenUtil;
}
@Override
public String getUserIdFromToken(String token) {
return jwtTokenUtil.getUserIdFromToken(token);
}
@Override
public Claims getAllClaimsFromToken(String token) {
return jwtTokenUtil.getAllClaimsFromToken(token);
}
@Override
public boolean validateToken(String token, String userId) {
return jwtTokenUtil.validateToken(token, userId);
}
@Override
public boolean isTokenExpired(String token) {
return jwtTokenUtil.isTokenExpired(token);
}
}

View File

@@ -11,15 +11,25 @@ import org.xyzh.common.core.domain.LoginParam;
import org.xyzh.common.core.domain.LoginDomain; import org.xyzh.common.core.domain.LoginDomain;
import org.xyzh.common.core.domain.ResultDomain; import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.core.enums.UserStatus; import org.xyzh.common.core.enums.UserStatus;
import org.xyzh.common.dto.permission.TbSysPermission;
import org.xyzh.common.dto.user.TbSysUser; import org.xyzh.common.dto.user.TbSysUser;
import org.xyzh.common.dto.log.TbSysLoginLog; import org.xyzh.common.dto.log.TbSysLoginLog;
import org.xyzh.common.dto.menu.TbSysMenu;
import org.xyzh.common.exception.auth.AuthException; import org.xyzh.common.exception.auth.AuthException;
import org.xyzh.common.utils.IDUtils; import org.xyzh.common.utils.IDUtils;
import jakarta.servlet.http.HttpServletRequest;
import org.xyzh.api.system.user.UserService; import org.xyzh.api.system.user.UserService;
import org.xyzh.api.system.role.RoleService; import org.xyzh.api.system.role.RoleService;
import org.xyzh.api.system.permission.PermissionService; import org.xyzh.api.system.permission.PermissionService;
import org.xyzh.common.redis.service.RedisService;
import org.xyzh.api.system.menu.MenuService;
import org.xyzh.common.vo.DeptRoleVO;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.ArrayList; import java.util.ArrayList;
/** /**
@@ -38,12 +48,18 @@ public class LoginServiceImpl implements LoginService {
@Autowired @Autowired
private UserService userService; private UserService userService;
@Autowired(required = false) @Autowired
private RoleService roleService; private RoleService roleService;
@Autowired(required = false) @Autowired
private PermissionService permissionService; private PermissionService permissionService;
@Autowired
private MenuService menuService;
@Autowired
private RedisService redisService;
@Autowired @Autowired
private JwtTokenUtil jwtTokenUtil; private JwtTokenUtil jwtTokenUtil;
@@ -51,9 +67,9 @@ public class LoginServiceImpl implements LoginService {
private LoginLogService loginLogService; private LoginLogService loginLogService;
@Override @Override
public ResultDomain<String> login(LoginParam loginParam) { public ResultDomain<LoginDomain> login(LoginParam loginParam, HttpServletRequest request) {
ResultDomain<String> result = new ResultDomain<>(); ResultDomain<LoginDomain> result = new ResultDomain<>();
String ipAddress = request.getRemoteAddr();
try { try {
// 自动检测登录类型 // 自动检测登录类型
String loginType = detectLoginType(loginParam); String loginType = detectLoginType(loginParam);
@@ -84,24 +100,40 @@ public class LoginServiceImpl implements LoginService {
return result; return result;
} }
// 验证密码 if (loginType.equals("password")) {
if (!strategy.verifyPassword(loginParam.getPassword(), user.getPassword())) { // 验证凭据(密码或验证码)
if (!strategy.verifyCredential(loginParam.getPassword(), user.getPassword())) {
result.fail("密码错误"); result.fail("密码错误");
logLoginAttempt(loginParam, user, false, "密码错误"); logLoginAttempt(loginParam, user, false, "密码错误");
return result; return result;
} }
}
else {
// 验证凭据(验证码)
String storedCaptcha = (String) redisService.get("captcha:" + loginParam.getPhone());
if (!strategy.verifyCredential(loginParam.getCaptcha(), storedCaptcha)) {
result.fail("验证码错误");
logLoginAttempt(loginParam, user, false, "验证码错误");
return result;
}
// 验证码使用后删除
redisService.delete("captcha:" + loginParam.getPhone());
}
// 构建登录域对象 // 构建登录域对象
LoginDomain loginDomain = buildLoginDomain(user, loginType); LoginDomain loginDomain = buildLoginDomain(user, loginType, ipAddress);
// 生成JWT令牌 // 生成JWT令牌
String token = jwtTokenUtil.generateToken(loginDomain); loginDomain.setToken(jwtTokenUtil.generateToken(loginDomain));
// 将LoginDomain存储到Redis中
String redisKey = "login:token:" + user.getID();
redisService.set(redisKey, loginDomain, 24 * 60 * 60, TimeUnit.SECONDS);
// 记录成功登录日志 // 记录成功登录日志
logLoginAttempt(loginParam, user, true, "登录成功"); logLoginAttempt(loginParam, user, true, "登录成功");
result.success("登录成功", (String)null); result.success("登录成功", loginDomain);
result.setData(token); result.setData(loginDomain);
} catch (AuthException e) { } catch (AuthException e) {
result.fail(e.getMessage()); result.fail(e.getMessage());
@@ -139,7 +171,9 @@ public class LoginServiceImpl implements LoginService {
if (StringUtils.hasText(loginParam.getLoginType())) { if (StringUtils.hasText(loginParam.getLoginType())) {
return loginParam.getLoginType(); return loginParam.getLoginType();
} }
if (StringUtils.hasText(loginParam.getPassword())) {
return "password";
}
if (StringUtils.hasText(loginParam.getEmail())) { if (StringUtils.hasText(loginParam.getEmail())) {
return "email"; return "email";
} }
@@ -164,35 +198,47 @@ public class LoginServiceImpl implements LoginService {
* @author yslg * @author yslg
* @since 2025-09-28 * @since 2025-09-28
*/ */
private LoginDomain buildLoginDomain(TbSysUser user, String loginType) { private LoginDomain buildLoginDomain(TbSysUser user, String loginType, String ipAddress) {
LoginDomain loginDomain = new LoginDomain(); LoginDomain loginDomain = new LoginDomain();
loginDomain.setUser(user); loginDomain.setUser(user);
loginDomain.setLoginType(loginType); loginDomain.setLoginType(loginType);
loginDomain.setLoginTime(new Date()); loginDomain.setLoginTime(new Date());
loginDomain.setIpAddress(ipAddress);
// 获取用户角色和权限(如果服务可用) // 获取用户角色和权限(如果服务可用)
if (roleService != null) {
try { try {
// TODO: 需要在RoleService中实现findRolesByUserId方法 ResultDomain<DeptRoleVO> resultDomain = roleService.getDeptRolesByUserId(user.getID());
// loginDomain.setRoles(roleService.findRolesByUserId(user.getID())); if (resultDomain.isSuccess()) {
loginDomain.setRoles(new ArrayList<>()); List<DeptRoleVO> roles = resultDomain.getDataList();
} catch (Exception e) { loginDomain.setRoles(roles);
} else {
loginDomain.setRoles(new ArrayList<>()); loginDomain.setRoles(new ArrayList<>());
} }
} else { } catch (Exception e) {
loginDomain.setRoles(new ArrayList<>()); loginDomain.setRoles(new ArrayList<>());
} }
if (permissionService != null) {
try { try {
// TODO: 需要在PermissionService中实现findPermissionsByUserId方法 ResultDomain<TbSysPermission> resultDomain = permissionService.getPermissionsByUserId(user.getID());
// loginDomain.setPermissions(permissionService.findPermissionsByUserId(user.getID())); if (resultDomain.isSuccess()) {
List<TbSysPermission> permissions = resultDomain.getDataList();
loginDomain.setPermissions(permissions);
} else {
loginDomain.setPermissions(new ArrayList<>()); loginDomain.setPermissions(new ArrayList<>());
}
} catch (Exception e) { } catch (Exception e) {
loginDomain.setPermissions(new ArrayList<>()); loginDomain.setPermissions(new ArrayList<>());
} }
try {
ResultDomain<TbSysMenu> resultDomain = menuService.getMenusByUserId(user.getID());
if (resultDomain.isSuccess()) {
List<TbSysMenu> menus = resultDomain.getDataList();
loginDomain.setMenus(menus);
} else { } else {
loginDomain.setPermissions(new ArrayList<>()); loginDomain.setMenus(new ArrayList<>());
}
} catch (Exception e) {
loginDomain.setMenus(new ArrayList<>());
} }
return loginDomain; return loginDomain;

View File

@@ -39,12 +39,12 @@ public interface LoginStrategy {
TbSysUser findUser(LoginParam loginParam); TbSysUser findUser(LoginParam loginParam);
/** /**
* @description 验证密码 * @description 验证凭据(密码或验证码)
* @param inputPassword 输入密码 * @param inputCredential 输入凭据(密码或验证码)
* @param storedPassword 存储密码 * @param storedCredential 存储凭据(密码或验证码)
* @return boolean 是否匹配 * @return boolean 是否匹配
* @author yslg * @author yslg
* @since 2025-09-28 * @since 2025-09-28
*/ */
boolean verifyPassword(String inputPassword, String storedPassword); boolean verifyCredential(String inputCredential, String storedCredential);
} }

View File

@@ -43,7 +43,7 @@ public class EmailLoginStrategy implements LoginStrategy {
} }
@Override @Override
public boolean verifyPassword(String inputPassword, String storedPassword) { public boolean verifyCredential(String inputCredential, String storedCredential) {
return passwordEncoder.matches(inputPassword, storedPassword); return passwordEncoder.matches(inputCredential, storedCredential);
} }
} }

View File

@@ -0,0 +1,70 @@
package org.xyzh.auth.strategy.impl;
import org.springframework.stereotype.Component;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.xyzh.auth.strategy.LoginStrategy;
import org.xyzh.common.core.domain.LoginParam;
import org.xyzh.common.dto.user.TbSysUser;
import org.xyzh.common.utils.NonUtils;
import org.xyzh.api.system.user.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @description PasswordLoginStrategy.java文件描述 密码登录策略
* @filename PasswordLoginStrategy.java
* @author yslg
* @copyright xyzh
* @since 2025-09-28
*/
@Component
public class PasswordLoginStrategy implements LoginStrategy {
private static final Logger logger = LoggerFactory.getLogger(PasswordLoginStrategy.class);
@Autowired
private UserService userService;
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public String getLoginType() {
return "password";
}
@Override
public boolean validate(LoginParam loginParam) {
if (NonUtils.isEmpty(loginParam.getPassword())) {
return false;
}
if (NonUtils.isEmpty(loginParam.getUsername()) && NonUtils.isEmpty(loginParam.getEmail()) && NonUtils.isEmpty(loginParam.getPhone())) {
return false;
}
return true;
}
@Override
public TbSysUser findUser(LoginParam loginParam) {
TbSysUser filter = new TbSysUser();
if (NonUtils.isNotEmpty(loginParam.getUsername())) {
filter.setUsername(loginParam.getUsername());
}
if (NonUtils.isNotEmpty(loginParam.getEmail())) {
filter.setEmail(loginParam.getEmail());
}
if (NonUtils.isNotEmpty(loginParam.getPhone())) {
filter.setPhone(loginParam.getPhone());
}
return userService.getUserByFilter(filter).getData();
}
@Override
public boolean verifyCredential(String inputCredential, String storedCredential) {
logger.info(passwordEncoder.encode(inputCredential));
return passwordEncoder.matches(inputCredential, storedCredential);
}
}

View File

@@ -43,11 +43,11 @@ public class PhoneLoginStrategy implements LoginStrategy {
} }
@Override @Override
public boolean verifyPassword(String inputPassword, String storedPassword) { public boolean verifyCredential(String inputCredential, String storedCredential) {
// 手机号登录可能使用验证码,如果有验证码则跳过密码验证 // 手机号登录可能使用验证码,如果有验证码则跳过密码验证
if (inputPassword == null) { if (inputCredential == null) {
return true; // 假设验证码已经在其他地方验证过了 return true; // 假设验证码已经在其他地方验证过了
} }
return passwordEncoder.matches(inputPassword, storedPassword); return passwordEncoder.matches(inputCredential, storedCredential);
} }
} }

View File

@@ -43,7 +43,7 @@ public class UsernameLoginStrategy implements LoginStrategy {
} }
@Override @Override
public boolean verifyPassword(String inputPassword, String storedPassword) { public boolean verifyCredential(String inputCredential, String storedCredential) {
return passwordEncoder.matches(inputPassword, storedPassword); return passwordEncoder.matches(inputCredential, storedCredential);
} }
} }

View File

@@ -39,7 +39,7 @@ public class WechatLoginStrategy implements LoginStrategy {
} }
@Override @Override
public boolean verifyPassword(String inputPassword, String storedPassword) { public boolean verifyCredential(String inputCredential, String storedCredential) {
// 微信登录通常不需要密码验证,通过微信授权码验证 // 微信登录通常不需要密码验证,通过微信授权码验证
// 这里可以添加微信授权验证逻辑 // 这里可以添加微信授权验证逻辑
return true; return true;

View File

@@ -5,6 +5,21 @@ spring:
application: application:
name: school-news-auth name: school-news-auth
# Redis配置
data:
redis:
host: localhost
port: 6379
password:
database: 0
timeout: 5000ms
lettuce:
pool:
max-active: 8
max-wait: -1ms
max-idle: 8
min-idle: 0
datasource: datasource:
driver-class-name: com.mysql.cj.jdbc.Driver driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/school_news?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai url: jdbc:mysql://localhost:3306/school_news?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai

View File

@@ -12,27 +12,29 @@
<!-- 定义日志存储的路径 --> <!-- 定义日志存储的路径 -->
<property name="FILE_PATH" value="./logs" /> <property name="FILE_PATH" value="./logs" />
<property name="FILE_NAME" value="school-news-auth" /> <property name="FILE_NAME" value="school-news-auth" />
<property name="file.encoding" value="UTF-8" />
<property name="console.encoding" value="UTF-8" />
</Properties> </Properties>
<appenders> <appenders>
<console name="Console" target="SYSTEM_OUT"> <console name="Console" target="SYSTEM_OUT">
<!--输出日志的格式--> <!--输出日志的格式-->
<PatternLayout pattern="${LOG_PATTERN}"/> <PatternLayout pattern="${LOG_PATTERN}" charset="UTF-8"/>
<!--控制台只输出level及其以上级别的信息onMatch其他的直接拒绝onMismatch--> <!--控制台只输出level及其以上级别的信息onMatch其他的直接拒绝onMismatch-->
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/> <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
</console> </console>
<!--文件会打印出所有信息这个log每次运行程序会自动清空由append属性决定适合临时测试用--> <!--文件会打印出所有信息这个log每次运行程序会自动清空由append属性决定适合临时测试用-->
<File name="Filelog" fileName="${FILE_PATH}/test.log" append="false"> <File name="Filelog" fileName="${FILE_PATH}/test.log" append="false">
<PatternLayout pattern="${LOG_PATTERN}"/> <PatternLayout pattern="${LOG_PATTERN}" charset="UTF-8"/>
</File> </File>
<!-- 这个会打印出所有的info及以下级别的信息每次大小超过size则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档--> <!-- 这个会打印出所有的info及以下级别的信息每次大小超过size则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
<RollingFile name="RollingFileInfo" fileName="${FILE_PATH}/info.log" filePattern="${FILE_PATH}/${FILE_NAME}-INFO-%d{yyyy-MM-dd}_%i.log.gz"> <RollingFile name="RollingFileInfo" fileName="${FILE_PATH}/${FILE_NAME}-info.log" filePattern="${FILE_PATH}/${FILE_NAME}-INFO-%d{yyyy-MM-dd}_%i.log.gz">
<!--控制台只输出level及以上级别的信息onMatch其他的直接拒绝onMismatch--> <!--控制台只输出level及以上级别的信息onMatch其他的直接拒绝onMismatch-->
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/> <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="${LOG_PATTERN}"/> <PatternLayout pattern="${LOG_PATTERN}" charset="UTF-8"/>
<Policies> <Policies>
<!--interval属性用来指定多久滚动一次默认是1 hour--> <!--interval属性用来指定多久滚动一次默认是1 hour-->
<TimeBasedTriggeringPolicy interval="1"/> <TimeBasedTriggeringPolicy interval="1"/>
@@ -43,10 +45,10 @@
</RollingFile> </RollingFile>
<!-- 这个会打印出所有的warn及以下级别的信息每次大小超过size则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档--> <!-- 这个会打印出所有的warn及以下级别的信息每次大小超过size则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
<RollingFile name="RollingFileWarn" fileName="${FILE_PATH}/warn.log" filePattern="${FILE_PATH}/${FILE_NAME}-WARN-%d{yyyy-MM-dd}_%i.log.gz"> <RollingFile name="RollingFileWarn" fileName="${FILE_PATH}/${FILE_NAME}-warn.log" filePattern="${FILE_PATH}/${FILE_NAME}-WARN-%d{yyyy-MM-dd}_%i.log.gz">
<!--控制台只输出level及以上级别的信息onMatch其他的直接拒绝onMismatch--> <!--控制台只输出level及以上级别的信息onMatch其他的直接拒绝onMismatch-->
<ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/> <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="${LOG_PATTERN}"/> <PatternLayout pattern="${LOG_PATTERN}" charset="UTF-8"/>
<Policies> <Policies>
<!--interval属性用来指定多久滚动一次默认是1 hour--> <!--interval属性用来指定多久滚动一次默认是1 hour-->
<TimeBasedTriggeringPolicy interval="1"/> <TimeBasedTriggeringPolicy interval="1"/>
@@ -57,10 +59,10 @@
</RollingFile> </RollingFile>
<!-- 这个会打印出所有的error及以下级别的信息每次大小超过size则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档--> <!-- 这个会打印出所有的error及以下级别的信息每次大小超过size则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
<RollingFile name="RollingFileError" fileName="${FILE_PATH}/error.log" filePattern="${FILE_PATH}/${FILE_NAME}-ERROR-%d{yyyy-MM-dd}_%i.log.gz"> <RollingFile name="RollingFileError" fileName="${FILE_PATH}/${FILE_NAME}-error.log" filePattern="${FILE_PATH}/${FILE_NAME}-ERROR-%d{yyyy-MM-dd}_%i.log.gz">
<!--控制台只输出level及以上级别的信息onMatch其他的直接拒绝onMismatch--> <!--控制台只输出level及以上级别的信息onMatch其他的直接拒绝onMismatch-->
<ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/> <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="${LOG_PATTERN}"/> <PatternLayout pattern="${LOG_PATTERN}" charset="UTF-8"/>
<Policies> <Policies>
<!--interval属性用来指定多久滚动一次默认是1 hour--> <!--interval属性用来指定多久滚动一次默认是1 hour-->
<TimeBasedTriggeringPolicy interval="1"/> <TimeBasedTriggeringPolicy interval="1"/>

View File

@@ -18,4 +18,35 @@
<maven.compiler.target>21</maven.compiler.target> <maven.compiler.target>21</maven.compiler.target>
</properties> </properties>
<dependencies>
<!-- Spring Web MVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<!-- Spring Context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<!-- Common Core dependency -->
<dependency>
<groupId>org.xyzh</groupId>
<artifactId>common-core</artifactId>
</dependency>
<!-- Common Util dependency -->
<dependency>
<groupId>org.xyzh</groupId>
<artifactId>common-util</artifactId>
</dependency>
<!-- Common Redis dependency -->
<dependency>
<groupId>org.xyzh</groupId>
<artifactId>common-redis</artifactId>
</dependency>
</dependencies>
</project> </project>

View File

@@ -1,7 +0,0 @@
package org.xyzh;
public class Main {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}

View File

@@ -0,0 +1,32 @@
package org.xyzh.common.annotation;
import java.lang.annotation.*;
/**
* @description HttpLogin.java文件描述 HTTP登录注解
* @filename HttpLogin.java
* @author yslg
* @copyright xyzh
* @since 2025-10-06
*/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface HttpLogin {
/**
* @description 是否必需默认为true
* @return boolean
* @author yslg
* @since 2025-10-06
*/
boolean required() default true;
/**
* @description 当token无效时的错误消息
* @return String
* @author yslg
* @since 2025-10-06
*/
String message() default "用户未登录或登录已过期";
}

View File

@@ -0,0 +1,34 @@
package org.xyzh.common.annotation.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.xyzh.common.annotation.resolver.HttpLoginArgumentResolver;
import java.util.List;
/**
* @description WebMvcConfig.java文件描述 Web MVC配置
* @filename WebMvcConfig.java
* @author yslg
* @copyright xyzh
* @since 2025-10-06
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
private final HttpLoginArgumentResolver httpLoginArgumentResolver;
/**
* 使用构造器注入
* 通过接口抽象解决了循环依赖问题,不再需要@Lazy注解
*/
public WebMvcConfig(HttpLoginArgumentResolver httpLoginArgumentResolver) {
this.httpLoginArgumentResolver = httpLoginArgumentResolver;
}
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(httpLoginArgumentResolver);
}
}

View File

@@ -0,0 +1,135 @@
package org.xyzh.common.annotation.resolver;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.xyzh.common.annotation.HttpLogin;
import org.xyzh.common.core.domain.LoginDomain;
import org.xyzh.common.core.security.TokenParser;
import org.xyzh.common.redis.service.RedisService;
import org.xyzh.common.utils.NonUtils;
import jakarta.servlet.http.HttpServletRequest;
/**
* @description HttpLoginArgumentResolver.java文件描述 HTTP登录参数解析器
* @filename HttpLoginArgumentResolver.java
* @author yslg
* @copyright xyzh
* @since 2025-10-06
*/
@Component
public class HttpLoginArgumentResolver implements HandlerMethodArgumentResolver {
private final TokenParser tokenParser;
private final RedisService redisService;
/**
* 使用构造器注入依赖TokenParser接口而非具体实现
* 这样避免了与auth模块的直接依赖解决循环依赖问题
*/
public HttpLoginArgumentResolver(TokenParser tokenParser,
RedisService redisService) {
this.tokenParser = tokenParser;
this.redisService = redisService;
}
private static final String TOKEN_PREFIX = "Bearer ";
private static final String REDIS_LOGIN_PREFIX = "login:token:";
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(HttpLogin.class)
&& LoginDomain.class.isAssignableFrom(parameter.getParameterType());
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
HttpLogin httpLogin = parameter.getParameterAnnotation(HttpLogin.class);
if (httpLogin == null) {
return null;
}
// 从请求头中获取token
String token = extractTokenFromRequest(webRequest);
if (NonUtils.isEmpty(token)) {
if (httpLogin.required()) {
throw new IllegalArgumentException(httpLogin.message());
}
return null;
}
try {
// 验证token格式和有效性
if (!tokenParser.validateToken(token, tokenParser.getUserIdFromToken(token))) {
if (httpLogin.required()) {
throw new IllegalArgumentException(httpLogin.message());
}
return null;
}
// 从Redis中获取LoginDomain
String userId = tokenParser.getUserIdFromToken(token);
String redisKey = REDIS_LOGIN_PREFIX + userId;
LoginDomain loginDomain = (LoginDomain) redisService.get(redisKey);
if (loginDomain == null) {
if (httpLogin.required()) {
throw new IllegalArgumentException(httpLogin.message());
}
return null;
}
// 更新token信息
loginDomain.setToken(token);
return loginDomain;
} catch (Exception e) {
if (httpLogin.required()) {
throw new IllegalArgumentException(httpLogin.message());
}
return null;
}
}
/**
* @description 从请求中提取token
* @param webRequest 请求对象
* @return String token
* @author yslg
* @since 2025-10-06
*/
private String extractTokenFromRequest(NativeWebRequest webRequest) {
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
if (request == null) {
return null;
}
// 优先从Authorization头获取
String authHeader = request.getHeader(HttpHeaders.AUTHORIZATION);
if (NonUtils.isNotEmpty(authHeader) && authHeader.startsWith(TOKEN_PREFIX)) {
return authHeader.substring(TOKEN_PREFIX.length());
}
// 从请求参数中获取token
String token = request.getParameter("token");
if (NonUtils.isNotEmpty(token)) {
return token;
}
// 从请求头中获取token
token = request.getHeader("token");
if (NonUtils.isNotEmpty(token)) {
return token;
}
return null;
}
}

View File

@@ -23,5 +23,12 @@
<groupId>org.xyzh</groupId> <groupId>org.xyzh</groupId>
<artifactId>common-dto</artifactId> <artifactId>common-dto</artifactId>
</dependency> </dependency>
<!-- JWT API - 仅接口定义具体实现由auth模块提供 -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<scope>provided</scope>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@@ -9,7 +9,7 @@ import org.xyzh.common.dto.role.TbSysRole;
import org.xyzh.common.dto.permission.TbSysPermission; import org.xyzh.common.dto.permission.TbSysPermission;
import org.xyzh.common.dto.dept.TbSysDeptRole; import org.xyzh.common.dto.dept.TbSysDeptRole;
import org.xyzh.common.dto.menu.TbSysMenu; import org.xyzh.common.dto.menu.TbSysMenu;
import org.xyzh.common.vo.DeptRoleVO;
/** /**
* @description LoginDomain.java文件描述 登录域对象 * @description LoginDomain.java文件描述 登录域对象
* @filename LoginDomain.java * @filename LoginDomain.java
@@ -40,7 +40,7 @@ public class LoginDomain implements Serializable {
* @author yslg * @author yslg
* @since 2025-09-28 * @since 2025-09-28
*/ */
private List<TbSysDeptRole> roles; private List<DeptRoleVO> roles;
/** /**
* @description 用户权限列表 * @description 用户权限列表
@@ -132,7 +132,7 @@ public class LoginDomain implements Serializable {
* @author yslg * @author yslg
* @since 2025-09-28 * @since 2025-09-28
*/ */
public List<TbSysDeptRole> getRoles() { public List<DeptRoleVO> getRoles() {
return roles; return roles;
} }
@@ -141,7 +141,7 @@ public class LoginDomain implements Serializable {
* @author yslg * @author yslg
* @since 2025-09-28 * @since 2025-09-28
*/ */
public void setRoles(List<TbSysDeptRole> roles) { public void setRoles(List<DeptRoleVO> roles) {
this.roles = roles; this.roles = roles;
} }

View File

@@ -0,0 +1,51 @@
package org.xyzh.common.core.security;
import io.jsonwebtoken.Claims;
/**
* @description TokenParser.java文件描述 令牌解析器接口
* @filename TokenParser.java
* @author yslg
* @copyright xyzh
* @since 2025-10-06
*/
public interface TokenParser {
/**
* @description 从令牌中获取用户ID
* @param token 令牌
* @return String 用户ID
* @author yslg
* @since 2025-10-06
*/
String getUserIdFromToken(String token);
/**
* @description 从令牌中获取所有声明信息
* @param token 令牌
* @return Claims 所有声明信息
* @author yslg
* @since 2025-10-06
*/
Claims getAllClaimsFromToken(String token);
/**
* @description 验证令牌
* @param token 令牌
* @param userId 用户ID
* @return boolean 是否有效
* @author yslg
* @since 2025-10-06
*/
boolean validateToken(String token, String userId);
/**
* @description 检查令牌是否过期
* @param token 令牌
* @return boolean 是否过期
* @author yslg
* @since 2025-10-06
*/
boolean isTokenExpired(String token);
}

View File

@@ -3,13 +3,13 @@ package org.xyzh.common.dto.user;
import org.xyzh.common.dto.BaseDTO; import org.xyzh.common.dto.BaseDTO;
/** /**
* @description TbSysUserRole.java文件描述 用户角色 * @description TbSysUserDeptRole.java文件描述 用户部门角色
* @filename TbSysUserRole.java * @filename TbSysUserDeptRole.java
* @author yslg * @author yslg
* @copyright xyzh * @copyright xyzh
* @since 2025-09-26 * @since 2025-09-26
*/ */
public class TbSysUserRole extends BaseDTO{ public class TbSysUserDeptRole extends BaseDTO{
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@@ -20,6 +20,13 @@ public class TbSysUserRole extends BaseDTO{
*/ */
private String userID; private String userID;
/**
* @description 部门ID
* @author yslg
* @since 2024-06
*/
private String deptID;
/** /**
* @description 角色ID * @description 角色ID
* @author yslg * @author yslg
@@ -49,6 +56,14 @@ public class TbSysUserRole extends BaseDTO{
this.userID = userID; this.userID = userID;
} }
public String getDeptID() {
return deptID;
}
public void setDeptID(String deptID) {
this.deptID = deptID;
}
public String getRoleID() { public String getRoleID() {
return roleID; return roleID;
} }
@@ -75,9 +90,10 @@ public class TbSysUserRole extends BaseDTO{
@Override @Override
public String toString() { public String toString() {
return "TbSysUserRole{" + return "TbSysUserDeptRole{" +
"id='" + getID() + '\'' + "id='" + getID() + '\'' +
", userID='" + userID + '\'' + ", userID='" + userID + '\'' +
", deptID='" + deptID + '\'' +
", roleID='" + roleID + '\'' + ", roleID='" + roleID + '\'' +
", creator='" + creator + '\'' + ", creator='" + creator + '\'' +
", updater='" + updater + '\'' + ", updater='" + updater + '\'' +

View File

@@ -0,0 +1,26 @@
package org.xyzh.common.vo;
import org.xyzh.common.dto.dept.TbSysDept;
import org.xyzh.common.dto.role.TbSysRole;
public class DeptRoleVO {
private TbSysDept dept;
private TbSysRole role;
public TbSysDept getDept() {
return dept;
}
public void setDept(TbSysDept dept) {
this.dept = dept;
}
public TbSysRole getRole() {
return role;
}
public void setRole(TbSysRole role) {
this.role = role;
}
}

View File

@@ -0,0 +1,25 @@
package org.xyzh.common.vo;
public class UserVO {
private String id;
private String userID;
private String username;
private String email;
private String phone;
private String wechatID;
private String avatar;
private String gender;
private String familyName;
private String givenName;
private String fullName;
private String idCard;
private String address;
private String createTime;
private String updateTime;
private String deleteTime;
private String deleted;
private String status;
}

View File

@@ -18,4 +18,49 @@
<maven.compiler.target>21</maven.compiler.target> <maven.compiler.target>21</maven.compiler.target>
</properties> </properties>
<dependencies>
<!-- Spring Boot Redis Starter -->
<!-- Redis 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<!-- 排除默认的logback依赖 -->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Spring Data Redis -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
</dependency>
<!-- FastJSON2 for JSON serialization -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
</dependency>
<!-- Common Core dependency -->
<dependency>
<groupId>org.xyzh</groupId>
<artifactId>common-core</artifactId>
</dependency>
<!-- Spring Context for @Component annotation -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<!-- Spring Boot Auto Configuration -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
</dependencies>
</project> </project>

View File

@@ -1,7 +0,0 @@
package org.xyzh;
public class Main {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}

View File

@@ -0,0 +1,54 @@
package org.xyzh.common.redis.config;
import org.xyzh.common.core.constant.Constants;
import java.nio.charset.Charset;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONReader;
import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.filter.Filter;
/**
* @description FastJson2JsonRedisSerializer.java文件描述
* @filename FastJson2JsonRedisSerializer.java
* @author yslg
* @copyright xyzh
* @since 2025-09-07
*/
public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T>
{
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
static final Filter AUTO_TYPE_FILTER = JSONReader.autoTypeFilter(Constants.JSON_WHITELIST_STR);
private Class<T> clazz;
public FastJson2JsonRedisSerializer(Class<T> clazz)
{
super();
this.clazz = clazz;
}
@Override
public byte[] serialize(T t) throws SerializationException
{
if (t == null)
{
return new byte[0];
}
return JSON.toJSONString(t, JSONWriter.Feature.WriteClassName).getBytes(DEFAULT_CHARSET);
}
@Override
public T deserialize(byte[] bytes) throws SerializationException
{
if (bytes == null || bytes.length <= 0)
{
return null;
}
String str = new String(bytes, DEFAULT_CHARSET);
return JSON.parseObject(str, clazz, AUTO_TYPE_FILTER);
}
}

View File

@@ -0,0 +1,44 @@
package org.xyzh.common.redis.config;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* @description RedisConfig.java文件描述 Redis配置
* @filename RedisConfig.java
* @author yslg
* @copyright xyzh
* @since 2025-09-07
*/
@Configuration
@EnableCaching
@AutoConfigureBefore(RedisAutoConfiguration.class)
public class RedisConfig {
@Bean
@SuppressWarnings(value = { "unchecked", "rawtypes" })
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory)
{
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class);
// 使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(serializer);
// Hash的key也采用StringRedisSerializer的序列化方式
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(serializer);
template.afterPropertiesSet();
return template;
}
}

View File

@@ -0,0 +1,384 @@
package org.xyzh.common.redis.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.RedisCallback;
import java.util.*;
import java.util.concurrent.TimeUnit;
import org.springframework.stereotype.Component;
/**
* @description RedisService.java Redis工具服务类封装常用Redis操作
* @filename RedisService.java
* @author yslg
* @copyright xyzh
* @since 2025-09-07
*/
@SuppressWarnings(value = { "unchecked", "rawtypes" })
@Component
public class RedisService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
* @description 设置key-value
* @param key String 键
* @param value Object 值
* @author yslg
* @since 2025-09-07
*/
public void set(String key, Object value) {
redisTemplate.opsForValue().set(key, value);
}
/**
* @description 设置key-value并指定过期时间
* @param key String 键
* @param value Object 值
* @param timeout long 过期时间
* @param unit TimeUnit 时间单位
* @author yslg
* @since 2025-09-07
*/
public void set(String key, Object value, long timeout, TimeUnit unit) {
redisTemplate.opsForValue().set(key, value, timeout, unit);
}
/**
* @description 获取key对应的value
* @param key String 键
* @return Object 值
* @author yslg
* @since 2025-09-07
*/
public Object get(String key) {
return redisTemplate.opsForValue().get(key);
}
/**
* @description 删除key
* @param key String 键
* @author yslg
* @since 2025-09-07
*/
public void delete(String key) {
redisTemplate.delete(key);
}
/**
* @description 批量删除key
* @param keys Collection<String> 键集合
* @author yslg
* @since 2025-09-07
*/
public void delete(Collection<String> keys) {
redisTemplate.delete(keys);
}
/**
* @description 判断key是否存在
* @param key String 键
* @return boolean 是否存在
* @author yslg
* @since 2025-09-07
*/
public boolean hasKey(String key) {
return redisTemplate.hasKey(key);
}
/**
* @description 设置key过期时间
* @param key String 键
* @param timeout long 过期秒数
* @author yslg
* @since 2025-09-07
*/
public void setExpire(String key, long timeout) {
redisTemplate.expire(key, timeout, TimeUnit.SECONDS);
}
/**
* @description 设置key过期时间自定义单位
* @param key String 键
* @param timeout long 过期时间
* @param unit TimeUnit 时间单位
* @author yslg
* @since 2025-09-07
*/
public void setExpire(String key, long timeout, TimeUnit unit) {
redisTemplate.expire(key, timeout, unit);
}
/**
* @description 获取key剩余过期时间
* @param key String 键
* @return long 剩余秒数
* @author yslg
* @since 2025-09-07
*/
public long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
/**
* @description 原子递增
* @param key String 键
* @param delta long 增量
* @return long 递增后值
* @author yslg
* @since 2025-09-07
*/
public long incr(String key, long delta) {
Long result = redisTemplate.opsForValue().increment(key, delta);
return result != null ? result : 0L;
}
/**
* @description 原子递减
* @param key String 键
* @param delta long 减量
* @return long 递减后值
* @author yslg
* @since 2025-09-07
*/
public long decr(String key, long delta) {
Long result = redisTemplate.opsForValue().increment(key, -delta);
return result != null ? result : 0L;
}
/**
* @description Hash操作-put
* @param key String 键
* @param hashKey String 哈希键
* @param value Object 值
* @author yslg
* @since 2025-09-07
*/
public void hSet(String key, String hashKey, Object value) {
redisTemplate.opsForHash().put(key, hashKey, value);
}
/**
* @description Hash操作-get
* @param key String 键
* @param hashKey String 哈希键
* @return Object 值
* @author yslg
* @since 2025-09-07
*/
public Object hGet(String key, String hashKey) {
return redisTemplate.opsForHash().get(key, hashKey);
}
/**
* @description Hash操作-获取所有
* @param key String 键
* @return Map<Object, Object> 哈希所有键值对
* @author yslg
* @since 2025-09-07
*/
public Map<Object, Object> hGetAll(String key) {
return redisTemplate.opsForHash().entries(key);
}
/**
* @description Hash操作-删除
* @param key String 键
* @param hashKeys String[] 哈希键数组
* @author yslg
* @since 2025-09-07
*/
public void hDelete(String key, String... hashKeys) {
redisTemplate.opsForHash().delete(key, (Object[]) hashKeys);
}
/**
* @description List操作-左入队
* @param key String 键
* @param value Object 值
* @author yslg
* @since 2025-09-07
*/
public void lPush(String key, Object value) {
redisTemplate.opsForList().leftPush(key, value);
}
/**
* @description List操作-右入队
* @param key String 键
* @param value Object 值
* @author yslg
* @since 2025-09-07
*/
public void rPush(String key, Object value) {
redisTemplate.opsForList().rightPush(key, value);
}
/**
* @description List操作-左出队
* @param key String 键
* @return Object 出队值
* @author yslg
* @since 2025-09-07
*/
public Object lPop(String key) {
return redisTemplate.opsForList().leftPop(key);
}
/**
* @description List操作-右出队
* @param key String 键
* @return Object 出队值
* @author yslg
* @since 2025-09-07
*/
public Object rPop(String key) {
return redisTemplate.opsForList().rightPop(key);
}
/**
* @description List操作-获取区间元素
* @param key String 键
* @param start long 起始索引
* @param end long 结束索引
* @return List<Object> 元素列表
* @author yslg
* @since 2025-09-07
*/
public List<Object> lRange(String key, long start, long end) {
return redisTemplate.opsForList().range(key, start, end);
}
/**
* @description Set操作-添加元素
* @param key String 键
* @param values Object[] 元素数组
* @author yslg
* @since 2025-09-07
*/
public void sAdd(String key, Object... values) {
redisTemplate.opsForSet().add(key, values);
}
/**
* @description Set操作-移除元素
* @param key String 键
* @param values Object[] 元素数组
* @author yslg
* @since 2025-09-07
*/
public void sRemove(String key, Object... values) {
redisTemplate.opsForSet().remove(key, values);
}
/**
* @description Set操作-获取所有元素
* @param key String 键
* @return Set<Object> 元素集合
* @author yslg
* @since 2025-09-07
*/
public Set<Object> sMembers(String key) {
return redisTemplate.opsForSet().members(key);
}
/**
* @description ZSet操作-添加元素
* @param key String 键
* @param value Object 元素
* @param score double 分数
* @author yslg
* @since 2025-09-07
*/
public void zAdd(String key, Object value, double score) {
redisTemplate.opsForZSet().add(key, value, score);
}
/**
* @description ZSet操作-移除元素
* @param key String 键
* @param values Object[] 元素数组
* @author yslg
* @since 2025-09-07
*/
public void zRemove(String key, Object... values) {
redisTemplate.opsForZSet().remove(key, values);
}
/**
* @description ZSet操作-按分数区间获取元素
* @param key String 键
* @param min double 最小分数
* @param max double 最大分数
* @return Set<Object> 元素集合
* @author yslg
* @since 2025-09-07
*/
public Set<Object> zRangeByScore(String key, double min, double max) {
return redisTemplate.opsForZSet().rangeByScore(key, min, max);
}
/**
* @description ZSet操作-获取全部元素
* @param key String 键
* @param start long 起始索引
* @param end long 结束索引
* @return Set<Object> 元素集合
* @author yslg
* @since 2025-09-07
*/
public Set<Object> zRange(String key, long start, long end) {
return redisTemplate.opsForZSet().range(key, start, end);
}
/**
* @description 发布消息Pub/Sub
* @param channel String 通道
* @param message Object 消息内容
* @author yslg
* @since 2025-09-07
*/
public void publish(String channel, Object message) {
redisTemplate.convertAndSend(channel, message);
}
/**
* @description 执行Redis原生命令
* @param action RedisCallback<?> 回调命令
* @return Object 执行结果
* @author yslg
* @since 2025-09-07
*/
public Object execute(RedisCallback<?> action) {
return redisTemplate.execute(action);
}
/**
* @description 获取所有key慎用
* @param pattern String 匹配模式
* @return Set<String> key集合
* @author yslg
* @since 2025-09-07
*/
public Set<String> keys(String pattern) {
Set<String> keys = redisTemplate.keys(pattern);
Set<String> stringKeys = new HashSet<>();
if (keys != null) {
for (String key : keys) {
stringKeys.add(key);
}
}
return stringKeys;
}
/**
* @description 清空当前数据库(慎用)
* @author yslg
* @since 2025-09-07
*/
public void flushDb() {
redisTemplate.execute((RedisCallback<Void>) connection -> { connection.flushDb(); return null; });
}
}

View File

@@ -1,50 +0,0 @@
16:57:09.456 [main] INFO org.xyzh.App - No active profile set, falling back to 1 default profile: "default"
16:58:18.891 [main] INFO org.xyzh.App - No active profile set, falling back to 1 default profile: "default"
17:17:14.156 [main] INFO org.xyzh.App - No active profile set, falling back to 1 default profile: "default"
17:19:09.640 [main] INFO org.xyzh.App - No active profile set, falling back to 1 default profile: "default"
17:39:25.742 [main] INFO org.xyzh.App - No active profile set, falling back to 1 default profile: "default"
17:39:26.835 [main] INFO org.apache.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8080"]
17:39:26.836 [main] INFO org.apache.catalina.core.StandardService - Starting service [Tomcat]
17:39:26.842 [main] INFO org.apache.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/10.1.46]
17:39:26.891 [main] INFO org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext
17:39:27.154 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.DepartmentMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
17:39:27.168 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.DepartmentMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById]
17:39:27.171 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.DepartmentMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById]
17:39:27.186 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.MenuMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
17:39:27.195 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.MenuMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById]
17:39:27.197 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.MenuMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById]
17:39:27.209 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.PermissionMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
17:39:27.216 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.PermissionMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById]
17:39:27.218 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.PermissionMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById]
17:39:27.238 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.RoleMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
17:39:27.245 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.RoleMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById]
17:39:27.247 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.RoleMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById]
17:39:27.286 [main] INFO org.apache.catalina.core.StandardService - Stopping service [Tomcat]
17:39:56.337 [main] INFO org.xyzh.App - No active profile set, falling back to 1 default profile: "default"
17:39:57.402 [main] INFO org.apache.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8080"]
17:39:57.403 [main] INFO org.apache.catalina.core.StandardService - Starting service [Tomcat]
17:39:57.404 [main] INFO org.apache.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/10.1.46]
17:39:57.458 [main] INFO org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext
17:39:57.711 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.DepartmentMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
17:39:57.725 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.DepartmentMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById]
17:39:57.727 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.DepartmentMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById]
17:39:57.741 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.MenuMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
17:39:57.750 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.MenuMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById]
17:39:57.752 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.MenuMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById]
17:39:57.763 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.PermissionMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
17:39:57.770 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.PermissionMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById]
17:39:57.772 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.PermissionMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById]
17:39:57.782 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.RoleMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
17:39:57.789 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.RoleMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById]
17:39:57.791 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.RoleMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById]
17:39:57.801 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.UserMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
17:39:57.808 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.UserMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById]
17:39:57.810 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.UserMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById]
17:39:58.316 [main] INFO com.baomidou.mybatisplus.extension.spring.MybatisPlusApplicationContextAware - Register ApplicationContext instances org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@149c3204
17:39:58.390 [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
17:39:58.538 [main] INFO com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Added connection com.mysql.cj.jdbc.ConnectionImpl@4d16975b
17:39:58.540 [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.
17:39:59.724 [main] INFO org.apache.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8080"]
17:40:00.762 [main] INFO org.xyzh.App - Started App in 7.332 seconds (process running for 8.448)
17:40:03.682 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown initiated...
17:40:03.688 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown completed.

View File

@@ -1,29 +0,0 @@
17:39:56.337 [main] INFO org.xyzh.App - No active profile set, falling back to 1 default profile: "default"
17:39:57.402 [main] INFO org.apache.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8080"]
17:39:57.403 [main] INFO org.apache.catalina.core.StandardService - Starting service [Tomcat]
17:39:57.404 [main] INFO org.apache.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/10.1.46]
17:39:57.458 [main] INFO org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext
17:39:57.711 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.DepartmentMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
17:39:57.725 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.DepartmentMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById]
17:39:57.727 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.DepartmentMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById]
17:39:57.741 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.MenuMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
17:39:57.750 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.MenuMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById]
17:39:57.752 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.MenuMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById]
17:39:57.763 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.PermissionMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
17:39:57.770 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.PermissionMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById]
17:39:57.772 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.PermissionMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById]
17:39:57.782 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.RoleMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
17:39:57.789 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.RoleMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById]
17:39:57.791 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.RoleMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById]
17:39:57.801 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.UserMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
17:39:57.808 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.UserMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById]
17:39:57.810 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.UserMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById]
17:39:57.893 [main] DEBUG org.xyzh.auth.filter.JwtAuthenticationFilter - Filter 'jwtAuthenticationFilter' configured for use
17:39:58.316 [main] INFO com.baomidou.mybatisplus.extension.spring.MybatisPlusApplicationContextAware - Register ApplicationContext instances org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@149c3204
17:39:58.390 [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
17:39:58.538 [main] INFO com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Added connection com.mysql.cj.jdbc.ConnectionImpl@4d16975b
17:39:58.540 [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.
17:39:59.724 [main] INFO org.apache.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8080"]
17:40:00.762 [main] INFO org.xyzh.App - Started App in 7.332 seconds (process running for 8.448)
17:40:03.682 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown initiated...
17:40:03.688 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown completed.

View File

@@ -1,27 +0,0 @@
17:39:27.154 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.DepartmentMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
17:39:27.168 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.DepartmentMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById]
17:39:27.171 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.DepartmentMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById]
17:39:27.186 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.MenuMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
17:39:27.195 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.MenuMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById]
17:39:27.197 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.MenuMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById]
17:39:27.209 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.PermissionMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
17:39:27.216 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.PermissionMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById]
17:39:27.218 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.PermissionMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById]
17:39:27.238 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.RoleMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
17:39:27.245 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.RoleMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById]
17:39:27.247 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.RoleMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById]
17:39:57.711 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.DepartmentMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
17:39:57.725 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.DepartmentMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById]
17:39:57.727 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.DepartmentMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById]
17:39:57.741 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.MenuMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
17:39:57.750 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.MenuMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById]
17:39:57.752 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.MenuMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById]
17:39:57.763 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.PermissionMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
17:39:57.770 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.PermissionMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById]
17:39:57.772 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.PermissionMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById]
17:39:57.782 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.RoleMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
17:39:57.789 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.RoleMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById]
17:39:57.791 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.RoleMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById]
17:39:57.801 [main] WARN com.baomidou.mybatisplus.core.injector.methods.Insert - [org.xyzh.system.mapper.UserMapper.insert] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.Insert]
17:39:57.808 [main] WARN com.baomidou.mybatisplus.core.injector.methods.DeleteById - [org.xyzh.system.mapper.UserMapper.deleteById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteById]
17:39:57.810 [main] WARN com.baomidou.mybatisplus.core.injector.methods.UpdateById - [org.xyzh.system.mapper.UserMapper.updateById] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.UpdateById]

View File

@@ -0,0 +1,139 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
校园新闻管理系统 - News模块日志配置
-->
<configuration status="WARN" monitorInterval="30">
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--变量配置-->
<Properties>
<!-- 格式化输出:%date表示日期%thread表示线程名%-5level级别从左显示5个字符宽度 %msg日志消息%n是换行符-->
<!-- %logger{36} 表示 Logger 名字最长36个字符 -->
<property name="LOG_PATTERN" value="%date{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" />
<!-- 定义日志存储的路径 -->
<property name="FILE_PATH" value="./logs" />
<!-- News模块日志文件名 -->
<property name="FILE_NAME" value="school-news-news" />
<!-- 设置系统属性 -->
<property name="file.encoding" value="UTF-8" />
<property name="console.encoding" value="UTF-8" />
</Properties>
<appenders>
<console name="Console" target="SYSTEM_OUT">
<!--输出日志的格式-->
<PatternLayout pattern="${LOG_PATTERN}" charset="UTF-8"/>
<!--控制台输出debug及以上级别的信息-->
<ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY"/>
</console>
<!--文件会打印出所有信息这个log每次运行程序会自动清空由append属性决定适合临时测试用-->
<File name="Filelog" fileName="${FILE_PATH}/${FILE_NAME}-test.log" append="false">
<PatternLayout pattern="${LOG_PATTERN}" charset="UTF-8"/>
</File>
<!-- 这个会打印出所有的info及以下级别的信息每次大小超过size则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
<RollingFile name="RollingFileInfo" fileName="${FILE_PATH}/${FILE_NAME}-info.log" filePattern="${FILE_PATH}/${FILE_NAME}-INFO-%d{yyyy-MM-dd}_%i.log.gz">
<!--控制台只输出level及以上级别的信息onMatch其他的直接拒绝onMismatch-->
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="${LOG_PATTERN}" charset="UTF-8"/>
<Policies>
<!--interval属性用来指定多久滚动一次默认是1 hour-->
<TimeBasedTriggeringPolicy interval="1"/>
<SizeBasedTriggeringPolicy size="10MB"/>
</Policies>
<!-- DefaultRolloverStrategy属性如不设置则默认为最多同一文件夹下7个文件开始覆盖-->
<DefaultRolloverStrategy max="15"/>
</RollingFile>
<!-- 这个会打印出所有的warn及以下级别的信息每次大小超过size则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
<RollingFile name="RollingFileWarn" fileName="${FILE_PATH}/${FILE_NAME}-warn.log" filePattern="${FILE_PATH}/${FILE_NAME}-WARN-%d{yyyy-MM-dd}_%i.log.gz">
<!--控制台只输出level及以上级别的信息onMatch其他的直接拒绝onMismatch-->
<ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="${LOG_PATTERN}" charset="UTF-8"/>
<Policies>
<!--interval属性用来指定多久滚动一次默认是1 hour-->
<TimeBasedTriggeringPolicy interval="1"/>
<SizeBasedTriggeringPolicy size="10MB"/>
</Policies>
<!-- DefaultRolloverStrategy属性如不设置则默认为最多同一文件夹下7个文件开始覆盖-->
<DefaultRolloverStrategy max="15"/>
</RollingFile>
<!-- 这个会打印出所有的error及以下级别的信息每次大小超过size则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
<RollingFile name="RollingFileError" fileName="${FILE_PATH}/${FILE_NAME}-error.log" filePattern="${FILE_PATH}/${FILE_NAME}-ERROR-%d{yyyy-MM-dd}_%i.log.gz">
<!--控制台只输出level及以上级别的信息onMatch其他的直接拒绝onMismatch-->
<ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="${LOG_PATTERN}" charset="UTF-8"/>
<Policies>
<!--interval属性用来指定多久滚动一次默认是1 hour-->
<TimeBasedTriggeringPolicy interval="1"/>
<SizeBasedTriggeringPolicy size="10MB"/>
</Policies>
<!-- DefaultRolloverStrategy属性如不设置则默认为最多同一文件夹下7个文件开始覆盖-->
<DefaultRolloverStrategy max="15"/>
</RollingFile>
</appenders>
<!--Logger节点用来单独指定日志的形式比如要为指定包下的class指定不同的日志级别等。-->
<!--然后定义loggers只有定义了logger并引入的appenderappender才会生效-->
<loggers>
<!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
<logger name="org.mybatis" level="info" additivity="false">
<AppenderRef ref="Console"/>
</logger>
<!--监控系统信息-->
<!--若是additivity设为false则 子Logger 只会在自己的appender里输出不会在 父Logger 的appender里输出。-->
<Logger name="org.springframework" level="info" additivity="false">
<AppenderRef ref="Console"/>
</Logger>
<!-- 项目包日志配置 - Auth模块 -->
<Logger name="org.xyzh.auth" level="debug" additivity="false">
<AppenderRef ref="Console"/>
<AppenderRef ref="Filelog"/>
<AppenderRef ref="RollingFileInfo"/>
<AppenderRef ref="RollingFileWarn"/>
<AppenderRef ref="RollingFileError"/>
</Logger>
<!-- 项目包日志配置 - System模块 -->
<Logger name="org.xyzh.system" level="debug" additivity="false">
<AppenderRef ref="Console"/>
<AppenderRef ref="Filelog"/>
<AppenderRef ref="RollingFileInfo"/>
<AppenderRef ref="RollingFileWarn"/>
<AppenderRef ref="RollingFileError"/>
</Logger>
<!-- 项目包日志配置 - News模块 -->
<Logger name="org.xyzh.news" level="debug" additivity="false">
<AppenderRef ref="Console"/>
<AppenderRef ref="Filelog"/>
<AppenderRef ref="RollingFileInfo"/>
<AppenderRef ref="RollingFileWarn"/>
<AppenderRef ref="RollingFileError"/>
</Logger>
<!-- 项目包日志配置 - Common模块 -->
<Logger name="org.xyzh.common" level="debug" additivity="false">
<AppenderRef ref="Console"/>
<AppenderRef ref="Filelog"/>
<AppenderRef ref="RollingFileInfo"/>
<AppenderRef ref="RollingFileWarn"/>
<AppenderRef ref="RollingFileError"/>
</Logger>
<root level="info">
<appender-ref ref="Console"/>
<appender-ref ref="Filelog"/>
<appender-ref ref="RollingFileInfo"/>
<appender-ref ref="RollingFileWarn"/>
<appender-ref ref="RollingFileError"/>
</root>
</loggers>
</configuration>

View File

@@ -43,6 +43,9 @@
<!-- Log4j2 依赖版本 --> <!-- Log4j2 依赖版本 -->
<log4j2.version>2.23.1</log4j2.version> <log4j2.version>2.23.1</log4j2.version>
<!-- Redis 依赖版本 -->
<spring-data-redis.version>3.5.4</spring-data-redis.version>
<lombok.version>1.18.40</lombok.version> <lombok.version>1.18.40</lombok.version>
</properties> </properties>
@@ -205,6 +208,18 @@
<version>3.4.4</version> <version>3.4.4</version>
</dependency> </dependency>
<!-- Redis 依赖管理 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>${spring-data-redis.version}</version>
</dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>
<dependencies> <dependencies>
@@ -245,6 +260,9 @@
<source>${java.version}</source> <source>${java.version}</source>
<target>${java.version}</target> <target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding> <encoding>${project.build.sourceEncoding}</encoding>
<compilerArgs>
<arg>-J-Dfile.encoding=UTF-8</arg>
</compilerArgs>
</configuration> </configuration>
</plugin> </plugin>
</plugins> </plugins>

View File

@@ -0,0 +1,43 @@
package org.xyzh.system.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.xyzh.api.system.user.UserService;
import org.xyzh.common.annotation.HttpLogin;
import org.xyzh.common.core.domain.LoginDomain;
import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.dto.user.TbSysUserInfo;
import org.springframework.web.bind.annotation.GetMapping;
/**
* @description UserController.java文件描述 用户控制器
* @filename UserController.java
* @author yslg
* @copyright xyzh
* @ since 2025-10-06
*/
@RestController
@RequestMapping("/user")
public class UserController {
private static final Logger logger = LoggerFactory.getLogger(UserController.class);
@Autowired
private UserService userService;
@GetMapping("/userinfo")
public ResultDomain<TbSysUserInfo> getUserInfo(@HttpLogin LoginDomain loginDomain){
ResultDomain<TbSysUserInfo> result = new ResultDomain<>();
logger.info("loginDomain: {}", loginDomain);
String userID = loginDomain.getUser().getID();
ResultDomain<TbSysUserInfo> userInfo = userService.getUserInfoById(userID);
result.setData(userInfo.getData());
return result;
}
}

View File

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import org.xyzh.common.dto.role.TbSysRole; import org.xyzh.common.dto.role.TbSysRole;
import org.xyzh.common.vo.DeptRoleVO;
import java.util.List; import java.util.List;
@@ -20,11 +21,11 @@ public interface RoleMapper extends BaseMapper<TbSysRole> {
/** /**
* @description 根据用户ID查询角色列表 * @description 根据用户ID查询角色列表
* @param userId 用户ID * @param userId 用户ID
* @return List<TbSysRole> 角色列表 * @return List<DeptRoleVO> 部门角色列表
* @author yslg * @author yslg
* @since 2025-09-28 * @since 2025-09-28
*/ */
List<TbSysRole> selectRolesByUserId(@Param("userId") String userId); List<DeptRoleVO> selectDeptRolesByUserId(@Param("userId") String userId);
/** /**
* @description 根据角色编码查询角色 * @description 根据角色编码查询角色

View File

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import org.xyzh.common.dto.user.TbSysUser; import org.xyzh.common.dto.user.TbSysUser;
import org.xyzh.common.dto.user.TbSysUserInfo;
import java.util.List; import java.util.List;
@@ -26,6 +27,15 @@ public interface UserMapper extends BaseMapper<TbSysUser> {
*/ */
TbSysUser selectByUsername(@Param("username") String username); TbSysUser selectByUsername(@Param("username") String username);
/**
* @description 根据用户ID查询用户信息
* @param userId 用户ID
* @return TbSysUserInfo 用户信息
* @author yslg
* @since 2025-10-06
*/
TbSysUserInfo selectUserInfoById(@Param("userId") String userId);
/** /**
* @description 根据邮箱查询用户 * @description 根据邮箱查询用户
* @param email 邮箱 * @param email 邮箱

View File

@@ -7,8 +7,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.xyzh.common.core.domain.ResultDomain; import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.dto.dept.TbSysDeptRole;
import org.xyzh.common.dto.role.TbSysRole; import org.xyzh.common.dto.role.TbSysRole;
import org.xyzh.common.utils.IDUtils; import org.xyzh.common.utils.IDUtils;
import org.xyzh.common.vo.DeptRoleVO;
import org.xyzh.system.mapper.RoleMapper; import org.xyzh.system.mapper.RoleMapper;
import org.xyzh.system.role.service.SysRoleService; import org.xyzh.system.role.service.SysRoleService;
@@ -89,24 +91,24 @@ public class SysRoleServiceImpl implements SysRoleService {
} }
@Override @Override
public ResultDomain<TbSysRole> getRolesByUserId(String userId) { public ResultDomain<DeptRoleVO> getDeptRolesByUserId(String userId) {
ResultDomain<TbSysRole> resultDomain = new ResultDomain<>(); ResultDomain<DeptRoleVO> resultDomain = new ResultDomain<>();
try { try {
logger.info("开始根据用户ID查询角色列表{}", userId); logger.info("开始根据用户ID查询部门角色列表:{}", userId);
if (!StringUtils.hasText(userId)) { if (!StringUtils.hasText(userId)) {
resultDomain.fail("用户ID不能为空"); resultDomain.fail("用户ID不能为空");
return resultDomain; return resultDomain;
} }
List<TbSysRole> roles = roleMapper.selectRolesByUserId(userId); List<DeptRoleVO> roles = roleMapper.selectDeptRolesByUserId(userId);
logger.info("根据用户ID查询角色列表完成共找到{}个角色", roles.size()); logger.info("根据用户ID查询部门角色列表完成,共找到{}个部门角色", roles.size());
resultDomain.success("查询成功", roles); resultDomain.success("查询成功", roles);
return resultDomain; return resultDomain;
} catch (Exception e) { } catch (Exception e) {
logger.error("根据用户ID查询角色列表失败{}", userId, e); logger.error("根据用户ID查询部门角色列表失败:{}", userId, e);
resultDomain.fail("查询角色失败:" + e.getMessage()); resultDomain.fail("查询角色失败:" + e.getMessage());
return resultDomain; return resultDomain;
} }

View File

@@ -8,6 +8,7 @@ import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.xyzh.common.core.domain.ResultDomain; import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.dto.user.TbSysUser; import org.xyzh.common.dto.user.TbSysUser;
import org.xyzh.common.dto.user.TbSysUserInfo;
import org.xyzh.common.utils.IDUtils; import org.xyzh.common.utils.IDUtils;
import org.xyzh.system.mapper.UserMapper; import org.xyzh.system.mapper.UserMapper;
import org.xyzh.system.user.service.SysUserService; import org.xyzh.system.user.service.SysUserService;
@@ -512,4 +513,34 @@ public class SysUserServiceImpl implements SysUserService {
return resultDomain; return resultDomain;
} }
} }
@Override
public ResultDomain<TbSysUserInfo> getUserInfoById(String userId) {
ResultDomain<TbSysUserInfo> resultDomain = new ResultDomain<>();
try {
logger.info("开始根据ID查询用户信息{}", userId);
if (!StringUtils.hasText(userId)) {
resultDomain.fail("用户ID不能为空");
return resultDomain;
}
TbSysUserInfo userInfo = userMapper.selectUserInfoById(userId);
if (userInfo == null) {
logger.warn("未找到用户信息:{}", userId);
resultDomain.fail("未找到指定用户信息");
return resultDomain;
}
logger.info("根据ID查询用户信息完成{}", userId);
resultDomain.success("查询成功", userInfo);
return resultDomain;
} catch (Exception e) {
logger.error("根据ID查询用户信息失败{}", userId, e);
resultDomain.fail("查询用户信息失败:" + e.getMessage());
return resultDomain;
}
}
} }

View File

@@ -83,9 +83,9 @@ mybatis-plus:
# 日志配置 # 日志配置
logging: logging:
config: classpath:log4j2-spring.xml config: classpath:log4j2-spring.xml
level: charset:
org.xyzh.system: DEBUG console: UTF-8
org.xyzh.system.mapper: DEBUG file: UTF-8
# 管理端点配置 # 管理端点配置
management: management:

View File

@@ -1,175 +1,139 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
@description log4j2-spring.xml文件描述 System模块Log4j2配置文件 校园新闻管理系统 - System模块日志配置
@filename log4j2-spring.xml
@author yslg
@copyright xyzh
@since 2025-09-28
--> -->
<Configuration status="WARN" monitorInterval="30"> <configuration status="WARN" monitorInterval="30">
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!-- 全局属性 --> <!--变量配置-->
<Properties> <Properties>
<!-- 应用名称 --> <!-- 格式化输出:%date表示日期%thread表示线程名%-5level级别从左显示5个字符宽度 %msg日志消息%n是换行符-->
<Property name="APP_NAME">school-news-system</Property> <!-- %logger{36} 表示 Logger 名字最长36个字符 -->
<!-- 日志文件路径 --> <property name="LOG_PATTERN" value="%date{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" />
<Property name="LOG_HOME">./logs/${APP_NAME}</Property> <!-- 定义日志存储的路径 -->
<!-- 日志格式 --> <property name="FILE_PATH" value="./logs" />
<Property name="LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level [%X{traceId}] %logger{36} - %msg%n</Property> <!-- System模块日志文件名 -->
<!-- 控制台日志格式(带颜色) --> <property name="FILE_NAME" value="school-news-system" />
<Property name="CONSOLE_PATTERN">%d{HH:mm:ss.SSS} %highlight{%-5level} [%t] %style{[%X{traceId}]}{cyan} %style{%logger{36}}{magenta} - %msg%n</Property> <!-- 设置系统属性 -->
<property name="file.encoding" value="UTF-8" />
<property name="console.encoding" value="UTF-8" />
</Properties> </Properties>
<!-- 输出器配置 --> <appenders>
<Appenders>
<!-- 控制台输出 --> <console name="Console" target="SYSTEM_OUT">
<Console name="Console" target="SYSTEM_OUT"> <!--输出日志的格式-->
<PatternLayout pattern="${CONSOLE_PATTERN}"/> <PatternLayout pattern="${LOG_PATTERN}" charset="UTF-8"/>
<!-- 只输出INFO及以上级别 --> <!--控制台输出debug及以上级别的信息-->
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/> <ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY"/>
</Console> </console>
<!-- 调试日志文件 --> <!--文件会打印出所有信息这个log每次运行程序会自动清空由append属性决定适合临时测试用-->
<RollingFile name="DebugFile" fileName="${LOG_HOME}/debug.log" <File name="Filelog" fileName="${FILE_PATH}/${FILE_NAME}-test.log" append="false">
filePattern="${LOG_HOME}/debug.%d{yyyy-MM-dd}.%i.log.gz"> <PatternLayout pattern="${LOG_PATTERN}" charset="UTF-8"/>
<PatternLayout pattern="${LOG_PATTERN}"/> </File>
<!-- 这个会打印出所有的info及以下级别的信息每次大小超过size则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
<RollingFile name="RollingFileInfo" fileName="${FILE_PATH}/${FILE_NAME}-info.log" filePattern="${FILE_PATH}/${FILE_NAME}-INFO-%d{yyyy-MM-dd}_%i.log.gz">
<!--控制台只输出level及以上级别的信息onMatch其他的直接拒绝onMismatch-->
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="${LOG_PATTERN}" charset="UTF-8"/>
<Policies> <Policies>
<!-- 每天轮转 --> <!--interval属性用来指定多久滚动一次默认是1 hour-->
<TimeBasedTriggeringPolicy interval="1"/> <TimeBasedTriggeringPolicy interval="1"/>
<!-- 文件大小超过100MB轮转 --> <SizeBasedTriggeringPolicy size="10MB"/>
<SizeBasedTriggeringPolicy size="100MB"/>
</Policies> </Policies>
<!-- 保留30天的日志文件 --> <!-- DefaultRolloverStrategy属性如不设置则默认为最多同一文件夹下7个文件开始覆盖-->
<DefaultRolloverStrategy max="30"/> <DefaultRolloverStrategy max="15"/>
<!-- 只输出DEBUG级别 -->
<LevelRangeFilter minLevel="DEBUG" maxLevel="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
</RollingFile> </RollingFile>
<!-- 信息日志文件 --> <!-- 这个会打印出所有的warn及以下级别的信息每次大小超过size则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
<RollingFile name="InfoFile" fileName="${LOG_HOME}/info.log" <RollingFile name="RollingFileWarn" fileName="${FILE_PATH}/${FILE_NAME}-warn.log" filePattern="${FILE_PATH}/${FILE_NAME}-WARN-%d{yyyy-MM-dd}_%i.log.gz">
filePattern="${LOG_HOME}/info.%d{yyyy-MM-dd}.%i.log.gz"> <!--控制台只输出level及以上级别的信息onMatch其他的直接拒绝onMismatch-->
<PatternLayout pattern="${LOG_PATTERN}"/> <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="${LOG_PATTERN}" charset="UTF-8"/>
<Policies> <Policies>
<!--interval属性用来指定多久滚动一次默认是1 hour-->
<TimeBasedTriggeringPolicy interval="1"/> <TimeBasedTriggeringPolicy interval="1"/>
<SizeBasedTriggeringPolicy size="100MB"/> <SizeBasedTriggeringPolicy size="10MB"/>
</Policies> </Policies>
<DefaultRolloverStrategy max="30"/> <!-- DefaultRolloverStrategy属性如不设置则默认为最多同一文件夹下7个文件开始覆盖-->
<!-- 只输出INFO级别 --> <DefaultRolloverStrategy max="15"/>
<LevelRangeFilter minLevel="INFO" maxLevel="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
</RollingFile> </RollingFile>
<!-- 警告日志文件 --> <!-- 这个会打印出所有的error及以下级别的信息每次大小超过size则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
<RollingFile name="WarnFile" fileName="${LOG_HOME}/warn.log" <RollingFile name="RollingFileError" fileName="${FILE_PATH}/${FILE_NAME}-error.log" filePattern="${FILE_PATH}/${FILE_NAME}-ERROR-%d{yyyy-MM-dd}_%i.log.gz">
filePattern="${LOG_HOME}/warn.%d{yyyy-MM-dd}.%i.log.gz"> <!--控制台只输出level及以上级别的信息onMatch其他的直接拒绝onMismatch-->
<PatternLayout pattern="${LOG_PATTERN}"/> <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="${LOG_PATTERN}" charset="UTF-8"/>
<Policies> <Policies>
<!--interval属性用来指定多久滚动一次默认是1 hour-->
<TimeBasedTriggeringPolicy interval="1"/> <TimeBasedTriggeringPolicy interval="1"/>
<SizeBasedTriggeringPolicy size="100MB"/> <SizeBasedTriggeringPolicy size="10MB"/>
</Policies> </Policies>
<DefaultRolloverStrategy max="30"/> <!-- DefaultRolloverStrategy属性如不设置则默认为最多同一文件夹下7个文件开始覆盖-->
<!-- 只输出WARN级别 --> <DefaultRolloverStrategy max="15"/>
<LevelRangeFilter minLevel="WARN" maxLevel="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
</RollingFile> </RollingFile>
<!-- 错误日志文件 --> </appenders>
<RollingFile name="ErrorFile" fileName="${LOG_HOME}/error.log"
filePattern="${LOG_HOME}/error.%d{yyyy-MM-dd}.%i.log.gz">
<PatternLayout pattern="${LOG_PATTERN}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1"/>
<SizeBasedTriggeringPolicy size="100MB"/>
</Policies>
<DefaultRolloverStrategy max="30"/>
<!-- 只输出ERROR及以上级别 -->
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
</RollingFile>
<!-- SQL日志文件 --> <!--Logger节点用来单独指定日志的形式比如要为指定包下的class指定不同的日志级别等。-->
<RollingFile name="SqlFile" fileName="${LOG_HOME}/sql.log" <!--然后定义loggers只有定义了logger并引入的appenderappender才会生效-->
filePattern="${LOG_HOME}/sql.%d{yyyy-MM-dd}.%i.log.gz"> <loggers>
<PatternLayout pattern="${LOG_PATTERN}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1"/>
<SizeBasedTriggeringPolicy size="50MB"/>
</Policies>
<DefaultRolloverStrategy max="7"/>
</RollingFile>
<!-- 异步输出器 --> <!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
<AsyncAppender name="AsyncConsole"> <logger name="org.mybatis" level="info" additivity="false">
<AppenderRef ref="Console"/>
</logger>
<!--监控系统信息-->
<!--若是additivity设为false则 子Logger 只会在自己的appender里输出不会在 父Logger 的appender里输出。-->
<Logger name="org.springframework" level="info" additivity="false">
<AppenderRef ref="Console"/> <AppenderRef ref="Console"/>
<BufferSize>1024</BufferSize>
</AsyncAppender>
<AsyncAppender name="AsyncDebugFile">
<AppenderRef ref="DebugFile"/>
<BufferSize>1024</BufferSize>
</AsyncAppender>
<AsyncAppender name="AsyncInfoFile">
<AppenderRef ref="InfoFile"/>
<BufferSize>1024</BufferSize>
</AsyncAppender>
<AsyncAppender name="AsyncWarnFile">
<AppenderRef ref="WarnFile"/>
<BufferSize>1024</BufferSize>
</AsyncAppender>
<AsyncAppender name="AsyncErrorFile">
<AppenderRef ref="ErrorFile"/>
<BufferSize>1024</BufferSize>
</AsyncAppender>
<AsyncAppender name="AsyncSqlFile">
<AppenderRef ref="SqlFile"/>
<BufferSize>512</BufferSize>
</AsyncAppender>
</Appenders>
<!-- 记录器配置 -->
<Loggers>
<!-- SQL日志 -->
<Logger name="org.xyzh.system.mapper" level="DEBUG" additivity="false">
<AppenderRef ref="AsyncSqlFile"/>
<AppenderRef ref="AsyncConsole"/>
</Logger> </Logger>
<!-- MyBatis日志 --> <!-- 项目包日志配置 - Auth模块 -->
<Logger name="com.baomidou.mybatisplus" level="DEBUG" additivity="false"> <Logger name="org.xyzh.auth" level="debug" additivity="false">
<AppenderRef ref="AsyncSqlFile"/> <AppenderRef ref="Console"/>
<AppenderRef ref="Filelog"/>
<AppenderRef ref="RollingFileInfo"/>
<AppenderRef ref="RollingFileWarn"/>
<AppenderRef ref="RollingFileError"/>
</Logger> </Logger>
<!-- Druid日志 --> <!-- 项目包日志配置 - System模块 -->
<Logger name="com.alibaba.druid" level="INFO" additivity="false"> <Logger name="org.xyzh.system" level="debug" additivity="false">
<AppenderRef ref="AsyncInfoFile"/> <AppenderRef ref="Console"/>
<AppenderRef ref="Filelog"/>
<AppenderRef ref="RollingFileInfo"/>
<AppenderRef ref="RollingFileWarn"/>
<AppenderRef ref="RollingFileError"/>
</Logger> </Logger>
<!-- Spring框架日志 --> <!-- 项目包日志配置 - News模块 -->
<Logger name="org.springframework" level="INFO" additivity="false"> <Logger name="org.xyzh.news" level="debug" additivity="false">
<AppenderRef ref="AsyncInfoFile"/> <AppenderRef ref="Console"/>
<AppenderRef ref="Filelog"/>
<AppenderRef ref="RollingFileInfo"/>
<AppenderRef ref="RollingFileWarn"/>
<AppenderRef ref="RollingFileError"/>
</Logger> </Logger>
<!-- 系统模块日志 --> <!-- 项目包日志配置 - Common模块 -->
<Logger name="org.xyzh.system" level="DEBUG" additivity="false"> <Logger name="org.xyzh.common" level="debug" additivity="false">
<AppenderRef ref="AsyncDebugFile"/> <AppenderRef ref="Console"/>
<AppenderRef ref="AsyncInfoFile"/> <AppenderRef ref="Filelog"/>
<AppenderRef ref="AsyncWarnFile"/> <AppenderRef ref="RollingFileInfo"/>
<AppenderRef ref="AsyncErrorFile"/> <AppenderRef ref="RollingFileWarn"/>
<AppenderRef ref="AsyncConsole"/> <AppenderRef ref="RollingFileError"/>
</Logger> </Logger>
<!-- 根记录器 --> <root level="info">
<Root level="INFO"> <appender-ref ref="Console"/>
<AppenderRef ref="AsyncInfoFile"/> <appender-ref ref="Filelog"/>
<AppenderRef ref="AsyncWarnFile"/> <appender-ref ref="RollingFileInfo"/>
<AppenderRef ref="AsyncErrorFile"/> <appender-ref ref="RollingFileWarn"/>
<AppenderRef ref="AsyncConsole"/> <appender-ref ref="RollingFileError"/>
</Root> </root>
</loggers>
</Loggers> </configuration>
</Configuration>

View File

@@ -6,12 +6,12 @@
<resultMap id="BaseResultMap" type="org.xyzh.common.dto.menu.TbSysMenu"> <resultMap id="BaseResultMap" type="org.xyzh.common.dto.menu.TbSysMenu">
<id column="id" property="id" jdbcType="VARCHAR"/> <id column="id" property="id" jdbcType="VARCHAR"/>
<result column="menu_id" property="menuID" jdbcType="VARCHAR"/> <result column="menu_id" property="menuID" jdbcType="VARCHAR"/>
<result column="name" property="menuName" jdbcType="VARCHAR"/> <result column="name" property="name" jdbcType="VARCHAR"/>
<result column="parent_id" property="parentID" jdbcType="VARCHAR"/> <result column="parent_id" property="parentID" jdbcType="VARCHAR"/>
<result column="url" property="path" jdbcType="VARCHAR"/> <result column="url" property="url" jdbcType="VARCHAR"/>
<result column="icon" property="icon" jdbcType="VARCHAR"/> <result column="icon" property="icon" jdbcType="VARCHAR"/>
<result column="order_num" property="sort" jdbcType="INTEGER"/> <result column="order_num" property="orderNum" jdbcType="INTEGER"/>
<result column="type" property="menuType" jdbcType="INTEGER"/> <result column="type" property="type" jdbcType="INTEGER"/>
<result column="creator" property="creator" jdbcType="VARCHAR"/> <result column="creator" property="creator" jdbcType="VARCHAR"/>
<result column="updater" property="updater" jdbcType="VARCHAR"/> <result column="updater" property="updater" jdbcType="VARCHAR"/>
<result column="create_time" property="createTime" jdbcType="TIMESTAMP"/> <result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
@@ -22,25 +22,19 @@
<!-- 基础字段 --> <!-- 基础字段 -->
<sql id="Base_Column_List"> <sql id="Base_Column_List">
id, menu_id, name, parent_id, url, icon, order_num, type, m.id, m.menu_id, m.name, m.parent_id, m.url, m.icon, m.order_num, m.type,
creator, updater, create_time, update_time, delete_time, deleted m.creator, m.updater, m.create_time, m.update_time, m.delete_time, m.deleted
</sql> </sql>
<!-- 通用条件 --> <!-- 通用条件 -->
<sql id="Where_Clause"> <sql id="Where_Clause">
<where> <where>
deleted = 0 deleted = 0
<if test="menuName != null and menuName != ''"> <if test="name != null and name != ''">
AND menu_name LIKE CONCAT('%', #{menuName}, '%') AND name LIKE CONCAT('%', #{name}, '%')
</if> </if>
<if test="menuType != null"> <if test="type != null">
AND menu_type = #{menuType} AND type = #{type}
</if>
<if test="status != null">
AND status = #{status}
</if>
<if test="visible != null">
AND visible = #{visible}
</if> </if>
</where> </where>
</sql> </sql>
@@ -48,81 +42,74 @@
<!-- 根据用户ID查询菜单列表 --> <!-- 根据用户ID查询菜单列表 -->
<select id="selectMenusByUserId" resultMap="BaseResultMap"> <select id="selectMenusByUserId" resultMap="BaseResultMap">
SELECT DISTINCT SELECT DISTINCT
m.id, m.menu_id, m.parent_id, m.menu_name, m.menu_type, <include refid="Base_Column_List"/>
m.path, m.component, m.permission, m.icon, m.sort, FROM tb_sys_user_dept_role ur
m.visible, m.status, m.external_link, m.cache, m.frame, INNER JOIN tb_sys_role_permission rp ON rp.role_id = ur.role_id
m.query, m.remark, m.creator, m.updater, INNER JOIN tb_sys_menu_permission mp ON mp.permission_id = rp.permission_id
m.create_time, m.update_time, m.delete_time, m.deleted INNER JOIN tb_sys_menu m ON m.menu_id = mp.menu_id
FROM tb_sys_menu m
INNER JOIN tb_sys_role_menu rm ON m.menu_id = rm.menu_id
INNER JOIN tb_sys_user_role ur ON rm.role_id = ur.role_id
WHERE m.deleted = 0 WHERE m.deleted = 0
AND rm.deleted = 0 AND rp.deleted = 0
AND mp.deleted = 0
AND ur.deleted = 0 AND ur.deleted = 0
AND ur.user_id = #{userId} AND ur.user_id = #{userId}
AND m.status = 1 ORDER BY m.create_time ASC
AND m.visible = 1
ORDER BY m.sort ASC, m.create_time ASC
</select> </select>
<!-- 根据角色ID查询菜单列表 --> <!-- 根据角色ID查询菜单列表 -->
<select id="selectMenusByRoleId" resultMap="BaseResultMap"> <select id="selectMenusByRoleId" resultMap="BaseResultMap">
SELECT SELECT
m.id, m.menu_id, m.parent_id, m.menu_name, m.menu_type, <include refid="Base_Column_List"/>
m.path, m.component, m.permission, m.icon, m.sort, FROM tb_sys_role_permission rp
m.visible, m.status, m.external_link, m.cache, m.frame, INNER JOIN tb_sys_menu_permission mp ON mp.permission_id = rp.permission_id
m.query, m.remark, m.creator, m.updater, INNER JOIN tb_sys_menu m ON m.menu_id = mp.menu_id
m.create_time, m.update_time, m.delete_time, m.deleted
FROM tb_sys_menu m
INNER JOIN tb_sys_role_menu rm ON m.menu_id = rm.menu_id
WHERE m.deleted = 0 WHERE m.deleted = 0
AND rm.deleted = 0 AND mp.deleted = 0
AND rm.role_id = #{roleId} AND rp.deleted = 0
ORDER BY m.sort ASC, m.create_time ASC AND rp.role_id = #{roleId}
ORDER BY m.create_time ASC
</select> </select>
<!-- 根据父菜单ID查询子菜单列表 --> <!-- 根据父菜单ID查询子菜单列表 -->
<select id="selectByParentId" resultMap="BaseResultMap"> <select id="selectByParentId" resultMap="BaseResultMap">
SELECT SELECT
<include refid="Base_Column_List"/> <include refid="Base_Column_List"/>
FROM tb_sys_menu FROM tb_sys_menu m
WHERE deleted = 0 WHERE m.deleted = 0
AND parent_id = #{parentId} AND parent_id = #{parentId}
ORDER BY sort ASC, create_time ASC ORDER BY create_time ASC
</select> </select>
<!-- 查询菜单树结构 --> <!-- 查询菜单树结构 -->
<select id="selectMenuTree" resultMap="BaseResultMap"> <select id="selectMenuTree" resultMap="BaseResultMap">
SELECT SELECT
<include refid="Base_Column_List"/> <include refid="Base_Column_List"/>
FROM tb_sys_menu FROM tb_sys_menu m
WHERE deleted = 0 WHERE m.deleted = 0
ORDER BY ORDER BY
CASE WHEN parent_id IS NULL OR parent_id = '' THEN 0 ELSE 1 END, CASE WHEN parent_id IS NULL OR parent_id = '' THEN 0 ELSE 1 END,
parent_id, parent_id,
sort ASC,
create_time ASC create_time ASC
</select> </select>
<!-- 检查菜单名称是否存在 --> <!-- 检查菜单名称是否存在 -->
<select id="countByMenuName" resultType="int"> <select id="countByMenuName" resultType="int">
SELECT COUNT(1) SELECT COUNT(1)
FROM tb_sys_menu FROM tb_sys_menu m
WHERE deleted = 0 WHERE deleted = 0
AND menu_name = #{menuName} AND m.name = #{name}
<if test="excludeId != null and excludeId != ''"> <if test="excludeId != null and excludeId != ''">
AND id != #{excludeId} AND m.id != #{excludeId}
</if> </if>
</select> </select>
<!-- 批量删除菜单(逻辑删除) --> <!-- 批量删除菜单(逻辑删除) -->
<update id="batchDeleteByIds"> <update id="batchDeleteByIds">
UPDATE tb_sys_menu UPDATE tb_sys_menu m
SET deleted = 1, SET deleted = 1,
delete_time = NOW(), delete_time = NOW(),
updater = #{updater} updater = #{updater}
WHERE deleted = 0 WHERE m.deleted = 0
AND id IN AND m.id IN
<foreach collection="menuIds" item="menuId" open="(" separator="," close=")"> <foreach collection="menuIds" item="menuId" open="(" separator="," close=")">
#{menuId} #{menuId}
</foreach> </foreach>
@@ -135,20 +122,10 @@
<if test="id != null">id,</if> <if test="id != null">id,</if>
<if test="menuID != null">menu_id,</if> <if test="menuID != null">menu_id,</if>
<if test="parentID != null">parent_id,</if> <if test="parentID != null">parent_id,</if>
<if test="menuName != null">menu_name,</if> <if test="name != null">name,</if>
<if test="menuType != null">menu_type,</if> <if test="type != null">type,</if>
<if test="path != null">path,</if> <if test="url != null">url,</if>
<if test="component != null">component,</if>
<if test="permission != null">permission,</if>
<if test="icon != null">icon,</if> <if test="icon != null">icon,</if>
<if test="sort != null">sort,</if>
<if test="visible != null">visible,</if>
<if test="status != null">status,</if>
<if test="externalLink != null">external_link,</if>
<if test="cache != null">cache,</if>
<if test="frame != null">frame,</if>
<if test="query != null">query,</if>
<if test="remark != null">remark,</if>
<if test="creator != null">creator,</if> <if test="creator != null">creator,</if>
<if test="createTime != null">create_time,</if> <if test="createTime != null">create_time,</if>
deleted deleted
@@ -157,20 +134,10 @@
<if test="id != null">#{id},</if> <if test="id != null">#{id},</if>
<if test="menuID != null">#{menuID},</if> <if test="menuID != null">#{menuID},</if>
<if test="parentID != null">#{parentID},</if> <if test="parentID != null">#{parentID},</if>
<if test="menuName != null">#{menuName},</if> <if test="name != null">#{name},</if>
<if test="menuType != null">#{menuType},</if> <if test="type != null">#{type},</if>
<if test="path != null">#{path},</if> <if test="url != null">#{url},</if>
<if test="component != null">#{component},</if>
<if test="permission != null">#{permission},</if>
<if test="icon != null">#{icon},</if> <if test="icon != null">#{icon},</if>
<if test="sort != null">#{sort},</if>
<if test="visible != null">#{visible},</if>
<if test="status != null">#{status},</if>
<if test="externalLink != null">#{externalLink},</if>
<if test="cache != null">#{cache},</if>
<if test="frame != null">#{frame},</if>
<if test="query != null">#{query},</if>
<if test="remark != null">#{remark},</if>
<if test="creator != null">#{creator},</if> <if test="creator != null">#{creator},</if>
<if test="createTime != null">#{createTime},</if> <if test="createTime != null">#{createTime},</if>
0 0
@@ -183,20 +150,10 @@
<set> <set>
<if test="menuID != null">menu_id = #{menuID},</if> <if test="menuID != null">menu_id = #{menuID},</if>
<if test="parentID != null">parent_id = #{parentID},</if> <if test="parentID != null">parent_id = #{parentID},</if>
<if test="menuName != null">menu_name = #{menuName},</if> <if test="name != null">name = #{name},</if>
<if test="menuType != null">menu_type = #{menuType},</if> <if test="type != null">type = #{type},</if>
<if test="path != null">path = #{path},</if> <if test="url != null">url = #{url},</if>
<if test="component != null">component = #{component},</if>
<if test="permission != null">permission = #{permission},</if>
<if test="icon != null">icon = #{icon},</if> <if test="icon != null">icon = #{icon},</if>
<if test="sort != null">sort = #{sort},</if>
<if test="visible != null">visible = #{visible},</if>
<if test="status != null">status = #{status},</if>
<if test="externalLink != null">external_link = #{externalLink},</if>
<if test="cache != null">cache = #{cache},</if>
<if test="frame != null">frame = #{frame},</if>
<if test="query != null">query = #{query},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="updater != null">updater = #{updater},</if> <if test="updater != null">updater = #{updater},</if>
update_time = NOW() update_time = NOW()
</set> </set>

View File

@@ -6,8 +6,8 @@
<resultMap id="BaseResultMap" type="org.xyzh.common.dto.permission.TbSysPermission"> <resultMap id="BaseResultMap" type="org.xyzh.common.dto.permission.TbSysPermission">
<id column="id" property="id" jdbcType="VARCHAR"/> <id column="id" property="id" jdbcType="VARCHAR"/>
<result column="permission_id" property="permissionID" jdbcType="VARCHAR"/> <result column="permission_id" property="permissionID" jdbcType="VARCHAR"/>
<result column="name" property="permissionName" jdbcType="VARCHAR"/> <result column="name" property="name" jdbcType="VARCHAR"/>
<result column="code" property="permissionCode" jdbcType="VARCHAR"/> <result column="code" property="code" jdbcType="VARCHAR"/>
<result column="description" property="description" jdbcType="VARCHAR"/> <result column="description" property="description" jdbcType="VARCHAR"/>
<result column="creator" property="creator" jdbcType="VARCHAR"/> <result column="creator" property="creator" jdbcType="VARCHAR"/>
<result column="updater" property="updater" jdbcType="VARCHAR"/> <result column="updater" property="updater" jdbcType="VARCHAR"/>
@@ -27,11 +27,11 @@
<sql id="Where_Clause"> <sql id="Where_Clause">
<where> <where>
deleted = 0 deleted = 0
<if test="permissionName != null and permissionName != ''"> <if test="name != null and name != ''">
AND permission_name LIKE CONCAT('%', #{permissionName}, '%') AND name LIKE CONCAT('%', #{name}, '%')
</if> </if>
<if test="permissionCode != null and permissionCode != ''"> <if test="code != null and code != ''">
AND permission_code = #{permissionCode} AND code = #{code}
</if> </if>
<if test="permissionType != null"> <if test="permissionType != null">
AND permission_type = #{permissionType} AND permission_type = #{permissionType}
@@ -45,63 +45,60 @@
<!-- 根据用户ID查询权限列表 --> <!-- 根据用户ID查询权限列表 -->
<select id="selectPermissionsByUserId" resultMap="BaseResultMap"> <select id="selectPermissionsByUserId" resultMap="BaseResultMap">
SELECT DISTINCT SELECT DISTINCT
p.id, p.permission_id, p.permission_name, p.permission_code, p.id, p.permission_id, p.name, p.code, p.description,
p.permission_type, p.resource_url, p.http_method, p.description, p.creator, p.updater,
p.status, p.sort, p.creator, p.updater,
p.create_time, p.update_time, p.delete_time, p.deleted p.create_time, p.update_time, p.delete_time, p.deleted
FROM tb_sys_permission p FROM tb_sys_user_dept_role ur
INNER JOIN tb_sys_role_permission rp ON p.permission_id = rp.permission_id INNER JOIN tb_sys_role_permission rp ON rp.role_id = ur.role_id
INNER JOIN tb_sys_user_role ur ON rp.role_id = ur.role_id INNER JOIN tb_sys_permission p ON p.permission_id = rp.permission_id
WHERE p.deleted = 0 WHERE p.deleted = 0
AND rp.deleted = 0 AND rp.deleted = 0
AND ur.deleted = 0 AND ur.deleted = 0
AND ur.user_id = #{userID} AND ur.user_id = #{userId}
AND p.status = 1 ORDER BY p.create_time ASC
ORDER BY p.sort ASC, p.create_time ASC
</select> </select>
<!-- 根据角色ID查询权限列表 --> <!-- 根据角色ID查询权限列表 -->
<select id="selectPermissionsByRoleId" resultMap="BaseResultMap"> <select id="selectPermissionsByRoleId" resultMap="BaseResultMap">
SELECT SELECT
p.id, p.permission_id, p.permission_name, p.permission_code, p.id, p.permission_id, p.name, p.code, p.description,
p.permission_type, p.resource_url, p.http_method, p.description, p.creator, p.updater,
p.status, p.sort, p.creator, p.updater,
p.create_time, p.update_time, p.delete_time, p.deleted p.create_time, p.update_time, p.delete_time, p.deleted
FROM tb_sys_permission p FROM tb_sys_role_permission rp
INNER JOIN tb_sys_role_permission rp ON p.permission_id = rp.permission_id INNER JOIN tb_sys_permission p ON p.permission_id = rp.permission_id
WHERE p.deleted = 0 WHERE p.deleted = 0
AND rp.deleted = 0 AND rp.deleted = 0
AND rp.role_id = #{roleId} AND rp.role_id = #{roleId}
ORDER BY p.sort ASC, p.create_time ASC ORDER BY p.create_time ASC
</select> </select>
<!-- 根据权限编码查询权限 --> <!-- 根据权限编码查询权限 -->
<select id="selectByPermissionCode" resultMap="BaseResultMap"> <select id="selectBycode" resultMap="BaseResultMap">
SELECT SELECT
<include refid="Base_Column_List"/> <include refid="Base_Column_List"/>
FROM tb_sys_permission FROM tb_sys_permission
WHERE deleted = 0 WHERE deleted = 0
AND permission_code = #{permissionCode} AND code = #{code}
LIMIT 1 LIMIT 1
</select> </select>
<!-- 检查权限名称是否存在 --> <!-- 检查权限名称是否存在 -->
<select id="countByPermissionName" resultType="int"> <select id="countByname" resultType="int">
SELECT COUNT(1) SELECT COUNT(1)
FROM tb_sys_permission FROM tb_sys_permission
WHERE deleted = 0 WHERE deleted = 0
AND permission_name = #{permissionName} AND name = #{name}
<if test="excludeId != null and excludeId != ''"> <if test="excludeId != null and excludeId != ''">
AND id != #{excludeId} AND id != #{excludeId}
</if> </if>
</select> </select>
<!-- 检查权限编码是否存在 --> <!-- 检查权限编码是否存在 -->
<select id="countByPermissionCode" resultType="int"> <select id="countBycode" resultType="int">
SELECT COUNT(1) SELECT COUNT(1)
FROM tb_sys_permission FROM tb_sys_permission
WHERE deleted = 0 WHERE deleted = 0
AND permission_code = #{permissionCode} AND code = #{code}
<if test="excludeId != null and excludeId != ''"> <if test="excludeId != null and excludeId != ''">
AND id != #{excludeId} AND id != #{excludeId}
</if> </if>
@@ -126,14 +123,13 @@
<trim prefix="(" suffix=")" suffixOverrides=","> <trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">id,</if> <if test="id != null">id,</if>
<if test="permissionID != null">permission_id,</if> <if test="permissionID != null">permission_id,</if>
<if test="permissionName != null">permission_name,</if> <if test="name != null">name,</if>
<if test="permissionCode != null">permission_code,</if> <if test="code != null">code,</if>
<if test="permissionType != null">permission_type,</if> <if test="permissionType != null">permission_type,</if>
<if test="resourceUrl != null">resource_url,</if> <if test="resourceUrl != null">resource_url,</if>
<if test="httpMethod != null">http_method,</if> <if test="httpMethod != null">http_method,</if>
<if test="description != null">description,</if> <if test="description != null">description,</if>
<if test="status != null">status,</if> <if test="status != null">status,</if>
<if test="sort != null">sort,</if>
<if test="creator != null">creator,</if> <if test="creator != null">creator,</if>
<if test="createTime != null">create_time,</if> <if test="createTime != null">create_time,</if>
deleted deleted
@@ -141,14 +137,13 @@
<trim prefix="values (" suffix=")" suffixOverrides=","> <trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">#{id},</if> <if test="id != null">#{id},</if>
<if test="permissionID != null">#{permissionID},</if> <if test="permissionID != null">#{permissionID},</if>
<if test="permissionName != null">#{permissionName},</if> <if test="name != null">#{name},</if>
<if test="permissionCode != null">#{permissionCode},</if> <if test="code != null">#{code},</if>
<if test="permissionType != null">#{permissionType},</if> <if test="permissionType != null">#{permissionType},</if>
<if test="resourceUrl != null">#{resourceUrl},</if> <if test="resourceUrl != null">#{resourceUrl},</if>
<if test="httpMethod != null">#{httpMethod},</if> <if test="httpMethod != null">#{httpMethod},</if>
<if test="description != null">#{description},</if> <if test="description != null">#{description},</if>
<if test="status != null">#{status},</if> <if test="status != null">#{status},</if>
<if test="sort != null">#{sort},</if>
<if test="creator != null">#{creator},</if> <if test="creator != null">#{creator},</if>
<if test="createTime != null">#{createTime},</if> <if test="createTime != null">#{createTime},</if>
0 0
@@ -160,14 +155,13 @@
UPDATE tb_sys_permission UPDATE tb_sys_permission
<set> <set>
<if test="permissionID != null">permission_id = #{permissionID},</if> <if test="permissionID != null">permission_id = #{permissionID},</if>
<if test="permissionName != null">permission_name = #{permissionName},</if> <if test="name != null">name = #{name},</if>
<if test="permissionCode != null">permission_code = #{permissionCode},</if> <if test="code != null">code = #{code},</if>
<if test="permissionType != null">permission_type = #{permissionType},</if> <if test="permissionType != null">permission_type = #{permissionType},</if>
<if test="resourceUrl != null">resource_url = #{resourceUrl},</if> <if test="resourceUrl != null">resource_url = #{resourceUrl},</if>
<if test="httpMethod != null">http_method = #{httpMethod},</if> <if test="httpMethod != null">http_method = #{httpMethod},</if>
<if test="description != null">description = #{description},</if> <if test="description != null">description = #{description},</if>
<if test="status != null">status = #{status},</if> <if test="status != null">status = #{status},</if>
<if test="sort != null">sort = #{sort},</if>
<if test="updater != null">updater = #{updater},</if> <if test="updater != null">updater = #{updater},</if>
update_time = NOW() update_time = NOW()
</set> </set>

View File

@@ -3,10 +3,11 @@
<mapper namespace="org.xyzh.system.mapper.RoleMapper"> <mapper namespace="org.xyzh.system.mapper.RoleMapper">
<!-- 基础结果映射 --> <!-- 基础结果映射 -->
<resultMap id="BaseResultMap" type="org.xyzh.common.dto.role.TbSysRole"> <resultMap id="tbSysRoleResultMap" type="org.xyzh.common.dto.role.TbSysRole">
<id column="id" property="id" jdbcType="VARCHAR"/> <id column="id" property="id" jdbcType="VARCHAR"/>
<result column="dept_id" property="deptID" jdbcType="VARCHAR"/>
<result column="role_id" property="roleID" jdbcType="VARCHAR"/> <result column="role_id" property="roleID" jdbcType="VARCHAR"/>
<result column="name" property="roleName" jdbcType="VARCHAR"/> <result column="name" property="name" jdbcType="VARCHAR"/>
<result column="description" property="description" jdbcType="VARCHAR"/> <result column="description" property="description" jdbcType="VARCHAR"/>
<result column="creator" property="creator" jdbcType="VARCHAR"/> <result column="creator" property="creator" jdbcType="VARCHAR"/>
<result column="updater" property="updater" jdbcType="VARCHAR"/> <result column="updater" property="updater" jdbcType="VARCHAR"/>
@@ -16,11 +17,42 @@
<result column="deleted" property="deleted" jdbcType="BOOLEAN"/> <result column="deleted" property="deleted" jdbcType="BOOLEAN"/>
</resultMap> </resultMap>
<resultMap id="deptRoleVOResultMap" type="org.xyzh.common.vo.DeptRoleVO">
<result column="dept_id" property="dept.deptID" jdbcType="VARCHAR"/>
<result column="dept_name" property="dept.name" jdbcType="VARCHAR"/>
<result column="dept_description" property="dept.description" jdbcType="VARCHAR"/>
<result column="dept_creator" property="dept.creator" jdbcType="VARCHAR"/>
<result column="dept_updater" property="dept.updater" jdbcType="VARCHAR"/>
<result column="dept_create_time" property="dept.createTime" jdbcType="TIMESTAMP"/>
<result column="dept_update_time" property="dept.updateTime" jdbcType="TIMESTAMP"/>
<result column="dept_delete_time" property="dept.deleteTime" jdbcType="TIMESTAMP"/>
<result column="dept_deleted" property="dept.deleted" jdbcType="BOOLEAN"/>
<result column="role_id" property="role.roleID" jdbcType="VARCHAR"/>
<result column="role_name" property="role.name" jdbcType="VARCHAR"/>
<result column="role_description" property="role.description" jdbcType="VARCHAR"/>
<result column="role_creator" property="role.creator" jdbcType="VARCHAR"/>
<result column="role_updater" property="role.updater" jdbcType="VARCHAR"/>
<result column="role_create_time" property="role.createTime" jdbcType="TIMESTAMP"/>
<result column="role_update_time" property="role.updateTime" jdbcType="TIMESTAMP"/>
<result column="role_delete_time" property="role.deleteTime" jdbcType="TIMESTAMP"/>
<result column="role_deleted" property="role.deleted" jdbcType="BOOLEAN"/>
</resultMap>
<!-- 基础字段 --> <!-- 基础字段 -->
<sql id="Base_Column_List"> <sql id="TbSysRole_Column_List">
id, role_id, name, description, creator, updater, id, dept_id, role_id, name, description, creator, updater,
create_time, update_time, delete_time, deleted create_time, update_time, delete_time, deleted
</sql> </sql>
<sql id="TbSysDeptRole_Column_List">
dr.id, dr.dept_id, dr.role_id,
r.name as role_name, d.name as dept_name,
r.description as role_description, d.description as dept_description,
r.creator as role_creator, d.creator as dept_creator,
r.updater as role_updater, d.updater as dept_updater,
r.create_time as role_create_time, d.create_time as dept_create_time,
r.update_time as role_update_time, d.update_time as dept_update_time,
r.delete_time as role_delete_time, d.delete_time as dept_delete_time,
r.deleted as role_deleted, d.deleted as dept_deleted
</sql>
<!-- 通用条件 --> <!-- 通用条件 -->
<sql id="Where_Clause"> <sql id="Where_Clause">
@@ -39,23 +71,21 @@
</sql> </sql>
<!-- 根据用户ID查询角色列表 --> <!-- 根据用户ID查询角色列表 -->
<select id="selectRolesByUserId" resultMap="BaseResultMap"> <select id="selectDeptRolesByUserId" resultMap="deptRoleVOResultMap">
SELECT SELECT
r.id, r.role_id, r.role_name, r.role_code, r.description, <include refid="TbSysDeptRole_Column_List"/>
r.status, r.sort, r.creator, r.updater, FROM tb_sys_user_dept_role dr
r.create_time, r.update_time, r.delete_time, r.deleted INNER JOIN tb_sys_role r ON r.role_id = dr.role_id
FROM tb_sys_role r INNER JOIN tb_sys_dept d ON d.dept_id = dr.dept_id
INNER JOIN tb_sys_user_role ur ON r.role_id = ur.role_id WHERE dr.deleted = 0
WHERE r.deleted = 0 AND dr.user_id = #{userId}
AND ur.deleted = 0 ORDER BY dr.create_time ASC
AND ur.user_id = #{userID}
ORDER BY r.sort ASC, r.create_time ASC
</select> </select>
<!-- 根据角色编码查询角色 --> <!-- 根据角色编码查询角色 -->
<select id="selectByRoleCode" resultMap="BaseResultMap"> <select id="selectByRoleCode" resultMap="tbSysRoleResultMap">
SELECT SELECT
<include refid="Base_Column_List"/> <include refid="TbSysRole_Column_List"/>
FROM tb_sys_role FROM tb_sys_role
WHERE deleted = 0 WHERE deleted = 0
AND role_code = #{roleCode} AND role_code = #{roleCode}
@@ -107,7 +137,6 @@
<if test="roleCode != null">role_code,</if> <if test="roleCode != null">role_code,</if>
<if test="description != null">description,</if> <if test="description != null">description,</if>
<if test="status != null">status,</if> <if test="status != null">status,</if>
<if test="sort != null">sort,</if>
<if test="creator != null">creator,</if> <if test="creator != null">creator,</if>
<if test="createTime != null">create_time,</if> <if test="createTime != null">create_time,</if>
deleted deleted
@@ -119,7 +148,6 @@
<if test="roleCode != null">#{roleCode},</if> <if test="roleCode != null">#{roleCode},</if>
<if test="description != null">#{description},</if> <if test="description != null">#{description},</if>
<if test="status != null">#{status},</if> <if test="status != null">#{status},</if>
<if test="sort != null">#{sort},</if>
<if test="creator != null">#{creator},</if> <if test="creator != null">#{creator},</if>
<if test="createTime != null">#{createTime},</if> <if test="createTime != null">#{createTime},</if>
0 0
@@ -135,7 +163,6 @@
<if test="roleCode != null">role_code = #{roleCode},</if> <if test="roleCode != null">role_code = #{roleCode},</if>
<if test="description != null">description = #{description},</if> <if test="description != null">description = #{description},</if>
<if test="status != null">status = #{status},</if> <if test="status != null">status = #{status},</if>
<if test="sort != null">sort = #{sort},</if>
<if test="updater != null">updater = #{updater},</if> <if test="updater != null">updater = #{updater},</if>
update_time = NOW() update_time = NOW()
</set> </set>

View File

@@ -17,12 +17,38 @@
<result column="status" property="status" jdbcType="INTEGER"/> <result column="status" property="status" jdbcType="INTEGER"/>
</resultMap> </resultMap>
<resultMap id="UserInfoResultMap" type="org.xyzh.common.dto.user.TbSysUserInfo">
<id column="id" property="id" jdbcType="VARCHAR"/>
<result column="user_id" property="userID" jdbcType="VARCHAR"/>
<result column="avatar" property="avatar" jdbcType="VARCHAR"/>
<result column="gender" property="gender" jdbcType="INTEGER"/>
<result column="family_name" property="familyName" jdbcType="VARCHAR"/>
<result column="given_name" property="givenName" jdbcType="VARCHAR"/>
<result column="full_name" property="fullName" jdbcType="VARCHAR"/>
<result column="id_card" property="idCard" jdbcType="VARCHAR"/>
<result column="address" property="address" jdbcType="VARCHAR"/>
<result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
<result column="update_time" property="updateTime" jdbcType="TIMESTAMP"/>
<result column="delete_time" property="deleteTime" jdbcType="TIMESTAMP"/>
<result column="deleted" property="deleted" jdbcType="INTEGER"/>
</resultMap>
<!-- 基础字段 --> <!-- 基础字段 -->
<sql id="Base_Column_List"> <sql id="Base_Column_List">
id, username, password, email, phone, wechat_id, id, username, password, email, phone, wechat_id,
create_time, update_time, delete_time, deleted, status create_time, update_time, delete_time, deleted, status
</sql> </sql>
<sql id="FullUser_Column_List">
id, user_id, avatar, gender, family_name, given_name, full_name, id_card, address,
create_time, update_time, delete_time, deleted, status
</sql>
<!-- 用户信息字段 -->
<sql id="UserInfo_Column_List">
id, user_id, avatar, gender, family_name, given_name, full_name, id_card, address,
create_time, update_time, delete_time, deleted
</sql>
<!-- 通用条件 --> <!-- 通用条件 -->
<sql id="Where_Clause"> <sql id="Where_Clause">
<where> <where>
@@ -52,6 +78,16 @@
LIMIT 1 LIMIT 1
</select> </select>
<!-- 根据用户ID查询用户信息 -->
<select id="selectUserInfoById" resultMap="UserInfoResultMap">
SELECT
<include refid="UserInfo_Column_List"/>
FROM tb_sys_user_info
WHERE deleted = 0
AND user_id = #{userId}
LIMIT 1
</select>
<!-- 根据邮箱查询用户 --> <!-- 根据邮箱查询用户 -->
<select id="selectByEmail" resultMap="BaseResultMap"> <select id="selectByEmail" resultMap="BaseResultMap">
SELECT SELECT