From 8c215c8be0f5076e8c95daf1b2203440ca7dfcad Mon Sep 17 00:00:00 2001
From: yxh <172933527@qq.com>
Date: 星期五, 23 十月 2026 13:42:50 +0800
Subject: [PATCH] 修改了报销校验

---
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceFunddetailController.java             |   25 +++
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceDonationwitnessorganController.java   |    3 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceEthicalreviewopinionsController.java  |   17 +
 ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceRelativesconfirmationServiceImpl.java |    6 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceRelativesconfirmationController.java  |   13 +
 ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ExpertFeeValidateService.java                |  144 +++++++++++++++++
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceDonatecompletioninfoController.java   |    5 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceDonateorganController.java            |   12 +
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceDonatecomporganController.java        |    3 
 ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceDonationwitnessServiceImpl.java       |    6 
 ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceMedicalevaluationServiceImpl.java     |    6 
 ruoyi-project/src/main/resources/mapper/project/ServiceFundMapper.xml                                   |    2 
 ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceDonatebaseinfoServiceImpl.java        |  112 +++++++++----
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceReimbursementdetailController.java    |   58 +++++++
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceMedicalevaluationController.java      |   22 ++
 ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceDonatecompletioninfoServiceImpl.java  |    6 
 ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceFundServiceImpl.java                  |   22 ++
 ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceEthicalreviewopinionsServiceImpl.java |    6 
 ruoyi-project/src/main/java/com/ruoyi/project/domain/BaseItemexpense.java                               |    8 +
 19 files changed, 423 insertions(+), 53 deletions(-)

diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceDonatecompletioninfoController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceDonatecompletioninfoController.java
index e5f8163..baef3eb 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceDonatecompletioninfoController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceDonatecompletioninfoController.java
@@ -179,6 +179,11 @@
     @Log(title = "鎹愮尞瀹屾垚", businessType = BusinessType.UPDATE)
     @PostMapping("/edit")
     public AjaxResult edit(@RequestBody ServiceDonatecompletioninfo serviceDonatecompletioninfo) {
+        // 浼樺厛鎸変富閿洿鏂帮紙鍓嶇宸插洖濉� id 鐨勫父瑙勮矾寰勶級
+        if (serviceDonatecompletioninfo.getId() != null) {
+            return toAjax(serviceDonatecompletioninfoService.updateById(serviceDonatecompletioninfo));
+        }
+        // 鍏煎鏈紶 id 鐨勬棫璋冪敤锛氭寜 infoid 瀹氫綅鏈垹闄よ褰�
         ServiceDonatecompletioninfo serviceDonatecompletioninfo1 = new ServiceDonatecompletioninfo();
         serviceDonatecompletioninfo1.setInfoid(serviceDonatecompletioninfo.getInfoid());
         List<ServiceDonatecompletioninfo> list = serviceDonatecompletioninfoService.queryList(serviceDonatecompletioninfo1);
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceDonatecomporganController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceDonatecomporganController.java
index ef0c43c..222be9f 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceDonatecomporganController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceDonatecomporganController.java
@@ -178,6 +178,7 @@
                 }
             }
         }
-        return toAjax(i);
+        // 鍥炰紶甯︿富閿殑鍒楄〃锛屼究浜庡墠绔洖濉� id
+        return AjaxResult.success(serviceDonatecomporganList);
     }
 }
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceDonateorganController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceDonateorganController.java
index ef5f73b..9bc8a89 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceDonateorganController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceDonateorganController.java
@@ -297,13 +297,23 @@
         Boolean i = null;
         for (ServiceDonateorgan serviceDonateorgan : serviceDonateorganList) {
             log.info("鎹愮尞鍣ㄥ畼绉绘id鏄惁涓虹┖ : {},鍩虹琛ㄧ殑id涓� : {}", serviceDonateorgan.getId(), serviceDonateorgan.getInfoid());
+            // 2026-10-22锛氬悓涓�妗堜緥銆佸悓涓�鍣ㄥ畼鍙繚鐣欎竴鏉℃湭鍒犻櫎璁板綍鈥斺�斿凡瀛樺湪鍒欐洿鏂帮紝閬垮厤閲嶅鎻掑叆
+            ServiceDonateorgan query = new ServiceDonateorgan();
+            query.setInfoid(serviceDonateorgan.getInfoid());
+            query.setOrganno(serviceDonateorgan.getOrganno());
+            query.setDel_flag(0);
+            List<ServiceDonateorgan> exist = serviceDonateorganService.queryList(query);
+            if (!CollectionUtils.isEmpty(exist)) {
+                serviceDonateorgan.setId(exist.get(0).getId());
+            }
             if (serviceDonateorgan.getId() == null) {
                 i = serviceDonateorganService.save(serviceDonateorgan);
             } else {
                 i = serviceDonateorganService.updateById(serviceDonateorgan);
             }
         }
-        return toAjax(i);
+        // 鍥炰紶甯︿富閿殑鍒楄〃锛屼究浜庡墠绔洖濉� id
+        return AjaxResult.success(serviceDonateorganList);
     }
 
 }
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceDonationwitnessorganController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceDonationwitnessorganController.java
index b2e5e4a..1a9cf4c 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceDonationwitnessorganController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceDonationwitnessorganController.java
@@ -134,6 +134,7 @@
                 i = serviceDonationwitnessorganService.updateById(serviceDonationwitnessorgan);
             }
         }
-        return toAjax(i);
+        // 鍥炰紶甯︿富閿殑鍒楄〃锛屼究浜庡墠绔洖濉� id
+        return AjaxResult.success(serviceDonationwitnessorganList);
     }
 }
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceEthicalreviewopinionsController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceEthicalreviewopinionsController.java
index cf6bbe4..3ef89ba 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceEthicalreviewopinionsController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceEthicalreviewopinionsController.java
@@ -74,10 +74,21 @@
      */
     //// @PreAuthorize("@ss.hasPermi('project:ethicalreviewopinions:add')")
     @Log(title = "浼︾悊瀹℃煡涓撳鎰忚", businessType = BusinessType.INSERT)
+    @RepeatSubmit
     @PostMapping("/add")
-//    @NotRepeatCommit(key = "param:arg[1]", value = 30000)
     public AjaxResult add(@RequestBody ServiceEthicalreviewopinions serviceEthicalreviewopinions) {
-        boolean save = serviceEthicalreviewopinionsService.save(serviceEthicalreviewopinions);
+        // 2026-10-22锛氬悓涓�妗堜緥鍙厑璁镐竴鏉℃湭鍒犻櫎璁板綍鈥斺�斿凡瀛樺湪鍒欐洿鏂帮紝閬垮厤鍙嶅淇濆瓨浜х敓閲嶅琛�
+        if (serviceEthicalreviewopinions.getInfoid() != null) {
+            ServiceEthicalreviewopinions query = new ServiceEthicalreviewopinions();
+            query.setInfoid(serviceEthicalreviewopinions.getInfoid());
+            List<ServiceEthicalreviewopinions> exist = serviceEthicalreviewopinionsService.queryList(query);
+            if (exist != null && !exist.isEmpty()) {
+                serviceEthicalreviewopinions.setId(exist.get(0).getId());
+                serviceEthicalreviewopinionsService.updateById(serviceEthicalreviewopinions);
+                return AjaxResult.success(serviceEthicalreviewopinions);
+            }
+        }
+        serviceEthicalreviewopinionsService.save(serviceEthicalreviewopinions);
         return AjaxResult.success(serviceEthicalreviewopinions);
     }
 
