From 8c65f898ed6e5b0c7a94c792c4562f6ec831dccd Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期六, 07 十一月 2026 08:50:53 +0800
Subject: [PATCH] feat: 完善质检、生产、销售、财务与人事模块并接入审批流程

---
 yudao-module-aftersales/src/main/java/cn/iocoder/yudao/module/aftersales/service/ticket/AfterSaleTicketServiceImpl.java |   80 ++++++++++++++++++++++++++++++++++++++++
 1 files changed, 80 insertions(+), 0 deletions(-)

diff --git a/yudao-module-aftersales/src/main/java/cn/iocoder/yudao/module/aftersales/service/ticket/AfterSaleTicketServiceImpl.java b/yudao-module-aftersales/src/main/java/cn/iocoder/yudao/module/aftersales/service/ticket/AfterSaleTicketServiceImpl.java
index cbf4c26..d55bffa 100644
--- a/yudao-module-aftersales/src/main/java/cn/iocoder/yudao/module/aftersales/service/ticket/AfterSaleTicketServiceImpl.java
+++ b/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 + ")";

--
Gitblit v1.9.3