!514 mall交易日志封装

* 交易日志封装
* 交易日志封装
* 交易日志模块
This commit is contained in:
陈賝
2023-06-17 14:00:10 +00:00
committed by 芋道源码
parent 35df912be7
commit 59e16795be
20 changed files with 470 additions and 51 deletions

View File

@ -19,23 +19,38 @@ import static cn.hutool.core.util.ArrayUtil.firstMatch;
@Getter
public enum TradeAfterSaleStatusEnum implements IntArrayValuable {
APPLY(10,"申请中", // 【申请售后】
"会员申请退款"),
SELLER_AGREE(20, "卖家通过", // 卖家通过售后;【商品待退货】
"商家同意退款"),
BUYER_DELIVERY(30,"待卖家收货", // 买家已退货,等待卖家收货;【商家待收货】
"会员填写退货物流信息"),
WAIT_REFUND(40, "等待平台退款", // 卖家已收货,等待平台退款;等待退款【等待退款】
"商家收货"),
COMPLETE(50, "完成", // 完成退款【退款成功】
"商家确认退款"),
BUYER_CANCEL(61, "买家取消售后", // 【买家取消】
"会员取消退款"),
SELLER_DISAGREE(62,"卖家拒绝", // 卖家拒绝售后;商家拒绝【商家拒绝】
"商家拒绝退款"),
SELLER_REFUSE(63,"卖家拒绝收货", // 卖家拒绝收货,终止售后;【商家收货
"商家拒绝收货"),
/**
* 【申请售后】
*/
APPLY(10,"申请中", "会员申请退款"),
/**
* 卖家通过售后;【商品待退货】
*/
SELLER_AGREE(20, "卖家通过", "商家同意退款"),
/**
* 买家已退货,等待卖家收货;【商家待收货】
*/
BUYER_DELIVERY(30,"待卖家收货", "会员填写退货物流信息"),
/**
* 卖家已收货,等待平台退款;等待退款【等待退款】
*/
WAIT_REFUND(40, "等待平台退款", "商家收货"),
/**
* 完成退款【退款成功】
*/
COMPLETE(50, "完成", "商家确认退款"),
/**
* 【买家取消】
*/
BUYER_CANCEL(61, "买家取消售后", "会员取消退款"),
/**
* 卖家拒绝售后;商家拒绝【商家拒绝】
*/
SELLER_DISAGREE(62,"卖家拒绝", "商家拒绝退款"),
/**
* 卖家拒绝收货,终止售后;【商家拒收货】
*/
SELLER_REFUSE(63,"卖家拒绝收货", "商家拒绝收货"),
;
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeAfterSaleStatusEnum::getStatus).toArray();

View File

