serv\web- 日志
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
package org.xyzh.system.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
/**
|
||||
* @description 异步日志配置 - 配置异步执行器
|
||||
* @filename AsyncLogConfig.java
|
||||
* @author yslg
|
||||
* @copyright xyzh
|
||||
* @since 2025-10-30
|
||||
*/
|
||||
@Configuration
|
||||
@EnableAsync
|
||||
public class AsyncLogConfig {
|
||||
|
||||
/**
|
||||
* @description 配置日志异步执行器
|
||||
* @return Executor
|
||||
*/
|
||||
@Bean(name = "logExecutor")
|
||||
public Executor logExecutor() {
|
||||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
|
||||
// 核心线程数
|
||||
executor.setCorePoolSize(2);
|
||||
|
||||
// 最大线程数
|
||||
executor.setMaxPoolSize(5);
|
||||
|
||||
// 队列容量
|
||||
executor.setQueueCapacity(1000);
|
||||
|
||||
// 线程名称前缀
|
||||
executor.setThreadNamePrefix("async-log-");
|
||||
|
||||
// 线程空闲时间(秒)
|
||||
executor.setKeepAliveSeconds(60);
|
||||
|
||||
// 拒绝策略:由调用线程处理(防止日志丢失)
|
||||
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
|
||||
|
||||
// 关闭时等待任务完成
|
||||
executor.setWaitForTasksToCompleteOnShutdown(true);
|
||||
|
||||
// 等待时间(秒)
|
||||
executor.setAwaitTerminationSeconds(60);
|
||||
|
||||
executor.initialize();
|
||||
return executor;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,14 +98,14 @@ public class DeptController {
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 查询部门绑定角色
|
||||
* @description 查询部门绑定角色(包含名称)
|
||||
* @param dept 部门信息
|
||||
* @return ResultDomain<TbSysRole> 角色信息
|
||||
* @return ResultDomain<UserDeptRoleVO> 部门角色信息
|
||||
* @author yslg
|
||||
* @since 2025-10-06
|
||||
*/
|
||||
@PostMapping("/role")
|
||||
public ResultDomain<TbSysRole> getDeptByRole(@RequestBody TbSysDept dept) {
|
||||
public ResultDomain<UserDeptRoleVO> getDeptByRole(@RequestBody TbSysDept dept) {
|
||||
return deptService.getDeptByRole(dept.getDeptID());
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package org.xyzh.system.controller;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.xyzh.api.system.log.LoginLogService;
|
||||
import org.xyzh.api.system.log.OperationLogService;
|
||||
import org.xyzh.common.core.domain.ResultDomain;
|
||||
import org.xyzh.common.core.page.PageParam;
|
||||
import org.xyzh.common.core.page.PageRequest;
|
||||
import org.xyzh.common.dto.system.TbSysLoginLog;
|
||||
import org.xyzh.common.dto.system.TbSysOperationLog;
|
||||
|
||||
/**
|
||||
* @description 日志管理控制器
|
||||
* @filename LogController.java
|
||||
* @author yslg
|
||||
* @copyright xyzh
|
||||
* @since 2025-10-30
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/sys/log")
|
||||
public class LogController {
|
||||
|
||||
@Autowired
|
||||
private LoginLogService loginLogService;
|
||||
|
||||
@Autowired
|
||||
private OperationLogService operationLogService;
|
||||
|
||||
/**
|
||||
* @description 分页查询登录日志
|
||||
* 根据条件分页查询登录日志,superadmin可查看所有日志,其他用户只能查看本部门及子部门的日志
|
||||
* @param loginLog 查询条件
|
||||
* @param pageNum 页码(从1开始)
|
||||
* @param pageSize 每页大小
|
||||
* @return ResultDomain<TbSysLoginLog> 登录日志分页列表
|
||||
*/
|
||||
@PostMapping("/login/page")
|
||||
public ResultDomain<TbSysLoginLog> getLoginLogPage(@RequestBody PageRequest<TbSysLoginLog> pageRequest) {
|
||||
|
||||
return loginLogService.selectLoginLogPage(pageRequest.getFilter(), pageRequest.getPageParam());
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 分页查询操作日志
|
||||
* 根据条件分页查询操作日志,superadmin可查看所有日志,其他用户只能查看本部门及子部门的日志
|
||||
* @param operationLog 查询条件
|
||||
* @param pageNum 页码(从1开始)
|
||||
* @param pageSize 每页大小
|
||||
* @return ResultDomain<TbSysOperationLog> 操作日志分页列表
|
||||
*/
|
||||
@PostMapping("/operation/page")
|
||||
public ResultDomain<TbSysOperationLog> getOperationLogPage(@RequestBody PageRequest<TbSysOperationLog> pageRequest) {
|
||||
|
||||
return operationLogService.selectOperationLogPage(pageRequest.getFilter(), pageRequest.getPageParam());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import org.xyzh.api.system.menu.MenuService;
|
||||
import org.xyzh.common.core.domain.ResultDomain;
|
||||
import org.xyzh.common.dto.menu.TbSysMenu;
|
||||
import org.xyzh.common.dto.menu.TbSysMenuPermission;
|
||||
import org.xyzh.common.vo.PermissionVO;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/menus")
|
||||
@@ -97,14 +98,14 @@ public class MenuController {
|
||||
|
||||
|
||||
/**
|
||||
* @description 查询菜单权限
|
||||
* @param menuId 菜单ID
|
||||
* @return ResultDomain<TbSysMenuPermission> 菜单权限信息
|
||||
* @description 查询菜单权限(包含模块名称等信息)
|
||||
* @param menu 菜单信息
|
||||
* @return ResultDomain<PermissionVO> 权限信息
|
||||
* @author yslg
|
||||
* @since 2025-10-06
|
||||
*/
|
||||
@PostMapping("/permission")
|
||||
public ResultDomain<TbSysMenuPermission> getMenuPermission(@RequestBody TbSysMenu menu) {
|
||||
public ResultDomain<PermissionVO> getMenuPermission(@RequestBody TbSysMenu menu) {
|
||||
return menuService.getMenuPermission(menu.getMenuID());
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import org.xyzh.common.core.domain.ResultDomain;
|
||||
import org.xyzh.common.dto.permission.TbSysPermission;
|
||||
import org.xyzh.common.dto.role.TbSysRole;
|
||||
import org.xyzh.common.dto.role.TbSysRolePermission;
|
||||
import org.xyzh.common.vo.PermissionVO;
|
||||
import org.xyzh.common.vo.UserDeptRoleVO;
|
||||
|
||||
/**
|
||||
@@ -37,8 +38,14 @@ public class RoleController {
|
||||
* @author yslg
|
||||
* @ since 2025-10-09
|
||||
*/
|
||||
/**
|
||||
* @description 查询所有角色(包含权限过滤)
|
||||
* @return ResultDomain<PermissionVO> 角色VO列表
|
||||
* @author yslg
|
||||
* @since 2025-10-30
|
||||
*/
|
||||
@PostMapping("/all")
|
||||
public ResultDomain<TbSysRole> all() {
|
||||
public ResultDomain<PermissionVO> all() {
|
||||
return roleService.getAllRoles();
|
||||
}
|
||||
|
||||
@@ -55,14 +62,14 @@ public class RoleController {
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 根据过滤条件获取角色列表
|
||||
* @description 根据过滤条件获取角色列表(包含权限过滤)
|
||||
* @param filter 过滤条件
|
||||
* @return ResultDomain<TbSysRole> 角色列表
|
||||
* @return ResultDomain<PermissionVO> 角色VO列表
|
||||
* @author yslg
|
||||
* @since 2025-10-09
|
||||
*/
|
||||
@PostMapping("/list")
|
||||
public ResultDomain<TbSysRole> getRoleList(@RequestBody TbSysRole filter) {
|
||||
public ResultDomain<PermissionVO> getRoleList(@RequestBody TbSysRole filter) {
|
||||
return roleService.getRoleList(filter);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.xyzh.common.dto.user.TbSysUser;
|
||||
import org.xyzh.common.dto.user.TbSysUserDeptRole;
|
||||
import org.xyzh.common.dto.user.TbSysUserInfo;
|
||||
import org.xyzh.common.vo.UserDeptRoleVO;
|
||||
import org.xyzh.common.vo.UserVO;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
@@ -92,8 +93,8 @@ public class UserController {
|
||||
* @since 2025-10-09
|
||||
*/
|
||||
@PostMapping("/list")
|
||||
public ResultDomain<TbSysUser> getUserList(@RequestBody TbSysUser filter) {
|
||||
return userService.getUserByFilter(filter);
|
||||
public ResultDomain<UserVO> getUserList(@RequestBody TbSysUser filter) {
|
||||
return userService.getUserVOByFilter(filter);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -103,10 +104,10 @@ public class UserController {
|
||||
* @since 2025-10-09
|
||||
*/
|
||||
@PostMapping("/page")
|
||||
public ResultDomain<TbSysUser> getUserPage(@RequestBody PageRequest<TbSysUser> pageRequest) {
|
||||
public ResultDomain<UserVO> getUserPage(@RequestBody PageRequest<TbSysUser> pageRequest) {
|
||||
TbSysUser filter = pageRequest.getFilter();
|
||||
PageParam pageParam = pageRequest.getPageParam();
|
||||
return userService.getUserPage(filter, pageParam);
|
||||
return userService.getUserVOPage(filter, pageParam);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -370,11 +370,12 @@ public class SysDepartmentServiceImpl implements SysDepartmentService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbSysRole> getDeptByRole(String deptId) {
|
||||
ResultDomain<TbSysRole> resultDomain = new ResultDomain<>();
|
||||
public ResultDomain<UserDeptRoleVO> getDeptByRole(String deptId) {
|
||||
ResultDomain<UserDeptRoleVO> resultDomain = new ResultDomain<>();
|
||||
try {
|
||||
logger.info("开始查询部门绑定角色:{}", deptId);
|
||||
List<TbSysRole> roles = deptRoleMapper.selectDeptRole(deptId);
|
||||
List<UserDeptRoleVO> roles = deptRoleMapper.selectDeptRole(deptId);
|
||||
logger.info("查询部门绑定角色完成,共找到{}条记录", roles.size());
|
||||
resultDomain.success("查询成功", roles);
|
||||
return resultDomain;
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
package org.xyzh.system.log;
|
||||
|
||||
import org.apache.logging.log4j.core.Appender;
|
||||
import org.apache.logging.log4j.core.Core;
|
||||
import org.apache.logging.log4j.core.Filter;
|
||||
import org.apache.logging.log4j.core.LogEvent;
|
||||
import org.apache.logging.log4j.core.appender.AbstractAppender;
|
||||
import org.apache.logging.log4j.core.config.Property;
|
||||
import org.apache.logging.log4j.core.config.plugins.Plugin;
|
||||
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
|
||||
import org.apache.logging.log4j.core.config.plugins.PluginElement;
|
||||
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
|
||||
import org.xyzh.common.utils.spring.SpringContextUtil;
|
||||
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
/**
|
||||
* @description 数据库日志Appender - 异步写入数据库
|
||||
* @filename DatabaseAppender.java
|
||||
* @author yslg
|
||||
* @copyright xyzh
|
||||
* @since 2025-10-30
|
||||
*/
|
||||
@Plugin(name = "DatabaseAppender", category = Core.CATEGORY_NAME, elementType = Appender.ELEMENT_TYPE, printObject = true)
|
||||
public class DatabaseAppender extends AbstractAppender {
|
||||
|
||||
// 异步队列,存储待处理的日志事件上下文
|
||||
private static final BlockingQueue<LogEventContext> logQueue = new ArrayBlockingQueue<>(10000);
|
||||
|
||||
// 日志处理工作线程
|
||||
private static LogEventProcessor processor;
|
||||
|
||||
protected DatabaseAppender(String name, Filter filter, boolean ignoreExceptions) {
|
||||
super(name, filter, null, ignoreExceptions, Property.EMPTY_ARRAY);
|
||||
|
||||
// 启动日志处理线程
|
||||
if (processor == null) {
|
||||
processor = new LogEventProcessor();
|
||||
Thread processorThread = new Thread(processor, "log-db-processor");
|
||||
processorThread.setDaemon(true);
|
||||
processorThread.start();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void append(LogEvent event) {
|
||||
// 在主线程中提取HTTP上下文信息(异步线程中无法获取)
|
||||
String userId = null;
|
||||
String username = null;
|
||||
String requestUrl = null;
|
||||
String requestMethod = null;
|
||||
String ipAddress = null;
|
||||
String ipSource = null;
|
||||
String browser = null;
|
||||
String os = null;
|
||||
|
||||
try {
|
||||
// 尝试获取用户信息
|
||||
SpringContextUtil contextUtil = SpringContextUtil.getBean(SpringContextUtil.class);
|
||||
if (contextUtil != null) {
|
||||
Object loginUtil = SpringContextUtil.getBean("loginUtil");
|
||||
if (loginUtil != null) {
|
||||
java.lang.reflect.Method getUserIdMethod = loginUtil.getClass().getMethod("getCurrentUserId");
|
||||
java.lang.reflect.Method getUsernameMethod = loginUtil.getClass().getMethod("getCurrentUsername");
|
||||
userId = (String) getUserIdMethod.invoke(null);
|
||||
username = (String) getUsernameMethod.invoke(null);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 非登录状态或反射调用失败,忽略
|
||||
}
|
||||
|
||||
try {
|
||||
// 尝试获取请求信息
|
||||
Class<?> servletUtilsClass = Class.forName("org.xyzh.common.utils.ServletUtils");
|
||||
requestUrl = (String) servletUtilsClass.getMethod("getRequestUrl").invoke(null);
|
||||
requestMethod = (String) servletUtilsClass.getMethod("getHeader", String.class).invoke(null, "X-HTTP-Method-Override");
|
||||
ipAddress = (String) servletUtilsClass.getMethod("getClientIp").invoke(null);
|
||||
ipSource = (String) servletUtilsClass.getMethod("getIpSource").invoke(null);
|
||||
browser = (String) servletUtilsClass.getMethod("getBrowser").invoke(null);
|
||||
os = (String) servletUtilsClass.getMethod("getOs").invoke(null);
|
||||
} catch (Exception e) {
|
||||
// 非HTTP请求上下文或类不存在,忽略
|
||||
}
|
||||
|
||||
// 创建日志事件上下文(包含HTTP上下文信息)
|
||||
LogEventContext context = new LogEventContext(
|
||||
event.toImmutable(), userId, username,
|
||||
requestUrl, requestMethod, ipAddress, ipSource, browser, os
|
||||
);
|
||||
|
||||
// 将日志事件上下文添加到队列中,非阻塞方式
|
||||
if (!logQueue.offer(context)) {
|
||||
// 队列满了,记录警告但不阻塞应用
|
||||
System.err.println("日志队列已满,丢弃日志: " + event.getMessage().getFormattedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
super.stop();
|
||||
if (processor != null) {
|
||||
processor.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 创建 DatabaseAppender 实例的工厂方法
|
||||
*/
|
||||
@PluginFactory
|
||||
public static DatabaseAppender createAppender(
|
||||
@PluginAttribute("name") String name,
|
||||
@PluginElement("Filter") Filter filter,
|
||||
@PluginAttribute("ignoreExceptions") boolean ignoreExceptions) {
|
||||
|
||||
if (name == null) {
|
||||
LOGGER.error("未指定 DatabaseAppender 名称");
|
||||
return null;
|
||||
}
|
||||
|
||||
return new DatabaseAppender(name, filter, ignoreExceptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取日志队列,供处理器使用
|
||||
*/
|
||||
public static BlockingQueue<LogEventContext> getLogQueue() {
|
||||
return logQueue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 日志事件处理器(内部类)
|
||||
*/
|
||||
static class LogEventProcessor implements Runnable {
|
||||
private volatile boolean running = true;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (running) {
|
||||
try {
|
||||
// 从队列中获取日志事件上下文(阻塞等待)
|
||||
LogEventContext context = logQueue.poll(1, TimeUnit.SECONDS);
|
||||
if (context != null) {
|
||||
processLogEvent(context);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
break;
|
||||
} catch (Exception e) {
|
||||
System.err.println("处理日志事件失败: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 处理单个日志事件
|
||||
*/
|
||||
private void processLogEvent(LogEventContext context) {
|
||||
try {
|
||||
// 通过 Spring 容器获取日志Service并保存
|
||||
LogEventHandler handler = SpringContextUtil.getBean(LogEventHandler.class);
|
||||
if (handler != null) {
|
||||
handler.handleLogEvent(context);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println("保存日志到数据库失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
running = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
package org.xyzh.system.log;
|
||||
|
||||
import org.apache.logging.log4j.core.LogEvent;
|
||||
|
||||
/**
|
||||
* @description 日志事件上下文 - 包含日志事件和HTTP上下文信息
|
||||
* @filename LogEventContext.java
|
||||
* @author yslg
|
||||
* @copyright xyzh
|
||||
* @since 2025-10-30
|
||||
*/
|
||||
public class LogEventContext {
|
||||
|
||||
private final LogEvent logEvent;
|
||||
private final String userId;
|
||||
private final String username;
|
||||
private final String requestUrl;
|
||||
private final String requestMethod;
|
||||
private final String ipAddress;
|
||||
private final String ipSource;
|
||||
private final String browser;
|
||||
private final String os;
|
||||
|
||||
public LogEventContext(LogEvent logEvent, String userId, String username,
|
||||
String requestUrl, String requestMethod,
|
||||
String ipAddress, String ipSource,
|
||||
String browser, String os) {
|
||||
this.logEvent = logEvent;
|
||||
this.userId = userId;
|
||||
this.username = username;
|
||||
this.requestUrl = requestUrl;
|
||||
this.requestMethod = requestMethod;
|
||||
this.ipAddress = ipAddress;
|
||||
this.ipSource = ipSource;
|
||||
this.browser = browser;
|
||||
this.os = os;
|
||||
}
|
||||
|
||||
public LogEvent getLogEvent() {
|
||||
return logEvent;
|
||||
}
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public String getRequestUrl() {
|
||||
return requestUrl;
|
||||
}
|
||||
|
||||
public String getRequestMethod() {
|
||||
return requestMethod;
|
||||
}
|
||||
|
||||
public String getIpAddress() {
|
||||
return ipAddress;
|
||||
}
|
||||
|
||||
public String getIpSource() {
|
||||
return ipSource;
|
||||
}
|
||||
|
||||
public String getBrowser() {
|
||||
return browser;
|
||||
}
|
||||
|
||||
public String getOs() {
|
||||
return os;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
package org.xyzh.system.log;
|
||||
|
||||
import org.apache.logging.log4j.core.LogEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.xyzh.common.dto.system.TbSysOperationLog;
|
||||
import org.xyzh.common.utils.IDUtils;
|
||||
import org.xyzh.system.mapper.SysOperationLogMapper;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @description 日志事件处理器 - 将日志事件转换并保存到数据库
|
||||
* @filename LogEventHandler.java
|
||||
* @author yslg
|
||||
* @copyright xyzh
|
||||
* @since 2025-10-30
|
||||
*/
|
||||
@Component
|
||||
public class LogEventHandler {
|
||||
|
||||
@Autowired
|
||||
private SysOperationLogMapper operationLogMapper;
|
||||
|
||||
/**
|
||||
* @description 处理日志事件(异步)
|
||||
* @param context 日志事件上下文(包含HTTP上下文信息)
|
||||
*/
|
||||
@Async("logExecutor")
|
||||
public void handleLogEvent(LogEventContext context) {
|
||||
try {
|
||||
// 处理 DEBUG 级别及以上的所有日志(由 ThresholdFilter 已过滤)
|
||||
// 这里不需要再次判断级别,直接保存即可
|
||||
TbSysOperationLog operationLog = buildOperationLog(context);
|
||||
operationLogMapper.insertOperationLog(operationLog);
|
||||
} catch (Exception e) {
|
||||
// 使用 System.err 而不是 logger,避免循环依赖
|
||||
System.err.println("保存日志到数据库失败: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 构建操作日志对象
|
||||
*/
|
||||
private TbSysOperationLog buildOperationLog(LogEventContext context) {
|
||||
LogEvent event = context.getLogEvent();
|
||||
TbSysOperationLog log = new TbSysOperationLog();
|
||||
|
||||
log.setID(IDUtils.generateID());
|
||||
|
||||
// 使用从主线程提取的用户信息
|
||||
log.setUserID(context.getUserId());
|
||||
log.setUsername(context.getUsername());
|
||||
|
||||
// 日志基本信息
|
||||
log.setModule(event.getLoggerName());
|
||||
log.setOperation(event.getLevel().name());
|
||||
log.setMethod(event.getLoggerName());
|
||||
|
||||
// 使用从主线程提取的请求信息
|
||||
log.setRequestUrl(context.getRequestUrl());
|
||||
log.setRequestMethod(context.getRequestMethod());
|
||||
log.setIpAddress(context.getIpAddress());
|
||||
log.setIpSource(context.getIpSource());
|
||||
log.setBrowser(context.getBrowser());
|
||||
log.setOs(context.getOs());
|
||||
|
||||
// 日志消息和异常信息
|
||||
log.setResponseData(event.getMessage().getFormattedMessage());
|
||||
if (event.getThrown() != null) {
|
||||
log.setErrorMessage(getStackTrace(event.getThrown()));
|
||||
log.setStatus(0); // 失败
|
||||
} else {
|
||||
log.setStatus(1); // 成功
|
||||
}
|
||||
|
||||
log.setExecuteTime(0); // 日志无执行时间
|
||||
log.setCreateTime(new Date(event.getTimeMillis()));
|
||||
|
||||
return log;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取异常堆栈信息
|
||||
*/
|
||||
private String getStackTrace(Throwable throwable) {
|
||||
if (throwable == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(throwable.getClass().getName()).append(": ").append(throwable.getMessage()).append("\n");
|
||||
|
||||
StackTraceElement[] elements = throwable.getStackTrace();
|
||||
int maxLines = Math.min(elements.length, 10); // 只保留前10行
|
||||
for (int i = 0; i < maxLines; i++) {
|
||||
sb.append("\tat ").append(elements[i].toString()).append("\n");
|
||||
}
|
||||
|
||||
if (elements.length > maxLines) {
|
||||
sb.append("\t... ").append(elements.length - maxLines).append(" more\n");
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
# 异步日志监听系统
|
||||
|
||||
## 功能说明
|
||||
|
||||
本系统实现了对 Logger 输出的监听,将ERROR级别及以上的日志异步写入数据库,用于日志审计和问题追踪。
|
||||
|
||||
## 核心组件
|
||||
|
||||
### 1. DatabaseAppender
|
||||
**路径**: `system/src/main/java/org/xyzh/system/log/DatabaseAppender.java`
|
||||
|
||||
自定义 Log4j2 Appender,负责:
|
||||
- 监听所有日志输出
|
||||
- 过滤 ERROR 级别及以上的日志
|
||||
- 将日志事件放入异步队列(非阻塞,防止影响业务性能)
|
||||
- 队列容量:10000条
|
||||
|
||||
### 2. LogEventHandler
|
||||
**路径**: `system/src/main/java/org/xyzh/system/log/LogEventHandler.java`
|
||||
|
||||
日志事件处理器,负责:
|
||||
- 从异步队列获取日志事件
|
||||
- 转换为 `TbSysOperationLog` 对象
|
||||
- 异步批量写入数据库
|
||||
- 自动提取:用户信息、请求信息、IP、浏览器、OS等
|
||||
|
||||
### 3. SpringContextUtil
|
||||
**路径**: `system/src/main/java/org/xyzh/system/log/SpringContextUtil.java`
|
||||
|
||||
Spring上下文工具类,用于在非Spring管理的类(如Log4j2 Appender)中获取Spring Bean。
|
||||
|
||||
### 4. AsyncLogConfig
|
||||
**路径**: `system/src/main/java/org/xyzh/system/config/AsyncLogConfig.java`
|
||||
|
||||
异步执行器配置:
|
||||
- 核心线程数:2
|
||||
- 最大线程数:5
|
||||
- 队列容量:1000
|
||||
- 拒绝策略:CallerRunsPolicy(防止日志丢失)
|
||||
|
||||
## 配置方法
|
||||
|
||||
### 1. 在 log4j2-spring.xml 中添加 Database Appender
|
||||
|
||||
```xml
|
||||
<appenders>
|
||||
<!-- ... 其他 appenders ... -->
|
||||
|
||||
<!-- 数据库日志Appender -->
|
||||
<DatabaseAppender name="DatabaseAppender" ignoreExceptions="false">
|
||||
<ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
|
||||
</DatabaseAppender>
|
||||
</appenders>
|
||||
|
||||
<loggers>
|
||||
<root level="info">
|
||||
<!-- ... 其他 appenders ... -->
|
||||
<!-- 数据库日志Appender -->
|
||||
<appender-ref ref="DatabaseAppender"/>
|
||||
</root>
|
||||
</loggers>
|
||||
```
|
||||
|
||||
### 2. 确保数据库表存在
|
||||
|
||||
表名:`tb_sys_operation_log`
|
||||
|
||||
主要字段:
|
||||
- `id` - 主键
|
||||
- `user_id` - 用户ID
|
||||
- `username` - 用户名
|
||||
- `module` - 模块名(Logger名称)
|
||||
- `operation` - 操作类型(日志级别)
|
||||
- `method` - 方法名
|
||||
- `request_url` - 请求URL
|
||||
- `request_method` - 请求方法
|
||||
- `request_params` - 请求参数
|
||||
- `response_data` - 日志消息
|
||||
- `ip_address` - IP地址
|
||||
- `ip_source` - IP来源
|
||||
- `browser` - 浏览器
|
||||
- `os` - 操作系统
|
||||
- `status` - 状态(0-失败,1-成功)
|
||||
- `error_message` - 异常堆栈
|
||||
- `execute_time` - 执行时间
|
||||
- `create_time` - 创建时间
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 记录错误日志
|
||||
|
||||
```java
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class UserService {
|
||||
private static final Logger logger = LoggerFactory.getLogger(UserService.class);
|
||||
|
||||
public void someMethod() {
|
||||
try {
|
||||
// 业务逻辑
|
||||
} catch (Exception e) {
|
||||
// 这条ERROR日志会自动写入数据库
|
||||
logger.error("用户操作失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 记录警告日志(不会写入数据库)
|
||||
|
||||
```java
|
||||
// WARN级别日志不会写入数据库,只写入文件
|
||||
logger.warn("这是一个警告信息");
|
||||
```
|
||||
|
||||
## 性能优化
|
||||
|
||||
1. **异步队列**:日志事件先放入内存队列,不阻塞业务线程
|
||||
2. **批量处理**:后台线程批量从队列取出并处理
|
||||
3. **线程池**:使用专用线程池处理日志写入
|
||||
4. **非阻塞**:队列满时丢弃日志而不阻塞
|
||||
5. **级别过滤**:只处理ERROR及以上级别,减少数据库压力
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **日志级别**:默认只记录ERROR级别及以上的日志到数据库
|
||||
2. **队列容量**:队列容量10000,超出会丢弃(打印警告到stderr)
|
||||
3. **关闭等待**:应用关闭时会等待60秒完成日志写入
|
||||
4. **循环依赖**:LogEventHandler中不要使用logger.error(),会造成循环
|
||||
5. **性能影响**:每次ERROR日志会触发数据库写入,避免频繁ERROR日志
|
||||
|
||||
## 监控建议
|
||||
|
||||
1. 定期检查 `tb_sys_operation_log` 表大小
|
||||
2. 定期归档或删除旧日志(如30天前的)
|
||||
3. 监控队列满的告警(stderr输出)
|
||||
4. 监控数据库写入性能
|
||||
|
||||
## 扩展功能
|
||||
|
||||
### 自定义日志级别过滤
|
||||
|
||||
修改 `LogEventHandler.handleLogEvent()` 方法:
|
||||
|
||||
```java
|
||||
// 改为记录WARN及以上级别
|
||||
if (event.getLevel().isMoreSpecificThan(org.apache.logging.log4j.Level.WARN)) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### 添加自定义字段
|
||||
|
||||
在 `buildOperationLog()` 方法中添加自定义字段提取逻辑。
|
||||
|
||||
### 批量写入优化
|
||||
|
||||
可以修改为收集多条日志后批量写入数据库,进一步提升性能。
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
package org.xyzh.system.log.service.impl;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.xyzh.api.system.log.LoginLogService;
|
||||
import org.xyzh.common.core.domain.ResultDomain;
|
||||
import org.xyzh.common.core.page.PageDomain;
|
||||
import org.xyzh.common.core.page.PageParam;
|
||||
import org.xyzh.common.dto.system.TbSysLoginLog;
|
||||
import org.xyzh.common.vo.UserDeptRoleVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.xyzh.system.mapper.SysLoginLogMapper;
|
||||
import org.xyzh.system.utils.LoginUtil;
|
||||
|
||||
@Service
|
||||
public class LoginLogServiceImpl implements LoginLogService {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(LoginLogServiceImpl.class);
|
||||
|
||||
@Autowired
|
||||
private SysLoginLogMapper sysLoginLogMapper;
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbSysLoginLog> insertLoginLog(TbSysLoginLog loginLog) {
|
||||
ResultDomain<TbSysLoginLog> result = new ResultDomain<>();
|
||||
int rows = sysLoginLogMapper.insertLoginLog(loginLog);
|
||||
if (rows > 0) {
|
||||
result.success("插入登录日志成功", loginLog);
|
||||
} else {
|
||||
result.fail( "插入登录日志失败");
|
||||
}
|
||||
logger.info("insertLoginLog: {}", loginLog);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbSysLoginLog> selectLoginLogList(TbSysLoginLog loginLog) {
|
||||
ResultDomain<TbSysLoginLog> result = new ResultDomain<>();
|
||||
List<UserDeptRoleVO> userDeptRoles = LoginUtil.getCurrentDeptRole();
|
||||
List<TbSysLoginLog> list = sysLoginLogMapper.selectLoginLogList(loginLog, userDeptRoles);
|
||||
if (list != null) {
|
||||
result.success("查询登录日志成功", list);
|
||||
} else {
|
||||
result.fail("查询登录日志失败");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbSysLoginLog> selectLoginLogPage(TbSysLoginLog loginLog, PageParam pageParam) {
|
||||
ResultDomain<TbSysLoginLog> result = new ResultDomain<>();
|
||||
List<UserDeptRoleVO> userDeptRoles = LoginUtil.getCurrentDeptRole();
|
||||
List<TbSysLoginLog> list = sysLoginLogMapper.selectLoginLogPage(loginLog, pageParam, userDeptRoles);
|
||||
PageDomain<TbSysLoginLog> pageDomain = new PageDomain<>();
|
||||
int count = sysLoginLogMapper.countLoginLog(loginLog, userDeptRoles);
|
||||
pageParam.setTotalElements(count);
|
||||
pageParam.setTotalPages((int)Math.ceil(count / pageParam.getPageSize() ));
|
||||
|
||||
pageDomain.setPageParam(pageParam);
|
||||
pageDomain.setDataList(list);
|
||||
if (list != null) {
|
||||
result.success("查询登录日志成功", pageDomain);
|
||||
} else {
|
||||
result.fail("查询登录日志失败");
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package org.xyzh.system.log.service.impl;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.xyzh.api.system.log.OperationLogService;
|
||||
import org.xyzh.common.core.domain.ResultDomain;
|
||||
import org.xyzh.common.core.page.PageDomain;
|
||||
import org.xyzh.common.core.page.PageParam;
|
||||
import org.xyzh.common.dto.system.TbSysOperationLog;
|
||||
import org.xyzh.common.vo.UserDeptRoleVO;
|
||||
import org.xyzh.system.mapper.SysOperationLogMapper;
|
||||
import org.xyzh.system.utils.LoginUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @description 操作日志服务实现
|
||||
* @filename SysOperationLogServiceImpl.java
|
||||
* @author yslg
|
||||
* @copyright xyzh
|
||||
* @since 2025-10-30
|
||||
*/
|
||||
@Service
|
||||
public class SysOperationLogServiceImpl implements OperationLogService {
|
||||
|
||||
@Autowired
|
||||
private SysOperationLogMapper operationLogMapper;
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbSysOperationLog> selectOperationLogPage(TbSysOperationLog operationLog, PageParam pageParam) {
|
||||
ResultDomain<TbSysOperationLog> result = new ResultDomain<>();
|
||||
|
||||
try {
|
||||
// 获取当前用户的部门角色信息(用于权限过滤)
|
||||
List<UserDeptRoleVO> userDeptRoles = LoginUtil.getCurrentDeptRole();
|
||||
|
||||
// 分页查询操作日志
|
||||
List<TbSysOperationLog> logs = operationLogMapper.selectOperationLogPage(operationLog, pageParam, userDeptRoles);
|
||||
|
||||
// 统计总数(带权限过滤)
|
||||
int count = operationLogMapper.countOperationLog(operationLog, userDeptRoles);
|
||||
pageParam.setTotalElements(count);
|
||||
pageParam.setTotalPages((int) Math.ceil((double) count / pageParam.getPageSize()));
|
||||
|
||||
// 构建分页结果
|
||||
PageDomain<TbSysOperationLog> pageDomain = new PageDomain<>();
|
||||
pageDomain.setPageParam(pageParam);
|
||||
pageDomain.setDataList(logs);
|
||||
|
||||
result.success("查询成功", pageDomain);
|
||||
} catch (Exception e) {
|
||||
result.fail("查询失败: " + e.getMessage());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countOperationLog(TbSysOperationLog operationLog) {
|
||||
// 获取当前用户的部门角色信息(用于权限过滤)
|
||||
List<UserDeptRoleVO> userDeptRoles = LoginUtil.getCurrentDeptRole();
|
||||
return operationLogMapper.countOperationLog(operationLog, userDeptRoles);
|
||||
}
|
||||
}
|
||||
@@ -7,20 +7,19 @@ import java.util.List;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.xyzh.common.dto.dept.TbSysDeptRole;
|
||||
import org.xyzh.common.dto.role.TbSysRole;
|
||||
import org.xyzh.common.vo.UserDeptRoleVO;
|
||||
|
||||
@Mapper
|
||||
public interface DeptRoleMapper extends BaseMapper<TbSysDeptRole> {
|
||||
|
||||
/**
|
||||
* @description 查询部门绑定角色
|
||||
* @description 查询部门绑定角色(包含名称)
|
||||
* @param deptId 部门ID
|
||||
* @return List<TbSysRole> 角色列表
|
||||
* @return List<UserDeptRoleVO> 部门角色列表
|
||||
* @author yslg
|
||||
* @since 2025-09-28
|
||||
*/
|
||||
List<TbSysRole> selectDeptRole(String deptId);
|
||||
List<UserDeptRoleVO> selectDeptRole(String deptId);
|
||||
|
||||
/**
|
||||
* @description 查询部门绑定角色列表(包含名称)
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.xyzh.common.dto.menu.TbSysMenuPermission;
|
||||
import org.xyzh.common.vo.PermissionVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -49,13 +50,13 @@ public interface MenuPermissionMapper extends BaseMapper<TbSysMenuPermission> {
|
||||
@Param("permissionId") String permissionId);
|
||||
|
||||
/**
|
||||
* @description 根据菜单ID查询权限关联列表
|
||||
* @description 根据菜单ID查询权限列表(包含模块名称等信息)
|
||||
* @param menuId 菜单ID
|
||||
* @return List<TbSysMenuPermission> 菜单权限关联列表
|
||||
* @return List<PermissionVO> 权限列表
|
||||
* @author yslg
|
||||
* @since 2025-10-07
|
||||
*/
|
||||
List<TbSysMenuPermission> selectByMenuId(@Param("menuId") String menuId);
|
||||
List<PermissionVO> selectByMenuId(@Param("menuId") String menuId);
|
||||
|
||||
/**
|
||||
* @description 根据权限ID查询菜单关联列表
|
||||
|
||||
@@ -141,22 +141,22 @@ public interface PermissionMapper extends BaseMapper<TbSysPermission> {
|
||||
PermissionVO selectPermissionVO(@Param("permission") PermissionVO permission);
|
||||
|
||||
/**
|
||||
* @description 查询权限绑定菜单
|
||||
* @description 查询权限绑定菜单(包含菜单名称描述)
|
||||
* @param permission 权限对象
|
||||
* @return List<TbSysMenu> 权限绑定菜单列表
|
||||
* @return List<PermissionVO> 权限VO列表(包含菜单信息)
|
||||
* @author yslg
|
||||
* @since 2025-10-08
|
||||
*/
|
||||
List<TbSysMenu> selectPermissionBindMenu(@Param("permission") PermissionVO permission);
|
||||
List<PermissionVO> selectPermissionBindMenu(@Param("permission") PermissionVO permission);
|
||||
|
||||
/**
|
||||
* @description 查询权限绑定角色
|
||||
* @description 查询权限绑定角色(包含角色名称描述和创建人更新人)
|
||||
* @param permission 权限对象
|
||||
* @return List<TbSysRole> 权限绑定角色列表
|
||||
* @return List<PermissionVO> 权限VO列表(包含角色信息)
|
||||
* @author yslg
|
||||
* @since 2025-10-08
|
||||
*/
|
||||
List<TbSysRole> selectPermissionBindRole(@Param("permission") PermissionVO permission);
|
||||
List<PermissionVO> selectPermissionBindRole(@Param("permission") PermissionVO permission);
|
||||
|
||||
/**
|
||||
* @description 根据模块ID查询权限列表
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.xyzh.common.dto.role.TbSysRole;
|
||||
import org.xyzh.common.vo.PermissionVO;
|
||||
import org.xyzh.common.vo.UserDeptRoleVO;
|
||||
|
||||
import java.util.List;
|
||||
@@ -24,16 +25,24 @@ public interface RoleMapper extends BaseMapper<TbSysRole> {
|
||||
* @author yslg
|
||||
* @since 2025-10-09
|
||||
*/
|
||||
List<TbSysRole> selectAllRoles();
|
||||
/**
|
||||
* @description 查询所有角色(包含权限过滤和创建人更新人名称)
|
||||
* @param userDeptRoles 用户部门角色列表(用于权限过滤)
|
||||
* @return List<PermissionVO> 角色VO列表
|
||||
* @author yslg
|
||||
* @since 2025-10-30
|
||||
*/
|
||||
List<PermissionVO> selectAllRoles(@Param("userDeptRoles") List<UserDeptRoleVO> userDeptRoles);
|
||||
|
||||
/**
|
||||
* @description 根据过滤条件查询角色列表
|
||||
* @description 根据过滤条件查询角色列表(包含权限过滤)
|
||||
* @param filter 过滤条件
|
||||
* @return List<TbSysRole> 角色列表
|
||||
* @param userDeptRoles 用户部门角色列表(用于权限过滤)
|
||||
* @return List<PermissionVO> 角色VO列表
|
||||
* @author yslg
|
||||
* @since 2025-10-09
|
||||
*/
|
||||
List<TbSysRole> selectRole(TbSysRole filter);
|
||||
List<PermissionVO> selectRole(@Param("filter") TbSysRole filter, @Param("userDeptRoles") List<UserDeptRoleVO> userDeptRoles);
|
||||
|
||||
/**
|
||||
* @description 插入角色
|
||||
@@ -71,35 +80,19 @@ public interface RoleMapper extends BaseMapper<TbSysRole> {
|
||||
*/
|
||||
List<UserDeptRoleVO> selectDeptRolesByUserId(@Param("userId") String userId);
|
||||
|
||||
/**
|
||||
* @description 根据角色编码查询角色
|
||||
* @param roleCode 角色编码
|
||||
* @return TbSysRole 角色信息
|
||||
* @author yslg
|
||||
* @since 2025-09-28
|
||||
*/
|
||||
TbSysRole selectByRoleCode(@Param("roleCode") String roleCode);
|
||||
|
||||
/**
|
||||
* @description 检查角色名称是否存在
|
||||
* @description 检查角色名称是否存在(包含权限过滤)
|
||||
* @param roleName 角色名称
|
||||
* @param excludeId 排除的角色ID
|
||||
* @param userDeptRoles 用户部门角色列表(用于权限过滤)
|
||||
* @return int 存在数量
|
||||
* @author yslg
|
||||
* @since 2025-09-28
|
||||
*/
|
||||
int countByRoleName(@Param("roleName") String roleName, @Param("excludeId") String excludeId);
|
||||
|
||||
/**
|
||||
* @description 检查角色编码是否存在
|
||||
* @param roleCode 角色编码
|
||||
* @param excludeId 排除的角色ID
|
||||
* @return int 存在数量
|
||||
* @author yslg
|
||||
* @since 2025-09-28
|
||||
*/
|
||||
int countByRoleCode(@Param("roleCode") String roleCode, @Param("excludeId") String excludeId);
|
||||
int countByRoleName(@Param("roleName") String roleName, @Param("excludeId") String excludeId, @Param("userDeptRoles") List<UserDeptRoleVO> userDeptRoles);
|
||||
|
||||
|
||||
/**
|
||||
* @description 批量删除角色(逻辑删除)
|
||||
* @param roleIds 角色ID列表
|
||||
@@ -111,7 +104,7 @@ public interface RoleMapper extends BaseMapper<TbSysRole> {
|
||||
int batchDeleteByIds(@Param("roleIds") List<String> roleIds, @Param("updater") String updater);
|
||||
|
||||
/**
|
||||
* @description 检查角色是否存在
|
||||
* @description 检查角色是否存在(精确查询,不需要权限过滤)
|
||||
* @param roleIds 角色ID列表
|
||||
* @return List<TbSysRole> 角色列表
|
||||
* @author yslg
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.xyzh.system.mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.xyzh.common.core.page.PageParam;
|
||||
import org.xyzh.common.dto.system.TbSysLoginLog;
|
||||
import org.xyzh.common.vo.UserDeptRoleVO;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
@Mapper
|
||||
public interface SysLoginLogMapper extends BaseMapper<TbSysLoginLog> {
|
||||
|
||||
int insertLoginLog(TbSysLoginLog loginLog);
|
||||
|
||||
List<TbSysLoginLog> selectLoginLogList(@Param("loginLog") TbSysLoginLog loginLog, @Param("userDeptRoles") List<UserDeptRoleVO> userDeptRoles);
|
||||
|
||||
List<TbSysLoginLog> selectLoginLogPage(@Param("loginLog") TbSysLoginLog loginLog, @Param("pageParam") PageParam pageParam, @Param("userDeptRoles") List<UserDeptRoleVO> userDeptRoles);
|
||||
|
||||
int countLoginLog(@Param("loginLog") TbSysLoginLog loginLog, @Param("userDeptRoles") List<UserDeptRoleVO> userDeptRoles);
|
||||
}
|
||||
@@ -2,7 +2,10 @@ package org.xyzh.system.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.xyzh.common.core.page.PageParam;
|
||||
import org.xyzh.common.dto.system.TbSysOperationLog;
|
||||
import org.xyzh.common.vo.UserDeptRoleVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -17,11 +20,46 @@ import java.util.List;
|
||||
public interface SysOperationLogMapper extends BaseMapper<TbSysOperationLog> {
|
||||
|
||||
/**
|
||||
* @description 查询操作日志列表
|
||||
* @param filter 过滤条件
|
||||
* @description 插入操作日志
|
||||
* @param operationLog 操作日志对象
|
||||
* @return int 影响行数
|
||||
* @author yslg
|
||||
* @since 2025-10-30
|
||||
*/
|
||||
int insertOperationLog(TbSysOperationLog operationLog);
|
||||
|
||||
/**
|
||||
* @description 查询操作日志列表(带权限过滤)
|
||||
* @param operationLog 过滤条件
|
||||
* @param userDeptRoles 当前用户的部门角色列表
|
||||
* @return List<TbSysOperationLog> 操作日志列表
|
||||
* @author yslg
|
||||
* @since 2025-10-15
|
||||
* @since 2025-10-30
|
||||
*/
|
||||
List<TbSysOperationLog> selectSysOperationLogs(TbSysOperationLog filter);
|
||||
List<TbSysOperationLog> selectOperationLogList(@Param("operationLog") TbSysOperationLog operationLog,
|
||||
@Param("userDeptRoles") List<UserDeptRoleVO> userDeptRoles);
|
||||
|
||||
/**
|
||||
* @description 分页查询操作日志列表(带权限过滤)
|
||||
* @param operationLog 过滤条件
|
||||
* @param pageParam 分页参数
|
||||
* @param userDeptRoles 当前用户的部门角色列表
|
||||
* @return List<TbSysOperationLog> 操作日志列表
|
||||
* @author yslg
|
||||
* @since 2025-10-30
|
||||
*/
|
||||
List<TbSysOperationLog> selectOperationLogPage(@Param("operationLog") TbSysOperationLog operationLog,
|
||||
@Param("pageParam") PageParam pageParam,
|
||||
@Param("userDeptRoles") List<UserDeptRoleVO> userDeptRoles);
|
||||
|
||||
/**
|
||||
* @description 统计操作日志数量(带权限过滤)
|
||||
* @param operationLog 过滤条件
|
||||
* @param userDeptRoles 当前用户的部门角色列表
|
||||
* @return int 日志数量
|
||||
* @author yslg
|
||||
* @since 2025-10-30
|
||||
*/
|
||||
int countOperationLog(@Param("operationLog") TbSysOperationLog operationLog,
|
||||
@Param("userDeptRoles") List<UserDeptRoleVO> userDeptRoles);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.apache.ibatis.annotations.Param;
|
||||
import org.xyzh.common.core.page.PageParam;
|
||||
import org.xyzh.common.dto.user.TbSysUser;
|
||||
import org.xyzh.common.dto.user.TbSysUserInfo;
|
||||
import org.xyzh.common.vo.UserDeptRoleVO;
|
||||
import org.xyzh.common.vo.UserVO;
|
||||
|
||||
import java.util.List;
|
||||
@@ -20,6 +21,8 @@ import java.util.List;
|
||||
@Mapper
|
||||
public interface UserMapper extends BaseMapper<TbSysUser> {
|
||||
|
||||
TbSysUser selectLoginUser(@Param("filter") TbSysUser filter);
|
||||
|
||||
/**
|
||||
* @description 插入用户
|
||||
* @param user 用户信息
|
||||
@@ -75,36 +78,61 @@ public interface UserMapper extends BaseMapper<TbSysUser> {
|
||||
TbSysUser selectByPhone(@Param("phone") String phone);
|
||||
|
||||
/**
|
||||
* @description 根据过滤条件查询用户
|
||||
* @description 根据过滤条件查询用户(包含权限过滤)
|
||||
* @param filter 过滤条件
|
||||
* @param userDeptRoles 用户部门角色列表
|
||||
* @return TbSysUser 用户信息
|
||||
* @author yslg
|
||||
* @since 2025-09-28
|
||||
*/
|
||||
List<TbSysUser> selectByFilter(@Param("filter") TbSysUser filter);
|
||||
List<TbSysUser> selectByFilter(@Param("filter") TbSysUser filter, @Param("userDeptRoles") List<UserDeptRoleVO> userDeptRoles);
|
||||
|
||||
/**
|
||||
* @description 查询用户列表(分页)
|
||||
* @description 根据过滤条件查询用户VO列表(包含userinfo和deptrole信息,包含权限过滤)
|
||||
* @param filter 过滤条件
|
||||
* @param userDeptRoles 用户部门角色列表
|
||||
* @return List<UserVO> 用户VO列表
|
||||
* @author yslg
|
||||
* @since 2025-10-30
|
||||
*/
|
||||
List<UserVO> selectUserVOByFilter(@Param("filter") TbSysUser filter, @Param("userDeptRoles") List<UserDeptRoleVO> userDeptRoles);
|
||||
|
||||
/**
|
||||
* @description 查询用户列表(包含权限过滤)
|
||||
* @param username 用户名(模糊查询)
|
||||
* @param email 邮箱(模糊查询)
|
||||
* @param status 用户状态
|
||||
* @param userDeptRoles 用户部门角色列表
|
||||
* @return List<TbSysUser> 用户列表
|
||||
* @author yslg
|
||||
* @since 2025-09-28
|
||||
*/
|
||||
List<TbSysUser> selectUserList(@Param("username") String username,
|
||||
@Param("email") String email,
|
||||
@Param("status") String status);
|
||||
@Param("status") String status,
|
||||
@Param("userDeptRoles") List<UserDeptRoleVO> userDeptRoles);
|
||||
|
||||
/**
|
||||
* @description 查询用户列表(分页)
|
||||
* @description 查询用户列表(分页,包含权限过滤)
|
||||
* @param filter 过滤条件
|
||||
* @param pageParam 分页参数
|
||||
* @param userDeptRoles 用户部门角色列表
|
||||
* @return List<TbSysUser> 用户列表
|
||||
* @author yslg
|
||||
* @since 2025-09-28
|
||||
*/
|
||||
List<TbSysUser> selectUserPage(@Param("filter") TbSysUser filter, @Param("pageParam") PageParam pageParam);
|
||||
List<TbSysUser> selectUserPage(@Param("filter") TbSysUser filter, @Param("pageParam") PageParam pageParam, @Param("userDeptRoles") List<UserDeptRoleVO> userDeptRoles);
|
||||
|
||||
/**
|
||||
* @description 查询用户VO列表(分页,包含userinfo和deptrole信息,包含权限过滤)
|
||||
* @param filter 过滤条件
|
||||
* @param pageParam 分页参数
|
||||
* @param userDeptRoles 用户部门角色列表
|
||||
* @return List<UserVO> 用户VO列表
|
||||
* @author yslg
|
||||
* @since 2025-10-30
|
||||
*/
|
||||
List<UserVO> selectUserVOPage(@Param("filter") TbSysUser filter, @Param("pageParam") PageParam pageParam, @Param("userDeptRoles") List<UserDeptRoleVO> userDeptRoles);
|
||||
|
||||
/**
|
||||
* @description 批量删除用户(逻辑删除)
|
||||
@@ -153,4 +181,7 @@ public interface UserMapper extends BaseMapper<TbSysUser> {
|
||||
* @since 2025-10-18
|
||||
*/
|
||||
UserVO selectUserInfoTotal(@Param("userId") String userId);
|
||||
|
||||
|
||||
int countDeptUser(@Param("deptId") String deptId);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import org.xyzh.common.core.domain.ResultDomain;
|
||||
import org.xyzh.common.dto.menu.TbSysMenu;
|
||||
import org.xyzh.common.dto.menu.TbSysMenuPermission;
|
||||
import org.xyzh.common.utils.IDUtils;
|
||||
import org.xyzh.common.vo.PermissionVO;
|
||||
import org.xyzh.system.mapper.MenuMapper;
|
||||
import org.xyzh.system.mapper.MenuPermissionMapper;
|
||||
import org.xyzh.system.menu.service.SysMenuService;
|
||||
@@ -463,16 +464,13 @@ public class SysMenuServiceImpl implements SysMenuService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbSysMenuPermission> getMenuPermission(String menuId) {
|
||||
ResultDomain<TbSysMenuPermission> resultDomain = new ResultDomain<>();
|
||||
public ResultDomain<PermissionVO> getMenuPermission(String menuId) {
|
||||
ResultDomain<PermissionVO> resultDomain = new ResultDomain<>();
|
||||
try {
|
||||
logger.info("开始查询菜单权限:{}", menuId);
|
||||
List<TbSysMenuPermission> menuPermissions = menuPermissionMapper.selectByMenuId(menuId);
|
||||
if (menuPermissions.isEmpty()) {
|
||||
resultDomain.fail("未找到菜单权限");
|
||||
return resultDomain;
|
||||
}
|
||||
resultDomain.success("查询菜单权限成功", menuPermissions);
|
||||
List<PermissionVO> permissions = menuPermissionMapper.selectByMenuId(menuId);
|
||||
logger.info("查询菜单权限完成,共找到{}个权限", permissions.size());
|
||||
resultDomain.success("查询菜单权限成功", permissions);
|
||||
return resultDomain;
|
||||
} catch (Exception e) {
|
||||
logger.error("查询菜单权限异常:{}", menuId, e);
|
||||
|
||||
@@ -301,14 +301,14 @@ public class SysPermissionServiceImpl implements SysPermissionService {
|
||||
PermissionVO permissionVO = permissionMapper.selectPermissionVO(permission);
|
||||
|
||||
if (permission.getBindType().equals("menu")) {
|
||||
List<TbSysMenu> bindMenus = permissionMapper.selectPermissionBindMenu(permission);
|
||||
permissionVO.setMenus(bindMenus);
|
||||
resultDomain.success("查询权限绑定列表成功", permissionVO);
|
||||
List<PermissionVO> bindMenus = permissionMapper.selectPermissionBindMenu(permission);
|
||||
logger.info("查询权限绑定菜单列表完成,共找到{}个菜单", bindMenus.size());
|
||||
resultDomain.success("查询权限绑定菜单列表成功", bindMenus);
|
||||
return resultDomain;
|
||||
} else {
|
||||
List<TbSysRole> bindRoles = permissionMapper.selectPermissionBindRole(permission);
|
||||
permissionVO.setRoles(bindRoles);
|
||||
resultDomain.success("查询权限绑定角色列表成功", permissionVO);
|
||||
List<PermissionVO> bindRoles = permissionMapper.selectPermissionBindRole(permission);
|
||||
logger.info("查询权限绑定角色列表完成,共找到{}个角色", bindRoles.size());
|
||||
resultDomain.success("查询权限绑定角色列表成功", bindRoles);
|
||||
return resultDomain;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,12 +8,15 @@ import org.springframework.util.StringUtils;
|
||||
import org.xyzh.common.core.domain.ResultDomain;
|
||||
import org.xyzh.common.dto.permission.TbSysPermission;
|
||||
import org.xyzh.common.dto.role.TbSysRole;
|
||||
import org.xyzh.common.dto.user.TbSysUser;
|
||||
import org.xyzh.common.utils.IDUtils;
|
||||
import org.xyzh.common.vo.PermissionVO;
|
||||
import org.xyzh.common.vo.UserDeptRoleVO;
|
||||
import org.xyzh.system.mapper.RolePermissionMapper;
|
||||
import org.xyzh.system.mapper.RoleMapper;
|
||||
import org.xyzh.system.mapper.UserDeptRoleMapper;
|
||||
import org.xyzh.system.role.service.SysRoleService;
|
||||
import org.xyzh.system.utils.LoginUtil;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
@@ -40,13 +43,19 @@ public class SysRoleServiceImpl implements SysRoleService {
|
||||
private UserDeptRoleMapper userDeptRoleMapper;
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbSysRole> getAllRoles() {
|
||||
ResultDomain<TbSysRole> resultDomain = new ResultDomain<>();
|
||||
public ResultDomain<PermissionVO> getAllRoles() {
|
||||
ResultDomain<PermissionVO> resultDomain = new ResultDomain<>();
|
||||
|
||||
try {
|
||||
logger.info("开始查询所有角色");
|
||||
logger.info("开始查询所有角色(包含权限过滤)");
|
||||
|
||||
List<TbSysRole> roles = roleMapper.selectAllRoles();
|
||||
// 获取当前用户的部门角色信息
|
||||
TbSysUser currentUser = LoginUtil.getCurrentUser();
|
||||
List<UserDeptRoleVO> userDeptRoles = roleMapper.selectDeptRolesByUserId(currentUser.getID());
|
||||
logger.info("当前用户拥有 {} 个部门角色", userDeptRoles.size());
|
||||
|
||||
// 查询有权限的角色列表
|
||||
List<PermissionVO> roles = roleMapper.selectAllRoles(userDeptRoles);
|
||||
|
||||
logger.info("查询所有角色完成,共找到{}个角色", roles.size());
|
||||
resultDomain.success("查询成功", roles);
|
||||
@@ -60,12 +69,18 @@ public class SysRoleServiceImpl implements SysRoleService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbSysRole> getRoleList(TbSysRole filter) {
|
||||
ResultDomain<TbSysRole> resultDomain = new ResultDomain<>();
|
||||
public ResultDomain<PermissionVO> getRoleList(TbSysRole filter) {
|
||||
ResultDomain<PermissionVO> resultDomain = new ResultDomain<>();
|
||||
try {
|
||||
logger.info("开始根据过滤条件查询角色列表:{}", filter);
|
||||
logger.info("开始根据过滤条件查询角色列表(包含权限过滤):{}", filter);
|
||||
|
||||
List<TbSysRole> roles = roleMapper.selectRole(filter);
|
||||
// 获取当前用户的部门角色信息
|
||||
TbSysUser currentUser = LoginUtil.getCurrentUser();
|
||||
List<UserDeptRoleVO> userDeptRoles = roleMapper.selectDeptRolesByUserId(currentUser.getID());
|
||||
logger.info("当前用户拥有 {} 个部门角色", userDeptRoles.size());
|
||||
|
||||
// 查询有权限的角色列表
|
||||
List<PermissionVO> roles = roleMapper.selectRole(filter, userDeptRoles);
|
||||
|
||||
logger.info("查询角色列表完成,共找到{}个角色", roles.size());
|
||||
resultDomain.success("查询成功", roles);
|
||||
@@ -233,18 +248,28 @@ public class SysRoleServiceImpl implements SysRoleService {
|
||||
resultDomain.fail("角色ID不能为空");
|
||||
return resultDomain;
|
||||
}
|
||||
// ByID 是精确查询,不需要权限过滤
|
||||
TbSysRole filter = new TbSysRole();
|
||||
filter.setRoleID(roleId);
|
||||
filter.setDeleted(false);
|
||||
List<TbSysRole> roles = roleMapper.selectRole(filter);
|
||||
TbSysRole role = roles.isEmpty() ? null : roles.get(0);
|
||||
// 获取当前用户的部门角色信息
|
||||
TbSysUser currentUser = LoginUtil.getCurrentUser();
|
||||
List<UserDeptRoleVO> userDeptRoles = roleMapper.selectDeptRolesByUserId(currentUser.getID());
|
||||
List<PermissionVO> roleVOs = roleMapper.selectRole(filter, userDeptRoles);
|
||||
|
||||
if (role == null) {
|
||||
if (roleVOs.isEmpty()) {
|
||||
logger.warn("未找到角色:{}", roleId);
|
||||
resultDomain.fail("未找到指定角色");
|
||||
return resultDomain;
|
||||
}
|
||||
|
||||
// 将 PermissionVO 转换为 TbSysRole
|
||||
PermissionVO roleVO = roleVOs.get(0);
|
||||
TbSysRole role = new TbSysRole();
|
||||
role.setRoleID(roleVO.getRoleID());
|
||||
role.setName(roleVO.getRoleName());
|
||||
role.setDescription(roleVO.getRoleDescription());
|
||||
|
||||
logger.info("根据ID查询角色完成:{}", roleId);
|
||||
resultDomain.success("查询成功", role);
|
||||
return resultDomain;
|
||||
@@ -291,7 +316,11 @@ public class SysRoleServiceImpl implements SysRoleService {
|
||||
return resultDomain;
|
||||
}
|
||||
|
||||
int count = roleMapper.countByRoleName(roleName, excludeId);
|
||||
// 获取当前用户的部门角色信息(用于权限过滤)
|
||||
TbSysUser currentUser = LoginUtil.getCurrentUser();
|
||||
List<UserDeptRoleVO> userDeptRoles = roleMapper.selectDeptRolesByUserId(currentUser.getID());
|
||||
|
||||
int count = roleMapper.countByRoleName(roleName, excludeId, userDeptRoles);
|
||||
boolean exists = count > 0;
|
||||
|
||||
logger.info("角色名称存在性检查完成:{},存在:{}", roleName, exists);
|
||||
|
||||
@@ -113,8 +113,9 @@ public class SysUserServiceImpl implements SysUserService {
|
||||
try {
|
||||
logger.info("开始查询所有用户");
|
||||
|
||||
List<UserDeptRoleVO> userDeptRoles = LoginUtil.getCurrentDeptRole();
|
||||
TbSysUser filter = new TbSysUser();
|
||||
List<TbSysUser> users = userMapper.selectByFilter(filter);
|
||||
List<TbSysUser> users = userMapper.selectByFilter(filter, userDeptRoles);
|
||||
|
||||
logger.info("查询所有用户完成,共找到{}个用户", users.size());
|
||||
resultDomain.success("查询成功", users);
|
||||
@@ -138,11 +139,12 @@ public class SysUserServiceImpl implements SysUserService {
|
||||
return resultDomain;
|
||||
}
|
||||
|
||||
List<UserDeptRoleVO> userDeptRoles = LoginUtil.getCurrentDeptRole();
|
||||
TbSysUser filter = new TbSysUser();
|
||||
filter.setID(userId);
|
||||
filter.setDeleted(false);
|
||||
|
||||
List<TbSysUser> users = userMapper.selectByFilter(filter);
|
||||
List<TbSysUser> users = userMapper.selectByFilter(filter, userDeptRoles);
|
||||
|
||||
if (users.isEmpty()) {
|
||||
logger.warn("未找到用户:{}", userId);
|
||||
@@ -213,7 +215,8 @@ public class SysUserServiceImpl implements SysUserService {
|
||||
// return resultDomain;
|
||||
// }
|
||||
|
||||
List<TbSysUser> users = userMapper.selectByFilter(filter);
|
||||
List<UserDeptRoleVO> userDeptRoles = LoginUtil.getCurrentDeptRole();
|
||||
List<TbSysUser> users = userMapper.selectByFilter(filter, userDeptRoles);
|
||||
|
||||
if (users.isEmpty()) {
|
||||
logger.warn("未找到符合条件的用户:{}", filter);
|
||||
@@ -232,13 +235,75 @@ public class SysUserServiceImpl implements SysUserService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<UserVO> getUserVOByFilter(TbSysUser filter) {
|
||||
ResultDomain<UserVO> resultDomain = new ResultDomain<>();
|
||||
try {
|
||||
logger.info("开始根据过滤条件查询用户VO:{}", filter);
|
||||
|
||||
if (filter == null) {
|
||||
resultDomain.fail("过滤条件不能为空");
|
||||
return resultDomain;
|
||||
}
|
||||
|
||||
List<UserDeptRoleVO> userDeptRoles = LoginUtil.getCurrentDeptRole();
|
||||
List<UserVO> userVOs = userMapper.selectUserVOByFilter(filter, userDeptRoles);
|
||||
|
||||
if (userVOs.isEmpty()) {
|
||||
logger.warn("未找到符合条件的用户:{}", filter);
|
||||
resultDomain.fail("未找到指定用户");
|
||||
return resultDomain;
|
||||
}
|
||||
|
||||
logger.info("成功查询到 {} 个用户", userVOs.size());
|
||||
resultDomain.success("查询成功", userVOs);
|
||||
return resultDomain;
|
||||
} catch (Exception e) {
|
||||
logger.error("根据过滤条件查询用户VO失败:{}", filter, e);
|
||||
resultDomain.fail("查询用户失败:" + e.getMessage());
|
||||
return resultDomain;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbSysUser> getLoginUser(TbSysUser filter) {
|
||||
ResultDomain<TbSysUser> resultDomain = new ResultDomain<>();
|
||||
TbSysUser users = userMapper.selectLoginUser(filter);
|
||||
resultDomain.success("查询成功", users);
|
||||
return resultDomain;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<TbSysUser> getUserPage(TbSysUser filter, PageParam pageParam) {
|
||||
ResultDomain<TbSysUser> resultDomain = new ResultDomain<>();
|
||||
List<TbSysUser> users = userMapper.selectUserPage(filter, pageParam);
|
||||
List<UserDeptRoleVO> userDeptRoles = LoginUtil.getCurrentDeptRole();
|
||||
List<TbSysUser> users = userMapper.selectUserPage(filter, pageParam, userDeptRoles);
|
||||
PageDomain<TbSysUser> pageDomain = new PageDomain<>();
|
||||
|
||||
int count = userMapper.countDeptUser(userDeptRoles.get(0).getDeptID());
|
||||
pageDomain.setDataList(users);
|
||||
pageDomain.setPageParam(pageParam);
|
||||
pageParam.setTotalElements(count);
|
||||
pageParam.setTotalPages((int) Math.ceil(count / pageParam.getPageSize()));
|
||||
pageDomain.setPageParam(pageParam);
|
||||
resultDomain.success("查询成功", pageDomain);
|
||||
return resultDomain;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultDomain<UserVO> getUserVOPage(TbSysUser filter, PageParam pageParam) {
|
||||
ResultDomain<UserVO> resultDomain = new ResultDomain<>();
|
||||
List<UserDeptRoleVO> userDeptRoles = LoginUtil.getCurrentDeptRole();
|
||||
List<UserVO> userVOs = userMapper.selectUserVOPage(filter, pageParam, userDeptRoles);
|
||||
PageDomain<UserVO> pageDomain = new PageDomain<>();
|
||||
|
||||
int count = userMapper.countDeptUser(userDeptRoles.get(0).getDeptID());
|
||||
pageDomain.setDataList(userVOs);
|
||||
pageDomain.setPageParam(pageParam);
|
||||
pageParam.setTotalElements(count);
|
||||
pageParam.setTotalPages((int) Math.ceil((double)count / pageParam.getPageSize()));
|
||||
pageDomain.setPageParam(pageParam);
|
||||
resultDomain.success("查询成功", pageDomain);
|
||||
return resultDomain;
|
||||
}
|
||||
@@ -503,6 +568,7 @@ public class SysUserServiceImpl implements SysUserService {
|
||||
return resultDomain;
|
||||
}
|
||||
|
||||
List<UserDeptRoleVO> userDeptRoles = LoginUtil.getCurrentDeptRole();
|
||||
TbSysUser filter = new TbSysUser();
|
||||
if (StringUtils.hasText(excludeId)) {
|
||||
filter.setID(excludeId);
|
||||
@@ -510,7 +576,7 @@ public class SysUserServiceImpl implements SysUserService {
|
||||
filter.setUsername(username);
|
||||
filter.setDeleted(false);
|
||||
|
||||
long count = userMapper.selectByFilter(filter).size();
|
||||
long count = userMapper.selectByFilter(filter, userDeptRoles).size();
|
||||
boolean exists = count > 0;
|
||||
|
||||
logger.info("用户名存在性检查完成:{},存在:{}", username, exists);
|
||||
@@ -535,6 +601,7 @@ public class SysUserServiceImpl implements SysUserService {
|
||||
return resultDomain;
|
||||
}
|
||||
|
||||
List<UserDeptRoleVO> userDeptRoles = LoginUtil.getCurrentDeptRole();
|
||||
TbSysUser filter = new TbSysUser();
|
||||
filter.setEmail(email);
|
||||
filter.setDeleted(false);
|
||||
@@ -543,7 +610,7 @@ public class SysUserServiceImpl implements SysUserService {
|
||||
filter.setID(excludeId);
|
||||
}
|
||||
|
||||
long count = userMapper.selectByFilter(filter).size();
|
||||
long count = userMapper.selectByFilter(filter, userDeptRoles).size();
|
||||
boolean exists = count > 0;
|
||||
|
||||
logger.info("邮箱存在性检查完成:{},存在:{}", email, exists);
|
||||
@@ -563,7 +630,8 @@ public class SysUserServiceImpl implements SysUserService {
|
||||
try {
|
||||
logger.info("开始搜索用户,用户名:{},邮箱:{},状态:{}", username, email, status);
|
||||
|
||||
List<TbSysUser> users = userMapper.selectUserList(username, email, status);
|
||||
List<UserDeptRoleVO> userDeptRoles = LoginUtil.getCurrentDeptRole();
|
||||
List<TbSysUser> users = userMapper.selectUserList(username, email, status, userDeptRoles);
|
||||
|
||||
logger.info("搜索用户完成,共找到{}个用户", users.size());
|
||||
resultDomain.success("搜索成功", users);
|
||||
|
||||
@@ -11,7 +11,7 @@ import org.xyzh.common.dto.user.TbSysUser;
|
||||
import org.xyzh.common.dto.user.TbSysUserInfo;
|
||||
import org.xyzh.common.redis.service.RedisService;
|
||||
import org.xyzh.common.utils.NonUtils;
|
||||
import org.xyzh.common.utils.ServletUtil;
|
||||
import org.xyzh.common.utils.ServletUtils;
|
||||
import org.xyzh.common.vo.UserDeptRoleVO;
|
||||
|
||||
/**
|
||||
@@ -48,7 +48,7 @@ public class LoginUtil {
|
||||
public static LoginDomain getCurrentLoginDomain() {
|
||||
try {
|
||||
// 从当前请求获取token
|
||||
String token = ServletUtil.getToken();
|
||||
String token = ServletUtils.getToken();
|
||||
if (NonUtils.isEmpty(token)) {
|
||||
return null;
|
||||
}
|
||||
@@ -238,6 +238,6 @@ public class LoginUtil {
|
||||
* @since 2025-10-07
|
||||
*/
|
||||
public static String getCurrentToken() {
|
||||
return ServletUtil.getToken();
|
||||
return ServletUtils.getToken();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,26 @@
|
||||
<result column="delete_time" property="deleteTime" jdbcType="TIMESTAMP"/>
|
||||
<result column="deleted" property="deleted" jdbcType="BOOLEAN"/>
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="DeptRoleResultMap" type="org.xyzh.common.dto.role.TbSysRole">
|
||||
<id column="role_id" property="roleID" jdbcType="VARCHAR"/>
|
||||
<result column="role_name" property="name" jdbcType="VARCHAR"/>
|
||||
<result column="role_description" property="description" jdbcType="VARCHAR"/>
|
||||
<result column="creator" property="creator" jdbcType="VARCHAR"/>
|
||||
<result column="updater" property="updater" 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="BOOLEAN"/>
|
||||
</resultMap>
|
||||
<!-- 部门角色VO结果映射 -->
|
||||
<resultMap id="DeptRoleVOResultMap" type="org.xyzh.common.vo.UserDeptRoleVO">
|
||||
<result column="dept_id" property="deptID" jdbcType="VARCHAR"/>
|
||||
<result column="dept_name" property="deptName" jdbcType="VARCHAR"/>
|
||||
<result column="dept_description" property="deptDescription" jdbcType="VARCHAR"/>
|
||||
<result column="role_id" property="roleID" jdbcType="VARCHAR"/>
|
||||
<result column="role_name" property="roleName" jdbcType="VARCHAR"/>
|
||||
<result column="role_description" property="roleDescription" jdbcType="VARCHAR"/>
|
||||
</resultMap>
|
||||
<!-- 基础字段 -->
|
||||
<sql id="Base_Column_List">
|
||||
id, dept_id, role_id, creator, updater,
|
||||
@@ -29,25 +48,24 @@
|
||||
</where>
|
||||
</sql>
|
||||
|
||||
<!-- selectDeptRole -->
|
||||
<!-- selectDeptRole - 查询指定部门的角色绑定(包含名称) -->
|
||||
|
||||
<select id="selectDeptRole">
|
||||
<select id="selectDeptRole" resultMap="DeptRoleVOResultMap">
|
||||
SELECT
|
||||
<include refid="Base_Column_List"/>
|
||||
FROM tb_sys_dept_role
|
||||
<include refid="Where_Clause"/>
|
||||
ORDER BY create_time DESC
|
||||
dr.dept_id,
|
||||
d.name AS dept_name,
|
||||
d.description AS dept_description,
|
||||
dr.role_id,
|
||||
r.name AS role_name,
|
||||
r.description AS role_description
|
||||
FROM tb_sys_dept_role dr
|
||||
LEFT JOIN tb_sys_dept d ON dr.dept_id = d.dept_id AND d.deleted = 0
|
||||
LEFT JOIN tb_sys_role r ON dr.role_id = r.role_id AND r.deleted = 0
|
||||
WHERE dr.deleted = 0
|
||||
AND dr.dept_id = #{deptId}
|
||||
ORDER BY dr.create_time DESC
|
||||
</select>
|
||||
|
||||
<!-- 部门角色VO结果映射 -->
|
||||
<resultMap id="DeptRoleVOResultMap" type="org.xyzh.common.vo.UserDeptRoleVO">
|
||||
<result column="dept_id" property="deptID" jdbcType="VARCHAR"/>
|
||||
<result column="dept_name" property="deptName" jdbcType="VARCHAR"/>
|
||||
<result column="dept_description" property="deptDescription" jdbcType="VARCHAR"/>
|
||||
<result column="role_id" property="roleID" jdbcType="VARCHAR"/>
|
||||
<result column="role_name" property="roleName" jdbcType="VARCHAR"/>
|
||||
<result column="role_description" property="roleDescription" jdbcType="VARCHAR"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="selectDeptRoleList" resultMap="DeptRoleVOResultMap">
|
||||
SELECT
|
||||
|
||||
@@ -15,6 +15,24 @@
|
||||
<result column="deleted" property="deleted" jdbcType="BOOLEAN"/>
|
||||
</resultMap>
|
||||
|
||||
<!-- 权限VO结果映射(用于菜单权限查询) -->
|
||||
<resultMap id="PermissionVOResultMap" type="org.xyzh.common.vo.PermissionVO">
|
||||
<id column="id" property="id" jdbcType="VARCHAR"/>
|
||||
<result column="module_id" property="moduleID" jdbcType="VARCHAR"/>
|
||||
<result column="module_name" property="moduleName" jdbcType="VARCHAR"/>
|
||||
<result column="module_description" property="moduleDescription" jdbcType="VARCHAR"/>
|
||||
<result column="permission_id" property="permissionID" jdbcType="VARCHAR"/>
|
||||
<result column="permission_name" property="name" jdbcType="VARCHAR"/>
|
||||
<result column="permission_code" property="code" jdbcType="VARCHAR"/>
|
||||
<result column="permission_description" property="description" jdbcType="VARCHAR"/>
|
||||
<result column="creator" property="creator" jdbcType="VARCHAR"/>
|
||||
<result column="updater" property="updater" 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="BOOLEAN"/>
|
||||
</resultMap>
|
||||
|
||||
<!-- 基础字段 -->
|
||||
<sql id="Base_Column_List">
|
||||
id, menu_id, permission_id, creator, updater,
|
||||
@@ -51,14 +69,29 @@
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<!-- 根据菜单ID查询权限关联列表 -->
|
||||
<select id="selectByMenuId" resultMap="BaseResultMap">
|
||||
<!-- 根据菜单ID查询权限列表(返回PermissionVO) -->
|
||||
<select id="selectByMenuId" resultMap="PermissionVOResultMap">
|
||||
SELECT
|
||||
<include refid="Base_Column_List"/>
|
||||
FROM tb_sys_menu_permission
|
||||
WHERE deleted = 0
|
||||
AND menu_id = #{menuId}
|
||||
ORDER BY create_time ASC
|
||||
mp.id,
|
||||
p.module_id,
|
||||
m.name AS module_name,
|
||||
m.description AS module_description,
|
||||
mp.permission_id,
|
||||
p.name AS permission_name,
|
||||
p.code AS permission_code,
|
||||
p.description AS permission_description,
|
||||
mp.creator,
|
||||
mp.updater,
|
||||
mp.create_time,
|
||||
mp.update_time,
|
||||
mp.delete_time,
|
||||
mp.deleted
|
||||
FROM tb_sys_menu_permission mp
|
||||
LEFT JOIN tb_sys_permission p ON mp.permission_id = p.permission_id AND p.deleted = 0
|
||||
LEFT JOIN tb_sys_module m ON p.module_id = m.module_id AND m.deleted = 0
|
||||
WHERE mp.deleted = 0
|
||||
AND mp.menu_id = #{menuId}
|
||||
ORDER BY mp.create_time ASC
|
||||
</select>
|
||||
|
||||
<!-- 根据权限ID查询菜单关联列表 -->
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
|
||||
<resultMap id="PermissionVO" type="org.xyzh.common.vo.PermissionVO">
|
||||
<id column="id" property="id" jdbcType="VARCHAR"/>
|
||||
<result column="module_id" property="moduleID" jdbcType="VARCHAR"/>
|
||||
<result column="module_name" property="moduleName" jdbcType="VARCHAR"/>
|
||||
<result column="module_description" property="moduleDescription" jdbcType="VARCHAR"/>
|
||||
<result column="permission_id" property="permissionID" jdbcType="VARCHAR"/>
|
||||
<result column="name" property="name" jdbcType="VARCHAR"/>
|
||||
<result column="code" property="code" jdbcType="VARCHAR"/>
|
||||
@@ -47,6 +50,26 @@
|
||||
<result column="description" property="description" jdbcType="VARCHAR"/>
|
||||
</resultMap>
|
||||
|
||||
<!-- 权限绑定菜单VO结果映射 -->
|
||||
<resultMap id="PermissionBindMenuVO" type="org.xyzh.common.vo.PermissionVO">
|
||||
<id column="id" property="id" jdbcType="VARCHAR"/>
|
||||
<result column="menu_id" property="menuID" jdbcType="VARCHAR"/>
|
||||
<result column="menu_name" property="menuName" jdbcType="VARCHAR"/>
|
||||
<result column="menu_url" property="menuUrl" jdbcType="VARCHAR"/>
|
||||
</resultMap>
|
||||
|
||||
<!-- 权限绑定角色VO结果映射 -->
|
||||
<resultMap id="PermissionBindRoleVO" type="org.xyzh.common.vo.PermissionVO">
|
||||
<id column="id" property="id" jdbcType="VARCHAR"/>
|
||||
<result column="role_id" property="roleID" jdbcType="VARCHAR"/>
|
||||
<result column="role_name" property="roleName" jdbcType="VARCHAR"/>
|
||||
<result column="role_description" property="roleDescription" jdbcType="VARCHAR"/>
|
||||
<result column="creator" property="creator" jdbcType="VARCHAR"/>
|
||||
<result column="creator_name" property="creatorName" jdbcType="VARCHAR"/>
|
||||
<result column="updater" property="updater" jdbcType="VARCHAR"/>
|
||||
<result column="updater_name" property="updaterName" jdbcType="VARCHAR"/>
|
||||
</resultMap>
|
||||
|
||||
<!-- 基础字段 -->
|
||||
<sql id="Base_Column_List">
|
||||
id, permission_id, name, code, description, module_id, creator, updater,
|
||||
@@ -226,13 +249,15 @@
|
||||
|
||||
<select id="selectPermissionList" resultMap="PermissionVO" >
|
||||
SELECT
|
||||
tsp.id, tsp.permission_id, tsp.name, tsp.code, tsp.description,
|
||||
tsp.id, tsp.module_id, tsp.permission_id, tsp.name, tsp.code, tsp.description,
|
||||
tsp.creator, tsp.updater,
|
||||
tsu.username as creator_name, tuu.username as updater_name,
|
||||
m.name as module_name, m.description as module_description,
|
||||
tsp.create_time, tsp.update_time, tsp.delete_time, tsp.deleted
|
||||
FROM tb_sys_permission tsp
|
||||
INNER JOIN tb_sys_user tsu ON tsp.creator = tsu.id
|
||||
LEFT JOIN tb_sys_user tuu ON tsp.updater = tuu.id
|
||||
LEFT JOIN tb_sys_module m ON tsp.module_id = m.module_id AND m.deleted = 0
|
||||
WHERE tsp.deleted = 0
|
||||
<if test="permission.name != null and permission.name != ''">
|
||||
AND tsp.name LIKE CONCAT('%', #{permission.name}, '%')
|
||||
@@ -247,13 +272,15 @@
|
||||
|
||||
<select id="selectPermissionVO" resultMap="PermissionVO" >
|
||||
SELECT
|
||||
tsp.id, tsp.permission_id, tsp.name, tsp.code, tsp.description,
|
||||
tsp.id, tsp.module_id, tsp.permission_id, tsp.name, tsp.code, tsp.description,
|
||||
tsp.creator, tsp.updater,
|
||||
tsu.username as creator_name, tuu.username as updater_name,
|
||||
m.name as module_name, m.description as module_description,
|
||||
tsp.create_time, tsp.update_time, tsp.delete_time, tsp.deleted
|
||||
FROM tb_sys_permission tsp
|
||||
INNER JOIN tb_sys_user tsu ON tsp.creator = tsu.id
|
||||
LEFT JOIN tb_sys_user tuu ON tsp.updater = tuu.id
|
||||
LEFT JOIN tb_sys_module m ON tsp.module_id = m.module_id AND m.deleted = 0
|
||||
WHERE tsp.deleted = 0
|
||||
<if test="permission.name != null and permission.name != ''">
|
||||
AND tsp.name LIKE CONCAT('%', #{permission.name}, '%')
|
||||
@@ -269,9 +296,12 @@
|
||||
|
||||
<!-- selectPermissionBindMenu -->
|
||||
|
||||
<select id="selectPermissionBindMenu" resultMap="PermissionBindMenu">
|
||||
<select id="selectPermissionBindMenu" resultMap="PermissionBindMenuVO">
|
||||
SELECT
|
||||
tsm.id, tsm.menu_id, tsm.name
|
||||
tsm.id,
|
||||
tsm.menu_id,
|
||||
tsm.name AS menu_name,
|
||||
tsm.url AS menu_url
|
||||
FROM tb_sys_menu tsm
|
||||
INNER JOIN tb_sys_menu_permission tsmp ON tsmp.menu_id = tsm.menu_id
|
||||
WHERE tsm.deleted = 0
|
||||
@@ -281,11 +311,20 @@
|
||||
</select>
|
||||
|
||||
<!-- selectPermissionBindRole -->
|
||||
<select id="selectPermissionBindRole" resultMap="PermissionBindRole">
|
||||
<select id="selectPermissionBindRole" resultMap="PermissionBindRoleVO">
|
||||
SELECT
|
||||
tsr.id, tsr.role_id, tsr.name, tsr.description
|
||||
tsr.id,
|
||||
tsr.role_id,
|
||||
tsr.name AS role_name,
|
||||
tsr.description AS role_description,
|
||||
tsr.creator,
|
||||
cu.username AS creator_name,
|
||||
tsr.updater,
|
||||
uu.username AS updater_name
|
||||
FROM tb_sys_role tsr
|
||||
INNER JOIN tb_sys_role_permission tsrp ON tsrp.role_id = tsr.role_id
|
||||
LEFT JOIN tb_sys_user cu ON tsr.creator = cu.id AND cu.deleted = 0
|
||||
LEFT JOIN tb_sys_user uu ON tsr.updater = uu.id AND uu.deleted = 0
|
||||
WHERE tsr.deleted = 0
|
||||
AND tsrp.deleted = 0
|
||||
AND tsrp.permission_id = #{permission.permissionID}
|
||||
|
||||
@@ -47,23 +47,97 @@
|
||||
</where>
|
||||
</sql>
|
||||
|
||||
<!-- selectAllRoles -->
|
||||
<!-- 权限过滤条件(基于dept_path的高效继承) -->
|
||||
<sql id="Permission_Filter">
|
||||
INNER JOIN tb_resource_permission rp ON r.role_id = rp.resource_id
|
||||
AND rp.resource_type = 5
|
||||
AND rp.deleted = 0
|
||||
AND rp.can_read = 1
|
||||
AND (
|
||||
-- 全局权限:所有用户可访问
|
||||
(rp.dept_id IS NULL AND rp.role_id IS NULL)
|
||||
<if test="userDeptRoles != null and userDeptRoles.size() > 0">
|
||||
OR EXISTS (
|
||||
SELECT 1
|
||||
FROM (
|
||||
<foreach collection="userDeptRoles" item="udr" separator=" UNION ALL ">
|
||||
SELECT #{udr.deptID} AS dept_id, #{udr.deptPath} AS dept_path, #{udr.roleID} AS role_id
|
||||
</foreach>
|
||||
) user_roles
|
||||
LEFT JOIN tb_sys_dept perm_dept ON perm_dept.dept_id = rp.dept_id AND perm_dept.deleted = 0
|
||||
WHERE
|
||||
-- 部门级权限:当前部门或父部门(通过dept_path判断继承关系)
|
||||
(rp.role_id IS NULL AND rp.dept_id IS NOT NULL
|
||||
AND user_roles.dept_path LIKE CONCAT(perm_dept.dept_path, '%'))
|
||||
-- 角色级权限:跨部门的角色权限
|
||||
OR (rp.dept_id IS NULL AND rp.role_id = user_roles.role_id)
|
||||
-- 精确权限:特定部门的特定角色
|
||||
OR (rp.dept_id = user_roles.dept_id AND rp.role_id = user_roles.role_id)
|
||||
)
|
||||
</if>
|
||||
)
|
||||
</sql>
|
||||
|
||||
<select id="selectAllRoles" resultMap="tbSysRoleResultMap">
|
||||
SELECT
|
||||
<include refid="TbSysRole_Column_List"/>
|
||||
FROM tb_sys_role
|
||||
WHERE deleted = 0
|
||||
ORDER BY role_id, create_time ASC
|
||||
<!-- 角色VO结果映射(包含创建人更新人名称) -->
|
||||
<resultMap id="RoleVOResultMap" type="org.xyzh.common.vo.PermissionVO">
|
||||
<id column="id" property="id" jdbcType="VARCHAR"/>
|
||||
<result column="role_id" property="roleID" jdbcType="VARCHAR"/>
|
||||
<result column="role_name" property="roleName" jdbcType="VARCHAR"/>
|
||||
<result column="role_description" property="roleDescription" jdbcType="VARCHAR"/>
|
||||
<result column="creator" property="creator" jdbcType="VARCHAR"/>
|
||||
<result column="creator_name" property="creatorName" jdbcType="VARCHAR"/>
|
||||
<result column="updater" property="updater" jdbcType="VARCHAR"/>
|
||||
<result column="updater_name" property="updaterName" jdbcType="VARCHAR"/>
|
||||
<result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
|
||||
<result column="update_time" property="updateTime" jdbcType="TIMESTAMP"/>
|
||||
</resultMap>
|
||||
|
||||
<!-- selectAllRoles - 添加权限过滤和VO返回 -->
|
||||
<select id="selectAllRoles" resultMap="RoleVOResultMap">
|
||||
SELECT DISTINCT
|
||||
r.id,
|
||||
r.role_id,
|
||||
r.name AS role_name,
|
||||
r.description AS role_description,
|
||||
r.creator,
|
||||
cu.username AS creator_name,
|
||||
r.updater,
|
||||
uu.username AS updater_name,
|
||||
r.create_time,
|
||||
r.update_time
|
||||
FROM tb_sys_role r
|
||||
<include refid="Permission_Filter"/>
|
||||
LEFT JOIN tb_sys_user cu ON r.creator = cu.id AND cu.deleted = 0
|
||||
LEFT JOIN tb_sys_user uu ON r.updater = uu.id AND uu.deleted = 0
|
||||
WHERE r.deleted = 0
|
||||
ORDER BY r.role_id, r.create_time ASC
|
||||
</select>
|
||||
|
||||
<!-- 根据过滤条件查询角色列表 -->
|
||||
<select id="selectRole" resultMap="tbSysRoleResultMap">
|
||||
SELECT
|
||||
<include refid="TbSysRole_Column_List"/>
|
||||
FROM tb_sys_role
|
||||
<include refid="Where_Clause"/>
|
||||
ORDER BY role_id, create_time ASC
|
||||
<!-- 根据过滤条件查询角色列表 - 添加权限过滤 -->
|
||||
<select id="selectRole" resultMap="RoleVOResultMap">
|
||||
SELECT DISTINCT
|
||||
r.id,
|
||||
r.role_id,
|
||||
r.name AS role_name,
|
||||
r.description AS role_description,
|
||||
r.creator,
|
||||
cu.username AS creator_name,
|
||||
r.updater,
|
||||
uu.username AS updater_name,
|
||||
r.create_time,
|
||||
r.update_time
|
||||
FROM tb_sys_role r
|
||||
<include refid="Permission_Filter"/>
|
||||
LEFT JOIN tb_sys_user cu ON r.creator = cu.id AND cu.deleted = 0
|
||||
LEFT JOIN tb_sys_user uu ON r.updater = uu.id AND uu.deleted = 0
|
||||
WHERE r.deleted = 0
|
||||
<if test="filter.roleID != null and filter.roleID != ''">
|
||||
AND r.role_id = #{filter.roleID}
|
||||
</if>
|
||||
<if test="filter.name != null and filter.name != ''">
|
||||
AND r.name LIKE CONCAT('%', #{filter.name}, '%')
|
||||
</if>
|
||||
ORDER BY r.role_id, r.create_time ASC
|
||||
</select>
|
||||
|
||||
<!-- 插入角色 -->
|
||||
@@ -108,35 +182,15 @@
|
||||
ORDER BY dr.create_time ASC
|
||||
</select>
|
||||
|
||||
<!-- 根据角色编码查询角色 -->
|
||||
<select id="selectByRoleCode" resultMap="tbSysRoleResultMap">
|
||||
SELECT
|
||||
<include refid="TbSysRole_Column_List"/>
|
||||
FROM tb_sys_role
|
||||
WHERE deleted = 0
|
||||
AND role_code = #{roleCode}
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<!-- 检查角色名称是否存在 -->
|
||||
<!-- 检查角色名称是否存在 - 添加权限过滤 -->
|
||||
<select id="countByRoleName" resultType="int">
|
||||
SELECT COUNT(1)
|
||||
FROM tb_sys_role
|
||||
WHERE deleted = 0
|
||||
AND name = #{roleName}
|
||||
SELECT COUNT(DISTINCT r.id)
|
||||
FROM tb_sys_role r
|
||||
<include refid="Permission_Filter"/>
|
||||
WHERE r.deleted = 0
|
||||
AND r.name = #{roleName}
|
||||
<if test="excludeId != null and excludeId != ''">
|
||||
AND id != #{excludeId}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<!-- 检查角色编码是否存在 -->
|
||||
<select id="countByRoleCode" resultType="int">
|
||||
SELECT COUNT(1)
|
||||
FROM tb_sys_role
|
||||
WHERE deleted = 0
|
||||
AND role_code = #{roleCode}
|
||||
<if test="excludeId != null and excludeId != ''">
|
||||
AND id != #{excludeId}
|
||||
AND r.id != #{excludeId}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
@@ -155,9 +209,8 @@
|
||||
|
||||
|
||||
|
||||
<!-- checkRoleExists -->
|
||||
|
||||
<select id="checkRoleExists">
|
||||
<!-- checkRoleExists - 检查角色是否存在,不需要权限过滤 -->
|
||||
<select id="checkRoleExists" resultMap="tbSysRoleResultMap">
|
||||
SELECT
|
||||
<include refid="TbSysRole_Column_List"/>
|
||||
FROM tb_sys_role
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.xyzh.system.mapper.SysLoginLogMapper">
|
||||
|
||||
<resultMap id="BaseResultMap" type="org.xyzh.common.dto.system.TbSysLoginLog">
|
||||
<id column="id" property="id" jdbcType="VARCHAR"/>
|
||||
<result column="user_id" property="userID" jdbcType="VARCHAR"/>
|
||||
<result column="username" property="username" jdbcType="VARCHAR"/>
|
||||
<result column="ip_address" property="ipAddress" jdbcType="VARCHAR"/>
|
||||
<result column="ip_source" property="ipSource" jdbcType="VARCHAR"/>
|
||||
<result column="browser" property="browser" jdbcType="VARCHAR"/>
|
||||
<result column="os" property="os" jdbcType="VARCHAR"/>
|
||||
<result column="password" property="password" jdbcType="VARCHAR"/>
|
||||
<result column="login_time" property="loginTime" jdbcType="TIMESTAMP"/>
|
||||
<result column="status" property="status" jdbcType="INTEGER"/>
|
||||
<result column="error_count" property="errorCount" jdbcType="INTEGER"/>
|
||||
<result column="message" property="message" jdbcType="VARCHAR"/>
|
||||
<result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
|
||||
</resultMap>
|
||||
|
||||
<!-- 权限过滤:通过用户的部门路径进行权限控制,superadmin可查看所有 -->
|
||||
<sql id="Permission_Filter">
|
||||
INNER JOIN tb_sys_user u ON ll.user_id = u.id AND u.deleted = 0
|
||||
INNER JOIN tb_sys_user_dept_role udr ON u.id = udr.user_id AND udr.deleted = 0
|
||||
INNER JOIN tb_sys_dept d ON udr.dept_id = d.dept_id AND d.deleted = 0
|
||||
WHERE (
|
||||
-- superadmin 可以查看所有登录日志
|
||||
EXISTS (
|
||||
SELECT 1 FROM (
|
||||
<foreach collection="userDeptRoles" item="currentRole" separator=" UNION ALL ">
|
||||
SELECT #{currentRole.deptID} AS dept_id, #{currentRole.roleID} AS role_id
|
||||
</foreach>
|
||||
) admin_check
|
||||
WHERE admin_check.dept_id = 'root_department'
|
||||
AND admin_check.role_id = 'superadmin'
|
||||
)
|
||||
-- 普通用户按部门路径过滤(本部门及子部门)
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM (
|
||||
<foreach collection="userDeptRoles" item="currentRole" separator=" UNION ALL ">
|
||||
SELECT #{currentRole.deptPath} AS user_dept_path
|
||||
</foreach>
|
||||
) user_roles
|
||||
WHERE d.dept_path LIKE CONCAT(user_roles.user_dept_path, '%')
|
||||
)
|
||||
)
|
||||
</sql>
|
||||
|
||||
<insert id="insertLoginLog" parameterType="org.xyzh.common.dto.system.TbSysLoginLog">
|
||||
INSERT INTO tb_sys_login_log (id, user_id, username, ip_address, ip_source, browser, os, password, login_time, status, error_count, message, create_time)
|
||||
VALUES (#{id}, #{userID}, #{username}, #{ipAddress}, #{ipSource}, #{browser}, #{os}, #{password}, #{loginTime, jdbcType=TIMESTAMP}, #{status}, #{errorCount}, #{message}, now());
|
||||
</insert>
|
||||
|
||||
<!-- 查询登录日志列表(带权限过滤) -->
|
||||
<select id="selectLoginLogList" resultMap="BaseResultMap">
|
||||
SELECT DISTINCT ll.*
|
||||
FROM tb_sys_login_log ll
|
||||
<include refid="Permission_Filter"/>
|
||||
<if test="loginLog.userID != null and loginLog.userID != ''">
|
||||
AND ll.user_id = #{loginLog.userID}
|
||||
</if>
|
||||
<if test="loginLog.username != null and loginLog.username != ''">
|
||||
AND ll.username LIKE CONCAT('%', #{loginLog.username}, '%')
|
||||
</if>
|
||||
<if test="loginLog.ipAddress != null and loginLog.ipAddress != ''">
|
||||
AND ll.ip_address = #{loginLog.ipAddress}
|
||||
</if>
|
||||
<if test="loginLog.status != null">
|
||||
AND ll.status = #{loginLog.status}
|
||||
</if>
|
||||
<if test="loginLog.browser != null and loginLog.browser != ''">
|
||||
AND ll.browser LIKE CONCAT('%', #{loginLog.browser}, '%')
|
||||
</if>
|
||||
<if test="loginLog.os != null and loginLog.os != ''">
|
||||
AND ll.os LIKE CONCAT('%', #{loginLog.os}, '%')
|
||||
</if>
|
||||
ORDER BY ll.login_time DESC
|
||||
</select>
|
||||
|
||||
<!-- 分页查询登录日志列表(带权限过滤) -->
|
||||
<select id="selectLoginLogPage" resultMap="BaseResultMap">
|
||||
SELECT DISTINCT ll.*
|
||||
FROM tb_sys_login_log ll
|
||||
<include refid="Permission_Filter"/>
|
||||
<if test="loginLog.userID != null and loginLog.userID != ''">
|
||||
AND ll.user_id = #{loginLog.userID}
|
||||
</if>
|
||||
<if test="loginLog.username != null and loginLog.username != ''">
|
||||
AND ll.username LIKE CONCAT('%', #{loginLog.username}, '%')
|
||||
</if>
|
||||
<if test="loginLog.ipAddress != null and loginLog.ipAddress != ''">
|
||||
AND ll.ip_address = #{loginLog.ipAddress}
|
||||
</if>
|
||||
<if test="loginLog.status != null">
|
||||
AND ll.status = #{loginLog.status}
|
||||
</if>
|
||||
<if test="loginLog.browser != null and loginLog.browser != ''">
|
||||
AND ll.browser LIKE CONCAT('%', #{loginLog.browser}, '%')
|
||||
</if>
|
||||
<if test="loginLog.os != null and loginLog.os != ''">
|
||||
AND ll.os LIKE CONCAT('%', #{loginLog.os}, '%')
|
||||
</if>
|
||||
ORDER BY ll.login_time DESC
|
||||
LIMIT #{pageParam.pageSize} OFFSET #{pageParam.offset}
|
||||
</select>
|
||||
|
||||
<!-- 统计登录日志数量(带权限过滤) -->
|
||||
<select id="countLoginLog" resultType="int">
|
||||
SELECT COUNT(DISTINCT ll.id)
|
||||
FROM tb_sys_login_log ll
|
||||
<include refid="Permission_Filter"/>
|
||||
<if test="loginLog.userID != null and loginLog.userID != ''">
|
||||
AND ll.user_id = #{loginLog.userID}
|
||||
</if>
|
||||
<if test="loginLog.username != null and loginLog.username != ''">
|
||||
AND ll.username LIKE CONCAT('%', #{loginLog.username}, '%')
|
||||
</if>
|
||||
<if test="loginLog.ipAddress != null and loginLog.ipAddress != ''">
|
||||
AND ll.ip_address = #{loginLog.ipAddress}
|
||||
</if>
|
||||
<if test="loginLog.status != null">
|
||||
AND ll.status = #{loginLog.status}
|
||||
</if>
|
||||
<if test="loginLog.browser != null and loginLog.browser != ''">
|
||||
AND ll.browser LIKE CONCAT('%', #{loginLog.browser}, '%')
|
||||
</if>
|
||||
<if test="loginLog.os != null and loginLog.os != ''">
|
||||
AND ll.os LIKE CONCAT('%', #{loginLog.os}, '%')
|
||||
</if>
|
||||
</select>
|
||||
</mapper>
|
||||
@@ -31,37 +31,99 @@
|
||||
browser, os, status, error_message, execute_time, create_time
|
||||
</sql>
|
||||
|
||||
<!-- 通用条件 -->
|
||||
<sql id="Where_Clause">
|
||||
<where>
|
||||
<if test="userID != null and userID != ''">
|
||||
AND user_id = #{userID}
|
||||
</if>
|
||||
<if test="username != null and username != ''">
|
||||
AND username LIKE CONCAT('%', #{username}, '%')
|
||||
</if>
|
||||
<if test="module != null and module != ''">
|
||||
AND module = #{module}
|
||||
</if>
|
||||
<if test="operation != null and operation != ''">
|
||||
AND operation = #{operation}
|
||||
</if>
|
||||
<if test="status != null">
|
||||
AND status = #{status}
|
||||
</if>
|
||||
<if test="ipAddress != null and ipAddress != ''">
|
||||
AND ip_address = #{ipAddress}
|
||||
</if>
|
||||
</where>
|
||||
<!-- 权限过滤:通过用户的部门路径进行权限控制,superadmin可查看所有 -->
|
||||
<sql id="Permission_Filter">
|
||||
INNER JOIN tb_sys_user u ON ol.user_id = u.id AND u.deleted = 0
|
||||
INNER JOIN tb_sys_user_dept_role udr ON u.id = udr.user_id AND udr.deleted = 0
|
||||
INNER JOIN tb_sys_dept d ON udr.dept_id = d.dept_id AND d.deleted = 0
|
||||
WHERE (
|
||||
-- superadmin 可以查看所有操作日志
|
||||
EXISTS (
|
||||
SELECT 1 FROM (
|
||||
<foreach collection="userDeptRoles" item="currentRole" separator=" UNION ALL ">
|
||||
SELECT #{currentRole.deptID} AS dept_id, #{currentRole.roleID} AS role_id
|
||||
</foreach>
|
||||
) admin_check
|
||||
WHERE admin_check.dept_id = 'root_department'
|
||||
AND admin_check.role_id = 'superadmin'
|
||||
)
|
||||
-- 普通用户按部门路径过滤(本部门及子部门)
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM (
|
||||
<foreach collection="userDeptRoles" item="currentRole" separator=" UNION ALL ">
|
||||
SELECT #{currentRole.deptPath} AS user_dept_path
|
||||
</foreach>
|
||||
) user_roles
|
||||
WHERE d.dept_path LIKE CONCAT(user_roles.user_dept_path, '%')
|
||||
)
|
||||
)
|
||||
</sql>
|
||||
|
||||
<!-- selectSysOperationLogs -->
|
||||
<select id="selectSysOperationLogs" resultMap="BaseResultMap">
|
||||
SELECT
|
||||
<include refid="Base_Column_List"/>
|
||||
FROM tb_sys_operation_log
|
||||
<!-- 通用条件 -->
|
||||
<sql id="Where_Clause">
|
||||
<if test="operationLog.userID != null and operationLog.userID != ''">
|
||||
AND ol.user_id = #{operationLog.userID}
|
||||
</if>
|
||||
<if test="operationLog.username != null and operationLog.username != ''">
|
||||
AND ol.username LIKE CONCAT('%', #{operationLog.username}, '%')
|
||||
</if>
|
||||
<if test="operationLog.module != null and operationLog.module != ''">
|
||||
AND ol.module LIKE CONCAT('%', #{operationLog.module}, '%')
|
||||
</if>
|
||||
<if test="operationLog.operation != null and operationLog.operation != ''">
|
||||
AND ol.operation = #{operationLog.operation}
|
||||
</if>
|
||||
<if test="operationLog.status != null">
|
||||
AND ol.status = #{operationLog.status}
|
||||
</if>
|
||||
<if test="operationLog.ipAddress != null and operationLog.ipAddress != ''">
|
||||
AND ol.ip_address = #{operationLog.ipAddress}
|
||||
</if>
|
||||
<if test="operationLog.requestUrl != null and operationLog.requestUrl != ''">
|
||||
AND ol.request_url LIKE CONCAT('%', #{operationLog.requestUrl}, '%')
|
||||
</if>
|
||||
</sql>
|
||||
|
||||
<!-- 插入操作日志 -->
|
||||
<insert id="insertOperationLog" parameterType="org.xyzh.common.dto.system.TbSysOperationLog">
|
||||
INSERT INTO tb_sys_operation_log (
|
||||
id, user_id, username, module, operation, method,
|
||||
request_url, request_method, request_params, response_data,
|
||||
ip_address, ip_source, browser, os, status,
|
||||
error_message, execute_time, create_time
|
||||
) VALUES (
|
||||
#{id}, #{userID}, #{username}, #{module}, #{operation}, #{method},
|
||||
#{requestUrl}, #{requestMethod}, #{requestParams}, #{responseData},
|
||||
#{ipAddress}, #{ipSource}, #{browser}, #{os}, #{status},
|
||||
#{errorMessage}, #{executeTime}, #{createTime, jdbcType=TIMESTAMP}
|
||||
)
|
||||
</insert>
|
||||
|
||||
<!-- 查询操作日志列表(带权限过滤) -->
|
||||
<select id="selectOperationLogList" resultMap="BaseResultMap">
|
||||
SELECT DISTINCT ol.*
|
||||
FROM tb_sys_operation_log ol
|
||||
<include refid="Permission_Filter"/>
|
||||
<include refid="Where_Clause"/>
|
||||
ORDER BY ol.create_time DESC
|
||||
</select>
|
||||
|
||||
<!-- 分页查询操作日志列表(带权限过滤) -->
|
||||
<select id="selectOperationLogPage" resultMap="BaseResultMap">
|
||||
SELECT DISTINCT ol.*
|
||||
FROM tb_sys_operation_log ol
|
||||
<include refid="Permission_Filter"/>
|
||||
<include refid="Where_Clause"/>
|
||||
ORDER BY ol.create_time DESC
|
||||
LIMIT #{pageParam.pageSize} OFFSET #{pageParam.offset}
|
||||
</select>
|
||||
|
||||
<!-- 统计操作日志数量(带权限过滤) -->
|
||||
<select id="countOperationLog" resultType="int">
|
||||
SELECT COUNT(DISTINCT ol.id)
|
||||
FROM tb_sys_operation_log ol
|
||||
<include refid="Permission_Filter"/>
|
||||
<include refid="Where_Clause"/>
|
||||
ORDER BY create_time DESC
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -33,11 +33,20 @@
|
||||
<result column="deleted" property="deleted" jdbcType="INTEGER"/>
|
||||
</resultMap>
|
||||
<resultMap id="UserInfoTotalResultMap" type="org.xyzh.common.vo.UserVO">
|
||||
<id column="id" property="id" jdbcType="VARCHAR"/>
|
||||
<result column="user_id" property="userID" jdbcType="VARCHAR"/>
|
||||
<result column="username" property="username" jdbcType="VARCHAR"/>
|
||||
<result column="avatar" property="avatar" jdbcType="VARCHAR"/>
|
||||
<result column="gender" property="gender" jdbcType="INTEGER"/>
|
||||
<result column="phone" property="phone" jdbcType="VARCHAR"/>
|
||||
<result column="email" property="email" jdbcType="VARCHAR"/>
|
||||
<result column="wechat_id" property="wechatID" jdbcType="VARCHAR"/>
|
||||
<result column="status" property="status" 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="dept_id" property="deptID" jdbcType="VARCHAR"/>
|
||||
<result column="parent_id" property="parentID" jdbcType="VARCHAR"/>
|
||||
<result column="dept_name" property="deptName" jdbcType="VARCHAR"/>
|
||||
<result column="role_name" property="roleName" jdbcType="VARCHAR"/>
|
||||
<result column="level" property="level" jdbcType="INTEGER"/>
|
||||
@@ -108,6 +117,31 @@
|
||||
</where>
|
||||
</sql>
|
||||
|
||||
<!-- 权限过滤条件(基于dept_path的用户权限过滤,superadmin可查看所有) -->
|
||||
<sql id="Permission_Filter">
|
||||
INNER JOIN tb_sys_user_dept_role udr ON u.id = udr.user_id AND udr.deleted = 0
|
||||
INNER JOIN tb_sys_dept d ON udr.dept_id = d.dept_id AND d.deleted = 0
|
||||
WHERE (
|
||||
EXISTS (
|
||||
SELECT 1 FROM (
|
||||
<foreach collection="userDeptRoles" item="currentRole" separator=" UNION ALL ">
|
||||
SELECT #{currentRole.deptID} AS dept_id, #{currentRole.roleID} AS role_id
|
||||
</foreach>
|
||||
) admin_check
|
||||
WHERE admin_check.dept_id = 'root_department'
|
||||
AND admin_check.role_id = 'superadmin'
|
||||
)
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM (
|
||||
<foreach collection="userDeptRoles" item="currentRole" separator=" UNION ALL ">
|
||||
SELECT #{currentRole.deptPath} AS user_dept_path
|
||||
</foreach>
|
||||
) user_roles
|
||||
WHERE d.dept_path LIKE CONCAT(user_roles.user_dept_path, '%')
|
||||
)
|
||||
)
|
||||
</sql>
|
||||
|
||||
<!-- 根据用户名查询用户 -->
|
||||
<select id="selectByUsername" resultMap="BaseResultMap">
|
||||
SELECT
|
||||
@@ -138,50 +172,223 @@
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<!-- 根据过滤条件查询用户 -->
|
||||
<!-- 根据过滤条件查询用户(包含权限过滤) -->
|
||||
<select id="selectByFilter" resultMap="BaseResultMap">
|
||||
SELECT
|
||||
<include refid="Base_Column_List"/>
|
||||
FROM tb_sys_user
|
||||
<where>
|
||||
deleted = 0
|
||||
<if test="filter.id != null and filter.id != ''">
|
||||
AND id = #{filter.id}
|
||||
</if>
|
||||
<if test="filter.username != null and filter.username != ''">
|
||||
AND username = #{filter.username}
|
||||
</if>
|
||||
<if test="filter.email != null and filter.email != ''">
|
||||
AND email = #{filter.email}
|
||||
</if>
|
||||
<if test="filter.phone != null and filter.phone != ''">
|
||||
AND phone = #{filter.phone}
|
||||
</if>
|
||||
<if test="filter.status != null">
|
||||
AND status = #{filter.status}
|
||||
</if>
|
||||
<if test="filter.wechatID != null and filter.wechatID != ''">
|
||||
AND wechat_id = #{filter.wechatID}
|
||||
</if>
|
||||
</where>
|
||||
SELECT DISTINCT u.*
|
||||
FROM tb_sys_user u
|
||||
<include refid="Permission_Filter"/>
|
||||
AND u.deleted = 0
|
||||
<if test="filter.id != null and filter.id != ''">
|
||||
AND u.id = #{filter.id}
|
||||
</if>
|
||||
<if test="filter.username != null and filter.username != ''">
|
||||
AND u.username = #{filter.username}
|
||||
</if>
|
||||
<if test="filter.email != null and filter.email != ''">
|
||||
AND u.email = #{filter.email}
|
||||
</if>
|
||||
<if test="filter.phone != null and filter.phone != ''">
|
||||
AND u.phone = #{filter.phone}
|
||||
</if>
|
||||
<if test="filter.status != null">
|
||||
AND u.status = #{filter.status}
|
||||
</if>
|
||||
<if test="filter.wechatID != null and filter.wechatID != ''">
|
||||
AND u.wechat_id = #{filter.wechatID}
|
||||
</if>
|
||||
ORDER BY u.create_time DESC
|
||||
</select>
|
||||
|
||||
<!-- 查询用户列表 -->
|
||||
<!-- 根据过滤条件查询用户VO列表(包含userinfo和deptrole信息,包含权限过滤) -->
|
||||
<select id="selectUserVOByFilter" resultMap="UserInfoTotalResultMap">
|
||||
SELECT DISTINCT
|
||||
u.id,
|
||||
u.username,
|
||||
u.email,
|
||||
u.phone,
|
||||
u.wechat_id,
|
||||
u.status,
|
||||
ui.user_id,
|
||||
ui.avatar,
|
||||
ui.gender,
|
||||
ui.family_name,
|
||||
ui.given_name,
|
||||
ui.full_name,
|
||||
ui.level,
|
||||
ui.id_card,
|
||||
ui.address,
|
||||
udr.dept_id,
|
||||
d.parent_id,
|
||||
GROUP_CONCAT(DISTINCT d.name ORDER BY d.name SEPARATOR ', ') as dept_name,
|
||||
GROUP_CONCAT(DISTINCT r.name ORDER BY r.name SEPARATOR ', ') as role_name,
|
||||
u.create_time,
|
||||
u.update_time
|
||||
FROM tb_sys_user u
|
||||
LEFT JOIN tb_sys_user_info ui ON u.id = ui.user_id AND ui.deleted = 0
|
||||
INNER JOIN tb_sys_user_dept_role udr ON u.id = udr.user_id AND udr.deleted = 0
|
||||
INNER JOIN tb_sys_dept d ON udr.dept_id = d.dept_id AND d.deleted = 0
|
||||
LEFT JOIN tb_sys_role r ON udr.role_id = r.role_id AND r.deleted = 0
|
||||
WHERE (
|
||||
EXISTS (
|
||||
SELECT 1 FROM (
|
||||
<foreach collection="userDeptRoles" item="currentRole" separator=" UNION ALL ">
|
||||
SELECT #{currentRole.deptID} AS dept_id, #{currentRole.roleID} AS role_id
|
||||
</foreach>
|
||||
) admin_check
|
||||
WHERE admin_check.dept_id = 'root_department'
|
||||
AND admin_check.role_id = 'superadmin'
|
||||
)
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM (
|
||||
<foreach collection="userDeptRoles" item="currentRole" separator=" UNION ALL ">
|
||||
SELECT #{currentRole.deptPath} AS user_dept_path
|
||||
</foreach>
|
||||
) user_roles
|
||||
WHERE d.dept_path LIKE CONCAT(user_roles.user_dept_path, '%')
|
||||
)
|
||||
)
|
||||
AND u.deleted = 0
|
||||
<if test="filter.id != null and filter.id != ''">
|
||||
AND u.id = #{filter.id}
|
||||
</if>
|
||||
<if test="filter.username != null and filter.username != ''">
|
||||
AND u.username LIKE CONCAT('%', #{filter.username}, '%')
|
||||
</if>
|
||||
<if test="filter.email != null and filter.email != ''">
|
||||
AND u.email LIKE CONCAT('%', #{filter.email}, '%')
|
||||
</if>
|
||||
<if test="filter.phone != null and filter.phone != ''">
|
||||
AND u.phone = #{filter.phone}
|
||||
</if>
|
||||
<if test="filter.status != null">
|
||||
AND u.status = #{filter.status}
|
||||
</if>
|
||||
<if test="filter.wechatID != null and filter.wechatID != ''">
|
||||
AND u.wechat_id = #{filter.wechatID}
|
||||
</if>
|
||||
GROUP BY u.id, u.username, u.email, u.phone, u.wechat_id, u.status,
|
||||
ui.user_id, ui.avatar, ui.gender, ui.family_name, ui.given_name,
|
||||
ui.full_name, ui.level, ui.id_card, ui.address, udr.dept_id, d.parent_id, u.create_time, u.update_time
|
||||
ORDER BY u.create_time DESC
|
||||
</select>
|
||||
|
||||
<!-- 查询用户列表(包含权限过滤) -->
|
||||
<select id="selectUserList" resultMap="BaseResultMap">
|
||||
SELECT
|
||||
<include refid="Base_Column_List"/>
|
||||
FROM tb_sys_user
|
||||
<include refid="Where_Clause"/>
|
||||
ORDER BY create_time DESC
|
||||
SELECT DISTINCT u.*
|
||||
FROM tb_sys_user u
|
||||
<include refid="Permission_Filter"/>
|
||||
AND u.deleted = 0
|
||||
<if test="username != null and username != ''">
|
||||
AND u.username LIKE CONCAT('%', #{username}, '%')
|
||||
</if>
|
||||
<if test="email != null and email != ''">
|
||||
AND u.email LIKE CONCAT('%', #{email}, '%')
|
||||
</if>
|
||||
<if test="status != null and status != ''">
|
||||
AND u.status = #{status}
|
||||
</if>
|
||||
ORDER BY u.create_time DESC
|
||||
</select>
|
||||
|
||||
<!-- 查询用户列表(分页) -->
|
||||
<!-- 查询用户列表(分页,包含权限过滤) -->
|
||||
<select id="selectUserPage" resultMap="BaseResultMap">
|
||||
SELECT
|
||||
<include refid="Base_Column_List"/>
|
||||
FROM tb_sys_user
|
||||
<include refid="Filter_Clause"/>
|
||||
ORDER BY create_time DESC
|
||||
SELECT DISTINCT u.*
|
||||
FROM tb_sys_user u
|
||||
<include refid="Permission_Filter"/>
|
||||
AND u.deleted = 0
|
||||
<if test="filter.id != null and filter.id != ''">
|
||||
AND u.id = #{filter.id}
|
||||
</if>
|
||||
<if test="filter.username != null and filter.username != ''">
|
||||
AND u.username = #{filter.username}
|
||||
</if>
|
||||
<if test="filter.email != null and filter.email != ''">
|
||||
AND u.email = #{filter.email}
|
||||
</if>
|
||||
<if test="filter.phone != null and filter.phone != ''">
|
||||
AND u.phone = #{filter.phone}
|
||||
</if>
|
||||
<if test="filter.status != null">
|
||||
AND u.status = #{filter.status}
|
||||
</if>
|
||||
<if test="filter.wechatID != null and filter.wechatID != ''">
|
||||
AND u.wechat_id = #{filter.wechatID}
|
||||
</if>
|
||||
ORDER BY u.create_time DESC
|
||||
LIMIT #{pageParam.pageSize} OFFSET #{pageParam.offset}
|
||||
</select>
|
||||
|
||||
<!-- 查询用户VO列表(分页,包含userinfo和deptrole信息,包含权限过滤) -->
|
||||
<select id="selectUserVOPage" resultMap="UserInfoTotalResultMap">
|
||||
SELECT DISTINCT
|
||||
u.id,
|
||||
u.username,
|
||||
u.email,
|
||||
u.phone,
|
||||
u.wechat_id,
|
||||
u.status,
|
||||
ui.user_id,
|
||||
ui.avatar,
|
||||
ui.gender,
|
||||
ui.family_name,
|
||||
ui.given_name,
|
||||
ui.full_name,
|
||||
ui.level,
|
||||
ui.id_card,
|
||||
ui.address,
|
||||
udr.dept_id,
|
||||
d.parent_id,
|
||||
GROUP_CONCAT(DISTINCT d.name ORDER BY d.name SEPARATOR ', ') as dept_name,
|
||||
GROUP_CONCAT(DISTINCT r.name ORDER BY r.name SEPARATOR ', ') as role_name,
|
||||
u.create_time,
|
||||
u.update_time
|
||||
FROM tb_sys_user u
|
||||
LEFT JOIN tb_sys_user_info ui ON u.id = ui.user_id AND ui.deleted = 0
|
||||
INNER JOIN tb_sys_user_dept_role udr ON u.id = udr.user_id AND udr.deleted = 0
|
||||
INNER JOIN tb_sys_dept d ON udr.dept_id = d.dept_id AND d.deleted = 0
|
||||
LEFT JOIN tb_sys_role r ON udr.role_id = r.role_id AND r.deleted = 0
|
||||
WHERE (
|
||||
EXISTS (
|
||||
SELECT 1 FROM (
|
||||
<foreach collection="userDeptRoles" item="currentRole" separator=" UNION ALL ">
|
||||
SELECT #{currentRole.deptID} AS dept_id, #{currentRole.roleID} AS role_id
|
||||
</foreach>
|
||||
) admin_check
|
||||
WHERE admin_check.dept_id = 'root_department'
|
||||
AND admin_check.role_id = 'superadmin'
|
||||
)
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM (
|
||||
<foreach collection="userDeptRoles" item="currentRole" separator=" UNION ALL ">
|
||||
SELECT #{currentRole.deptPath} AS user_dept_path
|
||||
</foreach>
|
||||
) user_roles
|
||||
WHERE d.dept_path LIKE CONCAT(user_roles.user_dept_path, '%')
|
||||
)
|
||||
)
|
||||
AND u.deleted = 0
|
||||
<if test="filter.id != null and filter.id != ''">
|
||||
AND u.id = #{filter.id}
|
||||
</if>
|
||||
<if test="filter.username != null and filter.username != ''">
|
||||
AND u.username LIKE CONCAT('%', #{filter.username}, '%')
|
||||
</if>
|
||||
<if test="filter.email != null and filter.email != ''">
|
||||
AND u.email LIKE CONCAT('%', #{filter.email}, '%')
|
||||
</if>
|
||||
<if test="filter.phone != null and filter.phone != ''">
|
||||
AND u.phone = #{filter.phone}
|
||||
</if>
|
||||
<if test="filter.status != null">
|
||||
AND u.status = #{filter.status}
|
||||
</if>
|
||||
<if test="filter.wechatID != null and filter.wechatID != ''">
|
||||
AND u.wechat_id = #{filter.wechatID}
|
||||
</if>
|
||||
GROUP BY u.id, u.username, u.email, u.phone, u.wechat_id, u.status,
|
||||
ui.user_id, ui.avatar, ui.gender, ui.family_name, ui.given_name,
|
||||
ui.full_name, ui.level, ui.id_card, ui.address, udr.dept_id, d.parent_id, u.create_time, u.update_time
|
||||
ORDER BY u.create_time DESC
|
||||
LIMIT #{pageParam.pageSize} OFFSET #{pageParam.offset}
|
||||
</select>
|
||||
|
||||
@@ -352,4 +559,26 @@
|
||||
WHERE tsui.user_id = #{userId}
|
||||
AND tsui.deleted = 0
|
||||
</select>
|
||||
|
||||
<!-- countDeptUser - 递归统计部门及其子部门的用户数量 -->
|
||||
<select id="countDeptUser" resultType="int">
|
||||
SELECT COUNT(DISTINCT tudr.user_id)
|
||||
FROM tb_sys_user_dept_role tudr
|
||||
INNER JOIN tb_sys_dept d ON tudr.dept_id = d.dept_id AND d.deleted = 0
|
||||
INNER JOIN tb_sys_user u ON tudr.user_id = u.id AND u.deleted = 0
|
||||
WHERE tudr.deleted = 0
|
||||
AND d.dept_path LIKE CONCAT(
|
||||
(SELECT dept_path FROM tb_sys_dept WHERE dept_id = #{deptId} AND deleted = 0),
|
||||
'%'
|
||||
)
|
||||
</select>
|
||||
|
||||
<!-- selectLoginUser -->
|
||||
|
||||
<select id="selectLoginUser">
|
||||
SELECT DISTINCT u.*
|
||||
FROM tb_sys_user u
|
||||
<include refid="Filter_Clause"/>
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
||||
Reference in New Issue
Block a user