14 小时以前 027a1c30ea0216080c3472c6c6b28acec4077c7d
src/main/java/com/ruoyi/mock/service/impl/DataGenerateServiceImpl.java
@@ -4,12 +4,16 @@
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.ai.assistant.Assistant;
import com.ruoyi.approve.mapper.ApprovalInstanceMapper;
import com.ruoyi.approve.pojo.ApprovalInstance;
import com.ruoyi.approve.service.ApprovalInstanceService;
import com.ruoyi.basic.mapper.ProductMapper;
import com.ruoyi.basic.mapper.ProductModelMapper;
import com.ruoyi.basic.pojo.Customer;
import com.ruoyi.basic.pojo.SupplierManage;
import com.ruoyi.basic.service.ICustomerService;
import com.ruoyi.basic.service.ISupplierService;
import com.ruoyi.common.enums.ReviewStatusEnum;
import com.ruoyi.mock.dto.DataGenerateRequest;
import com.ruoyi.mock.prompt.MockDataPrompt;
import com.ruoyi.mock.service.DataGenerateService;
@@ -20,15 +24,19 @@
import com.ruoyi.production.service.ProductionOrderService;
import com.ruoyi.production.service.ProductionPlanService;
import com.ruoyi.purchase.dto.PurchaseLedgerDto;
import com.ruoyi.purchase.pojo.PurchaseLedger;
import com.ruoyi.purchase.service.IPurchaseLedgerService;
import com.ruoyi.quality.pojo.QualityInspect;
import com.ruoyi.quality.pojo.QualityTestStandard;
import com.ruoyi.quality.pojo.QualityTestStandardBinding;
import com.ruoyi.quality.service.IQualityInspectService;
import com.ruoyi.quality.service.IQualityTestStandardService;
import com.ruoyi.quality.service.QualityTestStandardBindingService;
import com.ruoyi.sales.dto.SalesLedgerDto;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import com.ruoyi.sales.service.ISalesLedgerService;
import com.ruoyi.stock.dto.StockInventoryDto;
import com.ruoyi.stock.service.StockInRecordService;
import com.ruoyi.stock.service.StockInventoryService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -37,10 +45,13 @@
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
@Slf4j
@@ -61,6 +72,12 @@
    private final ProductionPlanService productionPlanService;
    private final ProductionOrderService productionOrderService;
    private final StockInventoryService stockInventoryService;
    // 采购完整流程需要的service
    private final ApprovalInstanceService approvalInstanceService;
    private final ApprovalInstanceMapper approvalInstanceMapper;
    private final IQualityInspectService qualityInspectService;
    private final StockInRecordService stockInRecordService;
    @Override
    public DataGenerateResult generate(DataGenerateRequest request) {
@@ -134,7 +151,8 @@
                totalGenerated += s.getSuccessCount();
            }
            if (grouped.containsKey("purchaseLedger")) {
                ModuleSummary s = createPurchaseLedgers(grouped.get("purchaseLedger"), supplierNameToId);
                ModuleSummary s = createPurchaseLedgers(grouped.get("purchaseLedger"), supplierNameToId,
                        request.getAdditionalInfo(), request.getDateEnd());
                summaries.add(s);
                totalGenerated += s.getSuccessCount();
            }
