From 0388d54af57e8d3d4a99554501b232ca572b50c6 Mon Sep 17 00:00:00 2001
From: 吴羡 <16976746+Xian-TT3@user.noreply.gitee.com>
Date: 星期一, 12 十月 2026 17:48:51 +0800
Subject: [PATCH] 客户满意度新增附件与委托单关联;供应商管理新增附件;标准物质接收、记录、验收模块调整;委托单新增已完成列表接口(满意度下拉用);管理记录服务调整

---
 cnas-require/src/main/java/com/ruoyi/require/pojo/FeStandardSubstanceRecord.java                        |   15 +
 cnas-require/src/main/java/com/ruoyi/require/service/FeStandardSubstanceRecordService.java              |    4 
 cnas-require/src/main/java/com/ruoyi/require/controller/SupplierManagementController.java               |   20 +
 cnas-require/src/main/java/com/ruoyi/require/pojo/SupplierManagementAttachment.java                     |   28 ++
 cnas-require/src/main/resources/mapper/FeStandardSubstanceRecordMapper.xml                              |    8 
 cnas-manage/src/main/java/com/ruoyi/manage/service/impl/ManageRecordIntervalsServiceImpl.java           |   36 +-
 cnas-manage/src/main/java/com/ruoyi/manage/controller/ClientSatisfactionController.java                 |   28 ++
 cnas-require/src/main/java/com/ruoyi/require/mapper/SupplierManagementAttachmentMapper.java             |    9 
 cnas-require/src/main/java/com/ruoyi/require/pojo/FeStandardSubstanceAcceptance.java                    |    3 
 inspect-server/src/main/java/com/ruoyi/inspect/controller/InsOrderController.java                       |   13 +
 cnas-manage/src/main/java/com/ruoyi/manage/pojo/ClientSatisfaction.java                                 |    9 
 cnas-require/src/main/java/com/ruoyi/require/service/impl/FeStandardSubstanceRecordServiceImpl.java     |   56 +++-
 cnas-require/src/main/java/com/ruoyi/require/service/impl/FeStandardSubstanceAcceptanceServiceImpl.java |    8 
 cnas-require/src/main/java/com/ruoyi/require/excel/FeStandardSubstanceImport.java                       |    5 
 cnas-require/src/main/java/com/ruoyi/require/excel/FeStandardSubstanceExcel.java                        |    4 
 cnas-require/src/main/java/com/ruoyi/require/service/impl/SupplierManagementServiceImpl.java            |   68 ++++++
 cnas-manage/src/main/java/com/ruoyi/manage/pojo/ClientSatisfactionAttachment.java                       |   31 ++
 cnas-manage/src/main/java/com/ruoyi/manage/service/impl/ClientSatisfactionServiceImpl.java              |   79 +++++++
 cnas-require/src/main/java/com/ruoyi/require/controller/FeStandardSubstanceAcceptanceController.java    |   17 +
 cnas-require/src/main/java/com/ruoyi/require/dto/AcceptanceDto.java                                     |    3 
 cnas-require/src/main/java/com/ruoyi/require/service/impl/FeStandardSubstanceServiceImpl.java           |    3 
 cnas-require/src/main/java/com/ruoyi/require/vo/SubstanceRecordVo.java                                  |   25 +-
 cnas-manage/src/main/java/com/ruoyi/manage/service/impl/ManageRecordVerifyServiceImpl.java              |   46 ++--
 cnas-require/src/main/java/com/ruoyi/require/service/SupplierManagementService.java                     |    8 
 cnas-require/src/main/java/com/ruoyi/require/vo/AcceptanceVo.java                                       |   14 +
 cnas-require/src/main/java/com/ruoyi/require/controller/FeStandardSubstanceRecordController.java        |   10 
 cnas-require/src/main/resources/mapper/FeStandardSubstanceAcceptanceMapper.xml                          |    4 
 cnas-manage/src/main/java/com/ruoyi/manage/mapper/ClientSatisfactionAttachmentMapper.java               |   12 +
 cnas-manage/src/main/java/com/ruoyi/manage/service/ClientSatisfactionService.java                       |   24 ++
 cnas-require/src/main/java/com/ruoyi/require/pojo/FeStandardSubstance.java                              |   15 +
 30 files changed, 514 insertions(+), 91 deletions(-)

diff --git a/cnas-manage/src/main/java/com/ruoyi/manage/controller/ClientSatisfactionController.java b/cnas-manage/src/main/java/com/ruoyi/manage/controller/ClientSatisfactionController.java
index b5b0102..1bcbe55 100644
--- a/cnas-manage/src/main/java/com/ruoyi/manage/controller/ClientSatisfactionController.java
+++ b/cnas-manage/src/main/java/com/ruoyi/manage/controller/ClientSatisfactionController.java
@@ -136,5 +136,33 @@
     public Result delAnalyseFile(Integer analyseFileId){
         return Result.success(clientSatisfactionAnalyseFileMapper.deleteById(analyseFileId));
     }
+
+    /**
+     * 鏌ヨ婊℃剰搴﹂檮浠�
+     */
+    @Operation(summary = "鏌ヨ婊℃剰搴﹂檮浠�")
+    @GetMapping("/selectAttachments")
+    public Result selectAttachments(Integer clientSatisfactionId) {
+        return Result.success(clientSatisfactionService.selectAttachments(clientSatisfactionId));
+    }
+
+    /**
+     * 涓婁紶婊℃剰搴﹂檮浠�
+     */
+    @Operation(summary = "涓婁紶婊℃剰搴﹂檮浠�")
+    @PostMapping("/uploadAttachment")
+    public Result uploadAttachment(@RequestParam("clientSatisfactionId") Integer clientSatisfactionId,
+                                   @RequestParam("file") MultipartFile file) {
+        return Result.success(clientSatisfactionService.uploadAttachment(clientSatisfactionId, file));
+    }
+
+    /**
+     * 鍒犻櫎婊℃剰搴﹂檮浠�
+     */
+    @Operation(summary = "鍒犻櫎婊℃剰搴﹂檮浠�")
+    @DeleteMapping("/deleteAttachment")
+    public Result deleteAttachment(Long id) {
+        return Result.success(clientSatisfactionService.deleteAttachment(id));
+    }
 }
 
diff --git a/cnas-manage/src/main/java/com/ruoyi/manage/mapper/ClientSatisfactionAttachmentMapper.java b/cnas-manage/src/main/java/com/ruoyi/manage/mapper/ClientSatisfactionAttachmentMapper.java
new file mode 100644
index 0000000..5dc6027
--- /dev/null
+++ b/cnas-manage/src/main/java/com/ruoyi/manage/mapper/ClientSatisfactionAttachmentMapper.java
@@ -0,0 +1,12 @@
+package com.ruoyi.manage.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.manage.pojo.ClientSatisfactionAttachment;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 瀹㈡埛婊℃剰搴﹂檮浠�
+ */
+@Mapper
+public interface ClientSatisfactionAttachmentMapper extends BaseMapper<ClientSatisfactionAttachment> {
+}
diff --git a/cnas-manage/src/main/java/com/ruoyi/manage/pojo/ClientSatisfaction.java b/cnas-manage/src/main/java/com/ruoyi/manage/pojo/ClientSatisfaction.java
index f3c67e4..66ba1fa 100644
--- a/cnas-manage/src/main/java/com/ruoyi/manage/pojo/ClientSatisfaction.java
+++ b/cnas-manage/src/main/java/com/ruoyi/manage/pojo/ClientSatisfaction.java
@@ -73,6 +73,15 @@
     @Schema(description = "澶囨敞(瀵规垜浠殑甯屾湜)")
     private String remark;
 
+    @Schema(description = "濮旀墭鍗昳d(ins_order.id)")
+    private Integer orderId;
+
+    @Schema(description = "濮旀墭鍗曠紪鍙�")
+    private String entrustCode;
+
+    @Schema(description = "鏍峰搧鍚嶇О")
+    private String sampleName;
+
     @Schema(description = "鍒涘缓浜�")
     @TableField(fill = FieldFill.INSERT)
     private Integer createUser;
