gongchunyi
5 小时以前 6c95c2f6a3602fe6f92898dd322c20bbe955e69d
src/main/java/com/ruoyi/approve/service/impl/ApproveNodeServiceImpl.java
@@ -1,6 +1,7 @@
package com.ruoyi.approve.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -10,27 +11,36 @@
import com.ruoyi.approve.pojo.ApproveNode;
import com.ruoyi.approve.pojo.ApproveProcess;
import com.ruoyi.approve.service.IApproveNodeService;
import com.ruoyi.approve.vo.ApproveProcessVO;
import com.ruoyi.common.enums.FileNameType;
import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.device.mapper.DeviceRepairMapper;
import com.ruoyi.device.pojo.DeviceRepair;
import com.ruoyi.other.service.impl.TempFileServiceImpl;
import com.ruoyi.procurementrecord.utils.StockUtils;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.project.system.service.ISysNoticeService;
import com.ruoyi.sales.mapper.CommonFileMapper;
import com.ruoyi.sales.mapper.SalesQuotationMapper;
import com.ruoyi.sales.mapper.SalesQuotationProductMapper;
import com.ruoyi.purchase.mapper.PurchaseLedgerMapper;
import com.ruoyi.purchase.pojo.PurchaseLedger;
import com.ruoyi.purchase.service.impl.PurchaseLedgerServiceImpl;
import com.ruoyi.sales.mapper.*;
import com.ruoyi.sales.pojo.CommonFile;
import com.ruoyi.sales.pojo.SalesLedger;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import com.ruoyi.sales.pojo.SalesQuotation;
import com.ruoyi.sales.pojo.ShippingInfo;
import com.ruoyi.sales.service.ShippingInfoService;
import com.ruoyi.sales.service.ISalesLedgerService;
import com.ruoyi.quality.service.IQualityInspectService;
import com.ruoyi.sales.service.impl.CommonFileServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Comparator;
@@ -38,7 +48,7 @@
import java.util.List;
@Service
@RequiredArgsConstructor
//@RequiredArgsConstructor
public class ApproveNodeServiceImpl extends ServiceImpl<ApproveNodeMapper, ApproveNode> implements IApproveNodeService {
    @Autowired
@@ -59,8 +69,36 @@
    private DeviceRepairMapper deviceRepairMapper;
    @Autowired
    private PurchaseLedgerMapper purchaseLedgerMapper;
    @Autowired
    private SalesQuotationMapper salesQuotationMapper;
    @Autowired
    private ShippingInfoMapper shippingInfoMapper;
    @Autowired
    private CommonFileServiceImpl commonFileService;
    @Autowired
    private StockUtils stockUtils;
    @Autowired
    private SalesLedgerProductMapper salesLedgerProductMapper;
    @Autowired
    private PurchaseLedgerServiceImpl purchaseLedgerServiceImpl;
    @Autowired
    private SalesLedgerMapper salesLedgerMapper;
    @Autowired
    @Lazy
    private ShippingInfoService shippingInfoService;
    @Autowired
    @Lazy
    private ISalesLedgerService salesLedgerService;
    @Autowired
    @Lazy
    private IQualityInspectService qualityInspectService;
    public ApproveProcess getApproveById(String id) {
@@ -102,12 +140,14 @@
        LambdaQueryWrapper<ApproveNode> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ApproveNode::getApproveProcessId, id);
        queryWrapper.eq(ApproveNode::getDeleteFlag, 0);
//        queryWrapper.eq(ApproveNode::getApproveNodeStatus, 0);
        List<ApproveNode> list = list(queryWrapper);
        // 按照 approveNodeOrder 字段升序排序
        list.sort(Comparator.comparingInt(ApproveNode::getApproveNodeOrder));
        LambdaQueryWrapper<ApproveProcess> approveProcessLambdaQueryWrapper = new LambdaQueryWrapper<>();
        approveProcessLambdaQueryWrapper.eq(ApproveProcess::getApproveId, id)
                .eq(ApproveProcess::getApproveDelete, 0)
//                .eq(ApproveProcess::getApproveStatus, 0)
                .last("limit 1");
        ApproveProcess approveProcess = approveProcessMapper.selectOne(approveProcessLambdaQueryWrapper);
        if(approveProcess != null && approveProcess.getApproveStatus() == 3){
@@ -140,6 +180,7 @@
        approveNodeLambdaQueryWrapper.eq(ApproveNode::getApproveProcessId, approveNode.getApproveProcessId())
                .eq(ApproveNode::getApproveNodeOrder, approveNode.getApproveNodeOrder() + 1)
                .eq(ApproveNode::getDeleteFlag, 0)
                .eq(ApproveNode::getApproveNodeStatus, 0)
                .last("limit 1");
        ApproveNode approveNode1 = approveNodeMapper.selectOne(approveNodeLambdaQueryWrapper);
        approveProcess.setApproveStatus(status);
@@ -163,6 +204,48 @@
            }
            deviceRepairMapper.updateById(deviceRepair);
        }
        //采购审核
        if(approveProcess.getApproveType().equals(5)){
            PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectOne(new LambdaQueryWrapper<PurchaseLedger>()
                    .eq(PurchaseLedger::getPurchaseContractNumber, approveProcess.getApproveReason())
                    .last("limit 1"));
            if(purchaseLedger != null) {
                if (status.equals(2)) {
                    // 同意
                    purchaseLedger.setApprovalStatus(3);
                    List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductMapper.selectList(new QueryWrapper<SalesLedgerProduct>()
                            .lambda().eq(SalesLedgerProduct::getSalesLedgerId, purchaseLedger.getId()).eq(SalesLedgerProduct::getType, 2));
                    boolean hasCheckedProduct = false;
                    for (SalesLedgerProduct salesLedgerProduct : salesLedgerProducts) {
                        // 质检
                        if (salesLedgerProduct.getIsChecked()) {
                            hasCheckedProduct = true;
                            purchaseLedgerServiceImpl.addQualityInspect(purchaseLedger, salesLedgerProduct);
                        }else {
                            //直接入库
                            stockUtils.addStock(null, salesLedgerProduct.getId(), salesLedgerProduct.getProductModelId(),
                                    salesLedgerProduct.getQuantity(), StockInQualifiedRecordTypeEnum.PURCHASE_STOCK_IN.getCode(), salesLedgerProduct.getId());
                            BigDecimal oldStocked = salesLedgerProduct.getStockedQuantity() == null ? BigDecimal.ZERO : salesLedgerProduct.getStockedQuantity();
                            BigDecimal orderQty = salesLedgerProduct.getQuantity() == null ? BigDecimal.ZERO : salesLedgerProduct.getQuantity();
                            BigDecimal newStocked = oldStocked.add(orderQty);
                            salesLedgerProduct.setStockedQuantity(newStocked);
                            salesLedgerProduct.setProductStockStatus(2);
                            salesLedgerProduct.fillRemainingQuantity();
                            salesLedgerProductMapper.updateById(salesLedgerProduct);
                        }
                    }
                    purchaseLedger.setStockStatus(hasCheckedProduct ? 0 : 2);
                } else if (status.equals(3)) {
                    // 拒绝
                    purchaseLedger.setApprovalStatus(4);
                } else if (status.equals(1)) {
                    // 审核中
                    purchaseLedger.setApprovalStatus(2);
                }
                purchaseLedgerMapper.updateById(purchaseLedger);
            }
        }
        // 销售报价状态修改
        if(approveProcess.getApproveType().equals(6)){
            SalesQuotation salesQuote = salesQuotationMapper.selectOne(new LambdaQueryWrapper<SalesQuotation>()
@@ -176,12 +259,153 @@
            }else if(status.equals(1) && salesQuote != null){
                salesQuote.setStatus("审核中");
            }
            salesQuotationMapper.updateById(salesQuote);
        }
        // 出库审批修改 (订单级别)
        if(approveProcess.getApproveType().equals(7)){
            String[] split = approveProcess.getApproveReason().split(":");
            if (split.length > 1) {
                String identifier = split[1];
                // 查找销售台账
                SalesLedger salesLedger = salesLedgerMapper.selectOne(new LambdaQueryWrapper<SalesLedger>()
                        .eq(SalesLedger::getSalesContractNo, identifier)
                        .last("limit 1"));
                if (salesLedger != null) {
                    if(status.equals(2)){
                        // 审批完成 -> 修改状态为审核通过,不扣除库存 (扣除库存移至发货台账补充信息阶段)
                        updateSalesLedgerDeliveryStatus(salesLedger.getId(), 4);
                        updateShippingInfoStatusByOrder(salesLedger.getId(), "审核通过");
                    } else if(status.equals(3)){
                        updateSalesLedgerDeliveryStatus(salesLedger.getId(), 3);
                        // 更新关联的发货记录为审核拒绝
                        updateShippingInfoStatusByOrder(salesLedger.getId(), "审核拒绝");
                    } else if(status.equals(1)){
                        updateSalesLedgerDeliveryStatus(salesLedger.getId(), 2);
                        updateShippingInfoStatusByOrder(salesLedger.getId(), "审核中");
                    }
                }
            }
        }
        // 销售订单成品入库审批
        if (approveProcess.getApproveType().equals(9)) {
            String reason = approveProcess.getApproveReason();
            // 销售格式:入库审批:合同号:salesLedgerId:productId1,productId2
            // 质检格式:原材料质检入库审批:inspectId:purchaseLedgerId
            if (org.springframework.util.StringUtils.hasText(reason)) {
                if (reason.startsWith("原材料质检入库审批:")) {
                    Integer inspectId = null;
                    String remark = approveProcess.getApproveRemark();
                    // 新逻辑:业务参数放在 approveRemark
                    if (org.springframework.util.StringUtils.hasText(remark) && remark.startsWith("qualityQualifiedInbound:")) {
                        String[] split = remark.split(":");
                        if (split.length >= 2) {
                            inspectId = Integer.valueOf(split[1]);
                        }
                    }
                    if (inspectId == null) {
                        String[] split = reason.split(":");
                        if (split.length >= 2) {
                            inspectId = Integer.valueOf(split[1]);
                        }
                    }
                    if (inspectId != null) {
                        if (status.equals(2)) {
                            qualityInspectService.executeQualifiedInboundApproval(inspectId);
                        } else if (status.equals(3)) {
                            qualityInspectService.markQualifiedInboundApprovalStatus(inspectId, 4);
                        } else if (status.equals(1)) {
                            qualityInspectService.markQualifiedInboundApprovalStatus(inspectId, 2);
                        }
                    }
                    // 质检审批不需要继续走销售订单入库
                    return;
                }
                if (reason.startsWith("销售扫码不合格入库审批:") || reason.startsWith("销售扫码合格入库审批:")) {
                    String remark = approveProcess.getApproveRemark();
                    boolean qualified = reason.startsWith("销售扫码合格入库审批:");
                    String prefix = qualified ? "scanQualified:" : "scanUnqualified:";
                    if (org.springframework.util.StringUtils.hasText(remark) && remark.startsWith(prefix)) {
                        String[] split = remark.split(":");
                        if (split.length >= 3) {
                            Long salesLedgerId = Long.valueOf(split[1]);
                            java.util.Map<Long, BigDecimal> inboundQtyByLineId = Arrays.stream(split[2].split(","))
                                    .filter(org.springframework.util.StringUtils::hasText)
                                    .map(s -> s.split("@"))
                                    .filter(arr -> arr.length == 2)
                                    .collect(java.util.stream.Collectors.toMap(
                                            arr -> Long.valueOf(arr[0]),
                                            arr -> new BigDecimal(arr[1]),
                                            BigDecimal::add,
                                            java.util.LinkedHashMap::new));
                            if (status.equals(2)) {
                                if (qualified) {
                                    salesLedgerService.executeSalesScanInboundApproved(salesLedgerId, inboundQtyByLineId);
                                } else {
                                    salesLedgerService.executeSalesScanInboundUnqualifiedApproved(salesLedgerId, inboundQtyByLineId);
                                }
                            }
                        }
                    }
                    return;
                }
                String[] split = reason.split(":");
                Long salesLedgerId = null;
                List<Long> productIds = null;
                //  入库审批理由只展示合同号    参数放在 approveRemark
                if (reason.startsWith("入库审批:")) {
                    String remark = approveProcess.getApproveRemark();
                    if (org.springframework.util.StringUtils.hasText(remark) && remark.startsWith("salesStock:")) {
                        String[] r = remark.split(":");
                        if (r.length >= 3) {
                            salesLedgerId = Long.valueOf(r[1]);
                            productIds = Arrays.stream(r[2].split(","))
                                    .filter(org.springframework.util.StringUtils::hasText)
                                    .map(Long::valueOf)
                                    .collect(java.util.stream.Collectors.toList());
                        }
                    }
                }
                //  入库审批:合同号:salesLedgerId:productId1,productId2
                if (salesLedgerId == null && split.length >= 4) {
                    salesLedgerId = Long.valueOf(split[2]);
                    productIds = Arrays.stream(split[3].split(","))
                            .filter(org.springframework.util.StringUtils::hasText)
                            .map(Long::valueOf)
                            .collect(java.util.stream.Collectors.toList());
                }
                if (salesLedgerId != null && productIds != null) {
                    if (status.equals(2)) {
                        // 审批通过执行入库
                        salesLedgerService.executeSalesStockApproved(salesLedgerId, productIds);
                    }
                }
            }
        }
        // 绑定附件
        if(!CollectionUtils.isEmpty(approveNode.getTempFileIds()) && approveNode.getApproveNodeStatus() == 1){
            tempFileService.migrateTempFilesToFormal(approveNode.getId(), approveNode.getTempFileIds(), FileNameType.ApproveNode.getValue());
        }
    }
    private void updateShippingInfoStatusByOrder(Long salesLedgerId, String statusText) {
        if (salesLedgerId == null) return;
        shippingInfoMapper.update(null, new UpdateWrapper<ShippingInfo>()
                .lambda()
                .set(ShippingInfo::getStatus, statusText)
                .eq(ShippingInfo::getSalesLedgerId, salesLedgerId));
    }
    private void updateSalesLedgerDeliveryStatus(Long salesLedgerId, Integer status) {
        if (salesLedgerId == null) return;
        SalesLedger salesLedger = salesLedgerMapper.selectById(salesLedgerId);
        if (salesLedger != null) {
            salesLedger.setDeliveryStatus(status);
            salesLedgerMapper.updateById(salesLedger);
        }
    }
