From fd5ff7ce41f402720c79546617842bbf679e576e Mon Sep 17 00:00:00 2001
From: tuqin <tuqin@tuqin.cn>
Date: 星期三, 21 十月 2026 16:32:55 +0800
Subject: [PATCH] fix(销售台账/产品维护): 图号与销售合同号长度校验、导入提示优化

---
 src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java |  115 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 105 insertions(+), 10 deletions(-)

diff --git a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
index b52b8bf..c2f95c1 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -12,12 +12,14 @@
 import com.ruoyi.account.mapper.sales.AccountSalesCollectionMapper;
 import com.ruoyi.account.pojo.sales.AccountInvoiceApplication;
 import com.ruoyi.account.pojo.sales.AccountSalesCollection;
+import com.ruoyi.basic.dto.StorageAttachmentDTO;
 import com.ruoyi.basic.enums.ApplicationTypeEnum;
 import com.ruoyi.basic.enums.RecordTypeEnum;
 import com.ruoyi.basic.mapper.CustomerMapper;
 import com.ruoyi.basic.mapper.ProductMapper;
 import com.ruoyi.basic.mapper.ProductModelMapper;
 import com.ruoyi.basic.pojo.Customer;
+import com.ruoyi.basic.pojo.ProductModel;
 import com.ruoyi.basic.utils.FileUtil;
 import com.ruoyi.common.enums.FileNameType;
 import com.ruoyi.common.enums.SaleEnum;
@@ -210,6 +212,12 @@
             resultDto.setProductData(products);
             resultDto.setSalesLedgerFiles(salesLedgerFiles);
         }
+
+        StorageAttachmentDTO attachmentQuery = new StorageAttachmentDTO();
+        attachmentQuery.setApplication(ApplicationTypeEnum.FILE.getType());
+        attachmentQuery.setRecordType(RecordTypeEnum.SALES_LEDGER.getType());
+        attachmentQuery.setRecordId(salesLedger.getId());
+        resultDto.setStorageBlobVOs(fileUtil.getStorageBlobVOsByApplicationAndRecordTypeAndRecordId(attachmentQuery));
         return resultDto;
     }
 
@@ -354,13 +362,37 @@
             // 褰曞叆浜烘暟鎹�
             List<SysUser> sysUsers = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>().in(SysUser::getNickName,
                     salesLedgerImportDtoList.stream().map(SalesLedgerImportDto::getEntryPerson).collect(Collectors.toList())));
