gaoluyang
3 天以前 8c65f898ed6e5b0c7a94c792c4562f6ec831dccd
yudao-module-aftersales/src/main/java/cn/iocoder/yudao/module/aftersales/service/ticket/AfterSaleTicketServiceImpl.java
@@ -5,6 +5,7 @@
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.aftersales.controller.admin.ticket.vo.ticket.AfterSaleTicketPageReqVO;
import cn.iocoder.yudao.module.aftersales.controller.admin.ticket.vo.ticket.AfterSaleTicketSaveReqVO;
import cn.iocoder.yudao.module.aftersales.api.dto.AfterSaleWarehouseReturnStageReqDTO;
import cn.iocoder.yudao.module.aftersales.dal.dataobject.problem.AfterSaleProblemDO;
import cn.iocoder.yudao.module.aftersales.dal.dataobject.ticket.AfterSaleTicketDO;
import cn.iocoder.yudao.module.aftersales.dal.dataobject.ticket.AfterSaleTicketItemDO;
@@ -29,6 +30,7 @@
import org.springframework.validation.annotation.Validated;
import java.time.LocalDateTime;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
@@ -249,6 +251,84 @@
                ticket.getStatus(), targetStatus, content);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void onWarehouseReturnQualityFinished(AfterSaleWarehouseReturnStageReqDTO reqDTO) {
        AfterSaleTicketDO ticket = findWarehouseReturnTicket(reqDTO);
        if (ticket == null || hasWarehouseReturnStage(ticket.getId(), reqDTO,
                AfterSaleTicketFlowService.ACTION_RETURN_QUALITY)) return;
        ticketFlowService.record(ticket.getId(), AfterSaleTicketFlowService.ACTION_RETURN_QUALITY, "退货质检完成",
                ticket.getStatus(), ticket.getStatus(), "销售退货单【" + warehouseReturnKey(reqDTO)
                        + "】质检完成,结论:" + reqDTO.getQualityResult());
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void onWarehouseReturnInboundFinished(AfterSaleWarehouseReturnStageReqDTO reqDTO) {
        AfterSaleTicketDO ticket = findWarehouseReturnTicket(reqDTO);
        if (ticket == null || hasWarehouseReturnStage(ticket.getId(), reqDTO,
                AfterSaleTicketFlowService.ACTION_RETURN_INBOUND)) return;
        Integer targetStatus = ticket.getStatus();
        if (AfterSaleTicketStatusEnum.WAITING_RETURN.getStatus().equals(targetStatus)) {
            targetStatus = AfterSaleTicketStatusEnum.WAITING_REFUND.getStatus();
            ticketMapper.updateById(new AfterSaleTicketDO().setId(ticket.getId()).setStatus(targetStatus));
        }
        ticketFlowService.record(ticket.getId(), AfterSaleTicketFlowService.ACTION_RETURN_INBOUND, "退货入库完成",
                ticket.getStatus(), targetStatus, "销售退货单【" + warehouseReturnKey(reqDTO) + "】已完成上架入库");
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void onWarehouseReturnRefundCompleted(AfterSaleWarehouseReturnStageReqDTO reqDTO) {
        if (reqDTO.getRefundAmount() == null || reqDTO.getRefundAmount().compareTo(BigDecimal.ZERO) < 0) {
            throw new cn.iocoder.yudao.framework.common.exception.ServiceException(400, "实际退款金额不能小于 0");
        }
        AfterSaleTicketDO ticket = findWarehouseReturnTicket(reqDTO);
        if (ticket == null) {
            throw new cn.iocoder.yudao.framework.common.exception.ServiceException(400,
                    "销售退货单未关联售后工单,请核对销售订单和退货单号");
        }
        if (hasWarehouseReturnStage(ticket.getId(), reqDTO,
                AfterSaleTicketFlowService.ACTION_RETURN_REFUND)) return;
        if (!AfterSaleTicketStatusEnum.WAITING_REFUND.getStatus().equals(ticket.getStatus())) {
            throw new cn.iocoder.yudao.framework.common.exception.ServiceException(400,
                    "退货入库完成后才能回写退款结果");
        }
        ticketMapper.updateById(new AfterSaleTicketDO().setId(ticket.getId())
                .setStatus(AfterSaleTicketStatusEnum.COMPLETED.getStatus())
                .setResolvedTime(LocalDateTime.now())
                .setVisitStatus(AfterSaleVisitStatusEnum.WAITING.getStatus()));
        ticketFlowService.record(ticket.getId(), AfterSaleTicketFlowService.ACTION_RETURN_REFUND, "退款完成",
                ticket.getStatus(), AfterSaleTicketStatusEnum.COMPLETED.getStatus(),
                "销售退货单【" + warehouseReturnKey(reqDTO) + "】实退金额:" + reqDTO.getRefundAmount());
    }
    private AfterSaleTicketDO findWarehouseReturnTicket(AfterSaleWarehouseReturnStageReqDTO reqDTO) {
        if (reqDTO.getSaleOrderId() == null || reqDTO.getReturnSalesId() == null) return null;
        String key = warehouseReturnKey(reqDTO);
        for (AfterSaleTicketDO candidate : ticketMapper.selectListBySaleOrderId(reqDTO.getSaleOrderId())) {
            boolean linked = ticketFlowService.getFlowList(candidate.getId()).stream()
                    .anyMatch(flow -> AfterSaleTicketFlowService.ACTION_RETURN.equals(flow.getAction())
                            && flow.getContent() != null && flow.getContent().contains("【" + key + "】"));
            if (linked) {
                ticketMapper.lockById(candidate.getId());
                return ticketMapper.selectById(candidate.getId());
            }
        }
        return null;
    }
    private boolean hasWarehouseReturnStage(Long ticketId, AfterSaleWarehouseReturnStageReqDTO reqDTO, String action) {
        return ticketFlowService.getFlowList(ticketId).stream()
                .anyMatch(flow -> action.equals(flow.getAction()) && flow.getContent() != null
                        && flow.getContent().contains("【" + warehouseReturnKey(reqDTO) + "】"));
    }
    private String warehouseReturnKey(AfterSaleWarehouseReturnStageReqDTO reqDTO) {
        return reqDTO.getReturnSalesCode() != null && !reqDTO.getReturnSalesCode().isBlank()
                ? reqDTO.getReturnSalesCode() : "ID=" + reqDTO.getReturnSalesId();
    }
    private String getHandlerName(Long handlerUserId) {
        AdminUserRespDTO handler = adminUserApi.getUser(handlerUserId);
        return handler != null ? handler.getNickname() : "用户(ID=" + handlerUserId + ")";