@@ -197,11 +421,17 @@
                        .eq(ApproveProcess::getApproveId, approveNode.getApproveProcessId())).get(0);
                if (approveProcess.getApproveUserIds().split(",").length > nodeOrder){
                    String id = approveProcess.getApproveUserIds().split(",")[nodeOrder];
                    sysNoticeService.simpleNoticeByUser(approveProcessType(approveProcess.getApproveType()),
                            approveNode.getApproveProcessId()+"流程编号的审批需要您审核!!!!!",
                            Arrays.asList(Long.valueOf(id)),
                            approveNode.getTenantId(),
                            "/collaborativeApproval/approvalProcess?approveType="+approveProcess.getApproveType()+"&approveId="+approveNode.getApproveProcessId());
                    if (approveProcess.getApproveType()==8){
                        sysNoticeService.simpleNoticeByUser(approveProcessType(approveProcess.getApproveType()),
                                approveProcess.getApproveId() + "流程编号的审批需要您审核!!!!!",
                                Arrays.asList(Long.valueOf(id)),
                                "/safeProduction/safeWorkApproval?approveType=" + approveProcess.getApproveType() + "&approveId=" + approveProcess.getApproveId());
                    }else {
                        sysNoticeService.simpleNoticeByUser(approveProcessType(approveProcess.getApproveType()),
                                approveProcess.getApproveId() + "流程编号的审批需要您审核!!!!!",
                                Arrays.asList(Long.valueOf(id)),
                                "/collaborativeApproval/approvalProcess?approveType=" + approveProcess.getApproveType() + "&approveId=" + approveProcess.getApproveId());
                    }
                }
                break;
            case 2:
@@ -215,11 +445,17 @@
    }
    @Override
    public void delApproveNodeByApproveId(Long id) {
    public void delApproveNodeByApproveId(String id) {
        List<ApproveNode> approveNodes = approveNodeMapper.selectList(new LambdaQueryWrapper<ApproveNode>()
                .eq(ApproveNode::getApproveProcessId, id));
        UpdateWrapper<ApproveNode> queryWrapper = new UpdateWrapper<>();
        queryWrapper.lambda().set(ApproveNode::getDeleteFlag, 1)
                .eq(ApproveNode::getApproveProcessId, id);
        update(queryWrapper);
        // 删除附件
        for (ApproveNode approveNode : approveNodes) {
            commonFileService.deleteByBusinessId(approveNode.getId(), FileNameType.ApproveNode.getValue());
        }
    }
    //审批类型获取(与前端页面对应)
@@ -238,7 +474,11 @@
            case 6:
                return "报价审批";
            case 7:
                return "出库审批";
                return "发货审批";
            case 8:
                return "危险作业审批";
            case 9:
                return "入库审批";
        }
        return null;
    }