@@ -357,7 +375,11 @@
        return summary("sales", "销售台账", items.size(), success, fail);
    }
    private ModuleSummary createPurchaseLedgers(List<JSONObject> items, Map<String, Long> supplierNameToId) {
    private ModuleSummary createPurchaseLedgers(List<JSONObject> items, Map<String, Long> supplierNameToId,
                                                 String additionalInfo, String dateEnd) {
        // 是否需要质检,从补充信息判断,默认不需要
        boolean needQualityInspect = additionalInfo != null
                && (additionalInfo.contains("质检") || additionalInfo.contains("需要检验"));
        int success = 0, fail = 0;
        for (JSONObject item : items) {
            try {
@@ -371,8 +393,12 @@
                dto.setProjectName(item.getString("projectName"));
                dto.setContractAmount(item.getBigDecimal("contractAmount"));
                dto.setPaymentMethod(item.getString("paymentMethod"));
                String entryDateStr = item.getString("entryDate");
                LocalDate entryDate = null;
                if (item.containsKey("entryDate")) {
                    dto.setEntryDate(java.sql.Date.valueOf(item.getString("entryDate")));
                    entryDate = LocalDate.parse(entryDateStr);
                    dto.setEntryDate(java.sql.Date.valueOf(entryDateStr));
                }
                if (item.containsKey("executionDate")) {
                    dto.setExecutionDate(java.sql.Date.valueOf(item.getString("executionDate")));
@@ -391,6 +417,8 @@
                        slp.setTaxRate(pd.getBigDecimal("taxRate"));
                        slp.setUnit(pd.getString("unit"));
                        slp.setType(2);
                        // 是否质检:从补充信息判断,默认不需要
                        slp.setIsChecked(needQualityInspect);
                        if (pd.containsKey("taxExclusiveTotalPrice")) {
                            slp.setTaxExclusiveTotalPrice(pd.getBigDecimal("taxExclusiveTotalPrice"));
                        } else if (pd.getBigDecimal("taxInclusiveTotalPrice") != null && pd.getBigDecimal("taxRate") != null) {
@@ -406,6 +434,15 @@
                    dto.setProductData(products);
                }
                purchaseLedgerService.addOrEditPurchase(dto);
                // 通过合同号找到刚创建的采购台账
                PurchaseLedger savedLedger = purchaseLedgerService.getOne(
                        new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<PurchaseLedger>()
                                .eq(PurchaseLedger::getPurchaseContractNumber, dto.getPurchaseContractNumber())
                                .last("limit 1"));
                if (savedLedger != null) {
                    // 走完整流程:审核通过 → 质检(可选) → 入库 + 入库审核通过
                    processPurchaseFullFlow(savedLedger, needQualityInspect, entryDate, dateEnd);
                }
                success++;
            } catch (Exception e) {
                log.warn("创建采购台账失败: {}", e.getMessage());
@@ -415,6 +452,108 @@
        return summary("purchase", "采购台账", items.size(), success, fail);
    }
    /**
     * 采购完整流程: 审核通过 → 质检(可选) → 入库审核通过
     */
    private void processPurchaseFullFlow(PurchaseLedger purchaseLedger, boolean needQualityInspect,
                                          LocalDate entryDate, String dateEnd) {
        try {
            // 1. 审批自动通过
            ApprovalInstance approvalInstance = approvalInstanceMapper.selectOne(
                    new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<ApprovalInstance>()
                            .eq(ApprovalInstance::getBusinessId, purchaseLedger.getId())
                            .eq(ApprovalInstance::getBusinessType, 5L)
                            .eq(ApprovalInstance::getDeleted, 0)
                            .orderByDesc(ApprovalInstance::getId)
                            .last("limit 1"));
            if (approvalInstance != null) {
                // 结算审批开始时间:基于录入日期,随机推0-3天
                LocalDate baseDate = entryDate != null ? entryDate : LocalDate.now();
                LocalDate approveDate = baseDate.plusDays(ThreadLocalRandom.current().nextInt(0, 4));
                // 使用autoApprove完成审批
                approvalInstanceService.autoApprove(approvalInstance.getId());
                log.info("采购台账[{}]审批通过, 审批日期: {}", purchaseLedger.getPurchaseContractNumber(), approveDate);
            }
            // 2. 质检流程(如果需要质检)
            if (needQualityInspect) {
                processQualityInspect(purchaseLedger, entryDate, dateEnd);
            }
            // 3. 入库审批通过
            processStockInApprove(purchaseLedger, dateEnd);
        } catch (Exception e) {
            log.warn("采购完整流程处理失败[{}]: {}", purchaseLedger.getPurchaseContractNumber(), e.getMessage());
        }
    }
    /**
     * 质检: 找到采购关联的质检单,自动提交为合格
     */
    private void processQualityInspect(PurchaseLedger purchaseLedger, LocalDate entryDate, String dateEnd) {
        try {
            List<QualityInspect> inspectList = qualityInspectService.list(
                    new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<QualityInspect>()
                            .eq(QualityInspect::getPurchaseLedgerId, purchaseLedger.getId()));
            for (QualityInspect qi : inspectList) {
                if (qi.getInspectState() == null || qi.getInspectState() == 0) {
                    qualityInspectService.autoSubmit(qi.getId());
                    log.info("采购台账[{}]质检单[{}]自动提交合格", purchaseLedger.getPurchaseContractNumber(), qi.getId());
                }
            }
        } catch (Exception e) {
            log.warn("质检流程处理失败[{}]: {}", purchaseLedger.getPurchaseContractNumber(), e.getMessage());
        }
    }
    /**
     * 入库审核: 找到入库记录并审批通过
     */
    private void processStockInApprove(PurchaseLedger purchaseLedger, String dateEnd) {
        try {
            List<com.ruoyi.stock.pojo.StockInRecord> stockRecords = stockInRecordService.list(
                    new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<com.ruoyi.stock.pojo.StockInRecord>()
                            .eq(com.ruoyi.stock.pojo.StockInRecord::getRecordId, purchaseLedger.getId())
                            .eq(com.ruoyi.stock.pojo.StockInRecord::getRecordType,
                                    String.valueOf(com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum.PURCHASE_STOCK_IN.getCode())));
            // 如果按PURCHASE_STOCK_IN找不到,尝试CUSTOMIZATION_UNSTOCK_OUT(质检合格入库)
            if (stockRecords.isEmpty()) {
                stockRecords = stockInRecordService.list(
                        new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<com.ruoyi.stock.pojo.StockInRecord>()
                                .eq(com.ruoyi.stock.pojo.StockInRecord::getRecordId, purchaseLedger.getId())
                                .eq(com.ruoyi.stock.pojo.StockInRecord::getRecordType,
                                        String.valueOf(com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum.CUSTOMIZATION_UNSTOCK_OUT.getCode())));
            }
            // 也尝试按质检单ID查找(质检单的recordId是质检单ID)
            for (QualityInspect qi : qualityInspectService.list(
                    new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<QualityInspect>()
                            .eq(QualityInspect::getPurchaseLedgerId, purchaseLedger.getId()))) {
                List<com.ruoyi.stock.pojo.StockInRecord> qiRecords = stockInRecordService.list(
                        new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<com.ruoyi.stock.pojo.StockInRecord>()
                                .eq(com.ruoyi.stock.pojo.StockInRecord::getRecordId, qi.getId()));
                stockRecords.addAll(qiRecords);
            }
            // 去重
            stockRecords = stockRecords.stream()
                    .collect(Collectors.toMap(com.ruoyi.stock.pojo.StockInRecord::getId, r -> r, (a, b) -> a))
                    .values().stream().collect(Collectors.toList());
            if (!stockRecords.isEmpty()) {
                List<Long> recordIds = stockRecords.stream()
                        .filter(r -> r.getApprovalStatus() == null || r.getApprovalStatus() == 0)
                        .map(com.ruoyi.stock.pojo.StockInRecord::getId)
                        .collect(Collectors.toList());
                if (!recordIds.isEmpty()) {
                    stockInRecordService.batchApprove(recordIds, ReviewStatusEnum.APPROVED.getCode());
                    log.info("采购台账[{}]入库审批通过, 入库记录数: {}", purchaseLedger.getPurchaseContractNumber(), recordIds.size());
                }
            }
        } catch (Exception e) {
            log.warn("入库审批失败[{}]: {}", purchaseLedger.getPurchaseContractNumber(), e.getMessage());
        }
    }
    private ModuleSummary createProductionPlans(List<JSONObject> items) {
        int success = 0, fail = 0;
        for (JSONObject item : items) {