From f0c9b593769315001591cb4a759650a76b71cb8f Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期一, 03 八月 2026 17:55:56 +0800
Subject: [PATCH] feat(crm): 合同导出功能优化及状态中文展示
---
.playwright-mcp/page-2026-08-03T09-20-36-226Z.yml | 154 +++++++++
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/tender/SrmTenderProjectServiceImpl.java | 91 +++++
.playwright-mcp/page-2026-08-03T09-22-54-018Z.yml | 168 ++++++++++
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractRespVO.java | 57 +-
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/supplier/vo/SrmSupplierPageReqVO.java | 3
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/tender/SrmBidEvaluationServiceImpl.java | 43 ++
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/tender/vo/SrmTenderProjectPartialUpdateReqVO.java | 21 +
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemServiceImpl.java | 95 -----
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/tender/SrmTenderProjectController.java | 8
.playwright-mcp/page-2026-08-03T09-22-30-620Z.yml | 17 +
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/tender/SrmTenderProjectService.java | 2
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/item/MesMdItemController.java | 29 -
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java | 14
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/tender/SrmTenderBidServiceImpl.java | 48 ++
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/dal/mysql/SrmTenderBidMapper.java | 5
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/enums/TenderStatusEnum.java | 37 ++
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/tender/SrmBidAwardServiceImpl.java | 38 +
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/enums/ErrorCodeConstants.java | 11
.playwright-mcp/page-2026-08-03T09-20-27-740Z.yml | 1
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/dal/mysql/SrmSupplierMapper.java | 3
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/enums/common/CrmAuditStatusEnum.java | 8
/dev/null | 24 -
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java | 1
.playwright-mcp/page-2026-08-03T09-22-42-679Z.yml | 1
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemService.java | 11
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/enums/LogRecordConstants.java | 45 ++
.playwright-mcp/page-2026-08-03T09-16-38-621Z.yml | 1
yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/item/MdmItemController.java | 12
28 files changed, 731 insertions(+), 217 deletions(-)
diff --git a/.playwright-mcp/page-2026-08-03T09-16-38-621Z.yml b/.playwright-mcp/page-2026-08-03T09-16-38-621Z.yml
new file mode 100644
index 0000000..6adf37e
--- /dev/null
+++ b/.playwright-mcp/page-2026-08-03T09-16-38-621Z.yml
@@ -0,0 +1 @@
+- generic [active]: 宸ヤ笟AI鏅洪�犲钩鍙�
\ No newline at end of file
diff --git a/.playwright-mcp/page-2026-08-03T09-20-27-740Z.yml b/.playwright-mcp/page-2026-08-03T09-20-27-740Z.yml
new file mode 100644
index 0000000..6adf37e
--- /dev/null
+++ b/.playwright-mcp/page-2026-08-03T09-20-27-740Z.yml
@@ -0,0 +1 @@
+- generic [active]: 宸ヤ笟AI鏅洪�犲钩鍙�
\ No newline at end of file
diff --git a/.playwright-mcp/page-2026-08-03T09-20-36-226Z.yml b/.playwright-mcp/page-2026-08-03T09-20-36-226Z.yml
new file mode 100644
index 0000000..1e8a48e
--- /dev/null
+++ b/.playwright-mcp/page-2026-08-03T09-20-36-226Z.yml
@@ -0,0 +1,154 @@
+- generic [ref=f1e7]:
+ - complementary [ref=f1e8]:
+ - generic [ref=f1e9]:
+ - 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]: 鍗忓悓鍔炲叕
+ - listitem [ref=f1e92]:
+ - generic [ref=f1e93] [cursor=pointer]: 浜哄姏璧勬簮
+ - listitem [ref=f1e99]:
+ - generic [ref=f1e100] [cursor=pointer]: 鍞悗绠$悊
+ - listitem [ref=f1e106]:
+ - generic [ref=f1e107] [cursor=pointer]: 鍩虹璁炬柦
+ - listitem [ref=f1e113]:
+ - generic [ref=f1e114] [cursor=pointer]: 绯荤粺绠$悊
+ - listitem [ref=f1e120]:
+ - generic [ref=f1e121] [cursor=pointer]: IM 鍗虫椂閫氳
+ - generic [ref=f1e134]:
+ - generic [ref=f1e135]:
+ - banner [ref=f1e136]:
+ - button [ref=f1e137] [cursor=pointer]
+ - button [ref=f1e140] [cursor=pointer]
+ - navigation "breadcrumb" [ref=f1e145]:
+ - list [ref=f1e146]:
+ - listitem [ref=f1e147]:
+ - link [disabled] [ref=f1e148]
+ - generic [ref=f1e155]:
+ - generic [ref=f1e157] [cursor=pointer]:
+ - generic [ref=f1e161]: 鎼滅储
+ - generic [ref=f1e162]: Ctrl K
+ - button [ref=f1e164] [cursor=pointer]
+ - button "dark" [ref=f1e169] [cursor=pointer]
+ - button [ref=f1e178] [cursor=pointer]
+ - button [ref=f1e184] [cursor=pointer]
+ - button [ref=f1e187] [cursor=pointer]
+ - button [ref=f1e193] [cursor=pointer]:
+ - button [ref=f1e195]
+ - button "宸ヤ綔鍙�" [ref=f1e199] [cursor=pointer]
+ - button [ref=f1e203] [cursor=pointer]:
+ - img "鑺嬮亾婧愮爜" [ref=f1e208]
+ - generic [ref=f1e210]:
+ - generic [ref=f1e211]: 棣栭〉
+ - button [ref=f1e233] [cursor=pointer]
+ - main [ref=f1e251]:
+ - generic [ref=f1e254]:
+ - generic [ref=f1e255]:
+ - generic [ref=f1e256]:
+ - heading "涓嬪崍濂斤紝娆㈣繋鍥炴潵" [level=1] [ref=f1e257]
+ - paragraph [ref=f1e258]: 2026骞�8鏈�3鏃� 鏄熸湡涓�
+ - generic [ref=f1e259]: 绯荤粺杩愯涓�
+ - generic [ref=f1e264]:
+ - generic [ref=f1e273] [cursor=pointer]:
+ - generic [ref=f1e274]: 鐢熶骇璁㈠崟
+ - generic [ref=f1e275]:
+ - generic [ref=f1e276]: "25"
+ - generic [ref=f1e278]: 杩涜涓�
+ - generic [ref=f1e279]:
+ - text: 寰呮帓浜� 15
+ - generic [ref=f1e281]: "|"
+ - text: 宸插畬鎴� 5
+ - generic [ref=f1e293] [cursor=pointer]:
+ - generic [ref=f1e294]: 浠婃棩浜ч噺
+ - generic [ref=f1e295]:
+ - generic [ref=f1e296]: "0"
+ - generic [ref=f1e298]: 浠�
+ - generic [ref=f1e299]: 鏄ㄦ棩 0 浠�
+ - generic [ref=f1e310] [cursor=pointer]:
+ - generic [ref=f1e311]: 璐ㄩ噺鍚堟牸鐜�
+ - generic [ref=f1e312]:
+ - generic [ref=f1e313]: "0.0"
+ - generic [ref=f1e315]: "%"
+ - generic [ref=f1e316]: 鍚堟牸 0 | 涓嶈壇 0
+ - generic [ref=f1e328] [cursor=pointer]:
+ - generic [ref=f1e329]: 璁惧杩愯鐜�
+ - generic [ref=f1e330]:
+ - generic [ref=f1e331]: "100.0"
+ - generic [ref=f1e333]: "%"
+ - generic [ref=f1e334]:
+ - generic [ref=f1e335]: 鍋滄満 0
+ - generic [ref=f1e336]: "|"
+ - generic [ref=f1e337]: 缁存姢 0
+ - generic [ref=f1e340]:
+ - generic [ref=f1e350] [cursor=pointer]:
+ - generic [ref=f1e351]: 閲囪喘璁㈠崟
+ - generic [ref=f1e352]:
+ - generic [ref=f1e353]: "14"
+ - generic [ref=f1e355]: 绗�
+ - generic [ref=f1e356]: ERP 閲囪喘绠$悊
+ - generic [ref=f1e367] [cursor=pointer]:
+ - generic [ref=f1e368]: 閿�鍞鍗�
+ - generic [ref=f1e369]:
+ - generic [ref=f1e370]: "22"
+ - generic [ref=f1e372]: 绗�
+ - generic [ref=f1e373]: ERP 閿�鍞鐞�
+ - generic [ref=f1e385] [cursor=pointer]:
+ - generic [ref=f1e386]: 鐗╂枡搴撳瓨
+ - generic [ref=f1e387]:
+ - generic [ref=f1e388]: "13"
+ - generic [ref=f1e390]: 鏉�
+ - generic [ref=f1e391]: MES 搴撳瓨鍙拌处
+ - generic [ref=f1e403] [cursor=pointer]:
+ - generic [ref=f1e404]: 鎴戠殑寰呭姙
+ - generic [ref=f1e405]:
+ - generic [ref=f1e406]: "1"
+ - generic [ref=f1e408]: 椤�
+ - generic [ref=f1e409]: BPM 寰呭鎵�
+ - generic [ref=f1e413]:
+ - heading "AI 鏅鸿兘鍒嗘瀽" [level=3] [ref=f1e414]
+ - generic [ref=f1e415]: 25 涓伐鍗曞彲鍒嗘瀽
+ - generic [ref=f1e416]:
+ - heading "鐢熶骇瓒嬪娍锛堣繎7澶╋級" [level=3] [ref=f1e419]
+ - generic [ref=f1e424]:
+ - generic [ref=f1e425]:
+ - generic [ref=f1e431] [cursor=pointer]:
+ - generic [ref=f1e432]: 瀹夌伅鍛煎彨
+ - generic [ref=f1e433]:
+ - generic [ref=f1e434]: "0"
+ - generic [ref=f1e436]: 鏈缃�
+ - generic [ref=f1e442] [cursor=pointer]:
+ - generic [ref=f1e443]: 缁翠慨宸ュ崟
+ - generic [ref=f1e444]:
+ - generic [ref=f1e445]: "0"
+ - generic [ref=f1e447]: 寰呭鐞�
+ - heading "宸ュ崟鐘舵�佸垎甯�" [level=4] [ref=f1e449]
+ - generic [ref=f1e457]:
+ - heading "蹇嵎鎿嶄綔" [level=3] [ref=f1e458]
+ - generic [ref=f1e459]:
+ - generic [ref=f1e460] [cursor=pointer]: 鐢熶骇宸ュ崟
+ - generic [ref=f1e463] [cursor=pointer]: 鐢熶骇鎶ュ伐
+ - generic [ref=f1e466] [cursor=pointer]: 璐ㄦ绠$悊
+ - generic [ref=f1e469] [cursor=pointer]: 璁惧鐐规
+ - generic [ref=f1e472] [cursor=pointer]: 鐢熶骇鎺掔▼
+ - generic [ref=f1e475] [cursor=pointer]: 瀹夌伅鍛煎彨
+ - generic [ref=f1e478] [cursor=pointer]: 鐗╂枡搴撳瓨
+ - generic [ref=f1e481] [cursor=pointer]: 宸ヨ壓璺嚎
+ - generic [ref=f1e484] [cursor=pointer]: 鏁版嵁鎶ヨ〃
\ No newline at end of file
diff --git a/.playwright-mcp/page-2026-08-03T09-22-30-620Z.yml b/.playwright-mcp/page-2026-08-03T09-22-30-620Z.yml
new file mode 100644
index 0000000..a7a7ba4
--- /dev/null
+++ b/.playwright-mcp/page-2026-08-03T09-22-30-620Z.yml
@@ -0,0 +1,17 @@
+- generic [ref=f2e3]:
+ - generic [ref=f2e6]:
+ - heading "鏃犳硶璁块棶姝ょ綉绔�" [level=1] [ref=f2e7]
+ - paragraph [ref=f2e8]:
+ - strong [ref=f2e9]: localhost
+ - text: 鎷掔粷浜嗘垜浠殑杩炴帴璇锋眰銆�
+ - generic [ref=f2e10]:
+ - paragraph [ref=f2e11]: 璇疯瘯璇曚互涓嬪姙娉曪細
+ - list [ref=f2e12]:
+ - listitem [ref=f2e13]: 妫�鏌ョ綉缁滆繛鎺�
+ - listitem [ref=f2e14]:
+ - link "妫�鏌ヤ唬鐞嗘湇鍔″櫒鍜岄槻鐏" [ref=f2e15] [cursor=pointer]:
+ - /url: "#buttons"
+ - generic [ref=f2e16]: ERR_CONNECTION_REFUSED
+ - generic [ref=f2e17]:
+ - button "閲嶆柊鍔犺浇" [ref=f2e19] [cursor=pointer]
+ - button "璇︽儏" [ref=f2e20] [cursor=pointer]
\ No newline at end of file
diff --git a/.playwright-mcp/page-2026-08-03T09-22-42-679Z.yml b/.playwright-mcp/page-2026-08-03T09-22-42-679Z.yml
new file mode 100644
index 0000000..6adf37e
--- /dev/null
+++ b/.playwright-mcp/page-2026-08-03T09-22-42-679Z.yml
@@ -0,0 +1 @@
+- generic [active]: 宸ヤ笟AI鏅洪�犲钩鍙�
\ No newline at end of file
diff --git a/.playwright-mcp/page-2026-08-03T09-22-54-018Z.yml b/.playwright-mcp/page-2026-08-03T09-22-54-018Z.yml
new file mode 100644
index 0000000..0107202
--- /dev/null
+++ b/.playwright-mcp/page-2026-08-03T09-22-54-018Z.yml
@@ -0,0 +1,168 @@
+- generic [ref=f3e7]:
+ - complementary [ref=f3e8]:
+ - generic [ref=f3e9]:
+ - link "宸ヤ笟AI鏅洪�犲钩鍙� 宸ヤ笟AI鏅洪�犲钩鍙�" [ref=f3e15] [cursor=pointer]:
+ - /url: javascript:void 0
+ - img "宸ヤ笟AI鏅洪�犲钩鍙�" [ref=f3e18]
+ - generic [ref=f3e19]: 宸ヤ笟AI鏅洪�犲钩鍙�
+ - menu [ref=f3e22]:
+ - menuitem "棣栭〉" [ref=f3e23] [cursor=pointer]
+ - listitem [ref=f3e30]:
+ - generic [ref=f3e31] [cursor=pointer]: 鍩虹鏁版嵁
+ - listitem [ref=f3e39]:
+ - generic [ref=f3e40] [cursor=pointer]: 閲囪喘绠$悊
+ - listitem [ref=f3e46]:
+ - generic [ref=f3e47] [cursor=pointer]: 钀ラ攢绠$悊
+ - listitem [ref=f3e53]:
+ - generic [ref=f3e54] [cursor=pointer]: 璁惧绠$悊
+ - listitem [ref=f3e61]:
+ - generic [ref=f3e62] [cursor=pointer]: 浠撳偍鐗╂祦
+ - listitem [ref=f3e70]:
+ - generic [ref=f3e71] [cursor=pointer]: 鐢熶骇绠℃帶
+ - listitem [ref=f3e78]:
+ - generic [ref=f3e79] [cursor=pointer]: 璐ㄩ噺绠$悊
+ - listitem [ref=f3e85]:
+ - generic [ref=f3e86] [cursor=pointer]: 鍗忓悓鍔炲叕
+ - listitem [ref=f3e92]:
+ - generic [ref=f3e93] [cursor=pointer]: 浜哄姏璧勬簮
+ - listitem [ref=f3e99]:
+ - generic [ref=f3e100] [cursor=pointer]: 鍞悗绠$悊
+ - listitem [ref=f3e106]:
+ - generic [ref=f3e107] [cursor=pointer]: 鍩虹璁炬柦
+ - listitem [ref=f3e113]:
+ - generic [ref=f3e114] [cursor=pointer]: 绯荤粺绠$悊
+ - listitem [ref=f3e120]:
+ - generic [ref=f3e121] [cursor=pointer]: IM 鍗虫椂閫氳
+ - generic [ref=f3e134]:
+ - generic [ref=f3e135]:
+ - banner [ref=f3e136]:
+ - button [ref=f3e137] [cursor=pointer]
+ - button [ref=f3e140] [cursor=pointer]
+ - navigation "breadcrumb" [ref=f3e145]:
+ - list [ref=f3e146]:
+ - listitem [ref=f3e147]:
+ - link [disabled] [ref=f3e148]
+ - generic [ref=f3e155]:
+ - generic [ref=f3e157] [cursor=pointer]:
+ - generic [ref=f3e161]: 鎼滅储
+ - generic [ref=f3e162]: Ctrl K
+ - button [ref=f3e164] [cursor=pointer]
+ - button "dark" [ref=f3e169] [cursor=pointer]
+ - button [ref=f3e178] [cursor=pointer]
+ - button [ref=f3e184] [cursor=pointer]
+ - button [ref=f3e187] [cursor=pointer]
+ - button [ref=f3e193] [cursor=pointer]:
+ - button [ref=f3e195]
+ - button "宸ヤ綔鍙�" [ref=f3e199] [cursor=pointer]
+ - button [ref=f3e203] [cursor=pointer]:
+ - img "鑺嬮亾婧愮爜" [ref=f3e208]
+ - generic [ref=f3e210]:
+ - generic [ref=f3e211]: 棣栭〉
+ - button [ref=f3e233] [cursor=pointer]
+ - main [ref=f3e251]:
+ - generic [ref=f3e254]:
+ - generic [ref=f3e255]:
+ - generic [ref=f3e256]:
+ - heading "涓嬪崍濂斤紝娆㈣繋鍥炴潵" [level=1] [ref=f3e257]
+ - paragraph [ref=f3e258]: 2026骞�8鏈�3鏃� 鏄熸湡涓�
+ - generic [ref=f3e259]: 绯荤粺杩愯涓�
+ - generic [ref=f3e264]:
+ - generic [ref=f3e273] [cursor=pointer]:
+ - generic [ref=f3e274]: 鐢熶骇璁㈠崟
+ - generic [ref=f3e275]:
+ - generic [ref=f3e276]: "25"
+ - generic [ref=f3e278]: 杩涜涓�
+ - generic [ref=f3e279]:
+ - text: 寰呮帓浜� 15
+ - generic [ref=f3e281]: "|"
+ - text: 宸插畬鎴� 5
+ - generic [ref=f3e293] [cursor=pointer]:
+ - generic [ref=f3e294]: 浠婃棩浜ч噺
+ - generic [ref=f3e295]:
+ - generic [ref=f3e296]: "0"
+ - generic [ref=f3e298]: 浠�
+ - generic [ref=f3e299]: 鏄ㄦ棩 0 浠�
+ - generic [ref=f3e310] [cursor=pointer]:
+ - generic [ref=f3e311]: 璐ㄩ噺鍚堟牸鐜�
+ - generic [ref=f3e312]:
+ - generic [ref=f3e313]: "0.0"
+ - generic [ref=f3e315]: "%"
+ - generic [ref=f3e316]: 鍚堟牸 0 | 涓嶈壇 0
+ - generic [ref=f3e328] [cursor=pointer]:
+ - generic [ref=f3e329]: 璁惧杩愯鐜�
+ - generic [ref=f3e330]:
+ - generic [ref=f3e331]: "100.0"
+ - generic [ref=f3e333]: "%"
+ - generic [ref=f3e334]:
+ - generic [ref=f3e335]: 鍋滄満 0
+ - generic [ref=f3e336]: "|"
+ - generic [ref=f3e337]: 缁存姢 0
+ - generic [ref=f3e340]:
+ - generic [ref=f3e350] [cursor=pointer]:
+ - generic [ref=f3e351]: 閲囪喘璁㈠崟
+ - generic [ref=f3e352]:
+ - generic [ref=f3e353]: "14"
+ - generic [ref=f3e355]: 绗�
+ - generic [ref=f3e356]: ERP 閲囪喘绠$悊
+ - generic [ref=f3e367] [cursor=pointer]:
+ - generic [ref=f3e368]: 閿�鍞鍗�
+ - generic [ref=f3e369]:
+ - generic [ref=f3e370]: "22"
+ - generic [ref=f3e372]: 绗�
+ - generic [ref=f3e373]: ERP 閿�鍞鐞�
+ - generic [ref=f3e385] [cursor=pointer]:
+ - generic [ref=f3e386]: 鐗╂枡搴撳瓨
+ - generic [ref=f3e387]:
+ - generic [ref=f3e388]: "13"
+ - generic [ref=f3e390]: 鏉�
+ - generic [ref=f3e391]: MES 搴撳瓨鍙拌处
+ - generic [ref=f3e403] [cursor=pointer]:
+ - generic [ref=f3e404]: 鎴戠殑寰呭姙
+ - generic [ref=f3e405]:
+ - generic [ref=f3e406]: "1"
+ - generic [ref=f3e408]: 椤�
+ - generic [ref=f3e409]: BPM 寰呭鎵�
+ - generic [ref=f3e412]:
+ - generic [ref=f3e413]:
+ - heading "AI 鏅鸿兘鍒嗘瀽" [level=3] [ref=f3e414]
+ - generic [ref=f3e415]: 25 涓伐鍗曞彲鍒嗘瀽
+ - generic [ref=f3e416]:
+ - generic [ref=f3e424] [cursor=pointer]:
+ - generic [ref=f3e425]: AI 鐗╂枡棰勬祴
+ - generic [ref=f3e426]: 棰勬祴鐗╂枡闇�姹備笌鐭己椋庨櫓
+ - generic [ref=f3e435] [cursor=pointer]:
+ - generic [ref=f3e436]: AI 鏃堕暱棰勬祴
+ - generic [ref=f3e437]: 棰勬祴鍚勫伐搴忕敓浜ц�楁椂
+ - generic [ref=f3e444] [cursor=pointer]:
+ - generic [ref=f3e445]: AI 椋庨櫓棰勬祴
+ - generic [ref=f3e446]: 璇嗗埆娼滃湪鐢熶骇椋庨櫓骞剁粰鍑哄缓璁�
+ - generic [ref=f3e456] [cursor=pointer]:
+ - generic [ref=f3e457]: AI 浜や粯璇勪及
+ - generic [ref=f3e458]: 璇勪及璁㈠崟浜や粯鍑嗘椂鐜囦笌寤舵湡鍥犵礌
+ - generic [ref=f3e461]:
+ - heading "鐢熶骇瓒嬪娍锛堣繎7澶╋級" [level=3] [ref=f3e464]
+ - generic [ref=f3e469]:
+ - generic [ref=f3e470]:
+ - generic [ref=f3e476] [cursor=pointer]:
+ - generic [ref=f3e477]: 瀹夌伅鍛煎彨
+ - generic [ref=f3e478]:
+ - generic [ref=f3e479]: "0"
+ - generic [ref=f3e481]: 鏈缃�
+ - generic [ref=f3e487] [cursor=pointer]:
+ - generic [ref=f3e488]: 缁翠慨宸ュ崟
+ - generic [ref=f3e489]:
+ - generic [ref=f3e490]: "0"
+ - generic [ref=f3e492]: 寰呭鐞�
+ - heading "宸ュ崟鐘舵�佸垎甯�" [level=4] [ref=f3e494]
+ - generic [ref=f3e502]:
+ - heading "蹇嵎鎿嶄綔" [level=3] [ref=f3e503]
+ - generic [ref=f3e504]:
+ - generic [ref=f3e505] [cursor=pointer]: 鐢熶骇宸ュ崟
+ - generic [ref=f3e512] [cursor=pointer]: 鐢熶骇鎶ュ伐
+ - generic [ref=f3e519] [cursor=pointer]: 璐ㄦ绠$悊
+ - generic [ref=f3e527] [cursor=pointer]: 璁惧鐐规
+ - generic [ref=f3e534] [cursor=pointer]: 鐢熶骇鎺掔▼
+ - generic [ref=f3e541] [cursor=pointer]: 瀹夌伅鍛煎彨
+ - generic [ref=f3e546] [cursor=pointer]: 鐗╂枡搴撳瓨
+ - generic [ref=f3e554] [cursor=pointer]: 宸ヨ壓璺嚎
+ - generic [ref=f3e562] [cursor=pointer]: 鏁版嵁鎶ヨ〃
\ No newline at end of file
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java
index 555ccd3..4de695d 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java
@@ -19,6 +19,7 @@
import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractProductDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
+import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService;
@@ -159,9 +160,18 @@
public void exportContractExcel(@Valid CrmContractPageReqVO exportReqVO,
HttpServletResponse response) throws IOException {
PageResult<CrmContractDO> pageResult = contractService.getContractPage(exportReqVO, getLoginUserId());
+ List<CrmContractRespVO> list = BeanUtils.toBean(pageResult.getList(), CrmContractRespVO.class);
+ // 璁$畻鏈洖娆鹃噾棰濄�佽浆鎹㈠鎵圭姸鎬佷负涓枃
+ list.forEach(vo -> {
+ if (vo.getTotalPrice() != null && vo.getTotalReceivablePrice() != null) {
+ vo.setUnReceivablePrice(vo.getTotalPrice().subtract(vo.getTotalReceivablePrice()));
+ }
+ if (vo.getAuditStatus() != null) {
+ vo.setAuditStatusName(CrmAuditStatusEnum.getNameByStatus(vo.getAuditStatus()));
+ }
+ });
// 瀵煎嚭 Excel
- ExcelUtils.write(response, "鍚堝悓.xls", "鏁版嵁", CrmContractRespVO.class,
- BeanUtils.toBean(pageResult.getList(), CrmContractRespVO.class));
+ ExcelUtils.write(response, "鍚堝悓.xls", "鏁版嵁", CrmContractRespVO.class, list);
}
@PutMapping("/transfer")
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractRespVO.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractRespVO.java
index d33143d..4410428 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractRespVO.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractRespVO.java
@@ -17,121 +17,120 @@
public class CrmContractRespVO {
@Schema(description = "鍚堝悓缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
- @ExcelProperty("鍚堝悓缂栧彿")
private Long id;
@Schema(description = "鍚堝悓鍚嶇О", requiredMode = Schema.RequiredMode.REQUIRED, example = "鐜嬩簲")
- @ExcelProperty("鍚堝悓鍚嶇О")
+ @ExcelProperty(value = "鍚堝悓鍚嶇О", index = 1)
private String name;
@Schema(description = "鍚堝悓缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "20230101")
- @ExcelProperty("鍚堝悓缂栧彿")
+ @ExcelProperty(value = "鍚堝悓缂栧彿", index = 0)
private String no;
@Schema(description = "瀹㈡埛缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "18336")
- @ExcelProperty("瀹㈡埛缂栧彿")
private Long customerId;
@Schema(description = "瀹㈡埛鍚嶇О", requiredMode = Schema.RequiredMode.REQUIRED, example = "18336")
- @ExcelProperty("瀹㈡埛鍚嶇О")
+ @ExcelProperty(value = "瀹㈡埛鍚嶇О", index = 2)
private String customerName;
@Schema(description = "鍟嗘満缂栧彿", example = "10864")
- @ExcelProperty("鍟嗘満缂栧彿")
private Long businessId;
@Schema(description = "鍟嗘満鍚嶇О", example = "10864")
- @ExcelProperty("鍟嗘満鍚嶇О")
+ @ExcelProperty(value = "鍟嗘満鍚嶇О", index = 3)
private String businessName;
@Schema(description = "鏈�鍚庤窡杩涙椂闂�")
- @ExcelProperty("鏈�鍚庤窡杩涙椂闂�")
+ @ExcelProperty(value = "鏈�鍚庤窡杩涙椂闂�", index = 14)
private LocalDateTime contactLastTime;
@Schema(description = "璐熻矗浜虹殑鐢ㄦ埛缂栧彿", example = "25682")
- @ExcelProperty("璐熻矗浜虹殑鐢ㄦ埛缂栧彿")
private Long ownerUserId;
@Schema(description = "璐熻矗浜哄悕瀛�", example = "25682")
- @ExcelProperty("璐熻矗浜哄悕瀛�")
+ @ExcelProperty(value = "璐熻矗浜�", index = 15)
private String ownerUserName;
@Schema(description = "璐熻矗浜洪儴闂�")
- @ExcelProperty("璐熻矗浜洪儴闂�")
+ @ExcelProperty(value = "鎵�灞為儴闂�", index = 16)
private String ownerUserDeptName;
@Schema(description = "宸ヤ綔娴佺紪鍙�", example = "1043")
- @ExcelProperty("宸ヤ綔娴佺紪鍙�")
private String processInstanceId;
@Schema(description = "瀹℃壒鐘舵��", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
- @ExcelProperty("瀹℃壒鐘舵��")
private Integer auditStatus;
+ @Schema(description = "鍚堝悓鐘舵�佸悕绉�", example = "瀹℃壒涓�")
+ @ExcelProperty(value = "鍚堝悓鐘舵��", index = 20)
+ private String auditStatusName;
+
@Schema(description = "涓嬪崟鏃ユ湡", requiredMode = Schema.RequiredMode.REQUIRED)
- @ExcelProperty("涓嬪崟鏃ユ湡")
+ @ExcelProperty(value = "涓嬪崟鏃堕棿", index = 6)
private LocalDateTime orderDate;
@Schema(description = "寮�濮嬫椂闂�")
- @ExcelProperty("寮�濮嬫椂闂�")
+ @ExcelProperty(value = "鍚堝悓寮�濮嬫椂闂�", index = 7)
private LocalDateTime startTime;
@Schema(description = "缁撴潫鏃堕棿")
- @ExcelProperty("缁撴潫鏃堕棿")
+ @ExcelProperty(value = "鍚堝悓缁撴潫鏃堕棿", index = 8)
private LocalDateTime endTime;
@Schema(description = "浜у搧鎬婚噾棰�", example = "19510")
- @ExcelProperty("浜у搧鎬婚噾棰�")
private BigDecimal totalProductPrice;
@Schema(description = "鏁村崟鎶樻墸")
- @ExcelProperty("鏁村崟鎶樻墸")
private BigDecimal discountPercent;
@Schema(description = "鍚堝悓閲戦", example = "5617")
- @ExcelProperty("鍚堝悓閲戦")
+ @ExcelProperty(value = "鍚堝悓閲戦锛堝厓锛�", index = 4)
private BigDecimal totalPrice;
@Schema(description = "瀹氶噾閲戦锛屽崟浣嶏細鍏�", example = "1000.00")
- @ExcelProperty("瀹氶噾閲戦")
+ @ExcelProperty(value = "瀹氶噾閲戦锛堝厓锛�", index = 5)
private BigDecimal depositPrice;
@Schema(description = "宸插洖娆鹃噾棰�", example = "5617")
- @ExcelProperty("宸插洖娆鹃噾棰�")
+ @ExcelProperty(value = "宸插洖娆鹃噾棰濓紙鍏冿級", index = 12)
private BigDecimal totalReceivablePrice;
+
+ @Schema(description = "鏈洖娆鹃噾棰濓紝绛変簬 鍚堝悓閲戦 - 宸插洖娆鹃噾棰�", example = "1000.00")
+ @ExcelProperty(value = "鏈洖娆鹃噾棰濓紙鍏冿級", index = 13)
+ private BigDecimal unReceivablePrice;
@Schema(description = "鍏宠仈 ERP 閿�鍞鍗曠紪鍙�", example = "12345")
private Long orderId;
@Schema(description = "ERP 閿�鍞鍗曞崟鍙�", example = "SO001")
- @ExcelProperty("閿�鍞鍗曞崟鍙�")
+ @ExcelProperty(value = "鍏宠仈璁㈠崟", index = 21)
private String orderNo;
@Schema(description = "瀹㈡埛绛剧害浜虹紪鍙�", example = "18546")
private Long signContactId;
@Schema(description = "瀹㈡埛绛剧害浜�", example = "灏忚眴")
- @ExcelProperty("瀹㈡埛绛剧害浜�")
+ @ExcelProperty(value = "瀹㈡埛绛剧害浜�", index = 9)
private String signContactName;
@Schema(description = "鍏徃绛剧害浜�", example = "14036")
private Long signUserId;
@Schema(description = "鍏徃绛剧害浜�", example = "灏忔槑")
- @ExcelProperty("鍏徃绛剧害浜�")
+ @ExcelProperty(value = "鍏徃绛剧害浜�", index = 10)
private String signUserName;
@Schema(description = "澶囨敞", example = "浣犵寽")
- @ExcelProperty("澶囨敞")
+ @ExcelProperty(value = "澶囨敞", index = 11)
private String remark;
@Schema(description = "鍒涘缓鏃堕棿", requiredMode = Schema.RequiredMode.REQUIRED)
- @ExcelProperty("鍒涘缓鏃堕棿")
+ @ExcelProperty(value = "鍒涘缓鏃堕棿", index = 18)
private LocalDateTime createTime;
@Schema(description = "鍒涘缓浜�", example = "25682")
- @ExcelProperty("鍒涘缓浜�")
private String creator;
@Schema(description = "鍒涘缓浜哄悕瀛�", example = "test")
- @ExcelProperty("鍒涘缓浜哄悕瀛�")
+ @ExcelProperty(value = "鍒涘缓浜�", index = 19)
private String creatorName;
@Schema(description = "鏇存柊鏃堕棿", requiredMode = Schema.RequiredMode.REQUIRED)
- @ExcelProperty("鏇存柊鏃堕棿")
+ @ExcelProperty(value = "鏇存柊鏃堕棿", index = 17)
private LocalDateTime updateTime;
@Schema(description = "浜у搧鍒楄〃")
diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/enums/common/CrmAuditStatusEnum.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/enums/common/CrmAuditStatusEnum.java
index b23de46..394652d 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/enums/common/CrmAuditStatusEnum.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/enums/common/CrmAuditStatusEnum.java
@@ -27,6 +27,14 @@
public static final Integer[] ARRAYS = Arrays.stream(values()).map(CrmAuditStatusEnum::getStatus).toArray(Integer[]::new);
+ public static String getNameByStatus(Integer status) {
+ if (status == null) return null;
+ for (CrmAuditStatusEnum e : values()) {
+ if (e.getStatus().equals(status)) return e.getName();
+ }
+ return null;
+ }
+
@Override
public Integer[] array() {
return ARRAYS;
diff --git a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/item/MdmItemController.java b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/item/MdmItemController.java
index 1e51193..461e65e 100644
--- a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/item/MdmItemController.java
+++ b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/item/MdmItemController.java
@@ -189,7 +189,17 @@
@Operation(summary = "鑾峰彇鐗╂枡绮剧畝鍒楄〃锛堝惎鐢ㄧ姸鎬侊紝鐢ㄤ簬涓嬫媺閫夋嫨锛�")
public CommonResult<List<MdmItemRespVO>> getItemSimpleList() {
List<MdmItemDO> list = itemService.getItemSimpleList();
- return success(BeanUtils.toBean(list, MdmItemRespVO.class));
+ List<MdmItemRespVO> respList = BeanUtils.toBean(list, MdmItemRespVO.class);
+ // 濉厖鍗曚綅鍚嶇О绛夊叧鑱斿瓧娈碉紝纭繚涓嬫媺閫夋嫨鍚庡彲甯﹀嚭鍗曚綅绛変俊鎭�
+ Map<Long, MdmUnitMeasureDO> unitMap = unitMeasureService.getUnitMeasureMap(
+ convertSet(respList, MdmItemRespVO::getUnitMeasureId));
+ respList.forEach(resp -> {
+ MdmUnitMeasureDO unit = unitMap.get(resp.getUnitMeasureId());
+ if (unit != null) {
+ resp.setUnitMeasureName(unit.getName());
+ }
+ });
+ return success(respList);
}
/**
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/item/MesMdItemController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/item/MesMdItemController.java
index b9d9492..1e58218 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/item/MesMdItemController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/item/MesMdItemController.java
@@ -8,8 +8,6 @@
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
-import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.MesMdItemImportExcelVO;
-import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.MesMdItemImportRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.MesMdItemPageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.MesMdItemRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.MesMdItemSaveReqVO;
@@ -29,7 +27,6 @@
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
-import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.Collections;
@@ -118,32 +115,6 @@
// 瀵煎嚭 Excel
ExcelUtils.write(response, "鐗╂枡浜у搧.xls", "鏁版嵁", MesMdItemRespVO.class,
buildItemVOList(pageResult.getList()));
- }
-
- @GetMapping("/get-import-template")
- @Operation(summary = "鑾峰緱鐗╂枡瀵煎叆妯℃澘")
- public void importTemplate(HttpServletResponse response) throws IOException {
- // 鎵嬪姩鍒涘缓瀵煎嚭 demo
- List<MesMdItemImportExcelVO> list = Collections.singletonList(
- MesMdItemImportExcelVO.builder().code("ITEM001").name("铻轰笣").specification("M6*20")
- .unitMeasureCode("PCS").itemTypeId(1L).status(0).build()
- );
- // 杈撳嚭
- ExcelUtils.write(response, "鐗╂枡瀵煎叆妯℃澘.xls", "鐗╂枡鍒楄〃", MesMdItemImportExcelVO.class, list);
- }
-
- @PostMapping("/import")
- @Operation(summary = "瀵煎叆鐗╂枡")
- @Parameters({
- @Parameter(name = "file", description = "Excel 鏂囦欢", required = true),
- @Parameter(name = "updateSupport", description = "鏄惁鏀寔鏇存柊锛岄粯璁や负 false", example = "true")
- })
- @PreAuthorize("@ss.hasPermission('mes:md-item:import')")
- public CommonResult<MesMdItemImportRespVO> importExcel(@RequestParam("file") MultipartFile file,
- @RequestParam(value = "updateSupport", required = false,
- defaultValue = "false") Boolean updateSupport) throws Exception {
- List<MesMdItemImportExcelVO> list = ExcelUtils.read(file, MesMdItemImportExcelVO.class);
- return success(itemService.importItemList(list, updateSupport));
}
// ==================== 鎷兼帴 VO ====================
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/item/vo/MesMdItemImportExcelVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/item/vo/MesMdItemImportExcelVO.java
deleted file mode 100644
index dee51f7..0000000
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/item/vo/MesMdItemImportExcelVO.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package cn.iocoder.yudao.module.mes.controller.admin.md.item.vo;
-
-import cn.idev.excel.annotation.ExcelProperty;
-import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
-import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
-import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.math.BigDecimal;
-
-/**
- * 鐗╂枡浜у搧 Excel 瀵煎叆 VO
- */
-@Data
-@Builder
-@AllArgsConstructor
-@NoArgsConstructor
-public class MesMdItemImportExcelVO {
-
- @ExcelProperty("鐗╂枡缂栫爜")
- private String code;
-
- @ExcelProperty("鐗╂枡鍚嶇О")
- private String name;
-
- @ExcelProperty("瑙勬牸鍨嬪彿")
- private String specification;
-
- @ExcelProperty("鍗曚綅缂栫爜")
- private String unitMeasureCode;
-
- @ExcelProperty("鐗╂枡鍒嗙被缂栧彿")
- private Long itemTypeId;
-
- @ExcelProperty(value = "鐘舵��", converter = DictConvert.class)
- @DictFormat(DictTypeConstants.COMMON_STATUS)
- private Integer status;
-
- @ExcelProperty("鏄惁鍚敤瀹夊叏搴撳瓨")
- private Boolean safeStockFlag;
-
- @ExcelProperty("鏈�浣庡簱瀛橀噺")
- private BigDecimal minStock;
-
- @ExcelProperty("鏈�楂樺簱瀛橀噺")
- private BigDecimal maxStock;
-
- @ExcelProperty("鏄惁楂樺�肩墿鏂�")
- private Boolean highValue;
-
- @ExcelProperty("鏄惁鍚敤鎵规绠$悊")
- private Boolean batchFlag;
-
- @ExcelProperty("澶囨敞")
- private String remark;
-
-}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/item/vo/MesMdItemImportRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/item/vo/MesMdItemImportRespVO.java
deleted file mode 100644
index de3f51b..0000000
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/item/vo/MesMdItemImportRespVO.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package cn.iocoder.yudao.module.mes.controller.admin.md.item.vo;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Builder;
-import lombok.Data;
-
-import java.util.List;
-import java.util.Map;
-
-@Schema(description = "绠$悊鍚庡彴 - MES 鐗╂枡浜у搧瀵煎叆 Response VO")
-@Data
-@Builder
-public class MesMdItemImportRespVO {
-
- @Schema(description = "鍒涘缓鎴愬姛鐨勭墿鏂欑紪鐮佹暟缁�", requiredMode = Schema.RequiredMode.REQUIRED)
- private List<String> createCodes;
-
- @Schema(description = "鏇存柊鎴愬姛鐨勭墿鏂欑紪鐮佹暟缁�", requiredMode = Schema.RequiredMode.REQUIRED)
- private List<String> updateCodes;
-
- @Schema(description = "瀵煎叆澶辫触鐨勭墿鏂欓泦鍚堬紝key 涓虹墿鏂欑紪鐮侊紝value 涓哄け璐ュ師鍥�", requiredMode = Schema.RequiredMode.REQUIRED)
- private Map<String, String> failureCodes;
-
-}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
index eb2ae1a..5c661bc 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
@@ -33,7 +33,6 @@
ErrorCode MD_ITEM_NOT_EXISTS = new ErrorCode(1_040_102_000, "鐗╂枡涓嶅瓨鍦�");
ErrorCode MD_ITEM_CODE_DUPLICATE = new ErrorCode(1_040_102_001, "鐗╂枡缂栫爜宸插瓨鍦�");
ErrorCode MD_ITEM_NAME_DUPLICATE = new ErrorCode(1_040_102_002, "鐗╂枡鍚嶇О宸插瓨鍦�");
- ErrorCode MD_ITEM_IMPORT_LIST_IS_EMPTY = new ErrorCode(1_040_102_003, "瀵煎叆鐗╂枡鏁版嵁涓嶈兘涓虹┖");
ErrorCode MD_ITEM_BATCH_REQUIRED = new ErrorCode(1_040_102_004, "褰撳墠鐗╂枡鍚敤浜嗘壒娆$鐞嗭紝璇烽�夋嫨鎵规");
ErrorCode MD_ITEM_IS_DISABLE = new ErrorCode(1_040_102_005, "鐗╂枡宸茬鐢�");
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemService.java
index a8b407a..5159a16 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemService.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemService.java
@@ -1,8 +1,6 @@
package cn.iocoder.yudao.module.mes.service.md.item;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.MesMdItemImportExcelVO;
-import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.MesMdItemImportRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.MesMdItemPageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.MesMdItemSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
@@ -116,15 +114,6 @@
* @return 鐗╂枡鏁伴噺
*/
Long getItemCountByItemTypeId(Long itemTypeId);
-
- /**
- * 鎵归噺瀵煎叆鐗╂枡
- *
- * @param importItems 瀵煎叆鐗╂枡鍒楄〃
- * @param updateSupport 鏄惁鏀寔鏇存柊
- * @return 瀵煎叆缁撴灉
- */
- MesMdItemImportRespVO importItemList(List<MesMdItemImportExcelVO> importItems, boolean updateSupport);
/**
* 鍩轰簬璁¢噺鍗曚綅缂栧彿锛岃幏寰楃墿鏂欐暟閲�
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemServiceImpl.java
index c8f85a6..fcefee0 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemServiceImpl.java
@@ -2,12 +2,8 @@
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
-import cn.hutool.core.util.StrUtil;
-import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.MesMdItemImportExcelVO;
-import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.MesMdItemImportRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.MesMdItemPageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.MesMdItemSaveReqVO;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
@@ -17,7 +13,7 @@
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mes.dal.mysql.md.item.MesMdItemMapper;
import cn.iocoder.yudao.module.mes.enums.md.MesMdItemTypeEnum;
-import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodeRuleCodeEnum;
+
import cn.iocoder.yudao.module.mes.enums.wm.BarcodeBizTypeEnum;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mes.service.md.autocode.MesMdAutoCodeRecordService;
@@ -31,7 +27,6 @@
import java.math.BigDecimal;
import java.util.*;
-import java.util.concurrent.atomic.AtomicInteger;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -308,94 +303,6 @@
@Override
public Long getItemCountByUnitMeasureId(Long unitMeasureId) {
return itemMapper.selectCountByUnitMeasureId(unitMeasureId);
- }
-
- @Override
- @Transactional(rollbackFor = Exception.class)
- public MesMdItemImportRespVO importItemList(List<MesMdItemImportExcelVO> importItems, boolean updateSupport) {
- // 1. 鍙傛暟鏍¢獙
- if (CollUtil.isEmpty(importItems)) {
- throw exception(MD_ITEM_IMPORT_LIST_IS_EMPTY);
- }
-
- // 2. 閬嶅巻锛岄�愪釜鍒涘缓 or 鏇存柊
- MesMdItemImportRespVO respVO = MesMdItemImportRespVO.builder()
- .createCodes(new ArrayList<>()).updateCodes(new ArrayList<>())
- .failureCodes(new LinkedHashMap<>()).build();
- AtomicInteger index = new AtomicInteger(1);
- importItems.forEach(importItem -> {
- int currentIndex = index.getAndIncrement();
- // 2.1 鏍¢獙瀛楁
- if (StrUtil.isBlank(importItem.getCode())) {
- // 绌虹紪鐮佹椂鑷姩鐢熸垚
- importItem.setCode(autoCodeRecordService.generateAutoCode(MesMdAutoCodeRuleCodeEnum.MD_ITEM_CODE.getCode()));
- }
- String key = importItem.getCode();
- if (StrUtil.isBlank(importItem.getName())) {
- respVO.getFailureCodes().put(key, "鐗╂枡鍚嶇О涓嶈兘涓虹┖");
- return;
- }
- if (StrUtil.isBlank(importItem.getUnitMeasureCode())) {
- respVO.getFailureCodes().put(key, "鍗曚綅缂栫爜涓嶈兘涓虹┖");
- return;
- }
- // 灏嗗崟浣嶇紪鐮佽浆鎹负鍗曚綅 ID
- MesMdUnitMeasureDO unitMeasure = unitMeasureService.getUnitMeasureByCode(importItem.getUnitMeasureCode());
- if (unitMeasure == null) {
- respVO.getFailureCodes().put(key, "鍗曚綅缂栫爜[" + importItem.getUnitMeasureCode() + "]涓嶅瓨鍦�");
- return;
- }
- if (importItem.getItemTypeId() == null) {
- respVO.getFailureCodes().put(key, "鐗╂枡鍒嗙被缂栧彿涓嶈兘涓虹┖");
- return;
- }
- // 2.2 鏍¢獙鍒嗙被鏄惁瀛樺湪
- try {
- validateItemTypeExists(importItem.getItemTypeId());
- } catch (ServiceException ex) {
- respVO.getFailureCodes().put(key, ex.getMessage());
- return;
- }
-
- // 2.3 鍒ゆ柇锛氬垱寤� or 鏇存柊
- MesMdItemDO existItem = itemMapper.selectByCode(importItem.getCode());
- if (existItem == null) {
- // 2.3.1 鍒涘缓
- try {
- validateItemNameUnique(null, importItem.getName());
- } catch (ServiceException ex) {
- respVO.getFailureCodes().put(key, ex.getMessage());
- return;
- }
- MesMdItemDO item = BeanUtils.toBean(importItem, MesMdItemDO.class);
- item.setUnitMeasureId(unitMeasure.getId());
- item.setStatus(CommonStatusEnum.DISABLE.getStatus()); // 榛樿绂佺敤銆備俊鎭畬鎴愬悗锛屽啀鍚敤
- clearStockIfNotSafe(item);
- itemMapper.insert(item);
- // 鑷姩鐢熸垚鏉$爜
- barcodeService.autoGenerateBarcode(BarcodeBizTypeEnum.ITEM.getValue(),
- item.getId(), item.getCode(), item.getName());
- respVO.getCreateCodes().add(importItem.getCode());
- } else if (updateSupport) {
- // 2.3.2 鏇存柊
- try {
- validateItemNameUnique(existItem.getId(), importItem.getName());
- } catch (ServiceException ex) {
- respVO.getFailureCodes().put(key, ex.getMessage());
- return;
- }
- MesMdItemDO updateObj = BeanUtils.toBean(importItem, MesMdItemDO.class);
- updateObj.setId(existItem.getId());
- updateObj.setUnitMeasureId(unitMeasure.getId());
- clearStockIfNotSafe(updateObj);
- itemMapper.updateById(updateObj);
- respVO.getUpdateCodes().add(importItem.getCode());
- } else {
- // 涓嶆敮鎸佹洿鏂�
- respVO.getFailureCodes().put(key, "鐗╂枡缂栫爜宸插瓨鍦�");
- }
- });
- return respVO;
}
/**
diff --git a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/supplier/vo/SrmSupplierPageReqVO.java b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/supplier/vo/SrmSupplierPageReqVO.java
index 8302ac8..833469d 100644
--- a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/supplier/vo/SrmSupplierPageReqVO.java
+++ b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/supplier/vo/SrmSupplierPageReqVO.java
@@ -33,4 +33,7 @@
@Schema(description = "浠呮樉绀哄凡閫氳繃鍑嗗叆瀹℃壒鐨勪緵搴斿晢")
private Boolean approved;
+ @Schema(description = "鎺掗櫎宸查�氳繃鍑嗗叆瀹℃壒鐨勪緵搴斿晢锛堢敤浜庢柊澧炲噯鍏ユ椂閬垮厤閲嶅閫夋嫨锛�")
+ private Boolean excludeApproved;
+
}
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 feb776a..6ad8a2b 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
@@ -96,6 +96,14 @@
return success(true);
}
+ @PutMapping("/update-info")
+ @Operation(summary = "閮ㄥ垎鏇存柊鎷涙爣淇℃伅锛堜粎鍙戝竷涓�/鎶曟爣涓彲缂栬緫锛氭嫑鏍囪鏄庡拰璧勮川瑕佹眰锛�")
+ @PreAuthorize("@ss.hasPermission('srm:tender-project:update')")
+ public CommonResult<Boolean> updateTenderProjectInfo(@Valid @RequestBody SrmTenderProjectPartialUpdateReqVO updateReqVO) {
+ tenderProjectService.updateTenderProjectPartial(updateReqVO);
+ return success(true);
+ }
+
// ========== 鐗╂枡瀛愯〃 ==========
@PostMapping("/material/create")
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
new file mode 100644
index 0000000..0b8aa99
--- /dev/null
+++ b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/controller/admin/tender/vo/SrmTenderProjectPartialUpdateReqVO.java
@@ -0,0 +1,21 @@
+package cn.iocoder.yudao.module.srm.controller.admin.tender.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+@Schema(description = "绠$悊鍚庡彴 - SRM 鎷涙爣椤圭洰閮ㄥ垎鏇存柊 Request VO锛堝彂甯冧腑/鎶曟爣涓樁娈碉級")
+@Data
+public class SrmTenderProjectPartialUpdateReqVO {
+
+ @Schema(description = "椤圭洰ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "椤圭洰ID涓嶈兘涓虹┖")
+ private Long id;
+
+ @Schema(description = "鎷涙爣鎻忚堪", example = "鏈鎷涙爣閲囪喘閽㈡潗涓�鎵�")
+ private String tenderDesc;
+
+ @Schema(description = "璧勮川瑕佹眰", example = "闇�鍏峰ISO9001璁よ瘉")
+ private String qualificationRequirements;
+
+}
diff --git a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/dal/mysql/SrmSupplierMapper.java b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/dal/mysql/SrmSupplierMapper.java
index a5ae79c..398696d 100644
--- a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/dal/mysql/SrmSupplierMapper.java
+++ b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/dal/mysql/SrmSupplierMapper.java
@@ -26,6 +26,9 @@
if (Boolean.TRUE.equals(reqVO.getApproved())) {
wrapper.apply("id IN (SELECT supplier_id FROM srm_supplier_apply WHERE apply_status = 40 AND supplier_id IS NOT NULL AND deleted = 0)");
}
+ if (Boolean.TRUE.equals(reqVO.getExcludeApproved())) {
+ wrapper.apply("id NOT IN (SELECT supplier_id FROM srm_supplier_apply WHERE apply_status = 40 AND supplier_id IS NOT NULL AND deleted = 0)");
+ }
return selectPage(reqVO, wrapper);
}
diff --git a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/dal/mysql/SrmTenderBidMapper.java b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/dal/mysql/SrmTenderBidMapper.java
index 766e20c..d98ca53 100644
--- a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/dal/mysql/SrmTenderBidMapper.java
+++ b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/dal/mysql/SrmTenderBidMapper.java
@@ -26,4 +26,9 @@
.eq(SrmTenderBidDO::getBidNo, bidNo));
}
+ default long countByTenderProjectId(Long tenderProjectId) {
+ return selectCount(new LambdaQueryWrapperX<SrmTenderBidDO>()
+ .eq(SrmTenderBidDO::getTenderProjectId, tenderProjectId));
+ }
+
}
diff --git a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/enums/ErrorCodeConstants.java b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/enums/ErrorCodeConstants.java
index e685314..106b948 100644
--- a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/enums/ErrorCodeConstants.java
+++ b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/enums/ErrorCodeConstants.java
@@ -48,6 +48,17 @@
ErrorCode AWARD_SUPPLIER_NOT_SYNCED = new ErrorCode(1_040_500_014, "渚涘簲鍟嗘湭鍚屾鑷矱RP锛屾棤娉曠敓鎴愰噰璐鍗�");
ErrorCode AWARD_QUOTE_NOT_EXISTS = new ErrorCode(1_040_500_015, "涓爣渚涘簲鍟嗘姤浠蜂笉瀛樺湪");
+ // 鐘舵�佹牎楠岀簿缁嗗寲閿欒鐮�
+ ErrorCode TENDER_MATERIAL_LOCKED = new ErrorCode(1_040_500_022, "鐗╂枡娓呭崟宸查攣瀹氾紝涓嶅厑璁稿鍒犳敼");
+ ErrorCode TENDER_BID_FORBIDDEN = new ErrorCode(1_040_500_023, "褰撳墠鐘舵�佷笉鍏佽鏂板鎶曟爣");
+ ErrorCode TENDER_QUOTE_FORBIDDEN = new ErrorCode(1_040_500_024, "褰撳墠鐘舵�佷笉鍏佽鎶ヤ环鎿嶄綔");
+ ErrorCode TENDER_END_TIME_PASSED = new ErrorCode(1_040_500_025, "鎶曟爣鎴鏃堕棿宸茶繃锛屼笉鍏佽鏂板鎶曟爣");
+ ErrorCode TENDER_PROJECT_LOCKED = new ErrorCode(1_040_500_026, "椤圭洰宸查攣瀹氾紝褰撳墠鐘舵�佷笉鍏佽鎿嶄綔");
+ ErrorCode TENDER_HAS_BIDS_CANNOT_DELETE = new ErrorCode(1_040_500_027, "宸插瓨鍦ㄦ姇鏍囨暟鎹紝涓嶅厑璁稿垹闄�");
+ ErrorCode TENDER_BID_FORBIDDEN_WITHDRAW = new ErrorCode(1_040_500_028, "褰撳墠鐘舵�佷笉鍏佽鎾ゆ爣");
+ ErrorCode TENDER_EVALUATION_FORBIDDEN = new ErrorCode(1_040_500_029, "褰撳墠鐘舵�佷笉鍏佽璇勬爣鎿嶄綔");
+ ErrorCode TENDER_AWARD_FORBIDDEN = new ErrorCode(1_040_500_030, "褰撳墠鐘舵�佷笉鍏佽瀹氭爣鎿嶄綔");
+
// ========== 閫氱敤 ==========
ErrorCode QUOTE_MATERIAL_DUPLICATE = new ErrorCode(1_040_900_001, "璇ユ姇鏍囧凡瀛樺湪鐩稿悓鐗╂枡鐨勬姤浠�");
diff --git a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/enums/LogRecordConstants.java b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/enums/LogRecordConstants.java
new file mode 100644
index 0000000..6d6cb50
--- /dev/null
+++ b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/enums/LogRecordConstants.java
@@ -0,0 +1,45 @@
+package cn.iocoder.yudao.module.srm.enums;
+
+/**
+ * SRM 鎿嶄綔鏃ュ織甯搁噺
+ */
+public interface LogRecordConstants {
+
+ // ======================= SRM_TENDER 鎷涙爣椤圭洰 =======================
+ String LOG_TENDER_TYPE = "SRM 鎷涙爣椤圭洰";
+ String LOG_TENDER_UPDATE_SUB_TYPE = "鏇存柊鎷涙爣椤圭洰";
+ String LOG_TENDER_UPDATE_SUCCESS = "鏇存柊浜嗘嫑鏍囬」鐩�恵{#tenderName}}銆戯紝"
+ + "鎷涙爣璇存槑锛歿{#oldTenderDesc}} 鈫� {{#newTenderDesc}}锛�"
+ + "璧勮川瑕佹眰锛歿{#oldQualification}} 鈫� {{#newQualification}}";
+
+ // ======================= SRM_BID 鎶曟爣 =======================
+ String LOG_BID_TYPE = "SRM 鎶曟爣";
+ String LOG_BID_CREATE_SUB_TYPE = "鍒涘缓鎶曟爣";
+ String LOG_BID_CREATE_SUCCESS = "渚涘簲鍟嗗鎷涙爣椤圭洰銆恵{#tenderName}}銆戞彁浜や簡鎶曟爣銆恵{#bidNo}}銆�";
+ String LOG_BID_WITHDRAW_SUB_TYPE = "鎾ゆ爣";
+ String LOG_BID_WITHDRAW_SUCCESS = "鎾ゅ洖浜嗘姇鏍囥�恵{#bidNo}}銆�";
+
+ // ======================= SRM_QUOTE 鎶ヤ环 =======================
+ String LOG_QUOTE_TYPE = "SRM 鎶ヤ环";
+ String LOG_QUOTE_CREATE_SUB_TYPE = "鍒涘缓鎶ヤ环";
+ String LOG_QUOTE_CREATE_SUCCESS = "鎻愪氦浜嗘姇鏍囩殑渚涘簲鍟嗘姤浠�";
+ String LOG_QUOTE_UPDATE_SUB_TYPE = "鏇存柊鎶ヤ环";
+ String LOG_QUOTE_UPDATE_SUCCESS = "鏇存柊浜嗘姇鏍囩殑渚涘簲鍟嗘姤浠�";
+
+ // ======================= SRM_EVALUATION 璇勬爣 =======================
+ String LOG_EVALUATION_TYPE = "SRM 璇勬爣";
+ String LOG_EVALUATION_CREATE_SUB_TYPE = "鍒涘缓璇勬爣";
+ String LOG_EVALUATION_CREATE_SUCCESS = "瀵规嫑鏍囬」鐩繘琛屼簡璇勬爣璇勫垎";
+ String LOG_EVALUATION_UPDATE_SUB_TYPE = "鏇存柊璇勬爣";
+ String LOG_EVALUATION_UPDATE_SUCCESS = "鏇存柊浜嗚瘎鏍囪褰�";
+
+ // ======================= SRM_AWARD 瀹氭爣 =======================
+ String LOG_AWARD_TYPE = "SRM 瀹氭爣";
+ String LOG_AWARD_CREATE_SUB_TYPE = "鍒涘缓瀹氭爣";
+ String LOG_AWARD_CREATE_SUCCESS = "鍒涘缓浜嗗畾鏍囥�恵{#createReqVO.awardNo}}銆�";
+ String LOG_AWARD_APPROVE_SUB_TYPE = "瀹℃壒瀹氭爣";
+ String LOG_AWARD_APPROVE_SUCCESS = "瀹℃壒閫氳繃浜嗗畾鏍囪褰�";
+ String LOG_AWARD_ORDER_SUB_TYPE = "鐢熸垚閲囪喘璁㈠崟";
+ String LOG_AWARD_ORDER_SUCCESS = "瀹氭爣璁板綍鐢熸垚浜嗛噰璐鍗�";
+
+}
diff --git a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/enums/TenderStatusEnum.java b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/enums/TenderStatusEnum.java
index f567c33..ca84fba 100644
--- a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/enums/TenderStatusEnum.java
+++ b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/enums/TenderStatusEnum.java
@@ -23,4 +23,41 @@
private final Integer code;
private final String name;
+ // ========== 鐘舵�佸伐鍏锋柟娉� ==========
+
+ /** DRAFT 鍏佽鍏ㄥ瓧娈电紪杈� */
+ public static boolean canEditFullProject(Integer status) {
+ return DRAFT.getCode().equals(status);
+ }
+
+ /** PUBLISHED 鎴� BIDDING 鍏佽閮ㄥ垎缂栬緫锛堟嫑鏍囪鏄庛�佽祫璐ㄨ姹傦級 */
+ public static boolean canEditPartialProject(Integer status) {
+ return PUBLISHED.getCode().equals(status) || BIDDING.getCode().equals(status);
+ }
+
+ /** DRAFT 鍏佽缂栬緫鐗╂枡娓呭崟 */
+ public static boolean canEditMaterial(Integer status) {
+ return DRAFT.getCode().equals(status);
+ }
+
+ /** PUBLISHED 鎴� BIDDING 鍏佽渚涘簲鍟嗘姇鏍� */
+ public static boolean canCreateBid(Integer status) {
+ return PUBLISHED.getCode().equals(status) || BIDDING.getCode().equals(status);
+ }
+
+ /** PUBLISHED 鎴� BIDDING 鍏佽渚涘簲鍟嗘姤浠� */
+ public static boolean canCreateOrUpdateQuote(Integer status) {
+ return PUBLISHED.getCode().equals(status) || BIDDING.getCode().equals(status);
+ }
+
+ /** EVALUATING 鍏佽璇勬爣鎿嶄綔 */
+ public static boolean canEvaluate(Integer status) {
+ return EVALUATING.getCode().equals(status);
+ }
+
+ /** EVALUATING 鍏佽瀹氭爣鎿嶄綔 */
+ public static boolean canAward(Integer status) {
+ return EVALUATING.getCode().equals(status);
+ }
+
}
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 962feb8..6104b97 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 com.mzt.logapi.starter.annotation.LogRecord;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -25,6 +26,8 @@
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
+
+import static cn.iocoder.yudao.module.srm.enums.LogRecordConstants.*;
/**
* SRM 瀹氭爣绠$悊 Service 瀹炵幇绫�
@@ -60,7 +63,14 @@
@Override
@Transactional(rollbackFor = Exception.class)
+ @LogRecord(type = LOG_AWARD_TYPE, subType = LOG_AWARD_CREATE_SUB_TYPE,
+ bizNo = "{{#createReqVO.awardNo}}", success = LOG_AWARD_CREATE_SUCCESS)
public Long createAward(SrmBidAwardSaveReqVO createReqVO) {
+ // 妫�鏌ユ嫑鏍囬」鐩姸鎬侊細浠� EVALUATING 鍏佽鍒涘缓瀹氭爣
+ SrmTenderProjectDO project = tenderProjectMapper.selectById(createReqVO.getTenderProjectId());
+ if (project == null || !TenderStatusEnum.canAward(project.getTenderStatus())) {
+ throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_AWARD_FORBIDDEN);
+ }
// 鏍¢獙鏄惁宸插瓨鍦ㄥ畾鏍�
SrmBidAwardDO existing = bidAwardMapper.selectByTenderProjectId(createReqVO.getTenderProjectId());
if (existing != null) {
@@ -95,6 +105,10 @@
@Transactional(rollbackFor = Exception.class)
public void deleteAward(Long id) {
SrmBidAwardDO award = validateAwardExists(id);
+ // 浠呭緟瀹℃壒鐘舵�佸彲鍒犻櫎
+ if (!AwardStatusEnum.PENDING_APPROVAL.getCode().equals(award.getAwardStatus())) {
+ throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_AWARD_FORBIDDEN);
+ }
bidAwardMapper.deleteById(id);
}
@@ -102,16 +116,18 @@
@Transactional(rollbackFor = Exception.class)
public void approveAward(Long id) {
SrmBidAwardDO award = validateAwardExists(id);
+ // 鏍¢獙鎷涙爣椤圭洰鐘舵�佷负璇勬爣涓�
+ SrmTenderProjectDO project = tenderProjectMapper.selectById(award.getTenderProjectId());
+ if (project == null || !TenderStatusEnum.canAward(project.getTenderStatus())) {
+ throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_AWARD_FORBIDDEN);
+ }
award.setAwardStatus(AwardStatusEnum.AWARDED.getCode());
award.setApprovalTime(LocalDateTime.now());
bidAwardMapper.updateById(award);
// 鏇存柊鎷涙爣椤圭洰鐘舵�佷负宸插畾鏍�
- SrmTenderProjectDO project = tenderProjectMapper.selectById(award.getTenderProjectId());
- if (project != null) {
- project.setTenderStatus(TenderStatusEnum.AWARDED.getCode());
- tenderProjectMapper.updateById(project);
- }
+ project.setTenderStatus(TenderStatusEnum.AWARDED.getCode());
+ tenderProjectMapper.updateById(project);
}
@Override
@@ -121,6 +137,11 @@
SrmBidAwardDO award = validateAwardExists(id);
if (!AwardStatusEnum.AWARDED.getCode().equals(award.getAwardStatus())) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.AWARD_STATUS_NOT_AWARDED);
+ }
+ // 鏍¢獙鎷涙爣椤圭洰鐘舵�佷负宸插畾鏍�
+ SrmTenderProjectDO project = tenderProjectMapper.selectById(award.getTenderProjectId());
+ if (project == null || !TenderStatusEnum.AWARDED.getCode().equals(project.getTenderStatus())) {
+ throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_AWARD_FORBIDDEN);
}
// 2. 鏌� SRM 渚涘簲鍟�
@@ -201,11 +222,8 @@
bidAwardMapper.updateById(award);
// 9. 鏇存柊鎷涙爣椤圭洰鐘舵��
- SrmTenderProjectDO project = tenderProjectMapper.selectById(award.getTenderProjectId());
- if (project != null) {
- project.setTenderStatus(TenderStatusEnum.CLOSED.getCode());
- tenderProjectMapper.updateById(project);
- }
+ project.setTenderStatus(TenderStatusEnum.CLOSED.getCode());
+ tenderProjectMapper.updateById(project);
}
private SrmBidAwardDO validateAwardExists(Long id) {
diff --git a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/tender/SrmBidEvaluationServiceImpl.java b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/tender/SrmBidEvaluationServiceImpl.java
index c0f3b72..f211793 100644
--- a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/tender/SrmBidEvaluationServiceImpl.java
+++ b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/tender/SrmBidEvaluationServiceImpl.java
@@ -11,6 +11,7 @@
import cn.iocoder.yudao.module.srm.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.srm.enums.TenderStatusEnum;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
+import com.mzt.logapi.starter.annotation.LogRecord;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -21,6 +22,8 @@
import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
+
+import static cn.iocoder.yudao.module.srm.enums.LogRecordConstants.*;
/**
* SRM 璇勬爣绠$悊 Service 瀹炵幇绫�
@@ -42,7 +45,20 @@
@Override
@Transactional(rollbackFor = Exception.class)
+ @LogRecord(type = LOG_EVALUATION_TYPE, subType = LOG_EVALUATION_CREATE_SUB_TYPE,
+ bizNo = "{{#createReqVO.tenderProjectId}}", success = LOG_EVALUATION_CREATE_SUCCESS)
public Long createEvaluation(SrmBidEvaluationSaveReqVO createReqVO) {
+ // 妫�鏌ユ嫑鏍囬」鐩姸鎬侊細BIDDING 鎴� EVALUATING 鎵嶅厑璁歌瘎鏍�
+ SrmTenderProjectDO project = tenderProjectMapper.selectById(createReqVO.getTenderProjectId());
+ if (project == null) {
+ throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_NOT_EXISTS);
+ }
+ Integer status = project.getTenderStatus();
+ if (!TenderStatusEnum.BIDDING.getCode().equals(status)
+ && !TenderStatusEnum.EVALUATING.getCode().equals(status)) {
+ throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_EVALUATION_FORBIDDEN);
+ }
+
SrmBidEvaluationDO evaluation = BeanUtils.toBean(createReqVO, SrmBidEvaluationDO.class);
// 寮哄埗缃┖ id锛岄伩鍏嶅墠绔紶鍏ュ凡鏈� id 瀵艰嚧涓婚敭鍐茬獊锛岀敱鏁版嵁搴撳簭鍒楄嚜鍔ㄧ敓鎴�
evaluation.setId(null);
@@ -60,8 +76,7 @@
evaluation.setEvaluationTime(LocalDateTime.now());
bidEvaluationMapper.insert(evaluation);
// 棣栨璇勬爣鏃舵洿鏂版嫑鏍囬」鐩姸鎬佷负璇勬爣涓�
- SrmTenderProjectDO project = tenderProjectMapper.selectById(createReqVO.getTenderProjectId());
- if (project != null && TenderStatusEnum.BIDDING.getCode().equals(project.getTenderStatus())) {
+ if (TenderStatusEnum.BIDDING.getCode().equals(project.getTenderStatus())) {
project.setTenderStatus(TenderStatusEnum.EVALUATING.getCode());
tenderProjectMapper.updateById(project);
}
@@ -74,6 +89,11 @@
SrmBidEvaluationDO existing = bidEvaluationMapper.selectById(updateReqVO.getId());
if (existing == null) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.EVALUATION_NOT_EXISTS_TENDER);
+ }
+ // 妫�鏌ユ嫑鏍囬」鐩姸鎬侊細浠� EVALUATING 鍏佽鏇存柊璇勬爣
+ SrmTenderProjectDO project = tenderProjectMapper.selectById(existing.getTenderProjectId());
+ if (project == null || !TenderStatusEnum.canEvaluate(project.getTenderStatus())) {
+ throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_EVALUATION_FORBIDDEN);
}
SrmBidEvaluationDO evaluation = BeanUtils.toBean(updateReqVO, SrmBidEvaluationDO.class);
BigDecimal price = nvl(evaluation.getPriceScore());
@@ -98,6 +118,10 @@
@Override
@Transactional(rollbackFor = Exception.class)
public void calculateRanking(Long tenderProjectId) {
+ SrmTenderProjectDO project = tenderProjectMapper.selectById(tenderProjectId);
+ if (project == null || !TenderStatusEnum.canEvaluate(project.getTenderStatus())) {
+ throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_EVALUATION_FORBIDDEN);
+ }
List<SrmBidEvaluationDO> list = bidEvaluationMapper.selectListByTenderProjectId(tenderProjectId);
// 鎸夌患鍚堣瘎鍒嗛檷搴忔帓鍚�
list.sort(Comparator.comparing(e -> e.getCompositeScore() != null ? e.getCompositeScore() : BigDecimal.ZERO, Comparator.reverseOrder()));
@@ -113,15 +137,20 @@
@Override
@Transactional(rollbackFor = Exception.class)
public Long createBidOpen(Long tenderProjectId) {
+ // 鏍¢獙鎷涙爣椤圭洰瀛樺湪涓旂姸鎬佷负鍙戝竷涓�
+ SrmTenderProjectDO project = tenderProjectMapper.selectById(tenderProjectId);
+ if (project == null) {
+ throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_NOT_EXISTS);
+ }
+ if (!TenderStatusEnum.PUBLISHED.getCode().equals(project.getTenderStatus())) {
+ throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_STATUS_NOT_PUBLISHED);
+ }
if (bidOpenMapper.selectByTenderProjectId(tenderProjectId) != null) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_STATUS_NOT_PUBLISHED);
}
// 寮�鏍囧悗鑷姩鏇存柊鎷涙爣椤圭洰鐘舵�佷负鎶曟爣涓�
- SrmTenderProjectDO project = tenderProjectMapper.selectById(tenderProjectId);
- if (project != null && TenderStatusEnum.PUBLISHED.getCode().equals(project.getTenderStatus())) {
- project.setTenderStatus(TenderStatusEnum.BIDDING.getCode());
- tenderProjectMapper.updateById(project);
- }
+ project.setTenderStatus(TenderStatusEnum.BIDDING.getCode());
+ tenderProjectMapper.updateById(project);
SrmBidOpenDO open = new SrmBidOpenDO();
open.setTenderProjectId(tenderProjectId);
open.setOpenTime(LocalDateTime.now());
diff --git a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/tender/SrmTenderBidServiceImpl.java b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/tender/SrmTenderBidServiceImpl.java
index 91e6e74..6410946 100644
--- a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/tender/SrmTenderBidServiceImpl.java
+++ b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/tender/SrmTenderBidServiceImpl.java
@@ -5,6 +5,7 @@
import cn.iocoder.yudao.module.srm.controller.admin.tender.vo.SrmTenderBidSaveReqVO;
import cn.iocoder.yudao.module.srm.dal.dataobject.SrmSupplierQuoteDO;
import cn.iocoder.yudao.module.srm.dal.dataobject.SrmTenderBidDO;
+import cn.iocoder.yudao.module.srm.dal.dataobject.SrmTenderProjectDO;
import cn.iocoder.yudao.module.srm.dal.mysql.SrmSupplierApplyMapper;
import cn.iocoder.yudao.module.srm.dal.mysql.SrmSupplierQuoteMapper;
import cn.iocoder.yudao.module.srm.dal.mysql.SrmTenderBidMapper;
@@ -13,6 +14,8 @@
import cn.iocoder.yudao.module.srm.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.srm.enums.TenderStatusEnum;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
+import com.mzt.logapi.context.LogRecordContext;
+import com.mzt.logapi.starter.annotation.LogRecord;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -20,6 +23,8 @@
import java.time.LocalDateTime;
import java.util.List;
+
+import static cn.iocoder.yudao.module.srm.enums.LogRecordConstants.*;
/**
* SRM 鎶曟爣绠$悊 Service 瀹炵幇绫�
@@ -44,9 +49,15 @@
@Override
@Transactional(rollbackFor = Exception.class)
+ @LogRecord(type = LOG_BID_TYPE, subType = LOG_BID_CREATE_SUB_TYPE,
+ bizNo = "{{#createReqVO.bidNo}}", success = LOG_BID_CREATE_SUCCESS)
public Long createBid(SrmTenderBidSaveReqVO createReqVO) {
- // 鏍¢獙鎷涙爣椤圭洰鏄惁瀛樺湪涓旂姸鎬佹纭�
- validateTenderStatus(createReqVO.getTenderProjectId());
+ // 鏍¢獙鎷涙爣椤圭洰鐘舵�侊紙PUBLISHED/BIDDING 鎵嶅厑璁告姇鏍囷級
+ SrmTenderProjectDO project = validateTenderStatus(createReqVO.getTenderProjectId());
+ // 妫�鏌ユ姇鏍囨埅姝㈡椂闂�
+ if (project.getEndTime() != null && LocalDateTime.now().isAfter(project.getEndTime())) {
+ throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_END_TIME_PASSED);
+ }
// 鏍¢獙渚涘簲鍟嗘槸鍚﹀凡閫氳繃鍑嗗叆瀹℃壒
if (!supplierApplyMapper.existsApprovedBySupplierId(createReqVO.getSupplierId())) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.BID_SUPPLIER_NOT_APPROVED);
@@ -64,6 +75,8 @@
bid.setBidStatus(BidStatusEnum.REGISTERED.getCode());
bid.setBidTime(LocalDateTime.now());
tenderBidMapper.insert(bid);
+ LogRecordContext.putVariable("bidNo", bid.getBidNo());
+ LogRecordContext.putVariable("tenderName", project.getTenderName());
return bid.getId();
}
@@ -79,20 +92,35 @@
@Override
@Transactional(rollbackFor = Exception.class)
+ @LogRecord(type = LOG_BID_TYPE, subType = LOG_BID_WITHDRAW_SUB_TYPE,
+ bizNo = "{{#id}}", success = LOG_BID_WITHDRAW_SUCCESS)
public void withdrawBid(Long id) {
SrmTenderBidDO bid = validateBidExists(id);
+ // 妫�鏌ユ嫑鏍囬」鐩姸鎬侊細浠� PUBLISHED/BIDDING 鍏佽鎾ゆ爣
+ SrmTenderProjectDO project = tenderProjectMapper.selectById(bid.getTenderProjectId());
+ if (project == null || !TenderStatusEnum.canCreateOrUpdateQuote(project.getTenderStatus())) {
+ throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_BID_FORBIDDEN_WITHDRAW);
+ }
bid.setBidStatus(BidStatusEnum.WITHDRAWN.getCode());
tenderBidMapper.updateById(bid);
// 鍒犻櫎鎶ヤ环
supplierQuoteMapper.deleteByBidId(id);
+ LogRecordContext.putVariable("bidNo", bid.getBidNo());
}
// ========== 鎶ヤ环绠$悊 ==========
@Override
+ @LogRecord(type = LOG_QUOTE_TYPE, subType = LOG_QUOTE_CREATE_SUB_TYPE,
+ bizNo = "{{#createReqVO.bidId}}", success = LOG_QUOTE_CREATE_SUCCESS)
public Long createQuote(SrmSupplierQuoteSaveReqVO createReqVO) {
// 鏍¢獙鎶曟爣鐘舵�侊紙鎾ゆ爣鍚庝笉鍏佽鎶ヤ环锛�
SrmTenderBidDO bid = validateBidNotWithdrawn(createReqVO.getBidId());
+ // 鏍¢獙鎷涙爣椤圭洰鐘舵�侊細浠� PUBLISHED/BIDDING 鍏佽鎶ヤ环
+ SrmTenderProjectDO project = tenderProjectMapper.selectById(bid.getTenderProjectId());
+ if (project == null || !TenderStatusEnum.canCreateOrUpdateQuote(project.getTenderStatus())) {
+ throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_QUOTE_FORBIDDEN);
+ }
// 鏍¢獙鍚屼竴鎶曟爣涓嬬墿鏂欎笉鍙噸澶嶆姤浠�
if (supplierQuoteMapper.existsByBidAndMaterial(createReqVO.getBidId(), createReqVO.getTenderMaterialId())) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.QUOTE_MATERIAL_DUPLICATE);
@@ -108,7 +136,12 @@
@Override
public void updateQuote(SrmSupplierQuoteSaveReqVO updateReqVO) {
// 鏍¢獙鎶曟爣鐘舵�侊紙鎾ゆ爣鍚庝笉鍏佽鎶ヤ环锛�
- validateBidNotWithdrawn(updateReqVO.getBidId());
+ SrmTenderBidDO bid = validateBidNotWithdrawn(updateReqVO.getBidId());
+ // 鏍¢獙鎷涙爣椤圭洰鐘舵�侊細浠� PUBLISHED/BIDDING 鍏佽鎶ヤ环
+ SrmTenderProjectDO project = tenderProjectMapper.selectById(bid.getTenderProjectId());
+ if (project == null || !TenderStatusEnum.canCreateOrUpdateQuote(project.getTenderStatus())) {
+ throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_QUOTE_FORBIDDEN);
+ }
// 鏍¢獙鍚屼竴鎶曟爣涓嬬墿鏂欎笉鍙噸澶嶆姤浠凤紙鎺掗櫎鑷韩锛�
SrmSupplierQuoteDO existing = supplierQuoteMapper.selectById(updateReqVO.getId());
if (existing != null && !existing.getTenderMaterialId().equals(updateReqVO.getTenderMaterialId())) {
@@ -143,9 +176,14 @@
return bid;
}
- private void validateTenderStatus(Long tenderProjectId) {
- if (tenderProjectMapper.selectById(tenderProjectId) == null) {
+ private SrmTenderProjectDO validateTenderStatus(Long tenderProjectId) {
+ SrmTenderProjectDO project = tenderProjectMapper.selectById(tenderProjectId);
+ if (project == null) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_NOT_EXISTS);
}
+ if (!TenderStatusEnum.canCreateBid(project.getTenderStatus())) {
+ throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_BID_FORBIDDEN);
+ }
+ return project;
}
}
diff --git a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/tender/SrmTenderProjectService.java b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/tender/SrmTenderProjectService.java
index 1ca5508..1edc7ac 100644
--- a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/tender/SrmTenderProjectService.java
+++ b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/tender/SrmTenderProjectService.java
@@ -2,6 +2,7 @@
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.srm.controller.admin.tender.vo.SrmTenderProjectPageReqVO;
+import cn.iocoder.yudao.module.srm.controller.admin.tender.vo.SrmTenderProjectPartialUpdateReqVO;
import cn.iocoder.yudao.module.srm.controller.admin.tender.vo.SrmTenderProjectSaveReqVO;
import cn.iocoder.yudao.module.srm.controller.admin.tender.vo.SrmTenderMaterialSaveReqVO;
import cn.iocoder.yudao.module.srm.dal.dataobject.SrmTenderMaterialDO;
@@ -14,6 +15,7 @@
Long createTenderProject(@Valid SrmTenderProjectSaveReqVO createReqVO);
void updateTenderProject(@Valid SrmTenderProjectSaveReqVO updateReqVO);
+ void updateTenderProjectPartial(@Valid SrmTenderProjectPartialUpdateReqVO updateReqVO);
void deleteTenderProject(Long id);
SrmTenderProjectDO getTenderProject(Long id);
PageResult<SrmTenderProjectDO> getTenderProjectPage(SrmTenderProjectPageReqVO pageReqVO);
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 7de0819..5d1b679 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
@@ -4,17 +4,21 @@
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
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;
import cn.iocoder.yudao.module.srm.controller.admin.tender.vo.SrmTenderProjectSaveReqVO;
import cn.iocoder.yudao.module.srm.dal.dataobject.SrmBidAwardDO;
import cn.iocoder.yudao.module.srm.dal.dataobject.SrmTenderMaterialDO;
import cn.iocoder.yudao.module.srm.dal.dataobject.SrmTenderProjectDO;
import cn.iocoder.yudao.module.srm.dal.mysql.SrmBidAwardMapper;
+import cn.iocoder.yudao.module.srm.dal.mysql.SrmTenderBidMapper;
import cn.iocoder.yudao.module.srm.dal.mysql.SrmTenderMaterialMapper;
import cn.iocoder.yudao.module.srm.dal.mysql.SrmTenderProjectMapper;
import cn.iocoder.yudao.module.srm.enums.AwardStatusEnum;
import cn.iocoder.yudao.module.srm.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.srm.enums.TenderStatusEnum;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
+import com.mzt.logapi.context.LogRecordContext;
+import com.mzt.logapi.starter.annotation.LogRecord;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
@@ -23,6 +27,8 @@
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
+
+import static cn.iocoder.yudao.module.srm.enums.LogRecordConstants.*;
@Service
@Validated
@@ -34,6 +40,8 @@
private SrmTenderMaterialMapper tenderMaterialMapper;
@Resource
private SrmBidAwardMapper bidAwardMapper;
+ @Resource
+ private SrmTenderBidMapper tenderBidMapper;
@Override
public Long createTenderProject(SrmTenderProjectSaveReqVO createReqVO) {
@@ -44,13 +52,42 @@
}
@Override
+ @LogRecord(type = LOG_TENDER_TYPE, subType = LOG_TENDER_UPDATE_SUB_TYPE,
+ bizNo = "{{#updateReqVO.id}}", success = LOG_TENDER_UPDATE_SUCCESS)
public void updateTenderProject(SrmTenderProjectSaveReqVO updateReqVO) {
SrmTenderProjectDO project = validateTenderExists(updateReqVO.getId());
- if (!TenderStatusEnum.DRAFT.getCode().equals(project.getTenderStatus())) {
- throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_STATUS_NOT_DRAFT);
+ Integer status = project.getTenderStatus();
+
+ // 鑽夌鐘舵�侊細鍏ㄥ瓧娈靛彲缂栬緫
+ if (TenderStatusEnum.canEditFullProject(status)) {
+ SrmTenderProjectDO updateObj = BeanUtils.toBean(updateReqVO, SrmTenderProjectDO.class);
+ updateObj.setTenderStatus(status); // 鐘舵�佷笉鍏佽鍓嶇浼犲叆瑕嗙洊
+ tenderProjectMapper.updateById(updateObj);
+ LogRecordContext.putVariable("tenderName", project.getTenderName());
+ LogRecordContext.putVariable("oldTenderDesc", project.getTenderDesc());
+ LogRecordContext.putVariable("newTenderDesc", updateReqVO.getTenderDesc());
+ LogRecordContext.putVariable("oldQualification", project.getQualificationRequirements());
+ LogRecordContext.putVariable("newQualification", updateReqVO.getQualificationRequirements());
+ return;
}
- SrmTenderProjectDO updateObj = BeanUtils.toBean(updateReqVO, SrmTenderProjectDO.class);
- tenderProjectMapper.updateById(updateObj);
+
+ // 鍙戝竷涓�/鎶曟爣涓細浠呭厑璁镐慨鏀规嫑鏍囪鏄庡拰璧勮川瑕佹眰
+ if (TenderStatusEnum.canEditPartialProject(status)) {
+ SrmTenderProjectDO updateObj = new SrmTenderProjectDO();
+ updateObj.setId(updateReqVO.getId());
+ updateObj.setTenderDesc(updateReqVO.getTenderDesc());
+ updateObj.setQualificationRequirements(updateReqVO.getQualificationRequirements());
+ tenderProjectMapper.updateById(updateObj);
+ LogRecordContext.putVariable("tenderName", project.getTenderName());
+ LogRecordContext.putVariable("oldTenderDesc", project.getTenderDesc());
+ LogRecordContext.putVariable("newTenderDesc", updateReqVO.getTenderDesc());
+ LogRecordContext.putVariable("oldQualification", project.getQualificationRequirements());
+ LogRecordContext.putVariable("newQualification", updateReqVO.getQualificationRequirements());
+ return;
+ }
+
+ // 鍏朵粬鐘舵�侊細涓嶅厑璁哥紪杈�
+ throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_PROJECT_LOCKED);
}
@Override
@@ -58,6 +95,10 @@
SrmTenderProjectDO project = validateTenderExists(id);
if (!TenderStatusEnum.DRAFT.getCode().equals(project.getTenderStatus())) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_STATUS_NOT_DRAFT);
+ }
+ // 妫�鏌ユ槸鍚﹀凡鏈夋姇鏍囨暟鎹�
+ if (tenderBidMapper.countByTenderProjectId(id) > 0) {
+ throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_HAS_BIDS_CANNOT_DELETE);
}
tenderMaterialMapper.deleteByTenderProjectId(id);
tenderProjectMapper.deleteById(id);
@@ -117,6 +158,10 @@
if (TenderStatusEnum.CLOSED.getCode().equals(project.getTenderStatus())) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_STATUS_ALREADY_CLOSED);
}
+ // 鑽夌鐘舵�佷笉鍏佽鐩存帴鍏抽棴
+ if (TenderStatusEnum.DRAFT.getCode().equals(project.getTenderStatus())) {
+ throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_PROJECT_LOCKED);
+ }
project.setTenderStatus(TenderStatusEnum.CLOSED.getCode());
tenderProjectMapper.updateById(project);
}
@@ -141,22 +186,60 @@
tenderProjectMapper.updateById(project);
}
+ @Override
+ @LogRecord(type = LOG_TENDER_TYPE, subType = LOG_TENDER_UPDATE_SUB_TYPE,
+ bizNo = "{{#updateReqVO.id}}", success = LOG_TENDER_UPDATE_SUCCESS)
+ public void updateTenderProjectPartial(SrmTenderProjectPartialUpdateReqVO updateReqVO) {
+ SrmTenderProjectDO project = validateTenderExists(updateReqVO.getId());
+ if (!TenderStatusEnum.canEditPartialProject(project.getTenderStatus())) {
+ throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_PROJECT_LOCKED);
+ }
+ SrmTenderProjectDO updateObj = new SrmTenderProjectDO();
+ updateObj.setId(updateReqVO.getId());
+ updateObj.setTenderDesc(updateReqVO.getTenderDesc());
+ updateObj.setQualificationRequirements(updateReqVO.getQualificationRequirements());
+ tenderProjectMapper.updateById(updateObj);
+ LogRecordContext.putVariable("tenderName", project.getTenderName());
+ LogRecordContext.putVariable("oldTenderDesc", project.getTenderDesc());
+ LogRecordContext.putVariable("newTenderDesc", updateReqVO.getTenderDesc());
+ LogRecordContext.putVariable("oldQualification", project.getQualificationRequirements());
+ LogRecordContext.putVariable("newQualification", updateReqVO.getQualificationRequirements());
+ }
+
// ========== 鐗╂枡瀛愯〃 ==========
@Override
public void createMaterial(SrmTenderMaterialSaveReqVO createReqVO) {
+ SrmTenderProjectDO project = validateTenderExists(createReqVO.getTenderProjectId());
+ if (!TenderStatusEnum.canEditMaterial(project.getTenderStatus())) {
+ throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_MATERIAL_LOCKED);
+ }
SrmTenderMaterialDO material = BeanUtils.toBean(createReqVO, SrmTenderMaterialDO.class);
tenderMaterialMapper.insert(material);
}
@Override
public void updateMaterial(SrmTenderMaterialSaveReqVO updateReqVO) {
+ SrmTenderMaterialDO existing = tenderMaterialMapper.selectById(updateReqVO.getId());
+ if (existing != null) {
+ SrmTenderProjectDO project = tenderProjectMapper.selectById(existing.getTenderProjectId());
+ if (project != null && !TenderStatusEnum.canEditMaterial(project.getTenderStatus())) {
+ throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_MATERIAL_LOCKED);
+ }
+ }
SrmTenderMaterialDO updateObj = BeanUtils.toBean(updateReqVO, SrmTenderMaterialDO.class);
tenderMaterialMapper.updateById(updateObj);
}
@Override
public void deleteMaterial(Long id) {
+ SrmTenderMaterialDO material = tenderMaterialMapper.selectById(id);
+ if (material != null) {
+ SrmTenderProjectDO project = tenderProjectMapper.selectById(material.getTenderProjectId());
+ if (project != null && !TenderStatusEnum.canEditMaterial(project.getTenderStatus())) {
+ throw ServiceExceptionUtil.exception(ErrorCodeConstants.TENDER_MATERIAL_LOCKED);
+ }
+ }
tenderMaterialMapper.deleteById(id);
}
--
Gitblit v1.9.3