package cn.iocoder.yudao.module.trade.framework.aftersale.core.aop;
|
|
import cn.hutool.core.util.ObjUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.StrUtil;
|
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
|
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderLogDO;
|
import cn.iocoder.yudao.module.trade.enums.aftersale.AfterSaleOperateTypeEnum;
|
import cn.iocoder.yudao.module.trade.framework.aftersale.core.annotations.AfterSaleLog;
|
import cn.iocoder.yudao.module.trade.service.aftersale.AfterSaleLogService;
|
import cn.iocoder.yudao.module.trade.service.aftersale.bo.AfterSaleLogCreateReqBO;
|
import jakarta.annotation.Resource;
|
import lombok.extern.slf4j.Slf4j;
|
import org.aspectj.lang.JoinPoint;
|
import org.aspectj.lang.annotation.AfterReturning;
|
import org.aspectj.lang.annotation.Aspect;
|
|
import java.util.Map;
|
|
import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
|
import static java.util.Collections.emptyMap;
|
|
/**
|
* 售后订单的操作记录的 AOP 切面
|
*
|
* @author 陈賝
|
* @since 2023/6/13 13:54
|
*/
|
@Slf4j
|
@Aspect
|
public class AfterSaleLogAspect {
|
|
/**
|
* 用户编号
|
*
|
* 目前的使用场景:支付回调时,需要强制设置下用户编号
|
*/
|
private static final ThreadLocal<Long> USER_ID = new ThreadLocal<>();
|
/**
|
* 用户类型
|
*/
|
private static final ThreadLocal<Integer> USER_TYPE = new ThreadLocal<>();
|
/**
|
* 订单编号
|
*/
|
private static final ThreadLocal<Long> AFTER_SALE_ID = new ThreadLocal<>();
|
/**
|
* 操作前的状态
|
*/
|
private static final ThreadLocal<Integer> BEFORE_STATUS = new ThreadLocal<>();
|
/**
|
* 操作后的状态
|
*/
|
private static final ThreadLocal<Integer> AFTER_STATUS = new ThreadLocal<>();
|
/**
|
* 操作类型(仅“动态场景”需要使用)
|
*/
|
private static final ThreadLocal<AfterSaleOperateTypeEnum> OPERATE_TYPE = new ThreadLocal<>();
|
/**
|
* 拓展参数 Map,用于格式化操作内容
|
*/
|
private static final ThreadLocal<Map<String, Object>> EXTS = new ThreadLocal<>();
|
|
@Resource
|
private AfterSaleLogService afterSaleLogService;
|
|
@AfterReturning(pointcut = "@annotation(afterSaleLog)")
|
public void doAfterReturning(JoinPoint joinPoint, AfterSaleLog afterSaleLog) {
|
try {
|
// 1.1 操作用户
|
Integer userType = getUserType();
|
Long userId = getUserId();
|
// 1.2 售后信息
|
Long afterSaleId = AFTER_SALE_ID.get();
|
if (afterSaleId == null) { // 如果未设置,只有注解,说明不需要记录日志
|
return;
|
}
|
AfterSaleOperateTypeEnum operateType = ObjUtil.defaultIfNull(OPERATE_TYPE.get(), afterSaleLog.operateType());
|
Integer beforeStatus = BEFORE_STATUS.get();
|
Integer afterStatus = AFTER_STATUS.get();
|
Map<String, Object> exts = ObjectUtil.defaultIfNull(EXTS.get(), emptyMap());
|
String content = StrUtil.format(operateType.getContent(), exts);
|
|
// 2. 记录日志
|
AfterSaleLogCreateReqBO createBO = new AfterSaleLogCreateReqBO()
|
.setUserId(userId).setUserType(userType)
|
.setAfterSaleId(afterSaleId).setBeforeStatus(beforeStatus).setAfterStatus(afterStatus)
|
.setOperateType(operateType.getType()).setContent(content);
|
afterSaleLogService.createAfterSaleLog(createBO);
|
} catch (Exception exception) {
|
log.error("[doAfterReturning][afterSaleLog({}) 日志记录错误]", toJsonString(afterSaleLog), exception);
|
} finally {
|
clear();
|
}
|
}
|
|
/**
|
* 获得用户类型
|
*
|
* 如果没有,则约定为 {@link TradeOrderLogDO#getUserType()} 系统
|
*
|
* @return 用户类型
|
*/
|
private static Integer getUserType() {
|
return ObjectUtil.defaultIfNull(WebFrameworkUtils.getLoginUserType(), TradeOrderLogDO.USER_TYPE_SYSTEM);
|
}
|
|
/**
|
* 获得用户编号
|
*
|
* 如果没有,则约定为 {@link TradeOrderLogDO#getUserId()} 系统
|
*
|
* @return 用户类型
|
*/
|
private static Long getUserId() {
|
if (USER_ID.get() != null) {
|
return USER_ID.get();
|
}
|
return ObjectUtil.defaultIfNull(WebFrameworkUtils.getLoginUserId(), TradeOrderLogDO.USER_ID_SYSTEM);
|
}
|
|
public static void setAfterSale(Long id, Integer beforeStatus, Integer afterStatus, Map<String, Object> exts) {
|
AFTER_SALE_ID.set(id);
|
BEFORE_STATUS.set(beforeStatus);
|
AFTER_STATUS.set(afterStatus);
|
EXTS.set(exts);
|
}
|
|
public static void setAfterSaleOperateType(AfterSaleOperateTypeEnum operateType) {
|
OPERATE_TYPE.set(operateType);
|
}
|
|
public static void setUserInfo(Long userId, Integer userType) {
|
USER_ID.set(userId);
|
USER_TYPE.set(userType);
|
}
|
|
private static void clear() {
|
USER_ID.remove();
|
USER_TYPE.remove();
|
AFTER_SALE_ID.remove();
|
BEFORE_STATUS.remove();
|
AFTER_STATUS.remove();
|
OPERATE_TYPE.remove();
|
EXTS.remove();
|
}
|
|
}
|