From e1797a873bf114329f4870062201d388155ef014 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期五, 14 八月 2026 13:39:51 +0800
Subject: [PATCH] refactor(erp): 移除采购来票审核流程并简化业务逻辑

---
 yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/tender/vo/SrmTenderProjectSaveReqVO.java             |    4 
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/enums/ErrorCodeConstants.java                                         |    7 
 .playwright-mcp/page-2026-08-14T05-18-36-135Z.yml                                                                                |    1 
 yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/tender/SrmTenderProjectServiceImpl.java                       |   30 ++
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseInvoiceController.java           |   27 -
 docs/srm_supplier_tender_integration.md                                                                                          |   78 +++++
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseInvoiceService.java                       |   25 -
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/purchase/ErpPurchaseInvoiceDO.java                     |   13 
 docs/srm_certificate_attachment_integration.md                                                                                   |  113 +++++++
 yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/tender/vo/SrmTenderProjectPartialUpdateReqVO.java    |    5 
 .playwright-mcp/page-2026-08-14T05-18-50-100Z.yml                                                                                |    1 
 yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/tender/SrmTenderProjectController.java               |   22 +
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/invoice/ErpPurchaseInvoicePageReqVO.java |    6 
 yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/supplier/SrmSupplierServiceImpl.java                          |    7 
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/purchase/ErpPurchaseInvoiceMapper.java                      |   23 -
 docs/erp_purchase_invoice_remove_audit.md                                                                                        |   70 ++++
 docs/purchase_invoice_payment_link.md                                                                                            |   49 +-
 yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/certificate/SrmSupplierCertificateController.java    |   14 
 .playwright-mcp/page-2026-08-14T05-19-08-995Z.yml                                                                                |  103 ++++++
 yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmModelConvert.java                               |    5 
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/invoice/ErpPurchaseInvoiceRespVO.java    |   12 
 yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/tender/vo/SrmTenderProjectRespVO.java                |    5 
 yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/tender/SrmBidAwardServiceImpl.java                            |    7 
 yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/enums/storage/StorageRecordTypeEnum.java                        |    6 
 yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/apply/SrmSupplierApplyServiceImpl.java                        |   37 ++
 docs/sql/erp_purchase_invoice_remove_audit.sql                                                                                   |    9 
 yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/supplier/SrmSupplierController.java                  |    7 
 yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/certificate/vo/SrmSupplierCertificateSaveReqVO.java  |    4 
 yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/certificate/SrmSupplierCertificateServiceImpl.java            |   22 +
 /dev/null                                                                                                                        |   34 --
 yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/apply/SrmSupplierApplyService.java                            |    7 
 yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/supplier/SrmSupplierService.java                              |    5 
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/finance/ErpFinancePaymentServiceImpl.java                     |   11 
 yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/certificate/vo/SrmSupplierCertificateRespVO.java     |    5 
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseInvoiceServiceImpl.java                   |   67 +---
 35 files changed, 621 insertions(+), 220 deletions(-)

diff --git a/.playwright-mcp/page-2026-08-14T05-18-36-135Z.yml b/.playwright-mcp/page-2026-08-14T05-18-36-135Z.yml
new file mode 100644
index 0000000..6adf37e
--- /dev/null
+++ b/.playwright-mcp/page-2026-08-14T05-18-36-135Z.yml
@@ -0,0 +1 @@
+- generic [active]: 宸ヤ笟AI鏅洪�犲钩鍙�
\ No newline at end of file
diff --git a/.playwright-mcp/page-2026-08-14T05-18-50-100Z.yml b/.playwright-mcp/page-2026-08-14T05-18-50-100Z.yml
new file mode 100644
index 0000000..6adf37e
--- /dev/null
+++ b/.playwright-mcp/page-2026-08-14T05-18-50-100Z.yml
@@ -0,0 +1 @@
+- generic [active]: 宸ヤ笟AI鏅洪�犲钩鍙�
\ No newline at end of file
diff --git a/.playwright-mcp/page-2026-08-14T05-19-08-995Z.yml b/.playwright-mcp/page-2026-08-14T05-19-08-995Z.yml
new file mode 100644
index 0000000..8384a0a
--- /dev/null
+++ b/.playwright-mcp/page-2026-08-14T05-19-08-995Z.yml
@@ -0,0 +1,103 @@
+- generic [ref=f1e7]:
+  - complementary [ref=f1e8]:
+    - generic [ref=f1e9]:
+      - generic [ref=f1e10] [cursor=pointer]
+      - link "宸ヤ笟AI鏅洪�犲钩鍙� 宸ヤ笟AI鏅洪�犲钩鍙�" [ref=f1e15] [cursor=pointer]:
+        - /url: javascript:void 0
+        - img "宸ヤ笟AI鏅洪�犲钩鍙�" [ref=f1e18]
+        - generic [ref=f1e19]: 宸ヤ笟AI鏅洪�犲钩鍙�
+      - menu [ref=f1e22]:
+        - menuitem "棣栭〉" [ref=f1e23] [cursor=pointer]
+        - listitem [ref=f1e30]:
+          - generic [ref=f1e31] [cursor=pointer]: 鍩虹鏁版嵁
+        - listitem [ref=f1e39]:
+          - generic [ref=f1e40] [cursor=pointer]: 閲囪喘绠$悊
+        - listitem [ref=f1e46]:
+          - generic [ref=f1e47] [cursor=pointer]: 钀ラ攢绠$悊
+        - listitem [ref=f1e53]:
+          - generic [ref=f1e54] [cursor=pointer]: 璁惧绠$悊
+        - listitem [ref=f1e61]:
+          - generic [ref=f1e62] [cursor=pointer]: 浠撳偍鐗╂祦
+        - listitem [ref=f1e70]:
+          - generic [ref=f1e71] [cursor=pointer]: 鐢熶骇绠℃帶
+        - listitem [ref=f1e78]:
+          - generic [ref=f1e79] [cursor=pointer]: 璐ㄩ噺绠$悊
+        - listitem [ref=f1e85]:
+          - generic [ref=f1e86] [cursor=pointer]: 鍐崇瓥BI澶у睆
+        - listitem [ref=f1e92]:
+          - generic [ref=f1e93] [cursor=pointer]: 鍗忓悓鍔炲叕
+          - list [ref=f1e99]:
+            - listitem [ref=f1e100]:
+              - generic [ref=f1e101] [cursor=pointer]: 娴佺▼绠$悊
+              - list [ref=f1e107]:
+                - menuitem "娴佺▼妯″瀷" [ref=f1e108] [cursor=pointer]
+                - menuitem "娴佺▼琛ㄥ崟" [ref=f1e113] [cursor=pointer]
+                - menuitem "娴佺▼鍒嗙被" [ref=f1e118] [cursor=pointer]
+                - menuitem "鐢ㄦ埛鍒嗙粍" [ref=f1e123] [cursor=pointer]
+                - menuitem "娴佺▼鐩戝惉鍣�" [ref=f1e128] [cursor=pointer]
+                - menuitem "娴佺▼琛ㄨ揪寮�" [ref=f1e133] [cursor=pointer]
+                - menuitem "娴佺▼瀹炰緥" [ref=f1e138] [cursor=pointer]
+                - menuitem "娴佺▼浠诲姟" [ref=f1e143] [cursor=pointer]
+            - listitem [ref=f1e148]:
+              - generic [ref=f1e149] [cursor=pointer]: 瀹℃壒涓績
+            - menuitem "API瀵嗛挜绠$悊" [ref=f1e155] [cursor=pointer]
+            - menuitem "妯″瀷绠$悊" [ref=f1e161] [cursor=pointer]
+            - menuitem "鐭ヨ瘑搴撶鐞�" [ref=f1e166] [cursor=pointer]
+            - menuitem "閫氱煡鍏憡" [ref=f1e172] [cursor=pointer]
+        - listitem [ref=f1e177]:
+          - generic [ref=f1e178] [cursor=pointer]: 浜哄姏璧勬簮
+        - listitem [ref=f1e184]:
+          - generic [ref=f1e185] [cursor=pointer]: 鍞悗绠$悊
+        - listitem [ref=f1e191]:
+          - generic [ref=f1e192] [cursor=pointer]: 鍩虹璁炬柦
+        - listitem [ref=f1e198]:
+          - generic [ref=f1e199] [cursor=pointer]: 绯荤粺绠$悊
+        - listitem [ref=f1e205]:
+          - generic [ref=f1e206] [cursor=pointer]: IM 鍗虫椂閫氳
+      - generic [ref=f1e214] [cursor=pointer]
+  - generic [ref=f1e219]:
+    - generic [ref=f1e220]:
+      - banner [ref=f1e221]:
+        - button [ref=f1e222] [cursor=pointer]
+        - button [ref=f1e225] [cursor=pointer]
+        - navigation "breadcrumb" [ref=f1e230]:
+          - list [ref=f1e231]:
+            - listitem [ref=f1e232]:
+              - link "鍗忓悓鍔炲叕" [ref=f1e233] [cursor=pointer]:
+                - /url: javascript:void 0
+              - listitem [ref=f1e237]
+            - listitem [ref=f1e240]:
+              - link "娴佺▼绠$悊" [ref=f1e241] [cursor=pointer]:
+                - /url: javascript:void 0
+              - listitem [ref=f1e245]
+            - listitem [ref=f1e248]:
+              - link "娴佺▼妯″瀷" [disabled] [ref=f1e249]
+        - generic [ref=f1e254]:
+          - generic [ref=f1e256] [cursor=pointer]:
+            - generic [ref=f1e260]: 鎼滅储
+            - generic [ref=f1e261]: Ctrl K
+          - button [ref=f1e263] [cursor=pointer]
+          - button "dark" [ref=f1e268] [cursor=pointer]
+          - button [ref=f1e277] [cursor=pointer]
+          - button [ref=f1e283] [cursor=pointer]
+          - button [ref=f1e286] [cursor=pointer]
+          - button [ref=f1e292] [cursor=pointer]:
+            - button [ref=f1e294]
+          - button "宸ヤ綔鍙�" [ref=f1e299] [cursor=pointer]
+          - button [ref=f1e303] [cursor=pointer]:
+            - img "瓒呯骇绠$悊鍛�" [ref=f1e308]
+      - generic [ref=f1e310]:
+        - generic [ref=f1e315]:
+          - generic [ref=f1e316] [cursor=pointer]: 棣栭〉
+          - generic [ref=f1e334] [cursor=pointer]: 娴佺▼妯″瀷
+        - generic [ref=f1e351]:
+          - button [ref=f1e352] [cursor=pointer]
+          - generic [ref=f1e359] [cursor=pointer]
+          - generic [ref=f1e363] [cursor=pointer]
+    - main [ref=f1e370]:
+      - generic [ref=f1e376]:
+        - generic [ref=f1e377]: 娴佺▼妯″瀷
+        - generic [ref=f1e379]:
+          - textbox "鎼滅储娴佺▼" [ref=f1e381]
+          - button "鏂板缓妯″瀷" [ref=f1e383] [cursor=pointer]
+          - button [ref=f1e387] [cursor=pointer]
\ No newline at end of file
diff --git a/docs/erp_purchase_invoice_remove_audit.md b/docs/erp_purchase_invoice_remove_audit.md
new file mode 100644
index 0000000..bbc75db
--- /dev/null
+++ b/docs/erp_purchase_invoice_remove_audit.md
@@ -0,0 +1,70 @@
+# ERP 閲囪喘鏉ョエ鍘绘帀瀹℃牳 - 鍓嶇鑱旇皟鏂规
+
+## 鍙樻洿鑳屾櫙
+
+閲囪喘鏉ョエ锛坄erp_purchase_invoice`锛変笉鍐嶉渶瑕佸鏍告祦绋嬶紝鏉ョエ鍒涘缓鍚庣洿鎺ョ敓鏁堛�佸彲鐩存帴鐢ㄤ簬浠樻銆傚悗绔凡鍒犻櫎瀹℃牳鐘舵�佸瓧娈碉紙`auditStatus`锛変笌宸ヤ綔娴佹畫鐣欏瓧娈碉紙`processInstanceId`锛夛紝骞剁Щ闄や簡瀹℃牳鐩稿叧鎺ュ彛锛涗粯娆惧垱寤烘椂涓嶅啀鏍¢獙"鏉ョエ蹇呴』瀹℃牳閫氳繃"銆�
+
+## 娑夊強椤甸潰
+
+- 閲囪喘鏉ョエ绠$悊椤碉紙`views/erp/purchase/invoice/`锛�
+- 浠樻鍗曠鐞嗛〉锛坄views/erp/finance/payment/`锛屼粎琛屼负鍙樺寲锛屾棤闇�鏀逛唬鐮侊級
+
+## 鎺ュ彛鍙樻洿
+
+### 宸插垹闄ゆ帴鍙�
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| PUT | /erp/purchase-invoice/update-status | 瀹℃牳/鍙嶅鏍革紝鍓嶇闇�鍒犻櫎瀵瑰簲鎸夐挳涓� API 鍑芥暟 |
+| GET | /erp/purchase-invoice/audit-count | 寰呭鏍告潵绁ㄦ暟閲忥紝鍓嶇闇�鍒犻櫎瀵瑰簲 API 鍑芥暟 |
+
+### 鍝嶅簲瀛楁鍙樺寲
+
+| 鎺ュ彛 | 鍙樺寲 |
+|------|------|
+| /erp/purchase-invoice/page | 鍝嶅簲绉婚櫎 `auditStatus`銆乣processInstanceId` 瀛楁 |
+| /erp/purchase-invoice/get | 鍝嶅簲绉婚櫎 `auditStatus`銆乣processInstanceId` 瀛楁 |
+| /erp/purchase-invoice/simple-list | 鍝嶅簲绉婚櫎 `auditStatus` 瀛楁锛涗笉鍐嶅彧杩斿洖"瀹℃牳閫氳繃"鏉ョエ锛屾敼涓鸿繑鍥炶渚涘簲鍟�/璁㈠崟涓�"宸蹭笂浼犻檮浠朵笖鍓╀綑鍙粯 > 0"鐨勫叏閮ㄦ潵绁� |
+| /erp/finance-payment/get銆�/page | 宓屽 `invoice` 瀵硅薄涓笉鍐嶅寘鍚� `auditStatus` 瀛楁 |
+
+### 鏍¢獙瑙勫垯鍙樺寲锛堝悗绔紝鍓嶇鏃犳敼鍔級
+
+| 鍦烘櫙 | 鍙樺寲 |
+|------|------|
+| 浠樻鍒涘缓/鏇存柊 | 鍘绘帀"鍏宠仈鏉ョエ蹇呴』瀹℃牳閫氳繃"鏍¢獙锛屽叾浣欐牎楠岋紙鏉ョエ瀛樺湪銆佸凡浼犻檮浠躲�佷緵搴斿晢涓�鑷淬�侀噾棰濅笉瓒呭墿浣欏彲浠橈級淇濈暀 |
+
+## 鍓嶇淇敼鐐�
+
+### 1. API 瀹氫箟锛坄src/api/erp/purchase/invoice/index.ts`锛�
+
+- `PurchaseInvoice` 绫诲瀷锛氬垹闄� `auditStatus`銆乣processInstanceId` 瀛楁
+- `PurchaseInvoiceSimple` 绫诲瀷锛氬垹闄� `auditStatus` 瀛楁
+- 鍒犻櫎鍑芥暟锛歚updatePurchaseInvoiceStatus`銆乣getAuditPurchaseInvoiceCount`
+- 鏇存柊 `getPurchaseInvoiceSimpleList` 娉ㄩ噴璇存槑
+
+### 2. 鏉ョエ鍒楄〃椤碉紙`src/views/erp/purchase/invoice/index.vue`锛�
+
+- 鍒犻櫎"瀹℃牳""鍙嶅鏍�"鎿嶄綔鎸夐挳鍙婂搴斿鐞嗗嚱鏁�
+- 鍒犻櫎"瀹℃壒鐘舵��"鍒楃殑鐘舵�� Tag 妯℃澘
+- 缂栬緫鎸夐挳涓嶅啀鎸夊鏍哥姸鎬佹帶鍒舵樉闅愶紙浠绘剰鐘舵�佸彲缂栬緫锛�
+- 鍒犻櫎鎸夐挳涓嶅啀鎸夊鏍哥姸鎬佹帶鍒舵樉闅愶紙鏄惁鍙垹鐢卞悗绔牎楠�"宸叉湁鏈夋晥浠樻鍗�"鍐冲畾锛�
+
+### 3. 鏉ョエ鍒楄〃閰嶇疆锛坄src/views/erp/purchase/invoice/data.ts`锛�
+
+- 鎼滅储琛ㄥ崟锛氬垹闄�"瀹℃牳鐘舵��"绛涢�夐」
+- 鍒楄〃鍒楋細鍒犻櫎"瀹℃壒鐘舵��"鍒�
+
+## 涓氬姟瑙勫垯璇存槑
+
+| 鍦烘櫙 | 瑙勫垯 |
+|------|------|
+| 鏉ョエ鍒涘缓 | 鍒涘缓鍗崇敓鏁堬紝鏃犲鏍哥幆鑺� |
+| 鏉ョエ缂栬緫 | 浠绘剰鐘舵�佸彲缂栬緫 |
+| 鏉ョエ鍒犻櫎 | 宸叉湁鏈夋晥浠樻鍗曪紙浠樻閲戦 > 0锛夊叧鑱旂殑鏉ョエ涓嶅彲鍒犻櫎锛屽悗绔細杩斿洖閿欒鎻愮ず |
+| 浠樻閫夋嫨鏉ョエ | 涓嬫媺鍙睍绀�"宸蹭笂浼犻檮浠朵笖鍓╀綑鍙粯 > 0"鐨勬潵绁紝涓嶅啀鏈�"寰呭鏍�"鏉ョエ |
+
+## 娉ㄦ剰浜嬮」
+
+- 浠樻妯″潡锛坄views/erp/finance/payment/`锛夋湭寮曠敤 `auditStatus`锛屾棤闇�淇敼锛涘叾"鍏宠仈鏉ョエ"涓嬫媺鍙�夎寖鍥撮殢鍚庣 simple-list 閫昏緫鑷姩鍙樺寲銆�
+- 鍘嗗彶鏉ョエ鏁版嵁锛氭暟鎹簱宸插垹闄� `audit_status`銆乣process_instance_id` 涓ゅ垪锛屽巻鍙叉潵绁ㄥ叏閮ㄨ涓烘湁鏁堬紝鍙洿鎺ョ敤浜庝粯娆俱��
+- 鍓嶇鎺ュ彛鍒犻櫎鍚庯紝璇峰悓姝ユ鏌ユ槸鍚︽湁鍏跺畠椤甸潰锛堝宸ヤ綔鍙�/寰呭姙锛夎皟鐢ㄥ凡鍒犻櫎鐨勬帴鍙o紝褰撳墠鏈彂鐜般��
diff --git a/docs/purchase_invoice_payment_link.md b/docs/purchase_invoice_payment_link.md
index fa6e939..388c433 100644
--- a/docs/purchase_invoice_payment_link.md
+++ b/docs/purchase_invoice_payment_link.md
@@ -2,7 +2,7 @@
 
 ## 娑夊強椤甸潰
 