diff --git a/cnas-manage/src/main/java/com/ruoyi/manage/pojo/ClientSatisfactionAttachment.java b/cnas-manage/src/main/java/com/ruoyi/manage/pojo/ClientSatisfactionAttachment.java
new file mode 100644
index 0000000..f34cae9
--- /dev/null
+++ b/cnas-manage/src/main/java/com/ruoyi/manage/pojo/ClientSatisfactionAttachment.java
@@ -0,0 +1,31 @@
+package com.ruoyi.manage.pojo;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 瀹㈡埛婊℃剰搴﹂檮浠�
+ */
+@Data
+@TableName("cnas_client_satisfaction_attachment")
+public class ClientSatisfactionAttachment {
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    private Integer clientSatisfactionId;
+    private String fileName;
+    private String fileUrl;
+    private Integer sort;
+    @TableField(fill = FieldFill.INSERT)
+    private Integer createUser;
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private Integer updateUser;
+    @TableField(fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime updateTime;
+}
diff --git a/cnas-manage/src/main/java/com/ruoyi/manage/service/ClientSatisfactionService.java b/cnas-manage/src/main/java/com/ruoyi/manage/service/ClientSatisfactionService.java
index 4f8c4e9..39c3bcd 100644
--- a/cnas-manage/src/main/java/com/ruoyi/manage/service/ClientSatisfactionService.java
+++ b/cnas-manage/src/main/java/com/ruoyi/manage/service/ClientSatisfactionService.java
@@ -5,9 +5,11 @@
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.ruoyi.manage.pojo.ClientSatisfaction;
 import com.ruoyi.manage.pojo.ClientSatisfactionAnalyseFile;
+import com.ruoyi.manage.pojo.ClientSatisfactionAttachment;
 import org.springframework.web.multipart.MultipartFile;
 
 import jakarta.servlet.http.HttpServletResponse;
+import java.util.List;
 
 /**
  * 瀹㈡埛婊℃剰搴�
@@ -55,5 +57,27 @@
      * @param userId             淇敼浜篿d
      */
     void confirmClientSatisfaction(ClientSatisfaction clientSatisfaction, Integer userId);
+
+    /**
+     * 鏌ヨ婊℃剰搴﹂檮浠�
+     * @param clientSatisfactionId 婊℃剰搴﹁褰昳d
+     * @return
+     */
+    List<ClientSatisfactionAttachment> selectAttachments(Integer clientSatisfactionId);
+
+    /**
+     * 涓婁紶婊℃剰搴﹂檮浠�
+     * @param clientSatisfactionId 婊℃剰搴﹁褰昳d
+     * @param file
+     * @return
+     */
+    ClientSatisfactionAttachment uploadAttachment(Integer clientSatisfactionId, MultipartFile file);
+
+    /**
+     * 鍒犻櫎婊℃剰搴﹂檮浠�
+     * @param id 闄勪欢id
+     * @return
+     */
+    boolean deleteAttachment(Long id);
 }
 
diff --git a/cnas-manage/src/main/java/com/ruoyi/manage/service/impl/ClientSatisfactionServiceImpl.java b/cnas-manage/src/main/java/com/ruoyi/manage/service/impl/ClientSatisfactionServiceImpl.java
index e38e930..e61d9aa 100644
--- a/cnas-manage/src/main/java/com/ruoyi/manage/service/impl/ClientSatisfactionServiceImpl.java
+++ b/cnas-manage/src/main/java/com/ruoyi/manage/service/impl/ClientSatisfactionServiceImpl.java
@@ -1,5 +1,6 @@
 package com.ruoyi.manage.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -9,13 +10,16 @@
 import com.deepoove.poi.config.ConfigureBuilder;
 import com.deepoove.poi.data.Pictures;
 import com.ruoyi.common.core.domain.entity.User;
+import com.ruoyi.common.exception.base.BaseException;
 import com.ruoyi.common.utils.QueryWrappers;
 import com.ruoyi.framework.exception.ErrorException;
 import com.ruoyi.manage.dto.ClientSatisfactionDto;
 import com.ruoyi.manage.mapper.ClientSatisfactionAnalyseFileMapper;
+import com.ruoyi.manage.mapper.ClientSatisfactionAttachmentMapper;
 import com.ruoyi.manage.mapper.ClientSatisfactionMapper;
 import com.ruoyi.manage.pojo.ClientSatisfaction;
 import com.ruoyi.manage.pojo.ClientSatisfactionAnalyseFile;
+import com.ruoyi.manage.pojo.ClientSatisfactionAttachment;
 import com.ruoyi.manage.service.ClientSatisfactionService;
 import com.ruoyi.system.mapper.UserMapper;
 import org.springframework.beans.factory.annotation.Value;
@@ -24,12 +28,14 @@
 import jakarta.annotation.Resource;
 import jakarta.servlet.http.HttpServletResponse;
 import java.io.File;
+import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.URLEncoder;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.HashMap;
+import java.util.List;
 
 
 /**
@@ -43,6 +49,9 @@
 
     @Resource
     private ClientSatisfactionAnalyseFileMapper clientSatisfactionAnalyseFileMapper;
+
+    @Resource
+    private ClientSatisfactionAttachmentMapper clientSatisfactionAttachmentMapper;
 
     @Resource
     private UserMapper userMapper;
@@ -184,5 +193,75 @@
         clientSatisfaction.setConfirmStatus(1);
         baseMapper.updateById(clientSatisfaction);
     }
+
+    /**
+     * 鏌ヨ婊℃剰搴﹂檮浠�
+     *
+     * @param clientSatisfactionId 婊℃剰搴﹁褰昳d
+     * @return
+     */
+    @Override
+    public List<ClientSatisfactionAttachment> selectAttachments(Integer clientSatisfactionId) {
+        return clientSatisfactionAttachmentMapper.selectList(new QueryWrapper<ClientSatisfactionAttachment>().lambda()
+                .eq(ClientSatisfactionAttachment::getClientSatisfactionId, clientSatisfactionId)
+                .orderByAsc(ClientSatisfactionAttachment::getSort, ClientSatisfactionAttachment::getId));
+    }
+
+    /**
+     * 涓婁紶婊℃剰搴﹂檮浠�
+     *
+     * @param clientSatisfactionId 婊℃剰搴﹁褰昳d
+     * @param file
+     * @return
+     */
+    @Override
+    public ClientSatisfactionAttachment uploadAttachment(Integer clientSatisfactionId, MultipartFile file) {
+        if (baseMapper.selectById(clientSatisfactionId) == null) {
+            throw new BaseException("瀹㈡埛婊℃剰搴﹁皟鏌ヤ笉瀛樺湪");
+        }
+        if (file == null || file.isEmpty()) {
+            throw new BaseException("闄勪欢涓嶈兘涓虹┖");
+        }
+        // 绯荤粺鍏ㄥ眬涓婁紶涓婇檺涓�200MB锛岃繖閲屾彁鍓嶇粰鍑哄弸濂芥彁绀�
+        if (file.getSize() > 200L * 1024 * 1024) {
+            throw new BaseException("闄勪欢涓嶈兘瓒呰繃200MB");
+        }
+        String originalName = file.getOriginalFilename();
+        if (originalName == null || originalName.trim().isEmpty()) {
+            originalName = "鏈懡鍚嶆枃浠�";
+        }
+        // 涓埆娴忚鍣ㄥ彲鑳藉甫涓婅矾寰勫墠缂�锛屽彧淇濈暀鏂囦欢鍚嶆湰韬�
+        originalName = originalName.replaceAll(".*[/\\\\]", "");
+        try {
+            // 鍥剧墖鏀惧浘鐗囩洰褰曪紙/img 闈欐�佽矾寰勶級锛屽叾浣欎换鎰忔牸寮忔斁 word 鐩綍锛�/word 闈欐�佽矾寰勶級
+            boolean image = originalName.matches("(?i).+\\.(jpg|jpeg|png|gif)$");
+            File directory = new File(image ? imgUrl : wordUrl);
+            if (!directory.exists()) {
+                directory.mkdirs();
+            }
+            String fileUrl = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMddHHmmssSSS")) + "-" + originalName;
+            file.transferTo(new File(directory, fileUrl));
+            ClientSatisfactionAttachment attachment = new ClientSatisfactionAttachment();
+            attachment.setClientSatisfactionId(clientSatisfactionId);
+            attachment.setFileName(originalName);
+            attachment.setFileUrl(fileUrl);
+            attachment.setSort(selectAttachments(clientSatisfactionId).size());
+            clientSatisfactionAttachmentMapper.insert(attachment);
+            return attachment;
+        } catch (IOException e) {
+            throw new BaseException("闄勪欢涓婁紶澶辫触");
+        }
+    }
+
+    /**
+     * 鍒犻櫎婊℃剰搴﹂檮浠�
+     *
+     * @param id 闄勪欢id
+     * @return
+     */
+    @Override
+    public boolean deleteAttachment(Long id) {
+        return clientSatisfactionAttachmentMapper.deleteById(id) > 0;
+    }
 }
 
