feat(审批): 添加审批状态验证和审批处理逻辑
添加审批状态验证方法`validateApprovalStatus`,确保审批状态合法。在`ReturnApprovalApplicationService`中实现审批通过和驳回的逻辑,包括退款金额验证、退款操作以及更新订单商品状态。同时,修复SQL查询中的空格问题。
This commit is contained in:
parent
980d279ba9
commit
92ba2b93a2
|
@ -6,6 +6,7 @@ import com.agileboot.common.exception.ApiException;
|
||||||
import com.agileboot.common.exception.error.ErrorCode;
|
import com.agileboot.common.exception.error.ErrorCode;
|
||||||
import com.agileboot.domain.shop.approval.ReturnApprovalApplicationService;
|
import com.agileboot.domain.shop.approval.ReturnApprovalApplicationService;
|
||||||
import com.agileboot.domain.shop.approval.command.AddReturnApprovalCommand;
|
import com.agileboot.domain.shop.approval.command.AddReturnApprovalCommand;
|
||||||
|
import com.agileboot.domain.shop.approval.command.UpdateReturnApprovalCommand;
|
||||||
import com.agileboot.domain.shop.approval.db.ReturnApprovalEntity;
|
import com.agileboot.domain.shop.approval.db.ReturnApprovalEntity;
|
||||||
import com.agileboot.domain.shop.approval.model.ReturnApprovalModel;
|
import com.agileboot.domain.shop.approval.model.ReturnApprovalModel;
|
||||||
import com.agileboot.domain.shop.approval.query.SearchApiReturnApprovalQuery;
|
import com.agileboot.domain.shop.approval.query.SearchApiReturnApprovalQuery;
|
||||||
|
@ -43,6 +44,38 @@ public class ApprovalApiController {
|
||||||
/** 订单应用服务,用于处理订单相关查询操作 */
|
/** 订单应用服务,用于处理订单相关查询操作 */
|
||||||
private final OrderApplicationService orderApplicationService;
|
private final OrderApplicationService orderApplicationService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理审批操作
|
||||||
|
*
|
||||||
|
* @param command 包含审批操作信息的命令对象
|
||||||
|
* @return 操作结果响应
|
||||||
|
* @throws ApiException 当参数校验失败或业务逻辑出错时抛出
|
||||||
|
*/
|
||||||
|
@PostMapping("/handle")
|
||||||
|
@ApiOperation(value = "处理审批操作")
|
||||||
|
public ResponseDTO<String> handleApproval(@Valid @RequestBody UpdateReturnApprovalCommand command) {
|
||||||
|
if (command.getApprovalId() == null) {
|
||||||
|
return ResponseDTO.fail(new ApiException(ErrorCode.Internal.INTERNAL_ERROR, "审批ID不能为空"));
|
||||||
|
}
|
||||||
|
if (command.getStatus() == null) {
|
||||||
|
return ResponseDTO.fail(new ApiException(ErrorCode.Internal.INTERNAL_ERROR, "操作状态不能为空"));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (command.getStatus() == 2) {
|
||||||
|
approvalApplicationService.approveApproval(command);
|
||||||
|
} else if (command.getStatus() == 3) {
|
||||||
|
approvalApplicationService.rejectApproval(command);
|
||||||
|
} else {
|
||||||
|
return ResponseDTO.fail(new ApiException(ErrorCode.Internal.INTERNAL_ERROR, "无效的操作状态"));
|
||||||
|
}
|
||||||
|
return ResponseDTO.ok("操作成功");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("审批操作失败", e);
|
||||||
|
return ResponseDTO.fail(new ApiException(ErrorCode.Internal.INTERNAL_ERROR, e.getMessage()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 提交退货审批申请
|
* 提交退货审批申请
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.agileboot.domain.shop.approval;
|
package com.agileboot.domain.shop.approval;
|
||||||
|
|
||||||
|
import com.agileboot.common.constant.PayApiConstants;
|
||||||
import com.agileboot.common.core.page.PageDTO;
|
import com.agileboot.common.core.page.PageDTO;
|
||||||
import com.agileboot.domain.common.command.BulkOperationCommand;
|
import com.agileboot.domain.common.command.BulkOperationCommand;
|
||||||
import com.agileboot.domain.shop.approval.command.AddReturnApprovalCommand;
|
import com.agileboot.domain.shop.approval.command.AddReturnApprovalCommand;
|
||||||
|
@ -14,8 +15,14 @@ import com.agileboot.domain.shop.approval.query.SearchReturnApprovalQuery;
|
||||||
import com.agileboot.domain.shop.order.db.ShopOrderGoodsEntity;
|
import com.agileboot.domain.shop.order.db.ShopOrderGoodsEntity;
|
||||||
import com.agileboot.domain.shop.order.model.OrderGoodsModel;
|
import com.agileboot.domain.shop.order.model.OrderGoodsModel;
|
||||||
import com.agileboot.domain.shop.order.model.OrderGoodsModelFactory;
|
import com.agileboot.domain.shop.order.model.OrderGoodsModelFactory;
|
||||||
|
import com.agileboot.domain.shop.order.model.OrderModel;
|
||||||
|
import com.agileboot.domain.shop.order.model.OrderModelFactory;
|
||||||
|
import com.agileboot.domain.shop.payment.PaymentApplicationService;
|
||||||
|
import com.agileboot.domain.shop.payment.dto.RefundVO;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -23,6 +30,9 @@ import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退货审批应用服务类,处理与退货审批相关的业务逻辑
|
||||||
|
*/
|
||||||
@Service
|
@Service
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
|
@ -31,7 +41,14 @@ public class ReturnApprovalApplicationService {
|
||||||
private final ReturnApprovalService approvalService;
|
private final ReturnApprovalService approvalService;
|
||||||
private final ReturnApprovalModelFactory modelFactory;
|
private final ReturnApprovalModelFactory modelFactory;
|
||||||
private final OrderGoodsModelFactory orderGoodsModelFactory;
|
private final OrderGoodsModelFactory orderGoodsModelFactory;
|
||||||
|
private final OrderModelFactory orderModelFactory;
|
||||||
|
private final PaymentApplicationService paymentApplicationService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取退货审批列表
|
||||||
|
* @param query 查询条件
|
||||||
|
* @return 分页的退货审批DTO列表
|
||||||
|
*/
|
||||||
public PageDTO<ReturnApprovalDTO> getApprovalList(SearchReturnApprovalQuery<ReturnApprovalEntity> query) {
|
public PageDTO<ReturnApprovalDTO> getApprovalList(SearchReturnApprovalQuery<ReturnApprovalEntity> query) {
|
||||||
Page<ReturnApprovalEntity> page = approvalService.getApprovalList(query);
|
Page<ReturnApprovalEntity> page = approvalService.getApprovalList(query);
|
||||||
List<ReturnApprovalDTO> dtoList = page.getRecords().stream()
|
List<ReturnApprovalDTO> dtoList = page.getRecords().stream()
|
||||||
|
@ -40,6 +57,11 @@ public class ReturnApprovalApplicationService {
|
||||||
return new PageDTO<>(dtoList, page.getTotal());
|
return new PageDTO<>(dtoList, page.getTotal());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加退货审批
|
||||||
|
* @param command 添加退货审批命令
|
||||||
|
* @return 创建的退货审批模型
|
||||||
|
*/
|
||||||
public ReturnApprovalModel addApproval(AddReturnApprovalCommand command) {
|
public ReturnApprovalModel addApproval(AddReturnApprovalCommand command) {
|
||||||
ReturnApprovalModel model = modelFactory.create();
|
ReturnApprovalModel model = modelFactory.create();
|
||||||
model.loadAddCommand(command);
|
model.loadAddCommand(command);
|
||||||
|
@ -47,12 +69,20 @@ public class ReturnApprovalApplicationService {
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新退货审批信息
|
||||||
|
* @param command 更新退货审批命令
|
||||||
|
*/
|
||||||
public void updateApproval(UpdateReturnApprovalCommand command) {
|
public void updateApproval(UpdateReturnApprovalCommand command) {
|
||||||
ReturnApprovalModel model = modelFactory.loadById(command.getApprovalId());
|
ReturnApprovalModel model = modelFactory.loadById(command.getApprovalId());
|
||||||
model.loadUpdateCommand(command);
|
model.loadUpdateCommand(command);
|
||||||
model.updateById();
|
model.updateById();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除退货审批
|
||||||
|
* @param command 批量操作命令,包含要删除的审批ID列表
|
||||||
|
*/
|
||||||
public void deleteApproval(BulkOperationCommand<Long> command) {
|
public void deleteApproval(BulkOperationCommand<Long> command) {
|
||||||
for (Long approvalId : command.getIds()) {
|
for (Long approvalId : command.getIds()) {
|
||||||
ReturnApprovalModel model = modelFactory.loadById(approvalId);
|
ReturnApprovalModel model = modelFactory.loadById(approvalId);
|
||||||
|
@ -60,6 +90,67 @@ public class ReturnApprovalApplicationService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 审批通过退货申请
|
||||||
|
* @param command 更新退货审批命令
|
||||||
|
* @throws IllegalArgumentException 如果退款金额不合法
|
||||||
|
* @throws RuntimeException 如果退款操作失败
|
||||||
|
*/
|
||||||
|
public void approveApproval(UpdateReturnApprovalCommand command) {
|
||||||
|
ReturnApprovalModel model = modelFactory.loadById(command.getApprovalId());
|
||||||
|
|
||||||
|
|
||||||
|
OrderModel orderModel = orderModelFactory.loadById(model.getOrderId());
|
||||||
|
OrderGoodsModel orderGoodsModel = orderGoodsModelFactory.loadById(model.getOrderGoodsId());
|
||||||
|
// 退款金额对比, 退款金额不能大于订单金额
|
||||||
|
// 金额转换(元转分)并四舍五入
|
||||||
|
BigDecimal amountInFen = orderGoodsModel.getTotalAmount()
|
||||||
|
.multiply(new BigDecimal("100"))
|
||||||
|
.setScale(0, RoundingMode.HALF_UP);
|
||||||
|
BigDecimal returnAmount = command.getReturnAmount();
|
||||||
|
// 退款金额转换(元转分)并四舍五入
|
||||||
|
returnAmount = returnAmount
|
||||||
|
.multiply(new BigDecimal("100"))
|
||||||
|
.setScale(0, RoundingMode.HALF_UP);
|
||||||
|
if (returnAmount.compareTo(BigDecimal.ZERO) <= 0) {
|
||||||
|
throw new IllegalArgumentException("退款金额必须大于0");
|
||||||
|
}
|
||||||
|
if (returnAmount.compareTo(amountInFen) > 0) {
|
||||||
|
throw new IllegalArgumentException("退款金额不能超过订单总额");
|
||||||
|
}
|
||||||
|
|
||||||
|
RefundVO refundVO = null;
|
||||||
|
try {
|
||||||
|
refundVO = paymentApplicationService.refund(
|
||||||
|
PayApiConstants.biz_id, PayApiConstants.appkey,
|
||||||
|
orderModel.getBizOrderId(), orderModel.getUcid(),
|
||||||
|
"退还", returnAmount.intValue());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("退款失败", e);
|
||||||
|
}
|
||||||
|
log.info("退款结果:{}", refundVO);
|
||||||
|
if (null == refundVO || !refundVO.getSuccess()) {
|
||||||
|
throw new RuntimeException("退款失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
model.validateApprovalStatus();
|
||||||
|
model.setAuditImages(command.getAuditImages());
|
||||||
|
model.setAuditRemark(command.getAuditRemark());
|
||||||
|
model.setReturnAmount(command.getReturnAmount());
|
||||||
|
model.setStatus(2); // 2表示审核通过状态
|
||||||
|
model.updateById();
|
||||||
|
|
||||||
|
// 更新关联订单商品状态
|
||||||
|
orderGoodsModel.setStatus(2); // 6表示已完成退货
|
||||||
|
orderGoodsModel.updateById();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提交退货审批申请
|
||||||
|
* @param command 添加退货审批命令
|
||||||
|
* @param orderGoods 关联的订单商品实体
|
||||||
|
* @return 创建的退货审批实体
|
||||||
|
*/
|
||||||
public ReturnApprovalEntity submitApproval(AddReturnApprovalCommand command, ShopOrderGoodsEntity orderGoods) {
|
public ReturnApprovalEntity submitApproval(AddReturnApprovalCommand command, ShopOrderGoodsEntity orderGoods) {
|
||||||
// 设置商品价格并初始化审批状态
|
// 设置商品价格并初始化审批状态
|
||||||
command.setGoodsId(orderGoods.getGoodsId());
|
command.setGoodsId(orderGoods.getGoodsId());
|
||||||
|
@ -89,4 +180,19 @@ public class ReturnApprovalApplicationService {
|
||||||
Page<ReturnApprovalEntity> page = approvalService.selectApprovalWithGoodsInfo(query);
|
Page<ReturnApprovalEntity> page = approvalService.selectApprovalWithGoodsInfo(query);
|
||||||
return new PageDTO<>(page.getRecords(), page.getTotal());
|
return new PageDTO<>(page.getRecords(), page.getTotal());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 审批驳回退货申请
|
||||||
|
* @param command 更新退货审批命令(包含驳回原因)
|
||||||
|
*/
|
||||||
|
public void rejectApproval(UpdateReturnApprovalCommand command) {
|
||||||
|
ReturnApprovalModel model = modelFactory.loadById(command.getApprovalId());
|
||||||
|
model.validateApprovalStatus();
|
||||||
|
|
||||||
|
// 更新审批状态为驳回
|
||||||
|
model.setStatus(3);
|
||||||
|
model.setAuditImages(command.getAuditImages());
|
||||||
|
model.setAuditRemark(command.getAuditRemark());
|
||||||
|
model.updateById();
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -20,7 +20,7 @@ public interface ReturnApprovalMapper extends BaseMapper<ReturnApprovalEntity> {
|
||||||
|
|
||||||
@Select("SELECT ra.*, sog.goods_name AS goodsName, sog.cover_img AS coverImg " +
|
@Select("SELECT ra.*, sog.goods_name AS goodsName, sog.cover_img AS coverImg " +
|
||||||
"FROM return_approval ra " +
|
"FROM return_approval ra " +
|
||||||
"LEFT JOIN shop_order_goods sog ON ra.order_goods_id = sog.order_goods_id" +
|
"LEFT JOIN shop_order_goods sog ON ra.order_goods_id = sog.order_goods_id " +
|
||||||
"${ew.customSqlSegment}")
|
"${ew.customSqlSegment}")
|
||||||
Page<ReturnApprovalEntity> selectApprovalWithGoodsInfo(Page<ReturnApprovalEntity> page,
|
Page<ReturnApprovalEntity> selectApprovalWithGoodsInfo(Page<ReturnApprovalEntity> page,
|
||||||
@Param(Constants.WRAPPER) Wrapper<ReturnApprovalEntity> queryWrapper);
|
@Param(Constants.WRAPPER) Wrapper<ReturnApprovalEntity> queryWrapper);
|
||||||
|
|
|
@ -36,4 +36,14 @@ public class ReturnApprovalModel extends ReturnApprovalEntity {
|
||||||
loadAddCommand(command);
|
loadAddCommand(command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void validateApprovalStatus() {
|
||||||
|
if (getStatus() == null || !isValidStatus(getStatus())) {
|
||||||
|
throw new RuntimeException("审批状态不合法");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isValidStatus(Integer status) {
|
||||||
|
return !status.equals(2);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
package com.agileboot.domain.shop.order.model;
|
package com.agileboot.domain.shop.order.model;
|
||||||
|
|
||||||
|
import com.agileboot.common.exception.ApiException;
|
||||||
|
import com.agileboot.common.exception.error.ErrorCode;
|
||||||
import com.agileboot.domain.shop.goods.db.ShopGoodsService;
|
import com.agileboot.domain.shop.goods.db.ShopGoodsService;
|
||||||
import com.agileboot.domain.shop.order.db.ShopOrderGoodsEntity;
|
import com.agileboot.domain.shop.order.db.ShopOrderGoodsEntity;
|
||||||
import com.agileboot.domain.shop.order.db.ShopOrderGoodsService;
|
import com.agileboot.domain.shop.order.db.ShopOrderGoodsService;
|
||||||
|
@ -13,6 +15,14 @@ public class OrderGoodsModelFactory {
|
||||||
private final ShopOrderGoodsService orderGoodsService;
|
private final ShopOrderGoodsService orderGoodsService;
|
||||||
private final ShopGoodsService goodsService;
|
private final ShopGoodsService goodsService;
|
||||||
|
|
||||||
|
public OrderGoodsModel loadById(Long orderGoodsId) {
|
||||||
|
ShopOrderGoodsEntity entity = orderGoodsService.getById(orderGoodsId);
|
||||||
|
if (entity == null) {
|
||||||
|
throw new ApiException(ErrorCode.Business.COMMON_OBJECT_NOT_FOUND, orderGoodsId, "订单商品");
|
||||||
|
}
|
||||||
|
return new OrderGoodsModel(entity, orderGoodsService, goodsService);
|
||||||
|
}
|
||||||
|
|
||||||
public OrderGoodsModel create(ShopOrderGoodsEntity entity) {
|
public OrderGoodsModel create(ShopOrderGoodsEntity entity) {
|
||||||
return new OrderGoodsModel(entity, orderGoodsService, goodsService);
|
return new OrderGoodsModel(entity, orderGoodsService, goodsService);
|
||||||
}
|
}
|
||||||
|
|
|
@ -214,8 +214,9 @@ public class PaymentApplicationService {
|
||||||
if (orderNO.startsWith("wxshop-")) {
|
if (orderNO.startsWith("wxshop-")) {
|
||||||
// 订单号格式为 wxshop-1-time,提取中间的订单号
|
// 订单号格式为 wxshop-1-time,提取中间的订单号
|
||||||
String orderId = orderNO.split("-")[1];
|
String orderId = orderNO.split("-")[1];
|
||||||
OrderModel orderModel = orderModelFactory.loadById(Long.valueOf(orderId));
|
log.info("退款回调处理成功, 订单号:{}", orderId);
|
||||||
orderModel.handleRefundSuccess();
|
// OrderModel orderModel = orderModelFactory.loadById(Long.valueOf(orderId));
|
||||||
|
// orderModel.handleRefundSuccess();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res.set("callback_code", 0);
|
res.set("callback_code", 0);
|
||||||
|
|
Loading…
Reference in New Issue