feat: 重构项目结构并新增微信小程序认证模块

This commit is contained in:
Ray.Hao
2026-03-24 07:52:05 +08:00
parent 465e63c99d
commit 8188c82c3d
158 changed files with 1342 additions and 1562 deletions

View File

@@ -0,0 +1,136 @@
package com.youlai.boot.common.aspect;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import com.youlai.boot.common.annotation.Log;
import com.youlai.boot.common.enums.ActionTypeEnum;
import com.youlai.boot.common.enums.LogModuleEnum;
import com.youlai.boot.common.util.IPUtils;
import com.youlai.boot.framework.security.util.SecurityUtils;
import com.youlai.boot.system.model.entity.SysLog;
import com.youlai.boot.system.service.LogService;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import java.time.LocalDateTime;
/**
* 日志切面
*
* @author Ray.Hao
* @since 2.10.0
*/
@Aspect
@Component
@RequiredArgsConstructor
@Slf4j
public class LogAspect {
private final LogService logService;
/**
* 日志注解切点
*/
@Pointcut("@annotation(logAnnotation)")
public void logPointCut(Log logAnnotation) {
}
/**
* 环绕通知:记录操作日志
*/
@Around(value = "logPointCut(logAnnotation)", argNames = "pjp,logAnnotation")
public Object around(ProceedingJoinPoint pjp, Log logAnnotation) throws Throwable {
long startTime = System.currentTimeMillis();
Object result = null;
Exception exception = null;
try {
result = pjp.proceed();
return result;
} catch (Exception e) {
exception = e;
throw e;
} finally {
long executionTime = System.currentTimeMillis() - startTime;
saveLogAsync(logAnnotation, executionTime, exception);
}
}
/**
* 异步保存日志
*/
@Async
public void saveLogAsync(Log logAnnotation, long executionTime, Exception exception) {
try {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attributes == null) {
return;
}
HttpServletRequest request = attributes.getRequest();
// 解析 User-Agent
String userAgentStr = request.getHeader("User-Agent");
UserAgent userAgent = UserAgentUtil.parse(userAgentStr);
// 解析 IP 地区
String ip = IPUtils.getIpAddr(request);
String region = IPUtils.getRegion(ip);
String province = null;
String city = null;
if (StrUtil.isNotBlank(region)) {
String[] parts = region.split("\\|");
if (parts.length >= 3) {
province = StrUtil.blankToDefault(parts[2], null);
city = StrUtil.blankToDefault(parts[3], null);
}
}
// 获取当前用户信息
Long userId = SecurityUtils.getUserId();
String username = SecurityUtils.getUsername();
// 构建日志实体
LogModuleEnum module = logAnnotation.module();
ActionTypeEnum actionType = logAnnotation.value();
String title = StrUtil.blankToDefault(logAnnotation.title(),
module.getLabel() + "-" + actionType.getLabel());
String content = logAnnotation.content();
SysLog logEntity = new SysLog();
logEntity.setModule(module);
logEntity.setActionType(actionType);
logEntity.setTitle(title);
logEntity.setContent(content);
logEntity.setOperatorId(userId);
logEntity.setOperatorName(username);
logEntity.setRequestUri(request.getRequestURI());
logEntity.setRequestMethod(request.getMethod());
logEntity.setIp(ip);
logEntity.setProvince(province);
logEntity.setCity(city);
logEntity.setDevice(userAgent.getOs().getName());
logEntity.setOs(userAgent.getOs().getName());
logEntity.setBrowser(userAgent.getBrowser().getName());
logEntity.setStatus(exception == null ? 1 : 0);
logEntity.setErrorMsg(exception != null ? exception.getMessage() : null);
logEntity.setExecutionTime((int) executionTime);
logEntity.setCreateTime(LocalDateTime.now());
logService.save(logEntity);
} catch (Exception e) {
log.error("保存操作日志异常: {}", e.getMessage());
}
}
}