diff --git a/cnas-manage/src/main/java/com/ruoyi/manage/service/impl/ManageRecordIntervalsServiceImpl.java b/cnas-manage/src/main/java/com/ruoyi/manage/service/impl/ManageRecordIntervalsServiceImpl.java
index 9b24dc6..0d0dcad 100644
--- a/cnas-manage/src/main/java/com/ruoyi/manage/service/impl/ManageRecordIntervalsServiceImpl.java
+++ b/cnas-manage/src/main/java/com/ruoyi/manage/service/impl/ManageRecordIntervalsServiceImpl.java
@@ -428,13 +428,7 @@
         List<ManageRecordIntervals> manageRecordIntervalsList = new ArrayList<>();
 
         DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
-        //鑾峰彇褰撳墠骞翠唤
-        LocalDate currentDate = LocalDate.now();
-        // 瀹氫箟鏃ユ湡鏍煎紡
-        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy");
-        // 鏍煎紡鍖栧綋鍓嶆棩鏈�
-        String currentMonth = currentDate.format(formatter);
-        ManageRecordIntervalsTotal manageRecordIntervalsTotal = manageRecordIntervalsTotalMapper.selectOne(Wrappers.<ManageRecordIntervalsTotal>lambdaQuery().eq(ManageRecordIntervalsTotal::getYear, currentMonth));
+        ManageRecordIntervalsTotal manageRecordIntervalsTotal = getOrCreateCurrentYearTotal();
         try {
             InputStream inputStream = file.getInputStream();
             XWPFDocument document = new XWPFDocument(inputStream);
@@ -482,13 +476,7 @@
 
     @Override
     public int addManageRecordIntervals(ManageRecordIntervals manageRecordIntervals) {
-        //鑾峰彇褰撳墠骞翠唤
-        LocalDate currentDate = LocalDate.now();
-        // 瀹氫箟鏃ユ湡鏍煎紡
-        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy");
-        // 鏍煎紡鍖栧綋鍓嶆棩鏈�
-        String currentMonth = currentDate.format(formatter);
-        ManageRecordIntervalsTotal manageRecordIntervalsTotal = manageRecordIntervalsTotalMapper.selectOne(Wrappers.<ManageRecordIntervalsTotal>lambdaQuery().eq(ManageRecordIntervalsTotal::getYear, currentMonth));
+        ManageRecordIntervalsTotal manageRecordIntervalsTotal = getOrCreateCurrentYearTotal();
         manageRecordIntervals.setRecordIntervalsTotalId(manageRecordIntervalsTotal.getId());
         manageRecordIntervalsMapper.insert(manageRecordIntervals);
         manageRecordIntervalsTotal.setTotalNum(1 + manageRecordIntervalsTotal.getTotalNum());
@@ -500,10 +488,28 @@
         ManageRecordIntervals manageRecordIntervals = manageRecordIntervalsMapper.selectById(id);
         manageRecordIntervalsMapper.deleteById(id);
         ManageRecordIntervalsTotal manageRecordIntervalsTotal = manageRecordIntervalsTotalMapper.selectById(manageRecordIntervals.getRecordIntervalsTotalId());
-        manageRecordIntervalsTotal.setTotalNum(manageRecordIntervalsTotal.getTotalNum() - 1);
+        if (manageRecordIntervalsTotal == null) {
+            return 0;
+        }
+        manageRecordIntervalsTotal.setTotalNum((manageRecordIntervalsTotal.getTotalNum() == null ? 0 : manageRecordIntervalsTotal.getTotalNum()) - 1);
         return manageRecordIntervalsTotalMapper.updateById(manageRecordIntervalsTotal);
     }
 
+    // 骞村害姹囨�昏褰曞師鏈敱姣忓勾 1 鏈� 1 鏃ョ殑瀹氭椂浠诲姟鍒涘缓锛屼换鍔℃湭鍚敤鏃舵澶勫厹搴曡嚜鍔ㄨˉ寤猴紝閬垮厤鍙� id 鏃舵姤绌烘寚閽�
+    private ManageRecordIntervalsTotal getOrCreateCurrentYearTotal() {
+        String year = String.valueOf(LocalDate.now().getYear());
+        ManageRecordIntervalsTotal manageRecordIntervalsTotal = manageRecordIntervalsTotalMapper.selectOne(Wrappers.<ManageRecordIntervalsTotal>lambdaQuery().eq(ManageRecordIntervalsTotal::getYear, year));
+        if (manageRecordIntervalsTotal == null) {
+            manageRecordIntervalsTotal = new ManageRecordIntervalsTotal();
+            manageRecordIntervalsTotal.setYear(year);
+            manageRecordIntervalsTotal.setTotalNum(0);
+            manageRecordIntervalsTotalMapper.insert(manageRecordIntervalsTotal);
+        } else if (manageRecordIntervalsTotal.getTotalNum() == null) {
+            manageRecordIntervalsTotal.setTotalNum(0);
+        }
+        return manageRecordIntervalsTotal;
+    }
+
     // 姘村钩鍚堝苟鍗曞厓鏍�
     private static void mergeCellsHorizontally(XWPFTable table, int row, int fromCol, int toCol) {
         for (int i = fromCol; i <= toCol; i++) {
diff --git a/cnas-manage/src/main/java/com/ruoyi/manage/service/impl/ManageRecordVerifyServiceImpl.java b/cnas-manage/src/main/java/com/ruoyi/manage/service/impl/ManageRecordVerifyServiceImpl.java
index a49d7b0..2b494da 100644
--- a/cnas-manage/src/main/java/com/ruoyi/manage/service/impl/ManageRecordVerifyServiceImpl.java
+++ b/cnas-manage/src/main/java/com/ruoyi/manage/service/impl/ManageRecordVerifyServiceImpl.java
@@ -53,28 +53,14 @@
     @Override
     public IPage<ManageRecordVerify> pageManageRecordVerify(Page page, ManageRecordVerify manageRecordVerify) {
         if (ObjectUtils.isEmpty(manageRecordVerify.getManageRecordTotalId())) {
-            //鑾峰彇褰撳墠骞翠唤
-            LocalDate currentDate = LocalDate.now();
-            // 瀹氫箟鏃ユ湡鏍煎紡
-            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy");
-            // 鏍煎紡鍖栧綋鍓嶆棩鏈�
-            String currentMonth = currentDate.format(formatter);
-            //鏌ヨ鍘嗗彶
-            ManageRecordTotal manageRecordTotal = manageRecordTotalMapper.selectOne(Wrappers.<ManageRecordTotal>lambdaQuery().eq(ManageRecordTotal::getYear, currentMonth));
-            manageRecordVerify.setManageRecordTotalId(manageRecordTotal.getId());
+            manageRecordVerify.setManageRecordTotalId(getOrCreateCurrentYearTotal().getId());
         }
         return manageRecordVerifyMapper.pageManageRecordVerify(page, QueryWrappers.queryWrappers(manageRecordVerify));
     }
 
     @Override
     public int addManageRecordVerify(ManageRecordVerify manageRecordVerify) {
-        //鑾峰彇褰撳墠骞翠唤
-        LocalDate currentDate = LocalDate.now();
-        // 瀹氫箟鏃ユ湡鏍煎紡
-        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy");
-        // 鏍煎紡鍖栧綋鍓嶆棩鏈�
-        String currentMonth = currentDate.format(formatter);
-        ManageRecordTotal manageRecordTotal = manageRecordTotalMapper.selectOne(Wrappers.<ManageRecordTotal>lambdaQuery().eq(ManageRecordTotal::getYear, currentMonth));
+        ManageRecordTotal manageRecordTotal = getOrCreateCurrentYearTotal();
         manageRecordVerify.setManageRecordTotalId(manageRecordTotal.getId());
         manageRecordVerifyMapper.insert(manageRecordVerify);
         manageRecordTotal.setTotalNum(1 + manageRecordTotal.getTotalNum());
@@ -86,7 +72,10 @@
         ManageRecordVerify manageRecordVerify = manageRecordVerifyMapper.selectById(id);
         manageRecordVerifyMapper.deleteById(id);
         ManageRecordTotal manageRecordTotal = manageRecordTotalMapper.selectById(manageRecordVerify.getManageRecordTotalId());
-        manageRecordTotal.setTotalNum(manageRecordTotal.getTotalNum() - 1);
+        if (manageRecordTotal == null) {
+            return 0;
+        }
+        manageRecordTotal.setTotalNum((manageRecordTotal.getTotalNum() == null ? 0 : manageRecordTotal.getTotalNum()) - 1);
         return manageRecordTotalMapper.updateById(manageRecordTotal);
     }
 
@@ -94,13 +83,7 @@
     public int exportManageRecordVerify(MultipartFile file) {
         List<ManageRecordVerify> manageRecordVerifyList = new ArrayList<>();
         DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
-        //鑾峰彇褰撳墠骞翠唤
-        LocalDate currentDate = LocalDate.now();
-        // 瀹氫箟鏃ユ湡鏍煎紡
-        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy");
-        // 鏍煎紡鍖栧綋鍓嶆棩鏈�
-        String currentMonth = currentDate.format(formatter);
-        ManageRecordTotal manageRecordTotal = manageRecordTotalMapper.selectOne(Wrappers.<ManageRecordTotal>lambdaQuery().eq(ManageRecordTotal::getYear, currentMonth));
+        ManageRecordTotal manageRecordTotal = getOrCreateCurrentYearTotal();
         try {
             InputStream inputStream = file.getInputStream();
             XWPFDocument document = new XWPFDocument(inputStream);
@@ -154,4 +137,19 @@
         }
         return 0;
     }
+
+    // 骞村害姹囨�昏褰曞師鏈敱姣忓勾 1 鏈� 1 鏃ョ殑瀹氭椂浠诲姟鍒涘缓锛屼换鍔℃湭鍚敤鏃舵澶勫厹搴曡嚜鍔ㄨˉ寤猴紝閬垮厤鍙� id 鏃舵姤绌烘寚閽�
+    private ManageRecordTotal getOrCreateCurrentYearTotal() {
+        String year = String.valueOf(LocalDate.now().getYear());
+        ManageRecordTotal manageRecordTotal = manageRecordTotalMapper.selectOne(Wrappers.<ManageRecordTotal>lambdaQuery().eq(ManageRecordTotal::getYear, year));
+        if (manageRecordTotal == null) {
+            manageRecordTotal = new ManageRecordTotal();
+            manageRecordTotal.setYear(year);
+            manageRecordTotal.setTotalNum(0);
+            manageRecordTotalMapper.insert(manageRecordTotal);
+        } else if (manageRecordTotal.getTotalNum() == null) {
+            manageRecordTotal.setTotalNum(0);
+        }
+        return manageRecordTotal;
+    }
 }
diff --git a/cnas-require/src/main/java/com/ruoyi/require/controller/FeStandardSubstanceAcceptanceController.java b/cnas-require/src/main/java/com/ruoyi/require/controller/FeStandardSubstanceAcceptanceController.java
index 923fc72..5113952 100644
--- a/cnas-require/src/main/java/com/ruoyi/require/controller/FeStandardSubstanceAcceptanceController.java
+++ b/cnas-require/src/main/java/com/ruoyi/require/controller/FeStandardSubstanceAcceptanceController.java
@@ -4,9 +4,11 @@
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.common.core.domain.Result;
 import com.ruoyi.require.dto.AcceptanceDto;
+import com.ruoyi.require.pojo.FeStandardSubstance;
 import com.ruoyi.require.pojo.FeStandardSubstanceAcceptanceInspection;
 import com.ruoyi.require.service.FeStandardSubstanceAcceptanceInspectionService;
 import com.ruoyi.require.service.FeStandardSubstanceAcceptanceService;
+import com.ruoyi.require.service.FeStandardSubstanceService;
 import com.ruoyi.require.vo.AcceptanceVo;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import io.swagger.v3.oas.annotations.Operation;
@@ -34,6 +36,8 @@
     private FeStandardSubstanceAcceptanceInspectionService inspectionService;
     @Resource
     private FeStandardSubstanceAcceptanceService feStandardSubstanceAcceptanceService;
+    @Resource
+    private FeStandardSubstanceService feStandardSubstanceService;
 
     @Operation(summary = "鏂板")
     @PostMapping("/addAcceptance")
@@ -58,7 +62,20 @@
 
     @Operation(summary = "缂栬緫")
     @PostMapping("/updateAcceptance")
+    @Transactional
     public Result updateAcceptance(@RequestBody AcceptanceDto acceptanceDto) {
+        FeStandardSubstance substance = acceptanceDto.getSubstance();
+        if (substance != null) {
+            if (substance.getId() == null) {
+                substance.setState(0);
+                feStandardSubstanceService.save(substance);
+            } else {
+                // 棰嗙敤鐘舵�佺敱棰嗙敤/褰掕繕鎿嶄綔缁存姢锛岀紪杈戦獙鏀跺崟鏃朵笉鍥炲啓
+                substance.setState(null);
+                feStandardSubstanceService.updateById(substance);
+            }
+            acceptanceDto.getAcceptance().setSubstanceId(substance.getId());
+        }
         feStandardSubstanceAcceptanceService.updateById(acceptanceDto.getAcceptance());
         for (FeStandardSubstanceAcceptanceInspection v : acceptanceDto.getList()) {
             if (v.getId()== null) {
diff --git a/cnas-require/src/main/java/com/ruoyi/require/controller/FeStandardSubstanceRecordController.java b/cnas-require/src/main/java/com/ruoyi/require/controller/FeStandardSubstanceRecordController.java
index fef8599..8dcdce2 100644
--- a/cnas-require/src/main/java/com/ruoyi/require/controller/FeStandardSubstanceRecordController.java
+++ b/cnas-require/src/main/java/com/ruoyi/require/controller/FeStandardSubstanceRecordController.java
@@ -37,12 +37,10 @@
         return Result.success();
     }
 
-    @Operation(summary = "鏍囧噯鐗╄川娓呭崟褰掕繕")
-    @PostMapping("/returnSubstance")
-    @Transactional
-    public Result returnSubstance(@RequestBody FeStandardSubstanceRecord record) {
-        feStandardSubstanceRecordService.returnSubstance(record);
-        return Result.success();
+    @Operation(summary = "鏌ヨ鏍囧噯鐗╄川鍓╀綑鍙鐢ㄦ暟閲�")
+    @GetMapping("/getRemainingQuantity/{substanceId}")
+    public Result<Long> getRemainingQuantity(@PathVariable("substanceId") Integer substanceId) {
+        return Result.success(feStandardSubstanceRecordService.getRemainingQuantity(substanceId));
     }
 
     @Operation(summary = "鏍囧噯鐗╄川娓呭崟棰嗙敤鏌ヨ")
diff --git a/cnas-require/src/main/java/com/ruoyi/require/controller/SupplierManagementController.java b/cnas-require/src/main/java/com/ruoyi/require/controller/SupplierManagementController.java
index 216a5ab..67f7bae 100644
--- a/cnas-require/src/main/java/com/ruoyi/require/controller/SupplierManagementController.java
+++ b/cnas-require/src/main/java/com/ruoyi/require/controller/SupplierManagementController.java
@@ -12,6 +12,7 @@
 import lombok.AllArgsConstructor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
 import jakarta.servlet.http.HttpServletResponse;
 import java.util.List;
@@ -88,4 +89,23 @@
         return Result.success(supplierManagementService.selectSupplierManagementAll());
     }
 
+    @Operation(summary = "鏌ヨ渚涘簲鍟嗛檮浠�")
+    @GetMapping("/selectAttachments")
+    public Result selectAttachments(Integer supplierManagementId) {
+        return Result.success(supplierManagementService.selectAttachments(supplierManagementId));
+    }
+
+    @Operation(summary = "涓婁紶渚涘簲鍟嗛檮浠�")
+    @PostMapping("/uploadAttachment")
+    public Result uploadAttachment(@RequestParam("supplierManagementId") Integer supplierManagementId,
+                                   @RequestParam("file") MultipartFile file) {
+        return Result.success(supplierManagementService.uploadAttachment(supplierManagementId, file));
+    }
+
+    @Operation(summary = "鍒犻櫎渚涘簲鍟嗛檮浠�")
+    @DeleteMapping("/deleteAttachment")
+    public Result deleteAttachment(Long id) {
+        return Result.success(supplierManagementService.deleteAttachment(id));
+    }
+
 }
diff --git a/cnas-require/src/main/java/com/ruoyi/require/dto/AcceptanceDto.java b/cnas-require/src/main/java/com/ruoyi/require/dto/AcceptanceDto.java
index a369361..335c935 100644
--- a/cnas-require/src/main/java/com/ruoyi/require/dto/AcceptanceDto.java
+++ b/cnas-require/src/main/java/com/ruoyi/require/dto/AcceptanceDto.java
@@ -1,5 +1,6 @@
 package com.ruoyi.require.dto;
 
+import com.ruoyi.require.pojo.FeStandardSubstance;
 import com.ruoyi.require.pojo.FeStandardSubstanceAcceptance;
 import com.ruoyi.require.pojo.FeStandardSubstanceAcceptanceInspection;
 import lombok.Data;
@@ -11,5 +12,7 @@
 
     private FeStandardSubstanceAcceptance acceptance;
 
+    private FeStandardSubstance substance;
+
     private List<FeStandardSubstanceAcceptanceInspection> list;
 }
diff --git a/cnas-require/src/main/java/com/ruoyi/require/excel/FeStandardSubstanceExcel.java b/cnas-require/src/main/java/com/ruoyi/require/excel/FeStandardSubstanceExcel.java
index 2f0691c..b9500e7 100644
--- a/cnas-require/src/main/java/com/ruoyi/require/excel/FeStandardSubstanceExcel.java
+++ b/cnas-require/src/main/java/com/ruoyi/require/excel/FeStandardSubstanceExcel.java
@@ -16,7 +16,7 @@
     @ExcelProperty("鐢熶骇鍘傚")
     private String factoryManufacturer;
 
-    @ExcelProperty("鍑哄満缂栧彿")
+    @ExcelProperty("鍑哄巶缂栧彿")
     private String factoryNum;
 
     @ExcelProperty("绠$悊缂栧彿")
@@ -34,7 +34,7 @@
     @ExcelProperty("鏈夋晥鏈�")
     private LocalDateTime effectiveDate;
 
-    @ExcelProperty("鏂囨。缂栧彿")
+    @ExcelProperty("妗f缂栧彿")
     private String fileNum;
 
     @ExcelProperty("瀛樻斁浣嶇疆")
diff --git a/cnas-require/src/main/java/com/ruoyi/require/excel/FeStandardSubstanceImport.java b/cnas-require/src/main/java/com/ruoyi/require/excel/FeStandardSubstanceImport.java
index 1588fd8..e2afe93 100644
--- a/cnas-require/src/main/java/com/ruoyi/require/excel/FeStandardSubstanceImport.java
+++ b/cnas-require/src/main/java/com/ruoyi/require/excel/FeStandardSubstanceImport.java
@@ -14,7 +14,7 @@
     @ExcelProperty("瑙勬牸鍨嬪彿*")
     private String model;
 
-    @ExcelProperty("鐢熶骇鍘傚*")
+    @ExcelProperty("鐢熶骇鍘傚")
     private String factoryManufacturer;
 
     @ExcelProperty("鍑哄巶缂栧彿*")
@@ -29,6 +29,9 @@
     @ExcelProperty("鏁伴噺*")
     private String quantity;
 
+    @ExcelProperty("鍗曚綅")
+    private String unit;
+
     @ExcelProperty("璐疆鏃ユ湡*(yyyy-MM-dd)")
     private String acquisitionDate;
 
diff --git a/cnas-require/src/main/java/com/ruoyi/require/mapper/SupplierManagementAttachmentMapper.java b/cnas-require/src/main/java/com/ruoyi/require/mapper/SupplierManagementAttachmentMapper.java
new file mode 100644
index 0000000..ce1bbdd
--- /dev/null
+++ b/cnas-require/src/main/java/com/ruoyi/require/mapper/SupplierManagementAttachmentMapper.java
@@ -0,0 +1,9 @@
+package com.ruoyi.require.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.require.pojo.SupplierManagementAttachment;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface SupplierManagementAttachmentMapper extends BaseMapper<SupplierManagementAttachment> {
+}
diff --git a/cnas-require/src/main/java/com/ruoyi/require/pojo/FeStandardSubstance.java b/cnas-require/src/main/java/com/ruoyi/require/pojo/FeStandardSubstance.java
index 3c01b66..0c6bc72 100644
--- a/cnas-require/src/main/java/com/ruoyi/require/pojo/FeStandardSubstance.java
+++ b/cnas-require/src/main/java/com/ruoyi/require/pojo/FeStandardSubstance.java
@@ -1,6 +1,7 @@
 package com.ruoyi.require.pojo;
 
 import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Getter;
 import lombok.Setter;
@@ -36,7 +37,10 @@
     @Schema(description = "鐢熶骇鍘傚")
     private String factoryManufacturer;
 
-    @Schema(description = "鍑哄満缂栧彿")
+    @Schema(description = "渚涘簲鍟�")
+    private String supplier;
+
+    @Schema(description = "鍑哄巶缂栧彿")
     private String factoryNum;
 
     @Schema(description = "绠$悊缂栧彿")
@@ -48,13 +52,18 @@
     @Schema(description = "鏁伴噺")
     private Long quantity;
 
+    @Schema(description = "鍗曚綅")
+    private String unit;
+
     @Schema(description = "璐疆鏃ユ湡")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime acquisitionDate;
 
     @Schema(description = "鏈夋晥鏈�")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime effectiveDate;
 
-    @Schema(description = "鏂囨。缂栧彿")
+    @Schema(description = "妗f缂栧彿")
     private String fileNum;
 
     @Schema(description = "瀛樻斁浣嶇疆")
@@ -70,11 +79,13 @@
     private String createUser;
 
     @TableField(fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime createTime;
 
     @TableField(fill = FieldFill.INSERT_UPDATE)
     private String updateUser;
 
     @TableField(fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime updateTime;
 }
diff --git a/cnas-require/src/main/java/com/ruoyi/require/pojo/FeStandardSubstanceAcceptance.java b/cnas-require/src/main/java/com/ruoyi/require/pojo/FeStandardSubstanceAcceptance.java
index 7941564..a447387 100644
--- a/cnas-require/src/main/java/com/ruoyi/require/pojo/FeStandardSubstanceAcceptance.java
+++ b/cnas-require/src/main/java/com/ruoyi/require/pojo/FeStandardSubstanceAcceptance.java
@@ -3,6 +3,7 @@
 import com.alibaba.excel.annotation.ExcelIgnore;
 import com.alibaba.excel.annotation.ExcelProperty;
 import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Getter;
 import lombok.Setter;
@@ -78,6 +79,7 @@
 
     @ExcelIgnore
     @TableField(fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime createTime;
 
     @ExcelIgnore
@@ -86,5 +88,6 @@
 
     @ExcelIgnore
     @TableField(fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime updateTime;
 }
diff --git a/cnas-require/src/main/java/com/ruoyi/require/pojo/FeStandardSubstanceRecord.java b/cnas-require/src/main/java/com/ruoyi/require/pojo/FeStandardSubstanceRecord.java
index 0a576cd..ecb6818 100644
--- a/cnas-require/src/main/java/com/ruoyi/require/pojo/FeStandardSubstanceRecord.java
+++ b/cnas-require/src/main/java/com/ruoyi/require/pojo/FeStandardSubstanceRecord.java
@@ -1,6 +1,7 @@
 package com.ruoyi.require.pojo;
 
 import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Getter;
 import lombok.Setter;
@@ -30,6 +31,15 @@
     @Schema(description = "鐗╄川id")
     private Integer substanceId;
 
+    @Schema(description = "鏈棰嗙敤鏁伴噺")
+    private Long borrowQuantity;
+
+    @Schema(description = "鍘熷鏁伴噺(棰嗙敤鏃跺揩鐓�)")
+    private Long originalQuantity;
+
+    @Schema(description = "棰嗙敤鍚庡墿浣欐暟閲�")
+    private Long remainingQuantity;
+
     @Schema(description = "鍊熺敤-瀹屽ソ鎬�")
     private String integrity;
 
@@ -40,9 +50,11 @@
     private String phone;
 
     @Schema(description = "鍊熺敤-鍊熷嚭鏃ユ湡")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime borrowDate;
 
     @Schema(description = "褰掕繕鏃ユ湡")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime borrowReturnDate;
 
     @Schema(description = "鍊熷嚭浜�")
@@ -58,6 +70,7 @@
     private String returnedPerson;
 
     @Schema(description = "褰掕繕-鏃ユ湡")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime returnDate;
 
     @Schema(description = "褰掕繕-瀹屽ソ鎬�")
@@ -67,11 +80,13 @@
     private String createUser;
 
     @TableField(fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime createTime;
 
     @TableField(fill = FieldFill.INSERT_UPDATE)
     private String updateUser;
 
     @TableField(fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime updateTime;
 }
diff --git a/cnas-require/src/main/java/com/ruoyi/require/pojo/SupplierManagementAttachment.java b/cnas-require/src/main/java/com/ruoyi/require/pojo/SupplierManagementAttachment.java
new file mode 100644
index 0000000..1025ddc
--- /dev/null
+++ b/cnas-require/src/main/java/com/ruoyi/require/pojo/SupplierManagementAttachment.java
@@ -0,0 +1,28 @@
+package com.ruoyi.require.pojo;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+@TableName("cnas_supplier_management_attachment")
+public class SupplierManagementAttachment {
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    private Integer supplierManagementId;
+    private String fileName;
+    private String fileUrl;
+    private Integer sort;
+    @TableField(fill = FieldFill.INSERT)
+    private Integer createUser;
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private Integer updateUser;
+    @TableField(fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime updateTime;
+}
diff --git a/cnas-require/src/main/java/com/ruoyi/require/service/FeStandardSubstanceRecordService.java b/cnas-require/src/main/java/com/ruoyi/require/service/FeStandardSubstanceRecordService.java
index 4e52b9a..b97db90 100644
--- a/cnas-require/src/main/java/com/ruoyi/require/service/FeStandardSubstanceRecordService.java
+++ b/cnas-require/src/main/java/com/ruoyi/require/service/FeStandardSubstanceRecordService.java
@@ -21,10 +21,10 @@
 
     void borrowSubstance(FeStandardSubstanceRecord feStandardSubstanceRecord);
 
-    void returnSubstance(FeStandardSubstanceRecord feStandardSubstanceRecord);
-
     List<FeStandardSubstanceRecord> getSubstanceRecord(Integer id);
 
     IPage<SubstanceRecordVo> getPage(Page page, SubstanceRecordVo vo);
 
+    Long getRemainingQuantity(Integer substanceId);
+
 }
diff --git a/cnas-require/src/main/java/com/ruoyi/require/service/SupplierManagementService.java b/cnas-require/src/main/java/com/ruoyi/require/service/SupplierManagementService.java
index 798f98c..3633345 100644
--- a/cnas-require/src/main/java/com/ruoyi/require/service/SupplierManagementService.java
+++ b/cnas-require/src/main/java/com/ruoyi/require/service/SupplierManagementService.java
@@ -4,6 +4,8 @@
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.ruoyi.require.pojo.SupplierManagement;
+import com.ruoyi.require.pojo.SupplierManagementAttachment;
+import org.springframework.web.multipart.MultipartFile;
 
 import jakarta.servlet.http.HttpServletResponse;
 import java.util.List;
@@ -29,4 +31,10 @@
     List<SupplierManagement> selectSupplierManagementByParentId(Integer parentId);
 
     List<SupplierManagement> selectSupplierManagementAll();
+
+    List<SupplierManagementAttachment> selectAttachments(Integer supplierManagementId);
+
+    SupplierManagementAttachment uploadAttachment(Integer supplierManagementId, MultipartFile file);
+
+    boolean deleteAttachment(Long id);
 }
diff --git a/cnas-require/src/main/java/com/ruoyi/require/service/impl/FeStandardSubstanceAcceptanceServiceImpl.java b/cnas-require/src/main/java/com/ruoyi/require/service/impl/FeStandardSubstanceAcceptanceServiceImpl.java
index edf0b99..e275cd5 100644
--- a/cnas-require/src/main/java/com/ruoyi/require/service/impl/FeStandardSubstanceAcceptanceServiceImpl.java
+++ b/cnas-require/src/main/java/com/ruoyi/require/service/impl/FeStandardSubstanceAcceptanceServiceImpl.java
@@ -53,6 +53,14 @@
     @Override
     public void addAcceptance(AcceptanceDto dto) {
         FeStandardSubstanceAcceptance acceptance = dto.getAcceptance();
+        FeStandardSubstance substance = dto.getSubstance();
+        if (substance != null) {
+            if (substance.getId() == null) {
+                substance.setState(0);
+                feStandardSubstanceMapper.insert(substance);
+            }
+            acceptance.setSubstanceId(substance.getId());
+        }
         this.baseMapper.insert(acceptance);
         List<FeStandardSubstanceAcceptanceInspection> list = dto.getList();
         if (CollectionUtils.isNotEmpty(list)) {
diff --git a/cnas-require/src/main/java/com/ruoyi/require/service/impl/FeStandardSubstanceRecordServiceImpl.java b/cnas-require/src/main/java/com/ruoyi/require/service/impl/FeStandardSubstanceRecordServiceImpl.java
index 0fb8618..4b53f5d 100644
--- a/cnas-require/src/main/java/com/ruoyi/require/service/impl/FeStandardSubstanceRecordServiceImpl.java
+++ b/cnas-require/src/main/java/com/ruoyi/require/service/impl/FeStandardSubstanceRecordServiceImpl.java
@@ -36,31 +36,51 @@
 
     @Override
     public void borrowSubstance(FeStandardSubstanceRecord feStandardSubstanceRecord) {
-        FeStandardSubstance standardSubstance = feStandardSubstanceMapper.selectOne(Wrappers.<FeStandardSubstance>lambdaQuery()
-                .eq(FeStandardSubstance::getId, feStandardSubstanceRecord.getSubstanceId())
-                .eq(FeStandardSubstance::getState, 0)
-                .last("limit 1"));
-        if (ObjectUtils.isEmpty(standardSubstance)){
-            throw new ErrorException("璇ョ墿璐ㄥ凡琚�熷嚭锛�");
+        Long borrowQuantity = feStandardSubstanceRecord.getBorrowQuantity();
+        if (borrowQuantity == null || borrowQuantity <= 0) {
+            throw new ErrorException("璇峰~鍐欐纭殑棰嗙敤鏁伴噺锛�");
         }
+        FeStandardSubstance standardSubstance = feStandardSubstanceMapper.selectById(feStandardSubstanceRecord.getSubstanceId());
+        if (ObjectUtils.isEmpty(standardSubstance)){
+            throw new ErrorException("璇ユ爣鍑嗙墿璐ㄤ笉瀛樺湪锛�");
+        }
+        long remaining = calcRemaining(standardSubstance);
+        if (remaining <= 0) {
+            throw new ErrorException("璇ユ爣鍑嗙墿璐ㄥ凡鍏ㄩ儴棰嗙敤锛屽墿浣欐暟閲忎负0锛�");
+        }
+        if (borrowQuantity > remaining) {
+            throw new ErrorException("棰嗙敤鏁伴噺涓嶈兘瓒呰繃鍓╀綑鏁伴噺锛堝綋鍓嶅墿浣�" + remaining + "锛夛紒");
+        }
+        long remainingAfter = remaining - borrowQuantity;
+        feStandardSubstanceRecord.setRemainingQuantity(remainingAfter);
+        // 璁板綍棰嗙敤褰撴椂鐨勫師濮嬫暟閲忓揩鐓э紝涔嬪悗娓呭崟閲屽啀鏀规暟閲忎笉褰卞搷鍘嗗彶棰嗙敤璁板綍
+        feStandardSubstanceRecord.setOriginalQuantity(standardSubstance.getQuantity());
         this.baseMapper.insert(feStandardSubstanceRecord);
-        standardSubstance.setState(1);
+        standardSubstance.setState(remainingAfter == 0 ? 1 : 0);
         feStandardSubstanceMapper.updateById(standardSubstance);
     }
 
     @Override
-    public void returnSubstance(FeStandardSubstanceRecord feStandardSubstanceRecord) {
-        FeStandardSubstance standardSubstance = feStandardSubstanceMapper.selectOne(Wrappers.<FeStandardSubstance>lambdaQuery()
-                .eq(FeStandardSubstance::getId, feStandardSubstanceRecord.getSubstanceId())
-                .eq(FeStandardSubstance::getState, 1));
-        if (ObjectUtils.isEmpty(standardSubstance)){
-            throw new ErrorException("璇ョ墿璐ㄦ湭琚鐢紝鏃犻渶褰掕繕锛�");
+    public Long getRemainingQuantity(Integer substanceId) {
+        FeStandardSubstance standardSubstance = feStandardSubstanceMapper.selectById(substanceId);
+        if (ObjectUtils.isEmpty(standardSubstance)) {
+            return 0L;
         }
-        standardSubstance.setState(0);
-        feStandardSubstanceMapper.updateById(standardSubstance);
-        baseMapper.update(feStandardSubstanceRecord, Wrappers.<FeStandardSubstanceRecord>lambdaUpdate()
-                .eq(FeStandardSubstanceRecord::getSubstanceId, feStandardSubstanceRecord.getSubstanceId())
-                .eq(FeStandardSubstanceRecord::getStatus, 0));
+        return Math.max(calcRemaining(standardSubstance), 0L);
+    }
+
+    private long calcRemaining(FeStandardSubstance substance) {
+        long total = substance.getQuantity() == null ? 0L : substance.getQuantity();
+        long borrowed = 0L;
+        List<FeStandardSubstanceRecord> records = this.baseMapper.selectList(Wrappers.<FeStandardSubstanceRecord>lambdaQuery()
+                .eq(FeStandardSubstanceRecord::getSubstanceId, substance.getId()));
+        for (FeStandardSubstanceRecord record : records) {
+            if ("1".equals(record.getStatus())) { // 鍘嗗彶褰掕繕璁板綍涓嶈鍏ュ凡棰嗙敤
+                continue;
+            }
+            borrowed += record.getBorrowQuantity() == null ? total : record.getBorrowQuantity();
+        }
+        return total - borrowed;
     }
 
     @Override
diff --git a/cnas-require/src/main/java/com/ruoyi/require/service/impl/FeStandardSubstanceServiceImpl.java b/cnas-require/src/main/java/com/ruoyi/require/service/impl/FeStandardSubstanceServiceImpl.java
index 7b97938..ea70f27 100644
--- a/cnas-require/src/main/java/com/ruoyi/require/service/impl/FeStandardSubstanceServiceImpl.java
+++ b/cnas-require/src/main/java/com/ruoyi/require/service/impl/FeStandardSubstanceServiceImpl.java
@@ -90,11 +90,12 @@
             FeStandardSubstance substance = new FeStandardSubstance();
             substance.setName(required(row.getName(), rowNumber, "鏍囧噯鐗╄川鍚嶇О"));
             substance.setModel(required(row.getModel(), rowNumber, "瑙勬牸鍨嬪彿"));
-            substance.setFactoryManufacturer(required(row.getFactoryManufacturer(), rowNumber, "鐢熶骇鍘傚"));
+            substance.setFactoryManufacturer(trim(row.getFactoryManufacturer()));
             substance.setFactoryNum(required(row.getFactoryNum(), rowNumber, "鍑哄巶缂栧彿"));
             substance.setManageNum(manageNum);
             substance.setUncertainty(required(row.getUncertainty(), rowNumber, "涓嶇‘瀹氬害"));
             substance.setQuantity(parseQuantity(row.getQuantity(), rowNumber));
+            substance.setUnit(trim(row.getUnit()));
             substance.setAcquisitionDate(parseDate(row.getAcquisitionDate(), rowNumber, "璐疆鏃ユ湡"));
             substance.setEffectiveDate(parseDate(row.getEffectiveDate(), rowNumber, "鏈夋晥鏈�"));
             substance.setFileNum(required(row.getFileNum(), rowNumber, "妗f缂栧彿"));
diff --git a/cnas-require/src/main/java/com/ruoyi/require/service/impl/SupplierManagementServiceImpl.java b/cnas-require/src/main/java/com/ruoyi/require/service/impl/SupplierManagementServiceImpl.java
index 2c8e5ee..d38b9c8 100644
--- a/cnas-require/src/main/java/com/ruoyi/require/service/impl/SupplierManagementServiceImpl.java
+++ b/cnas-require/src/main/java/com/ruoyi/require/service/impl/SupplierManagementServiceImpl.java
@@ -8,18 +8,26 @@
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.exception.base.BaseException;
 import com.ruoyi.common.utils.QueryWrappers;
 import com.ruoyi.require.dto.SupplierManagementDto;
+import com.ruoyi.require.mapper.SupplierManagementAttachmentMapper;
 import com.ruoyi.require.mapper.SupplierManagementMapper;
 import com.ruoyi.require.pojo.SupplierManagement;
+import com.ruoyi.require.pojo.SupplierManagementAttachment;
 import com.ruoyi.require.service.SupplierManagementService;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
 
 import jakarta.servlet.http.HttpServletResponse;
+import java.io.File;
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
 import java.util.List;
 
 /**
@@ -35,6 +43,15 @@
 
     @Autowired
     private SupplierManagementMapper supplierManagementMapper;
+
+    @Autowired
+    private SupplierManagementAttachmentMapper supplierManagementAttachmentMapper;
+
+    @Value("${file.path}")
+    private String filePath;
+
+    @Value("${wordUrl}")
+    private String wordUrl;
 
     public SupplierManagementServiceImpl(SupplierManagementMapper supplierManagementMapper) {
         this.supplierManagementMapper = supplierManagementMapper;
@@ -88,4 +105,55 @@
     public List<SupplierManagement> selectSupplierManagementAll() {
         return supplierManagementMapper.selectList(null);
     }
+
+    @Override
+    public List<SupplierManagementAttachment> selectAttachments(Integer supplierManagementId) {
+        return supplierManagementAttachmentMapper.selectList(new QueryWrapper<SupplierManagementAttachment>().lambda()
+                .eq(SupplierManagementAttachment::getSupplierManagementId, supplierManagementId)
+                .orderByAsc(SupplierManagementAttachment::getSort, SupplierManagementAttachment::getId));
+    }
+
+    @Override
+    public SupplierManagementAttachment uploadAttachment(Integer supplierManagementId, MultipartFile file) {
+        if (supplierManagementMapper.selectById(supplierManagementId) == null) {
+            throw new BaseException("渚涘簲鍟嗕笉瀛樺湪");
+        }
+        if (file == null || file.isEmpty()) {
+            throw new BaseException("闄勪欢涓嶈兘涓虹┖");
+        }
+        // 绯荤粺鍏ㄥ眬涓婁紶涓婇檺涓�200MB锛岃繖閲屾彁鍓嶇粰鍑哄弸濂芥彁绀�
+        if (file.getSize() > 200L * 1024 * 1024) {
+            throw new BaseException("闄勪欢涓嶈兘瓒呰繃200MB");
+        }
+        String originalName = file.getOriginalFilename();
+        if (originalName == null || originalName.trim().isEmpty()) {
+            originalName = "鏈懡鍚嶆枃浠�";
+        }
+        // 涓埆娴忚鍣ㄥ彲鑳藉甫涓婅矾寰勫墠缂�锛屽彧淇濈暀鏂囦欢鍚嶆湰韬�
+        originalName = originalName.replaceAll(".*[/\\\\]", "");
+        try {
+            // 鍥剧墖鏀惧浘鐗囩洰褰曪紙/img 闈欐�佽矾寰勶級锛屽叾浣欎换鎰忔牸寮忔斁 word 鐩綍锛�/word 闈欐�佽矾寰勶級
+            boolean image = originalName.matches("(?i).+\\.(jpg|jpeg|png|gif)$");
+            File directory = new File(image ? filePath : wordUrl);
+            if (!directory.exists()) {
+                directory.mkdirs();
+            }
+            String fileUrl = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMddHHmmssSSS")) + "-" + originalName;
+            file.transferTo(new File(directory, fileUrl));
+            SupplierManagementAttachment attachment = new SupplierManagementAttachment();
+            attachment.setSupplierManagementId(supplierManagementId);
+            attachment.setFileName(originalName);
+            attachment.setFileUrl(fileUrl);
+            attachment.setSort(selectAttachments(supplierManagementId).size());
+            supplierManagementAttachmentMapper.insert(attachment);
+            return attachment;
+        } catch (IOException e) {
+            throw new BaseException("闄勪欢涓婁紶澶辫触");
+        }
+    }
+
+    @Override
+    public boolean deleteAttachment(Long id) {
+        return supplierManagementAttachmentMapper.deleteById(id) > 0;
+    }
 }
diff --git a/cnas-require/src/main/java/com/ruoyi/require/vo/AcceptanceVo.java b/cnas-require/src/main/java/com/ruoyi/require/vo/AcceptanceVo.java
index 38133df..2a325fa 100644
--- a/cnas-require/src/main/java/com/ruoyi/require/vo/AcceptanceVo.java
+++ b/cnas-require/src/main/java/com/ruoyi/require/vo/AcceptanceVo.java
@@ -1,5 +1,6 @@
 package com.ruoyi.require.vo;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
@@ -20,7 +21,7 @@
     @Schema(description = "鐢熶骇鍘傚")
     private String factoryManufacturer;
 
-    @Schema(description = "鍑哄満缂栧彿")
+    @Schema(description = "鍑哄巶缂栧彿")
     private String factoryNum;
 
     @Schema(description = "绠$悊缂栧彿")
@@ -32,15 +33,24 @@
     @Schema(description = "鏁伴噺")
     private Long quantity;
 
+    @Schema(description = "鍗曚綅")
+    private String unit;
+
     @Schema(description = "璐疆鏃ユ湡")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime acquisitionDate;
 
     @Schema(description = "鏈夋晥鏈�")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime effectiveDate;
 
-    @Schema(description = "鏂囨。缂栧彿")
+    @Schema(description = "妗f缂栧彿")
     private String fileNum;
 
     @Schema(description = "瀛樻斁浣嶇疆")
     private String position;
+
+    @Schema(description = "鎻愪氦鏃堕棿")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
 }
diff --git a/cnas-require/src/main/java/com/ruoyi/require/vo/SubstanceRecordVo.java b/cnas-require/src/main/java/com/ruoyi/require/vo/SubstanceRecordVo.java
index d98cad5..7907cc7 100644
--- a/cnas-require/src/main/java/com/ruoyi/require/vo/SubstanceRecordVo.java
+++ b/cnas-require/src/main/java/com/ruoyi/require/vo/SubstanceRecordVo.java
@@ -1,5 +1,6 @@
 package com.ruoyi.require.vo;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
@@ -17,29 +18,27 @@
     @Schema(description = "瑙勬牸鍨嬪彿")
     private String model;
 
-    @Schema(description = "鍑哄満缂栧彿")
+    @Schema(description = "鍑哄巶缂栧彿")
     private String factoryNum;
 
     @Schema(description = "鏁伴噺")
     private Long quantity;
 
+    @Schema(description = "鍗曚綅")
+    private String unit;
+
+    @Schema(description = "鏈棰嗙敤鏁伴噺")
+    private Long borrowQuantity;
+
+    @Schema(description = "棰嗙敤鍚庡墿浣欐暟閲�")
+    private Long remainingQuantity;
+
     @Schema(description = "棰嗙敤浜�")
     private String borrowUser;
 
     @Schema(description = "鍊熷嚭鏃ユ湡")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime borrowDate;
-
-    @Schema(description = "褰掕繕鏃ユ湡")
-    private LocalDateTime returnDate;
-
-    @Schema(description = "褰掕繕浜�")
-    private String returnedPerson;
-
-    @Schema(description = "瀹屽ソ鎬�")
-    private String returnIntegrity;
-
-    @Schema(description = "0锛氬�熺敤 1:褰掕繕")
-    private String status;
 
     @Schema(description = "澶囨敞")
     private String remark;
diff --git a/cnas-require/src/main/resources/mapper/FeStandardSubstanceAcceptanceMapper.xml b/cnas-require/src/main/resources/mapper/FeStandardSubstanceAcceptanceMapper.xml
index e336198..8741603 100644
--- a/cnas-require/src/main/resources/mapper/FeStandardSubstanceAcceptanceMapper.xml
+++ b/cnas-require/src/main/resources/mapper/FeStandardSubstanceAcceptanceMapper.xml
@@ -30,10 +30,12 @@
             ss.manage_num,
             ss.uncertainty,
             ss.quantity,
+            ss.unit,
             ss.acquisition_date,
             ss.effective_date,
             ss.file_num,
-            ss.position
+            ss.position,
+            sa.create_time
         FROM cnas_fe_standard_substance_acceptance sa
                  LEFT JOIN cnas_fe_standard_substance ss on ss.id = sa.substance_id
         <where>
diff --git a/cnas-require/src/main/resources/mapper/FeStandardSubstanceRecordMapper.xml b/cnas-require/src/main/resources/mapper/FeStandardSubstanceRecordMapper.xml
index 315d743..97e1063 100644
--- a/cnas-require/src/main/resources/mapper/FeStandardSubstanceRecordMapper.xml
+++ b/cnas-require/src/main/resources/mapper/FeStandardSubstanceRecordMapper.xml
@@ -25,13 +25,13 @@
         ss.name,
         ss.model,
         ss.factory_num,
-        ss.quantity,
+        COALESCE(ssr.original_quantity, ss.quantity) AS quantity,
+        ss.unit,
+        COALESCE(ssr.borrow_quantity, ss.quantity) AS borrowQuantity,
+        COALESCE(ssr.remaining_quantity, 0) AS remainingQuantity,
         ssr.borrow_user,
         ssr.borrow_date,
-        ssr.return_date,
         ssr.integrity,
-        ssr.return_integrity,
-        ssr.returned_person,
         ss.remark
         FROM cnas_fe_standard_substance_record ssr
         LEFT JOIN cnas_fe_standard_substance ss on ss.id = ssr.substance_id
diff --git a/inspect-server/src/main/java/com/ruoyi/inspect/controller/InsOrderController.java b/inspect-server/src/main/java/com/ruoyi/inspect/controller/InsOrderController.java
index d6b9869..52b75c7 100644
--- a/inspect-server/src/main/java/com/ruoyi/inspect/controller/InsOrderController.java
+++ b/inspect-server/src/main/java/com/ruoyi/inspect/controller/InsOrderController.java
@@ -1,5 +1,6 @@
 package com.ruoyi.inspect.controller;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.basic.dto.InventoryDetailDTO;
@@ -287,4 +288,16 @@
         return insOrderService.judgeNotSpotCheckOrder(insPlaceOrderDto.getSampleList(), insPlaceOrderDto.getInsOrder());
     }
 
+    @Operation(summary = "鏌ヨ宸插畬鎴愬鎵樺崟(瀹㈡埛婊℃剰搴︿笅鎷夌敤, 浠呭凡妫�楠宻tate=4)")
+    @GetMapping("/selectCompletedOrders")
+    public Result selectCompletedOrders() {
+        LambdaQueryWrapper<InsOrder> qw = new LambdaQueryWrapper<>();
+        qw.select(InsOrder::getId, InsOrder::getEntrustCode, InsOrder::getCompany,
+                        InsOrder::getCompanyId, InsOrder::getSampleView)
+                .eq(InsOrder::getState, 4)
+                .isNotNull(InsOrder::getCompany)
+                .orderByDesc(InsOrder::getCreateTime);
+        return Result.success(insOrderService.page(new Page<>(1, 500), qw).getRecords());
+    }
+
 }

--
Gitblit v1.9.3