package com.lzh.hosp.aop;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Maps;
import com.lzh.hosp.enums.OperateTypeEnum;
import com.lzh.hosp.model.CommonResult;
import com.lzh.hosp.model.OperateLog;
import com.lzh.hosp.model.ResponseResult;
import com.lzh.hosp.service.OperateLogFrameworkService;
import com.lzh.hosp.service.SystemOperateLogService;
import com.lzh.hosp.utils.JsonUtils;
import com.lzh.hosp.utils.ServletUtils;
import com.lzh.hosp.utils.TracerUtils;
import com.lzh.hosp.utils.WebFrameworkUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
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.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.IntStream;
/**
* 拦截使用 @OperateLog 注解,如果满足条件,则生成操作日志。
* 满足如下任一条件,则会进行记录:
* 1. 使用 @ApiOperation + 非 @GetMapping
* 2. 使用 @OperateLog 注解
* <p>
* 但是,如果声明 @OperateLog 注解时,将 enable 属性设置为 false 时,强制不记录。
*
*/
@Aspect
@Slf4j
@Component
public class OperateLogAspect {
/**
* 用于记录操作内容的上下文
*
* @see OperateLog#getContent()
*/
private static final ThreadLocal<String> CONTENT = new ThreadLocal<>();
/**
* 用于记录拓展字段的上下文
*
* @see OperateLog#getExts()
*/
private static final ThreadLocal<Map<String, Object>> EXTS = new ThreadLocal<>();
@Autowired
private SystemOperateLogService systemOperateLogService;
@Around("@annotation(operation)")
public Object around(ProceedingJoinPoint joinPoint, Operation operation) throws Throwable {
// 可能也添加了 @ApiOperation 注解
com.lzh.hosp.annotation.OperateLog operateLog = getMethodAnnotation(joinPoint,
com.lzh.hosp.annotation.OperateLog.class);
return around0(joinPoint, operateLog, operation);
}
@Around("!@annotation(io.swagger.v3.oas.annotations.Operation) && @annotation(operateLog)")
// 兼容处理,只添加 @OperateLog 注解的情况
public Object around(ProceedingJoinPoint joinPoint,
com.lzh.hosp.annotation.OperateLog operateLog) throws Throwable {
return around0(joinPoint, operateLog, null);
}
private Object around0(ProceedingJoinPoint joinPoint,
com.lzh.hosp.annotation.OperateLog operateLog,
Operation operation) throws Throwable {
// 目前,只有管理员,才记录操作日志!所以非管理员,直接调用,不进行记录
// Integer userType = WebFrameworkUtils.getLoginUserType();
// if (!Objects.equals(userType, UserTypeEnum.ADMIN.getValue())) {
// return joinPoint.proceed();
// }
// 记录开始时间
LocalDateTime startTime = LocalDateTime.now();
try {
// 执行原有方法
Object result = joinPoint.proceed();
// 记录正常执行时的操作日志
this.log(joinPoint, operateLog, operation, startTime, result, null);
return result;
} catch (Throwable exception) {
this.log(joinPoint, operateLog, operation, startTime, null, exception);
throw exception;
} finally {
clearThreadLocal();
}
}
public static void setContent(String content) {
CONTENT.set(content);
}
public static void addExt(String key, Object value) {
if (EXTS.get() == null) {
EXTS.set(new HashMap<>());
}
EXTS.get().put(key, value);
}
private static void clearThreadLocal() {
CONTENT.remove();
EXTS.remove();
}
private void log(ProceedingJoinPoint joinPoint,
com.lzh.hosp.annotation.OperateLog operateLog,
Operation operation,
LocalDateTime startTime, Object result, Throwable exception) {
try {
// 判断不记录的情况
if (!isLogEnable(joinPoint, operateLog)) {
return;
}
// 真正记录操作日志
this.log0(joinPoint, operateLog, operation, startTime, result, exception);
} catch (Throwable ex) {
log.error("[log][记录操作日志时,发生异常,其中参数是 joinPoint({}) operateLog({}) apiOperation({}) result({}) exception({}) ]",
joinPoint, operateLog, operation, result, exception, ex);
}
}
private void log0(ProceedingJoinPoint joinPoint,
com.lzh.hosp.annotation.OperateLog operateLog,
Operation operation,
LocalDateTime startTime, Object result, Throwable exception) {
OperateLog operateLogObj = new OperateLog();
// 补全通用字段
operateLogObj.setTraceId(TracerUtils.getTraceId());
operateLogObj.setStartTime(startTime);
// 补充用户信息
fillUserFields(operateLogObj);
// 补全模块信息
fillModuleFields(operateLogObj, joinPoint, operateLog, operation);
// 补全请求信息
fillRequestFields(operateLogObj);
// 补全方法信息
fillMethodFields(operateLogObj, joinPoint, operateLog, startTime, result, exception);
// 异步记录日志
systemOperateLogService.createOperateLog(operateLogObj);
// operateLogFrameworkService.createOperateLog(operateLogObj);
}
private static void fillUserFields(OperateLog operateLogObj) {
operateLogObj.setUserId(WebFrameworkUtils.getUserId());
// operateLogObj.setUserType(WebFrameworkUtils.getLoginUserType());
}
private static void fillModuleFields(OperateLog operateLogObj,
ProceedingJoinPoint joinPoint,
com.lzh.hosp.annotation.OperateLog operateLog,
Operation operation) {
// module 属性
if (operateLog != null) {
operateLogObj.setModule(operateLog.module());
}
if (StrUtil.isEmpty(operateLogObj.getModule())) {
Tag tag = getClassAnnotation(joinPoint, Tag.class);
if (tag != null) {
// 优先读取 @Tag 的 name 属性
if (StrUtil.isNotEmpty(tag.name())) {
operateLogObj.setModule(tag.name());
}
// 没有的话,读取 @API 的 description 属性
if (StrUtil.isEmpty(operateLogObj.getModule()) && ArrayUtil.isNotEmpty(tag.description())) {
operateLogObj.setModule(tag.description());
}
}
}
// name 属性
if (operateLog != null) {
operateLogObj.setName(operateLog.name());
}
if (StrUtil.isEmpty(operateLogObj.getName()) && operation != null) {
没有合适的资源?快使用搜索试试~ 我知道了~
基于Java核心技术的医院门诊系统设计源码
共337个文件
java:171个
js:53个
vue:42个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 153 浏览量
2024-09-28
14:50:52
上传
评论
收藏 2.61MB ZIP 举报
温馨提示
该项目是一款基于Java核心技术的医院门诊系统设计源码,包含338个文件,涵盖171个Java源文件、52个JavaScript脚本、42个Vue组件、18个XML配置文件、9个JSON数据文件、7个PNG图片、6个HTML页面、4个CSS样式表、4个Git忽略规则、4个CSS样式表、3个Markdown文档。系统融合了多种技术,包括Java、JavaScript、Vue、HTML、CSS等,旨在为医院提供高效便捷的门诊服务管理解决方案。
资源推荐
资源详情
资源评论
收起资源包目录
基于Java核心技术的医院门诊系统设计源码 (337个子文件)
.browserslistrc 30B
mvnw.cmd 7KB
demo.css 6KB
iconfont.css 4KB
global.css 298B
global.css 66B
.editorconfig 121B
iconfont.eot 4KB
.gitignore 395B
.gitignore 231B
.gitignore 231B
.gitignore 231B
demo_symbol.html 6KB
demo_unicode.html 6KB
demo_fontclass.html 4KB
index.html 611B
index.html 611B
index.html 611B
favicon.ico 4KB
favicon.ico 4KB
favicon.ico 4KB
org.springframework.boot.autoconfigure.AutoConfiguration.imports 52B
maven-wrapper.jar 59KB
OperateLogAspect.java 16KB
PatientServiceImpl.java 13KB
ScheduleServiceImpl.java 12KB
WebSocketServer.java 12KB
SysUserController.java 9KB
PrescriptionServiceImpl.java 9KB
CommonUtils.java 9KB
SpeechSynthesizerDemo.java 7KB
SysUserServiceImpl.java 7KB
OrderInfoServiceImpl.java 7KB
RedisCache.java 6KB
PatientController.java 6KB
ScheduleController.java 6KB
DoctorController.java 5KB
WeightedRoundRobinAvailable.java 5KB
SecurityConfig.java 5KB
WebFrameworkUtils.java 5KB
OrderController.java 5KB
HospSystemApplicationTests.java 5KB
MsmServiceImpl.java 5KB
MedicineController.java 5KB
OperationLogController.java 5KB
PrescriptionController.java 4KB
JsonUtils.java 4KB
SystemOperateLog.java 4KB
MedicineServiceImpl.java 4KB
SysRoleController.java 4KB
CommentServiceImpl.java 4KB
ServletUtils.java 3KB
OperateLogDO.java 3KB
ServerNode.java 3KB
JwtUtil.java 3KB
SysMenuController.java 3KB
CommonResult.java 3KB
SysMenuServiceImpl.java 3KB
Prescription.java 3KB
Patient.java 3KB
Schedule.java 3KB
JwtAuthenticationTokenFilter.java 3KB
OperateLogServiceImpl.java 3KB
DoctorServiceImpl.java 3KB
GlobalExceptionHandler.java 3KB
DictServiceImpl.java 3KB
OrderInfo.java 2KB
OperateLogCreateReqDTO.java 2KB
NoticeController.java 2KB
AccountUser.java 2KB
SysUser.java 2KB
FileServiceImpl.java 2KB
Doctor.java 2KB
GlobalErrorCodeConstants.java 2KB
SysMenu.java 2KB
RedisKeyExpirationListener.java 2KB
Medicine.java 2KB
WebProperties.java 2KB
Comment.java 2KB
PrescriptionDetailServiceImpl.java 2KB
SwaggerConfig.java 2KB
CommentController.java 2KB
OperateLogPageReqVO.java 2KB
ResultCodeEnum.java 2KB
FastJsonRedisSerializer.java 2KB
StrUtils.java 2KB
JwtLogoutSuccessHandler.java 2KB
RequestAdvice.java 2KB
OperateLog.java 2KB
Dict.java 2KB
ResponseResult.java 2KB
PrescriptionDetail.java 2KB
UserDetailsServiceImpl.java 2KB
MedicineWarehouse.java 1KB
RandomUtil.java 1KB
SysRole.java 1KB
Notice.java 1KB
BaseDO.java 1KB
ScheduleApiController.java 1KB
OperateLog.java 1KB
共 337 条
- 1
- 2
- 3
- 4
资源评论
lsx202406
- 粉丝: 1829
- 资源: 3858
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- NPC逆变并网仿真(闭环SPWM)2021a 逆变器采用二极管钳位型NPC,直流侧输入电压800V,含PLL锁相环, 采用双环控
- 盘式电机 maxwell 电磁仿真模型 双转单定结构,halbach 结构,双定单转 24 槽 20 极,18槽 1 2 极,1
- 关于fpga时序约束的书籍
- 1模型简介:COMSOL Multiphysi随机圆,球 2案例内容:数值模拟一个,程序代码,二维三维 3模型特
- 固体氧化物燃料电池SOFC模型,COMSOL电池仿真计算
- comsol超宽带布儒斯特角不对称反射
- Flow3d 11.1 lpbf 熔池仿真模拟 slm 选区激光熔化 1.该模拟设包含颗粒床以及建立过程(有视频),运用
- 1模型简介:COMSOL Multiphysi对注浆浆液渗流过程颗粒沉积引起的渗透率变化进行数值模拟研究 根据魏建平裂隙
- 三相有源电力滤器APF仿真 波形从上到下分别是: 电网电流 APF电流 整流性负载电流 APF能够保证电网电流成正弦
- 永磁同步电机的MTPA最大转矩电流比控制算法+弱磁控制的仿真模型 (附带一份建模及说明文档) 1. 永磁同步电机的数学模型;
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功