@@ -87,7 +98,7 @@
     //// @PreAuthorize("@ss.hasPermi('project:ethicalreviewopinions:edit')")
     @Log(title = "浼︾悊瀹℃煡涓撳鎰忚", businessType = BusinessType.UPDATE)
     @PostMapping("/edit")
-//    @RepeatSubmit
+    @RepeatSubmit
     public AjaxResult edit(@RequestBody ServiceEthicalreviewopinions serviceEthicalreviewopinions) {
         return toAjax(serviceEthicalreviewopinionsService.updateById(serviceEthicalreviewopinions));
     }
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceFunddetailController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceFunddetailController.java
index 4dc7e41..167f43d 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceFunddetailController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceFunddetailController.java
@@ -87,6 +87,13 @@
     @PostMapping("/add")
     @NotRepeatCommit(key = "param:arg[1]", value = 30000)
     public AjaxResult add(@RequestBody ServiceFunddetail serviceFunddetail) {
+        // 2026-10-15锛氶檮浠舵枃浠跺悕瑙勮寖浜屾鏍¢獙锛堜笌鍓嶇 opo-web/src/utils/fileNameCheck.js 鍚屽彛寰勶紝
+        // 鐩殑鏄槻姝㈢粫杩囧墠绔洿鎺ヨ皟鎺ュ彛淇濆瓨涓嶅悎瑙勯檮浠跺悕锛夈�傛柊澧炲満鏅病鏈夊巻鍙查檮浠讹紝鐢ㄤ弗鏍兼ā寮忋��
+        String nameError = com.ruoyi.project.common.AttachmentNameValidator
+                .checkJsonList(serviceFunddetail.getInvoicefiles(), serviceFunddetail.getAnnexfiles());
+        if (nameError != null) {
+            return AjaxResult.error("闄勪欢鏂囦欢鍚嶄笉绗﹀悎瑕佹眰锛屾棤娉曚繚瀛橈細" + nameError);
+        }
         boolean save = serviceFunddetailService.save(serviceFunddetail);
         return AjaxResult.success(serviceFunddetail);
     }
@@ -101,6 +108,24 @@
     @NotRepeatCommit(key = "param:arg[1]", value = 30000)
     public AjaxResult edit(@RequestBody ServiceFunddetail serviceFunddetail) {
         log.info("淇敼鐨勬暟鎹俊鎭細{}", serviceFunddetail);
+        // 2026-10-15锛氶檮浠舵枃浠跺悕瑙勮寖浜屾鏍¢獙銆備慨鏀瑰満鏅寜涓氬姟鍙e緞"鍙牎楠屾湰娆″彉鏇寸殑闄勪欢"锛�
+        // 淇濆瓨鍓嶈鏄庣粏宸插瓨鍦ㄧ殑鍘嗗彶闄勪欢鍚嶄笉鍙備笌鏍¢獙锛屽惁鍒欒�佸崟鎹紙鍘嗗彶涓嶅悎瑙勫悕鍗犳瘮寰堥珮锛夋敼涓噾棰濋兘瀛樹笉杩涘幓銆�
+        java.util.Set<String> existingNames = new java.util.HashSet<>();
+        if (serviceFunddetail.getId() != null) {
+            ServiceFunddetail oldDetail = serviceFunddetailService.getById(serviceFunddetail.getId());
+            if (oldDetail != null) {
+                existingNames.addAll(com.ruoyi.project.common.AttachmentNameValidator
+                        .collectNames(oldDetail.getInvoicefiles()));
+                existingNames.addAll(com.ruoyi.project.common.AttachmentNameValidator
+                        .collectNames(oldDetail.getAnnexfiles()));
+            }
+        }
+        String nameError = com.ruoyi.project.common.AttachmentNameValidator
+                .checkJsonListForUpdate(existingNames, serviceFunddetail.getInvoicefiles(),
+                        serviceFunddetail.getAnnexfiles());
+        if (nameError != null) {
+            return AjaxResult.error("闄勪欢鏂囦欢鍚嶄笉绗﹀悎瑕佹眰锛屾棤娉曚繚瀛橈細" + nameError);
+        }
         return toAjax(serviceFunddetailService.updateById(serviceFunddetail));
     }
 
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceMedicalevaluationController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceMedicalevaluationController.java
index d80dd34..19e7041 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceMedicalevaluationController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceMedicalevaluationController.java
@@ -128,10 +128,21 @@
     @ApiOperation("鏂板鍖诲璇勪及")
     //// @PreAuthorize("@ss.hasPermi('project:medicalevaluation:add')")
     @Log(title = "鍖诲璇勪及", businessType = BusinessType.INSERT)
+    @RepeatSubmit
     @PostMapping("/add")
-//    @NotRepeatCommit(key = "param:arg[1]", value = 30000)
     public AjaxResult add(@RequestBody ServiceMedicalevaluation serviceMedicalevaluation) {
-        boolean save = serviceMedicalevaluationService.save(serviceMedicalevaluation);
+        // 2026-10-22锛氬悓涓�妗堜緥鍙厑璁镐竴鏉℃湭鍒犻櫎璁板綍鈥斺�斿凡瀛樺湪鍒欐洿鏂帮紝閬垮厤鍙嶅淇濆瓨浜х敓閲嶅琛�
+        if (serviceMedicalevaluation.getInfoid() != null) {
+            ServiceMedicalevaluation query = new ServiceMedicalevaluation();
+            query.setInfoid(serviceMedicalevaluation.getInfoid());
+            List<ServiceMedicalevaluation> exist = serviceMedicalevaluationService.queryList(query);
+            if (exist != null && !exist.isEmpty()) {
+                serviceMedicalevaluation.setId(exist.get(0).getId());
+                serviceMedicalevaluationService.updateById(serviceMedicalevaluation);
+                return AjaxResult.success(serviceMedicalevaluation);
+            }
+        }
+        serviceMedicalevaluationService.save(serviceMedicalevaluation);
         return AjaxResult.success(serviceMedicalevaluation);
     }
 
@@ -141,9 +152,14 @@
     @ApiOperation("淇敼鍖诲璇勪及")
     //// @PreAuthorize("@ss.hasPermi('project:medicalevaluation:edit')")
     @Log(title = "鍖诲璇勪及", businessType = BusinessType.UPDATE)
+    @RepeatSubmit
     @PostMapping("/edit")