-- 閲囪喘鏉ョエ绠$悊椤碉紙**鏂板缓椤甸潰**锛屽弬鑰冮噰璐敵璇�/閲囪喘璁㈠崟椤甸潰缁撴瀯锛�
+- 閲囪喘鏉ョエ绠$悊椤碉紙鏉ョエ鍒楄〃銆佹柊澧�/缂栬緫/璇︽儏寮圭獥锛�
 - 閲囪喘璁㈠崟璇︽儏椤碉紙灞曠ず璇ヨ鍗曚笅宸插叧鑱旂殑鏉ョエ淇℃伅锛�
 - 浠樻鍗曠鐞嗛〉锛堟柊寤�/缂栬緫寮圭獥銆佸垪琛ㄣ�佽鎯咃級
 - 浠樻鍗曡鎯呴〉锛堝睍绀哄叧鑱旂殑鏉ョエ淇℃伅锛�
@@ -10,15 +10,14 @@
 ## 涓氬姟娴佺▼涓庢暟鎹甫鍏�
 
 1. 閲囪喘璁㈠崟锛堝鏍搁�氳繃锛�-> 鍒涘缓鏉ョエ锛歚purchaseOrderId` 蹇呴�夛紝渚涘簲鍟嗚嚜鍔ㄥ甫鍑猴紙浠ラ噰璐鍗曠殑渚涘簲鍟嗕负鍑嗭紝鍓嶇鏃犻渶浼� `supplierId`锛岀敱鍚庣鎸夐噰璐鍗曟煡璇㈣缃級銆�
-2. 鏉ョエ鍒涘缓鍚� -> 涓婁紶鍙戠エ闄勪欢锛堣蛋 system 妯″潡 Storage API锛夈��
-3. 鏉ョエ鎻愪氦瀹℃壒 -> 瀹℃壒閫氳繃 -> 鎵嶅彲浣滀负浠樻鍏宠仈瀵硅薄銆�
-4. 鏂板缓浠樻鍗� -> 閫夋嫨鍏宠仈鏉ョエ锛坄invoiceId` 蹇呭~锛夛細浠� `GET /erp/purchase-invoice/simple-list?supplierId=&purchaseOrderId=` 閫夋嫨锛屼粎鏄剧ず"瀹℃壒閫氳繃 + 宸蹭笂浼犻檮浠� + 鍓╀綑鍙粯閲戦 > 0"鐨勬潵绁紱閫夋嫨鍚� `remainingInvoicePrice` 鍙敤浜庨濉粯娆鹃噾棰濅笂闄愩��
+2. 鏉ョエ鍒涘缓鍚� -> 涓婁紶鍙戠エ闄勪欢锛堣蛋 system 妯″潡 Storage API锛夈��**鏉ョエ鍒涘缓鍗崇敓鏁堬紝鏃犲鏍哥幆鑺�**銆�
+3. 鏂板缓浠樻鍗� -> 閫夋嫨鍏宠仈鏉ョエ锛坄invoiceId` 蹇呭~锛夛細浠� `GET /erp/purchase-invoice/simple-list?supplierId=&purchaseOrderId=` 閫夋嫨锛屼粎鏄剧ず"宸蹭笂浼犻檮浠� + 鍓╀綑鍙粯閲戦 > 0"鐨勬潵绁紱閫夋嫨鍚� `remainingInvoicePrice` 鍙敤浜庨濉粯娆鹃噾棰濅笂闄愩��
 
 瀵瑰簲鍏崇郴锛�**閲囪喘璁㈠崟(1) -> 鏉ョエ(N) -> 浠樻(M)**銆�
 
 ## API
 
-### 1. 鏉ョエ绠$悊锛堟柊锛�
+### 1. 鏉ョエ绠$悊
 
 | 鏂规硶 | 璺緞 | 璇存槑 |
 |------|------|------|
@@ -28,9 +27,9 @@
 | GET | /erp/purchase-invoice/get?id= | 鑾峰緱鏉ョエ璇︽儏 |
 | GET | /erp/purchase-invoice/page | 鏉ョエ鍒嗛〉 |
 | GET | /erp/purchase-invoice/export-excel | 瀵煎嚭鏉ョエ Excel |
-| PUT | /erp/purchase-invoice/submit?id= | 鎻愪氦鏉ョエ瀹℃壒 |
-| GET | /erp/purchase-invoice/audit-count | 寰呭鏍告潵绁ㄦ暟閲� |
 | GET | /erp/purchase-invoice/simple-list?supplierId=&purchaseOrderId= | 绮剧畝鍒楄〃锛堜粯娆捐〃鍗曢�夋潵绁級 |
+
+> 宸茬Щ闄ゆ帴鍙o細`/erp/purchase-invoice/update-status`锛堝鏍�/鍙嶅鏍革級銆乣/erp/purchase-invoice/audit-count`锛堝緟瀹℃牳鏁伴噺锛夈�傚墠绔鍚屾鍒犻櫎瀵瑰簲鎸夐挳涓庢帴鍙h皟鐢ㄣ��
 
 **鍒涘缓/鏇存柊鏉ョエ璇锋眰鍙傛暟锛�**
 
@@ -46,17 +45,18 @@
 | remark | String | 鍚� | 澶囨敞 |
 | blobIds | List\<Long\> | 鍚� | 鍙戠エ闄勪欢 blobId 鍒楄〃 |
 
-**鏉ョエ鍒嗛〉/璇︽儏鍝嶅簲鏂板瀛楁锛�**
+**鏉ョエ鍒嗛〉/璇︽儏鍝嶅簲瀛楁锛�**
 
 | 瀛楁 | 绫诲瀷 | 璇存槑 |
 |------|------|------|
 | no | String | 鏉ョエ缂栧彿锛堝悗绔敓鎴愶紝鍓嶇紑 FPD锛� |
 | supplierName | String | 渚涘簲鍟嗗悕绉� |
 | order | Object | 閲囪喘璁㈠崟淇℃伅锛堝祵濂楋級 |
-| auditStatus | Integer | 瀹℃壒鐘舵�侊紙0鏈彁浜�/10瀹℃壒涓�/20瀹℃牳閫氳繃/30瀹℃牳涓嶉�氳繃/40宸插彇娑堬級 |
 | attachmentList | List | 鍙戠エ闄勪欢鍒楄〃 |
 | hasAttachment | Boolean | 鏄惁宸蹭笂浼犲彂绁ㄩ檮浠� |
 | remainingInvoicePrice | BigDecimal | 鍓╀綑鍙粯閲戦 = 鏉ョエ閲戦 - 璇ユ潵绁ㄥ凡浠樻閲戦 |
