refactor: 根包由 com.bestsch.bschclassmanage 重命名为 com.yunhai.bschclassmanage
- git mv src/main/java/com/bestsch/bschclassmanage -> src/main/java/com/yunhai/bschclassmanage - 255 个 Java 文件的 package/import 同步替换为 com.yunhai.bschclassmanage - pom.xml 项目 groupId 设为 com.yunhai(与外部依赖 com.bestsch:bsch-* 无关,未改动) - IDE 缓存 workspace.xml 路径同步更新(外部依赖坐标 com.bestsch:bsch-* 保持不动)
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
package com.yunhai.bschclassmanage.aspect;
|
||||
|
||||
import com.yunhai.bschclassmanage.model.tool.UserSysRole;
|
||||
import com.yunhai.bschclassmanage.utils.OtherUtil;
|
||||
import com.yunhai.bschclassmanage.utils.UserContext;
|
||||
import com.yunhai.platform.utils.model.BoaUser;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@Aspect
|
||||
@Component
|
||||
@Order(1)
|
||||
public class ControllerUserContextAspect {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ControllerUserContextAspect.class);
|
||||
|
||||
@Around("execution(* com.yunhai.bschclassmanage.controller..*.*(..))")
|
||||
public Object setUserContext(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
// 1. 从方法参数中提取 BoaUser 和 UserSysRole
|
||||
Object[] args = joinPoint.getArgs();
|
||||
BoaUser boaUser = null;
|
||||
UserSysRole userSysRole = null;
|
||||
|
||||
for (Object arg : args) {
|
||||
if (arg instanceof BoaUser) {
|
||||
boaUser = (BoaUser) arg;
|
||||
} else if (arg instanceof UserSysRole) {
|
||||
userSysRole = (UserSysRole) arg;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 填充 UserContext
|
||||
populateUserContext(boaUser, userSysRole);
|
||||
|
||||
try {
|
||||
return joinPoint.proceed();
|
||||
} finally {
|
||||
UserContext.clear();
|
||||
log.debug("UserContext cleared for {}", joinPoint.getSignature().toShortString());
|
||||
}
|
||||
}
|
||||
|
||||
private HttpServletRequest getCurrentHttpRequest() {
|
||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
return attributes != null ? attributes.getRequest() : null;
|
||||
}
|
||||
|
||||
private void populateUserContext(BoaUser boaUser, UserSysRole userSysRole) {
|
||||
if (boaUser != null) {
|
||||
UserContext.setUserId(boaUser.getId());
|
||||
UserContext.setUserName(boaUser.getName() != null ? boaUser.getName() : "unknown");
|
||||
log.debug("UserContext set from parameter/session: id={}, name={}", boaUser.getId(), boaUser.getName());
|
||||
} else {
|
||||
UserContext.setUserName("anonymous");
|
||||
log.warn("No BoaUser found, using anonymous");
|
||||
}
|
||||
|
||||
if (userSysRole != null) {
|
||||
UserContext.setRoleId(userSysRole.getRoleId());
|
||||
UserContext.setSchId(userSysRole.getSchId());
|
||||
log.debug("UserContext set roleId={}, schId={}", userSysRole.getRoleId(), userSysRole.getSchId());
|
||||
}
|
||||
|
||||
String clientIp = OtherUtil.getClientIp();
|
||||
UserContext.setIp(clientIp);
|
||||
log.debug("Client IP set: {}", clientIp);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
package com.yunhai.bschclassmanage.aspect;
|
||||
|
||||
import com.yunhai.bschclassmanage.annotation.OperationLog;
|
||||
import com.yunhai.bschclassmanage.entity.OperationLogRecord;
|
||||
import com.yunhai.bschclassmanage.service.ILogService;
|
||||
import com.yunhai.bschclassmanage.utils.LogContextHolder;
|
||||
import com.yunhai.bschclassmanage.utils.UserContext;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.DefaultParameterNameDiscoverer;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.ExpressionParser;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.lang.reflect.Method;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Aspect
|
||||
@Component
|
||||
@Order(2)
|
||||
public class OperationLogAspect {
|
||||
|
||||
@Autowired
|
||||
private ILogService logService;
|
||||
|
||||
private final ExpressionParser parser = new SpelExpressionParser();
|
||||
private final DefaultParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer();
|
||||
|
||||
@Around("@annotation(operationLog)")
|
||||
public Object logAround(ProceedingJoinPoint joinPoint, OperationLog operationLog) throws Throwable {
|
||||
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||
Method method = signature.getMethod();
|
||||
Object[] args = joinPoint.getArgs();
|
||||
|
||||
// 从 UserContext 获取用户信息(由 ControllerAspect 设置)
|
||||
String ip = UserContext.getIp();
|
||||
String operator = UserContext.getUserName();
|
||||
Integer userId = UserContext.getUserId();
|
||||
Integer schId = UserContext.getSchId();
|
||||
|
||||
Object result = null;
|
||||
String content = null;
|
||||
|
||||
try {
|
||||
// 1. 先执行业务方法(内部会调用 LogContextHolder.setDescription)
|
||||
result = joinPoint.proceed();
|
||||
|
||||
// 2. 业务方法执行后,尝试获取动态描述
|
||||
String dynamicDesc = LogContextHolder.getDescription();
|
||||
if (StringUtils.hasText(dynamicDesc)) {
|
||||
content = dynamicDesc;
|
||||
} else {
|
||||
// 无动态描述,则解析 SpEL 模板(此时 result 可用于 #result)
|
||||
content = resolveDescription(operationLog.description(), method, args, result);
|
||||
}
|
||||
return result;
|
||||
|
||||
} finally {
|
||||
// 3. 清理 ThreadLocal(在业务方法执行后)
|
||||
LogContextHolder.clear();
|
||||
|
||||
// 4. 保存日志(确保 content 非空)
|
||||
if (content != null) {
|
||||
saveLogAsync(ip, operator, userId, schId, operationLog.module(), content);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析日志描述:优先从 ThreadLocal 获取动态描述,否则解析 SpEL 模板
|
||||
*/
|
||||
private String resolveDescription(String template, Method method, Object[] args, Object result) {
|
||||
// 优先从 ThreadLocal 获取动态描述
|
||||
String dynamicDesc = LogContextHolder.getDescription();
|
||||
if (StringUtils.hasText(dynamicDesc)) {
|
||||
return dynamicDesc;
|
||||
}
|
||||
|
||||
// 没有动态描述,则解析 SpEL
|
||||
if (!StringUtils.hasText(template)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
EvaluationContext context = new StandardEvaluationContext();
|
||||
String[] paramNames = discoverer.getParameterNames(method);
|
||||
if (paramNames != null) {
|
||||
for (int i = 0; i < paramNames.length; i++) {
|
||||
context.setVariable(paramNames[i], args[i]);
|
||||
}
|
||||
}
|
||||
if (result != null) {
|
||||
context.setVariable("result", result);
|
||||
}
|
||||
|
||||
org.springframework.expression.common.TemplateParserContext parserContext =
|
||||
new org.springframework.expression.common.TemplateParserContext("#{", "}");
|
||||
Expression exp = parser.parseExpression(template, parserContext);
|
||||
return exp.getValue(context, String.class);
|
||||
}
|
||||
|
||||
|
||||
@Async
|
||||
public void saveLogAsync(String ip,String operator,Integer operatorId,Integer schId, String module, String content) {
|
||||
try { OperationLogRecord log = new OperationLogRecord();
|
||||
log.setOperator(operator);
|
||||
log.setOperatorId(operatorId);
|
||||
log.setIp(ip);
|
||||
log.setSchId(schId);
|
||||
log.setModule(module);
|
||||
log.setContent(content);
|
||||
log.setOperateTime(LocalDateTime.now());
|
||||
logService.save(log);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace(); // 生产环境建议用日志输出
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user