@ -58,6 +58,10 @@
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-biz-ip</artifactId>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-biz-trade</artifactId>
</dependency>
<!-- Web 相关 -->
<dependency>
@ -93,6 +97,7 @@
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-excel</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.controller.admin.aftersale;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.trade.core.annotations.AfterSaleLog;
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi;
@ -11,6 +12,7 @@ import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSal
import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSalePageReqVO;
import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRefuseReqVO;
import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleRespPageItemVO;
import cn.iocoder.yudao.module.trade.controller.app.aftersale.vo.AppTradeAfterSaleCreateReqVO;
import cn.iocoder.yudao.module.trade.convert.aftersale.TradeAfterSaleConvert;
import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.TradeAfterSaleDO;
import cn.iocoder.yudao.module.trade.service.aftersale.TradeAfterSaleService;
@ -110,4 +112,20 @@ public class TradeAfterSaleController {
return success(true);
}
/**
* 售后日志测试
*
* @param createReqVO
* @return cn.iocoder.yudao.framework.common.pojo.CommonResult<java.lang.Long>
* @author 陈賝
* @date 2023/6/14 21:39
*/
@PostMapping(value = "/create")
@AfterSaleLog(id = "#createReqVO.orderItemId", content = "'申请售后:售后编号['+#createReqVO.orderItemId+'] , '", operateType = "#createReqVO.operateType")
public CommonResult<Long> createAfterSale(@RequestBody AppTradeAfterSaleCreateReqVO createReqVO) {
return success(1L);
// return success(afterSaleService.createAfterSale(getLoginUserId(), createReqVO));
}
}

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.trade.controller.app.aftersale.vo;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.framework.trade.core.enums.AfterSaleStatusEnum;
import cn.iocoder.yudao.module.trade.enums.aftersale.TradeAfterSaleWayEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@ -31,6 +32,13 @@ public class AppTradeAfterSaleCreateReqVO {
@NotNull(message = "申请原因不能为空")
private String applyReason;
/**
* @see AfterSaleStatusEnum
*/
@Schema(description = "操作类型", required = true, example = "1")
@NotNull(message = "操作类型不能为空")
private String operateType;
@Schema(description = "补充描述", example = "商品质量不好")
private String applyDescription;

View File

@ -52,29 +52,9 @@ public class TradeAfterSaleLogDO extends BaseDO {
*/
private Long afterSaleId;
/**
* 订单编号
*
* 关联 {@link TradeOrderDO#getId()}
* 操作类型 {@link TradeAfterSaleStatusEnum}
*/
private Long orderId;
/**
* 订单项编号
*
* 关联 {@link TradeOrderItemDO#getId()}
*/
private Long orderItemId;
/**
* 售后状态(之前)
*
* 枚举 {@link TradeAfterSaleStatusEnum}
*/
private Integer beforeStatus;
/**
* 售后状态(之后)
*
* 枚举 {@link TradeAfterSaleStatusEnum}
*/
private Integer afterStatus;
private String operateType;
/**
* 操作明细
*/

View File

@ -5,6 +5,8 @@ import cn.hutool.core.util.RandomUtil;
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
import cn.iocoder.yudao.framework.trade.core.dto.TradeAfterSaleLogDTO;
import cn.iocoder.yudao.framework.trade.core.service.AfterSaleLogService;
import cn.iocoder.yudao.module.pay.api.refund.PayRefundApi;
import cn.iocoder.yudao.module.pay.api.refund.dto.PayRefundCreateReqDTO;
import cn.iocoder.yudao.module.trade.controller.admin.aftersale.vo.TradeAfterSaleDisagreeReqVO;
@ -26,6 +28,8 @@ import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEn
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum;
import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
import cn.iocoder.yudao.module.trade.service.order.TradeOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
@ -43,9 +47,10 @@ import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
*
* @author 芋道源码
*/
@Slf4j
@Service
@Validated
public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSaleLogService {
@Resource
private TradeOrderService tradeOrderService;
@ -80,7 +85,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
/**
* 校验交易订单项是否可以申请售后
*
* @param userId 用户编号
* @param userId 用户编号
* @param createReqVO 售后创建信息
* @return 交易订单项
*/
@ -117,7 +122,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
}
// 如果是【退货退款】的情况,需要额外校验是否发货
if (createReqVO.getWay().equals(TradeAfterSaleWayEnum.RETURN_AND_REFUND.getWay())
&& !TradeOrderStatusEnum.haveDelivered(order.getStatus())) {
&& !TradeOrderStatusEnum.haveDelivered(order.getStatus())) {
throw exception(AFTER_SALE_CREATE_FAIL_ORDER_STATUS_NO_DELIVERED);
}
return orderItem;
@ -133,7 +138,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
TradeOrderDO order = tradeOrderService.getOrder(orderItem.getUserId(), orderItem.getOrderId());
afterSale.setOrderNo(order.getNo()); // 记录 orderNo 订单流水,方便后续检索
afterSale.setType(TradeOrderStatusEnum.isCompleted(order.getStatus())
? TradeAfterSaleTypeEnum.AFTER_SALE.getType() : TradeAfterSaleTypeEnum.IN_SALE.getType());
? TradeAfterSaleTypeEnum.AFTER_SALE.getType() : TradeAfterSaleTypeEnum.IN_SALE.getType());
// TODO 退还积分
tradeAfterSaleMapper.insert(afterSale);
@ -380,13 +385,38 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService {
TradeOrderItemAfterSaleStatusEnum.NONE.getStatus(), null);
}
@Deprecated
private void createAfterSaleLog(Long userId, Integer userType, TradeAfterSaleDO afterSale,
Integer beforeStatus, Integer afterStatus) {
TradeAfterSaleLogDO afterSaleLog = new TradeAfterSaleLogDO().setUserId(userId).setUserType(userType)
.setAfterSaleId(afterSale.getId()).setOrderId(afterSale.getOrderId())
.setOrderItemId(afterSale.getOrderItemId()).setBeforeStatus(beforeStatus).setAfterStatus(afterStatus)
.setContent(TradeAfterSaleStatusEnum.valueOf(afterStatus).getContent());
tradeAfterSaleLogMapper.insert(afterSaleLog);
TradeAfterSaleLogDTO logDTO = new TradeAfterSaleLogDTO()
.setUserId(userId)
.setUserType(userType)
.setAfterSaleId(afterSale.getId())
.setOperateType(afterStatus.toString());
// TODO 废弃,待删除
this.insert(logDTO);
}
/**
* 日志记录
*
* @param logDTO 日志记录
* @author 陈賝
* @date 2023/6/12 14:18
*/
@Override
@Async
public void insert(TradeAfterSaleLogDTO logDTO) {
try {
TradeAfterSaleLogDO afterSaleLog = new TradeAfterSaleLogDO()
.setUserId(logDTO.getUserId())
.setUserType(logDTO.getUserType())
.setAfterSaleId(logDTO.getAfterSaleId())
.setOperateType(logDTO.getOperateType())
.setContent(logDTO.getContent());
tradeAfterSaleLogMapper.insert(afterSaleLog);
}catch (Exception exception){
log.error("日志记录错误", exception);
}
}
}

View File

@ -66,6 +66,7 @@ public class TradeAfterSaleServiceTest extends BaseDbUnitTest {
AppTradeAfterSaleCreateReqVO createReqVO = new AppTradeAfterSaleCreateReqVO()
.setOrderItemId(1L).setRefundPrice(100).setWay(TradeAfterSaleWayEnum.RETURN_AND_REFUND.getWay())
.setApplyReason("退钱").setApplyDescription("快退")
.setOperateType("APPLY")
.setApplyPicUrls(asList("https://www.baidu.com/1.png", "https://www.baidu.com/2.png"));
// mock 方法(交易订单项)
TradeOrderItemDO orderItem = randomPojo(TradeOrderItemDO.class, o -> {
@ -102,8 +103,8 @@ public class TradeAfterSaleServiceTest extends BaseDbUnitTest {
assertEquals(afterSaleLog.getUserType(), UserTypeEnum.MEMBER.getValue());
assertEquals(afterSaleLog.getAfterSaleId(), afterSaleId);
assertPojoEquals(afterSale, orderItem, "id", "creator", "createTime", "updater", "updateTime");
assertNull(afterSaleLog.getBeforeStatus());
assertEquals(afterSaleLog.getAfterStatus(), TradeAfterSaleStatusEnum.APPLY.getStatus());
// assertNull(afterSaleLog.getBeforeStatus());
// assertEquals(afterSaleLog.getAfterStatus(), TradeAfterSaleStatusEnum.APPLY.getStatus());
assertEquals(afterSaleLog.getContent(), TradeAfterSaleStatusEnum.APPLY.getContent());
}