+
+> 宸茬Щ闄ゅ搷搴斿瓧娈碉細`auditStatus`锛堝鎵圭姸鎬侊級銆乣processInstanceId`锛堝伐浣滄祦缂栧彿锛夈��
 
 **simple-list 鍝嶅簲锛�**
 
@@ -69,18 +69,17 @@
 | price | BigDecimal | 鏉ョエ閲戦 |
 | supplierId | Long | 渚涘簲鍟嗙紪鍙� |
 | purchaseOrderId | Long | 閲囪喘璁㈠崟缂栧彿 |
-| auditStatus | Integer | 瀹℃壒鐘舵�� |
 | hasAttachment | Boolean | 鏄惁宸蹭笂浼犻檮浠讹紙鎭掍负 true锛� |
 | remainingInvoicePrice | BigDecimal | 鍓╀綑鍙粯閲戦 |
 
-### 2. 浠樻鍗曪紙鎺ュ彛鍙樻洿锛�
+### 2. 浠樻鍗�
 
 | 鏂规硶 | 璺緞 | 璇存槑 |
 |------|------|------|
-| POST | /erp/finance-payment/create | 鍒涘缓浠樻鍗曪紝璇锋眰浣撴柊澧� `invoiceId`锛堝繀濉級 |
-| PUT | /erp/finance-payment/update | 鏇存柊浠樻鍗曪紝璇锋眰浣撴柊澧� `invoiceId`锛堝繀濉級 |
-| GET | /erp/finance-payment/get | 鍝嶅簲鏂板 `invoiceId`銆乣invoice` 宓屽瀵硅薄 |
-| GET | /erp/finance-payment/page | 鍝嶅簲鏂板 `invoiceId`銆乣invoice` 宓屽瀵硅薄 |
+| POST | /erp/finance-payment/create | 鍒涘缓浠樻鍗曪紝璇锋眰浣撳惈 `invoiceId`锛堝繀濉級 |
+| PUT | /erp/finance-payment/update | 鏇存柊浠樻鍗曪紝璇锋眰浣撳惈 `invoiceId`锛堝繀濉級 |
+| GET | /erp/finance-payment/get | 鍝嶅簲鍚� `invoiceId`銆乣invoice` 宓屽瀵硅薄 |
+| GET | /erp/finance-payment/page | 鍝嶅簲鍚� `invoiceId`銆乣invoice` 宓屽瀵硅薄 |
 
 **璇锋眰鍙傛暟鏂板锛�**
 
@@ -93,7 +92,7 @@
 | 瀛楁 | 绫诲瀷 | 璇存槑 |
 |------|------|------|
 | invoiceId | Long | 鍏宠仈鐨勬潵绁ㄧ紪鍙� |
-| invoice | Object | 鍏宠仈鐨勬潵绁ㄤ俊鎭紙鍚� no銆乮nvoiceNo銆乮nvoiceTitle銆乸rice銆乤uditStatus 绛夛級 |
+| invoice | Object | 鍏宠仈鐨勬潵绁ㄤ俊鎭紙鍚� no銆乮nvoiceNo銆乮nvoiceTitle銆乸rice 绛夛級 |
 
 **鍝嶅簲绀轰緥锛�**
 
@@ -109,8 +108,7 @@
       "no": "FPD20260810000001",
       "invoiceNo": "02564178",
       "invoiceTitle": "XX绉戞妧鏈夐檺鍏徃",
-      "price": 9000.00,
-      "auditStatus": 20
+      "price": 9000.00
     },
     "paymentPrice": 5000.00
   }
@@ -127,20 +125,20 @@
 | 鍙戠エ鍙风爜/鎶ご | 鏉ョエ鍒楄〃銆佽鎯� | 褰曞叆瀛楁 |
 | 鏉ョエ閲戦 | 鏉ョエ鍒楄〃銆佽鎯呫�佷粯娆捐〃鍗� | 鍏� |
 | 鏉ョエ鏃ユ湡 | 鏉ョエ鍒楄〃銆佽鎯� | |
-| 瀹℃壒鐘舵�� | 鏉ョエ鍒楄〃銆佽鎯� | 瀛楀吀灞曠ず |
-| 鍙戠エ闄勪欢 | 鏉ョエ璇︽儏銆佹潵绁ㄥ垪琛� | 涓婁紶/棰勮/涓嬭浇 |
+| 鍙戠エ闄勪欢 | 鏉ョエ璇︽儏銆佹潵绁ㄥ垪琛� | 涓婁紶/棰勮/涓嬭浇锛屾湁闄勪欢鏄剧ず"宸蹭笂浼�"Tag |
 | 鍓╀綑鍙粯閲戦 | 鏉ョエ鍒楄〃銆佷粯娆捐〃鍗� | 鏉ョエ閲戦 - 宸蹭粯娆鹃噾棰� |
 | 鍏宠仈鏉ョエ | 浠樻鍒楄〃銆佷粯娆捐鎯� | 灞曠ず invoice.no / invoice.invoiceNo / invoice.price |
+
+> 宸茬Щ闄ゅ睍绀哄瓧娈碉細鏉ョエ鍒楄〃鐨�"瀹℃壒鐘舵��"鍒椼�佹悳绱㈡潯浠�"瀹℃牳鐘舵��"銆�"瀹℃牳/鍙嶅鏍�"鎿嶄綔鎸夐挳銆�
 
 ## 涓氬姟瑙勫垯璇存槑
 
 | 鍦烘櫙 | 瑙勫垯 |
 |------|------|
-| 鏉ョエ鍒涘缓 | 閲囪喘璁㈠崟蹇呴』瀹℃牳閫氳繃锛涙潵绁ㄤ緵搴斿晢涓庨噰璐鍗曚竴鑷达紱鏉ョエ閲戦涓嶈秴杩囪鍗曞墿浣欏彲寮�绁ㄩ噾棰� |
-| 鏉ョエ缂栬緫 | 浠�"鏈彁浜�"鐘舵�佸彲缂栬緫 |
-| 鏉ョエ鍒犻櫎 | 瀹℃壒閫氳繃鍚庝笉鍙垹闄� |
-| 鏉ョエ鎻愪氦瀹℃壒 | 浠�"鏈彁浜�"鐘舵�佸彲鎻愪氦锛屾彁浜ゅ悗杩涘叆瀹℃壒涓� |
-| 浠樻閫夋嫨鏉ョエ | 浠呭鎵归�氳繃 + 宸蹭笂浼犲彂绁ㄩ檮浠剁殑鏉ョエ鍙�� |
+| 鏉ョエ鍒涘缓 | 閲囪喘璁㈠崟蹇呴』瀹℃牳閫氳繃锛涙潵绁ㄤ緵搴斿晢涓庨噰璐鍗曚竴鑷达紱鏉ョエ閲戦涓嶈秴杩囪鍗曞墿浣欏彲寮�绁ㄩ噾棰濓紱**鍒涘缓鍗崇敓鏁堬紝鏃犻渶瀹℃牳** |
+| 鏉ョエ缂栬緫 | 浠绘剰鐘舵�佸彲缂栬緫锛屾棤瀹℃牳鐘舵�侀檺鍒� |
+| 鏉ョエ鍒犻櫎 | 宸叉湁鏈夋晥浠樻鍗曪紙鏈綔搴熶笖浠樻閲戦 > 0锛夊叧鑱旂殑鏉ョエ涓嶅彲鍒犻櫎锛屽叾浣欏彲鍒犻櫎 |
+| 浠樻閫夋嫨鏉ョエ | 宸蹭笂浼犲彂绁ㄩ檮浠朵笖鍓╀綑鍙粯閲戦 > 0 鐨勬潵绁ㄥ彲閫夛紙**涓嶅啀瑕佹眰瀹℃牳閫氳繃**锛� |
 | 浠樻閲戦涓婇檺 | 浠樻閲戦 <= 璇ユ潵绁ㄩ噾棰� - 璇ユ潵绁ㄥ凡浠樻閲戦锛堟湭瀹℃牳+瀹℃壒涓�+宸插鏍镐粯娆撅紝鎺掗櫎浣滃簾锛� |
 | 渚涘簲鍟嗕竴鑷存�� | 浠樻鐨勪緵搴斿晢蹇呴』涓庡叧鑱旀潵绁ㄧ殑渚涘簲鍟嗕竴鑷� |
 | 瀛橀噺浠樻鍗� | invoiceId 涓虹┖鐨勫瓨閲忎粯娆惧崟锛岀紪杈戞椂闇�閲嶆柊閫夋嫨鍚堟牸鏉ョエ |
@@ -151,5 +149,4 @@
 - 浠樻琛ㄥ崟閫夋嫨鏉ョエ鏃讹紝鍏堟寜渚涘簲鍟嗚繃婊わ紙`supplierId`锛夛紝鍙�夎鍗曟椂浼� `purchaseOrderId` 杩涗竴姝ヨ繃婊ゃ��
 - `remainingInvoicePrice` 涓鸿礋鏁版垨 0 鐨勬潵绁ㄤ笉浼氬嚭鐜板湪 simple-list 涓紝鍓嶇鍙洿鎺ユ寜杩斿洖鍒楄〃娓叉煋銆�
 - 浠樻閲戦鏍¢獙鍦ㄥ悗绔紝鍓嶇鍙皢鏉ョエ鐨� `remainingInvoicePrice` 浣滀负浠樻閲戦杈撳叆涓婇檺鎻愮ず銆�
-- 鏉ョエ瀹℃壒鐘舵�佸彉鍖栭�氳繃 BPM 鍥炶皟鏇存柊锛屽墠绔棤闇�澶勭悊锛屽垎椤垫帴鍙g洿鎺ヨ繑鍥炴渶鏂扮姸鎬併��
 - 鏉ョエ鍙戠エ闄勪欢涓婁紶浣跨敤 system 妯″潡 Storage API锛坲pload -> bind锛夛紝涓嶈浣跨敤鏃х増 /infra/file 鎺ュ彛銆�
diff --git a/docs/sql/erp_purchase_invoice_remove_audit.sql b/docs/sql/erp_purchase_invoice_remove_audit.sql
new file mode 100644
index 0000000..4fe4dcd
--- /dev/null
+++ b/docs/sql/erp_purchase_invoice_remove_audit.sql
@@ -0,0 +1,9 @@
+-- ERP 閲囪喘鏉ョエ鍘绘帀瀹℃牳锛氬垹闄ゅ鏍哥姸鎬佸瓧娈典笌宸ヤ綔娴佹畫鐣欏瓧娈�
+-- 鑳屾櫙锛氭潵绁ㄥ垱寤哄嵆鐢熸晥锛屾棤闇�瀹℃牳锛屼粯娆句笉鍐嶆牎楠�"鏉ョエ瀹℃牳閫氳繃"
+-- 鎵ц鏃舵満锛氭柊鍚庣閮ㄧ讲鍚庣殑鍋滄湇绐楀彛鎵ц锛堟棫浠g爜璇诲啓杩欎袱鍒楋紝鍏堝垹鍒椾細瀵艰嚧杩愯鏃舵姤閿欙級
+
+ALTER TABLE erp_purchase_invoice DROP COLUMN audit_status;
+ALTER TABLE erp_purchase_invoice DROP COLUMN process_instance_id;
+
+-- 娓呯悊瀛ゅ効鑿滃崟鏉冮檺锛堝搴斿凡鍒犻櫎鐨� /update-status 瀹℃牳鎺ュ彛锛�
+DELETE FROM system_menu WHERE permission = 'erp:purchase-invoice:update-status';
diff --git a/docs/srm_certificate_attachment_integration.md b/docs/srm_certificate_attachment_integration.md
new file mode 100644
index 0000000..3791d42
--- /dev/null
+++ b/docs/srm_certificate_attachment_integration.md
@@ -0,0 +1,113 @@
+# SRM 璧勮川闄勪欢涓婁紶 - 鍓嶇鑱旇皟鏂规
+
+## 娑夊強椤甸潰
+
+- 閲囪喘绠$悊-SRM-渚涘簲鍟嗙鐞�-璧勮川璇佷功鍒楄〃椤�
+- 閲囪喘绠$悊-SRM-渚涘簲鍟嗙鐞�-璧勮川璇佷功鏂板/缂栬緫寮圭獥
+- 閲囪喘绠$悊-SRM-鎷涙爣椤圭洰-鏂板/缂栬緫寮圭獥锛堝惈鍙戝竷涓�/鎶曟爣涓殑閮ㄥ垎鏇存柊锛�
+- 閲囪喘绠$悊-SRM-鎷涙爣椤圭洰-璇︽儏椤�
+
+## 涓氬姟娴佺▼涓庢暟鎹甫鍏�
+
+1. 鐢ㄦ埛鍦ㄨ〃鍗曚腑閫氳繃涓婁紶缁勪欢閫夋嫨鏂囦欢
+2. 涓婁紶缁勪欢璋冪敤 `/system/storage-blob/upload` 鑾峰緱 `blobId`
+3. 淇濆瓨涓氬姟璁板綍锛堣祫璐ㄨ瘉涔� / 鎷涙爣椤圭洰锛夋椂锛屽皢鏂囦欢 ID 鍒楄〃 `blobIds` 闅忎笟鍔℃暟鎹竴骞舵彁浜�
+4. 鍚庣鍦ㄤ笟鍔¤褰曚繚瀛樺悗锛岄�氳繃 `recordType + recordId` 灏嗘枃浠剁粦瀹氬埌 `system_storage_attachment` 涓棿琛�
+5. 鏌ヨ涓氬姟璁板綍锛堣鎯呫�佸垎椤碉級鏃讹紝鍚庣杩斿洖 `attachmentList`锛堝惈鏂囦欢 URL銆佸悕绉帮級锛屽墠绔睍绀轰笅杞介摼鎺�
+
+## API
+
+### 1. 璧勮川璇佷功闄勪欢
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| POST | /system/storage-blob/upload | 涓婁紶鏂囦欢锛屽叆鍙� multipart 鐨� `files`锛岃繑鍥� Blob 鍒楄〃锛堝惈 `id`锛� |
+| POST | /srm/supplier-certificate/create | 鍒涘缓璧勮川璇佷功锛屾柊澧炲叆鍙� `blobIds` |
+| PUT | /srm/supplier-certificate/update | 鏇存柊璧勮川璇佷功锛屾柊澧炲叆鍙� `blobIds`锛堝閲忔洿鏂伴檮浠讹級 |
+| DELETE | /srm/supplier-certificate/delete | 鍒犻櫎璧勮川璇佷功锛屽悓姝ュ垹闄ら檮浠� |
+| GET | /srm/supplier-certificate/page | 鍒嗛〉鏌ヨ锛屽搷搴旀柊澧� `attachmentList` |
+| GET | /srm/supplier-certificate/get | 璇︽儏鏌ヨ锛屽搷搴旀柊澧� `attachmentList` |
+| GET | /srm/supplier-certificate/list-by-supplier | 鎸変緵搴斿晢鏌ヨ锛屽搷搴旀柊澧� `attachmentList` |
+
+**璇锋眰鍙傛暟锛坈reate/update 鏂板瀛楁锛夛細**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| blobIds | Array\<Long\> | 鍚� | 璧勮川璇佷功闄勪欢鏂囦欢 ID 鍒楄〃 |
+
+**鍝嶅簲瀛楁鏂板锛坅ttachmentList 鏁扮粍鍏冪礌锛夛細**
+
+| 瀛楁 | 绫诲瀷 | 璇存槑 |
+|------|------|------|
+| id | Long | 鏂囦欢 ID |
+| name | String | 鍘熸枃浠跺悕 |
+| url | String | 鏂囦欢璁块棶鍦板潃 |
+| previewURL | String | 棰勮鍦板潃 |
+| downloadURL | String | 涓嬭浇鍦板潃 |
+
+**鍝嶅簲绀轰緥锛�**
+
+```json
+{
+  "code": 0,
+  "data": {
+    "id": 1,
+    "supplierId": 10,
+    "certificateName": "ISO9001璐ㄩ噺绠$悊浣撶郴",
+    "attachmentList": [
+      {
+        "id": 1001,
+        "name": "iso9001_cert.pdf",
+        "url": "https://example.com/files/xxx.pdf"
+      }
+    ]
+  }
+}
+```
+
+### 2. 鎷涙爣椤圭洰璧勮川瑕佹眰闄勪欢
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| POST | /system/storage-blob/upload | 涓婁紶鏂囦欢锛屽叆鍙� multipart 鐨� `files`锛岃繑鍥� Blob 鍒楄〃锛堝惈 `id`锛� |
+| POST | /srm/tender-project/create | 鍒涘缓鎷涙爣椤圭洰锛屾柊澧炲叆鍙� `blobIds` |
+| PUT | /srm/tender-project/update | 鏇存柊鎷涙爣椤圭洰锛屾柊澧炲叆鍙� `blobIds`锛堣崏绋�/鍙戝竷涓�/鎶曟爣涓潎澧為噺鏇存柊闄勪欢锛� |
+| PUT | /srm/tender-project/update-info | 閮ㄥ垎鏇存柊锛堝彂甯冧腑/鎶曟爣涓級锛屾柊澧炲叆鍙� `blobIds` |
+| DELETE | /srm/tender-project/delete | 鍒犻櫎鎷涙爣椤圭洰锛屽悓姝ュ垹闄ら檮浠� |
+| GET | /srm/tender-project/get | 璇︽儏鏌ヨ锛屽搷搴旀柊澧� `attachmentList` |
+| GET | /srm/tender-project/page | 鍒嗛〉鏌ヨ锛屽搷搴旀柊澧� `attachmentList` |
+
+**璇锋眰鍙傛暟锛坈reate/update/update-info 鏂板瀛楁锛夛細**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| blobIds | Array\<Long\> | 鍚� | 璧勮川瑕佹眰闄勪欢鏂囦欢 ID 鍒楄〃 |
+
+**鍝嶅簲瀛楁鏂板锛�** 鍚岃祫璐ㄨ瘉涔︼紝`attachmentList` 鏁扮粍鍏冪礌鍚� `id`銆乣name`銆乣url`銆乣previewURL`銆乣downloadURL`銆�
+
+## 瀛楁灞曠ず瑙勫垯
+
+| 瀛楁 | 灞曠ず浣嶇疆 | 璇存槑 |
+|------|----------|------|
+| 璇佷功闄勪欢 | 璧勮川璇佷功鍒楄〃 | 鏂板銆岄檮浠躲�嶅垪锛屾樉绀洪檮浠跺悕绉伴摼鎺ワ紝鐐瑰嚮鏂扮獥鍙f墦寮�锛涙棤闄勪欢鏄剧ず `--` |
+| 璇佷功闄勪欢 | 璧勮川璇佷功鏂板/缂栬緫寮圭獥 | 銆岃瘉涔﹂檮浠躲�嶄笂浼犻」锛屾敮鎸佸鏂囦欢锛岀紪杈戞椂鍥炴樉宸蹭笂浼犳枃浠� |
+| 璧勮川瑕佹眰闄勪欢 | 鎷涙爣椤圭洰鏂板/缂栬緫寮圭獥 | 銆岃祫璐ㄨ姹傞檮浠躲�嶄笂浼犻」锛屾敮鎸佸鏂囦欢锛岀紪杈戞椂鍥炴樉宸蹭笂浼犳枃浠� |
+| 璧勮川瑕佹眰闄勪欢 | 鎷涙爣椤圭洰璇︽儏椤� | 銆岃祫璐ㄨ姹傘�嶆姌鍙犻潰鏉垮唴灞曠ず闄勪欢鍚嶇О閾炬帴锛岀偣鍑绘柊绐楀彛鎵撳紑 |
+
+## 涓氬姟瑙勫垯璇存槑
+
+| 鍦烘櫙 | 瑙勫垯 |
+|------|------|
+| 缂栬緫鍥炴樉 | 缂栬緫鏃跺悗绔繑鍥� `attachmentList`锛屽墠绔皢鍏舵槧灏勪负涓婁紶缁勪欢鏂囦欢瀵硅薄锛坄uid`銆乣name`銆乣url`銆乣status='done'`銆乣id`锛夊苟璧嬬粰 `blobIds`锛屾彁浜ゆ椂鎸� `valueKey='id'` 鎻愬彇鏂囦欢 ID 鎻愪氦 |
+| 闄勪欢鏇存柊 | 鍚庣鎸夈�屽閲忔洿鏂般�嶅鐞嗭細浠ユ湰娆℃彁浜ょ殑 `blobIds` 涓哄噯锛岃嚜鍔ㄥ垹闄ゅ凡绉婚櫎鐨勬枃浠剁粦瀹氥�佹柊澧炴柊涓婁紶鐨勬枃浠剁粦瀹� |
+| 鍒犻櫎涓氬姟璁板綍 | 鍒犻櫎璧勮川璇佷功/鎷涙爣椤圭洰鏃讹紝鍚庣鍚屾鍒犻櫎鍏堕檮浠� |
+| 鍙戝竷涓�/鎶曟爣涓紪杈� | 鎷涙爣椤圭洰鍦ㄥ彂甯冧腑/鎶曟爣涓樁娈甸�氳繃 `update-info` 鎺ュ彛浠呰兘淇敼鎷涙爣璇存槑銆佽祫璐ㄨ姹傚強璧勮川瑕佹眰闄勪欢 |
+| 涓婁紶鏍煎紡 | 鏀寔 jpg銆乯peg銆乸ng銆乸df銆乨oc銆乨ocx锛屽崟涓枃浠朵笉瓒呰繃 2MB |
+
+## 娉ㄦ剰浜嬮」
+
+- 涓婁紶蹇呴』璧� `/system/storage-blob/upload`锛岀姝娇鐢ㄦ棫鐗� `/infra/file/*` 鎺ュ彛銆�
+- 璧勮川璇佷功涓庢嫑鏍囬」鐩娇鐢ㄤ笉鍚岀殑 `recordType`锛氳祫璐ㄨ瘉涔︿负 `srm_supplier_certificate`锛屾嫑鏍囬」鐩负 `srm_tender_project`锛屽墠绔棤闇�鍏冲績锛岀敱鍚庣澶勭悊銆�
+- 缂栬緫鍥炴樉鏃惰嫢鐢ㄦ埛鏈敼鍔ㄩ檮浠讹紝鎻愪氦鐨� `blobIds` 浠嶅簲鍖呭惈鍘熸湁鏂囦欢 ID锛堢敱涓婁紶缁勪欢鍥炴樉瀵硅薄鎼哄甫锛夛紝閬垮厤闄勪欢琚鍒犮��
+- 鎷涙爣椤圭洰閮ㄥ垎鏇存柊锛坄update-info`锛夎姹備綋鍚屾牱闇�鎼哄甫 `blobIds`銆�
+- 鍒楄〃椤甸檮浠堕摼鎺ュ缓璁� `target="_blank"` 鏂扮獥鍙f墦寮�锛屼究浜庨瑙� PDF/鍥剧墖銆�
diff --git a/docs/srm_supplier_tender_integration.md b/docs/srm_supplier_tender_integration.md
new file mode 100644
index 0000000..c8d9129
--- /dev/null
+++ b/docs/srm_supplier_tender_integration.md
@@ -0,0 +1,78 @@
+# SRM 渚涘簲鍟嗘姇鏍囬�変汉 & 涓爣鑷姩鍑嗗叆 - 鍓嶇鑱旇皟鏂规
+
+## 娑夊強椤甸潰
+
+- 鎷涙爣椤圭洰璇︽儏椤碉紙鎶曟爣绠$悊 Tab銆佽瘎鏍� Tab 鐨勪緵搴斿晢閫夋嫨锛�
+- SRM 渚涘簲鍟嗙鐞嗛〉闈紙浠呮柊澧� `getSupplierList` API锛岄〉闈㈡湰韬棤鏀瑰姩锛�
+
+## 鑳屾櫙涓庨渶姹�
+
+1. 鎷涙爣椤圭洰璇︽儏椤典腑銆屾柊澧炴姇鏍囥�嶃�岃瘎鏍囥�嶆椂閫夋嫨渚涘簲鍟嗭紝**涓嶅啀杩囨护鍑嗗叆鐘舵��**锛岀洿鎺ユ煡璇緵搴斿晢妗f鍒楄〃銆�
+2. 涓爣骞剁敓鎴愰噰璐鍗曟椂锛屽鏋滀緵搴斿晢灏氭湭鍑嗗叆锛屽悗绔細鑷姩鍒涘缓鍑嗗叆鐢宠骞剁疆涓哄凡閫氳繃锛屽墠绔棤闇�棰濆澶勭悊銆�
+
+## API
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| GET | /srm/supplier/list | 鑾峰彇渚涘簲鍟嗘。妗堝垪琛紙涓嶈繃婊ゅ噯鍏ョ姸鎬侊級 |
+
+**璇锋眰鍙傛暟锛�** 鏃�
+
+**鍝嶅簲锛�**
+
+| 瀛楁 | 绫诲瀷 | 璇存槑 |
+|------|------|------|
+| id | number | 渚涘簲鍟� ID |
+| name | string | 渚涘簲鍟嗗悕绉� |
+| code | string | 渚涘簲鍟嗙紪鐮� |
+| status | number | 鐘舵�侊紙0 鍚敤锛�1 绂佺敤锛� |
+
+**鍝嶅簲绀轰緥锛�**
+
+```json
+{
+  "code": 0,
+  "data": [
+    { "id": 1, "code": "SUP001", "name": "鏌愭煇鍏徃", "status": 0 }
+  ]
+}
+```
+
+## 鍓嶇淇敼鐐�
+
+### 1. 鏂板 API 鍑芥暟
+
+鍦� `src/api/srm/supplier/index.ts` 涓柊澧� `getSupplierList()`锛岃姹� `/srm/supplier/list`銆�
+
+> 鍘熸湁鐨� `getSupplierSimpleList()`锛堣姹� `/srm/supplier/simple-list`锛屼粎杩斿洖宸插噯鍏ヤ緵搴斿晢锛�**淇濈暀涓嶅姩**锛屽叾瀹冮〉闈紙閲囪喘璁㈠崟銆侀噰璐叆搴撱�両QC 绛夛級浠嶄娇鐢ㄥ畠銆�
+
+### 2. 鎷涙爣椤圭洰璇︽儏椤垫敼鐢ㄦ。妗堝垪琛�
+
+`src/views/srm/tender/detail.vue` 涓細
+
+- 灏� `getSupplierSimpleList` 鐨� import 鏇挎崲涓� `getSupplierList`
+- 灏� `onMounted` 涓姞杞戒緵搴斿晢鏁版嵁鐨勮皟鐢ㄦ敼涓� `getSupplierList`
+
+璇ラ〉闈㈢殑銆屾姇鏍囩鐞嗐�嶄緵搴斿晢閫夋嫨涓嬫媺銆併�岃瘎鏍囥�嶄緵搴斿晢閫夋嫨涓嬫媺锛屽潎浣跨敤鍚屼竴涓� `supplierList`锛屾浛鎹㈠悗涓や釜涓嬫媺閮戒細灞曠ず鍏ㄩ儴渚涘簲鍟嗘。妗堬紙涓嶈繃婊ゅ噯鍏ワ級銆�
+
+## 瀛楁灞曠ず瑙勫垯
+
+| 瀛楁 | 灞曠ず浣嶇疆 | 璇存槑 |
+|------|----------|------|
+| id | 涓嬫媺 value | 渚涘簲鍟� ID锛屾彁浜ょ粰鍚庣 |
+| name | 涓嬫媺 label | 渚涘簲鍟嗗悕绉� |
+
+## 涓氬姟瑙勫垯璇存槑
+
+| 鍦烘櫙 | 瑙勫垯 |
+|------|------|
+| 鎶曟爣鏃堕�夋嫨渚涘簲鍟� | 灞曠ず鍏ㄩ儴渚涘簲鍟嗘。妗堬紝涓嶅啀杩囨护鍑嗗叆鐘舵�� |
+| 璇勬爣鏃堕�夋嫨渚涘簲鍟� | 鍚屾姇鏍囷紝灞曠ず鍏ㄩ儴渚涘簲鍟嗘。妗� |
+| 涓爣鐢熸垚閲囪喘璁㈠崟 | 鑻ヤ緵搴斿晢鏈噯鍏ワ紝鍚庣鑷姩鍒涘缓鍑嗗叆鐢宠骞剁洿鎺ョ疆涓哄凡閫氳繃锛屽啀鐢熸垚閲囪喘璁㈠崟锛涘墠绔棤闇�璋冪敤鍑嗗叆鐩稿叧鎺ュ彛 |
+| 鏈噯鍏ヤ緵搴斿晢鑳藉惁鎶曟爣 | 鍙互锛屾姇鏍囦笉鍙楀噯鍏ョ姸鎬侀檺鍒� |
+
+## 娉ㄦ剰浜嬮」
+
+- `getSupplierList` 杩斿洖鐨勬暟缁勫厓绱犲惈 `id`銆乣name`锛屽彲鐩存帴鐢ㄤ簬涓嬫媺閫夐」锛坄{ id, name }`锛夈��
+- 渚涘簲鍟嗚绂佺敤锛坰tatus = 1锛夋椂鏄惁鍏佽鎶曟爣锛氭湰鎺ュ彛涓嶈繃婊ゅ噯鍏ョ姸鎬侊紝`status` 瀛楁鐢卞墠绔喅瀹氭槸鍚﹁繃婊ゅ睍绀猴紱鐩墠鎷涙爣璇︽儏椤典笅鎷変笉杩囨护銆�
+- 涓爣鑷姩鍑嗗叆鏄悗绔涓猴紝鍓嶇銆岀‘璁や腑鏍囥�嶃�岀敓鎴愰噰璐鍗曘�嶆寜閽殑璋冪敤鏂瑰紡涓嶅彉銆�
diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmModelConvert.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmModelConvert.java
index 2101b22..5ef8a14 100644
--- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmModelConvert.java
+++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/convert/definition/BpmModelConvert.java
@@ -58,8 +58,9 @@
             List<DeptRespDTO> startDepts = metaInfo != null ? convertList(metaInfo.getStartDeptIds(), deptMap::get) : null;
             return buildModel0(model, metaInfo, form, category, deployment, processDefinition, startUsers, startDepts);
         });
-        // 鎺掑簭
-        result.sort(Comparator.comparing(BpmModelMetaInfoVO::getSort));
+        // 鎺掑簭锛氭墜宸ラ儴缃诧紙DB 鐩存彃锛夌殑妯″瀷鍙兘娌℃湁 metaInfo/sort锛屽厹搴曟帓鍒版渶鍚�
+        result.sort(Comparator.comparing(BpmModelMetaInfoVO::getSort,
+                Comparator.nullsLast(Comparator.naturalOrder())));
         return result;
     }
 
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseInvoiceController.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseInvoiceController.java
index 8d00f34..28c882a 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseInvoiceController.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseInvoiceController.java
@@ -15,7 +15,6 @@
 import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order.ErpPurchaseOrderRespVO;
 import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInvoiceDO;
 import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderDO;
-import cn.iocoder.yudao.module.erp.enums.ErpPurchaseInvoiceAuditStatusEnum;
 import cn.iocoder.yudao.module.erp.service.finance.ErpFinancePaymentService;
 import cn.iocoder.yudao.module.erp.service.purchase.ErpPurchaseInvoiceService;
 import cn.iocoder.yudao.module.erp.service.purchase.ErpPurchaseInvoiceServiceImpl;
@@ -169,24 +168,8 @@
         });
     }
 
-    @PutMapping("/update-status")
-    @Operation(summary = "鏇存柊鏉ョエ鐨勭姸鎬侊紙瀹℃牳/鍙嶅鏍革級")
-    @PreAuthorize("@ss.hasPermission('erp:purchase-invoice:update-status')")
-    public CommonResult<Boolean> updatePurchaseInvoiceStatus(@RequestParam("id") Long id,
-                                                             @RequestParam("status") Integer status) {
-        invoiceService.updatePurchaseInvoiceStatus(id, status);
-        return success(true);
-    }
-
-    @GetMapping("/audit-count")
-    @Operation(summary = "鑾峰緱寰呭鏍告潵绁ㄦ暟閲�")
-    @PreAuthorize("@ss.hasPermission('erp:purchase-invoice:query')")
-    public CommonResult<Long> getAuditInvoiceCount() {
-        return success(invoiceService.getAuditInvoiceCount());
-    }
-
     @GetMapping("/simple-list")
-    @Operation(summary = "鑾峰緱鏉ョエ绮剧畝鍒楄〃", description = "鍙寘鍚鏍搁�氳繃涓斿凡涓婁紶鍙戠エ闄勪欢鐨勬潵绁紝涓昏鐢ㄤ簬浠樻鍒涘缓鏃堕�夋嫨鍏宠仈鏉ョエ")
+    @Operation(summary = "鑾峰緱鏉ョエ绮剧畝鍒楄〃", description = "鍙寘鍚凡涓婁紶鍙戠エ闄勪欢鐨勬潵绁紝涓昏鐢ㄤ簬浠樻鍒涘缓鏃堕�夋嫨鍏宠仈鏉ョエ")
     @Parameter(name = "supplierId", description = "渚涘簲鍟嗙紪鍙�", required = true)
     @Parameter(name = "purchaseOrderId", description = "閲囪喘璁㈠崟缂栧彿锛堝彲閫夛紝鐢ㄤ簬鎸夎鍗曡繃婊わ級")
     @PreAuthorize("@ss.hasPermission('erp:purchase-invoice:query')")
@@ -195,11 +178,9 @@
             @RequestParam(value = "purchaseOrderId", required = false) Long purchaseOrderId) {
         List<ErpPurchaseInvoiceDO> invoices;
         if (purchaseOrderId != null) {
-            invoices = invoiceService.getPurchaseInvoiceListByOrderIdAndStatus(purchaseOrderId,
-                    List.of(ErpPurchaseInvoiceAuditStatusEnum.APPROVE.getStatus()));
+            invoices = invoiceService.getPurchaseInvoiceListByOrderId(purchaseOrderId);
         } else {
-            invoices = invoiceService.getPurchaseInvoiceListBySupplierIdAndStatus(supplierId,
-                    List.of(ErpPurchaseInvoiceAuditStatusEnum.APPROVE.getStatus()));
+            invoices = invoiceService.getPurchaseInvoiceListBySupplierId(supplierId);
         }
         if (CollUtil.isEmpty(invoices)) {
             return success(Collections.emptyList());
@@ -225,7 +206,7 @@
                     .setId(invoice.getId()).setNo(invoice.getNo()).setInvoiceNo(invoice.getInvoiceNo())
                     .setInvoiceTitle(invoice.getInvoiceTitle()).setPrice(invoice.getPrice())
                     .setSupplierId(invoice.getSupplierId()).setPurchaseOrderId(invoice.getPurchaseOrderId())
-                    .setAuditStatus(invoice.getAuditStatus()).setHasAttachment(true)
+                    .setHasAttachment(true)
                     .setRemainingInvoicePrice(remainingPrice));
         }
         return success(result);
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/invoice/ErpPurchaseInvoicePageReqVO.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/invoice/ErpPurchaseInvoicePageReqVO.java
index e92270c..172c373 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/invoice/ErpPurchaseInvoicePageReqVO.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/invoice/ErpPurchaseInvoicePageReqVO.java
@@ -1,8 +1,6 @@
 package cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.invoice;
 
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import cn.iocoder.yudao.framework.common.validation.InEnum;
-import cn.iocoder.yudao.module.erp.enums.ErpPurchaseInvoiceAuditStatusEnum;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
@@ -22,9 +20,5 @@
 
     @Schema(description = "閲囪喘璁㈠崟缂栧彿", example = "17386")
     private Long purchaseOrderId;
-
-    @Schema(description = "瀹℃壒鐘舵��", example = "20")
-    @InEnum(ErpPurchaseInvoiceAuditStatusEnum.class)
-    private Integer auditStatus;
 
 }
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/invoice/ErpPurchaseInvoiceRespVO.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/invoice/ErpPurchaseInvoiceRespVO.java
index 3d84083..e2cd5db 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/invoice/ErpPurchaseInvoiceRespVO.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/invoice/ErpPurchaseInvoiceRespVO.java
@@ -1,9 +1,6 @@
 package cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.invoice;
 
-import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
-import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
 import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order.ErpPurchaseOrderRespVO;
-import cn.iocoder.yudao.module.erp.enums.DictTypeConstants;
 import cn.iocoder.yudao.module.system.api.storage.dto.StorageBlobRespDTO;
 import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
 import cn.idev.excel.annotation.ExcelProperty;
@@ -54,15 +51,6 @@
     @Schema(description = "鏉ョエ鏃ユ湡", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-02")
     @ExcelProperty("鏉ョエ鏃ユ湡")
     private LocalDateTime invoiceTime;
-
-    @Schema(description = "瀹℃壒鐘舵��", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
-    @ExcelProperty(value = "瀹℃壒鐘舵��", converter = DictConvert.class)
-    @DictFormat(DictTypeConstants.AUDIT_STATUS)
-    private Integer auditStatus;
-
-    @Schema(description = "宸ヤ綔娴佺紪鍙�", example = "1043")
-    @ExcelProperty("宸ヤ綔娴佺紪鍙�")
-    private String processInstanceId;
 
     @Schema(description = "澶囨敞", example = "澶囨敞")
     @ExcelProperty("澶囨敞")
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/purchase/ErpPurchaseInvoiceDO.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/purchase/ErpPurchaseInvoiceDO.java
index f86231c..53e1781 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/purchase/ErpPurchaseInvoiceDO.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/purchase/ErpPurchaseInvoiceDO.java
@@ -1,7 +1,6 @@
 package cn.iocoder.yudao.module.erp.dal.dataobject.purchase;
 
 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
-import cn.iocoder.yudao.module.erp.enums.ErpPurchaseInvoiceAuditStatusEnum;
 import com.baomidou.mybatisplus.annotation.KeySequence;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
@@ -66,17 +65,5 @@
      * 澶囨敞
      */
     private String remark;
-    /**
-     * 宸ヤ綔娴佺紪鍙�
-     *
-     * 鍏宠仈 ProcessInstance 鐨� id 灞炴��
-     */
-    private String processInstanceId;
-    /**
-     * 瀹℃壒鐘舵��
-     *
-     * 鏋氫妇 {@link ErpPurchaseInvoiceAuditStatusEnum}
-     */
-    private Integer auditStatus;
 
 }
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/purchase/ErpPurchaseInvoiceMapper.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/purchase/ErpPurchaseInvoiceMapper.java
index cdbef63..e10010c 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/purchase/ErpPurchaseInvoiceMapper.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/purchase/ErpPurchaseInvoiceMapper.java
@@ -5,11 +5,8 @@
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.invoice.ErpPurchaseInvoicePageReqVO;
 import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInvoiceDO;
-import cn.iocoder.yudao.module.erp.enums.ErpPurchaseInvoiceAuditStatusEnum;
-import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.ibatis.annotations.Mapper;
 
-import java.util.Collection;
 import java.util.List;
 
 /**
@@ -24,34 +21,22 @@
         return selectOne(ErpPurchaseInvoiceDO::getNo, no);
     }
 
-    default int updateByIdAndStatus(Long id, Integer status, ErpPurchaseInvoiceDO updateObj) {
-        return update(updateObj, new LambdaUpdateWrapper<ErpPurchaseInvoiceDO>()
-                .eq(ErpPurchaseInvoiceDO::getId, id).eq(ErpPurchaseInvoiceDO::getAuditStatus, status));
-    }
-
     default PageResult<ErpPurchaseInvoiceDO> selectPage(ErpPurchaseInvoicePageReqVO reqVO) {
         return selectPage(reqVO, new LambdaQueryWrapperX<ErpPurchaseInvoiceDO>()
                 .likeIfPresent(ErpPurchaseInvoiceDO::getNo, reqVO.getNo())
                 .eqIfPresent(ErpPurchaseInvoiceDO::getSupplierId, reqVO.getSupplierId())
                 .eqIfPresent(ErpPurchaseInvoiceDO::getPurchaseOrderId, reqVO.getPurchaseOrderId())
-                .eqIfPresent(ErpPurchaseInvoiceDO::getAuditStatus, reqVO.getAuditStatus())
                 .orderByDesc(ErpPurchaseInvoiceDO::getId));
     }
 
-    default List<ErpPurchaseInvoiceDO> selectListByOrderIdAndStatus(Long orderId, Collection<Integer> auditStatuses) {
+    default List<ErpPurchaseInvoiceDO> selectListByOrderId(Long orderId) {
         return selectList(new LambdaQueryWrapperX<ErpPurchaseInvoiceDO>()
-                .eq(ErpPurchaseInvoiceDO::getPurchaseOrderId, orderId)
-                .in(ErpPurchaseInvoiceDO::getAuditStatus, auditStatuses));
+                .eq(ErpPurchaseInvoiceDO::getPurchaseOrderId, orderId));
     }
 
-    default List<ErpPurchaseInvoiceDO> selectListBySupplierIdAndStatus(Long supplierId, Collection<Integer> auditStatuses) {
+    default List<ErpPurchaseInvoiceDO> selectListBySupplierId(Long supplierId) {
         return selectList(new LambdaQueryWrapperX<ErpPurchaseInvoiceDO>()
-                .eq(ErpPurchaseInvoiceDO::getSupplierId, supplierId)
-                .in(ErpPurchaseInvoiceDO::getAuditStatus, auditStatuses));
-    }
-
-    default Long selectCountByAudit() {
-        return selectCount(ErpPurchaseInvoiceDO::getAuditStatus, ErpPurchaseInvoiceAuditStatusEnum.PROCESS.getStatus());
+                .eq(ErpPurchaseInvoiceDO::getSupplierId, supplierId));
     }
 
 }
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/enums/ErpPurchaseInvoiceAuditStatusEnum.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/enums/ErpPurchaseInvoiceAuditStatusEnum.java
deleted file mode 100644
index 3363972..0000000
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/enums/ErpPurchaseInvoiceAuditStatusEnum.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package cn.iocoder.yudao.module.erp.enums;
-
-import cn.iocoder.yudao.framework.common.core.ArrayValuable;
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-
-import java.util.Arrays;
-
-/**
- * ERP 閲囪喘鏉ョエ瀹℃壒鐘舵�佹灇涓�
- *
- * @author 瓒呯骇绠$悊鍛�
- */
-@RequiredArgsConstructor
-@Getter
-public enum ErpPurchaseInvoiceAuditStatusEnum implements ArrayValuable<Integer> {
-
-    DRAFT(0, "鏈彁浜�"),
-    PROCESS(10, "瀹℃壒涓�"),
-    APPROVE(20, "瀹℃牳閫氳繃"),
-    REJECT(30, "瀹℃牳涓嶉�氳繃"),
-    CANCEL(40, "宸插彇娑�");
-
-    public static final Integer[] ARRAYS = Arrays.stream(values()).map(ErpPurchaseInvoiceAuditStatusEnum::getStatus).toArray(Integer[]::new);
-
-    private final Integer status;
-    private final String name;
-
-    @Override
-    public Integer[] array() {
-        return ARRAYS;
-    }
-
-}
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/enums/ErrorCodeConstants.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/enums/ErrorCodeConstants.java
index 64e984f..958f6fc 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/enums/ErrorCodeConstants.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/enums/ErrorCodeConstants.java
@@ -57,14 +57,10 @@
     // ========== ERP 閲囪喘鏉ョエ锛�1-030-105-000锛� ==========
     ErrorCode PURCHASE_INVOICE_NOT_EXISTS = new ErrorCode(1_030_105_000, "鏉ョエ涓嶅瓨鍦�");
     ErrorCode PURCHASE_INVOICE_NO_EXISTS = new ErrorCode(1_030_105_001, "鐢熸垚鏉ョエ缂栧彿澶辫触锛岃閲嶆柊鎻愪氦");
-    ErrorCode PURCHASE_INVOICE_UPDATE_FAIL_EDITING_PROHIBITED = new ErrorCode(1_030_105_002, "鏉ョエ({})涓嶆槸鏈鏍哥姸鎬侊紝鏃犳硶淇敼");
-    ErrorCode PURCHASE_INVOICE_DELETE_FAIL_IS_APPROVE = new ErrorCode(1_030_105_003, "鍒犻櫎鏉ョエ澶辫触锛屽師鍥狅細鏉ョエ瀹℃壒宸查�氳繃");
-    ErrorCode PURCHASE_INVOICE_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS = new ErrorCode(1_030_105_005, "鏇存柊鏉ョエ瀹℃牳鐘舵�佸け璐ワ紝鍘熷洜锛氭潵绁ㄤ笉鏄鏍镐腑鐘舵��");
+    ErrorCode PURCHASE_INVOICE_DELETE_FAIL_HAS_PAYMENT = new ErrorCode(1_030_105_004, "鍒犻櫎鏉ョエ澶辫触锛屽師鍥狅細鏉ョエ宸插瓨鍦ㄦ湁鏁堜粯娆惧崟");
     ErrorCode PURCHASE_INVOICE_CREATE_FAIL_ORDER_NOT_APPROVE = new ErrorCode(1_030_105_006, "鍒涘缓鏉ョエ澶辫触锛屽師鍥狅細閲囪喘璁㈠崟涓嶆槸瀹℃牳閫氳繃鐘舵��");
     ErrorCode PURCHASE_INVOICE_CREATE_FAIL_SUPPLIER_MISMATCH = new ErrorCode(1_030_105_007, "鍒涘缓鏉ョエ澶辫触锛屽師鍥狅細鏉ョエ渚涘簲鍟嗕笌閲囪喘璁㈠崟涓嶄竴鑷�");
     ErrorCode PURCHASE_INVOICE_CREATE_FAIL_PRICE_EXCEEDS_LIMIT = new ErrorCode(1_030_105_008, "鍒涘缓鏉ョエ澶辫触锛屽師鍥狅細鏉ョエ閲戦瓒呭嚭閲囪喘璁㈠崟閲戦锛岀洰鍓嶅彲寮�绁細{} 鍏�");
-    ErrorCode PURCHASE_INVOICE_APPROVE_FAIL = new ErrorCode(1_030_105_009, "瀹℃牳澶辫触锛屽彧鏈夋湭瀹℃牳鐨勬潵绁ㄦ墠鑳藉鏍�");
-    ErrorCode PURCHASE_INVOICE_PROCESS_FAIL = new ErrorCode(1_030_105_010, "鍙嶅鏍稿け璐ワ紝鍙湁宸插鏍哥殑鏉ョエ鎵嶈兘鍙嶅鏍�");
 
     // ========== ERP 閲囪喘閫�璐э紙1-030-103-000锛� ==========
     ErrorCode PURCHASE_RETURN_NOT_EXISTS = new ErrorCode(1_030_103_000, "閲囪喘閫�璐у崟涓嶅瓨鍦�");
@@ -193,7 +189,6 @@
     ErrorCode FINANCE_PAYMENT_NO_EXISTS = new ErrorCode(1_030_601_004, "鐢熸垚浠樻鍗曞彿澶辫触锛岃閲嶆柊鎻愪氦");
     ErrorCode FINANCE_PAYMENT_UPDATE_FAIL_APPROVE = new ErrorCode(1_030_601_005, "浠樻鍗�({})宸插鏍革紝鏃犳硶淇敼");
     ErrorCode FINANCE_PAYMENT_CREATE_FAIL_INVOICE_NOT_EXISTS = new ErrorCode(1_030_601_006, "鍒涘缓浠樻鍗曞け璐ワ紝鍘熷洜锛氬叧鑱旂殑鏉ョエ涓嶅瓨鍦�");
-    ErrorCode FINANCE_PAYMENT_CREATE_FAIL_INVOICE_NOT_APPROVE = new ErrorCode(1_030_601_007, "鍒涘缓浠樻鍗曞け璐ワ紝鍘熷洜锛氬叧鑱旂殑鏉ョエ涓嶆槸瀹℃壒閫氳繃鐘舵��");
     ErrorCode FINANCE_PAYMENT_CREATE_FAIL_INVOICE_NOT_ATTACHMENT = new ErrorCode(1_030_601_008, "鍒涘缓浠樻鍗曞け璐ワ紝鍘熷洜锛氬叧鑱旂殑鏉ョエ鏈笂浼犲彂绁ㄩ檮浠�");
     ErrorCode FINANCE_PAYMENT_CREATE_FAIL_INVOICE_SUPPLIER_MISMATCH = new ErrorCode(1_030_601_009, "鍒涘缓浠樻鍗曞け璐ワ紝鍘熷洜锛氬叧鑱旂殑鏉ョエ涓庢墍閫変緵搴斿晢涓嶅尮閰�");
     ErrorCode FINANCE_PAYMENT_CREATE_FAIL_INVOICE_PRICE_EXCEEDS = new ErrorCode(1_030_601_010, "鍒涘缓浠樻鍗曞け璐ワ紝鍘熷洜锛氫粯娆鹃噾棰濊秴鍑鸿鏉ョエ鍓╀綑鍙粯閲戦锛岀洰鍓嶅彲浠橈細{} 鍏�");
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/finance/ErpFinancePaymentServiceImpl.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/finance/ErpFinancePaymentServiceImpl.java
index 408d6d6..5fdd106 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/finance/ErpFinancePaymentServiceImpl.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/finance/ErpFinancePaymentServiceImpl.java
@@ -20,7 +20,6 @@
 import cn.iocoder.yudao.module.erp.dal.mysql.finance.ErpFinancePaymentMapper;
 import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO;
 import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
-import cn.iocoder.yudao.module.erp.enums.ErpPurchaseInvoiceAuditStatusEnum;
 import cn.iocoder.yudao.module.erp.service.purchase.ErpPurchaseInvoiceService;
 import cn.iocoder.yudao.module.erp.service.purchase.ErpPurchaseInvoiceServiceImpl;
 import cn.iocoder.yudao.module.erp.service.purchase.ErpSupplierService;
@@ -354,7 +353,7 @@
     }
 
     /**
-     * 鏍¢獙浠樻鍗曞叧鑱旂殑鏉ョエ锛氬瓨鍦ㄣ�佸鎵归�氳繃銆佸凡涓婁紶鍙戠エ闄勪欢銆佷緵搴斿晢涓庢潵绁ㄤ竴鑷�
+     * 鏍¢獙浠樻鍗曞叧鑱旂殑鏉ョエ锛氬瓨鍦ㄣ�佸凡涓婁紶鍙戠エ闄勪欢銆佷緵搴斿晢涓庢潵绁ㄤ竴鑷�
      *
      * @param invoiceId 鏉ョエ缂栧彿
      * @param supplierId 渚涘簲鍟嗙紪鍙�
@@ -365,16 +364,12 @@
         if (invoice == null) {
             throw exception(FINANCE_PAYMENT_CREATE_FAIL_INVOICE_NOT_EXISTS);
         }
-        // 2. 鏍¢獙鏉ョエ瀹℃壒閫氳繃
-        if (ObjectUtil.notEqual(invoice.getAuditStatus(), ErpPurchaseInvoiceAuditStatusEnum.APPROVE.getStatus())) {
-            throw exception(FINANCE_PAYMENT_CREATE_FAIL_INVOICE_NOT_APPROVE);
-        }
-        // 3. 鏍¢獙宸蹭笂浼犲彂绁ㄩ檮浠�
+        // 2. 鏍¢獙宸蹭笂浼犲彂绁ㄩ檮浠�
         if (CollUtil.isEmpty(storageAttachmentApi.listAttachments(
                 ErpPurchaseInvoiceServiceImpl.PURCHASE_INVOICE_RECORD_TYPE, invoiceId))) {
             throw exception(FINANCE_PAYMENT_CREATE_FAIL_INVOICE_NOT_ATTACHMENT);
         }
-        // 4. 鏍¢獙渚涘簲鍟嗕笌鏉ョエ涓�鑷达紙闃茶剰鏁版嵁锛�
+        // 3. 鏍¢獙渚涘簲鍟嗕笌鏉ョエ涓�鑷达紙闃茶剰鏁版嵁锛�
         if (ObjectUtil.notEqual(invoice.getSupplierId(), supplierId)) {
             throw exception(FINANCE_PAYMENT_CREATE_FAIL_INVOICE_SUPPLIER_MISMATCH);
         }
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseInvoiceService.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseInvoiceService.java
index 9e0650a..10ec261 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseInvoiceService.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseInvoiceService.java
@@ -42,14 +42,6 @@
     void deletePurchaseInvoice(Long id);
 
     /**
-     * 鏇存柊鏉ョエ鐨勭姸鎬侊紙瀹℃牳/鍙嶅鏍革級
-     *
-     * @param id 缂栧彿
-     * @param status 鐘舵��
-     */
-    void updatePurchaseInvoiceStatus(Long id, Integer status);
-
-    /**
      * 鑾峰緱鏉ョエ
      *
      * @param id 缂栧彿
@@ -84,28 +76,19 @@
     PageResult<ErpPurchaseInvoiceDO> getPurchaseInvoicePage(ErpPurchaseInvoicePageReqVO pageReqVO);
 
     /**
-     * 鏍规嵁閲囪喘璁㈠崟缂栧彿鍜屽鎵圭姸鎬佽幏寰楁潵绁ㄥ垪琛�
+     * 鏍规嵁閲囪喘璁㈠崟缂栧彿鑾峰緱鏉ョエ鍒楄〃
      *
      * @param orderId 閲囪喘璁㈠崟缂栧彿
-     * @param auditStatuses 瀹℃壒鐘舵�侀泦鍚�
      * @return 鏉ョエ鍒楄〃
      */
-    List<ErpPurchaseInvoiceDO> getPurchaseInvoiceListByOrderIdAndStatus(Long orderId, Collection<Integer> auditStatuses);
+    List<ErpPurchaseInvoiceDO> getPurchaseInvoiceListByOrderId(Long orderId);
 
     /**
-     * 鏍规嵁渚涘簲鍟嗙紪鍙峰拰瀹℃壒鐘舵�佽幏寰楁潵绁ㄥ垪琛�
+     * 鏍规嵁渚涘簲鍟嗙紪鍙疯幏寰楁潵绁ㄥ垪琛�
      *
      * @param supplierId 渚涘簲鍟嗙紪鍙�
-     * @param auditStatuses 瀹℃壒鐘舵�侀泦鍚�
      * @return 鏉ョエ鍒楄〃
      */
-    List<ErpPurchaseInvoiceDO> getPurchaseInvoiceListBySupplierIdAndStatus(Long supplierId, Collection<Integer> auditStatuses);
-
-    /**
-     * 鑾峰緱寰呭鏍告潵绁ㄦ暟閲�
-     *
-     * @return 鏁伴噺
-     */
-    Long getAuditInvoiceCount();
+    List<ErpPurchaseInvoiceDO> getPurchaseInvoiceListBySupplierId(Long supplierId);
 
 }
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseInvoiceServiceImpl.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseInvoiceServiceImpl.java
index 19c6e7e..ab24aed 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseInvoiceServiceImpl.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseInvoiceServiceImpl.java
@@ -9,9 +9,9 @@
 import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.invoice.ErpPurchaseInvoiceSaveReqVO;
 import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInvoiceDO;
 import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderDO;
+import cn.iocoder.yudao.module.erp.dal.mysql.finance.ErpFinancePaymentMapper;
 import cn.iocoder.yudao.module.erp.dal.mysql.purchase.ErpPurchaseInvoiceMapper;
 import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO;
-import cn.iocoder.yudao.module.erp.enums.ErpPurchaseInvoiceAuditStatusEnum;
 import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi;
 import jakarta.annotation.Resource;
 import org.springframework.stereotype.Service;
@@ -21,6 +21,7 @@
 import java.math.BigDecimal;
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue;
@@ -44,6 +45,9 @@
     private ErpPurchaseInvoiceMapper invoiceMapper;
 
     @Resource
+    private ErpFinancePaymentMapper financePaymentMapper;
+
+    @Resource
     private ErpNoRedisDAO noRedisDAO;
 
     @Resource
@@ -65,9 +69,8 @@
             throw exception(PURCHASE_INVOICE_NO_EXISTS);
         }
 
-        // 2.1 鎻掑叆鏉ョエ锛堝垱寤哄悗鍗充负鏈鏍哥姸鎬侊級
-        ErpPurchaseInvoiceDO invoice = BeanUtils.toBean(createReqVO, ErpPurchaseInvoiceDO.class)
-                .setNo(no).setAuditStatus(ErpPurchaseInvoiceAuditStatusEnum.PROCESS.getStatus());
+        // 2.1 鎻掑叆鏉ョエ锛堝垱寤哄悗鍗充负鏈夋晥鐘舵�侊紝鏃犻渶瀹℃牳锛�
+        ErpPurchaseInvoiceDO invoice = BeanUtils.toBean(createReqVO, ErpPurchaseInvoiceDO.class).setNo(no);
         invoiceMapper.insert(invoice);
 
         // 2.2 缁戝畾鍙戠エ闄勪欢
@@ -88,12 +91,9 @@
     }
 
     private void validatePurchaseInvoicePriceExceedsLimit(ErpPurchaseInvoiceSaveReqVO reqVO) {
-        // 1. 璁$畻鍓╀綑鍙紑绁ㄩ噾棰濓紝涓嶅寘鎷� reqVO 鑷韩锛堝鎵逛腑涔熷崰鐢ㄩ搴︼紝闃叉绱鏉ョエ瓒呰繃閲囪喘璁㈠崟閲戦锛�
+        // 1. 璁$畻鍓╀綑鍙紑绁ㄩ噾棰濓紝涓嶅寘鎷� reqVO 鑷韩锛堟墍鏈夋湁鏁堟潵绁ㄩ兘鍗犵敤棰濆害锛岄槻姝㈢疮璁℃潵绁ㄨ秴杩囬噰璐鍗曢噾棰濓級
         ErpPurchaseOrderDO purchaseOrder = purchaseOrderService.getPurchaseOrder(reqVO.getPurchaseOrderId());
-        List<ErpPurchaseInvoiceDO> invoices = invoiceMapper.selectListByOrderIdAndStatus(reqVO.getPurchaseOrderId(),
-                List.of(ErpPurchaseInvoiceAuditStatusEnum.DRAFT.getStatus(),
-                        ErpPurchaseInvoiceAuditStatusEnum.PROCESS.getStatus(),
-                        ErpPurchaseInvoiceAuditStatusEnum.APPROVE.getStatus()));
+        List<ErpPurchaseInvoiceDO> invoices = invoiceMapper.selectListByOrderId(reqVO.getPurchaseOrderId());
         if (reqVO.getId() != null) {
             invoices.removeIf(invoice -> ObjectUtil.equal(invoice.getId(), reqVO.getId()));
         }
@@ -110,12 +110,8 @@
     public void updatePurchaseInvoice(ErpPurchaseInvoiceSaveReqVO updateReqVO) {
         Assert.notNull(updateReqVO.getId(), "鏉ョエ缂栧彿涓嶈兘涓虹┖");
         // 1.1 鏍¢獙瀛樺湪
-        ErpPurchaseInvoiceDO oldInvoice = validatePurchaseInvoiceExists(updateReqVO.getId());
-        // 1.2 鍙湁鏈鏍稿彲浠ョ紪杈�
-        if (ObjectUtil.notEqual(oldInvoice.getAuditStatus(), ErpPurchaseInvoiceAuditStatusEnum.PROCESS.getStatus())) {
-            throw exception(PURCHASE_INVOICE_UPDATE_FAIL_EDITING_PROHIBITED, oldInvoice.getNo());
-        }
-        // 1.3 鏍¢獙鍏宠仈鏁版嵁 + 鍙紑绁ㄩ噾棰�
+        validatePurchaseInvoiceExists(updateReqVO.getId());
+        // 1.2 鏍¢獙鍏宠仈鏁版嵁 + 鍙紑绁ㄩ噾棰�
         validateRelationDataExists(updateReqVO);
         validatePurchaseInvoicePriceExceedsLimit(updateReqVO);
 
@@ -131,35 +127,17 @@
     @Transactional(rollbackFor = Exception.class)
     public void deletePurchaseInvoice(Long id) {
         // 1.1 鏍¢獙瀛樺湪
-        ErpPurchaseInvoiceDO invoice = validatePurchaseInvoiceExists(id);
-        // 1.2 瀹℃壒閫氳繃鏃讹紝涓嶅厑璁稿垹闄�
-        if (ObjectUtil.equal(invoice.getAuditStatus(), ErpPurchaseInvoiceAuditStatusEnum.APPROVE.getStatus())) {
-            throw exception(PURCHASE_INVOICE_DELETE_FAIL_IS_APPROVE);
+        validatePurchaseInvoiceExists(id);
+        // 1.2 宸叉湁鏈夋晥浠樻鍗曞叧鑱旂殑鏉ョエ锛屼笉鍏佽鍒犻櫎锛堜繚鎸佹潵绁ㄤ笌浠樻鐨勫叧鑱斿畬鏁存�э級
+        Map<Long, BigDecimal> paidMap = financePaymentMapper.selectPaymentPriceMapByInvoiceId(List.of(id));
+        if (paidMap.getOrDefault(id, BigDecimal.ZERO).compareTo(BigDecimal.ZERO) > 0) {
+            throw exception(PURCHASE_INVOICE_DELETE_FAIL_HAS_PAYMENT);
         }
 
         // 2.1 鍒犻櫎鍙戠エ闄勪欢
         storageAttachmentApi.deleteAttachmentsByRecord(PURCHASE_INVOICE_RECORD_TYPE, id);
         // 2.2 鍒犻櫎鏉ョエ
         invoiceMapper.deleteById(id);
-    }
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public void updatePurchaseInvoiceStatus(Long id, Integer status) {
-        boolean approve = ErpPurchaseInvoiceAuditStatusEnum.APPROVE.getStatus().equals(status);
-        // 1.1 鏍¢獙瀛樺湪
-        ErpPurchaseInvoiceDO invoice = validatePurchaseInvoiceExists(id);
-        // 1.2 鏍¢獙鐘舵��
-        if (invoice.getAuditStatus().equals(status)) {
-            throw exception(approve ? PURCHASE_INVOICE_APPROVE_FAIL : PURCHASE_INVOICE_PROCESS_FAIL);
-        }
-
-        // 2. 鏇存柊鐘舵��
-        int updateCount = invoiceMapper.updateByIdAndStatus(id, invoice.getAuditStatus(),
-                new ErpPurchaseInvoiceDO().setAuditStatus(status));
-        if (updateCount == 0) {
-            throw exception(approve ? PURCHASE_INVOICE_APPROVE_FAIL : PURCHASE_INVOICE_PROCESS_FAIL);
-        }
     }
 
     private ErpPurchaseInvoiceDO validatePurchaseInvoiceExists(Long id) {
@@ -189,18 +167,13 @@
     }
 
     @Override
-    public List<ErpPurchaseInvoiceDO> getPurchaseInvoiceListByOrderIdAndStatus(Long orderId, Collection<Integer> auditStatuses) {
-        return invoiceMapper.selectListByOrderIdAndStatus(orderId, auditStatuses);
+    public List<ErpPurchaseInvoiceDO> getPurchaseInvoiceListByOrderId(Long orderId) {
+        return invoiceMapper.selectListByOrderId(orderId);
     }
 
     @Override
-    public List<ErpPurchaseInvoiceDO> getPurchaseInvoiceListBySupplierIdAndStatus(Long supplierId, Collection<Integer> auditStatuses) {
-        return invoiceMapper.selectListBySupplierIdAndStatus(supplierId, auditStatuses);
-    }
-
-    @Override
-    public Long getAuditInvoiceCount() {
-        return invoiceMapper.selectCountByAudit();
+    public List<ErpPurchaseInvoiceDO> getPurchaseInvoiceListBySupplierId(Long supplierId) {
+        return invoiceMapper.selectListBySupplierId(supplierId);
     }
 
 }
diff --git a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/certificate/SrmSupplierCertificateController.java b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/certificate/SrmSupplierCertificateController.java
index 003ed7e..40d0a03 100644
--- a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/certificate/SrmSupplierCertificateController.java
+++ b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/certificate/SrmSupplierCertificateController.java
@@ -6,7 +6,9 @@
 import cn.iocoder.yudao.module.srm.controller.admin.certificate.vo.*;
 import cn.iocoder.yudao.module.srm.dal.dataobject.SrmSupplierDO;
 import cn.iocoder.yudao.module.srm.service.certificate.SrmSupplierCertificateService;
+import cn.iocoder.yudao.module.srm.service.certificate.SrmSupplierCertificateServiceImpl;
 import cn.iocoder.yudao.module.srm.service.supplier.SrmSupplierService;
+import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -34,6 +36,9 @@
 
     @Resource
     private SrmSupplierService supplierService;
+
+    @Resource
+    private StorageAttachmentApi storageAttachmentApi;
 
     @PostMapping("/create")
     @Operation(summary = "鍒涘缓璧勮川璇佷功")
@@ -66,6 +71,7 @@
         var pageResult = certificateService.getCertificatePage(pageReqVO);
         var respList = BeanUtils.toBean(pageResult.getList(), SrmSupplierCertificateRespVO.class);
         enrichSupplierNames(respList);
+        enrichAttachments(respList);
         return success(new PageResult<>(respList, pageResult.getTotal()));
     }
 
@@ -75,6 +81,7 @@
     public CommonResult<List<SrmSupplierCertificateRespVO>> getListBySupplier(@RequestParam("supplierId") Long supplierId) {
         var list = BeanUtils.toBean(certificateService.getCertificateListBySupplierId(supplierId), SrmSupplierCertificateRespVO.class);
         enrichSupplierNames(list);
+        enrichAttachments(list);
         return success(list);
     }
 
@@ -93,6 +100,7 @@
     public CommonResult<SrmSupplierCertificateRespVO> getCertificate(@RequestParam("id") Long id) {
         var resp = BeanUtils.toBean(certificateService.getCertificate(id), SrmSupplierCertificateRespVO.class);
         enrichSupplierName(resp);
+        enrichAttachments(List.of(resp));
         return success(resp);
     }
 
@@ -118,4 +126,10 @@
         }
     }
 
+    private void enrichAttachments(List<SrmSupplierCertificateRespVO> list) {
+        if (list == null || list.isEmpty()) return;
+        list.forEach(vo -> vo.setAttachmentList(storageAttachmentApi.listAttachments(
+                SrmSupplierCertificateServiceImpl.CERTIFICATE_RECORD_TYPE, vo.getId())));
+    }
+
 }
diff --git a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/certificate/vo/SrmSupplierCertificateRespVO.java b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/certificate/vo/SrmSupplierCertificateRespVO.java
index 672a969..0cb8443 100644
--- a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/certificate/vo/SrmSupplierCertificateRespVO.java
+++ b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/certificate/vo/SrmSupplierCertificateRespVO.java
@@ -1,10 +1,12 @@
 package cn.iocoder.yudao.module.srm.controller.admin.certificate.vo;
 
+import cn.iocoder.yudao.module.system.api.storage.dto.StorageBlobRespDTO;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
 import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.util.List;
 
 @Schema(description = "绠$悊鍚庡彴 - SRM 渚涘簲鍟嗚祫璐ㄨ瘉涔� Response VO")
 @Data
@@ -52,4 +54,7 @@
     @Schema(description = "鍒涘缓鏃堕棿")
     private LocalDateTime createTime;
 
+    @Schema(description = "璇佷功闄勪欢鍒楄〃")
+    private List<StorageBlobRespDTO> attachmentList;
+
 }
diff --git a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/certificate/vo/SrmSupplierCertificateSaveReqVO.java b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/certificate/vo/SrmSupplierCertificateSaveReqVO.java
index 64c493e..3938430c 100644
--- a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/certificate/vo/SrmSupplierCertificateSaveReqVO.java
+++ b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/certificate/vo/SrmSupplierCertificateSaveReqVO.java
@@ -6,6 +6,7 @@
 import lombok.Data;
 
 import java.time.LocalDate;
+import java.util.List;
 
 @Schema(description = "绠$悊鍚庡彴 - SRM 渚涘簲鍟嗚祫璐ㄨ瘉涔﹀垱寤�/鏇存柊 Request VO")
 @Data
@@ -47,4 +48,7 @@
     @Schema(description = "澶囨敞", example = "骞村害璧勮川瀹℃牳")
     private String remark;
 
+    @Schema(description = "璇佷功闄勪欢鏂囦欢ID鍒楄〃")
+    private List<Long> blobIds;
+
 }
diff --git a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/supplier/SrmSupplierController.java b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/supplier/SrmSupplierController.java
index e183de0..c0b71d8 100644
--- a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/supplier/SrmSupplierController.java
+++ b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/supplier/SrmSupplierController.java
@@ -80,6 +80,13 @@
         return success(BeanUtils.toBean(list, SrmSupplierRespVO.class));
     }
 
+    @GetMapping("/list")
+    @Operation(summary = "鑾峰彇渚涘簲鍟嗘。妗堝垪琛紙涓嶈繃婊ゅ噯鍏ョ姸鎬侊級")
+    public CommonResult<List<SrmSupplierRespVO>> getSupplierAllList() {
+        List<SrmSupplierDO> list = supplierService.getSupplierAllList();
+        return success(BeanUtils.toBean(list, SrmSupplierRespVO.class));
+    }
+
     @GetMapping("/export-excel")
     @Operation(summary = "瀵煎嚭渚涘簲鍟� Excel")
     @PreAuthorize("@ss.hasPermission('srm:supplier:export')")
diff --git a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/tender/SrmTenderProjectController.java b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/tender/SrmTenderProjectController.java
index 8126210..abed6e7 100644
--- a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/tender/SrmTenderProjectController.java
+++ b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/tender/SrmTenderProjectController.java
@@ -5,6 +5,8 @@
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.srm.controller.admin.tender.vo.*;
 import cn.iocoder.yudao.module.srm.service.tender.SrmTenderProjectService;
+import cn.iocoder.yudao.module.srm.service.tender.SrmTenderProjectServiceImpl;
+import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -26,6 +28,9 @@
 
     @Resource
     private SrmTenderProjectService tenderProjectService;
+
+    @Resource
+    private StorageAttachmentApi storageAttachmentApi;
 
     @PostMapping("/create")
     @Operation(summary = "鍒涘缓鎷涙爣椤圭洰")
@@ -54,14 +59,27 @@
     @Operation(summary = "鑾峰彇鎷涙爣椤圭洰璇︽儏")
     @PreAuthorize("@ss.hasPermission('srm:tender-project:query')")
     public CommonResult<SrmTenderProjectRespVO> getTenderProject(@RequestParam("id") Long id) {
-        return success(BeanUtils.toBean(tenderProjectService.getTenderProject(id), SrmTenderProjectRespVO.class));
+        var resp = BeanUtils.toBean(tenderProjectService.getTenderProject(id), SrmTenderProjectRespVO.class);
+        enrichAttachments(List.of(resp));
+        return success(resp);
     }
 
     @GetMapping("/page")
     @Operation(summary = "鑾峰彇鎷涙爣椤圭洰鍒嗛〉")
     @PreAuthorize("@ss.hasPermission('srm:tender-project:query')")
     public CommonResult<PageResult<SrmTenderProjectRespVO>> getTenderProjectPage(@Valid SrmTenderProjectPageReqVO pageReqVO) {
-        return success(BeanUtils.toBean(tenderProjectService.getTenderProjectPage(pageReqVO), SrmTenderProjectRespVO.class));
+        var pageResult = tenderProjectService.getTenderProjectPage(pageReqVO);
+        var respList = BeanUtils.toBean(pageResult.getList(), SrmTenderProjectRespVO.class);
+        enrichAttachments(respList);
+        return success(new PageResult<>(respList, pageResult.getTotal()));
+    }
+
+    // ========== 鍏宠仈鏁版嵁濉厖 ==========
+
+    private void enrichAttachments(List<SrmTenderProjectRespVO> list) {
+        if (list == null || list.isEmpty()) return;
+        list.forEach(vo -> vo.setAttachmentList(storageAttachmentApi.listAttachments(
+                SrmTenderProjectServiceImpl.TENDER_PROJECT_RECORD_TYPE, vo.getId())));
     }
 
     @PutMapping("/publish")
diff --git a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/tender/vo/SrmTenderProjectPartialUpdateReqVO.java b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/tender/vo/SrmTenderProjectPartialUpdateReqVO.java
index 0b8aa99..aa7203d 100644
--- a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/tender/vo/SrmTenderProjectPartialUpdateReqVO.java
+++ b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/tender/vo/SrmTenderProjectPartialUpdateReqVO.java
@@ -4,6 +4,8 @@
 import jakarta.validation.constraints.NotNull;
 import lombok.Data;
 
+import java.util.List;
+
 @Schema(description = "绠$悊鍚庡彴 - SRM 鎷涙爣椤圭洰閮ㄥ垎鏇存柊 Request VO锛堝彂甯冧腑/鎶曟爣涓樁娈碉級")
 @Data
 public class SrmTenderProjectPartialUpdateReqVO {
@@ -18,4 +20,7 @@
     @Schema(description = "璧勮川瑕佹眰", example = "闇�鍏峰ISO9001璁よ瘉")
     private String qualificationRequirements;
 
+    @Schema(description = "璧勮川瑕佹眰闄勪欢鏂囦欢ID鍒楄〃")
+    private List<Long> blobIds;
+
 }
diff --git a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/tender/vo/SrmTenderProjectRespVO.java b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/tender/vo/SrmTenderProjectRespVO.java
index f32cd6a..ccaebb8 100644
--- a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/tender/vo/SrmTenderProjectRespVO.java
+++ b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/tender/vo/SrmTenderProjectRespVO.java
@@ -1,10 +1,12 @@
 package cn.iocoder.yudao.module.srm.controller.admin.tender.vo;
 
+import cn.iocoder.yudao.module.system.api.storage.dto.StorageBlobRespDTO;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
+import java.util.List;
 
 @Schema(description = "绠$悊鍚庡彴 - SRM 鎷涙爣椤圭洰 Response VO")
 @Data
@@ -55,6 +57,9 @@
     @Schema(description = "璧勮川瑕佹眰", example = "闇�鍏峰ISO9001璁よ瘉")
     private String qualificationRequirements;
 
+    @Schema(description = "璧勮川瑕佹眰闄勪欢鍒楄〃")
+    private List<StorageBlobRespDTO> attachmentList;
+
     @Schema(description = "閲囪喘鐢宠ID", example = "1")
     private Long purchaseRequestId;
 
diff --git a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/tender/vo/SrmTenderProjectSaveReqVO.java b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/tender/vo/SrmTenderProjectSaveReqVO.java
index f0e2385..436e1d8 100644
--- a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/tender/vo/SrmTenderProjectSaveReqVO.java
+++ b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/tender/vo/SrmTenderProjectSaveReqVO.java
@@ -7,6 +7,7 @@
 
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
+import java.util.List;
 
 @Schema(description = "绠$悊鍚庡彴 - SRM 鎷涙爣椤圭洰鍒涘缓/鏇存柊 Request VO")
 @Data
@@ -60,6 +61,9 @@
     @Schema(description = "璧勮川瑕佹眰", example = "闇�鍏峰ISO9001璁よ瘉")
     private String qualificationRequirements;
 
+    @Schema(description = "璧勮川瑕佹眰闄勪欢鏂囦欢ID鍒楄〃")
+    private List<Long> blobIds;
+
     @Schema(description = "閲囪喘鐢宠ID", example = "1")
     private Long purchaseRequestId;
 
diff --git a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/apply/SrmSupplierApplyService.java b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/apply/SrmSupplierApplyService.java
index 30e75da..ba759ca 100644
--- a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/apply/SrmSupplierApplyService.java
+++ b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/apply/SrmSupplierApplyService.java
@@ -61,4 +61,11 @@
      */
     void approve(Long id);
 
+    /**
+     * 纭繚渚涘簲鍟嗗凡鍑嗗叆锛氭湭鍑嗗叆鍒欒嚜鍔ㄥ垱寤哄噯鍏ョ敵璇峰苟缃负宸查�氳繃
+     *
+     * @param supplierId 渚涘簲鍟嗙紪鍙�
+     */
+    void ensureSupplierApproved(Long supplierId);
+
 }
diff --git a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/apply/SrmSupplierApplyServiceImpl.java b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/apply/SrmSupplierApplyServiceImpl.java
index 58988e0..9a1a9f3 100644
--- a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/apply/SrmSupplierApplyServiceImpl.java
+++ b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/apply/SrmSupplierApplyServiceImpl.java
@@ -145,6 +145,43 @@
 
     @Override
     @Transactional(rollbackFor = Exception.class)
+    public void ensureSupplierApproved(Long supplierId) {
+        if (supplierId == null) {
+            return;
+        }
+        // 鏍¢獙渚涘簲鍟嗗瓨鍦�
+        SrmSupplierDO supplier = supplierMapper.selectById(supplierId);
+        if (supplier == null) {
+            throw ServiceExceptionUtil.exception(ErrorCodeConstants.SUPPLIER_NOT_EXISTS);
+        }
+        // 宸插噯鍏ュ垯鏃犻渶澶勭悊
+        if (supplierApplyMapper.existsApprovedBySupplierId(supplierId)) {
+            return;
+        }
+        // 鑷姩鍒涘缓鍑嗗叆鐢宠骞剁洿鎺ョ疆涓哄凡閫氳繃
+        SrmSupplierApplyDO apply = new SrmSupplierApplyDO();
+        apply.setApplyNo(generateApplyNo());
+        apply.setSupplierId(supplierId);
+        apply.setSupplierName(supplier.getName());
+        apply.setSupplierType(supplier.getType());
+        apply.setCompanyNature(supplier.getCompanyNature());
+        apply.setRegisteredCapital(supplier.getRegisteredCapital());
+        apply.setBusinessLicenseNo(supplier.getBusinessLicenseNo());
+        apply.setTaxNo(supplier.getTaxNo());
+        apply.setAddress(supplier.getAddress());
+        apply.setBankName(supplier.getBankName());
+        apply.setBankAccount(supplier.getBankAccount());
+        apply.setContactName(supplier.getContactName());
+        apply.setContactMobile(supplier.getContactMobile());
+        apply.setContactEmail(supplier.getContactEmail());
+        apply.setRemark("涓爣鐢熸垚閲囪喘璁㈠崟鏃惰嚜鍔ㄥ噯鍏ュ苟閫氳繃");
+        apply.setApplyStatus(SupplierApplyStatusEnum.APPROVED.getCode());
+        apply.setApplyTime(LocalDateTime.now());
+        supplierApplyMapper.insert(apply);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
     public void approve(Long id) {
         SrmSupplierApplyDO apply = validateApplyExists(id);
         if (!SupplierApplyStatusEnum.APPROVED.getCode().equals(apply.getApplyStatus())) {
diff --git a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/certificate/SrmSupplierCertificateServiceImpl.java b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/certificate/SrmSupplierCertificateServiceImpl.java
index 7dddd49..78132f6 100644
--- a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/certificate/SrmSupplierCertificateServiceImpl.java
+++ b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/certificate/SrmSupplierCertificateServiceImpl.java
@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.module.srm.service.certificate;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.srm.controller.admin.certificate.vo.SrmSupplierCertificatePageReqVO;
@@ -8,8 +9,10 @@
 import cn.iocoder.yudao.module.srm.dal.mysql.SrmSupplierCertificateMapper;
 import cn.iocoder.yudao.module.srm.enums.ErrorCodeConstants;
 import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
+import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi;
 import jakarta.annotation.Resource;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
 import java.time.LocalDate;
@@ -19,28 +22,47 @@
 @Validated
 public class SrmSupplierCertificateServiceImpl implements SrmSupplierCertificateService {
 
+    /**
+     * 璧勮川璇佷功闄勪欢鐨勪笟鍔¤褰曠被鍨嬶紝瀵瑰簲 {@link cn.iocoder.yudao.module.system.enums.storage.StorageRecordTypeEnum#SRM_SUPPLIER_CERTIFICATE}
+     */
+    public static final String CERTIFICATE_RECORD_TYPE = "srm_supplier_certificate";
+
     @Resource
     private SrmSupplierCertificateMapper certificateMapper;
 
+    @Resource
+    private StorageAttachmentApi storageAttachmentApi;
+
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public Long createCertificate(SrmSupplierCertificateSaveReqVO createReqVO) {
         SrmSupplierCertificateDO certificate = BeanUtils.toBean(createReqVO, SrmSupplierCertificateDO.class);
         updateStatus(certificate);
         certificateMapper.insert(certificate);
+        // 缁戝畾璇佷功闄勪欢
+        if (CollUtil.isNotEmpty(createReqVO.getBlobIds())) {
+            storageAttachmentApi.bindAttachments("file", CERTIFICATE_RECORD_TYPE, certificate.getId(), createReqVO.getBlobIds());
+        }
         return certificate.getId();
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void updateCertificate(SrmSupplierCertificateSaveReqVO updateReqVO) {
         validateCertificateExists(updateReqVO.getId());
         SrmSupplierCertificateDO updateObj = BeanUtils.toBean(updateReqVO, SrmSupplierCertificateDO.class);
         updateStatus(updateObj);
         certificateMapper.updateById(updateObj);
+        // 澧為噺鏇存柊璇佷功闄勪欢
+        storageAttachmentApi.updateAttachments("file", CERTIFICATE_RECORD_TYPE, updateReqVO.getId(), updateReqVO.getBlobIds());
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void deleteCertificate(Long id) {
         validateCertificateExists(id);
+        // 鍒犻櫎璇佷功闄勪欢
+        storageAttachmentApi.deleteAttachmentsByRecord(CERTIFICATE_RECORD_TYPE, id);
         certificateMapper.deleteById(id);
     }
 
diff --git a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/supplier/SrmSupplierService.java b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/supplier/SrmSupplierService.java
index c43333c..2b8783d 100644
--- a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/supplier/SrmSupplierService.java
+++ b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/supplier/SrmSupplierService.java
@@ -46,6 +46,11 @@
     List<SrmSupplierDO> getSupplierSimpleList();
 
     /**
+     * 鑾峰彇鍏ㄩ儴渚涘簲鍟嗘。妗堝垪琛紙涓嶈繃婊ゅ噯鍏ョ姸鎬侊紝鐢ㄤ簬鎶曟爣閫夋嫨渚涘簲鍟嗭級
+     */
+    List<SrmSupplierDO> getSupplierAllList();
+
+    /**
      * 鑾峰彇渚涘簲鍟嗗垪琛�
      */
     List<SrmSupplierDO> getSupplierList(Collection<Long> ids);
diff --git a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/supplier/SrmSupplierServiceImpl.java b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/supplier/SrmSupplierServiceImpl.java
index fe7fe1a..c9d5858 100644
--- a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/supplier/SrmSupplierServiceImpl.java
+++ b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/supplier/SrmSupplierServiceImpl.java
@@ -3,6 +3,7 @@
 import cn.hutool.core.collection.CollUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.srm.controller.admin.supplier.vo.SrmSupplierPageReqVO;
 import cn.iocoder.yudao.module.srm.controller.admin.supplier.vo.SrmSupplierSaveReqVO;
 import cn.iocoder.yudao.module.srm.dal.dataobject.*;
@@ -107,6 +108,12 @@
     }
 
     @Override
+    public List<SrmSupplierDO> getSupplierAllList() {
+        return supplierMapper.selectList(new LambdaQueryWrapperX<SrmSupplierDO>()
+                .orderByAsc(SrmSupplierDO::getId));
+    }
+
+    @Override
     public List<SrmSupplierDO> getSupplierList(Collection<Long> ids) {
         if (CollUtil.isEmpty(ids)) {
             return Collections.emptyList();
diff --git a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/tender/SrmBidAwardServiceImpl.java b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/tender/SrmBidAwardServiceImpl.java
index f005359..aa836d3 100644
--- a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/tender/SrmBidAwardServiceImpl.java
+++ b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/tender/SrmBidAwardServiceImpl.java
@@ -14,6 +14,7 @@
 import cn.iocoder.yudao.module.srm.enums.BidStatusEnum;
 import cn.iocoder.yudao.module.srm.enums.ErrorCodeConstants;
 import cn.iocoder.yudao.module.srm.enums.TenderStatusEnum;
+import cn.iocoder.yudao.module.srm.service.apply.SrmSupplierApplyService;
 import com.mzt.logapi.starter.annotation.LogRecord;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
@@ -61,6 +62,9 @@
 
     @Resource
     private ErpPurchaseOrderApi erpPurchaseOrderApi;
+
+    @Resource
+    private SrmSupplierApplyService supplierApplyService;
 
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -162,6 +166,9 @@
             throw ServiceExceptionUtil.exception(ErrorCodeConstants.AWARD_SUPPLIER_NOT_SYNCED);
         }
 
+        // 渚涘簲鍟嗘湭鍑嗗叆鍒欒嚜鍔ㄥ噯鍏ュ苟閫氳繃锛屼繚璇侀噰璐鍗曟祦绋嬪彲鐢�
+        supplierApplyService.ensureSupplierApproved(srmSupplier.getId());
+
         // 3. 鏌ユ嫑鏍囩墿鏂欏垪琛�
         List<SrmTenderMaterialDO> materials = tenderMaterialMapper
                 .selectListByTenderProjectId(award.getTenderProjectId());
diff --git a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/tender/SrmTenderProjectServiceImpl.java b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/tender/SrmTenderProjectServiceImpl.java
index f8ae67f..73b86db 100644
--- a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/tender/SrmTenderProjectServiceImpl.java
+++ b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/tender/SrmTenderProjectServiceImpl.java
@@ -7,6 +7,7 @@
 import cn.iocoder.yudao.module.erp.api.purchase.dto.ErpPurchaseOrderCreateReqDTO;
 import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
 import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
+import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi;
 import cn.iocoder.yudao.module.srm.controller.admin.tender.vo.SrmTenderMaterialSaveReqVO;
 import cn.iocoder.yudao.module.srm.controller.admin.tender.vo.SrmTenderProjectPageReqVO;
 import cn.iocoder.yudao.module.srm.controller.admin.tender.vo.SrmTenderProjectPartialUpdateReqVO;
@@ -18,6 +19,7 @@
 import cn.iocoder.yudao.module.srm.enums.BidStatusEnum;
 import cn.iocoder.yudao.module.srm.enums.ErrorCodeConstants;
 import cn.iocoder.yudao.module.srm.enums.TenderStatusEnum;
+import cn.iocoder.yudao.module.srm.service.apply.SrmSupplierApplyService;
 import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
 import com.mzt.logapi.context.LogRecordContext;
 import com.mzt.logapi.starter.annotation.LogRecord;
@@ -41,6 +43,11 @@
 @Slf4j
 public class SrmTenderProjectServiceImpl implements SrmTenderProjectService {
 
+    /**
+     * 鎷涙爣椤圭洰璧勮川瑕佹眰闄勪欢鐨勪笟鍔¤褰曠被鍨嬶紝瀵瑰簲 {@link cn.iocoder.yudao.module.system.enums.storage.StorageRecordTypeEnum#SRM_TENDER_PROJECT}
+     */
+    public static final String TENDER_PROJECT_RECORD_TYPE = "srm_tender_project";
+
     @Resource
     private SrmTenderProjectMapper tenderProjectMapper;
     @Resource
@@ -60,8 +67,13 @@
     private MdmItemApi mdmItemApi;
     @Resource
     private ErpPurchaseOrderApi erpPurchaseOrderApi;
+    @Resource
+    private SrmSupplierApplyService supplierApplyService;
+    @Resource
+    private StorageAttachmentApi storageAttachmentApi;
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public Long createTenderProject(SrmTenderProjectSaveReqVO createReqVO) {
         SrmTenderProjectDO project = BeanUtils.toBean(createReqVO, SrmTenderProjectDO.class);
         project.setTenderStatus(TenderStatusEnum.DRAFT.getCode());
@@ -69,10 +81,15 @@
             project.setBiddingMode(tenderConfigService.getConfig().getDefaultBiddingMode());
         }
         tenderProjectMapper.insert(project);
+        // 缁戝畾璧勮川瑕佹眰闄勪欢
+        if (CollUtil.isNotEmpty(createReqVO.getBlobIds())) {
+            storageAttachmentApi.bindAttachments("file", TENDER_PROJECT_RECORD_TYPE, project.getId(), createReqVO.getBlobIds());
+        }
         return project.getId();
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     @LogRecord(type = LOG_TENDER_TYPE, subType = LOG_TENDER_UPDATE_SUB_TYPE,
             bizNo = "{{#updateReqVO.id}}", success = LOG_TENDER_UPDATE_SUCCESS)
     public void updateTenderProject(SrmTenderProjectSaveReqVO updateReqVO) {
@@ -84,6 +101,8 @@
             SrmTenderProjectDO updateObj = BeanUtils.toBean(updateReqVO, SrmTenderProjectDO.class);
             updateObj.setTenderStatus(status); // 鐘舵�佷笉鍏佽鍓嶇浼犲叆瑕嗙洊
             tenderProjectMapper.updateById(updateObj);
+            // 澧為噺鏇存柊璧勮川瑕佹眰闄勪欢
+            storageAttachmentApi.updateAttachments("file", TENDER_PROJECT_RECORD_TYPE, updateReqVO.getId(), updateReqVO.getBlobIds());
             LogRecordContext.putVariable("tenderName", project.getTenderName());
             LogRecordContext.putVariable("oldTenderDesc", project.getTenderDesc());
             LogRecordContext.putVariable("newTenderDesc", updateReqVO.getTenderDesc());
@@ -99,6 +118,8 @@
             updateObj.setTenderDesc(updateReqVO.getTenderDesc());
             updateObj.setQualificationRequirements(updateReqVO.getQualificationRequirements());
             tenderProjectMapper.updateById(updateObj);
+            // 澧為噺鏇存柊璧勮川瑕佹眰闄勪欢
+            storageAttachmentApi.updateAttachments("file", TENDER_PROJECT_RECORD_TYPE, updateReqVO.getId(), updateReqVO.getBlobIds());
             LogRecordContext.putVariable("tenderName", project.getTenderName());
             LogRecordContext.putVariable("oldTenderDesc", project.getTenderDesc());
             LogRecordContext.putVariable("newTenderDesc", updateReqVO.getTenderDesc());
@@ -112,6 +133,7 @@
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void deleteTenderProject(Long id) {
         SrmTenderProjectDO project = validateTenderExists(id);
         if (!TenderStatusEnum.DRAFT.getCode().equals(project.getTenderStatus())) {
@@ -121,6 +143,8 @@
         if (tenderBidMapper.countByTenderProjectId(id) > 0) {
             throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_HAS_BIDS_CANNOT_DELETE);
         }
+        // 鍒犻櫎璧勮川瑕佹眰闄勪欢
+        storageAttachmentApi.deleteAttachmentsByRecord(TENDER_PROJECT_RECORD_TYPE, id);
         tenderMaterialMapper.deleteByTenderProjectId(id);
         tenderProjectMapper.deleteById(id);
     }
@@ -284,6 +308,9 @@
             throw ServiceExceptionUtil.exception(ErrorCodeConstants.AWARD_SUPPLIER_NOT_SYNCED);
         }
 
+        // 渚涘簲鍟嗘湭鍑嗗叆鍒欒嚜鍔ㄥ噯鍏ュ苟閫氳繃锛屼繚璇侀噰璐鍗曟祦绋嬪彲鐢�
+        supplierApplyService.ensureSupplierApproved(supplier.getId());
+
         // 鏌ユ嫑鏍囩墿鏂�
         List<SrmTenderMaterialDO> materials = tenderMaterialMapper
                 .selectListByTenderProjectId(award.getTenderProjectId());
@@ -368,6 +395,7 @@
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     @LogRecord(type = LOG_TENDER_TYPE, subType = LOG_TENDER_UPDATE_SUB_TYPE,
             bizNo = "{{#updateReqVO.id}}", success = LOG_TENDER_UPDATE_SUCCESS)
     public void updateTenderProjectPartial(SrmTenderProjectPartialUpdateReqVO updateReqVO) {
@@ -380,6 +408,8 @@
         updateObj.setTenderDesc(updateReqVO.getTenderDesc());
         updateObj.setQualificationRequirements(updateReqVO.getQualificationRequirements());
         tenderProjectMapper.updateById(updateObj);
+        // 澧為噺鏇存柊璧勮川瑕佹眰闄勪欢
+        storageAttachmentApi.updateAttachments("file", TENDER_PROJECT_RECORD_TYPE, updateReqVO.getId(), updateReqVO.getBlobIds());
         LogRecordContext.putVariable("tenderName", project.getTenderName());
         LogRecordContext.putVariable("oldTenderDesc", project.getTenderDesc());
         LogRecordContext.putVariable("newTenderDesc", updateReqVO.getTenderDesc());
diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/enums/storage/StorageRecordTypeEnum.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/enums/storage/StorageRecordTypeEnum.java
index 599e513..0806302 100644
--- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/enums/storage/StorageRecordTypeEnum.java
+++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/enums/storage/StorageRecordTypeEnum.java
@@ -60,7 +60,11 @@
     AFTER_SALE_RETURN("aftersales_after_sale_return", "鍞悗閫�璐х敵璇�"),
 
     // ===== MES =====
-    MES_PD_DOCUMENT("mes_pd_document", "MES 璁捐璧勬枡");
+    MES_PD_DOCUMENT("mes_pd_document", "MES 璁捐璧勬枡"),
+
+    // ===== SRM =====
+    SRM_SUPPLIER_CERTIFICATE("srm_supplier_certificate", "SRM 渚涘簲鍟嗚祫璐ㄨ瘉涔�"),
+    SRM_TENDER_PROJECT("srm_tender_project", "SRM 鎷涙爣椤圭洰");
 
     private final String type;
     private final String description;

--
Gitblit v1.9.3