-//    @NotRepeatCommit(key = "param:arg[1]", value = 30000)
     public AjaxResult edit(@RequestBody ServiceMedicalevaluation serviceMedicalevaluation) {
+        // 浼樺厛鎸変富閿洿鏂帮紙鍓嶇宸插洖濉� id 鐨勫父瑙勮矾寰勶級
+        if (serviceMedicalevaluation.getId() != null) {
+            return toAjax(serviceMedicalevaluationService.updateById(serviceMedicalevaluation));
+        }
+        // 鍏煎鏈紶 id 鐨勬棫璋冪敤锛氭寜 infoid 瀹氫綅鏈垹闄よ褰�
         List<ServiceMedicalevaluation> list = serviceMedicalevaluationService.queryList(serviceMedicalevaluation);
         if (CollectionUtils.isEmpty(list)) {
             return error("鍖诲璇勪及鏁版嵁涓嶅瓨鍦�,璇锋鏌ュ悗鍐嶆淇敼");
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceReimbursementdetailController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceReimbursementdetailController.java
index ca09670..ed619ef 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceReimbursementdetailController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceReimbursementdetailController.java
@@ -102,6 +102,21 @@
     @PostMapping("/add")
     @RepeatSubmit
     public AjaxResult add(@RequestBody ServiceReimbursementdetailVO serviceReimbursementdetailVO) {
+        // 2026-10-15锛氶檮浠舵枃浠跺悕瑙勮寖浜屾鏍¢獙锛堜笌鍓嶇 opo-web/src/utils/fileNameCheck.js 鍚屽彛寰勶紝
+        // 鐩殑鏄槻姝㈢粫杩囧墠绔洿鎺ヨ皟鎺ュ彛淇濆瓨涓嶅悎瑙勯檮浠跺悕锛夈�傛柊澧炲満鏅病鏈夊巻鍙查檮浠讹紝鐢ㄤ弗鏍兼ā寮忋��
+        // 娉ㄦ剰锛歀ist 涓虹┖鏃跺繀椤诲洖閫�鏍¢獙瀛楃涓插瓧娈碉紙annexfiles / invoicefiles锛夛紝
+        // 鍚﹀垯鍙紶瀛楃涓插瓧娈靛氨鑳界粫杩囨牎楠岋紙鎺ュ彛灞傞潰鐨勭粫杩囧彛锛夈��
+        String invoiceJson = CollectionUtils.isEmpty(serviceReimbursementdetailVO.getInvoicefilesList())
+                ? serviceReimbursementdetailVO.getInvoicefiles()
+                : JSON.toJSONString(serviceReimbursementdetailVO.getInvoicefilesList());
+        String annexJson = CollectionUtils.isEmpty(serviceReimbursementdetailVO.getAnnexfilesList())
+                ? serviceReimbursementdetailVO.getAnnexfiles()
+                : JSON.toJSONString(serviceReimbursementdetailVO.getAnnexfilesList());
+        String nameError = com.ruoyi.project.common.AttachmentNameValidator
+                .checkJsonList(invoiceJson, annexJson);
+        if (nameError != null) {
+            return AjaxResult.error("闄勪欢鏂囦欢鍚嶄笉绗﹀悎瑕佹眰锛屾棤娉曚繚瀛橈細" + nameError);
+        }
         ServiceReimbursementdetail serviceReimbursementdetail = DtoConversionUtils.sourceToTarget(serviceReimbursementdetailVO, ServiceReimbursementdetail.class);
         //灏嗗墠绔紶鏉ョ殑闄勪欢闆嗗悎杞垚瀛楃涓�
         if (!CollectionUtils.isEmpty(serviceReimbursementdetailVO.getAnnexfilesList())) {
@@ -123,6 +138,24 @@
     @PostMapping("/updateRDlList")
     public AjaxResult updateRDlList(@RequestBody List<ServiceReimbursementdetail> serviceReimbursementdetails) {
         for (ServiceReimbursementdetail serviceReimbursementdetail : serviceReimbursementdetails) {
+            // 2026-10-15锛氶檮浠舵枃浠跺悕瑙勮寖浜屾鏍¢獙锛堝彧鏍¢獙鏈鍙樻洿鐨勯檮浠讹紝鍘嗗彶闄勪欢鏀捐锛�
+            java.util.Set<String> existingNames = new java.util.HashSet<>();
+            if (serviceReimbursementdetail.getId() != null) {
+                ServiceReimbursementdetail oldDetail = serviceReimbursementdetailService
+                        .getById(serviceReimbursementdetail.getId());
+                if (oldDetail != null) {
+                    existingNames.addAll(com.ruoyi.project.common.AttachmentNameValidator
+                            .collectNames(oldDetail.getInvoicefiles()));
+                    existingNames.addAll(com.ruoyi.project.common.AttachmentNameValidator
+                            .collectNames(oldDetail.getAnnexfiles()));
+                }
+            }
+            String nameError = com.ruoyi.project.common.AttachmentNameValidator.checkJsonListForUpdate(
+                    existingNames, serviceReimbursementdetail.getInvoicefiles(),
+                    serviceReimbursementdetail.getAnnexfiles());
+            if (nameError != null) {
+                return AjaxResult.error("闄勪欢鏂囦欢鍚嶄笉绗﹀悎瑕佹眰锛屾棤娉曚繚瀛橈細" + nameError);
+            }
             serviceReimbursementdetailService.saveOrUpdate(serviceReimbursementdetail);
 
         }
@@ -138,6 +171,31 @@
     @PostMapping("/reimbursementdetailEdit")
     //@RepeatSubmit
     public AjaxResult edit(@RequestBody ServiceReimbursementdetailVO serviceReimbursementdetailVO) {
+        // 2026-10-15锛氶檮浠舵枃浠跺悕瑙勮寖浜屾鏍¢獙锛堜笌鍓嶇 fileNameCheck 鍚屽彛寰勶紝闃叉缁曡繃鍓嶇锛夈��
+        // 淇敼鍦烘櫙鎸変笟鍔″彛寰�"鍙牎楠屾湰娆″彉鏇寸殑闄勪欢"锛氫繚瀛樺墠宸插瓨鍦ㄧ殑鍘嗗彶闄勪欢鍚嶄笉鍙備笌鏍¢獙锛岄伩鍏嶅崱浣忚�佸崟鎹��
+        java.util.Set<String> existingNames = new java.util.HashSet<>();
+        if (serviceReimbursementdetailVO.getId() != null) {
+            ServiceReimbursementdetail oldDetail = serviceReimbursementdetailService
+                    .getById(serviceReimbursementdetailVO.getId());
+            if (oldDetail != null) {
+                existingNames.addAll(com.ruoyi.project.common.AttachmentNameValidator
+                        .collectNames(oldDetail.getInvoicefiles()));
+                existingNames.addAll(com.ruoyi.project.common.AttachmentNameValidator
+                        .collectNames(oldDetail.getAnnexfiles()));
+            }
+        }
+        // List 涓虹┖鏃跺洖閫�鏍¢獙瀛楃涓插瓧娈碉紙annexfiles / invoicefiles锛夛紝鍫典綇"鍙紶瀛楃涓插瓧娈�"鐨勭粫杩囧彛
+        String invoiceJson = CollectionUtils.isEmpty(serviceReimbursementdetailVO.getInvoicefilesList())
+                ? serviceReimbursementdetailVO.getInvoicefiles()
+                : JSON.toJSONString(serviceReimbursementdetailVO.getInvoicefilesList());
+        String annexJson = CollectionUtils.isEmpty(serviceReimbursementdetailVO.getAnnexfilesList())
+                ? serviceReimbursementdetailVO.getAnnexfiles()
+                : JSON.toJSONString(serviceReimbursementdetailVO.getAnnexfilesList());
+        String nameError = com.ruoyi.project.common.AttachmentNameValidator
+                .checkJsonListForUpdate(existingNames, invoiceJson, annexJson);
+        if (nameError != null) {
+            return AjaxResult.error("闄勪欢鏂囦欢鍚嶄笉绗﹀悎瑕佹眰锛屾棤娉曚繚瀛橈細" + nameError);
+        }
         if (serviceReimbursementdetailVO.getTrafficexpense() == null) {
             serviceReimbursementdetailVO.setTrafficexpense(new BigDecimal(0));
         }
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceRelativesconfirmationController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceRelativesconfirmationController.java
index 71bfc70..7a4a790 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceRelativesconfirmationController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/project/ServiceRelativesconfirmationController.java
@@ -122,7 +122,18 @@
     @RepeatSubmit
     public AjaxResult add(@RequestBody ServiceRelativesconfirmation serviceRelativesconfirmation) {
         log.info("鏂板鎹愮尞浜插睘纭锛歿}", serviceRelativesconfirmation);
-        boolean save = serviceRelativesconfirmationService.save(serviceRelativesconfirmation);
+        // 2026-10-22锛氬悓涓�妗堜緥鍙厑璁镐竴鏉℃湭鍒犻櫎璁板綍鈥斺�斿凡瀛樺湪鍒欐洿鏂帮紝閬垮厤鍙嶅淇濆瓨浜х敓閲嶅琛�
+        if (serviceRelativesconfirmation.getInfoid() != null) {
+            ServiceRelativesconfirmation query = new ServiceRelativesconfirmation();
+            query.setInfoid(serviceRelativesconfirmation.getInfoid());
+            List<ServiceRelativesconfirmation> exist = serviceRelativesconfirmationService.queryList(query);
+            if (exist != null && !exist.isEmpty()) {
+                serviceRelativesconfirmation.setId(exist.get(0).getId());
+                serviceRelativesconfirmationService.updateById(serviceRelativesconfirmation);
+                return AjaxResult.success(serviceRelativesconfirmation);
+            }
+        }
+        serviceRelativesconfirmationService.save(serviceRelativesconfirmation);
         return AjaxResult.success(serviceRelativesconfirmation);
     }
 
diff --git a/ruoyi-project/src/main/java/com/ruoyi/project/domain/BaseItemexpense.java b/ruoyi-project/src/main/java/com/ruoyi/project/domain/BaseItemexpense.java
index 3a8af09..bcdf08f 100644
--- a/ruoyi-project/src/main/java/com/ruoyi/project/domain/BaseItemexpense.java
+++ b/ruoyi-project/src/main/java/com/ruoyi/project/domain/BaseItemexpense.java
@@ -47,5 +47,13 @@
     @Excel(name = "鍚敤鐘舵��")
     private String usestate;
 
+    /**
+     * 涓撳璐规牎楠屾ā寮忥細1=寮哄埗鏍¢獙锛堥噾棰濈被闂涓嶉�氳繃鍒欎笉鑳戒繚瀛橈級锛�2=鏍¢獙鎻愰啋锛堥噾棰濈被闂浠呮彁閱掞紝鍏佽淇濆瓨锛夛紱3=涓嶆牎楠岋紙璺宠繃閲戦绫昏鍒欙級銆�
+     * 鏁版嵁璐ㄩ噺绫昏鍒欙紙閲戦涓� 0銆佹湭濉啓璐圭敤璇存槑锛夊湪涓夌妯″紡涓嬮兘寮哄埗銆�
+     */
+    @ApiModelProperty("涓撳璐规牎楠屾ā寮忥細1=寮哄埗鏍¢獙 2=鏍¢獙鎻愰啋 3=涓嶆牎楠�")
+    @Excel(name = "鏍¢獙妯″紡")
+    private Integer validateMode;
+
 }
 
diff --git a/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ExpertFeeValidateService.java b/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ExpertFeeValidateService.java
index 6d297f4..a8be60f 100644
--- a/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ExpertFeeValidateService.java
+++ b/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ExpertFeeValidateService.java
@@ -305,6 +305,65 @@
         }
         log.info("[涓撳璐规牎楠宂 鍙備笌鏍¢獙鏄庣粏 {} 鏉★細{}", rows.size(), describeRows(rows));
 
+        // 2026-10-15锛氭寜"璐圭敤椤圭洰"鐨勬牎楠屾ā寮忥紙base_itemexpense.validate_mode锛夋媶鍒嗘槑缁嗗悗鍒嗗埆鏍¢獙
+        //   1=寮哄埗鏍¢獙锛氶噾棰濈被闂 鈫� 闃绘柇锛坋rror锛�
+        //   2=鏍¢獙鎻愰啋锛氶噾棰濈被闂 鈫� 浠呮彁閱掞紙warning锛夛紝鍏佽淇濆瓨
+        //   3=涓嶆牎楠�  锛氳烦杩囪椤圭洰鍏ㄩ儴閲戦绫昏鍒�
+        // 璇存槑锛氶噾棰濈被瑙勫垯鍏ㄩ儴鎸夐」鐩� id 鍒ゅ畾锛屽悓涓�椤圭洰鐨勬槑缁嗘墠浼氫簰鐩镐骇鐢熷悎璁$被闂锛�
+        //       鍥犳鎸夐」鐩媶鍒嗕笉浼氬奖鍝嶅悇瑙勫垯鍐呴儴閫昏緫锛涘惈璺ㄩ」鐩瘮杈冪殑瑙勫垯锛堝璇勪及鍐茬獊锛�
+        //       鍦ㄥ弻鏂归兘鏄己鍒舵ā寮忔椂浠嶇劧涓�璧峰弬涓庯紝琛屼负涓嶅彉銆�
+        List<DetailRow> forcedRows = new ArrayList<>();
+        List<DetailRow> remindRows = new ArrayList<>();
+        List<DetailRow> skippedRows = new ArrayList<>();
+        for (DetailRow row : rows) {
+            int mode = loadItemMode(row.getItemid());
+            if (mode == MODE_SKIP) {
+                skippedRows.add(row);
+            } else if (mode == MODE_REMIND) {
+                remindRows.add(row);
+            } else {
+                forcedRows.add(row);
+            }
+        }
+        log.info("[涓撳璐规牎楠宂 鏍¢獙妯″紡缁熻锛氬己鍒�={} 鎻愰啋={} 涓嶆牎楠�={}",
+                forcedRows.size(), remindRows.size(), skippedRows.size());
+
+        // 1) 寮哄埗鏍¢獙锛氭甯搁樆鏂�
+        runAmountRules(forcedRows, result);
+
+        // 2) 鏍¢獙鎻愰啋锛氬悓鏍疯窇涓�閬嶏紝浣嗘妸缁撴灉闄嶇骇涓烘彁閱掞紙涓嶉樆鏂級
+        if (!remindRows.isEmpty()) {
+            ExpertFeeCheckResult remindResult = new ExpertFeeCheckResult();
+            runAmountRules(remindRows, remindResult);
+            for (String error : remindResult.getErrors()) {
+                // 涓氬姟鏂圭‘璁ょ殑鎻愰啋鏂囨锛氶噾棰濈被闂鍦ㄣ�屾牎楠屾彁閱掋�嶆ā寮忎笅涓嶉樆鏂紝浠呮彁绀哄悗鍙户缁繚瀛�
+                result.addWarning("璇ヨ垂鐢ㄩ」瀛樺湪瓒呮爣鍑嗘儏鍐碉紝浠呬綔鎻愰啋锛屾槸鍚︾户缁繚瀛橈紵銆�" + error + "銆�");
+            }
+            if (!remindResult.getErrors().isEmpty()) {
+                log.info("[涓撳璐规牎楠宂 浠ヤ笅鏄庣粏鎵�灞為」鐩负銆屾牎楠屾彁閱掋�嶆ā寮忥紝浠呮彁閱掍笉闃绘柇锛歿}", describeRows(remindRows));
+            }
+        }
+
+        // 3) 涓嶆牎楠岋細璺宠繃閲戦绫昏鍒欙紝浠呰褰曟棩蹇楋紝渚夸簬浜嬪悗鍥炴函
+        if (!skippedRows.isEmpty()) {
+            log.info("[涓撳璐规牎楠宂 浠ヤ笅鏄庣粏鎵�灞為」鐩负銆屼笉鏍¢獙銆嶆ā寮忥紝宸茶烦杩囬噾棰濈被瑙勫垯锛歿}", describeRows(skippedRows));
+        }
+
+        // 4) 鏁版嵁璐ㄩ噺绫昏鍒欙紙閲戦涓� 0銆佹湭濉啓璐圭敤璇存槑锛夊湪涓夌妯″紡涓嬮兘寮哄埗锛�
+        //    瀵规湭鍙備笌寮哄埗鏍¢獙鐨勬槑缁嗗崟鐙窇涓�娆�"鍙煡鏁版嵁璐ㄩ噺"鐨勬鏌ワ紝閬垮厤鍑虹幇閲戦涓虹┖鐨勮剰鏁版嵁
+        checkItemStandard(remindRows, result, false);
+        checkItemStandard(skippedRows, result, false);
+
+        log.info("[涓撳璐规牎楠宂 鏍¢獙瀹屾垚 闃绘柇={} 鎻愮ず={} 闃绘柇淇℃伅={} 鎻愮ず淇℃伅={}",
+                result.getErrors().size(), result.getWarnings().size(),
+                result.getErrors(), result.getWarnings());
+        return result;
+    }
+
+    /**
+     * 閲戦绫昏鍒欙紙鍙�"鏍¢獙妯″紡"褰卞搷锛夛細鍚堣闄愰銆丒COM銆佸姪鎵嬨�佹墜鏈銆佽瘎浼板啿绐併�佽垂鐢ㄦ爣鍑嗐�佸櫒瀹樿幏鍙栧姞鎴愩��
+     */
+    private void runAmountRules(List<DetailRow> rows, ExpertFeeCheckResult result) {
         // 瑙勫垯 1~4銆�7~9锛氬悎璁¢檺棰濈被锛堥樆鏂級锛屽叏閮ㄦ寜椤圭洰 id 鍒ゅ畾
         checkSingleItemLimit(rows, resolveItemIds(CFG_ITEM_ORGAN_MAINTAIN, "鎹愮尞鍖婚櫌鍣ㄥ畼鍔熻兘缁存姢璐�", FALLBACK_ORGAN_MAINTAIN),
                 false,
@@ -321,13 +380,8 @@
 
         // 瑙勫垯 5锛氫粎鎻愮ず锛涘熀鏈鍒欎笌鍣ㄥ畼鑾峰彇鍔犳垚锛氱‖鎷︽埅
         checkAssessConflict(rows, result);
-        checkItemStandard(rows, result);
+        checkItemStandard(rows, result, true);
         checkDoctorOrganSecond(rows, result);
-
-        log.info("[涓撳璐规牎楠宂 鏍¢獙瀹屾垚 闃绘柇={} 鎻愮ず={} 闃绘柇淇℃伅={} 鎻愮ず淇℃伅={}",
-                result.getErrors().size(), result.getWarnings().size(),
-                result.getErrors(), result.getWarnings());
-        return result;
     }
 
     /** 鎶婂弬涓庢牎楠岀殑鏄庣粏鎷兼垚涓�琛岋紝渚夸簬鎺掓煡銆屼负浠�涔堟病鎷︿綇銆嶏紙閲戦銆侀」鐩�佸満鏅竴鐩簡鐒讹級 */
@@ -626,6 +680,18 @@
      * 鑻ユ嬁绋庡墠閲戦锛堝惈绋庡姞浠峰悗鐨勫�硷級鍘绘瘮锛屼細鎶婂ぇ閲忔甯稿崟鎹鍒や负瓒呮爣鍑嗭紙瀹炴祴 3168 缁� vs 162 缁勶級銆�
      */
     private void checkItemStandard(List<DetailRow> rows, ExpertFeeCheckResult result) {
+        checkItemStandard(rows, result, true);
+    }
+
+    /**
+     * 璐圭敤鏍囧噯鏍¢獙銆�
+     *
+     * @param amountCheck {@code true}=瀹屾暣鏍¢獙锛堝惈閲戦绫昏鍒欙紝鍙楅」鐩牎楠屾ā寮忓奖鍝嶏級锛�
+     *                    {@code false}=鍙煡鏁版嵁璐ㄩ噺锛堥噾棰濅负 0銆佹湭濉啓璐圭敤璇存槑锛夛紝
+     *                    鐢ㄤ簬銆屾牎楠屾彁閱� / 涓嶆牎楠屻�嶆ā寮忎笅瀵规湭鍙備笌寮哄埗鏍¢獙鐨勬槑缁嗗仛鍏滃簳寮哄埗锛�
+     *                    閬垮厤鍑虹幇閲戦涓虹┖鐨勮剰鏁版嵁銆�
+     */
+    private void checkItemStandard(List<DetailRow> rows, ExpertFeeCheckResult result, boolean amountCheck) {
         Map<String, List<DetailRow>> groups = new LinkedHashMap<>();
         Map<String, BigDecimal> groupStandards = new LinkedHashMap<>();
         Map<String, String> groupLabels = new LinkedHashMap<>();
@@ -644,9 +710,17 @@
             }
             BigDecimal standard = loadItemStandard(row.getItemid(), scope);
             if (standard == null) {
+                if (!amountCheck) {
+                    // 銆屾湭鎵惧埌璐圭敤鏍囧噯銆嶅睘閲戦绫婚棶棰橈紝鎸夐」鐩牎楠屾ā寮忓鐞�
+                    continue;
+                }
                 result.addError(String.format(
                         "%s鏈壘鍒板搴旂殑璐圭敤鏍囧噯锛堥」鐩甶d=%s锛岃垂鐢ㄨ鏄�=%s锛夛紝涓嶅厑璁告姤閿�锛岃鑱旂郴绠$悊鍛樼淮鎶よ垂鐢ㄦ爣鍑�",
                         itemLabel(row), row.getItemid(), scope));
+                continue;
+            }
+            if (!amountCheck) {
+                // 鍙煡鏁版嵁璐ㄩ噺锛氫笉鍐嶅仛璐圭敤鏍囧噯姣旇緝涓庨噸澶嶅綍鍏ユ彁閱�
                 continue;
             }
             String key = groupKey(row, scope);
@@ -765,6 +839,64 @@
      *
      * @return 鎵句笉鍒版椂杩斿洖 {@code null}锛岃皟鐢ㄦ柟鎸夈�屽尮閰嶄笉鍒版爣鍑嗐�嶉樆鏂�
      */
+    /** 鏍¢獙妯″紡锛氬己鍒舵牎楠岋紙閲戦绫婚棶棰樹笉閫氳繃鍒欎笉鑳戒繚瀛橈級 */
+    private static final int MODE_FORCE = 1;
+    /** 鏍¢獙妯″紡锛氭牎楠屾彁閱掞紙閲戦绫婚棶棰樹粎鎻愰啋锛屽厑璁镐繚瀛橈級 */
+    private static final int MODE_REMIND = 2;
+    /** 鏍¢獙妯″紡锛氫笉鏍¢獙锛堣烦杩囪椤圭洰鐨勯噾棰濈被瑙勫垯锛� */
+    private static final int MODE_SKIP = 3;
+
+    /** 椤圭洰鏍¢獙妯″紡缂撳瓨锛�60 绉掞級锛宬ey = itemid */
+    private final Map<Long, Integer> itemModeCache = new java.util.concurrent.ConcurrentHashMap<>();
+    private final Map<Long, Long> itemModeExpireCache = new java.util.concurrent.ConcurrentHashMap<>();
+
+    /**
+     * 璇诲彇璐圭敤椤圭洰鐨勬牎楠屾ā寮忥紙{@code base_itemexpense.validate_mode}锛夛紝缂撳瓨 60 绉掋��
+     *
+     * <p>璇讳笉鍒般�佸彇鍊奸潪娉曟垨鏌ヨ寮傚父鏃�**涓�寰嬫寜銆屽己鍒舵牎楠屻�嶅鐞�**锛�
+     * 淇濊瘉涓嶄細鍥犱负寮�鍏宠涓嶅埌鑰屾斁鏉炬牎楠岋紙瀹佸彲澶氭嫤锛屼笉鍙紡鎷︼級銆�
+     */
+    private int loadItemMode(Long itemid) {
+        if (itemid == null) {
+            return MODE_FORCE;
+        }
+        long now = System.currentTimeMillis();
+        Integer cached = itemModeCache.get(itemid);
+        Long expireAt = itemModeExpireCache.get(itemid);
+        if (cached != null && expireAt != null && expireAt > now) {
+            return cached;
+        }
+        int mode = MODE_FORCE;
+        try {
+            // 2026-10-15锛堜慨澶嶏級锛氫笉鑳界敤 wrapper.select("ValidateMode") + selectMaps 鍙栬繖涓�鍒楋紝涓ゅ閮戒細璁╂ā寮忓彇涓嶅埌锛�
+            //   鈶� 瀛楃涓插垪鍚嶄細琚� MyBatis-Plus 鍘熸牱鎷艰繘 SELECT锛岃�岀湡瀹炲垪鍚嶆槸 validate_mode锛�
+            //      MySQL 鐩存帴鎶� Unknown column 'ValidateMode'锛屽紓甯歌涓嬮潰鐨� catch 鍚炴帀鍚庢案杩滃洖钀姐�屽己鍒舵牎楠屻�嶏紱
+            //   鈶� 鍗充娇鎶婂垪鍚嶆敼鎴� validate_mode锛宻electMaps 杩斿洖鐨� Map key 涔熸槸鍘熷鍒楁爣绛撅紙validate_mode锛�
+            //      涓嶄細杞垚椹煎嘲锛夛紝涓� "validatemode" 鍖归厤涓嶄笂锛屾ā寮忎緷鐒跺彇涓嶅埌銆�
+            // 鏀逛负涓庡悓绫� loadItemStandards 涓�鑷寸殑瀹炰綋鏄犲皠鍐欐硶锛堢粡瀹炰綋瀛楁 validateMode 鏄犲皠鍒板垪 validate_mode锛夈��
+            QueryWrapper<BaseItemexpense> wrapper = new QueryWrapper<>();
+            wrapper.eq("ItemId", itemid);
+            wrapper.eq("UseState", "1");
+            wrapper.apply("del_flag = 0");
+            wrapper.orderByAsc("Id");
+            List<BaseItemexpense> list = baseItemexpenseMapper.selectList(wrapper);
+            if (!CollectionUtils.isEmpty(list) && list.get(0) != null
+                    && list.get(0).getValidateMode() != null) {
+                mode = list.get(0).getValidateMode();
+            }
+            if (mode != MODE_FORCE && mode != MODE_REMIND && mode != MODE_SKIP) {
+                log.warn("[涓撳璐规牎楠宂 椤圭洰鏍¢獙妯″紡鍙栧�奸潪娉曪紝鎸夊己鍒舵牎楠屽鐞嗭紝itemid={}锛寁alidate_mode={}", itemid, mode);
+                mode = MODE_FORCE;
+            }
+        } catch (Exception e) {
+            log.error("[涓撳璐规牎楠宂 璇诲彇椤圭洰鏍¢獙妯″紡澶辫触锛屾寜寮哄埗鏍¢獙澶勭悊锛宨temid={}", itemid, e);
+            mode = MODE_FORCE;
+        }
+        itemModeCache.put(itemid, mode);
+        itemModeExpireCache.put(itemid, now + ITEM_EXPENSE_CACHE_MILLIS);
+        return mode;
+    }
+
     private BigDecimal loadItemStandard(Long itemid, String scope) {
         return loadItemStandards(itemid).get(scope);
     }
diff --git a/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceDonatebaseinfoServiceImpl.java b/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceDonatebaseinfoServiceImpl.java
index a89a649..06dea79 100644
--- a/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceDonatebaseinfoServiceImpl.java
+++ b/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceDonatebaseinfoServiceImpl.java
@@ -216,24 +216,27 @@
     public List<ServiceDonatebaseinfo> selectServiceDonatebaseinfoList(ServiceDonatebaseinfo serviceDonatebaseinfo) {
 
         SysUser user = SecurityUtils.getLoginUser().getUser();
-        List<SysRole> l = user.getRoles();
-        int b = 0;
+        // 瓒呯骇绠$悊鍛樹笉鍙�"鍙湅鏈汉鎶ラ�� / 鍙湅鏈儴闂�"鐨勬暟鎹寖鍥撮檺鍒讹紝鍙煡鐪嬪叏閮ㄦ暟鎹�
+        if (!isSuperAdmin(user)) {
+            List<SysRole> l = user.getRoles();
+            int b = 0;
 
-        for (SysRole r : l) {
-            if (r.getRoleId().longValue() == 3) {
-                b = 1;
+            for (SysRole r : l) {
+                if (r.getRoleId().longValue() == 3) {
+                    b = 1;
+                }
+                if (r.getRoleId().longValue() == 13) {
+                    b = 2;
+                }
             }
-            if (r.getRoleId().longValue() == 13) {
-                b = 2;
-            }
-        }
-        if (b == 1) {
+            if (b == 1) {
 //            serviceDonatebaseinfo.setCreateBy(user.getUserName());
-            log.info("user.getUserName()鐨勫�间负 ---- 锛歿}", user.getUserName());
-            serviceDonatebaseinfo.setReporterno(user.getUserName());
-        }
-        if (b == 2) {
-            serviceDonatebaseinfo.setDeptid(user.getDeptId());
+                log.info("user.getUserName()鐨勫�间负 ---- 锛歿}", user.getUserName());
+                serviceDonatebaseinfo.setReporterno(user.getUserName());
+            }
+            if (b == 2) {
+                serviceDonatebaseinfo.setDeptid(user.getDeptId());
+            }
         }
         List<ServiceDonatebaseinfo> serviceDonatebaseinfos = serviceDonatebaseinfoMapper.selectServiceDonatebaseinfoList(serviceDonatebaseinfo);
 
@@ -282,23 +285,26 @@
     public List<ServiceDonatebaseinfo> getPatName(ServiceDonatebaseinfo serviceDonatebaseinfo) {
 
         SysUser user = SecurityUtils.getLoginUser().getUser();
-        List<SysRole> l = user.getRoles();
-        int b = 0;
+        // 瓒呯骇绠$悊鍛樹笉鍙楁暟鎹寖鍥撮檺鍒讹紝鍙煡鐪嬪叏閮ㄦ暟鎹�
+        if (!isSuperAdmin(user)) {
+            List<SysRole> l = user.getRoles();
+            int b = 0;
 
-        for (SysRole r : l) {
-            if (r.getRoleId().longValue() == 3) {
-                b = 1;
+            for (SysRole r : l) {
+                if (r.getRoleId().longValue() == 3) {
+                    b = 1;
+                }
+                if (r.getRoleId().longValue() == 13) {
+                    b = 2;
+                }
             }
-            if (r.getRoleId().longValue() == 13) {
-                b = 2;
+            if (b == 1) {
+                log.info("user.getUserName()鐨勫�间负 ---- 锛歿}", user.getUserName());
+                serviceDonatebaseinfo.setReporterno(user.getUserName());
             }
-        }
-        if (b == 1) {
-            log.info("user.getUserName()鐨勫�间负 ---- 锛歿}", user.getUserName());
-            serviceDonatebaseinfo.setReporterno(user.getUserName());
-        }
-        if (b == 2) {
-            serviceDonatebaseinfo.setDeptid(user.getDeptId());
+            if (b == 2) {
+                serviceDonatebaseinfo.setDeptid(user.getDeptId());
+            }
         }
         List<ServiceDonatebaseinfo> serviceDonatebaseinfos = serviceDonatebaseinfoMapper.getPatName(serviceDonatebaseinfo);
 
@@ -308,15 +314,18 @@
     @Override
     public List<ServiceDonatebaseinfo> listForSearch(ServiceDonatebaseinfo serviceDonatebaseinfo) {
         SysUser user = SecurityUtils.getLoginUser().getUser();
-        List<SysRole> l = user.getRoles();
-        Boolean b = false;
-        for (SysRole r : l) {
-            if (r.getRoleId().longValue() == 3) {
-                b = true;
+        // 瓒呯骇绠$悊鍛樹笉鍙楁暟鎹寖鍥撮檺鍒讹紝鍙煡鐪嬪叏閮ㄦ暟鎹�
+        if (!isSuperAdmin(user)) {
+            List<SysRole> l = user.getRoles();
+            Boolean b = false;
+            for (SysRole r : l) {
+                if (r.getRoleId().longValue() == 3) {
+                    b = true;
+                }
             }
-        }
-        if (b) {
-            serviceDonatebaseinfo.setCreateBy(user.getUserName());
+            if (b) {
+                serviceDonatebaseinfo.setCreateBy(user.getUserName());
+            }
         }
 
         return serviceDonatebaseinfoMapper.listForSearch(serviceDonatebaseinfo);
@@ -581,4 +590,33 @@
         //灏嗘暟鎹皝闂紝骞惰繑鍥�
         return map;
     }
+
+    /**
+     * 鏄惁瓒呯骇绠$悊鍛樸��
+     *
+     * <p>鍒ゅ畾涓鸿秴绾х鐞嗗憳鐨勬儏褰細
+     * <ul>
+     *   <li>鍐呯疆绠$悊鍛樿处鍙凤紙userId = 1锛夛紱</li>
+     *   <li>璐﹀彿琚巿浜�"瓒呯骇绠$悊鍛�"瑙掕壊锛坮oleId = 1锛夈��</li>
+     * </ul>
+     * 瓒呯骇绠$悊鍛樹笉鍙�"鍙湅鏈汉鎶ラ�侊紙瑙掕壊3 涓撹亴浜哄憳锛�/ 鍙湅鏈儴闂紙瑙掕壊13 涓氬姟缁勯暱锛�"鐨勬暟鎹寖鍥撮檺鍒讹紝
+     * 鍙煡鐪嬪叏閮ㄦ暟鎹��
+     */
+    private boolean isSuperAdmin(SysUser user) {
+        if (user == null) {
+            return false;
+        }
+        if (SysUser.isAdmin(user.getUserId())) {
+            return true;
+        }
+        List<SysRole> roles = user.getRoles();
+        if (roles != null) {
+            for (SysRole role : roles) {
+                if (role.getRoleId() != null && role.getRoleId().longValue() == 1L) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
 }
diff --git a/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceDonatecompletioninfoServiceImpl.java b/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceDonatecompletioninfoServiceImpl.java
index 42176f1..fbd0243 100644
--- a/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceDonatecompletioninfoServiceImpl.java
+++ b/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceDonatecompletioninfoServiceImpl.java
@@ -74,6 +74,12 @@
         if (StringUtils.isNotNull(serviceDonatecompletioninfo.getInfoid())) {
             wrappers.eq(ServiceDonatecompletioninfo::getInfoid, serviceDonatecompletioninfo.getInfoid());
         }
+        // 2026-10-22锛氶粯璁ゅ彧鏌ヨ鏈垹闄よ褰�
+        if (StringUtils.isNotNull(serviceDonatecompletioninfo.getDel_flag())) {
+            wrappers.eq(ServiceDonatecompletioninfo::getDel_flag, serviceDonatecompletioninfo.getDel_flag());
+        } else {
+            wrappers.eq(ServiceDonatecompletioninfo::getDel_flag, 0);
+        }
         return this.list(wrappers);
     }
 
diff --git a/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceDonationwitnessServiceImpl.java b/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceDonationwitnessServiceImpl.java
index 53f6c13..4e15e11 100644
--- a/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceDonationwitnessServiceImpl.java
+++ b/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceDonationwitnessServiceImpl.java
@@ -73,6 +73,12 @@
         if (StringUtils.isNotBlank(serviceDonationwitness.getOperationdoctor())) {
             wrappers.eq(ServiceDonationwitness::getOperationdoctor, serviceDonationwitness.getOperationdoctor());
         }
+        // 2026-10-22锛氶粯璁ゅ彧鏌ヨ鏈垹闄よ褰�
+        if (StringUtils.isNotNull(serviceDonationwitness.getDel_flag())) {
+            wrappers.eq(ServiceDonationwitness::getDel_flag, serviceDonationwitness.getDel_flag());
+        } else {
+            wrappers.eq(ServiceDonationwitness::getDel_flag, 0);
+        }
         return this.list(wrappers);
     }
 
diff --git a/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceEthicalreviewopinionsServiceImpl.java b/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceEthicalreviewopinionsServiceImpl.java
index 1d974e5..c3da3ec 100644
--- a/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceEthicalreviewopinionsServiceImpl.java
+++ b/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceEthicalreviewopinionsServiceImpl.java
@@ -81,6 +81,12 @@
         if (serviceEthicalreviewopinions.getConclusionorder() != null) {
             wrappers.eq(ServiceEthicalreviewopinions::getConclusionorder, serviceEthicalreviewopinions.getConclusionorder());
         }
+        // 2026-10-22锛氶粯璁ゅ彧鏌ヨ鏈垹闄よ褰�
+        if (StringUtils.isNotNull(serviceEthicalreviewopinions.getDel_flag())) {
+            wrappers.eq(ServiceEthicalreviewopinions::getDel_flag, serviceEthicalreviewopinions.getDel_flag());
+        } else {
+            wrappers.eq(ServiceEthicalreviewopinions::getDel_flag, 0);
+        }
         return this.list(wrappers);
     }
 
diff --git a/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceFundServiceImpl.java b/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceFundServiceImpl.java
index 17d1ed3..49f934e 100644
--- a/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceFundServiceImpl.java
+++ b/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceFundServiceImpl.java
@@ -1583,6 +1583,28 @@
 
             // 淇濆瓨璇︽儏鏁版嵁
             for (ServiceFunddetailVO serviceFunddetailVO : serviceFunddetails) {
+                // 2026-10-15锛氶檮浠舵枃浠跺悕瑙勮寖浜屾鏍¢獙锛堜笌鍓嶇 fileNameCheck 鍚屽彛寰勶紱鍙牎楠屾湰娆″彉鏇寸殑闄勪欢锛屽巻鍙查檮浠舵斁琛岋級
+                java.util.Set<String> existingNames = new java.util.HashSet<>();
+                if (serviceFunddetailVO.getId() != null) {
+                    ServiceFunddetail oldDetail = serviceFunddetailMapper.selectById(serviceFunddetailVO.getId());
+                    if (oldDetail != null) {
+                        existingNames.addAll(com.ruoyi.project.common.AttachmentNameValidator
+                                .collectNames(oldDetail.getInvoicefiles()));
+                        existingNames.addAll(com.ruoyi.project.common.AttachmentNameValidator
+                                .collectNames(oldDetail.getAnnexfiles()));
+                    }
+                }
+                String invoiceJson = CollectionUtils.isEmpty(serviceFunddetailVO.getInvoicefilesList())
+                        ? serviceFunddetailVO.getInvoicefiles()
+                        : JSON.toJSONString(serviceFunddetailVO.getInvoicefilesList());
+                String annexJson = CollectionUtils.isEmpty(serviceFunddetailVO.getAnnexfilesList())
+                        ? serviceFunddetailVO.getAnnexfiles()
+                        : JSON.toJSONString(serviceFunddetailVO.getAnnexfilesList());
+                String nameError = com.ruoyi.project.common.AttachmentNameValidator
+                        .checkJsonListForUpdate(existingNames, invoiceJson, annexJson);
+                if (nameError != null) {
+                    throw new BaseException("闄勪欢鏂囦欢鍚嶄笉绗﹀悎瑕佹眰锛屾棤娉曚繚瀛橈細" + nameError);
+                }
                 //鍘绘帀韬唤璇佺殑棣栧熬绌烘牸
                 if (StringUtils.isNotEmpty(serviceFunddetailVO.getIdcardno())) {
                     serviceFunddetailVO.setIdcardno(serviceFunddetailVO.getIdcardno().trim());
diff --git a/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceMedicalevaluationServiceImpl.java b/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceMedicalevaluationServiceImpl.java
index f80b863..85271b7 100644
--- a/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceMedicalevaluationServiceImpl.java
+++ b/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceMedicalevaluationServiceImpl.java
@@ -54,6 +54,12 @@
         if (StringUtils.isNotBlank(serviceMedicalevaluation.getDonorno())) {
             wrappers.eq(ServiceMedicalevaluation::getDonorno, serviceMedicalevaluation.getDonorno());
         }
+        // 2026-10-22锛氶粯璁ゅ彧鏌ヨ鏈垹闄よ褰�
+        if (StringUtils.isNotNull(serviceMedicalevaluation.getDel_flag())) {
+            wrappers.eq(ServiceMedicalevaluation::getDel_flag, serviceMedicalevaluation.getDel_flag());
+        } else {
+            wrappers.eq(ServiceMedicalevaluation::getDel_flag, 0);
+        }
         return this.list(wrappers);
     }
 
diff --git a/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceRelativesconfirmationServiceImpl.java b/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceRelativesconfirmationServiceImpl.java
index 8f422db..97be067 100644
--- a/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceRelativesconfirmationServiceImpl.java
+++ b/ruoyi-project/src/main/java/com/ruoyi/project/service/impl/ServiceRelativesconfirmationServiceImpl.java
@@ -185,6 +185,12 @@
         if (serviceRelativesconfirmation.getUpdateTime() != null) {
             wrappers.eq(ServiceRelativesconfirmation::getUpdateTime, serviceRelativesconfirmation.getUpdateTime());
         }
+        // 2026-10-22锛氶粯璁ゅ彧鏌ヨ鏈垹闄よ褰�
+        if (StringUtils.isNotNull(serviceRelativesconfirmation.getDel_flag())) {
+            wrappers.eq(ServiceRelativesconfirmation::getDel_flag, serviceRelativesconfirmation.getDel_flag());
+        } else {
+            wrappers.eq(ServiceRelativesconfirmation::getDel_flag, 0);
+        }
         return this.list(wrappers);
     }
 
diff --git a/ruoyi-project/src/main/resources/mapper/project/ServiceFundMapper.xml b/ruoyi-project/src/main/resources/mapper/project/ServiceFundMapper.xml
index edefa9f..14ab295 100644
--- a/ruoyi-project/src/main/resources/mapper/project/ServiceFundMapper.xml
+++ b/ruoyi-project/src/main/resources/mapper/project/ServiceFundMapper.xml
@@ -142,6 +142,8 @@
 
         where del_flag = '0'
         <if test="donorno != null  and donorno != ''">and DonorNo = #{donorno}</if>
+        <!-- 2026-10-22锛氭姤閿�鍗曞垪琛ㄦ敮鎸佹寜"鎹愮尞鑰呭鍚�"妯$硦绛涢�夛紙浠呭湪浼犲�兼椂鐢熸晥锛屼笉褰卞搷鍏跺畠璋冪敤鏂癸級 -->
+        <if test="donorname != null  and donorname != ''">and DonorName like concat('%', #{donorname}, '%')</if>
         <if test="fundTaxId != null ">and fund_tax_id = #{fundTaxId}</if>
         <if test="userno != null  and userno != ''">and UserNo = #{userno}</if>
         <if test="username != null  and username != ''">and UserName like concat('%', #{username}, '%')</if>

--
Gitblit v1.9.3