-            for (SalesLedgerImportDto salesLedgerImportDto : salesLedgerImportDtoList) {
-                SalesLedger salesLedger1 = salesLedgerMapper.selectOne(new LambdaQueryWrapper<SalesLedger>()
-                        .eq(SalesLedger::getSalesContractNo, salesLedgerImportDto.getSalesContractNo())
-                        .last("LIMIT 1"));
-                if (salesLedger1 != null) {
+            // 閿�鍞崟鍙烽噸澶嶆牎楠岋細鏂囦欢鍐呴噸澶嶆垨搴撳唴宸插瓨鍦ㄧ殑锛岀洿鎺ュけ璐ュ苟鍥炴樉鍘熸湁閿�鍞崟鍙�
+            List<String> duplicateContractNos = new ArrayList<>();
+            Set<String> importContractNos = new HashSet<>();
+            for (SalesLedgerImportDto item : salesLedgerImportDtoList) {
+                String contractNo = StringUtils.trim(item.getSalesContractNo());
+                if (StringUtils.isEmpty(contractNo)) {
                     continue;
                 }
+                if (contractNo.length() > 50) {
+                    return AjaxResult.error("閿�鍞崟鍙枫��" + contractNo + "銆戦暱搴︿笉鑳借秴杩�50涓瓧绗�");
+                }
+                if (!importContractNos.add(contractNo)) {
+                    duplicateContractNos.add(contractNo);
+                }
+            }
+            if (CollectionUtils.isNotEmpty(duplicateContractNos)) {
+                return AjaxResult.error("瀵煎叆鏂囦欢涓瓨鍦ㄩ噸澶嶇殑閿�鍞崟鍙凤細" + String.join("銆�", duplicateContractNos));
+            }
+            if (CollectionUtils.isNotEmpty(importContractNos)) {
+                List<SalesLedger> existLedgers = salesLedgerMapper.selectList(new LambdaQueryWrapper<SalesLedger>()
+                        .in(SalesLedger::getSalesContractNo, importContractNos)
+                        .select(SalesLedger::getId, SalesLedger::getSalesContractNo));
+                if (CollectionUtils.isNotEmpty(existLedgers)) {
+                    String existNos = existLedgers.stream()
+                            .map(SalesLedger::getSalesContractNo)
+                            .distinct()
+                            .collect(Collectors.joining("銆�"));
+                    return AjaxResult.error("浠ヤ笅閿�鍞崟鍙峰凡瀛樺湪锛屼笉鑳介噸澶嶆柊澧烇細" + existNos);
+                }
+            }
+            for (SalesLedgerImportDto salesLedgerImportDto : salesLedgerImportDtoList) {
                 SalesLedger salesLedger = new SalesLedger();
                 BeanUtils.copyProperties(salesLedgerImportDto, salesLedger);
                 salesLedger.setExecutionDate(DateUtils.toLocalDate(salesLedgerImportDto.getExecutionDate()));
@@ -382,7 +414,7 @@
                         .map(SysUser::getUserId)
                         .orElse(null);
                 if (aLong == null)
-                    throw new RuntimeException("褰曞叆浜�:" + salesLedger.getEntryPerson() + ",鏃犲搴旂敤鎴凤紒");
+                    throw new RuntimeException("褰曞叆浜�:" + salesLedger.getEntryPerson() + ",鏃犲搴旂敤鎴凤紒璇峰~鍐欑郴缁熺敤鎴风殑鏄电О锛堜笉鏄櫥褰曡处鍙凤級");
                 salesLedger.setEntryPerson(aLong.toString());
                 // 閿�鍞骇鍝佹暟鎹粦瀹氾紝閫氳繃閿�鍞崟鍙疯幏鍙栧搴旈攢鍞骇鍝佹暟鎹�
                 List<SalesLedgerProductImportDto> salesLedgerProductImportDtos = salesLedgerProductImportDtoList.stream()
@@ -401,6 +433,11 @@
                     BeanUtils.copyProperties(salesLedgerProductImportDto, salesLedgerProduct);
                     salesLedgerProduct.setSalesLedgerId(salesLedger.getId());
                     salesLedgerProduct.setType(1);
+                    // 鐗╂枡缂栫爜 -> 浜у搧缂栫爜
+                    String materialCode = StringUtils.trim(salesLedgerProductImportDto.getMaterialCode());
+                    if (StringUtils.isNotEmpty(materialCode)) {
+                        salesLedgerProduct.setProductCode(materialCode);
+                    }
                     AmountUtils.normalizeSalesLedgerProduct(salesLedgerProduct);
                     // 璁$畻涓嶅惈绋庢�讳环
                     salesLedgerProduct.setTaxExclusiveTotalPrice(
@@ -415,6 +452,10 @@
                             .ifPresent(map -> {
                                 salesLedgerProduct.setProductModelId(Long.parseLong(map.get("modelId").toString()));
                                 salesLedgerProduct.setProductId(Long.parseLong(map.get("id").toString()));
+                                // 鏈~鐗╂枡缂栫爜鏃讹紝鎸変骇鍝佸瀷鍙峰洖濉骇鍝佺紪鐮�
+                                if (StringUtils.isEmpty(salesLedgerProduct.getProductCode()) && map.get("productCode") != null) {
+                                    salesLedgerProduct.setProductCode(map.get("productCode").toString());
+                                }
                             });
 //                    salesLedgerProduct.setProductId(productList.stream()
 //                            .filter(product -> product.getProductName().equals(salesLedgerProduct.getProductCategory()))
@@ -429,7 +470,7 @@
                     salesLedgerProduct.setRegister(loginUser.getNickName());
                     salesLedgerProduct.setRegisterDate(LocalDateTime.now());
                     salesLedgerProduct.setApproveStatus(0);
-                    salesLedgerProduct.setIsProduction(salesLedgerProductImportDto.getIsProduction() == 1);
+                    salesLedgerProduct.setIsProduction(parseProductionFlag(salesLedgerProductImportDto.getIsProduction()));
                     salesLedgerProductMapper.insert(salesLedgerProduct);
                     // 娣诲姞鐢熶骇鏁版嵁
                     salesLedgerProductServiceImpl.addProductionData(salesLedgerProduct);
@@ -575,9 +616,17 @@
         AmountUtils.normalizeContractAmount(salesLedger);
         salesLedger.setCustomerName(customer.getCustomerName());
         salesLedger.setTenantId(customer.getTenantId());
-        // 3. 鏂板鎴栨洿鏂颁富琛�
+        // 3. 閿�鍞悎鍚屽彿鍞竴鏍¢獙锛堟敮鎸佸瓧姣嶃�佹暟瀛楀強鐗规畩瀛楃锛屼笉鍋氬瓧绗﹂泦闄愬埗锛�
+        String contractNo = StringUtils.trim(salesLedger.getSalesContractNo());
+        if (StringUtils.isNotEmpty(contractNo)) {
+            if (contractNo.length() > 50) {
+                throw new BaseException("閿�鍞悎鍚屽彿闀垮害涓嶈兘瓒呰繃50涓瓧绗�");
+            }
+            checkSalesContractNoUnique(contractNo, salesLedger.getId());
+            salesLedger.setSalesContractNo(contractNo);
+        }
+        // 4. 鏂板鎴栨洿鏂颁富琛�
         if (salesLedger.getId() == null) {
-            String contractNo = salesLedger.getSalesContractNo();
             if (StringUtils.isEmpty(contractNo)) {
                 contractNo = generateSalesContractNo();
             }
@@ -588,7 +637,7 @@
         }
 
 
-        // 4. 澶勭悊瀛愯〃鏁版嵁
+        // 5. 澶勭悊瀛愯〃鏁版嵁
         List<SalesLedgerProduct> productList = salesLedgerDto.getProductData();
         if (productList != null && !productList.isEmpty()) {
             AmountUtils.normalizeSalesLedgerProducts(productList);
@@ -608,8 +657,31 @@
         return 1;
     }
 
+    /**
+     * 閿�鍞悎鍚屽彿鍞竴鏍¢獙锛堢紪杈戞椂鎺掗櫎鑷韩锛�
+     */
+    private void checkSalesContractNoUnique(String salesContractNo, Long currentId) {
+        LambdaQueryWrapper<SalesLedger> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(SalesLedger::getSalesContractNo, salesContractNo)
+                .ne(currentId != null, SalesLedger::getId, currentId)
+                .last("limit 1");
+        SalesLedger duplicate = salesLedgerMapper.selectOne(queryWrapper);
+        if (duplicate != null) {
+            throw new BaseException("閿�鍞悎鍚屽彿" + salesContractNo + "宸插瓨鍦紙閿�鍞崟鍙凤細" + duplicate.getSalesContractNo() + "锛夛紝璇烽噸鏂板~鍐�");
+        }
+    }
+
     @Override
     public void handleSalesLedgerProducts(Long salesLedgerId, List<SalesLedgerProduct> products, SaleEnum type) {
+        // 浜у搧缂栫爜鍏滃簳锛氬墠绔湭浼犳椂鎸変骇鍝佸瀷鍙峰洖濉�
+        products.forEach(p -> {
+            if (StringUtils.isEmpty(p.getProductCode()) && p.getProductModelId() != null) {
+                ProductModel productModel = productModelMapper.selectById(p.getProductModelId());
+                if (productModel != null) {
+                    p.setProductCode(productModel.getProductCode());
+                }
+            }
+        });
         // 鎸塈D鍒嗙粍锛屽尯鍒嗘柊澧炲拰鏇存柊鐨勮褰�
         Map<Boolean, List<SalesLedgerProduct>> partitionedProducts = products.stream()
                 .peek(p -> p.setSalesLedgerId(salesLedgerId))
@@ -636,6 +708,17 @@
                 salesLedgerProductServiceImpl.addProductionData(salesLedgerProduct);
             }
         }
+    }
+
+    /**
+     * 瑙f瀽瀵煎叆鐨勨�滄槸鍚︾敓浜р�濆垪锛氭敮鎸� 1/0銆佹槸/鍚�
+     */
+    private static boolean parseProductionFlag(String value) {
+        if (StringUtils.isEmpty(value)) {
+            return false;
+        }
+        String v = value.trim();
+        return "1".equals(v) || "鏄�".equals(v) || "true".equalsIgnoreCase(v) || "yes".equalsIgnoreCase(v);
     }
 
     private SalesLedger convertToEntity(SalesLedgerDto dto) {
@@ -793,4 +876,16 @@
         result.put("ledger", ledger);
         return result;
     }
+
+    @Override
+    public Map<Long, SalesLedgerEditFlagDto> getEditFlags(List<Long> ids) {
+        if (CollectionUtils.isEmpty(ids)) {
+            return new HashMap<>();
+        }
+        List<SalesLedgerEditFlagDto> flags = salesLedgerMapper.selectEditFlags(ids);
+        return flags.stream().collect(Collectors.toMap(
+                SalesLedgerEditFlagDto::getSalesLedgerId,
+                Function.identity(),
+                (existing, replacement) -> existing));
+    }
 }

--
Gitblit v1.9.3