From 6faf65a6a7e72b7ecff52355f798fd00a516ba77 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期四, 30 四月 2026 17:37:13 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_NEW_pro' into dev_NEW_pro
---
src/views/procurementManagement/procurementInvoiceLedger/index.vue | 159 -
src/views/productionManagement/processRoute/index.vue | 3
src/views/collaborativeApproval/rulesRegulationsManagement/index.vue | 80
src/views/basicData/product/index.vue | 1132 +++++----
src/views/productionManagement/processRoute/processRouteItem/index.vue | 20
jsconfig.json | 10
src/api/productionManagement/productionOrder.js | 9
src/views/salesManagement/salesLedger/index.vue | 34
src/views/productionManagement/workOrderManagement/index.vue | 27
src/views/salesManagement/invoiceLedger/index.vue | 25
src/views/productionManagement/productionTraceability/index.vue | 831 +++++++
src/components/Dialog/FileList.vue | 29
src/layout/components/Sidebar/index.vue | 234 +-
src/views/safeProduction/safetyTrainingAssessment/index.vue | 49
src/views/customerService/afterSalesHandling/index.vue | 165 -
src/views/safeProduction/safeQualifications/index.vue | 40
src/views/inventoryManagement/stockManagement/New.vue | 9
src/api/productionManagement/productionProcess.js | 6
src/components/PIMTable/PIMTable.vue | 5
src/views/financialManagement/revenueManagement/index.vue | 423 +--
src/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue | 33
src/router/index.js | 40
src/views/productionManagement/workOrderEdit/index.vue | 5
src/views/financialManagement/expenseManagement/index.vue | 176 -
src/views/productionManagement/productionOrder/components/MaterialDetailDialog.vue | 5
src/views/procurementManagement/procurementLedger/index.vue | 2436 ++++++++++----------
src/main.js | 3
src/views/productionManagement/productionOrder/index.vue | 68
FILE_UPLOAD_README.md | 480 ++++
src/api/basicData/productProcess.js | 10
src/views/safeProduction/dangerInvestigation/index.vue | 178 -
31 files changed, 3,638 insertions(+), 3,086 deletions(-)
diff --git a/FILE_UPLOAD_README.md b/FILE_UPLOAD_README.md
new file mode 100644
index 0000000..ad5b42a
--- /dev/null
+++ b/FILE_UPLOAD_README.md
@@ -0,0 +1,480 @@
+# 鏈湴鏂囦欢涓婁紶 README
+
+鏈枃妗e熀浜庝互涓嬪疄鐜版暣鐞嗭細
+
+- `src/components/AttachmentUpload/file/index.vue`
+- `src/components/AttachmentUpload/image/index.vue`
+- `src/components/AttachmentPreview/image/index.vue`
+- `src/components/Dialog/FileList.vue`
+- `src/api/basicData/common.js`
+- `src/api/publicApi/commonFile.js`
+
+鐩稿叧缁勪欢宸插湪 `src/main.js` 涓敞鍐屼负鍏ㄥ眬缁勪欢锛屽彲鐩存帴鍦ㄩ〉闈腑浣跨敤锛�
+
+- `FileUpload`
+- `ImageUpload`
+- `ImagePreview`
+- `FileListDialog`
+
+## 1. 鍔熻兘姒傝
+
+褰撳墠杩欏涓婁紶鑳藉姏涓昏鍒嗕负 4 閮ㄥ垎锛�
+
+1. `FileUpload`锛氭櫘閫氭枃浠朵笂浼狅紝鏀寔鎷栨嫿銆佹壒閲忎笂浼犮�侀瑙堛�佸垹闄�
+2. `ImageUpload`锛氬浘鐗囦笂浼狅紝鏀寔鍥剧墖澧欏睍绀恒�侀瑙堛�佸垹闄�
+3. `ImagePreview`锛氬浘鐗囧垪琛ㄩ瑙堝睍绀�
+4. `FileListDialog`锛氫笟鍔¢檮浠跺脊绐楋紝鏀寔鏌ヨ銆佷笂浼犮�佸垹闄ゃ�佷笅杞�
+
+涓婁紶搴曞眰缁熶竴璧版帴鍙o細
+
+- `POST /common/upload`
+
+瀵瑰簲鏂规硶鍦� `src/api/basicData/common.js`锛�
+
+```js
+uploadFile(data)
+```
+
+## 2. 涓婁紶鎺ュ彛璇存槑
+
+### 2.1 閫氱敤涓婁紶鎺ュ彛
+
+鏂囦欢涓婁紶缁勪欢鍜屽浘鐗囦笂浼犵粍浠堕兘璋冪敤浜嗭細
+
+```js
+import { uploadFile } from '@/api/basicData/common'
+```
+
+鎺ュ彛鐗瑰緛锛�
+
+- 璇锋眰鏂瑰紡锛歚POST`
+- 鍦板潃锛歚/common/upload`
+- 璇锋眰绫诲瀷锛歚multipart/form-data`
+- 鏀寔 `FormData` 鎵归噺涓婁紶
+- 榛樿瀛楁鍚嶏細`files`
+
+缁勪欢鍐呴儴浼氳繖鏍风粍瑁呭弬鏁帮細
+
+```js
+const formData = new FormData()
+validFiles.forEach((file) => {
+ formData.append(props.uploadFieldName, file.raw)
+})
+```
+
+### 2.2 涓婁紶杩斿洖鍊艰姹�
+
+涓婁紶鎴愬姛鍚庯紝缁勪欢浼氬皾璇曚粠浠ヤ笅缁撴瀯涓彁鍙栨暟缁勶細
+
+- `response`
+- `response.data`
+- `response.data.data`
+- `response.payload`
+- `response.payload.data`
+- `response.rows`
+- `response.result`
+
+鍥犳鍚庣杩斿洖鏁扮粍鏃讹紝涓婇潰浠绘剰涓�绉嶇粨鏋勯兘鍙互琚瘑鍒��
+
+缁勪欢灞曠ず鏃跺父鐢ㄥ埌鐨勫瓧娈垫湁锛�
+
+- 鏂囦欢鍚嶏細`name` / `originalFilename` / `fileName` / `uidFilename`
+- 鏂囦欢鍦板潃锛歚url` / `downloadURL`
+- 鍥剧墖鍦板潃锛歚url` / `previewURL` / `previewUrl`
+- 涓婚敭锛歚id`
+
+寤鸿涓婁紶鎺ュ彛杩斿洖鐨勫崟椤瑰璞″敖閲忓寘鍚細
+
+```js
+{
+ id: 1,
+ originalFilename: 'demo.pdf',
+ downloadURL: 'https://xxx/demo.pdf',
+ previewURL: 'https://xxx/demo.png'
+}
+```
+
+## 3. FileUpload 鏂囦欢涓婁紶缁勪欢
+
+缁勪欢璺緞锛�
+
+`src/components/AttachmentUpload/file/index.vue`
+
+### 3.1 鍩虹鐢ㄦ硶
+
+```vue
+<template>
+ <FileUpload v-model:file-list="fileList" />
+</template>
+
+<script setup>
+import { ref } from 'vue'
+
+const fileList = ref([])
+</script>
+```
+
+### 3.2 甯哥敤灞炴��
+
+| 灞炴�� | 璇存槑 | 绫诲瀷 | 榛樿鍊� |
+| --- | --- | --- | --- |
+| `fileList` | 缁戝畾鏂囦欢鍒楄〃 | `Array` | `[]` |
+| `limit` | 鏈�澶т笂浼犳暟閲� | `Number` | `10` |
+| `fileSize` | 鍗曚釜鏂囦欢澶у皬闄愬埗锛屽崟浣� MB | `Number` | `50` |
+| `fileType` | 鍏佽涓婁紶鐨勬枃浠剁被鍨嬶紝濡� `['pdf', 'docx']` | `Array` | `[]` |
+| `buttonText` | 涓婁紶鎻愮ず鏂囨 | `String` | `鍗曞嚮閫夋嫨鏂囦欢` |
+| `disabled` | 鏄惁绂佺敤 | `Boolean` | `false` |
+| `uploadFieldName` | `FormData` 瀛楁鍚� | `String` | `files` |
+| `index` | 琛ㄦ牸/鍒楄〃琛屾ā寮忎笅鐨勫綋鍓嶈绱㈠紩 | `Number` | `-1` |
+| `childrenKey` | 琛屽唴鎸傝浇瀛楁鍚� | `String` | `files` |
+
+### 3.3 浜嬩欢
+
+| 浜嬩欢 | 璇存槑 |
+| --- | --- |
+| `update:fileList` | 鏂囦欢鍒楄〃鍙樺寲鏃惰Е鍙� |
+| `change` | 鏂囦欢鍒楄〃鍙樺寲鏃惰Е鍙戯紝杩斿洖鏈�鏂板垪琛� |
+
+### 3.4 闄愬埗瑙勫垯
+
+缁勪欢鍐呭凡瀹炵幇锛�
+
+- 鏂囦欢鏁伴噺闄愬埗
+- 鏂囦欢澶у皬闄愬埗
+- 鏂囦欢绫诲瀷鏍¢獙
+- 涓婁紶涓姸鎬侀攣瀹�
+- 澶辫触鍚庤嚜鍔ㄦ竻绌哄綋鍓嶉�夋嫨闃熷垪
+
+渚嬪闄愬埗 PDF/Word锛�
+
+```vue
+<FileUpload
+ v-model:file-list="fileList"
+ :limit="5"
+ :file-size="20"
+ :file-type="['pdf', 'doc', 'docx']"
+/>
+```
+
+### 3.5 杩斿洖鏁版嵁鏍煎紡寤鸿
+
+`FileUpload` 鏇撮�傚悎鎺ユ敹杩欐牱鐨勫垪琛細
+
+```js
+[
+ {
+ id: 1,
+ originalFilename: '鍚堝悓.pdf',
+ downloadURL: 'https://xxx/contract.pdf'
+ }
+]
+```
+
+鍥犱负缁勪欢鎵撳紑鏂囦欢鏃朵細浼樺厛璇诲彇锛�
+
+```js
+url || downloadURL || previewURL || previewUrl
+```
+
+### 3.6 琛屽唴宓屽妯″紡
+
+濡傛灉涓婁紶缁勪欢鏀惧湪琛ㄦ牸鏌愪竴琛屼腑锛屽彲閰嶅悎 `index` 鍜� `childrenKey` 浣跨敤锛�
+
+```vue
+<FileUpload
+ v-model:file-list="tableData"
+ :index="scope.$index"
+ children-key="files"
+/>
+```
+
+姝ゆ椂缁勪欢浼氳嚜鍔ㄨ鍐欙細
+
+```js
+tableData[scope.$index].files
+```
+
+## 4. ImageUpload 鍥剧墖涓婁紶缁勪欢
+
+缁勪欢璺緞锛�
+
+`src/components/AttachmentUpload/image/index.vue`
+
+### 4.1 鍩虹鐢ㄦ硶
+
+```vue
+<template>
+ <ImageUpload v-model:file-list="imageList" />
+</template>
+
+<script setup>
+import { ref } from 'vue'
+
+const imageList = ref([])
+</script>
+```
+
+### 4.2 榛樿琛屼负
+
+鍥剧墖涓婁紶缁勪欢榛樿锛�
+
+- 鏈�澶氫笂浼� `10` 寮�
+- 鍗曞紶涓嶈秴杩� `10MB`
+- 榛樿鏀寔鏍煎紡锛歚png / jpg / jpeg / webp`
+- 浣跨敤 `picture-card` 椋庢牸灞曠ず
+- 鐐瑰嚮缂╃暐鍥惧彲棰勮澶у浘
+
+### 4.3 甯哥敤绀轰緥
+
+```vue
+<ImageUpload
+ v-model:file-list="imageList"
+ :limit="9"
+ :file-size="5"
+ :file-type="['png', 'jpg', 'jpeg']"
+ button-text="涓婁紶鍥剧墖"
+/>
+```
+
+### 4.4 杩斿洖鏁版嵁鏍煎紡寤鸿
+
+`ImageUpload` 灞曠ず鍥剧墖鏃朵紭鍏堣鍙栵細
+
+```js
+url || previewURL || previewUrl
+```
+
+寤鸿鍚庣杩斿洖锛�
+
+```js
+[
+ {
+ id: 1,
+ originalFilename: '鐜板満鍥剧墖.jpg',
+ previewURL: 'https://xxx/image.jpg'
+ }
+]
+```
+
+### 4.5 琛屽唴宓屽妯″紡
+
+鍥剧墖缁勪欢鍚屾牱鏀寔琛屽唴瀛楁鍐欏洖锛�
+
+```vue
+<ImageUpload
+ v-model:file-list="tableData"
+ :index="scope.$index"
+ children-key="images"
+/>
+```
+
+榛樿鍐欏洖瀛楁涓� `images`銆�
+
+## 5. ImagePreview 鍥剧墖棰勮缁勪欢
+
+缁勪欢璺緞锛�
+
+`src/components/AttachmentPreview/image/index.vue`
+
+### 5.1 鍩虹鐢ㄦ硶
+
+```vue
+<ImagePreview :file-list="imageList" />
+```
+
+### 5.2 鍙厤缃」
+
+| 灞炴�� | 璇存槑 | 绫诲瀷 | 榛樿鍊� |
+| --- | --- | --- | --- |
+| `fileList` | 鍥剧墖鍒楄〃 | `Array` | `[]` |
+| `thumbSize` | 缂╃暐鍥惧ぇ灏� | `Number` | `72` |
+| `gap` | 缂╃暐鍥鹃棿璺� | `Number` | `10` |
+
+### 5.3 鏁版嵁瑕佹眰
+
+缁勪欢浼氳繃婊ゆ病鏈� `previewURL` 鐨勯」锛屽洜姝ゅ鏋滆姝e父鏄剧ず锛屽缓璁嚦灏戝寘鍚細
+
+```js
+[
+ {
+ previewURL: 'https://xxx/image.jpg',
+ originalFilename: '鍥剧墖1.jpg'
+ }
+]
+```
+
+濡傛灉鍒楄〃涓虹┖锛岀粍浠舵樉绀衡�滄殏鏃犲浘鐗団�濄��
+
+## 6. FileListDialog 闄勪欢寮圭獥缁勪欢
+
+缁勪欢璺緞锛�
+
+`src/components/Dialog/FileList.vue`
+
+杩欎釜缁勪欢閫傚悎涓氬姟琛ㄥ崟鎴栬鎯呴〉閲岀殑鈥滈檮浠剁鐞嗏�濆満鏅紝鑳藉姏鍖呮嫭锛�
+
+- 鏍规嵁涓氬姟涓婚敭鏌ヨ闄勪欢鍒楄〃
+- 鎵撳紑寮圭獥鏌ョ湅闄勪欢
+- 鍦ㄥ脊绐椾腑缁х画涓婁紶闄勪欢
+- 鍒犻櫎闄勪欢
+- 涓嬭浇闄勪欢
+
+### 6.1 缁勪欢灞炴��
+
+| 灞炴�� | 璇存槑 | 绫诲瀷 | 榛樿鍊� |
+| --- | --- | --- | --- |
+| `visible` | 鏄惁鏄剧ず寮圭獥 | `Boolean` | 蹇呬紶 |
+| `recordType` | 涓氬姟绫诲瀷 | `String` | `''` |
+| `recordId` | 涓氬姟涓婚敭 | `Number` | `0` |
+| `title` | 寮圭獥鏍囬 | `String` | `闄勪欢` |
+| `width` | 寮圭獥瀹藉害 | `String` | `50%` |
+| `showActions` | 鏄惁鏄剧ず涓嬭浇/鍒犻櫎鎿嶄綔鍒� | `Boolean` | `true` |
+
+### 6.2 鍩虹鐢ㄦ硶
+
+```vue
+<template>
+ <el-button @click="visible = true">鏌ョ湅闄勪欢</el-button>
+
+ <FileListDialog
+ v-model:visible="visible"
+ record-type="salesLedger"
+ :record-id="rowId"
+ title="闄勪欢鍒楄〃"
+ />
+</template>
+
+<script setup>
+import { ref } from 'vue'
+
+const visible = ref(false)
+const rowId = ref(1001)
+</script>
+```
+
+### 6.3 缁勪欢鍐呴儴渚濊禆鐨勬帴鍙�
+
+`FileListDialog` 鏈韩涓嶇洿鎺ヨ皟鐢� `commonFile.js`锛岃�屾槸渚濊禆锛�
+
+- `attachmentList`
+- `createAttachment`
+- `deleteAttachment`
+
+澶勭悊閫昏緫涓猴細
+
+1. 鎵撳紑寮圭獥鍚庢牴鎹� `recordType + recordId` 鏌ヨ闄勪欢
+2. 鐐瑰嚮鈥滀笂浼犻檮浠垛�濆悗锛屽唴閮ㄤ娇鐢� `AttachmentUpload/file` 鍏堜笂浼犲埌 `/common/upload`
+3. 涓婁紶鎴愬姛鍚庯紝灏嗚繑鍥炵殑鏂囦欢瀵硅薄鍜屽凡鏈夊垪琛ㄤ竴璧锋彁浜ょ粰 `createAttachment`
+4. 鍒犻櫎鏃惰皟鐢� `deleteAttachment`
+5. 涓嬭浇鏃剁洿鎺� `window.open(downloadURL, '_blank')`
+
+鍥犳杩欓噷瑕佺壒鍒敞鎰忥細
+
+- `recordType` 鍜� `recordId` 蹇呴』鏄湁鏁堜笟鍔℃爣璇�
+- 涓婁紶鎴愬姛杩斿洖鐨勬暟鎹紝闇�瑕佽兘琚� `createAttachment` 鐩存帴鎺ユ敹
+- 鍒楄〃涓殑涓嬭浇鍦板潃瀛楁搴斾负 `downloadURL`
+
+## 7. commonFile.js 璇存槑
+
+鏂囦欢璺緞锛�
+
+`src/api/publicApi/commonFile.js`
+
+褰撳墠鏂囦欢鎻愪緵鐨勬槸鍏叡鏂囦欢鍒犻櫎鎺ュ彛锛�
+
+```js
+delCommonFile(ids)
+delCommonFileInvoiceLedger(ids)
+```
+
+瀵瑰簲鎺ュ彛锛�
+
+- `/commonFile/delCommonFile`
+- `/invoiceLedger/delFile`
+
+杩欎袱涓柟娉曟洿閫傚悎宸茬粡鍜屽叿浣撲笟鍔$粦瀹氬悗鐨勨�滃垹闄ゅ凡淇濆瓨闄勪欢鈥濆満鏅紝涓嶈礋璐d笂浼犳枃浠舵湰韬��
+
+绀轰緥锛�
+
+```js
+import { delCommonFile } from '@/api/publicApi/commonFile'
+
+await delCommonFile([1, 2, 3])
+```
+
+## 8. 鎺ㄨ崘浣跨敤鏂瑰紡
+
+### 8.1 鏅�氫笟鍔¤〃鍗曚笂浼犻檮浠�
+
+```vue
+<FileUpload v-model:file-list="form.storageBlobDTOs" />
+```
+
+鎻愪氦琛ㄥ崟鏃剁洿鎺ュ甫涓婏細
+
+```js
+{
+ ...form,
+ storageBlobDTOs: form.storageBlobDTOs
+}
+```
+
+### 8.2 鍥剧墖绫讳笟鍔�
+
+```vue
+<ImageUpload v-model:file-list="form.images" />
+<ImagePreview :file-list="form.images" />
+```
+
+### 8.3 宸茶惤搴撻檮浠剁鐞�
+
+```vue
+<FileListDialog
+ v-model:visible="dialogVisible"
+ :record-type="recordType"
+ :record-id="recordId"
+/>
+```
+
+閫傚悎璇︽儏椤点�佸鎵归〉銆佸彴璐﹂〉杩欑被鈥滄煡鐪嬪苟缁存姢褰撳墠涓氬姟闄勪欢鈥濈殑鍦烘櫙銆�
+
+## 9. 娉ㄦ剰浜嬮」
+
+1. `FileUpload` 鍜� `ImageUpload` 鍙槸璐熻矗鎶婃枃浠跺厛浼犲埌 `/common/upload`锛屼笉绛変簬宸茬粡鍜屼笟鍔℃暟鎹粦瀹氥��
+2. 濡傛灉涓氬姟闇�瑕佹寔涔呭寲闄勪欢鍏崇郴锛屼粛闇�瑕佸湪淇濆瓨琛ㄥ崟鏃舵妸杩斿洖鐨勬枃浠跺璞℃彁浜ょ粰涓氬姟鎺ュ彛銆�
+3. `ImagePreview` 褰撳墠鍙瘑鍒� `previewURL`锛屽鏋滃悗绔彧杩斿洖 `url`锛岄瑙堢粍浠跺皢涓嶄細灞曠ず锛屾渶濂界粺涓�琛ラ綈 `previewURL`銆�
+4. `FileListDialog` 渚濊禆 `recordType`銆乣recordId` 鏌ヨ鍜屼繚瀛橀檮浠跺叧绯伙紝鏂板涓氬姟鏃惰鍏堢‘璁ゅ悗绔叧鑱旀帴鍙e彲鐢ㄣ��
+5. 鍒犻櫎鏈湴鍒楄〃椤瑰拰鍒犻櫎宸蹭繚瀛橀檮浠舵槸涓や欢浜嬶細
+ - 涓婁紶缁勪欢閲岀殑鍒犻櫎锛氬彧浼氫粠褰撳墠鍓嶇缁戝畾鏁扮粍涓Щ闄�
+ - `commonFile.js` / `deleteAttachment`锛氭墠鏄湡姝h皟鐢ㄥ悗绔垹闄�
+
+## 10. 涓�濂楁渶甯歌鐨勯〉闈㈠啓娉�
+
+```vue
+<template>
+ <el-form :model="form">
+ <el-form-item label="闄勪欢">
+ <FileUpload v-model:file-list="form.storageBlobDTOs" :limit="5" />
+ </el-form-item>
+
+ <el-form-item label="鐜板満鍥剧墖">
+ <ImageUpload v-model:file-list="form.images" :limit="9" />
+ </el-form-item>
+
+ <el-form-item label="鍥剧墖棰勮">
+ <ImagePreview :file-list="form.images" />
+ </el-form-item>
+ </el-form>
+</template>
+
+<script setup>
+import { ref } from 'vue'
+
+const form = ref({
+ storageBlobDTOs: [],
+ images: [],
+})
+</script>
+```
+
+濡傛灉浣犵殑鐩爣鏄�滃厛涓婁紶锛屽啀璺熶笟鍔′竴璧蜂繚瀛樷�濓紝杩欏鍐欐硶鍙互鐩存帴浣滀负鍩虹妯℃澘浣跨敤銆�
diff --git a/jsconfig.json b/jsconfig.json
new file mode 100644
index 0000000..365552f
--- /dev/null
+++ b/jsconfig.json
@@ -0,0 +1,10 @@
+{
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["src/*"],
+ "~/*": ["./*"]
+ }
+ },
+ "include": ["src/**/*.js", "src/**/*.vue", "vite.config.js"]
+}
diff --git a/src/api/basicData/productProcess.js b/src/api/basicData/productProcess.js
index e0208fa..46356fd 100644
--- a/src/api/basicData/productProcess.js
+++ b/src/api/basicData/productProcess.js
@@ -1,10 +1,10 @@
-import request from '@/utils/request'
+import request from "@/utils/request";
// 宸ュ簭鍒楄〃鍒嗛〉鏌ヨ
export function productProcessListPage(query) {
return request({
- url: '/productProcess/listPage',
- method: 'get',
- params: query
- })
+ url: "/technologyOperation/listPage",
+ method: "get",
+ params: query,
+ });
}
diff --git a/src/api/productionManagement/productionOrder.js b/src/api/productionManagement/productionOrder.js
index 688abfc..9b5751d 100644
--- a/src/api/productionManagement/productionOrder.js
+++ b/src/api/productionManagement/productionOrder.js
@@ -45,6 +45,15 @@
});
}
+// 鐢熶骇璁㈠崟-淇敼
+export function updateProductOrder(data) {
+ return request({
+ url: "/productionOrder/updateOrder",
+ method: "post",
+ data: data,
+ });
+}
+
export function delProductOrder(ids) {
return request({
url: `/productionOrder/delete`,
diff --git a/src/api/productionManagement/productionProcess.js b/src/api/productionManagement/productionProcess.js
index 7001997..783f584 100644
--- a/src/api/productionManagement/productionProcess.js
+++ b/src/api/productionManagement/productionProcess.js
@@ -4,7 +4,7 @@
// 鍒嗛〉鏌ヨ
export function listPage(query) {
return request({
- url: "/productProcess/listPage",
+ url: "/technologyOperation/listPage",
method: "get",
params: query,
});
@@ -53,7 +53,7 @@
// 瀵煎叆鏁版嵁
export function importData(data) {
return request({
- url: "/productProcess/importData",
+ url: "/technologyOperation/importData",
method: "post",
data: data,
});
@@ -62,7 +62,7 @@
// 涓嬭浇妯℃澘
export function downloadTemplate() {
return request({
- url: "/productProcess/downloadTemplate",
+ url: "/technologyOperation/downloadTemplate",
method: "post",
responseType: "blob",
});
diff --git a/src/components/Dialog/FileList.vue b/src/components/Dialog/FileList.vue
index 136ff8b..6e0ca23 100644
--- a/src/components/Dialog/FileList.vue
+++ b/src/components/Dialog/FileList.vue
@@ -5,7 +5,8 @@
@close="handleClose"
class="attachment-dialog">
<!-- 宸ュ叿鏍� -->
- <div class="toolbar">
+ <div v-if="editable"
+ class="toolbar">
<el-button type="primary"
size="small"
@click="handleUpload">
@@ -16,10 +17,11 @@
<el-dialog v-model="uploadDialogVisible"
title="涓婁紶闄勪欢"
width="50%"
- @close="handleUploadClose">
+ @close="closeUpload">
<AttachmentUpload v-model:file-list="newFileList" />
<template #footer>
- <el-button @click="handleUploadClose">鍏抽棴</el-button>
+ <el-button @click="saveUpload">淇濆瓨</el-button>
+ <el-button @click="closeUpload">鍏抽棴</el-button>
</template>
</el-dialog>
<!-- 鏂囦欢鍒楄〃琛ㄦ牸 -->
@@ -40,11 +42,12 @@
<el-button link
type="primary"
size="small"
- :href="scope.row.downloadURL"
- class="download-link">
+ class="download-link"
+ @click="downloadFile(scope.row.downloadURL)">
涓嬭浇
</el-button>
- <el-button link
+ <el-button v-if="editable"
+ link
type="danger"
size="small"
@click="handleDelete(scope.row)">
@@ -93,6 +96,10 @@
type: Boolean,
default: true,
},
+ editable: {
+ type: Boolean,
+ default: true,
+ },
});
const emit = defineEmits(["close", "download", "upload", "delete"]);
@@ -119,7 +126,7 @@
uploadDialogVisible.value = true;
};
- const handleUploadClose = async () => {
+ const saveUpload = async () => {
// 妫�鏌ユ槸鍚︽湁鏂颁笂浼犵殑鏂囦欢
if (newFileList.value.length > 0) {
try {
@@ -136,6 +143,11 @@
proxy?.$modal?.msgError("涓婁紶澶辫触");
}
}
+ uploadDialogVisible.value = false;
+ };
+
+ const closeUpload = () => {
+ newFileList.value = [];
uploadDialogVisible.value = false;
};
@@ -160,6 +172,9 @@
});
};
+ const downloadFile = url => {
+ window.open(url, "_blank");
+ };
onMounted(() => {
setList();
});
diff --git a/src/components/PIMTable/PIMTable.vue b/src/components/PIMTable/PIMTable.vue
index 61df179..f99b1eb 100644
--- a/src/components/PIMTable/PIMTable.vue
+++ b/src/components/PIMTable/PIMTable.vue
@@ -21,6 +21,7 @@
class="lims-table">
<el-table-column align="center"
type="selection"
+ :selectable="selectable"
width="55"
v-if="isSelection" />
<el-table-column align="center"
@@ -258,6 +259,10 @@
type: Boolean,
default: false,
},
+ selectable: {
+ type: Function,
+ default: () => true,
+ },
isShowPagination: {
type: Boolean,
default: true,
diff --git a/src/layout/components/Sidebar/index.vue b/src/layout/components/Sidebar/index.vue
index 83d3026..0692dda 100644
--- a/src/layout/components/Sidebar/index.vue
+++ b/src/layout/components/Sidebar/index.vue
@@ -1,142 +1,142 @@
<template>
- <div :class="{ 'has-logo': showLogo }" class="sidebar-container">
- <logo v-if="showLogo" :collapse="isCollapse" />
+ <div :class="{ 'has-logo': showLogo }"
+ class="sidebar-container">
+ <logo v-if="showLogo"
+ :collapse="isCollapse" />
<el-scrollbar wrap-class="scrollbar-wrapper">
- <el-menu
- :default-active="activeMenu"
- :collapse="isCollapse"
- :background-color="getMenuBackground"
- :text-color="getMenuTextColor"
- :unique-opened="true"
- :active-text-color="theme"
- :collapse-transition="false"
- mode="vertical"
- :class="sideTheme"
- >
- <sidebar-item
- v-for="(route, index) in sidebarRouters"
- :key="route.path + index"
- :item="route"
- :base-path="route.path"
- />
+ <el-menu :default-active="activeMenu"
+ :collapse="isCollapse"
+ :background-color="getMenuBackground"
+ :text-color="getMenuTextColor"
+ :unique-opened="true"
+ :active-text-color="theme"
+ :collapse-transition="false"
+ mode="vertical"
+ :class="sideTheme">
+ <sidebar-item v-for="(route, index) in sidebarRouters"
+ :key="route.path + index"
+ :item="route"
+ :base-path="route.path" />
</el-menu>
</el-scrollbar>
</div>
</template>
<script setup>
-import Logo from './Logo'
-import SidebarItem from './SidebarItem'
-import variables from '@/assets/styles/variables.module.scss'
-import useAppStore from '@/store/modules/app'
-import useSettingsStore from '@/store/modules/settings'
-import usePermissionStore from '@/store/modules/permission'
+ import Logo from "./Logo";
+ import SidebarItem from "./SidebarItem";
+ import variables from "@/assets/styles/variables.module.scss";
+ import useAppStore from "@/store/modules/app";
+ import useSettingsStore from "@/store/modules/settings";
+ import usePermissionStore from "@/store/modules/permission";
-const route = useRoute()
-const appStore = useAppStore()
-const settingsStore = useSettingsStore()
-const permissionStore = usePermissionStore()
+ const route = useRoute();
+ const appStore = useAppStore();
+ const settingsStore = useSettingsStore();
+ const permissionStore = usePermissionStore();
-const sidebarRouters = computed(() => permissionStore.sidebarRouters)
-const showLogo = computed(() => settingsStore.sidebarLogo)
-const sideTheme = computed(() => settingsStore.sideTheme)
-const theme = computed(() => settingsStore.theme)
-const isCollapse = computed(() => !appStore.sidebar.opened)
+ const sidebarRouters = computed(() => permissionStore.sidebarRouters);
+ const showLogo = computed(() => settingsStore.sidebarLogo);
+ const sideTheme = computed(() => settingsStore.sideTheme);
+ const theme = computed(() => settingsStore.theme);
+ const isCollapse = computed(() => !appStore.sidebar.opened);
-const getMenuBackground = computed(() => 'var(--sidebar-bg)')
+ const getMenuBackground = computed(() => "var(--sidebar-bg)");
-const getMenuTextColor = computed(() => {
- if (settingsStore.isDark) {
- return 'var(--sidebar-text)'
- }
- return sideTheme.value === 'theme-dark' ? variables.menuText : variables.menuLightText
-})
+ const getMenuTextColor = computed(() => {
+ if (settingsStore.isDark) {
+ return "var(--sidebar-text)";
+ }
+ return sideTheme.value === "theme-dark"
+ ? variables.menuText
+ : variables.menuLightText;
+ });
-const activeMenu = computed(() => {
- const { meta, path } = route
- if (meta.activeMenu) {
- return meta.activeMenu
- }
- return path
-})
+ const activeMenu = computed(() => {
+ const { meta, path } = route;
+ if (meta.activeMenu) {
+ return meta.activeMenu;
+ }
+ return path;
+ });
</script>
<style lang="scss" scoped>
-.sidebar-container {
- background-color: v-bind(getMenuBackground);
- border-radius: 22px;
- overflow: hidden;
-
- .scrollbar-wrapper {
+ .sidebar-container {
background-color: v-bind(getMenuBackground);
- }
-
- .el-menu {
- border: none;
- height: 100%;
- width: 100% !important;
border-radius: 22px;
+ overflow: hidden;
- .el-menu-item,
- .el-sub-menu__title {
- margin-bottom: 6px;
- border-radius: 14px;
- color: v-bind(getMenuTextColor);
+ .scrollbar-wrapper {
+ background-color: v-bind(getMenuBackground);
+ }
- &:hover {
- background-color: var(--menu-hover, rgba(0, 0, 0, 0.06)) !important;
+ .el-menu {
+ border: none;
+ height: 100%;
+ width: 100% !important;
+ border-radius: 22px;
+
+ .el-menu-item,
+ .el-sub-menu__title {
+ margin-bottom: 6px;
+ border-radius: 14px;
+ color: v-bind(getMenuTextColor);
+
+ &:hover {
+ background-color: var(--menu-hover, rgba(0, 0, 0, 0.06)) !important;
+ border-radius: 14px;
+ }
+ }
+
+ .el-menu-item {
+ &.is-active {
+ color: v-bind(theme);
+ background-color: var(--menu-active-bg, rgba(0, 0, 0, 0.06)) !important;
+ font-weight: 600;
+ }
+ }
+
+ .el-sub-menu__title {
+ color: v-bind(getMenuTextColor);
+ }
+
+ :deep(.el-sub-menu.is-active > .el-sub-menu__title) {
+ color: v-bind(theme) !important;
+ font-weight: 600;
+ background-color: var(--menu-active-bg, rgba(0, 0, 0, 0.06)) !important;
+ border-radius: 14px;
+ margin: 0 10px 6px !important;
+ // width: calc(100% - 20px) !important;
+ padding-left: 10px !important;
+ padding-right: 10px !important;
+ box-sizing: border-box;
+ overflow: hidden;
+ background-clip: padding-box;
+ }
+
+ :deep(.el-menu-item.is-active) {
+ margin: 0 10px 6px !important;
+ width: calc(100% - 20px) !important;
+ padding-left: 10px !important;
+ padding-right: 10px !important;
+ box-sizing: border-box;
+ overflow: hidden;
+ background-clip: padding-box;
+ border-radius: 14px;
+ }
+
+ :deep(.el-sub-menu.is-active > .el-sub-menu__title .menu-title),
+ :deep(.el-sub-menu.is-active > .el-sub-menu__title .svg-icon),
+ :deep(.el-menu-item.is-active .menu-title),
+ :deep(.el-menu-item.is-active .svg-icon) {
+ color: v-bind(theme) !important;
+ }
+
+ :deep(.el-sub-menu__title:hover),
+ :deep(.el-menu-item:hover) {
border-radius: 14px;
}
}
-
- .el-menu-item {
- &.is-active {
- color: v-bind(theme);
- background-color: var(--menu-active-bg, rgba(0, 0, 0, 0.06)) !important;
- font-weight: 600;
- }
- }
-
- .el-sub-menu__title {
- color: v-bind(getMenuTextColor);
- }
-
- :deep(.el-sub-menu.is-active > .el-sub-menu__title) {
- color: v-bind(theme) !important;
- font-weight: 600;
- background-color: var(--menu-active-bg, rgba(0, 0, 0, 0.06)) !important;
- border-radius: 14px;
- margin: 0 10px 6px !important;
- width: calc(100% - 20px) !important;
- padding-left: 10px !important;
- padding-right: 10px !important;
- box-sizing: border-box;
- overflow: hidden;
- background-clip: padding-box;
- }
-
- :deep(.el-menu-item.is-active) {
- margin: 0 10px 6px !important;
- width: calc(100% - 20px) !important;
- padding-left: 10px !important;
- padding-right: 10px !important;
- box-sizing: border-box;
- overflow: hidden;
- background-clip: padding-box;
- border-radius: 14px;
- }
-
- :deep(.el-sub-menu.is-active > .el-sub-menu__title .menu-title),
- :deep(.el-sub-menu.is-active > .el-sub-menu__title .svg-icon),
- :deep(.el-menu-item.is-active .menu-title),
- :deep(.el-menu-item.is-active .svg-icon) {
- color: v-bind(theme) !important;
- }
-
- :deep(.el-sub-menu__title:hover),
- :deep(.el-menu-item:hover) {
- border-radius: 14px;
- }
}
-}
</style>
diff --git a/src/main.js b/src/main.js
index b80c9b6..025ff14 100644
--- a/src/main.js
+++ b/src/main.js
@@ -48,6 +48,8 @@
import ImageUpload from "@/components/AttachmentUpload/image";
// 鍥剧墖棰勮缁勪欢
import ImagePreview from "@/components/AttachmentPreview/image";
+// 闄勪欢寮圭獥缁勪欢
+import FileListDialog from "@/components/Dialog/FileList.vue";
// 瀛楀吀鏍囩缁勪欢
import DictTag from "@/components/DictTag";
// 琛ㄦ牸缁勪欢
@@ -92,6 +94,7 @@
app.component("FileUpload", FileUpload);
app.component("ImageUpload", ImageUpload);
app.component("ImagePreview", ImagePreview);
+app.component("FileListDialog", FileListDialog);
app.component("RightToolbar", RightToolbar);
app.component("Editor", Editor);
app.component("PIMTable", PIMTable);
diff --git a/src/router/index.js b/src/router/index.js
index cc2b88c..c9b163c 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -146,106 +146,106 @@
path: "general-ledger",
component: () => import("@/views/financialManagement/generalLedger/index.vue"),
name: "GeneralLedger",
- meta: { title: "鎬诲笎绉戠洰" }
+ meta: { title: "鎬诲笎绉戠洰" },
},
{
path: "sales-out",
component: () => import("@/views/financialManagement/receivable/salesOut.vue"),
name: "SalesOut",
- meta: { title: "閿�鍞嚭搴�" }
+ meta: { title: "閿�鍞嚭搴�" },
},
{
path: "sales-return",
component: () => import("@/views/financialManagement/receivable/salesReturn.vue"),
name: "SalesReturn",
- meta: { title: "閿�鍞��璐�" }
+ meta: { title: "閿�鍞��璐�" },
},
{
path: "receivable-reconciliation",
component: () => import("@/views/financialManagement/receivable/reconciliation.vue"),
name: "ReceivableReconciliation",
- meta: { title: "搴旀敹瀵硅处" }
+ meta: { title: "搴旀敹瀵硅处" },
},
{
path: "invoice-apply",
component: () => import("@/views/financialManagement/receivable/invoiceApply.vue"),
name: "InvoiceApply",
- meta: { title: "寮�绁ㄧ敵璇�" }
+ meta: { title: "寮�绁ㄧ敵璇�" },
},
{
path: "output-invoice",
component: () => import("@/views/financialManagement/receivable/outputInvoice.vue"),
name: "OutputInvoice",
- meta: { title: "閿�椤瑰彂绁�" }
+ meta: { title: "閿�椤瑰彂绁�" },
},
{
path: "receipt",
component: () => import("@/views/financialManagement/receivable/receipt.vue"),
name: "Receipt",
- meta: { title: "鏀舵鍗�" }
+ meta: { title: "鏀舵鍗�" },
},
{
path: "purchase-in",
component: () => import("@/views/financialManagement/payable/purchaseIn.vue"),
name: "PurchaseIn",
- meta: { title: "閲囪喘鍏ュ簱" }
+ meta: { title: "閲囪喘鍏ュ簱" },
},
{
path: "payable-reconciliation",
component: () => import("@/views/financialManagement/payable/reconciliation.vue"),
name: "PayableReconciliation",
- meta: { title: "搴斾粯瀵硅处" }
+ meta: { title: "搴斾粯瀵硅处" },
},
{
path: "input-invoice",
component: () => import("@/views/financialManagement/payable/input-invoice.vue"),
name: "InputInvoice",
- meta: { title: "杩涢」鍙戠エ" }
+ meta: { title: "杩涢」鍙戠エ" },
},
{
path: "payment-apply",
component: () => import("@/views/financialManagement/payable/paymentApply.vue"),
name: "PaymentApply",
- meta: { title: "浠樻鐢宠" }
+ meta: { title: "浠樻鐢宠" },
},
{
path: "payment",
component: () => import("@/views/financialManagement/payable/payment.vue"),
name: "Payment",
- meta: { title: "浠樻鍗�" }
+ meta: { title: "浠樻鍗�" },
},
{
path: "fixed-assets",
component: () => import("@/views/financialManagement/assets/fixedAssets.vue"),
name: "FixedAssets",
- meta: { title: "鍥哄畾璧勪骇" }
+ meta: { title: "鍥哄畾璧勪骇" },
},
{
path: "intangible-assets",
component: () => import("@/views/financialManagement/assets/intangibleAssets.vue"),
name: "IntangibleAssets",
- meta: { title: "鏃犲舰璧勪骇" }
+ meta: { title: "鏃犲舰璧勪骇" },
},
{
path: "voucher",
component: () => import("@/views/financialManagement/voucher/index.vue"),
name: "Voucher",
- meta: { title: "鍑瘉" }
+ meta: { title: "鍑瘉" },
},
{
path: "voucher-general-ledger",
component: () => import("@/views/financialManagement/voucher/generalLedger.vue"),
name: "VoucherGeneralLedger",
- meta: { title: "绉戠洰鎬诲笎" }
+ meta: { title: "绉戠洰鎬诲笎" },
},
{
path: "voucher-detail-ledger",
component: () => import("@/views/financialManagement/voucher/detailLedger.vue"),
name: "VoucherDetailLedger",
- meta: { title: "绉戠洰鏄庣粏甯�" }
- }
- ]
- }
+ meta: { title: "绉戠洰鏄庣粏甯�" },
+ },
+ ],
+ },
];
// 鍔ㄦ�佽矾鐢憋紝鍩轰簬鐢ㄦ埛鏉冮檺鍔ㄦ�佸幓鍔犺浇
diff --git a/src/views/basicData/product/index.vue b/src/views/basicData/product/index.vue
index 10b51bf..99ab028 100644
--- a/src/views/basicData/product/index.vue
+++ b/src/views/basicData/product/index.vue
@@ -2,41 +2,34 @@
<div class="app-container product-view">
<div class="left">
<div>
- <el-input
- v-model="search"
- style="width: 210px"
- placeholder="杈撳叆鍏抽敭瀛楄繘琛屾悳绱�"
- @change="searchFilter"
- @clear="searchFilter"
- clearable
- prefix-icon="Search"
- />
- <el-button
- v-if="false"
- type="primary"
- @click="openProDia('addOne')"
- style="margin-left: 10px"
- >鏂板浜у搧澶х被</el-button
- >
+ <el-input v-model="search"
+ style="width: 210px"
+ placeholder="杈撳叆鍏抽敭瀛楄繘琛屾悳绱�"
+ @change="searchFilter"
+ @clear="searchFilter"
+ clearable
+ prefix-icon="Search" />
+ <el-button v-if="false"
+ type="primary"
+ @click="openProDia('addOne')"
+ style="margin-left: 10px">鏂板浜у搧澶х被</el-button>
</div>
<div ref="containerRef">
- <el-tree
- ref="tree"
- v-loading="treeLoad"
- :data="list"
- @node-click="handleNodeClick"
- :expand-on-click-node="false"
- @node-expand="handleNodeExpand"
- @node-collapse="handleNodeCollapse"
- :key="treeKey"
- :default-expanded-keys="expandedKeys"
- :filter-node-method="filterNode"
- :props="{ children: 'children', label: 'label' }"
- highlight-current
- node-key="id"
- class="product-tree-scroll"
- style="height: calc(100vh - 190px); overflow-y: auto"
- >
+ <el-tree ref="tree"
+ v-loading="treeLoad"
+ :data="list"
+ @node-click="handleNodeClick"
+ :expand-on-click-node="false"
+ @node-expand="handleNodeExpand"
+ @node-collapse="handleNodeCollapse"
+ :key="treeKey"
+ :default-expanded-keys="expandedKeys"
+ :filter-node-method="filterNode"
+ :props="{ children: 'children', label: 'label' }"
+ highlight-current
+ node-key="id"
+ class="product-tree-scroll"
+ style="height: calc(100vh - 190px); overflow-y: auto">
<template #default="{ node, data }">
<div class="custom-tree-node">
<span class="tree-node-content">
@@ -47,25 +40,23 @@
<span class="tree-node-label">{{ data.label }}</span>
</span>
<div>
- <el-button
- type="primary"
- link
- :disabled="isTopLevelNode(data, node)"
- @click="openProDia('edit', data)"
- >
+ <el-button type="primary"
+ link
+ :disabled="isTopLevelNode(data, node)"
+ @click="openProDia('edit', data)">
缂栬緫
</el-button>
- <el-button type="primary" link @click="openProDia('add', data)">
+ <el-button type="primary"
+ link
+ @click="openProDia('add', data)">
娣诲姞浜у搧
</el-button>
- <el-button
- v-if="!node.childNodes.length"
- style="margin-left: 4px"
- type="danger"
- link
- :disabled="isTopLevelNode(data, node)"
- @click="remove(node, data)"
- >
+ <el-button v-if="!node.childNodes.length"
+ style="margin-left: 4px"
+ type="danger"
+ link
+ :disabled="isTopLevelNode(data, node)"
+ @click="remove(node, data)">
鍒犻櫎
</el-button>
</div>
@@ -75,103 +66,109 @@
</div>
</div>
<div class="right">
- <div style="margin-bottom: 10px" v-if="isShowButton">
- <el-button type="primary" @click="openModelDia('add')">
+ <div style="margin-bottom: 10px"
+ v-if="isShowButton">
+ <el-button type="primary"
+ @click="openModelDia('add')">
鏂板瑙勬牸鍨嬪彿
</el-button>
- <ImportExcel :product-id="currentId" @uploadSuccess="getModelList" />
- <el-button
- type="danger"
- @click="handleDelete"
- style="margin-left: 10px"
- plain
- >
+ <ImportExcel :product-id="currentId"
+ @uploadSuccess="getModelList" />
+ <el-button type="danger"
+ @click="handleDelete"
+ style="margin-left: 10px"
+ plain>
鍒犻櫎
</el-button>
</div>
- <PIMTable
- rowKey="id"
- :column="tableColumn"
- :tableData="tableData"
- :page="page"
- :isSelection="true"
- @selection-change="handleSelectionChange"
- :tableLoading="tableLoading"
- @pagination="pagination"
- ></PIMTable>
+ <PIMTable rowKey="id"
+ :column="tableColumn"
+ :tableData="tableData"
+ :page="page"
+ :isSelection="true"
+ @selection-change="handleSelectionChange"
+ :tableLoading="tableLoading"
+ @pagination="pagination"></PIMTable>
</div>
- <el-dialog v-model="productDia" title="浜у搧" width="400px" @keydown.enter.prevent>
- <el-form
- :model="form"
- label-width="140px"
- label-position="top"
- :rules="rules"
- ref="formRef"
- >
+ <el-dialog v-model="productDia"
+ title="浜у搧"
+ width="400px"
+ @keydown.enter.prevent>
+ <el-form :model="form"
+ label-width="140px"
+ label-position="top"
+ :rules="rules"
+ ref="formRef">
<el-row :gutter="30">
<el-col :span="24">
- <el-form-item label="浜у搧鍚嶇О锛�" prop="productName">
- <el-input
- v-model="form.productName"
- placeholder="璇疯緭鍏ヤ骇鍝佸悕绉�"
- maxlength="20"
- show-word-limit
- clearable
- @keydown.enter.prevent
- />
+ <el-form-item label="浜у搧鍚嶇О锛�"
+ prop="productName">
+ <el-input v-model="form.productName"
+ placeholder="璇疯緭鍏ヤ骇鍝佸悕绉�"
+ maxlength="20"
+ show-word-limit
+ clearable
+ @keydown.enter.prevent />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<div class="dialog-footer">
- <el-button type="primary" @click="submitForm">纭</el-button>
+ <el-button type="primary"
+ @click="submitForm">纭</el-button>
<el-button @click="closeProDia">鍙栨秷</el-button>
</div>
</template>
</el-dialog>
- <el-dialog
- v-model="modelDia"
- title="瑙勬牸鍨嬪彿"
- width="400px"
- @close="closeModelDia"
- @keydown.enter.prevent
- >
- <el-form
- :model="modelForm"
- label-width="140px"
- label-position="top"
- :rules="modelRules"
- ref="modelFormRef"
- >
+ <el-dialog v-model="modelDia"
+ title="瑙勬牸鍨嬪彿"
+ width="400px"
+ @close="closeModelDia"
+ @keydown.enter.prevent>
+ <el-form :model="modelForm"
+ label-width="140px"
+ label-position="top"
+ :rules="modelRules"
+ ref="modelFormRef">
<el-row>
+ <el-row>
+ <el-col :span="24">
+ <el-form-item label="浜у搧缂栧彿锛�"
+ prop="productCode">
+ <el-input v-model="modelForm.productCode"
+ placeholder="璇疯緭鍏ヤ骇鍝佺紪鍙�"
+ clearable
+ @keydown.enter.prevent />
+ </el-form-item>
+ </el-col>
+ </el-row>
<el-col :span="24">
- <el-form-item label="瑙勬牸鍨嬪彿锛�" prop="model">
- <el-input
- v-model="modelForm.model"
- placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
- clearable
- @keydown.enter.prevent
- />
+ <el-form-item label="瑙勬牸鍨嬪彿锛�"
+ prop="model">
+ <el-input v-model="modelForm.model"
+ placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
+ clearable
+ @keydown.enter.prevent />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
- <el-form-item label="鍗曚綅锛�" prop="unit">
- <el-input
- v-model="modelForm.unit"
- placeholder="璇疯緭鍏ュ崟浣�"
- clearable
- @keydown.enter.prevent
- />
+ <el-form-item label="鍗曚綅锛�"
+ prop="unit">
+ <el-input v-model="modelForm.unit"
+ placeholder="璇疯緭鍏ュ崟浣�"
+ clearable
+ @keydown.enter.prevent />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<div class="dialog-footer">
- <el-button type="primary" @click="submitModelForm">纭</el-button>
+ <el-button type="primary"
+ @click="submitModelForm">纭</el-button>
<el-button @click="closeModelDia">鍙栨秷</el-button>
</div>
</template>
@@ -180,473 +177,480 @@
</template>
<script setup>
-import { nextTick, ref } from "vue";
-import { ElMessageBox } from "element-plus";
-import {
- addOrEditProduct,
- addOrEditProductModel,
- delProduct,
- delProductModel,
- modelListPage,
- productTreeList,
-} from "@/api/basicData/product.js";
-import ImportExcel from "./ImportExcel/index.vue";
+ import { nextTick, ref } from "vue";
+ import { ElMessageBox } from "element-plus";
+ import {
+ addOrEditProduct,
+ addOrEditProductModel,
+ delProduct,
+ delProductModel,
+ modelListPage,
+ productTreeList,
+ } from "@/api/basicData/product.js";
+ import ImportExcel from "./ImportExcel/index.vue";
-const { proxy } = getCurrentInstance();
-const tree = ref(null);
-const containerRef = ref(null);
-const treeKey = ref(0);
-const expandedKeySet = new Set();
-const EXPANDED_STORAGE_KEY = "basicData_product_tree_expanded_keys_v2";
+ const { proxy } = getCurrentInstance();
+ const tree = ref(null);
+ const containerRef = ref(null);
+ const treeKey = ref(0);
+ const expandedKeySet = new Set();
+ const EXPANDED_STORAGE_KEY = "basicData_product_tree_expanded_keys_v2";
-const loadExpandedKeys = () => {
- if (typeof window === "undefined") {
- return [];
- }
- try {
- const saved = localStorage.getItem(EXPANDED_STORAGE_KEY);
- return saved ? JSON.parse(saved) : [];
- } catch (error) {
- console.error(error);
- return [];
- }
-};
-
-const saveExpandedKeys = () => {
- if (typeof window === "undefined") {
- return;
- }
- localStorage.setItem(
- EXPANDED_STORAGE_KEY,
- JSON.stringify(Array.from(expandedKeySet))
- );
-};
-
-loadExpandedKeys().forEach((key) => expandedKeySet.add(key));
-
-const syncExpandedKeysFromTree = () => {
- const keys = [];
- const walk = (nodes) => {
- (nodes || []).forEach((item) => {
- if (item.expanded && item.data?.id !== undefined) {
- keys.push(item.data.id);
- }
- if (item.childNodes && item.childNodes.length) {
- walk(item.childNodes);
- }
- });
- };
-
- walk(tree.value?.root?.childNodes);
- expandedKeySet.clear();
- keys.forEach((key) => expandedKeySet.add(key));
- expandedKeys.value = keys;
- saveExpandedKeys();
-};
-
-const normalizeExpandedKeys = (treeData) => {
- const parentMap = new Map();
- const walk = (nodes, parentId = null) => {
- (nodes || []).forEach((item) => {
- parentMap.set(item.id, parentId);
- if (item.children && item.children.length) {
- walk(item.children, item.id);
- }
- });
- };
-
- walk(treeData);
-
- const normalizedKeys = Array.from(expandedKeySet).filter((key) => {
- if (!parentMap.has(key)) {
- return false;
+ const loadExpandedKeys = () => {
+ if (typeof window === "undefined") {
+ return [];
}
- let currentId = key;
- while (parentMap.has(currentId)) {
- const parentId = parentMap.get(currentId);
- if (!parentId) {
- return true;
- }
- if (!expandedKeySet.has(parentId)) {
+ try {
+ const saved = localStorage.getItem(EXPANDED_STORAGE_KEY);
+ return saved ? JSON.parse(saved) : [];
+ } catch (error) {
+ console.error(error);
+ return [];
+ }
+ };
+
+ const saveExpandedKeys = () => {
+ if (typeof window === "undefined") {
+ return;
+ }
+ localStorage.setItem(
+ EXPANDED_STORAGE_KEY,
+ JSON.stringify(Array.from(expandedKeySet))
+ );
+ };
+
+ loadExpandedKeys().forEach(key => expandedKeySet.add(key));
+
+ const syncExpandedKeysFromTree = () => {
+ const keys = [];
+ const walk = nodes => {
+ (nodes || []).forEach(item => {
+ if (item.expanded && item.data?.id !== undefined) {
+ keys.push(item.data.id);
+ }
+ if (item.childNodes && item.childNodes.length) {
+ walk(item.childNodes);
+ }
+ });
+ };
+
+ walk(tree.value?.root?.childNodes);
+ expandedKeySet.clear();
+ keys.forEach(key => expandedKeySet.add(key));
+ expandedKeys.value = keys;
+ saveExpandedKeys();
+ };
+
+ const normalizeExpandedKeys = treeData => {
+ const parentMap = new Map();
+ const walk = (nodes, parentId = null) => {
+ (nodes || []).forEach(item => {
+ parentMap.set(item.id, parentId);
+ if (item.children && item.children.length) {
+ walk(item.children, item.id);
+ }
+ });
+ };
+
+ walk(treeData);
+
+ const normalizedKeys = Array.from(expandedKeySet).filter(key => {
+ if (!parentMap.has(key)) {
return false;
}
- currentId = parentId;
- }
- return true;
- });
-
- if (normalizedKeys.length !== expandedKeySet.size) {
- expandedKeySet.clear();
- normalizedKeys.forEach((key) => expandedKeySet.add(key));
- saveExpandedKeys();
- }
-};
-
-const productDia = ref(false);
-const modelDia = ref(false);
-const modelOperationType = ref("");
-const search = ref("");
-const currentId = ref("");
-const currentParentId = ref("");
-const operationType = ref("");
-const treeLoad = ref(false);
-const list = ref([]);
-const expandedKeys = ref([]);
-const tableColumn = ref([
- {
- label: "瑙勬牸鍨嬪彿",
- prop: "model",
- },
- {
- label: "鍗曚綅",
- prop: "unit",
- },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- operation: [
- {
- name: "缂栬緫",
- type: "text",
- clickFun: (row) => {
- openModelDia("edit", row);
- },
- },
- ],
- },
-]);
-const tableData = ref([]);
-const tableLoading = ref(false);
-const isShowButton = ref(false);
-const selectedRows = ref([]);
-const page = reactive({
- current: 1,
- size: 10,
- total: 0,
-});
-const data = reactive({
- form: {
- productName: "",
- },
- rules: {
- productName: [
- { required: true, message: "璇疯緭鍏�", trigger: "blur" },
- { max: 20, message: "浜у搧鍚嶇О涓嶈兘瓒呰繃20涓瓧绗�", trigger: "blur" },
- ],
- },
- modelForm: {
- model: "",
- unit: "",
- },
- modelRules: {
- model: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- unit: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- },
-});
-const { form, rules, modelForm, modelRules } = toRefs(data);
-// 鏌ヨ浜у搧鏍�
-const getProductTreeList = () => {
- treeLoad.value = true;
- productTreeList()
- .then((res) => {
- list.value = res || [];
- normalizeExpandedKeys(list.value);
- expandedKeys.value = Array.from(expandedKeySet);
- treeKey.value += 1;
- nextTick(() => {
- tree.value?.setDefaultExpandedKeys?.(expandedKeys.value);
- });
- })
- .catch((err) => {
- console.error(err);
- })
- .finally(() => {
- treeLoad.value = false;
- });
-};
-const handleNodeExpand = (data) => {
- nextTick(syncExpandedKeysFromTree);
-};
-const handleNodeCollapse = (data, node) => {
- node?.eachNode?.((item) => {
- item.collapse();
- });
- nextTick(syncExpandedKeysFromTree);
-};
-// 杩囨护浜у搧鏍�
-const searchFilter = () => {
- proxy.$refs.tree.filter(search.value);
-};
-const isTopLevelNode = (data, node) => {
- if (node?.level !== undefined) {
- return node.level === 1;
- }
- return [null, undefined, "", 0, "0"].includes(data?.parentId);
-};
-// 鎵撳紑浜у搧寮规
-const openProDia = (type, data) => {
- if (data && type === "edit" && isTopLevelNode(data)) {
- proxy.$modal.msgWarning("涓�绾ц妭鐐逛笉鑳界紪杈戞垨鍒犻櫎");
- return;
- }
- operationType.value = type;
- productDia.value = true;
- form.value.productName = "";
- if (type === "edit") {
- form.value.productName = data.productName;
- }
-};
-// 鎵撳紑瑙勬牸鍨嬪彿寮规
-const openModelDia = (type, data) => {
- modelOperationType.value = type;
- modelDia.value = true;
- modelForm.value.model = "";
- modelForm.value.model = "";
- modelForm.value.id = "";
- if (type === "edit") {
- modelForm.value = { ...data };
- }
-};
-// 鎻愪氦浜у搧鍚嶇О淇敼
-const submitForm = () => {
- proxy.$refs.formRef.validate((valid) => {
- if (valid) {
- if (operationType.value === "add") {
- form.value.parentId = currentId.value;
- form.value.id = "";
- } else if (operationType.value === "addOne") {
- form.value.id = "";
- form.value.parentId = "";
- } else {
- form.value.id = currentId.value;
- form.value.parentId = "";
+ let currentId = key;
+ while (parentMap.has(currentId)) {
+ const parentId = parentMap.get(currentId);
+ if (!parentId) {
+ return true;
+ }
+ if (!expandedKeySet.has(parentId)) {
+ return false;
+ }
+ currentId = parentId;
}
- addOrEditProduct(form.value).then((res) => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeProDia();
- getProductTreeList();
- });
- }
- });
-};
-// 鍏抽棴浜у搧寮规
-const closeProDia = () => {
- proxy.$refs.formRef.resetFields();
- productDia.value = false;
-};
+ return true;
+ });
-// 鍒犻櫎浜у搧
-const remove = (node, data) => {
- if (isTopLevelNode(data, node)) {
- proxy.$modal.msgWarning("涓�绾ц妭鐐逛笉鑳界紪杈戞垨鍒犻櫎");
- return;
- }
- let ids = [];
- ids.push(data.id);
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- tableLoading.value = true;
- delProduct(ids)
- .then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+ if (normalizedKeys.length !== expandedKeySet.size) {
+ expandedKeySet.clear();
+ normalizedKeys.forEach(key => expandedKeySet.add(key));
+ saveExpandedKeys();
+ }
+ };
+
+ const productDia = ref(false);
+ const modelDia = ref(false);
+ const modelOperationType = ref("");
+ const search = ref("");
+ const currentId = ref("");
+ const currentParentId = ref("");
+ const operationType = ref("");
+ const treeLoad = ref(false);
+ const list = ref([]);
+ const expandedKeys = ref([]);
+ const tableColumn = ref([
+ {
+ label: "浜у搧缂栧彿",
+ prop: "productCode",
+ },
+ {
+ label: "瑙勬牸鍨嬪彿",
+ prop: "model",
+ },
+ {
+ label: "鍗曚綅",
+ prop: "unit",
+ },
+ {
+ dataType: "action",
+ label: "鎿嶄綔",
+ align: "center",
+ operation: [
+ {
+ name: "缂栬緫",
+ type: "text",
+ clickFun: row => {
+ openModelDia("edit", row);
+ },
+ },
+ ],
+ },
+ ]);
+ const tableData = ref([]);
+ const tableLoading = ref(false);
+ const isShowButton = ref(false);
+ const selectedRows = ref([]);
+ const page = reactive({
+ current: 1,
+ size: 10,
+ total: 0,
+ });
+ const data = reactive({
+ form: {
+ productName: "",
+ },
+ rules: {
+ productName: [
+ { required: true, message: "璇疯緭鍏�", trigger: "blur" },
+ { max: 20, message: "浜у搧鍚嶇О涓嶈兘瓒呰繃20涓瓧绗�", trigger: "blur" },
+ ],
+ },
+ modelForm: {
+ model: "",
+ unit: "",
+ productCode: "",
+ },
+ modelRules: {
+ model: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ unit: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ productCode: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ },
+ });
+ const { form, rules, modelForm, modelRules } = toRefs(data);
+ // 鏌ヨ浜у搧鏍�
+ const getProductTreeList = () => {
+ treeLoad.value = true;
+ productTreeList()
+ .then(res => {
+ list.value = res || [];
+ normalizeExpandedKeys(list.value);
+ expandedKeys.value = Array.from(expandedKeySet);
+ treeKey.value += 1;
+ nextTick(() => {
+ tree.value?.setDefaultExpandedKeys?.(expandedKeys.value);
+ });
+ })
+ .catch(err => {
+ console.error(err);
+ })
+ .finally(() => {
+ treeLoad.value = false;
+ });
+ };
+ const handleNodeExpand = data => {
+ nextTick(syncExpandedKeysFromTree);
+ };
+ const handleNodeCollapse = (data, node) => {
+ node?.eachNode?.(item => {
+ item.collapse();
+ });
+ nextTick(syncExpandedKeysFromTree);
+ };
+ // 杩囨护浜у搧鏍�
+ const searchFilter = () => {
+ proxy.$refs.tree.filter(search.value);
+ };
+ const isTopLevelNode = (data, node) => {
+ if (node?.level !== undefined) {
+ return node.level === 1;
+ }
+ return [null, undefined, "", 0, "0"].includes(data?.parentId);
+ };
+ // 鎵撳紑浜у搧寮规
+ const openProDia = (type, data) => {
+ if (data && type === "edit" && isTopLevelNode(data)) {
+ proxy.$modal.msgWarning("涓�绾ц妭鐐逛笉鑳界紪杈戞垨鍒犻櫎");
+ return;
+ }
+ operationType.value = type;
+ productDia.value = true;
+ form.value.productName = "";
+ if (type === "edit") {
+ form.value.productName = data.productName;
+ }
+ };
+ // 鎵撳紑瑙勬牸鍨嬪彿寮规
+ const openModelDia = (type, data) => {
+ modelOperationType.value = type;
+ modelDia.value = true;
+ modelForm.value.model = "";
+ modelForm.value.unit = "";
+ modelForm.value.productCode = "";
+ modelForm.value.id = "";
+ if (type === "edit") {
+ modelForm.value = { ...data };
+ }
+ };
+ // 鎻愪氦浜у搧鍚嶇О淇敼
+ const submitForm = () => {
+ proxy.$refs.formRef.validate(valid => {
+ if (valid) {
+ if (operationType.value === "add") {
+ form.value.parentId = currentId.value;
+ form.value.id = "";
+ } else if (operationType.value === "addOne") {
+ form.value.id = "";
+ form.value.parentId = "";
+ } else {
+ form.value.id = currentId.value;
+ form.value.parentId = "";
+ }
+ addOrEditProduct(form.value).then(res => {
+ proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+ closeProDia();
getProductTreeList();
- })
- .finally(() => {
- tableLoading.value = false;
});
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
+ }
});
-};
-// 閫夋嫨浜у搧
-const handleNodeClick = (val, node, el) => {
- // 鍒ゆ柇鏄惁涓哄彾瀛愯妭鐐�
- isShowButton.value = !(val.children && val.children.length > 0);
- // 鍙湁鍙跺瓙鑺傜偣鎵嶆墽琛屼互涓嬮�昏緫
- currentId.value = val.id;
- currentParentId.value = val.parentId;
- getModelList();
-};
+ };
+ // 鍏抽棴浜у搧寮规
+ const closeProDia = () => {
+ proxy.$refs.formRef.resetFields();
+ productDia.value = false;
+ };
-// 鎻愪氦瑙勬牸鍨嬪彿淇敼
-const submitModelForm = () => {
- proxy.$refs.modelFormRef.validate((valid) => {
- if (valid) {
- modelForm.value.productId = currentId.value;
- addOrEditProductModel(modelForm.value).then((res) => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeModelDia();
- getModelList();
- });
+ // 鍒犻櫎浜у搧
+ const remove = (node, data) => {
+ if (isTopLevelNode(data, node)) {
+ proxy.$modal.msgWarning("涓�绾ц妭鐐逛笉鑳界紪杈戞垨鍒犻櫎");
+ return;
}
- });
-};
-// 鍏抽棴鍨嬪彿寮规
-const closeModelDia = () => {
- proxy.$refs.modelFormRef.resetFields();
- modelDia.value = false;
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-
-// 鏌ヨ瑙勬牸鍨嬪彿
-const pagination = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getModelList();
-};
-const getModelList = () => {
- tableLoading.value = true;
- modelListPage({
- id: currentId.value,
- current: page.current,
- size: page.size,
- }).then((res) => {
- console.log("res", res);
- tableData.value = res.records;
- page.total = res.total;
- tableLoading.value = false;
- });
-};
-// 鍒犻櫎瑙勬牸鍨嬪彿
-const handleDelete = () => {
- let ids = [];
- if (selectedRows.value.length > 0) {
- ids = selectedRows.value.map((item) => item.id);
- } else {
- proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
- return;
- }
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- tableLoading.value = true;
- delProductModel(ids)
- .then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getModelList();
- })
- .finally(() => {
- tableLoading.value = false;
- });
+ let ids = [];
+ ids.push(data.id);
+ ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
})
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
+ .then(() => {
+ tableLoading.value = true;
+ delProduct(ids)
+ .then(res => {
+ proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+ getProductTreeList();
+ })
+ .finally(() => {
+ tableLoading.value = false;
+ });
+ })
+ .catch(() => {
+ proxy.$modal.msg("宸插彇娑�");
+ });
+ };
+ // 閫夋嫨浜у搧
+ const handleNodeClick = (val, node, el) => {
+ // 鍒ゆ柇鏄惁涓哄彾瀛愯妭鐐�
+ isShowButton.value = !(val.children && val.children.length > 0);
+ // 鍙湁鍙跺瓙鑺傜偣鎵嶆墽琛屼互涓嬮�昏緫
+ currentId.value = val.id;
+ currentParentId.value = val.parentId;
+ getModelList();
+ };
+
+ // 鎻愪氦瑙勬牸鍨嬪彿淇敼
+ const submitModelForm = () => {
+ proxy.$refs.modelFormRef.validate(valid => {
+ if (valid) {
+ modelForm.value.productId = currentId.value;
+ addOrEditProductModel(modelForm.value).then(res => {
+ proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+ closeModelDia();
+ getModelList();
+ });
+ }
});
-};
-// 璋冪敤tree杩囨护鏂规硶 涓枃鑻辫繃婊�
-const filterNode = (value, data, node) => {
- if (!value) {
- //濡傛灉鏁版嵁涓虹┖锛屽垯杩斿洖true,鏄剧ず鎵�鏈夌殑鏁版嵁椤�
- return true;
- }
- // 鏌ヨ鍒楄〃鏄惁鏈夊尮閰嶆暟鎹紝灏嗗�煎皬鍐欙紝鍖归厤鑻辨枃鏁版嵁
- let val = value.toLowerCase();
- return chooseNode(val, data, node); // 璋冪敤杩囨护浜屽眰鏂规硶
-};
-// 杩囨护鐖惰妭鐐� / 瀛愯妭鐐� (濡傛灉杈撳叆鐨勫弬鏁版槸鐖惰妭鐐逛笖鑳藉尮閰嶏紝鍒欒繑鍥炶鑺傜偣浠ュ強鍏朵笅鐨勬墍鏈夊瓙鑺傜偣锛涘鏋滃弬鏁版槸瀛愯妭鐐癸紝鍒欒繑鍥炶鑺傜偣鐨勭埗鑺傜偣銆俷ame鏄腑鏂囧瓧绗︼紝enName鏄嫳鏂囧瓧绗�.
-const chooseNode = (value, data, node) => {
- if (data.label.indexOf(value) !== -1) {
- return true;
- }
- const level = node.level;
- // 濡傛灉浼犲叆鐨勮妭鐐规湰韬氨鏄竴绾ц妭鐐瑰氨涓嶇敤鏍¢獙浜�
- if (level === 1) {
- return false;
- }
- // 鍏堝彇褰撳墠鑺傜偣鐨勭埗鑺傜偣
- let parentData = node.parent;
- // 閬嶅巻褰撳墠鑺傜偣鐨勭埗鑺傜偣
- let index = 0;
- while (index < level - 1) {
- // 濡傛灉鍖归厤鍒扮洿鎺ヨ繑鍥烇紝姝ゅname鍊兼槸涓枃瀛楃锛宔nName鏄嫳鏂囧瓧绗︺�傚垽鏂尮閰嶄腑鑻辨枃杩囨护
- if (parentData.data.label.indexOf(value) !== -1) {
+ };
+ // 鍏抽棴鍨嬪彿寮规
+ const closeModelDia = () => {
+ proxy.$refs.modelFormRef.resetFields();
+ modelDia.value = false;
+ };
+ // 琛ㄦ牸閫夋嫨鏁版嵁
+ const handleSelectionChange = selection => {
+ selectedRows.value = selection;
+ };
+
+ // 鏌ヨ瑙勬牸鍨嬪彿
+ const pagination = obj => {
+ page.current = obj.page;
+ page.size = obj.limit;
+ getModelList();
+ };
+ const getModelList = () => {
+ tableLoading.value = true;
+ modelListPage({
+ id: currentId.value,
+ current: page.current,
+ size: page.size,
+ }).then(res => {
+ console.log("res", res);
+ tableData.value = res.records;
+ page.total = res.total;
+ tableLoading.value = false;
+ });
+ };
+ // 鍒犻櫎瑙勬牸鍨嬪彿
+ const handleDelete = () => {
+ let ids = [];
+ if (selectedRows.value.length > 0) {
+ ids = selectedRows.value.map(item => item.id);
+ } else {
+ proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+ return;
+ }
+ ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
+ .then(() => {
+ tableLoading.value = true;
+ delProductModel(ids)
+ .then(res => {
+ proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+ getModelList();
+ })
+ .finally(() => {
+ tableLoading.value = false;
+ });
+ })
+ .catch(() => {
+ proxy.$modal.msg("宸插彇娑�");
+ });
+ };
+ // 璋冪敤tree杩囨护鏂规硶 涓枃鑻辫繃婊�
+ const filterNode = (value, data, node) => {
+ if (!value) {
+ //濡傛灉鏁版嵁涓虹┖锛屽垯杩斿洖true,鏄剧ず鎵�鏈夌殑鏁版嵁椤�
return true;
}
- // 鍚﹀垯鐨勮瘽鍐嶅線涓婁竴灞傚仛鍖归厤
- parentData = parentData.parent;
- index++;
- }
- // 娌″尮閰嶅埌杩斿洖false
- return false;
-};
-getProductTreeList();
+ // 鏌ヨ鍒楄〃鏄惁鏈夊尮閰嶆暟鎹紝灏嗗�煎皬鍐欙紝鍖归厤鑻辨枃鏁版嵁
+ let val = value.toLowerCase();
+ return chooseNode(val, data, node); // 璋冪敤杩囨护浜屽眰鏂规硶
+ };
+ // 杩囨护鐖惰妭鐐� / 瀛愯妭鐐� (濡傛灉杈撳叆鐨勫弬鏁版槸鐖惰妭鐐逛笖鑳藉尮閰嶏紝鍒欒繑鍥炶鑺傜偣浠ュ強鍏朵笅鐨勬墍鏈夊瓙鑺傜偣锛涘鏋滃弬鏁版槸瀛愯妭鐐癸紝鍒欒繑鍥炶鑺傜偣鐨勭埗鑺傜偣銆俷ame鏄腑鏂囧瓧绗︼紝enName鏄嫳鏂囧瓧绗�.
+ const chooseNode = (value, data, node) => {
+ if (data.label.indexOf(value) !== -1) {
+ return true;
+ }
+ const level = node.level;
+ // 濡傛灉浼犲叆鐨勮妭鐐规湰韬氨鏄竴绾ц妭鐐瑰氨涓嶇敤鏍¢獙浜�
+ if (level === 1) {
+ return false;
+ }
+ // 鍏堝彇褰撳墠鑺傜偣鐨勭埗鑺傜偣
+ let parentData = node.parent;
+ // 閬嶅巻褰撳墠鑺傜偣鐨勭埗鑺傜偣
+ let index = 0;
+ while (index < level - 1) {
+ // 濡傛灉鍖归厤鍒扮洿鎺ヨ繑鍥烇紝姝ゅname鍊兼槸涓枃瀛楃锛宔nName鏄嫳鏂囧瓧绗︺�傚垽鏂尮閰嶄腑鑻辨枃杩囨护
+ if (parentData.data.label.indexOf(value) !== -1) {
+ return true;
+ }
+ // 鍚﹀垯鐨勮瘽鍐嶅線涓婁竴灞傚仛鍖归厤
+ parentData = parentData.parent;
+ index++;
+ }
+ // 娌″尮閰嶅埌杩斿洖false
+ return false;
+ };
+ getProductTreeList();
</script>
<style scoped>
-.product-view {
- display: flex;
-}
-.left {
- width: 450px;
- min-width: 450px;
- padding: 16px;
- background: #ffffff;
-}
-.right {
- flex: 1;
- min-width: 0;
- padding: 16px;
- margin-left: 20px;
- background: #ffffff;
-}
-.custom-tree-node {
- flex: 1;
- min-width: 0;
- display: flex;
- align-items: center;
- justify-content: space-between;
- font-size: 14px;
- padding-right: 8px;
-}
-.tree-node-content {
- flex: 1;
- min-width: 0;
- display: flex;
- align-items: center;
- height: 100%;
- overflow: hidden;
-}
-.tree-node-content .orange-icon {
- flex-shrink: 0;
-}
-.tree-node-label {
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-.orange-icon {
- color: orange;
- font-size: 18px;
- margin-right: 8px; /* 鍥炬爣涓庢枃瀛椾箣闂村姞鐐归棿璺� */
-}
-.product-tree-scroll {
- scrollbar-width: thin;
- scrollbar-color: #c0c4cc #f5f7fa;
-}
-.product-tree-scroll::-webkit-scrollbar {
- width: 8px;
-}
-.product-tree-scroll::-webkit-scrollbar-track {
- background: #f5f7fa;
- border-radius: 4px;
-}
-.product-tree-scroll::-webkit-scrollbar-thumb {
- background: #c0c4cc;
- border-radius: 4px;
-}
-.product-tree-scroll::-webkit-scrollbar-thumb:hover {
- background: #909399;
-}
+ .product-view {
+ display: flex;
+ }
+ .left {
+ width: 450px;
+ min-width: 450px;
+ padding: 16px;
+ background: #ffffff;
+ }
+ .right {
+ flex: 1;
+ min-width: 0;
+ padding: 16px;
+ margin-left: 20px;
+ background: #ffffff;
+ }
+ .custom-tree-node {
+ flex: 1;
+ min-width: 0;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ font-size: 14px;
+ padding-right: 8px;
+ }
+ .tree-node-content {
+ flex: 1;
+ min-width: 0;
+ display: flex;
+ align-items: center;
+ height: 100%;
+ overflow: hidden;
+ }
+ .tree-node-content .orange-icon {
+ flex-shrink: 0;
+ }
+ .tree-node-label {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+ .orange-icon {
+ color: orange;
+ font-size: 18px;
+ margin-right: 8px; /* 鍥炬爣涓庢枃瀛椾箣闂村姞鐐归棿璺� */
+ }
+ .product-tree-scroll {
+ scrollbar-width: thin;
+ scrollbar-color: #c0c4cc #f5f7fa;
+ }
+ .product-tree-scroll::-webkit-scrollbar {
+ width: 8px;
+ }
+ .product-tree-scroll::-webkit-scrollbar-track {
+ background: #f5f7fa;
+ border-radius: 4px;
+ }
+ .product-tree-scroll::-webkit-scrollbar-thumb {
+ background: #c0c4cc;
+ border-radius: 4px;
+ }
+ .product-tree-scroll::-webkit-scrollbar-thumb:hover {
+ background: #909399;
+ }
</style>
diff --git a/src/views/collaborativeApproval/rulesRegulationsManagement/index.vue b/src/views/collaborativeApproval/rulesRegulationsManagement/index.vue
index eb0802e..f7ba9d9 100644
--- a/src/views/collaborativeApproval/rulesRegulationsManagement/index.vue
+++ b/src/views/collaborativeApproval/rulesRegulationsManagement/index.vue
@@ -212,14 +212,7 @@
</el-table-column>
</el-table>
</el-dialog>
- <FileListDialog ref="fileListDialogRef"
- v-model="fileDialogVisible"
- :show-upload-button="true"
- :show-delete-button="true"
- :delete-method="handleAttachmentDelete"
- :rules-regulations-management-id="currentFileRuleId"
- :name-column-label="'闄勪欢鍚嶇О'"
- @upload="handleAttachmentUpload"/>
+ <FileList v-if="fileDialogVisible" v-model:visible="fileDialogVisible" record-type="rules_regulations_management" :record-id="recordId" />
</div>
</template>
@@ -235,7 +228,7 @@
addReadingStatus,
updateReadingStatus,
} from "@/api/collaborativeApproval/sealManagement.js";
- import FileListDialog from "@/components/Dialog/FileListDialog.vue";
+ const FileList = defineAsyncComponent(() => import("@/components/Dialog/FileList.vue"));
import {
listRuleFiles,
delRuleFile,
@@ -254,14 +247,7 @@
total: 0,
});
// 闄勪欢寮圭獥
- const fileDialogVisible = ref(false);
- const fileListDialogRef = ref(null);
const currentFileRuleId = ref(null);
- const filePage = reactive({
- current: 1,
- size: 1000,
- total: 0,
- });
// 瑙勭珷鍒跺害鐩稿叧
const showRegulationDialog = ref(false);
const showRegulationDetailDialog = ref(false);
@@ -564,63 +550,15 @@
);
};
- // 闄勪欢锛氭煡璇�
- const fetchRuleFiles = async rulesRegulationsManagementId => {
- const params = {
- current: filePage.current,
- size: filePage.size,
- rulesRegulationsManagementId,
- };
- const res = await listRuleFiles(params);
- const records = res?.data?.records || [];
- filePage.total = res?.data?.total || records.length;
- const mapped = records.map(item => ({
- id: item.id,
- name: item.fileName || item.name,
- url: item.fileUrl || item.url,
- raw: item,
- }));
- fileListDialogRef.value?.setList(mapped);
- };
-
// 鎵撳紑闄勪欢寮圭獥
- const openFileDialog = async row => {
- currentFileRuleId.value = row.id;
- fileDialogVisible.value = true;
- await fetchRuleFiles(row.id);
- };
+ const recordId =ref(0)
+ const fileDialogVisible = ref(false)
- // 鍒锋柊闄勪欢鍒楄〃
- const refreshFileList = async () => {
- if (!currentFileRuleId.value) return;
- await fetchRuleFiles(currentFileRuleId.value);
- };
-
- // 涓婁紶闄勪欢锛堢敱瀛愮粍浠惰Е鍙戯級
- const handleAttachmentUpload = async filePayload => {
- if (!currentFileRuleId.value) return;
- const payload = {
- name: filePayload?.fileName || filePayload?.name,
- url: filePayload?.fileUrl || filePayload?.url,
- rulesRegulationsManagementId: currentFileRuleId.value,
- };
- await addRuleFile(payload);
- ElMessage.success("鏂囦欢涓婁紶鎴愬姛");
- await refreshFileList();
- };
-
- // 鍒犻櫎闄勪欢
- const handleAttachmentDelete = async row => {
- if (!row?.id) return false;
- try {
- await ElMessageBox.confirm("纭鍒犻櫎璇ラ檮浠讹紵", "鎻愮ず", { type: "warning" });
- } catch {
- return false;
- }
- await delRuleFile([row.id]);
- ElMessage.success("鍒犻櫎鎴愬姛");
- await refreshFileList();
- };
+ // 鎵撳紑闄勪欢寮规
+ const openFileDialog = async (row) => {
+ recordId.value = row.id
+ fileDialogVisible.value = true
+ }
// 鑾峰彇瑙勭珷鍒跺害鍒楄〃鏁版嵁
const getRegulationList = async () => {
diff --git a/src/views/customerService/afterSalesHandling/index.vue b/src/views/customerService/afterSalesHandling/index.vue
index 57cc2eb..d023f51 100644
--- a/src/views/customerService/afterSalesHandling/index.vue
+++ b/src/views/customerService/afterSalesHandling/index.vue
@@ -102,33 +102,19 @@
></PIMTable>
</div>
<form-dia ref="formDia" @close="handleQuery"></form-dia>
- <FileListDialog
- ref="fileListRef"
- v-model="fileListDialogVisible"
- title="鍞悗闄勪欢"
- :show-upload-button="true"
- :show-delete-button="true"
- :upload-method="handleFileUpload"
- :delete-method="handleFileDelete"
- />
- </div>
+ <FileList v-if="fileDialogVisible" v-model:visible="fileDialogVisible" record-type="after_sales_service" :record-id="recordId" />
+ </div>
</template>
<script setup>
-import { onMounted, ref, reactive, toRefs, getCurrentInstance, nextTick } from "vue";
+import {onMounted, ref, reactive, toRefs, getCurrentInstance, nextTick, defineAsyncComponent} from "vue";
import FormDia from "@/views/customerService/afterSalesHandling/components/formDia.vue";
-import FileListDialog from "@/components/Dialog/FileListDialog.vue";
import { ElMessageBox } from "element-plus";
-import request from "@/utils/request";
-import { getToken } from "@/utils/auth";
import {
afterSalesServiceListPage,
- afterSalesServiceFileListPage,
- afterSalesServiceFileDel,
} from "@/api/customerService/index.js";
-import useUserStore from "@/store/modules/user.js";
const { proxy } = getCurrentInstance();
-const userStore = useUserStore()
+const FileList = defineAsyncComponent(() => import("@/components/Dialog/FileList.vue"));
const data = reactive({
searchForm: {
@@ -303,144 +289,15 @@
})
}
+
+// 鎵撳紑闄勪欢寮圭獥
+const recordId =ref(0)
+const fileDialogVisible = ref(false)
+
// 鎵撳紑闄勪欢寮规
const openFilesFormDia = async (row) => {
- currentFileRow.value = row
- try {
- const res = await afterSalesServiceFileListPage({
- afterSalesServiceId: row.id,
- current: 1,
- size: 100,
- })
- if (res.code === 200 && fileListRef.value) {
- const fileList = (res.data?.records || []).map((item) => ({
- name: item.name || item.fileName,
- url: item.url || item.fileUrl,
- id: item.id,
- ...item,
- }))
- fileListRef.value.open(fileList)
- fileListDialogVisible.value = true
- } else {
- fileListRef.value?.open([])
- fileListDialogVisible.value = true
- }
- } catch (error) {
- proxy.$modal.msgError("鑾峰彇闄勪欢鍒楄〃澶辫触")
- fileListRef.value?.open([])
- fileListDialogVisible.value = true
- }
-}
-
-// 涓婁紶闄勪欢
-const handleFileUpload = async () => {
- if (!currentFileRow.value) {
- proxy.$modal.msgWarning("璇峰厛閫夋嫨鏁版嵁")
- return
- }
- return new Promise((resolve) => {
- const input = document.createElement("input")
- input.type = "file"
- input.style.display = "none"
- input.onchange = async (e) => {
- const file = e.target.files[0]
- if (!file) {
- resolve(null)
- return
- }
- try {
- const formData = new FormData()
- formData.append("file", file)
- formData.append("id", currentFileRow.value.id)
- const uploadRes = await request({
- url: "/afterSalesService/file/upload",
- method: "post",
- data: formData,
- headers: {
- "Content-Type": "multipart/form-data",
- Authorization: `Bearer ${getToken()}`,
- },
- })
- if (uploadRes.code === 200) {
- proxy.$modal.msgSuccess("鏂囦欢涓婁紶鎴愬姛")
- // 閲嶆柊鑾峰彇鏂囦欢鍒楄〃
- const listRes = await afterSalesServiceFileListPage({
- afterSalesServiceId: currentFileRow.value.id,
- current: 1,
- size: 100,
- })
- if (listRes.code === 200 && fileListRef.value) {
- const fileList = (listRes.data?.records || []).map((item) => ({
- name: item.fileName,
- url: item.fileUrl,
- id: item.id,
- ...item,
- }))
- fileListRef.value.setList(fileList)
- }
- resolve({ name: file.name, url: "", id: null })
- } else {
- proxy.$modal.msgError(uploadRes.msg || "鏂囦欢涓婁紶澶辫触")
- resolve(null)
- }
- } catch (err) {
- proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触")
- resolve(null)
- } finally {
- document.body.removeChild(input)
- }
- }
- document.body.appendChild(input)
- input.click()
- })
-}
-
-// 鍒犻櫎闄勪欢
-const handleFileDelete = async (row) => {
- try {
- // 娣诲姞纭瀵硅瘽妗�
- const confirmResult = await ElMessageBox.confirm(
- '纭畾瑕佸垹闄よ繖涓檮浠跺悧锛�',
- '鍒犻櫎纭',
- {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }
- )
-
- if (confirmResult === 'confirm') {
- const res = await afterSalesServiceFileDel(row.id)
- if (res.code === 200) {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛")
- if (currentFileRow.value && fileListRef.value) {
- const listRes = await afterSalesServiceFileListPage({
- afterSalesServiceId: currentFileRow.value.id,
- current: 1,
- size: 100,
- })
- if (listRes.code === 200) {
- const fileList = (listRes.data?.records || []).map((item) => ({
- name: item.fileName,
- url: item.fileUrl,
- id: item.id,
- ...item,
- }))
- fileListRef.value.setList(fileList)
- }
- }
- } else {
- proxy.$modal.msgError(res.msg || "鍒犻櫎澶辫触")
- return false
- }
- }
- } catch (error) {
- // 濡傛灉鐢ㄦ埛鍙栨秷鍒犻櫎锛屼笉鏄剧ず閿欒淇℃伅
- if (error !== 'cancel') {
- proxy.$modal.msgError("鍒犻櫎澶辫触")
- }
- return false
- }
+ recordId.value = row.id
+ fileDialogVisible.value = true
}
// 鏌ヨ鍒楄〃
diff --git a/src/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue b/src/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue
index b7fa07e..923dd2c 100644
--- a/src/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue
+++ b/src/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue
@@ -228,39 +228,6 @@
form.value.entryDate = getCurrentDate();
}
-// 涓婁紶鍓嶆牎妫�
-function handleBeforeUpload(file) {
- proxy.$modal.loading("姝e湪涓婁紶鏂囦欢锛岃绋嶅��...");
- return true;
-}
-// 涓婁紶澶辫触
-function handleUploadError(err) {
- proxy.$modal.msgError("涓婁紶鏂囦欢澶辫触");
- proxy.$modal.closeLoading();
-}
-// 涓婁紶鎴愬姛鍥炶皟
-function handleUploadSuccess(res, file, uploadFiles) {
- proxy.$modal.closeLoading();
- if (res.code === 200) {
- file.tempId = res.data.tempId;
- form.value.tempFileIds.push(file.tempId);
- proxy.$modal.msgSuccess("涓婁紶鎴愬姛");
- } else {
- proxy.$modal.msgError(res.msg);
- proxy.$refs.fileUpload.handleRemove(file);
- }
-}
-// 绉婚櫎鏂囦欢
-function handleRemove(file) {
- if (operationType.value === "edit") {
- let ids = [];
- ids.push(file.id);
- delLedgerFile(ids).then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- });
- }
-}
-
// 澶勭悊鏈夋晥鏃ユ湡杈撳叆锛屽彧鍏佽姝f暣鏁�
const handleValidInput = (value) => {
if (value === '' || value === null || value === undefined) {
diff --git a/src/views/financialManagement/expenseManagement/index.vue b/src/views/financialManagement/expenseManagement/index.vue
index ac55d01..173f8e1 100644
--- a/src/views/financialManagement/expenseManagement/index.vue
+++ b/src/views/financialManagement/expenseManagement/index.vue
@@ -76,27 +76,18 @@
</PIMTable>
</div>
<Modal ref="modalRef" @success="getTableData"></Modal>
- <FileListDialog
- ref="fileListRef"
- v-model="fileListDialogVisible"
- :show-upload-button="true"
- :show-delete-button="true"
- :upload-method="handleUpload"
- :delete-method="handleFileDelete"
- />
+ <FileList v-if="fileDialogVisible" v-model:visible="fileDialogVisible" record-type="account_expense" :record-id="recordId" />
</div>
</template>
<script setup>
import { usePaginationApi } from "@/hooks/usePaginationApi";
-import { listPage, delAccountExpense, fileListPage, fileAdd, fileDel } from "@/api/financialManagement/expenseManagement";
-import { onMounted, getCurrentInstance, ref, computed } from "vue";
+import { listPage, delAccountExpense } from "@/api/financialManagement/expenseManagement";
+import {onMounted, getCurrentInstance, ref, computed, defineAsyncComponent} from "vue";
import Modal from "./Modal.vue";
import { ElMessageBox, ElMessage } from "element-plus";
import dayjs from "dayjs";
-import FileListDialog from "@/components/Dialog/FileListDialog.vue";
-import request from "@/utils/request";
-import { getToken } from "@/utils/auth";
+const FileList = defineAsyncComponent(() => import("@/components/Dialog/FileList.vue"));
defineOptions({
name: "鏀嚭绠$悊",
@@ -108,9 +99,6 @@
const modalRef = ref();
const { checkout_payment } = proxy.useDict("checkout_payment");
const { expense_types } = proxy.useDict("expense_types");
-const fileListRef = ref(null);
-const fileListDialogVisible = ref(false);
-const currentFileRow = ref(null);
const accountType = ref('鏀嚭');
const {
@@ -315,156 +303,16 @@
proxy.$modal.msg("宸插彇娑�");
});
};
+
+// 鎵撳紑闄勪欢寮圭獥
+const recordId =ref(0)
+const fileDialogVisible = ref(false)
+
// 鎵撳紑闄勪欢寮规
const openFilesFormDia = async (row) => {
- currentFileRow.value = row;
- accountType.value = '鏀嚭';
- try {
- const res = await fileListPage({
- accountId: row.id,
- accountType: accountType.value,
- current: 1,
- size: 100
- });
- if (res.code === 200 && fileListRef.value) {
- // 灏嗘暟鎹浆鎹负 FileListDialog 闇�瑕佺殑鏍煎紡
- const fileList = (res.data?.records || []).map(item => ({
- name: item.name,
- url: item.url,
- id: item.id,
- ...item
- }));
- fileListRef.value.open(fileList);
- fileListDialogVisible.value = true;
- }
- } catch (error) {
- proxy.$modal.msgError("鑾峰彇闄勪欢鍒楄〃澶辫触");
- }
-};
-
-// 涓婁紶闄勪欢
-const handleUpload = async () => {
- if (!currentFileRow.value) {
- proxy.$modal.msgWarning("璇峰厛閫夋嫨鏁版嵁");
- return null;
- }
-
- return new Promise((resolve) => {
- // 鍒涘缓涓�涓殣钘忕殑鏂囦欢杈撳叆鍏冪礌
- const input = document.createElement('input');
- input.type = 'file';
- input.style.display = 'none';
- input.onchange = async (e) => {
- const file = e.target.files[0];
- if (!file) {
- resolve(null);
- return;
- }
-
- try {
- // 浣跨敤 FormData 涓婁紶鏂囦欢
- const formData = new FormData();
- formData.append('file', file);
-
- const uploadRes = await request({
- url: '/file/upload',
- method: 'post',
- data: formData,
- headers: {
- 'Content-Type': 'multipart/form-data',
- Authorization: `Bearer ${getToken()}`
- }
- });
-
- if (uploadRes.code === 200) {
- // 淇濆瓨闄勪欢淇℃伅
- const fileData = {
- accountId: currentFileRow.value.id,
- accountType: accountType.value,
- name: uploadRes.data.originalName || file.name,
- url: uploadRes.data.tempPath || uploadRes.data.url
- };
-
- const saveRes = await fileAdd(fileData);
- if (saveRes.code === 200) {
- proxy.$modal.msgSuccess("鏂囦欢涓婁紶鎴愬姛");
- // 閲嶆柊鍔犺浇鏂囦欢鍒楄〃
- const listRes = await fileListPage({
- accountId: currentFileRow.value.id,
- accountType: accountType.value,
- current: 1,
- size: 100
- });
- if (listRes.code === 200 && fileListRef.value) {
- const fileList = (listRes.data?.records || []).map(item => ({
- name: item.name,
- url: item.url,
- id: item.id,
- ...item
- }));
- fileListRef.value.setList(fileList);
- }
- // 杩斿洖鏂版枃浠朵俊鎭�
- resolve({
- name: fileData.name,
- url: fileData.url,
- id: saveRes.data?.id
- });
- } else {
- proxy.$modal.msgError(saveRes.msg || "鏂囦欢淇濆瓨澶辫触");
- resolve(null);
- }
- } else {
- proxy.$modal.msgError(uploadRes.msg || "鏂囦欢涓婁紶澶辫触");
- resolve(null);
- }
- } catch (error) {
- proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
- resolve(null);
- } finally {
- document.body.removeChild(input);
- }
- };
-
- document.body.appendChild(input);
- input.click();
- });
-};
-
-// 鍒犻櫎闄勪欢
-const handleFileDelete = async (row) => {
- try {
- const res = await fileDel([row.id]);
- if (res.code === 200) {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- // 閲嶆柊鍔犺浇鏂囦欢鍒楄〃
- if (currentFileRow.value && fileListRef.value) {
- const listRes = await fileListPage({
- accountId: currentFileRow.value.id,
- accountType: accountType.value,
- current: 1,
- size: 100
- });
- if (listRes.code === 200) {
- const fileList = (listRes.data?.records || []).map(item => ({
- name: item.name,
- url: item.url,
- id: item.id,
- ...item
- }));
- fileListRef.value.setList(fileList);
- }
- }
- return true; // 杩斿洖 true 琛ㄧず鍒犻櫎鎴愬姛锛岀粍浠朵細鏇存柊鍒楄〃
- } else {
- proxy.$modal.msgError(res.msg || "鍒犻櫎澶辫触");
- return false;
- }
- } catch (error) {
- proxy.$modal.msgError("鍒犻櫎澶辫触");
- return false;
- }
-};
+ recordId.value = row.id
+ fileDialogVisible.value = true
+}
onMounted(() => {
getTableData();
diff --git a/src/views/financialManagement/revenueManagement/index.vue b/src/views/financialManagement/revenueManagement/index.vue
index e2eb28e..bcef5b6 100644
--- a/src/views/financialManagement/revenueManagement/index.vue
+++ b/src/views/financialManagement/revenueManagement/index.vue
@@ -3,22 +3,22 @@
<el-form :model="filters" :inline="true">
<el-form-item label="鏀跺叆鏃ユ湡:">
<el-date-picker v-model="filters.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
- placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
+ placeholder="璇烽�夋嫨" clearable @change="changeDaterange"/>
</el-form-item>
<el-form-item label="鏀舵鏂瑰紡:">
<el-select
- v-model="filters.incomeMethodLabel"
- placeholder="璇烽�夋嫨"
- clearable
- style="width: 200px;"
- >
- <el-option
- v-for="item in incomeMethodOptions"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- />
- </el-select>
+ v-model="filters.incomeMethodLabel"
+ placeholder="璇烽�夋嫨"
+ clearable
+ style="width: 200px;"
+ >
+ <el-option
+ v-for="item in incomeMethodOptions"
+ :key="item.value"
+ :label="item.label"
+ :value="item.value"
+ />
+ </el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getTableData">鎼滅储</el-button>
@@ -29,32 +29,32 @@
<div class="actions">
<div></div>
<div>
- <el-button type="primary" @click="add" icon="Plus"> 鏂板 </el-button>
+ <el-button type="primary" @click="add" icon="Plus"> 鏂板</el-button>
<el-button @click="handleOut" icon="download">瀵煎嚭</el-button>
<el-button
- type="danger"
- icon="Delete"
- :disabled="multipleList.length <= 0 || hasBusinessIdInSelection"
- @click="handleBatchDelete"
+ type="danger"
+ icon="Delete"
+ :disabled="multipleList.length <= 0 || hasBusinessIdInSelection"
+ @click="handleBatchDelete"
>
鎵归噺鍒犻櫎
</el-button>
</div>
</div>
<PIMTable
- rowKey="id"
- isSelection
- :column="columns"
- :tableData="dataList"
- :page="{
+ rowKey="id"
+ isSelection
+ :column="columns"
+ :tableData="dataList"
+ :page="{
current: pagination.currentPage,
size: pagination.pageSize,
total: pagination.total,
}"
- :isShowSummary="true"
- :summaryMethod="summarizeMainTable"
- @selection-change="handleSelectionChange"
- @pagination="changePage"
+ :isShowSummary="true"
+ :summaryMethod="summarizeMainTable"
+ @selection-change="handleSelectionChange"
+ @pagination="changePage"
>
<template #incomeMethodSlot="{ row }">
<el-tag>
@@ -62,18 +62,18 @@
</el-tag>
</template>
<template #operation="{ row }">
- <el-button
- type="primary"
- link
- :disabled="!!row.businessId"
- @click="edit(row.id)"
+ <el-button
+ type="primary"
+ link
+ :disabled="!!row.businessId"
+ @click="edit(row.id)"
>
缂栬緫
</el-button>
<el-button
- type="primary"
- link
- @click="openFilesFormDia(row)"
+ type="primary"
+ link
+ @click="openFilesFormDia(row)"
>
闄勪欢
</el-button>
@@ -81,28 +81,16 @@
</PIMTable>
</div>
<Modal ref="modalRef" @success="getTableData"></Modal>
- <!-- todo 闄勪欢棰勮鐩稿叧 -->
- <FileListDialog
- ref="fileListRef"
- v-model="fileListDialogVisible"
- :show-upload-button="true"
- :show-delete-button="true"
- :upload-method="handleUpload"
- :delete-method="handleFileDelete"
- />
+ <FileListDialog v-if="fileListDialogVisible" :record-id="currentRecordId" record-type="account_income" v-model:visible="fileListDialogVisible"/>
</div>
</template>
<script setup>
-import { usePaginationApi } from "@/hooks/usePaginationApi";
-import { listPage, delAccountIncome, fileListPage, fileAdd, fileDel } from "@/api/financialManagement/revenueManagement";
-import { onMounted, getCurrentInstance, ref, computed } from "vue";
-import Modal from "./Modal.vue";
-import { ElMessageBox, ElMessage } from "element-plus";
+import {usePaginationApi} from "@/hooks/usePaginationApi";
+import {listPage, delAccountIncome} from "@/api/financialManagement/revenueManagement";
+import {onMounted, getCurrentInstance, ref, computed} from "vue";
+import {ElMessageBox, ElMessage} from "element-plus";
import dayjs from "dayjs";
-import FileListDialog from "@/components/Dialog/FileListDialog.vue";
-import request from "@/utils/request";
-import { getToken } from "@/utils/auth";
defineOptions({
name: "鏀跺叆绠$悊",
@@ -110,15 +98,14 @@
// 琛ㄦ牸澶氶�夋閫変腑椤�
const multipleList = ref([]);
-const { proxy } = getCurrentInstance();
+const {proxy} = getCurrentInstance();
const modalRef = ref();
-const { payment_methods } = proxy.useDict("payment_methods");
-const { receipt_payment_type } = proxy.useDict("receipt_payment_type");
-const { income_types } = proxy.useDict("income_types");
+const {payment_methods} = proxy.useDict("payment_methods");
+const {receipt_payment_type} = proxy.useDict("receipt_payment_type");
+const {income_types} = proxy.useDict("income_types");
const fileListRef = ref(null);
const fileListDialogVisible = ref(false);
-const currentFileRow = ref(null);
-const accountType = ref('鏀跺叆');
+const currentRecordId = ref(0);
const incomeMethodOptions = computed(() => {
const merged = [...(payment_methods.value || []), ...(receipt_payment_type.value || [])];
@@ -127,7 +114,7 @@
const label = item?.label;
if (!label) return;
if (!uniqueMap.has(label)) {
- uniqueMap.set(label, { label, value: label });
+ uniqueMap.set(label, {label, value: label});
}
});
return Array.from(uniqueMap.values());
@@ -142,86 +129,86 @@
resetFilters,
onCurrentChange,
} = usePaginationApi(
- listPage,
- {
- incomeMethodLabel: undefined,
- entryDate: undefined,
- },
- [
+ listPage,
{
- label: "鏀跺叆鏃ユ湡",
- prop: "incomeDate",
+ incomeMethodLabel: undefined,
+ entryDate: undefined,
},
- {
- label: "鏀跺叆绫诲瀷",
- prop: "incomeType",
- dataType: "tag",
- formatData: (params) => {
- if (income_types.value.find((m) => m.value == params)) {
- return income_types.value.find((m) => m.value == params).label;
- } else {
- return null
- }
+ [
+ {
+ label: "鏀跺叆鏃ユ湡",
+ prop: "incomeDate",
},
- },
- {
- label: "瀹㈡埛鍚嶇О",
- prop: "customerName",
- width: '200'
+ {
+ label: "鏀跺叆绫诲瀷",
+ prop: "incomeType",
+ dataType: "tag",
+ formatData: (params) => {
+ if (income_types.value.find((m) => m.value == params)) {
+ return income_types.value.find((m) => m.value == params).label;
+ } else {
+ return null
+ }
+ },
+ },
+ {
+ label: "瀹㈡埛鍚嶇О",
+ prop: "customerName",
+ width: '200'
- },
- {
- label: "鏀跺叆閲戦",
- prop: "incomeMoney",
+ },
+ {
+ label: "鏀跺叆閲戦",
+ prop: "incomeMoney",
- },
- {
- label: "鏀跺叆鎻忚堪",
- prop: "incomeDescribed",
+ },
+ {
+ label: "鏀跺叆鎻忚堪",
+ prop: "incomeDescribed",
- },
- {
- label: "鏀舵鏂瑰紡",
- prop: "incomeMethodLabel",
- align: 'center',
- width: '100',
- dataType: "slot",
- slot: "incomeMethodSlot",
- },
- {
- label: "鍙戠エ鍙风爜",
- prop: "invoiceNumber",
+ },
+ {
+ label: "鏀舵鏂瑰紡",
+ prop: "incomeMethodLabel",
+ align: 'center',
+ width: '100',
+ dataType: "slot",
+ slot: "incomeMethodSlot",
+ },
+ {
+ label: "鍙戠エ鍙风爜",
+ prop: "invoiceNumber",
- },
- {
- label: "澶囨敞",
- prop: "note",
+ },
+ {
+ label: "澶囨敞",
+ prop: "note",
- },
- {
- label: "褰曞叆浜�",
- prop: "inputUser",
- },
- {
- label: "褰曞叆鏃ユ湡",
- prop: "inputTime",
+ },
+ {
+ label: "褰曞叆浜�",
+ prop: "inputUser",
+ },
+ {
+ label: "褰曞叆鏃ユ湡",
+ prop: "inputTime",
- },
+ },
+ {
+ fixed: "right",
+ label: "鎿嶄綔",
+ dataType: "slot",
+ slot: "operation",
+ align: "center",
+ width: "160px",
+ },
+ ],
+ undefined,
{
- fixed: "right",
- label: "鎿嶄綔",
- dataType: "slot",
- slot: "operation",
- align: "center",
- width: "160px",
- },
- ],
- undefined,
- {
- incomeMethodLabel: (value) => ({
- incomeMethodLabel: value || undefined,
- }),
- }
+ incomeMethodLabel: (value) => ({
+ incomeMethodLabel: value || undefined,
+ }),
+ }
);
// 琛ㄦ牸鍚堣锛氭敹鍏ラ噾棰�
@@ -232,8 +219,8 @@
const getIncomeMethodLabel = (row) => {
const methodValue = row?.incomeMethod;
const dictList = String(row?.businessType) === "1"
- ? receipt_payment_type.value
- : payment_methods.value;
+ ? receipt_payment_type.value
+ : payment_methods.value;
return dictList.find((item) => item.value == methodValue)?.label || "--";
};
@@ -259,9 +246,9 @@
}
modalRef.value.loadForm(id);
};
-const changePage = ({ page, limit }) => {
+const changePage = ({page, limit}) => {
pagination.currentPage = page;
- pagination.pageSize = limit;
+ pagination.pageSize = limit;
onCurrentChange(page);
};
const deleteRow = (id) => {
@@ -283,13 +270,13 @@
return;
}
}
-
+
ElMessageBox.confirm("姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?", "鎻愮ず", {
confirmButtonText: "纭畾",
cancelButtonText: "鍙栨秷",
type: "warning",
}).then(async () => {
- const { code } = await delAccountIncome(id);
+ const {code} = await delAccountIncome(id);
if (code == 200) {
ElMessage({
type: "success",
@@ -306,13 +293,13 @@
proxy.$modal.msgWarning("璇烽�夋嫨瑕佸垹闄ょ殑鏁版嵁");
return;
}
-
+
// 妫�鏌ユ槸鍚︽湁 businessId
if (hasBusinessIdInSelection.value) {
proxy.$modal.msgWarning("閫変腑鐨勮褰曚腑鍖呭惈宸插叧鑱斾笟鍔$殑璁板綍锛屼笉鑳藉垹闄�");
return;
}
-
+
const ids = multipleList.value.map((item) => item.id);
deleteRow(ids);
};
@@ -336,162 +323,17 @@
cancelButtonText: "鍙栨秷",
type: "warning",
})
- .then(() => {
- proxy.download(`/account/accountIncome/export`, {}, "鏀跺叆鍙拌处.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
+ .then(() => {
+ proxy.download(`/account/accountIncome/export`, {}, "鏀跺叆鍙拌处.xlsx");
+ })
+ .catch(() => {
+ proxy.$modal.msg("宸插彇娑�");
+ });
};
// 鎵撳紑闄勪欢寮规
const openFilesFormDia = async (row) => {
- currentFileRow.value = row;
- accountType.value = '鏀跺叆';
- try {
- const res = await fileListPage({
- accountId: row.id,
- accountType: accountType.value,
- current: 1,
- size: 100
- });
- if (res.code === 200 && fileListRef.value) {
- // 灏嗘暟鎹浆鎹负 FileListDialog 闇�瑕佺殑鏍煎紡
- const fileList = (res.data?.records || []).map(item => ({
- name: item.name,
- url: item.url,
- id: item.id,
- ...item
- }));
- fileListRef.value.open(fileList);
- fileListDialogVisible.value = true;
- }
- } catch (error) {
- proxy.$modal.msgError("鑾峰彇闄勪欢鍒楄〃澶辫触");
- }
-};
-
-// 涓婁紶闄勪欢
-const handleUpload = async () => {
- if (!currentFileRow.value) {
- proxy.$modal.msgWarning("璇峰厛閫夋嫨鏁版嵁");
- return null;
- }
-
- return new Promise((resolve) => {
- // 鍒涘缓涓�涓殣钘忕殑鏂囦欢杈撳叆鍏冪礌
- const input = document.createElement('input');
- input.type = 'file';
- input.style.display = 'none';
- input.onchange = async (e) => {
- const file = e.target.files[0];
- if (!file) {
- resolve(null);
- return;
- }
-
- try {
- // 浣跨敤 FormData 涓婁紶鏂囦欢
- const formData = new FormData();
- formData.append('file', file);
-
- const uploadRes = await request({
- url: '/file/upload',
- method: 'post',
- data: formData,
- headers: {
- 'Content-Type': 'multipart/form-data',
- Authorization: `Bearer ${getToken()}`
- }
- });
-
- if (uploadRes.code === 200) {
- // 淇濆瓨闄勪欢淇℃伅
- const fileData = {
- accountId: currentFileRow.value.id,
- accountType: accountType.value,
- name: uploadRes.data.originalName || file.name,
- url: uploadRes.data.tempPath || uploadRes.data.url
- };
-
- const saveRes = await fileAdd(fileData);
- if (saveRes.code === 200) {
- proxy.$modal.msgSuccess("鏂囦欢涓婁紶鎴愬姛");
- // 閲嶆柊鍔犺浇鏂囦欢鍒楄〃
- const listRes = await fileListPage({
- accountId: currentFileRow.value.id,
- accountType: accountType.value,
- current: 1,
- size: 100
- });
- if (listRes.code === 200 && fileListRef.value) {
- const fileList = (listRes.data?.records || []).map(item => ({
- name: item.name,
- url: item.url,
- id: item.id,
- ...item
- }));
- fileListRef.value.setList(fileList);
- }
- // 杩斿洖鏂版枃浠朵俊鎭�
- resolve({
- name: fileData.name,
- url: fileData.url,
- id: saveRes.data?.id
- });
- } else {
- proxy.$modal.msgError(saveRes.msg || "鏂囦欢淇濆瓨澶辫触");
- resolve(null);
- }
- } else {
- proxy.$modal.msgError(uploadRes.msg || "鏂囦欢涓婁紶澶辫触");
- resolve(null);
- }
- } catch (error) {
- proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
- resolve(null);
- } finally {
- document.body.removeChild(input);
- }
- };
-
- document.body.appendChild(input);
- input.click();
- });
-};
-
-// 鍒犻櫎闄勪欢
-const handleFileDelete = async (row) => {
- try {
- const res = await fileDel([row.id]);
- if (res.code === 200) {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- // 閲嶆柊鍔犺浇鏂囦欢鍒楄〃
- if (currentFileRow.value && fileListRef.value) {
- const listRes = await fileListPage({
- accountId: currentFileRow.value.id,
- accountType: accountType.value,
- current: 1,
- size: 100
- });
- if (listRes.code === 200) {
- const fileList = (listRes.data?.records || []).map(item => ({
- name: item.name,
- url: item.url,
- id: item.id,
- ...item
- }));
- fileListRef.value.setList(fileList);
- }
- }
- return true; // 杩斿洖 true 琛ㄧず鍒犻櫎鎴愬姛锛岀粍浠朵細鏇存柊鍒楄〃
- } else {
- proxy.$modal.msgError(res.msg || "鍒犻櫎澶辫触");
- return false;
- }
- } catch (error) {
- proxy.$modal.msgError("鍒犻櫎澶辫触");
- return false;
- }
+ currentRecordId.value = row.id;
+ fileListDialogVisible.value = true;
};
onMounted(() => {
@@ -503,6 +345,7 @@
.table_list {
margin-top: unset;
}
+
.actions {
display: flex;
justify-content: space-between;
diff --git a/src/views/inventoryManagement/stockManagement/New.vue b/src/views/inventoryManagement/stockManagement/New.vue
index 1c9b333..2addb95 100644
--- a/src/views/inventoryManagement/stockManagement/New.vue
+++ b/src/views/inventoryManagement/stockManagement/New.vue
@@ -57,14 +57,7 @@
style="width: 100%" />
</el-form-item>
<el-form-item label="鎵瑰彿"
- prop="batchNo"
- :rules="[
- {
- required: true,
- message: '璇疯緭鍏ユ壒鍙�',
- trigger: 'blur',
- }
- ]">
+ prop="batchNo">
<el-input v-model="formState.batchNo"
placeholder="璇疯緭鍏ユ壒鍙�" />
</el-form-item>
diff --git a/src/views/procurementManagement/procurementInvoiceLedger/index.vue b/src/views/procurementManagement/procurementInvoiceLedger/index.vue
index d82e3e7..c94d8c2 100644
--- a/src/views/procurementManagement/procurementInvoiceLedger/index.vue
+++ b/src/views/procurementManagement/procurementInvoiceLedger/index.vue
@@ -69,7 +69,7 @@
<el-button
type="primary"
link
- @click="downLoadFile(row)"
+ @click="openFileDialog(row)"
>
闄勪欢
</el-button>
@@ -83,16 +83,7 @@
</template>
</PIMTable>
</div>
- <FileListDialog
- ref="fileListRef"
- v-model="fileListDialogVisible"
- title="闄勪欢鍒楄〃"
- :showUploadButton="true"
- :showDeleteButton="true"
- :deleteMethod="handleDeleteFile"
- :uploadMethod="handleFileUpload"
- :rulesRegulationsManagementId="currentRowId"
- />
+ <FileList v-if="fileDialogVisible" v-model:visible="fileDialogVisible" record-type="ticket_registration" :record-id="recordId" />
<EditModal ref="editmodalRef" @success="getTableData"></EditModal>
</div>
</template>
@@ -113,9 +104,9 @@
import { onMounted } from "vue";
import { ElMessageBox } from "element-plus";
import EditModal from "./Modal/EditModal.vue";
-import FileListDialog from '@/components/Dialog/FileListDialog.vue';
import useUserStore from "@/store/modules/user.js";
const userStore = useUserStore();
+const FileList = defineAsyncComponent(() => import("@/components/Dialog/FileList.vue"));
defineOptions({
name: "鏉ョエ鍙拌处",
@@ -290,143 +281,15 @@
onCurrentChange(page);
};
-const downLoadFile = row => {
- currentRowId.value = row.id;
- if (fileListRef.value) {
- fileListRef.value.open(row.commonFiles || []);
- }
-};
+// 鎵撳紑闄勪欢寮圭獥
+const recordId =ref(0)
+const fileDialogVisible = ref(false)
-// 涓婁紶闄勪欢锛堣嚜瀹氫箟涓婁紶鏂规硶锛�
-const handleFileUpload = async () => {
- if (!currentRowId.value) {
- proxy.$modal.msgWarning("缂哄皯鐧昏ID锛屾棤娉曚繚瀛橀檮浠�");
- return;
- }
-
- return new Promise((resolve) => {
- // 鍒涘缓涓�涓殣钘忕殑鏂囦欢杈撳叆鍏冪礌
- const input = document.createElement('input');
- input.type = 'file';
- input.style.display = 'none';
- input.onchange = async (e) => {
- const file = e.target.files[0];
- if (!file) {
- resolve(null);
- return;
- }
-
- try {
- // 浣跨敤 FormData 涓婁紶鏂囦欢
- const formData = new FormData();
- formData.append('file', file);
- formData.append('type', '4'); // type 鍙傛暟锛岀敤鎴锋湭鎸囧畾鍏蜂綋鍊硷紝鍏堜紶绌哄瓧绗︿覆
- formData.append('id', currentRowId.value); // 褰撳墠琛岀殑 id
-
- const uploadRes = await request({
- url: '/file/uploadByCommon',
- method: 'post',
- data: formData,
- headers: {
- 'Content-Type': 'multipart/form-data',
- Authorization: `Bearer ${getToken()}`
- }
- });
-
- if (uploadRes.code === 200) {
- proxy.$modal.msgSuccess("闄勪欢涓婁紶鎴愬姛");
-
- // 鍒锋柊鍒楄〃鑾峰彇鏈�鏂版暟鎹�
- await new Promise((resolveRefresh) => {
- // 璋冪敤 API 鑾峰彇鏈�鏂板垪琛ㄦ暟鎹�
- productRecordPage({
- ...filters,
- current: pagination.currentPage,
- size: pagination.pageSize
- }).then(({ code, data }) => {
- if (code === 200) {
- // 鏇存柊鏁版嵁鍒楄〃
- dataList.value = data.records;
- pagination.total = data.total;
-
- // 浠庡閮ㄦ暟鎹幏鍙� commonFiles
- const currentRow = dataList.value.find(row => row.id === currentRowId.value);
- if (currentRow && fileListRef.value) {
- // 鍒锋柊闄勪欢鍒楄〃锛屼娇鐢ㄤ粠澶栭儴鑾峰彇鐨勬渶鏂� commonFiles
- fileListRef.value.open(currentRow.commonFiles || []);
- }
- resolveRefresh();
- } else {
- resolveRefresh();
- }
- }).catch(() => {
- resolveRefresh();
- });
- });
-
- resolve({
- name: uploadRes.data?.originalName || file.name,
- url: uploadRes.data?.tempPath || uploadRes.data?.url,
- id: uploadRes.data?.id
- });
- } else {
- proxy.$modal.msgError(uploadRes.msg || "鏂囦欢涓婁紶澶辫触");
- resolve(null);
- }
- } catch (error) {
- console.error("闄勪欢涓婁紶澶辫触:", error);
- proxy.$modal.msgError("闄勪欢涓婁紶澶辫触");
- resolve(null);
- } finally {
- document.body.removeChild(input);
- }
- };
-
- document.body.appendChild(input);
- input.click();
- });
-};
-
-// 鍒犻櫎闄勪欢
-const handleDeleteFile = async (file) => {
- try {
- await delCommonFile([file.id]);
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-
- // 鍒锋柊鍒楄〃鑾峰彇鏈�鏂版暟鎹�
- await new Promise((resolveRefresh) => {
- // 璋冪敤 API 鑾峰彇鏈�鏂板垪琛ㄦ暟鎹�
- productRecordPage({
- ...filters,
- current: pagination.currentPage,
- size: pagination.pageSize
- }).then(({ code, data }) => {
- if (code === 200) {
- // 鏇存柊鏁版嵁鍒楄〃
- dataList.value = data.records;
- pagination.total = data.total;
-
- // 浠庡閮ㄦ暟鎹幏鍙� commonFiles
- const currentRow = dataList.value.find(row => row.id === currentRowId.value);
- if (currentRow && fileListRef.value) {
- // 鍒锋柊闄勪欢鍒楄〃锛屼娇鐢ㄤ粠澶栭儴鑾峰彇鐨勬渶鏂� commonFiles
- fileListRef.value.open(currentRow.commonFiles || []);
- }
- resolveRefresh();
- } else {
- resolveRefresh();
- }
- }).catch(() => {
- resolveRefresh();
- });
- });
-
- return true;
- } catch (error) {
- proxy.$modal.msgError("鍒犻櫎澶辫触");
- return false;
- }
-};
+// 鎵撳紑闄勪欢寮规
+const openFileDialog = async (row) => {
+ recordId.value = row.id
+ fileDialogVisible.value = true
+}
const openEdit = (row) => {
editmodalRef.value.open(row);
diff --git a/src/views/procurementManagement/procurementLedger/index.vue b/src/views/procurementManagement/procurementLedger/index.vue
index 32b54a9..1991342 100644
--- a/src/views/procurementManagement/procurementLedger/index.vue
+++ b/src/views/procurementManagement/procurementLedger/index.vue
@@ -9,7 +9,7 @@
placeholder="璇疯緭鍏�"
clearable
prefix-icon="Search"
- @change="handleQuery" />
+ @change="handleQuery"/>
</el-form-item>
<el-form-item label="閲囪喘鍚堝悓鍙凤細">
<el-input v-model="searchForm.purchaseContractNumber"
@@ -17,21 +17,21 @@
placeholder="璇疯緭鍏�"
@change="handleQuery"
clearable
- :prefix-icon="Search" />
+ :prefix-icon="Search"/>
</el-form-item>
<el-form-item label="閿�鍞悎鍚屽彿锛�">
<el-input v-model="searchForm.salesContractNo"
placeholder="璇疯緭鍏�"
clearable
prefix-icon="Search"
- @change="handleQuery" />
+ @change="handleQuery"/>
</el-form-item>
<el-form-item label="椤圭洰鍚嶇О锛�">
<el-input v-model="searchForm.projectName"
placeholder="璇疯緭鍏�"
clearable
prefix-icon="Search"
- @change="handleQuery" />
+ @change="handleQuery"/>
</el-form-item>
<el-form-item label="褰曞叆鏃ユ湡锛�">
<el-date-picker v-model="searchForm.entryDate"
@@ -40,11 +40,12 @@
type="daterange"
placeholder="璇烽�夋嫨"
clearable
- @change="changeDaterange" />
+ @change="changeDaterange"/>
</el-form-item>
<el-form-item>
<el-button type="primary"
- @click="handleQuery"> 鎼滅储 </el-button>
+ @click="handleQuery"> 鎼滅储
+ </el-button>
</el-form-item>
</el-form>
</div>
@@ -57,7 +58,8 @@
<el-button @click="handleOut">瀵煎嚭</el-button>
<el-button type="danger"
plain
- @click="handleDelete">鍒犻櫎</el-button>
+ @click="handleDelete">鍒犻櫎
+ </el-button>
</div>
<el-table :data="tableData"
border
@@ -71,7 +73,7 @@
height="calc(100vh - 21.5em)">
<el-table-column align="center"
type="selection"
- width="55" />
+ width="55"/>
<el-table-column type="expand">
<template #default="props">
<el-table :data="props.row.children"
@@ -81,62 +83,62 @@
<el-table-column align="center"
label="搴忓彿"
type="index"
- width="60" />
+ width="60"/>
<el-table-column label="浜у搧澶х被"
- prop="productCategory" />
+ prop="productCategory"/>
<el-table-column label="瑙勬牸鍨嬪彿"
- prop="specificationModel" />
+ prop="specificationModel"/>
<el-table-column label="鍗曚綅"
- prop="unit" />
+ prop="unit"/>
<el-table-column label="鏁伴噺"
- prop="quantity" />
+ prop="quantity"/>
<el-table-column label="鍙敤鏁伴噺"
- prop="availableQuality" />
+ prop="availableQuality"/>
<el-table-column label="閫�璐ф暟閲�"
- prop="returnQuality" />
-
+ prop="returnQuality"/>
+
<el-table-column label="绋庣巼(%)"
- prop="taxRate" />
+ prop="taxRate"/>
<el-table-column label="鍚◣鍗曚环(鍏�)"
prop="taxInclusiveUnitPrice"
- :formatter="formattedNumber" />
+ :formatter="formattedNumber"/>
<el-table-column label="鍚◣鎬讳环(鍏�)"
prop="taxInclusiveTotalPrice"
- :formatter="formattedNumber" />
+ :formatter="formattedNumber"/>
<el-table-column label="涓嶅惈绋庢�讳环(鍏�)"
prop="taxExclusiveTotalPrice"
- :formatter="formattedNumber" />
+ :formatter="formattedNumber"/>
</el-table>
</template>
</el-table-column>
<el-table-column align="center"
label="搴忓彿"
type="index"
- width="60" />
+ width="60"/>
<el-table-column label="閲囪喘鍚堝悓鍙�"
prop="purchaseContractNumber"
width="160"
- show-overflow-tooltip />
+ show-overflow-tooltip/>
<el-table-column label="閿�鍞悎鍚屽彿"
prop="salesContractNo"
- width="160"
- show-overflow-tooltip />
+ width="160"
+ show-overflow-tooltip/>
<el-table-column label="渚涘簲鍟嗗悕绉�"
prop="supplierName"
- width="160"
- show-overflow-tooltip />
+ width="160"
+ show-overflow-tooltip/>
<el-table-column label="椤圭洰鍚嶇О"
prop="projectName"
width="320"
- show-overflow-tooltip />
+ show-overflow-tooltip/>
<el-table-column label="瀹℃壒鐘舵��"
prop="approvalStatus"
width="100"
show-overflow-tooltip>
<template #default="scope">
- <el-tag
- :type="getApprovalStatusType(scope.row.approvalStatus)"
- size="small">
+ <el-tag
+ :type="getApprovalStatusType(scope.row.approvalStatus)"
+ size="small">
{{ approvalStatusText[scope.row.approvalStatus] || '鏈煡鐘舵��' }}
</el-tag>
</template>
@@ -144,28 +146,28 @@
<el-table-column label="绛捐鏃ユ湡"
prop="executionDate"
width="100"
- show-overflow-tooltip />
+ show-overflow-tooltip/>
<el-table-column label="浠樻鏂瑰紡"
width="100"
prop="paymentMethod"
- show-overflow-tooltip />
+ show-overflow-tooltip/>
<el-table-column label="鍚堝悓閲戦(鍏�)"
prop="contractAmount"
width="200"
show-overflow-tooltip
- :formatter="formattedNumber" />
+ :formatter="formattedNumber"/>
<el-table-column label="褰曞叆浜�"
prop="recorderName"
width="120"
- show-overflow-tooltip />
+ show-overflow-tooltip/>
<el-table-column label="褰曞叆鏃ユ湡"
prop="entryDate"
width="100"
- show-overflow-tooltip />
+ show-overflow-tooltip/>
<el-table-column label="澶囨敞"
prop="remarks"
width="200"
- show-overflow-tooltip />
+ show-overflow-tooltip/>
<el-table-column fixed="right"
label="鎿嶄綔"
width="120"
@@ -174,10 +176,11 @@
<el-button link
type="primary"
@click="openForm('edit', scope.row)"
- :disabled="scope.row.approvalStatus !== 1 && scope.row.approvalStatus !== 4">缂栬緫</el-button>
+ :disabled="scope.row.approvalStatus !== 1 && scope.row.approvalStatus !== 4">缂栬緫
+ </el-button>
<el-button link
type="primary"
- @click="downLoadFile(scope.row)">闄勪欢</el-button>
+ @click="openFileDialog(scope.row)">闄勪欢</el-button>
</template>
</el-table-column>
</el-table>
@@ -186,15 +189,15 @@
layout="total, sizes, prev, pager, next, jumper"
:page="page.current"
:limit="page.size"
- @pagination="paginationChange" />
+ @pagination="paginationChange"/>
</div>
<FormDialog v-model="dialogFormVisible"
- :title="operationType === 'add' ? '鏂板閲囪喘鍙拌处椤甸潰' : '缂栬緫閲囪喘鍙拌处椤甸潰'"
- :width="'70%'"
- :operation-type="operationType"
- @close="closeDia"
- @confirm="submitForm"
- @cancel="closeDia">
+ :title="operationType === 'add' ? '鏂板閲囪喘鍙拌处椤甸潰' : '缂栬緫閲囪喘鍙拌处椤甸潰'"
+ :width="'70%'"
+ :operation-type="operationType"
+ @close="closeDia"
+ @confirm="submitForm"
+ @cancel="closeDia">
<el-form :model="form"
label-width="140px"
label-position="top"
@@ -206,7 +209,7 @@
prop="purchaseContractNumber">
<el-input v-model="form.purchaseContractNumber"
placeholder="璇疯緭鍏�"
- clearable />
+ clearable/>
</el-form-item>
</el-col>
<el-col :span="12">
@@ -220,7 +223,7 @@
<el-option v-for="item in salesContractList"
:key="item.id"
:label="item.salesContractNo"
- :value="item.id" />
+ :value="item.id"/>
</el-select>
</el-form-item>
</el-col>
@@ -236,7 +239,8 @@
<el-option v-for="item in supplierList"
:key="item.id"
:label="item.supplierName"
- :value="item.id" >{{item.supplierName + '---' + item.supplierType}}</el-option>
+ :value="item.id">{{ item.supplierName + '---' + item.supplierType }}
+ </el-option>
</el-select>
</el-form-item>
</el-col>
@@ -245,7 +249,7 @@
prop="projectName">
<el-input v-model="form.projectName"
placeholder="璇疯緭鍏�"
- clearable />
+ clearable/>
</el-form-item>
</el-col>
</el-row>
@@ -254,7 +258,7 @@
<el-form-item label="浠樻鏂瑰紡">
<el-input v-model="form.paymentMethod"
placeholder="璇疯緭鍏�"
- clearable />
+ clearable/>
</el-form-item>
</el-col>
<el-col :span="12">
@@ -266,7 +270,7 @@
format="YYYY-MM-DD"
type="date"
placeholder="璇烽�夋嫨"
- clearable />
+ clearable/>
</el-form-item>
</el-col>
</el-row>
@@ -274,7 +278,7 @@
<el-col :span="12">
<el-form-item label="褰曞叆浜猴細"
prop="recorderId">
- <el-input v-model="form.recorderName" placeholder="鑷姩濉厖" disabled />
+ <el-input v-model="form.recorderName" placeholder="鑷姩濉厖" disabled/>
</el-form-item>
</el-col>
<el-col :span="12">
@@ -286,7 +290,7 @@
format="YYYY-MM-DD"
type="date"
placeholder="璇烽�夋嫨"
- clearable />
+ clearable/>
</el-form-item>
</el-col>
</el-row>
@@ -294,10 +298,12 @@
<el-form-item label="浜у搧淇℃伅锛�"
prop="entryDate">
<el-button type="primary"
- @click="openProductForm('add')">娣诲姞</el-button>
+ @click="openProductForm('add')">娣诲姞
+ </el-button>
<el-button plain
type="danger"
- @click="deleteProduct">鍒犻櫎</el-button>
+ @click="deleteProduct">鍒犻櫎
+ </el-button>
</el-form-item>
<div class="select-button-group"
style="width: 500px; margin: 20px 0;"
@@ -321,12 +327,12 @@
:value="item.templateName">
<div style="display: flex; justify-content: space-between; align-items: center;">
<span>{{ item.templateName }}</span>
- <el-icon
- v-if="item.id"
- class="delete-icon"
- @click.stop="handleDeleteTemplate(item)"
- style="cursor: pointer; color: #f56c6c; font-size: 14px; margin-left: 8px;">
- <Delete />
+ <el-icon
+ v-if="item.id"
+ class="delete-icon"
+ @click.stop="handleDeleteTemplate(item)"
+ style="cursor: pointer; color: #f56c6c; font-size: 14px; margin-left: 8px;">
+ <Delete/>
</el-icon>
</div>
</el-option>
@@ -347,40 +353,40 @@
:summary-method="summarizeProTable">
<el-table-column align="center"
type="selection"
- width="55" />
+ width="55"/>
<el-table-column align="center"
label="搴忓彿"
type="index"
- width="60" />
+ width="60"/>
<el-table-column label="浜у搧澶х被"
- prop="productCategory" />
+ prop="productCategory"/>
<el-table-column label="瑙勬牸鍨嬪彿"
- prop="specificationModel" />
+ prop="specificationModel"/>
<el-table-column label="鍗曚綅"
prop="unit"
- width="70" />
+ width="70"/>
<el-table-column label="鏁伴噺"
prop="quantity"
- width="70" />
+ width="70"/>
<el-table-column label="搴撳瓨棰勮鏁伴噺"
prop="warnNum"
width="120"
- show-overflow-tooltip />
+ show-overflow-tooltip/>
<el-table-column label="绋庣巼(%)"
prop="taxRate"
- width="80" />
+ width="80"/>
<el-table-column label="鍚◣鍗曚环(鍏�)"
prop="taxInclusiveUnitPrice"
:formatter="formattedNumber"
- width="150" />
+ width="150"/>
<el-table-column label="鍚◣鎬讳环(鍏�)"
prop="taxInclusiveTotalPrice"
:formatter="formattedNumber"
- width="150" />
+ width="150"/>
<el-table-column label="涓嶅惈绋庢�讳环(鍏�)"
prop="taxExclusiveTotalPrice"
:formatter="formattedNumber"
- width="150" />
+ width="150"/>
<el-table-column label="鏄惁璐ㄦ"
prop="isChecked"
width="150">
@@ -397,7 +403,8 @@
<template #default="scope">
<el-button link
type="primary"
- @click="openProductForm('edit', scope.row, scope.$index)">缂栬緫</el-button>
+ @click="openProductForm('edit', scope.row, scope.$index)">缂栬緫
+ </el-button>
</template>
</el-table-column>
</el-table>
@@ -409,7 +416,7 @@
placeholder="璇疯緭鍏�"
clearable
type="textarea"
- :rows="2" />
+ :rows="2"/>
</el-form-item>
</el-col>
</el-row>
@@ -417,24 +424,7 @@
<el-col :span="24">
<el-form-item label="闄勪欢鏉愭枡锛�"
prop="purchaseLedgerFiles">
- <el-upload v-model:file-list="fileList"
- :action="upload.url"
- multiple
- ref="fileUpload"
- auto-upload
- :headers="upload.headers"
- :before-upload="handleBeforeUpload"
- :on-error="handleUploadError"
- :on-success="handleUploadSuccess"
- :on-remove="handleRemove">
- <el-button type="primary">涓婁紶</el-button>
- <template #tip>
- <div class="el-upload__tip">
- 鏂囦欢鏍煎紡鏀寔
- doc锛宒ocx锛寈ls锛寈lsx锛宲pt锛宲ptx锛宲df锛宼xt锛寈ml锛宩pg锛宩peg锛宲ng锛実if锛宐mp锛宺ar锛寊ip锛�7z
- </div>
- </template>
- </el-upload>
+ <FileUpload v-model:file-list="fileList"/>
</el-form-item>
</el-col>
</el-row>
@@ -442,26 +432,26 @@
</FormDialog>
<!-- 瀵煎叆寮圭獥 -->
<FormDialog
- v-model="importUpload.open"
- :title="importUpload.title"
- :width="'600px'"
- @close="importUpload.open = false"
- @confirm="submitImportFile"
- @cancel="importUpload.open = false"
+ v-model="importUpload.open"
+ :title="importUpload.title"
+ :width="'600px'"
+ @close="importUpload.open = false"
+ @confirm="submitImportFile"
+ @cancel="importUpload.open = false"
>
<el-upload
- ref="importUploadRef"
- :limit="1"
- accept=".xlsx,.xls"
- :action="importUpload.url"
- :headers="importUpload.headers"
- :before-upload="importUpload.beforeUpload"
- :on-success="importUpload.onSuccess"
- :on-error="importUpload.onError"
- :on-progress="importUpload.onProgress"
- :on-change="importUpload.onChange"
- :auto-upload="false"
- drag
+ ref="importUploadRef"
+ :limit="1"
+ accept=".xlsx,.xls"
+ :action="importUpload.url"
+ :headers="importUpload.headers"
+ :before-upload="importUpload.beforeUpload"
+ :on-success="importUpload.onSuccess"
+ :on-error="importUpload.onError"
+ :on-progress="importUpload.onProgress"
+ :on-change="importUpload.onChange"
+ :auto-upload="false"
+ drag
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">
@@ -476,12 +466,12 @@
</el-upload>
</FormDialog>
<FormDialog v-model="productFormVisible"
- :title="productOperationType === 'add' ? '鏂板浜у搧' : '缂栬緫浜у搧'"
- :width="'40%'"
- :operation-type="productOperationType"
- @close="closeProductDia"
- @confirm="submitProduct"
- @cancel="closeProductDia">
+ :title="productOperationType === 'add' ? '鏂板浜у搧' : '缂栬緫浜у搧'"
+ :width="'40%'"
+ :operation-type="productOperationType"
+ @close="closeProductDia"
+ @confirm="submitProduct"
+ @cancel="closeProductDia">
<el-form :model="productForm"
label-width="140px"
label-position="top"
@@ -499,7 +489,7 @@
@change="getModels"
:data="productOptions"
:render-after-expand="false"
- style="width: 100%" />
+ style="width: 100%"/>
</el-form-item>
</el-col>
</el-row>
@@ -515,7 +505,7 @@
<el-option v-for="item in modelOptions"
:key="item.id"
:label="item.model"
- :value="item.id" />
+ :value="item.id"/>
</el-select>
</el-form-item>
</el-col>
@@ -526,7 +516,7 @@
prop="unit">
<el-input v-model="productForm.unit"
placeholder="璇疯緭鍏�"
- clearable />
+ clearable/>
</el-form-item>
</el-col>
<el-col :span="12">
@@ -537,11 +527,11 @@
clearable
@change="mathNum">
<el-option label="1"
- value="1" />
+ value="1"/>
<el-option label="6"
- value="6" />
+ value="6"/>
<el-option label="13"
- value="13" />
+ value="13"/>
</el-select>
</el-form-item>
</el-col>
@@ -556,7 +546,7 @@
:min="0"
clearable
style="width: 100%"
- @change="mathNum" />
+ @change="mathNum"/>
</el-form-item>
</el-col>
<el-col :span="12">
@@ -569,7 +559,7 @@
style="width: 100%"
v-model="productForm.quantity"
placeholder="璇疯緭鍏�"
- @change="mathNum" />
+ @change="mathNum"/>
</el-form-item>
</el-col>
</el-row>
@@ -583,7 +573,7 @@
:min="0"
clearable
style="width: 100%"
- @change="reverseMathNum('taxInclusiveTotalPrice')" />
+ @change="reverseMathNum('taxInclusiveTotalPrice')"/>
</el-form-item>
</el-col>
<el-col :span="12">
@@ -595,7 +585,7 @@
:min="0"
clearable
style="width: 100%"
- @change="reverseMathNum('taxExclusiveTotalPrice')" />
+ @change="reverseMathNum('taxExclusiveTotalPrice')"/>
</el-form-item>
</el-col>
</el-row>
@@ -607,9 +597,9 @@
placeholder="璇烽�夋嫨"
clearable>
<el-option label="澧炴櫘绁�"
- value="澧炴櫘绁�" />
+ value="澧炴櫘绁�"/>
<el-option label="澧炰笓绁�"
- value="澧炰笓绁�" />
+ value="澧炰笓绁�"/>
</el-select>
</el-form-item>
</el-col>
@@ -621,7 +611,7 @@
:step="0.1"
:min="0"
clearable
- style="width: 100%" />
+ style="width: 100%"/>
</el-form-item>
</el-col>
</el-row>
@@ -631,24 +621,23 @@
prop="isChecked">
<el-radio-group v-model="productForm.isChecked">
<el-radio label="鏄�"
- :value="true" />
+ :value="true"/>
<el-radio label="鍚�"
- :value="false" />
+ :value="false"/>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
</el-form>
</FormDialog>
- <FileListDialog
- ref="fileListRef"
- v-model="fileListDialogVisible"
- title="闄勪欢鍒楄〃"
- />
+ <FileList v-if="fileListDialogVisible" v-model:visible="fileListDialogVisible" record-type="purchase_ledger" :record-id="recordId" />
</div>
</template>
<script setup>
+import {Search, Delete} from "@element-plus/icons-vue";
+import FormDialog from '@/components/Dialog/FormDialog.vue';
+import FileListDialog from '@/components/Dialog/FileListDialog.vue';
import { getToken } from "@/utils/auth";
import pagination from "@/components/PIMTable/Pagination.vue";
import {
@@ -661,10 +650,7 @@
} from "vue";
import { Search, Delete } from "@element-plus/icons-vue";
import { ElMessageBox, ElMessage } from "element-plus";
- import FormDialog from '@/components/Dialog/FormDialog.vue';
- import FileListDialog from '@/components/Dialog/FileListDialog.vue';
import {
- getSalesLedgerWithProducts,
addOrUpdateSalesLedgerProduct,
delProduct,
delLedgerFile,
@@ -685,431 +671,434 @@
delPurchaseTemplate,
} from "@/api/procurementManagement/procurementLedger.js";
import useFormData from "@/hooks/useFormData.js";
+ const FileList = defineAsyncComponent(() => import("@/components/Dialog/FileList.vue"));
- const { proxy } = getCurrentInstance();
- const tableData = ref([]);
- const productData = ref([]);
- const selectedRows = ref([]);
- const productSelectedRows = ref([]);
- const modelOptions = ref([]);
- const productOptions = ref([]);
- const salesContractList = ref([]);
- const supplierList = ref([]);
- const tableLoading = ref(false);
- const page = reactive({
- current: 1,
- size: 100,
- });
- const total = ref(0);
- const fileList = ref([]);
- import useUserStore from "@/store/modules/user";
- import { modelList, productTreeList } from "@/api/basicData/product.js";
- import dayjs from "dayjs";
+const {proxy} = getCurrentInstance();
+const tableData = ref([]);
+const productData = ref([]);
+const selectedRows = ref([]);
+const productSelectedRows = ref([]);
+const modelOptions = ref([]);
+const productOptions = ref([]);
+const salesContractList = ref([]);
+const supplierList = ref([]);
+const tableLoading = ref(false);
+const fileListDialogVisible = ref(false)
+const page = reactive({
+ current: 1,
+ size: 100,
+});
+const total = ref(0);
+const fileList = ref([]);
+import useUserStore from "@/store/modules/user";
+import {modelList, productTreeList} from "@/api/basicData/product.js";
+import dayjs from "dayjs";
+import FileUpload from "@/components/AttachmentUpload/file/index.vue";
- const userStore = useUserStore();
+const userStore = useUserStore();
- // 璁㈠崟瀹℃壒鐘舵�佹樉绀烘枃鏈�
- const approvalStatusText = {
- 1: "寰呭鏍�",
- 2: "瀹℃壒涓�",
- 3: "瀹℃壒閫氳繃",
- 4: "瀹℃壒澶辫触",
+// 璁㈠崟瀹℃壒鐘舵�佹樉绀烘枃鏈�
+const approvalStatusText = {
+ 1: "寰呭鏍�",
+ 2: "瀹℃壒涓�",
+ 3: "瀹℃壒閫氳繃",
+ 4: "瀹℃壒澶辫触",
+};
+
+// 鑾峰彇瀹℃壒鐘舵�佹爣绛剧被鍨�
+const getApprovalStatusType = (status) => {
+ const typeMap = {
+ 1: "info", // 寰呭鏍� - 鐏拌壊
+ 2: "warning", // 瀹℃壒涓� - 姗欒壊
+ 3: "success", // 瀹℃壒閫氳繃 - 缁胯壊
+ 4: "danger", // 瀹℃壒澶辫触 - 绾㈣壊
};
+ return typeMap[status] || "";
+};
- // 鑾峰彇瀹℃壒鐘舵�佹爣绛剧被鍨�
- const getApprovalStatusType = (status) => {
- const typeMap = {
- 1: "info", // 寰呭鏍� - 鐏拌壊
- 2: "warning", // 瀹℃壒涓� - 姗欒壊
- 3: "success", // 瀹℃壒閫氳繃 - 缁胯壊
- 4: "danger", // 瀹℃壒澶辫触 - 绾㈣壊
- };
- return typeMap[status] || "";
- };
+const templateName = ref("");
+const filterInputValue = ref("");
+const templateList = ref([]);
+const isTemplateNameDuplicate = ref(false); // 鏍囪妯℃澘鍚嶇О鏄惁閲嶅
+// 褰撳墠閫変腑鐨勬ā鏉縄D锛堢敤浜庡尯鍒嗘柊澧炴ā鏉胯繕鏄洿鏂版ā鏉匡級
+const currentTemplateId = ref(null);
- const templateName = ref("");
- const filterInputValue = ref("");
- const templateList = ref([]);
- const isTemplateNameDuplicate = ref(false); // 鏍囪妯℃澘鍚嶇О鏄惁閲嶅
- // 褰撳墠閫変腑鐨勬ā鏉縄D锛堢敤浜庡尯鍒嗘柊澧炴ā鏉胯繕鏄洿鏂版ā鏉匡級
- const currentTemplateId = ref(null);
-
- // 妫�鏌ユā鏉垮悕绉版槸鍚﹂噸澶�
- const checkTemplateNameDuplicate = name => {
- if (!name || name.trim() === "") {
- isTemplateNameDuplicate.value = false;
- return false;
- }
- const isDuplicate = templateList.value.some(
+// 妫�鏌ユā鏉垮悕绉版槸鍚﹂噸澶�
+const checkTemplateNameDuplicate = name => {
+ if (!name || name.trim() === "") {
+ isTemplateNameDuplicate.value = false;
+ return false;
+ }
+ const isDuplicate = templateList.value.some(
item => item.templateName === name.trim()
- );
- isTemplateNameDuplicate.value = isDuplicate;
- return isDuplicate;
- };
+ );
+ isTemplateNameDuplicate.value = isDuplicate;
+ return isDuplicate;
+};
- // 闃叉姈瀹氭椂鍣�
- let duplicateCheckTimer = null;
- const onTemplateFilterChange = val => {
- filterInputValue.value = val ?? "";
- // 娓呴櫎涔嬪墠鐨勫畾鏃跺櫒
- if (duplicateCheckTimer) {
- clearTimeout(duplicateCheckTimer);
- }
- // 瀹炴椂妫�鏌ユā鏉垮悕绉版槸鍚﹂噸澶嶏紙闃叉姈澶勭悊锛岄伩鍏嶉绻佹彁绀猴級
- if (val && val.trim()) {
- duplicateCheckTimer = setTimeout(() => {
- const isDuplicate = checkTemplateNameDuplicate(val);
- if (isDuplicate) {
- ElMessage({
- message: "妯℃澘鍚嶇О宸插瓨鍦紝璇锋洿鎹㈡ā鏉垮悕绉�",
- type: "warning",
- duration: 2000,
- });
- }
- }, 300); // 300ms 闃叉姈
- } else {
- isTemplateNameDuplicate.value = false;
- }
- };
-
- // allow-create 鏃讹紝杈撳叆涓嶅瓨鍦ㄧ殑鍐呭浼氫綔涓� string 鍊艰繑鍥烇紱杩欓噷鍚屾鍥炶緭鍏ユ浠ョ‘淇濇枃瀛椾笉涓�
- const onTemplateChange = async val => {
- if (typeof val === "string") {
- filterInputValue.value = val;
- // 閫夋嫨鎴栬緭鍏ユ椂妫�鏌ラ噸澶�
- checkTemplateNameDuplicate(val);
- }
-
- // 杩囨护鏁版嵁锛屾煡鎵惧尮閰嶇殑妯℃澘
- const matchedTemplate = templateList.value.find(
- item => item.templateName === val
- );
-
- if (matchedTemplate?.id) {
- // 璁板綍褰撳墠閫変腑鐨勬ā鏉縄D锛屽悗缁繚瀛樻椂杩涜鏇存柊鎿嶄綔
- currentTemplateId.value = matchedTemplate.id;
- // 閫変腑宸叉湁妯℃澘鏃讹紝涓嶅簲瑙嗕负鈥滄ā鏉垮悕绉伴噸澶嶅鑷翠笉鍙繚瀛樷��
- isTemplateNameDuplicate.value = false;
- // 濡傛灉鎵惧埌妯℃澘锛屽彧璧嬪�间緵搴斿晢銆侀」鐩悕绉般�佷粯娆炬柟寮忓拰浜у搧淇℃伅
- if (matchedTemplate.supplierId) {
- form.value.supplierId = matchedTemplate.supplierId;
- }
- if (matchedTemplate.supplierName) {
- form.value.supplierName = matchedTemplate.supplierName;
- }
- if (matchedTemplate.projectName) {
- form.value.projectName = matchedTemplate.projectName;
- }
- if (matchedTemplate.paymentMethod) {
- form.value.paymentMethod = matchedTemplate.paymentMethod;
- }
- // 妯℃澘鏁版嵁涓殑浜у搧瀛楁鏄� productList锛岄渶瑕佽浆鎹负 productData
- productData.value = matchedTemplate.productList || matchedTemplate.productData || [];
- } else {
- // 鏈尮閰嶅埌宸叉湁妯℃澘锛岃涓烘柊妯℃澘
- currentTemplateId.value = null;
- // 濡傛灉娌℃湁鎵惧埌妯℃澘锛岄噸缃〃鍗曪紙淇濇寔褰撳墠琛ㄥ崟鐘舵�侊級
- const currentFormData = { ...form.value };
- const currentProductData = [...productData.value];
-
- // 濡傛灉瀵硅瘽妗嗘湭鎵撳紑锛屽厛鎵撳紑
- if (!dialogFormVisible.value) {
- operationType.value = "add";
- dialogFormVisible.value = true;
- }
-
- // 绛夊緟涓嬩竴涓� tick 鍚庢仮澶嶆暟鎹�
- await nextTick();
- form.value = {
- ...form.value,
- ...currentFormData,
- };
- productData.value = currentProductData;
- }
- };
-
- // 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
- const operationType = ref("");
- const dialogFormVisible = ref(false);
- const data = reactive({
- searchForm: {
- supplierName: "", // 渚涘簲鍟嗗悕绉�
- purchaseContractNumber: "", // 閲囪喘鍚堝悓缂栧彿
- salesContractNo: "", // 閿�鍞悎鍚岀紪鍙�
- projectName: "", // 椤圭洰鍚嶇О
- entryDate: null, // 褰曞叆鏃ユ湡
- entryDateStart: undefined,
- entryDateEnd: undefined,
- },
- form: {
- purchaseContractNumber: "",
- salesLedgerId: "",
- projectName: "",
- recorderId: "",
- recorderName: "",
- entryDate: "",
- productData: [],
- supplierName: "",
- supplierId: "",
- paymentMethod: "",
- executionDate: "",
- isChecked: false,
- },
- rules: {
- purchaseContractNumber: [
- { required: true, message: "璇疯緭鍏�", trigger: "blur" },
- ],
- projectName: [
- { required: true, message: "璇疯緭鍏ラ」鐩悕绉�", trigger: "blur" },
- ],
- supplierId: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- entryDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- executionDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- },
- });
- const { form, rules } = toRefs(data);
- const { form: searchForm } = useFormData({
- ...data.searchForm,
- // 璁剧疆褰曞叆鏃ユ湡鑼冨洿涓哄綋澶�
- entryDate: [
- dayjs().startOf("day").format("YYYY-MM-DD"),
- dayjs().endOf("day").format("YYYY-MM-DD"),
- ],
- entryDateStart: dayjs().startOf("day").format("YYYY-MM-DD"),
- entryDateEnd: dayjs().endOf("day").format("YYYY-MM-DD"),
- });
-
- // 浜у搧琛ㄥ崟寮规鏁版嵁
- const productFormVisible = ref(false);
- const productOperationType = ref("");
- const productOperationIndex = ref("");
- const currentId = ref("");
- const productFormData = reactive({
- productForm: {
- productId: "",
- productCategory: "",
- productModelId: "",
- specificationModel: "",
- unit: "",
- quantity: "",
- taxInclusiveUnitPrice: "",
- taxRate: "",
- taxInclusiveTotalPrice: "",
- taxExclusiveTotalPrice: "",
- invoiceType: "",
- warnNum: "",
- isChecked: false,
- },
- productRules: {
- productId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- productModelId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- unit: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- quantity: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- taxInclusiveUnitPrice: [
- { required: true, message: "璇疯緭鍏�", trigger: "blur" },
- ],
- taxRate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- warnNum: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- taxInclusiveTotalPrice: [
- { required: true, message: "璇疯緭鍏�", trigger: "blur" },
- ],
- taxExclusiveTotalPrice: [
- { required: true, message: "璇疯緭鍏�", trigger: "blur" },
- ],
- invoiceType: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- isChecked: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- },
- });
- const { productForm, productRules } = toRefs(productFormData);
- const upload = reactive({
- // 涓婁紶鐨勫湴鍧�
- url: import.meta.env.VITE_APP_BASE_API + "/file/upload",
- // 璁剧疆涓婁紶鐨勮姹傚ご閮�
- headers: { Authorization: "Bearer " + getToken() },
- });
-
- // 瀵煎叆鐩稿叧
- const importUploadRef = ref(null);
- const importUpload = reactive({
- title: "瀵煎叆閲囪喘鍙拌处",
- open: false,
- url: import.meta.env.VITE_APP_BASE_API + "/purchase/ledger/import",
- headers: { Authorization: "Bearer " + getToken() },
- isUploading: false,
- beforeUpload: (file) => {
- const isExcel = file.name.endsWith(".xlsx") || file.name.endsWith(".xls");
- const isLt10M = file.size / 1024 / 1024 < 10;
- if (!isExcel) {
- proxy.$modal.msgError("涓婁紶鏂囦欢鍙兘鏄� xlsx/xls 鏍煎紡!");
- return false;
- }
- if (!isLt10M) {
- proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃 10MB!");
- return false;
- }
- return true;
- },
- onChange: (file, fileList) => {
- // noop
- },
- onProgress: (event, file, fileList) => {
- // noop
- },
- onSuccess: (response, file, fileList) => {
- importUpload.isUploading = false;
- if (response?.code === 200) {
- proxy.$modal.msgSuccess("瀵煎叆鎴愬姛");
- importUpload.open = false;
- if (importUploadRef.value) {
- importUploadRef.value.clearFiles?.();
- }
- getList();
- } else {
- proxy.$modal.msgError(response?.msg || "瀵煎叆澶辫触");
- }
- },
- onError: () => {
- importUpload.isUploading = false;
- proxy.$modal.msgError("瀵煎叆澶辫触锛岃閲嶈瘯");
- },
- });
-
- const handleImport = () => {
- importUpload.title = "瀵煎叆閲囪喘鍙拌处";
- importUpload.open = true;
- importUpload.isUploading = false;
- if (importUploadRef.value) {
- importUploadRef.value.clearFiles?.();
- }
- };
-
- // 涓嬭浇瀵煎叆妯℃澘锛堝鍚庣璺緞涓嶅悓锛屽彲鍦ㄦ澶勮皟鏁达級
- const downloadTemplate = () => {
- proxy.download("/purchase/ledger/exportTemplate", {}, "閲囪喘鍙拌处瀵煎叆妯℃澘.xlsx");
- };
-
- const submitImportFile = () => {
- importUpload.isUploading = true;
- proxy.$refs["importUploadRef"]?.submit?.();
- };
-
- const changeDaterange = value => {
- if (value) {
- searchForm.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
- searchForm.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
- } else {
- searchForm.entryDateStart = undefined;
- searchForm.entryDateEnd = undefined;
- }
- handleQuery();
- };
-
- const formattedNumber = (row, column, cellValue) => {
- return parseFloat(cellValue).toFixed(2);
- };
- // 鏌ヨ鍒楄〃
- /** 鎼滅储鎸夐挳鎿嶄綔 */
- const handleQuery = () => {
- page.current = 1;
- getList();
- };
-
- // 淇濆瓨妯℃澘
- const handleButtonClick = async () => {
- // 妫�鏌ユā鏉垮悕绉版槸鍚︿负绌�
- if (!templateName.value || templateName.value.trim() === "") {
- ElMessage({
- message: "璇疯緭鍏ユā鏉垮悕绉�",
- type: "warning",
- });
- return;
- }
-
- // 濡傛灉鏄�滄柊澧炴ā鏉库�濓紙娌℃湁閫変腑宸叉湁妯℃澘锛夛紝鎵嶉渶瑕佸仛閲嶅悕鏍¢獙锛�
- // 鑻ユ槸閫変腑宸叉湁妯℃澘鍚庝慨鏀癸紝鍒欏厑璁镐娇鐢ㄥ師鍚嶇О锛堣涓烘洿鏂帮級
- if (!currentTemplateId.value) {
- const isDuplicate = checkTemplateNameDuplicate(templateName.value);
+// 闃叉姈瀹氭椂鍣�
+let duplicateCheckTimer = null;
+const onTemplateFilterChange = val => {
+ filterInputValue.value = val ?? "";
+ // 娓呴櫎涔嬪墠鐨勫畾鏃跺櫒
+ if (duplicateCheckTimer) {
+ clearTimeout(duplicateCheckTimer);
+ }
+ // 瀹炴椂妫�鏌ユā鏉垮悕绉版槸鍚﹂噸澶嶏紙闃叉姈澶勭悊锛岄伩鍏嶉绻佹彁绀猴級
+ if (val && val.trim()) {
+ duplicateCheckTimer = setTimeout(() => {
+ const isDuplicate = checkTemplateNameDuplicate(val);
if (isDuplicate) {
ElMessage({
message: "妯℃澘鍚嶇О宸插瓨鍦紝璇锋洿鎹㈡ā鏉垮悕绉�",
type: "warning",
+ duration: 2000,
});
- return;
}
+ }, 300); // 300ms 闃叉姈
+ } else {
+ isTemplateNameDuplicate.value = false;
+ }
+};
+
+// allow-create 鏃讹紝杈撳叆涓嶅瓨鍦ㄧ殑鍐呭浼氫綔涓� string 鍊艰繑鍥烇紱杩欓噷鍚屾鍥炶緭鍏ユ浠ョ‘淇濇枃瀛椾笉涓�
+const onTemplateChange = async val => {
+ if (typeof val === "string") {
+ filterInputValue.value = val;
+ // 閫夋嫨鎴栬緭鍏ユ椂妫�鏌ラ噸澶�
+ checkTemplateNameDuplicate(val);
+ }
+
+ // 杩囨护鏁版嵁锛屾煡鎵惧尮閰嶇殑妯℃澘
+ const matchedTemplate = templateList.value.find(
+ item => item.templateName === val
+ );
+
+ if (matchedTemplate?.id) {
+ // 璁板綍褰撳墠閫変腑鐨勬ā鏉縄D锛屽悗缁繚瀛樻椂杩涜鏇存柊鎿嶄綔
+ currentTemplateId.value = matchedTemplate.id;
+ // 閫変腑宸叉湁妯℃澘鏃讹紝涓嶅簲瑙嗕负鈥滄ā鏉垮悕绉伴噸澶嶅鑷翠笉鍙繚瀛樷��
+ isTemplateNameDuplicate.value = false;
+ // 濡傛灉鎵惧埌妯℃澘锛屽彧璧嬪�间緵搴斿晢銆侀」鐩悕绉般�佷粯娆炬柟寮忓拰浜у搧淇℃伅
+ if (matchedTemplate.supplierId) {
+ form.value.supplierId = matchedTemplate.supplierId;
+ }
+ if (matchedTemplate.supplierName) {
+ form.value.supplierName = matchedTemplate.supplierName;
+ }
+ if (matchedTemplate.projectName) {
+ form.value.projectName = matchedTemplate.projectName;
+ }
+ if (matchedTemplate.paymentMethod) {
+ form.value.paymentMethod = matchedTemplate.paymentMethod;
+ }
+ // 妯℃澘鏁版嵁涓殑浜у搧瀛楁鏄� productList锛岄渶瑕佽浆鎹负 productData
+ productData.value = matchedTemplate.productList || matchedTemplate.productData || [];
+ } else {
+ // 鏈尮閰嶅埌宸叉湁妯℃澘锛岃涓烘柊妯℃澘
+ currentTemplateId.value = null;
+ // 濡傛灉娌℃湁鎵惧埌妯℃澘锛岄噸缃〃鍗曪紙淇濇寔褰撳墠琛ㄥ崟鐘舵�侊級
+ const currentFormData = {...form.value};
+ const currentProductData = [...productData.value];
+
+ // 濡傛灉瀵硅瘽妗嗘湭鎵撳紑锛屽厛鎵撳紑
+ if (!dialogFormVisible.value) {
+ operationType.value = "add";
+ dialogFormVisible.value = true;
}
- // 妫�鏌ヤ緵搴斿晢鏄惁閫夋嫨
- if (!form.value.supplierId) {
+ // 绛夊緟涓嬩竴涓� tick 鍚庢仮澶嶆暟鎹�
+ await nextTick();
+ form.value = {
+ ...form.value,
+ ...currentFormData,
+ };
+ productData.value = currentProductData;
+ }
+};
+
+// 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
+const operationType = ref("");
+const dialogFormVisible = ref(false);
+const data = reactive({
+ searchForm: {
+ supplierName: "", // 渚涘簲鍟嗗悕绉�
+ purchaseContractNumber: "", // 閲囪喘鍚堝悓缂栧彿
+ salesContractNo: "", // 閿�鍞悎鍚岀紪鍙�
+ projectName: "", // 椤圭洰鍚嶇О
+ entryDate: null, // 褰曞叆鏃ユ湡
+ entryDateStart: undefined,
+ entryDateEnd: undefined,
+ },
+ form: {
+ purchaseContractNumber: "",
+ salesLedgerId: "",
+ projectName: "",
+ recorderId: "",
+ recorderName: "",
+ entryDate: "",
+ productData: [],
+ supplierName: "",
+ supplierId: "",
+ paymentMethod: "",
+ executionDate: "",
+ isChecked: false,
+ },
+ rules: {
+ purchaseContractNumber: [
+ {required: true, message: "璇疯緭鍏�", trigger: "blur"},
+ ],
+ projectName: [
+ {required: true, message: "璇疯緭鍏ラ」鐩悕绉�", trigger: "blur"},
+ ],
+ supplierId: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
+ entryDate: [{required: true, message: "璇烽�夋嫨", trigger: "change"}],
+ executionDate: [{required: true, message: "璇烽�夋嫨", trigger: "change"}],
+ },
+});
+const {form, rules} = toRefs(data);
+const {form: searchForm} = useFormData({
+ ...data.searchForm,
+ // 璁剧疆褰曞叆鏃ユ湡鑼冨洿涓哄綋澶�
+ entryDate: [
+ dayjs().startOf("day").format("YYYY-MM-DD"),
+ dayjs().endOf("day").format("YYYY-MM-DD"),
+ ],
+ entryDateStart: dayjs().startOf("day").format("YYYY-MM-DD"),
+ entryDateEnd: dayjs().endOf("day").format("YYYY-MM-DD"),
+});
+
+// 浜у搧琛ㄥ崟寮规鏁版嵁
+const productFormVisible = ref(false);
+const productOperationType = ref("");
+const productOperationIndex = ref("");
+const currentId = ref("");
+const productFormData = reactive({
+ productForm: {
+ productId: "",
+ productCategory: "",
+ productModelId: "",
+ specificationModel: "",
+ unit: "",
+ quantity: "",
+ taxInclusiveUnitPrice: "",
+ taxRate: "",
+ taxInclusiveTotalPrice: "",
+ taxExclusiveTotalPrice: "",
+ invoiceType: "",
+ warnNum: "",
+ isChecked: false,
+ },
+ productRules: {
+ productId: [{required: true, message: "璇烽�夋嫨", trigger: "change"}],
+ productModelId: [{required: true, message: "璇烽�夋嫨", trigger: "change"}],
+ unit: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
+ quantity: [{required: true, message: "璇疯緭鍏�", trigger: "blur"}],
+ taxInclusiveUnitPrice: [
+ {required: true, message: "璇疯緭鍏�", trigger: "blur"},
+ ],
+ taxRate: [{required: true, message: "璇烽�夋嫨", trigger: "change"}],
+ warnNum: [{required: true, message: "璇烽�夋嫨", trigger: "change"}],
+ taxInclusiveTotalPrice: [
+ {required: true, message: "璇疯緭鍏�", trigger: "blur"},
+ ],
+ taxExclusiveTotalPrice: [
+ {required: true, message: "璇疯緭鍏�", trigger: "blur"},
+ ],
+ invoiceType: [{required: true, message: "璇烽�夋嫨", trigger: "change"}],
+ isChecked: [{required: true, message: "璇烽�夋嫨", trigger: "change"}],
+ },
+});
+const {productForm, productRules} = toRefs(productFormData);
+const upload = reactive({
+ // 涓婁紶鐨勫湴鍧�
+ url: import.meta.env.VITE_APP_BASE_API + "/file/upload",
+ // 璁剧疆涓婁紶鐨勮姹傚ご閮�
+ headers: {Authorization: "Bearer " + getToken()},
+});
+
+// 瀵煎叆鐩稿叧
+const importUploadRef = ref(null);
+const importUpload = reactive({
+ title: "瀵煎叆閲囪喘鍙拌处",
+ open: false,
+ url: import.meta.env.VITE_APP_BASE_API + "/purchase/ledger/import",
+ headers: {Authorization: "Bearer " + getToken()},
+ isUploading: false,
+ beforeUpload: (file) => {
+ const isExcel = file.name.endsWith(".xlsx") || file.name.endsWith(".xls");
+ const isLt10M = file.size / 1024 / 1024 < 10;
+ if (!isExcel) {
+ proxy.$modal.msgError("涓婁紶鏂囦欢鍙兘鏄� xlsx/xls 鏍煎紡!");
+ return false;
+ }
+ if (!isLt10M) {
+ proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃 10MB!");
+ return false;
+ }
+ return true;
+ },
+ onChange: (file, fileList) => {
+ // noop
+ },
+ onProgress: (event, file, fileList) => {
+ // noop
+ },
+ onSuccess: (response, file, fileList) => {
+ importUpload.isUploading = false;
+ if (response?.code === 200) {
+ proxy.$modal.msgSuccess("瀵煎叆鎴愬姛");
+ importUpload.open = false;
+ if (importUploadRef.value) {
+ importUploadRef.value.clearFiles?.();
+ }
+ getList();
+ } else {
+ proxy.$modal.msgError(response?.msg || "瀵煎叆澶辫触");
+ }
+ },
+ onError: () => {
+ importUpload.isUploading = false;
+ proxy.$modal.msgError("瀵煎叆澶辫触锛岃閲嶈瘯");
+ },
+});
+
+const handleImport = () => {
+ importUpload.title = "瀵煎叆閲囪喘鍙拌处";
+ importUpload.open = true;
+ importUpload.isUploading = false;
+ if (importUploadRef.value) {
+ importUploadRef.value.clearFiles?.();
+ }
+};
+
+// 涓嬭浇瀵煎叆妯℃澘锛堝鍚庣璺緞涓嶅悓锛屽彲鍦ㄦ澶勮皟鏁达級
+const downloadTemplate = () => {
+ proxy.download("/purchase/ledger/exportTemplate", {}, "閲囪喘鍙拌处瀵煎叆妯℃澘.xlsx");
+};
+
+const submitImportFile = () => {
+ importUpload.isUploading = true;
+ proxy.$refs["importUploadRef"]?.submit?.();
+};
+
+const changeDaterange = value => {
+ if (value) {
+ searchForm.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
+ searchForm.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
+ } else {
+ searchForm.entryDateStart = undefined;
+ searchForm.entryDateEnd = undefined;
+ }
+ handleQuery();
+};
+
+const formattedNumber = (row, column, cellValue) => {
+ return parseFloat(cellValue).toFixed(2);
+};
+// 鏌ヨ鍒楄〃
+/** 鎼滅储鎸夐挳鎿嶄綔 */
+const handleQuery = () => {
+ page.current = 1;
+ getList();
+};
+
+// 淇濆瓨妯℃澘
+const handleButtonClick = async () => {
+ // 妫�鏌ユā鏉垮悕绉版槸鍚︿负绌�
+ if (!templateName.value || templateName.value.trim() === "") {
+ ElMessage({
+ message: "璇疯緭鍏ユā鏉垮悕绉�",
+ type: "warning",
+ });
+ return;
+ }
+
+ // 濡傛灉鏄�滄柊澧炴ā鏉库�濓紙娌℃湁閫変腑宸叉湁妯℃澘锛夛紝鎵嶉渶瑕佸仛閲嶅悕鏍¢獙锛�
+ // 鑻ユ槸閫変腑宸叉湁妯℃澘鍚庝慨鏀癸紝鍒欏厑璁镐娇鐢ㄥ師鍚嶇О锛堣涓烘洿鏂帮級
+ if (!currentTemplateId.value) {
+ const isDuplicate = checkTemplateNameDuplicate(templateName.value);
+ if (isDuplicate) {
ElMessage({
- message: "璇峰厛閫夋嫨渚涘簲鍟�",
+ message: "妯℃澘鍚嶇О宸插瓨鍦紝璇锋洿鎹㈡ā鏉垮悕绉�",
type: "warning",
});
return;
}
+ }
- // 妫�鏌ユ槸鍚︽湁浜у搧鏁版嵁
- if (!productData.value || productData.value.length === 0) {
- ElMessage({
- message: '璇峰厛娣诲姞浜у搧淇℃伅',
- type: 'warning',
+ // 妫�鏌ヤ緵搴斿晢鏄惁閫夋嫨
+ if (!form.value.supplierId) {
+ ElMessage({
+ message: "璇峰厛閫夋嫨渚涘簲鍟�",
+ type: "warning",
+ });
+ return;
+ }
+
+ // 妫�鏌ユ槸鍚︽湁浜у搧鏁版嵁
+ if (!productData.value || productData.value.length === 0) {
+ ElMessage({
+ message: '璇峰厛娣诲姞浜у搧淇℃伅',
+ type: 'warning',
+ });
+ return;
+ }
+
+ try {
+ let params = {
+ productData: proxy.HaveJson(productData.value),
+ supplierId: form.value.supplierId,
+ paymentMethod: form.value.paymentMethod,
+ recorderId: form.value.recorderId,
+ recorderName: form.value.recorderName,
+ projectName: form.value.projectName,
+ templateName: templateName.value.trim(),
+ };
+ console.log("template params ===>", params, "currentTemplateId:", currentTemplateId.value);
+
+ // 濡傛灉 currentTemplateId 鏈夊�硷紝璇存槑褰撳墠鏄�滅紪杈戝凡鏈夋ā鏉库�� 鈫� 璋冪敤鏇存柊鎺ュ彛
+ // 鍚﹀垯涓衡�滄柊寤烘ā鏉库�� 鈫� 璋冪敤鏂板鎺ュ彛
+ let res;
+ if (currentTemplateId.value) {
+ res = await updatePurchaseTemplate({
+ id: currentTemplateId.value,
+ ...params,
});
- return;
+ } else {
+ res = await addPurchaseTemplate(params);
}
- try {
- let params = {
- productData: proxy.HaveJson(productData.value),
- supplierId: form.value.supplierId,
- paymentMethod: form.value.paymentMethod,
- recorderId: form.value.recorderId,
- recorderName: form.value.recorderName,
- projectName: form.value.projectName,
- templateName: templateName.value.trim(),
- };
- console.log("template params ===>", params, "currentTemplateId:", currentTemplateId.value);
-
- // 濡傛灉 currentTemplateId 鏈夊�硷紝璇存槑褰撳墠鏄�滅紪杈戝凡鏈夋ā鏉库�� 鈫� 璋冪敤鏇存柊鎺ュ彛
- // 鍚﹀垯涓衡�滄柊寤烘ā鏉库�� 鈫� 璋冪敤鏂板鎺ュ彛
- let res;
- if (currentTemplateId.value) {
- res = await updatePurchaseTemplate({
- id: currentTemplateId.value,
- ...params,
- });
- } else {
- res = await addPurchaseTemplate(params);
- }
-
- if (res && res.code === 200) {
- ElMessage({
- message: currentTemplateId.value ? "妯℃澘鏇存柊鎴愬姛" : "妯℃澘淇濆瓨鎴愬姛",
- type: "success",
- });
- // 淇濆瓨鎴愬姛鍚庨噸鏂拌幏鍙栨ā鏉垮垪琛�
- await getTemplateList();
- // 娓呯┖妯℃澘鍚嶇О杈撳叆
- templateName.value = "";
- filterInputValue.value = "";
- isTemplateNameDuplicate.value = false;
- // 淇濆瓨/鏇存柊瀹屾垚鍚庯紝閲嶇疆褰撳墠妯℃澘ID
- currentTemplateId.value = null;
- } else {
- ElMessage({
- message: res?.msg || "妯℃澘淇濆瓨澶辫触",
- type: "error",
- });
- }
- } catch (error) {
- console.error("淇濆瓨妯℃澘澶辫触:", error);
+ if (res && res.code === 200) {
ElMessage({
- message: "妯℃澘淇濆瓨澶辫触锛岃绋嶅悗閲嶈瘯",
+ message: currentTemplateId.value ? "妯℃澘鏇存柊鎴愬姛" : "妯℃澘淇濆瓨鎴愬姛",
+ type: "success",
+ });
+ // 淇濆瓨鎴愬姛鍚庨噸鏂拌幏鍙栨ā鏉垮垪琛�
+ await getTemplateList();
+ // 娓呯┖妯℃澘鍚嶇О杈撳叆
+ templateName.value = "";
+ filterInputValue.value = "";
+ isTemplateNameDuplicate.value = false;
+ // 淇濆瓨/鏇存柊瀹屾垚鍚庯紝閲嶇疆褰撳墠妯℃澘ID
+ currentTemplateId.value = null;
+ } else {
+ ElMessage({
+ message: res?.msg || "妯℃澘淇濆瓨澶辫触",
type: "error",
});
}
- };
- // 瀛愯〃鍚堣鏂规硶
- const summarizeChildrenTable = param => {
- return proxy.summarizeTable(
+ } catch (error) {
+ console.error("淇濆瓨妯℃澘澶辫触:", error);
+ ElMessage({
+ message: "妯℃澘淇濆瓨澶辫触锛岃绋嶅悗閲嶈瘯",
+ type: "error",
+ });
+ }
+};
+// 瀛愯〃鍚堣鏂规硶
+const summarizeChildrenTable = param => {
+ return proxy.summarizeTable(
param,
[
"taxInclusiveUnitPrice",
@@ -1121,20 +1110,20 @@
"futureTicketsAmount",
],
{
- ticketsNum: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
- futureTickets: { noDecimal: true }, // 涓嶄繚鐣欏皬鏁�
+ ticketsNum: {noDecimal: true}, // 涓嶄繚鐣欏皬鏁�
+ futureTickets: {noDecimal: true}, // 涓嶄繚鐣欏皬鏁�
}
- );
- };
- const paginationChange = obj => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
- };
- const getList = () => {
- tableLoading.value = true;
- const { entryDate, ...rest } = searchForm;
- purchaseListPage({ ...rest, ...page })
+ );
+};
+const paginationChange = obj => {
+ page.current = obj.page;
+ page.size = obj.limit;
+ getList();
+};
+const getList = () => {
+ tableLoading.value = true;
+ const {entryDate, ...rest} = searchForm;
+ purchaseListPage({...rest, ...page})
.then(res => {
tableLoading.value = false;
// tableData.value = res.data.records;
@@ -1151,458 +1140,461 @@
.catch(() => {
tableLoading.value = false;
});
- };
- // 琛ㄦ牸閫夋嫨鏁版嵁
- const handleSelectionChange = selection => {
- selectedRows.value = selection;
- };
- const productSelected = selectedRows => {
- productSelectedRows.value = selectedRows;
- };
- const expandedRowKeys = ref([]);
- // 灞曞紑琛�
- const expandChange = async (row, expandedRows) => {
- if (expandedRows.length > 0) {
- expandedRowKeys.value = [];
+};
+// 琛ㄦ牸閫夋嫨鏁版嵁
+const handleSelectionChange = selection => {
+ selectedRows.value = selection;
+};
+const productSelected = selectedRows => {
+ productSelectedRows.value = selectedRows;
+};
+const expandedRowKeys = ref([]);
+// 灞曞紑琛�
+const expandChange = async (row, expandedRows) => {
+ if (expandedRows.length > 0) {
+ expandedRowKeys.value = [];
+ try {
+ const res = await productList({salesLedgerId: row.id, type: 2});
+ const index = tableData.value.findIndex(item => item.id === row.id);
+ if (index > -1) {
+ tableData.value[index].children = res.data || [];
+ expandedRowKeys.value.push(row.id);
+ }
+ } catch (error) {
+ console.error("鍔犺浇浜у搧鍒楄〃澶辫触:", error);
+ proxy.$modal.msgError("鍔犺浇浜у搧鍒楄〃澶辫触");
+ // 灞曞紑澶辫触鏃讹紝绉婚櫎灞曞紑鐘舵��
+ const index = expandedRows.findIndex(item => item.id === row.id);
+ if (index > -1) {
+ expandedRows.splice(index, 1);
+ }
+ }
+ } else {
+ expandedRowKeys.value = [];
+ }
+};
+// 涓昏〃鍚堣鏂规硶
+const summarizeMainTable = param => {
+ return proxy.summarizeTable(param, ["contractAmount"]);
+};
+// 瀛愯〃鍚堣鏂规硶
+const summarizeProTable = param => {
+ return proxy.summarizeTable(param, [
+ "taxInclusiveUnitPrice",
+ "taxInclusiveTotalPrice",
+ "taxExclusiveTotalPrice",
+ ]);
+};
+// 鎵撳紑寮规
+const openForm = async (type, row) => {
+ // 缂栬緫鏃舵鏌ュ鏍哥姸鎬侊紝鍙湁寰呭鏍�(1)鍜屽鎵瑰け璐�(4)鎵嶈兘缂栬緫
+ if (type === "edit" && row) {
+ if (row.approvalStatus !== 1 && row.approvalStatus !== 4) {
+ proxy.$modal.msgWarning("鍙湁寰呭鏍稿拰瀹℃壒澶辫触鐘舵�佺殑璁板綍鎵嶈兘缂栬緫");
+ return;
+ }
+ }
+
+ await getTemplateList();
+ operationType.value = type;
+ form.value = {};
+ productData.value = [];
+ fileList.value = [];
+ templateName.value = "";
+ filterInputValue.value = "";
+ isTemplateNameDuplicate.value = false;
+ try {
+ // 骞惰鍔犺浇鍩虹鏁版嵁
+ const [salesRes, supplierRes] = await Promise.all([
+ getSalesNo(),
+ getOptions(),
+ ]);
+
+ salesContractList.value = salesRes || [];
+ // 渚涘簲鍟嗚繃婊ゅ嚭isWhite=0 鐨勬暟鎹�
+ supplierList.value = (supplierRes.data || []).filter(
+ item => item.isWhite === 0
+ );
+
+ // 璁剧疆榛樿鍊�
+ form.value.recorderName = userStore.nickName;
+ form.value.entryDate = getCurrentDate();
+
+ if (type === "add") {
+ // 鏂板鏃剁敓鎴愰噰璐悎鍚屽彿
try {
- const res = await productList({ salesLedgerId: row.id, type: 2 });
- const index = tableData.value.findIndex(item => item.id === row.id);
- if (index > -1) {
- tableData.value[index].children = res.data || [];
- expandedRowKeys.value.push(row.id);
+ const purchaseNoRes = await createPurchaseNo();
+ if (purchaseNoRes?.data) {
+ form.value.purchaseContractNumber = purchaseNoRes.data;
}
} catch (error) {
- console.error("鍔犺浇浜у搧鍒楄〃澶辫触:", error);
- proxy.$modal.msgError("鍔犺浇浜у搧鍒楄〃澶辫触");
- // 灞曞紑澶辫触鏃讹紝绉婚櫎灞曞紑鐘舵��
- const index = expandedRows.findIndex(item => item.id === row.id);
- if (index > -1) {
- expandedRows.splice(index, 1);
- }
+ console.error("鐢熸垚閲囪喘鍚堝悓鍙峰け璐�:", error);
+ proxy.$modal.msgWarning("鐢熸垚閲囪喘鍚堝悓鍙峰け璐�");
}
- } else {
- expandedRowKeys.value = [];
- }
- };
- // 涓昏〃鍚堣鏂规硶
- const summarizeMainTable = param => {
- return proxy.summarizeTable(param, ["contractAmount"]);
- };
- // 瀛愯〃鍚堣鏂规硶
- const summarizeProTable = param => {
- return proxy.summarizeTable(param, [
- "taxInclusiveUnitPrice",
- "taxInclusiveTotalPrice",
- "taxExclusiveTotalPrice",
- ]);
- };
- // 鎵撳紑寮规
- const openForm = async (type, row) => {
- // 缂栬緫鏃舵鏌ュ鏍哥姸鎬侊紝鍙湁寰呭鏍�(1)鍜屽鎵瑰け璐�(4)鎵嶈兘缂栬緫
- if (type === "edit" && row) {
- if (row.approvalStatus !== 1 && row.approvalStatus !== 4) {
- proxy.$modal.msgWarning("鍙湁寰呭鏍稿拰瀹℃壒澶辫触鐘舵�佺殑璁板綍鎵嶈兘缂栬緫");
+ } else if (type === "edit" && row?.id) {
+ // 缂栬緫鏃跺姞杞芥暟鎹�
+ currentId.value = row.id;
+ try {
+ const purchaseRes = await getPurchaseById({id: row.id, type: 2});
+ form.value = {...purchaseRes};
+ productData.value = purchaseRes.productData || [];
+ fileList.value = purchaseRes.storageBlobVOS || [];
+ } catch (error) {
+ console.error("鍔犺浇閲囪喘鍙拌处鏁版嵁澶辫触:", error);
+ proxy.$modal.msgError("鍔犺浇鏁版嵁澶辫触");
return;
}
}
-
- await getTemplateList();
- operationType.value = type;
- form.value = {};
- productData.value = [];
- fileList.value = [];
- templateName.value = "";
- filterInputValue.value = "";
- isTemplateNameDuplicate.value = false;
+
+ if (form.value.salesLedgerId == -1) {
+ form.value.salesLedgerId = null;
+ }
+ console.log(form.value, "form.value===========");
+ dialogFormVisible.value = true;
+ } catch (error) {
+ console.error("鎵撳紑琛ㄥ崟澶辫触:", error);
+ proxy.$modal.msgError("鍔犺浇鍩虹鏁版嵁澶辫触");
+ }
+};
+
+// 涓婁紶鍓嶆牎妫�
+function handleBeforeUpload(file) {
+ // 鏍℃鏂囦欢澶у皬
+ if (file.size > 1024 * 1024 * 10) {
+ proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃10MB!");
+ return false;
+ }
+ proxy.$modal.loading("姝e湪涓婁紶鏂囦欢锛岃绋嶅��...");
+ return true;
+}
+
+// 涓婁紶澶辫触
+function handleUploadError(err) {
+ proxy.$modal.msgError("涓婁紶鏂囦欢澶辫触");
+ proxy.$modal.closeLoading();
+}
+
+// 涓婁紶鎴愬姛鍥炶皟
+function handleUploadSuccess(res, file, uploadFiles) {
+ proxy.$modal.closeLoading();
+ if (res.code === 200) {
+ file.tempId = res.data.tempId;
+ proxy.$modal.msgSuccess("涓婁紶鎴愬姛");
+ } else {
+ proxy.$modal.msgError(res.msg);
+ proxy.$refs.fileUpload.handleRemove(file);
+ }
+}
+
+// 绉婚櫎鏂囦欢
+async function handleRemove(file) {
+ if (!file?.id) {
+ return;
+ }
+ console.log("handleRemove", file.id);
+ if (file.size > 1024 * 1024 * 10) {
+ // 浠呭墠绔竻鐞嗭紝涓嶈皟鐢ㄥ垹闄ゆ帴鍙e拰鎻愮ず
+ return;
+ }
+
+ if (operationType.value === "edit" && file.id) {
try {
- // 骞惰鍔犺浇鍩虹鏁版嵁
- const [salesRes, supplierRes] = await Promise.all([
- getSalesNo(),
- getOptions(),
- ]);
-
- salesContractList.value = salesRes || [];
- // 渚涘簲鍟嗚繃婊ゅ嚭isWhite=0 鐨勬暟鎹�
- supplierList.value = (supplierRes.data || []).filter(
- item => item.isWhite === 0
- );
-
- // 璁剧疆榛樿鍊�
- form.value.recorderName = userStore.nickName;
- form.value.entryDate = getCurrentDate();
-
- if (type === "add") {
- // 鏂板鏃剁敓鎴愰噰璐悎鍚屽彿
- try {
- const purchaseNoRes = await createPurchaseNo();
- if (purchaseNoRes?.data) {
- form.value.purchaseContractNumber = purchaseNoRes.data;
- }
- } catch (error) {
- console.error("鐢熸垚閲囪喘鍚堝悓鍙峰け璐�:", error);
- proxy.$modal.msgWarning("鐢熸垚閲囪喘鍚堝悓鍙峰け璐�");
- }
- } else if (type === "edit" && row?.id) {
- // 缂栬緫鏃跺姞杞芥暟鎹�
- currentId.value = row.id;
- try {
- const purchaseRes = await getPurchaseById({ id: row.id, type: 2 });
- form.value = { ...purchaseRes };
- productData.value = purchaseRes.productData || [];
- fileList.value = purchaseRes.salesLedgerFiles || [];
- } catch (error) {
- console.error("鍔犺浇閲囪喘鍙拌处鏁版嵁澶辫触:", error);
- proxy.$modal.msgError("鍔犺浇鏁版嵁澶辫触");
- return;
- }
- }
-
- if (form.value.salesLedgerId == -1) {
- form.value.salesLedgerId = null;
- }
- console.log(form.value, "form.value===========");
- dialogFormVisible.value = true;
+ await delLedgerFile([file.id]);
+ proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
} catch (error) {
- console.error("鎵撳紑琛ㄥ崟澶辫触:", error);
- proxy.$modal.msgError("鍔犺浇鍩虹鏁版嵁澶辫触");
- }
- };
- // 涓婁紶鍓嶆牎妫�
- function handleBeforeUpload(file) {
- // 鏍℃鏂囦欢澶у皬
- if (file.size > 1024 * 1024 * 10) {
- proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃10MB!");
- return false;
- }
- proxy.$modal.loading("姝e湪涓婁紶鏂囦欢锛岃绋嶅��...");
- return true;
- }
- // 涓婁紶澶辫触
- function handleUploadError(err) {
- proxy.$modal.msgError("涓婁紶鏂囦欢澶辫触");
- proxy.$modal.closeLoading();
- }
- // 涓婁紶鎴愬姛鍥炶皟
- function handleUploadSuccess(res, file, uploadFiles) {
- proxy.$modal.closeLoading();
- if (res.code === 200) {
- file.tempId = res.data.tempId;
- proxy.$modal.msgSuccess("涓婁紶鎴愬姛");
- } else {
- proxy.$modal.msgError(res.msg);
- proxy.$refs.fileUpload.handleRemove(file);
+ console.error("鍒犻櫎鏂囦欢澶辫触:", error);
+ proxy.$modal.msgError("鍒犻櫎鏂囦欢澶辫触");
}
}
- // 绉婚櫎鏂囦欢
- async function handleRemove(file) {
- if (!file?.id) {
- return;
- }
- console.log("handleRemove", file.id);
- if (file.size > 1024 * 1024 * 10) {
- // 浠呭墠绔竻鐞嗭紝涓嶈皟鐢ㄥ垹闄ゆ帴鍙e拰鎻愮ず
- return;
- }
+}
- if (operationType.value === "edit" && file.id) {
- try {
- await delLedgerFile([file.id]);
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- } catch (error) {
- console.error("鍒犻櫎鏂囦欢澶辫触:", error);
- proxy.$modal.msgError("鍒犻櫎鏂囦欢澶辫触");
- }
- }
- }
- // 鎻愪氦琛ㄥ崟
- const submitForm = () => {
- proxy.$refs["formRef"].validate(valid => {
- if (valid) {
- if (productData.value.length > 0) {
- // 鏂板鏃讹紝闇�瑕佷粠姣忎釜浜у搧瀵硅薄涓垹闄� id 瀛楁
- let processedProductData = productData.value;
- if (operationType.value === "add") {
- processedProductData = productData.value.map(product => {
- const { id, ...rest } = product;
- return rest;
- });
- }
- form.value.productData = proxy.HaveJson(processedProductData);
- } else {
- proxy.$modal.msgWarning("璇锋坊鍔犱骇鍝佷俊鎭�");
- return;
- }
- let tempFileIds = [];
- if (fileList.value.length > 0) {
- tempFileIds = fileList.value.map(item => item.tempId);
- }
- form.value.tempFileIds = tempFileIds;
- form.value.type = 2;
-
- // 濡傛灉salesLedgerId涓虹┖锛屽垯涓嶄紶閫抯alesContractNo
- if (!form.value.salesLedgerId) {
- form.value.salesContractNo = "";
- }
-
- // 鏂板鏃朵笉浼犻�抜d
- const submitData = { ...form.value };
+// 鎻愪氦琛ㄥ崟
+const submitForm = () => {
+ proxy.$refs["formRef"].validate(valid => {
+ if (valid) {
+ if (productData.value.length > 0) {
+ // 鏂板鏃讹紝闇�瑕佷粠姣忎釜浜у搧瀵硅薄涓垹闄� id 瀛楁
+ let processedProductData = productData.value;
if (operationType.value === "add") {
- delete submitData.id;
+ processedProductData = productData.value.map(product => {
+ const {id, ...rest} = product;
+ return rest;
+ });
}
-
- addOrEditPurchase(submitData).then(res => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- getList();
- });
+ form.value.productData = proxy.HaveJson(processedProductData);
+ } else {
+ proxy.$modal.msgWarning("璇锋坊鍔犱骇鍝佷俊鎭�");
+ return;
}
- });
- };
- // 鍏抽棴寮规
- const closeDia = () => {
- proxy.resetForm("formRef");
- dialogFormVisible.value = false;
- };
- // 鎵撳紑浜у搧寮规
- const openProductForm = async (type, row, index) => {
- productOperationType.value = type;
- productOperationIndex.value = index;
- productForm.value = {};
- proxy.resetForm("productFormRef");
- productFormVisible.value = true;
-
- // 鍏堣幏鍙栦骇鍝侀�夐」锛岀‘淇濇暟鎹姞杞藉畬鎴�
- await getProductOptions();
-
- // 绛夊緟 DOM 鏇存柊
- await nextTick();
-
- if (type === "add") {
- productForm.value.isChecked = false;
- }
+ form.value.storageBlobDTOS = fileList.value;
+ form.value.type = 2;
- if (type === "edit") {
- // 澶嶅埗琛屾暟鎹�
- productForm.value = { ...row };
-
- // 濡傛灉鏄粠妯℃澘鍔犺浇鐨勬暟鎹紝鍙兘娌℃湁 productId 鍜� productModelId
- // 闇�瑕佹牴鎹� productCategory 鍜� specificationModel 鏉ユ煡鎵惧搴旂殑 ID
- if (!productForm.value.productId && productForm.value.productCategory) {
- // 鏍规嵁 productCategory 鏌ユ壘 productId
- const findProductIdByCategory = (nodes, categoryName) => {
- for (let i = 0; i < nodes.length; i++) {
- if (nodes[i].label === categoryName) {
- return nodes[i].value;
- }
- if (nodes[i].children && nodes[i].children.length > 0) {
- const found = findProductIdByCategory(nodes[i].children, categoryName);
- if (found) return found;
- }
+ // 濡傛灉salesLedgerId涓虹┖锛屽垯涓嶄紶閫抯alesContractNo
+ if (!form.value.salesLedgerId) {
+ form.value.salesContractNo = "";
+ }
+
+ // 鏂板鏃朵笉浼犻�抜d
+ const submitData = {...form.value};
+ if (operationType.value === "add") {
+ delete submitData.id;
+ }
+
+ addOrEditPurchase(submitData).then(res => {
+ proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+ closeDia();
+ getList();
+ });
+ }
+ });
+};
+// 鍏抽棴寮规
+const closeDia = () => {
+ proxy.resetForm("formRef");
+ dialogFormVisible.value = false;
+};
+// 鎵撳紑浜у搧寮规
+const openProductForm = async (type, row, index) => {
+ productOperationType.value = type;
+ productOperationIndex.value = index;
+ productForm.value = {};
+ proxy.resetForm("productFormRef");
+ productFormVisible.value = true;
+
+ // 鍏堣幏鍙栦骇鍝侀�夐」锛岀‘淇濇暟鎹姞杞藉畬鎴�
+ await getProductOptions();
+
+ // 绛夊緟 DOM 鏇存柊
+ await nextTick();
+
+ if (type === "add") {
+ productForm.value.isChecked = false;
+ }
+
+ if (type === "edit") {
+ // 澶嶅埗琛屾暟鎹�
+ productForm.value = {...row};
+
+ // 濡傛灉鏄粠妯℃澘鍔犺浇鐨勬暟鎹紝鍙兘娌℃湁 productId 鍜� productModelId
+ // 闇�瑕佹牴鎹� productCategory 鍜� specificationModel 鏉ユ煡鎵惧搴旂殑 ID
+ if (!productForm.value.productId && productForm.value.productCategory) {
+ // 鏍规嵁 productCategory 鏌ユ壘 productId
+ const findProductIdByCategory = (nodes, categoryName) => {
+ for (let i = 0; i < nodes.length; i++) {
+ if (nodes[i].label === categoryName) {
+ return nodes[i].value;
}
- return null;
- };
-
- const productId = findProductIdByCategory(productOptions.value, productForm.value.productCategory);
- if (productId) {
- productForm.value.productId = productId;
- // 鑾峰彇鍨嬪彿鍒楄〃骞剁瓑寰呭畬鎴�
- const modelRes = await modelList({ id: productId });
- modelOptions.value = modelRes;
-
- // 绛夊緟 DOM 鏇存柊
- await nextTick();
-
- // 鏍规嵁 specificationModel 鏌ユ壘 productModelId
- if (productForm.value.specificationModel && modelOptions.value.length > 0) {
- const modelItem = modelOptions.value.find(
- item => item.model === productForm.value.specificationModel
- );
- if (modelItem) {
- productForm.value.productModelId = modelItem.id;
- // 璁剧疆瑙勬牸鍨嬪彿鍜屽崟浣�
- getProductModel(modelItem.id);
- }
+ if (nodes[i].children && nodes[i].children.length > 0) {
+ const found = findProductIdByCategory(nodes[i].children, categoryName);
+ if (found) return found;
}
}
- } else if (productForm.value.productId) {
- // 濡傛灉鏈� productId锛屾甯稿姞杞藉瀷鍙峰垪琛�
- await getModels(productForm.value.productId);
-
+ return null;
+ };
+
+ const productId = findProductIdByCategory(productOptions.value, productForm.value.productCategory);
+ if (productId) {
+ productForm.value.productId = productId;
+ // 鑾峰彇鍨嬪彿鍒楄〃骞剁瓑寰呭畬鎴�
+ const modelRes = await modelList({id: productId});
+ modelOptions.value = modelRes;
+
// 绛夊緟 DOM 鏇存柊
await nextTick();
-
- if (productForm.value.productModelId) {
- getProductModel(productForm.value.productModelId);
+
+ // 鏍规嵁 specificationModel 鏌ユ壘 productModelId
+ if (productForm.value.specificationModel && modelOptions.value.length > 0) {
+ const modelItem = modelOptions.value.find(
+ item => item.model === productForm.value.specificationModel
+ );
+ if (modelItem) {
+ productForm.value.productModelId = modelItem.id;
+ // 璁剧疆瑙勬牸鍨嬪彿鍜屽崟浣�
+ getProductModel(modelItem.id);
+ }
}
}
-
- // 鏈�鍚庡啀绛夊緟涓�娆� DOM 鏇存柊锛岀‘淇濇墍鏈夋暟鎹兘宸茶缃�
+ } else if (productForm.value.productId) {
+ // 濡傛灉鏈� productId锛屾甯稿姞杞藉瀷鍙峰垪琛�
+ await getModels(productForm.value.productId);
+
+ // 绛夊緟 DOM 鏇存柊
await nextTick();
+
+ if (productForm.value.productModelId) {
+ getProductModel(productForm.value.productModelId);
+ }
}
- };
- const getProductOptions = () => {
- return productTreeList().then(res => {
- productOptions.value = convertIdToValue(res);
+
+ // 鏈�鍚庡啀绛夊緟涓�娆� DOM 鏇存柊锛岀‘淇濇墍鏈夋暟鎹兘宸茶缃�
+ await nextTick();
+ }
+};
+const getProductOptions = () => {
+ return productTreeList().then(res => {
+ productOptions.value = convertIdToValue(res);
+ return res;
+ });
+};
+const getModels = value => {
+ if (value) {
+ productForm.value.productCategory =
+ findNodeById(productOptions.value, value) || "";
+ return modelList({id: value}).then(res => {
+ modelOptions.value = res;
return res;
});
- };
- const getModels = value => {
- if (value) {
- productForm.value.productCategory =
- findNodeById(productOptions.value, value) || "";
- return modelList({ id: value }).then(res => {
- modelOptions.value = res;
- return res;
- });
- } else {
- productForm.value.productCategory = "";
- modelOptions.value = [];
- return Promise.resolve([]);
- }
- };
- const getProductModel = value => {
- const index = modelOptions.value.findIndex(item => item.id === value);
- if (index !== -1) {
- productForm.value.specificationModel = modelOptions.value[index].model;
- productForm.value.unit = modelOptions.value[index].unit;
- } else {
- productForm.value.specificationModel = null;
- productForm.value.unit = null;
- }
- };
- const findNodeById = (nodes, productId) => {
- for (let i = 0; i < nodes.length; i++) {
- if (nodes[i].value === productId) {
- return nodes[i].label; // 鎵惧埌鑺傜偣锛岃繑鍥炶鑺傜偣鐨刲abel
- }
- if (nodes[i].children && nodes[i].children.length > 0) {
- const foundNode = findNodeById(nodes[i].children, productId);
- if (foundNode) {
- return foundNode; // 鍦ㄥ瓙鑺傜偣涓壘鍒帮紝鐩存帴杩斿洖锛堝凡缁忔槸label瀛楃涓诧級
- }
- }
- }
- return null; // 娌℃湁鎵惧埌鑺傜偣锛岃繑鍥瀗ull
- };
- function convertIdToValue(data) {
- return data.map(item => {
- const { id, children, ...rest } = item;
- const newItem = {
- ...rest,
- value: id, // 灏� id 鏀逛负 value
- };
- if (children && children.length > 0) {
- newItem.children = convertIdToValue(children);
- }
-
- return newItem;
- });
+ } else {
+ productForm.value.productCategory = "";
+ modelOptions.value = [];
+ return Promise.resolve([]);
}
- // 鎻愪氦浜у搧琛ㄥ崟
- const submitProduct = () => {
- proxy.$refs["productFormRef"].validate(valid => {
- if (valid) {
- if (operationType.value === "edit") {
- submitProductEdit();
- } else {
- if (productOperationType.value === "add") {
- productData.value.push({ ...productForm.value });
- console.log("productData.value---", productData.value);
- } else {
- productData.value[productOperationIndex.value] = {
- ...productForm.value,
- };
- }
- closeProductDia();
- }
- }
- });
- };
- const submitProductEdit = () => {
- productForm.value.salesLedgerId = currentId.value;
- productForm.value.type = 2;
- addOrUpdateSalesLedgerProduct(productForm.value).then(res => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeProductDia();
- getPurchaseById({ id: currentId.value, type: 2 }).then(res => {
- productData.value = res.productData;
- });
- });
- };
- // 鍒犻櫎浜у搧
- const deleteProduct = () => {
- if (productSelectedRows.value.length === 0) {
- proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
- return;
+};
+const getProductModel = value => {
+ const index = modelOptions.value.findIndex(item => item.id === value);
+ if (index !== -1) {
+ productForm.value.specificationModel = modelOptions.value[index].model;
+ productForm.value.unit = modelOptions.value[index].unit;
+ } else {
+ productForm.value.specificationModel = null;
+ productForm.value.unit = null;
+ }
+};
+const findNodeById = (nodes, productId) => {
+ for (let i = 0; i < nodes.length; i++) {
+ if (nodes[i].value === productId) {
+ return nodes[i].label; // 鎵惧埌鑺傜偣锛岃繑鍥炶鑺傜偣鐨刲abel
}
- if (operationType.value === "add") {
- productSelectedRows.value.forEach(selectedRow => {
- const index = productData.value.findIndex(
- product => product.id === selectedRow.id
- );
- if (index !== -1) {
- productData.value.splice(index, 1);
- }
- });
- } else {
- let ids = [];
- if (productSelectedRows.value.length > 0) {
- ids = productSelectedRows.value.map(item => item.id);
+ if (nodes[i].children && nodes[i].children.length > 0) {
+ const foundNode = findNodeById(nodes[i].children, productId);
+ if (foundNode) {
+ return foundNode; // 鍦ㄥ瓙鑺傜偣涓壘鍒帮紝鐩存帴杩斿洖锛堝凡缁忔槸label瀛楃涓诧級
}
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
+ }
+ }
+ return null; // 娌℃湁鎵惧埌鑺傜偣锛岃繑鍥瀗ull
+};
+
+function convertIdToValue(data) {
+ return data.map(item => {
+ const {id, children, ...rest} = item;
+ const newItem = {
+ ...rest,
+ value: id, // 灏� id 鏀逛负 value
+ };
+ if (children && children.length > 0) {
+ newItem.children = convertIdToValue(children);
+ }
+
+ return newItem;
+ });
+}
+
+// 鎻愪氦浜у搧琛ㄥ崟
+const submitProduct = () => {
+ proxy.$refs["productFormRef"].validate(valid => {
+ if (valid) {
+ if (operationType.value === "edit") {
+ submitProductEdit();
+ } else {
+ if (productOperationType.value === "add") {
+ productData.value.push({...productForm.value});
+ console.log("productData.value---", productData.value);
+ } else {
+ productData.value[productOperationIndex.value] = {
+ ...productForm.value,
+ };
+ }
+ closeProductDia();
+ }
+ }
+ });
+};
+const submitProductEdit = () => {
+ productForm.value.salesLedgerId = currentId.value;
+ productForm.value.type = 2;
+ addOrUpdateSalesLedgerProduct(productForm.value).then(res => {
+ proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+ closeProductDia();
+ getPurchaseById({id: currentId.value, type: 2}).then(res => {
+ productData.value = res.productData;
+ });
+ });
+};
+// 鍒犻櫎浜у搧
+const deleteProduct = () => {
+ if (productSelectedRows.value.length === 0) {
+ proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+ return;
+ }
+ if (operationType.value === "add") {
+ productSelectedRows.value.forEach(selectedRow => {
+ const index = productData.value.findIndex(
+ product => product.id === selectedRow.id
+ );
+ if (index !== -1) {
+ productData.value.splice(index, 1);
+ }
+ });
+ } else {
+ let ids = [];
+ if (productSelectedRows.value.length > 0) {
+ ids = productSelectedRows.value.map(item => item.id);
+ }
+ ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
.then(() => {
delProduct(ids).then(res => {
proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
closeProductDia();
- getPurchaseById({ id: currentId.value, type: 2 }).then(
- res => {
- productData.value = res.productData;
- }
+ getPurchaseById({id: currentId.value, type: 2}).then(
+ res => {
+ productData.value = res.productData;
+ }
);
});
})
.catch(() => {
proxy.$modal.msg("宸插彇娑�");
});
- }
- };
- // 鍏抽棴浜у搧寮规
- const closeProductDia = () => {
- proxy.resetForm("productFormRef");
- productFormVisible.value = false;
- };
- // 瀵煎嚭
- const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
+ }
+};
+// 鍏抽棴浜у搧寮规
+const closeProductDia = () => {
+ proxy.resetForm("productFormRef");
+ productFormVisible.value = false;
+};
+// 瀵煎嚭
+const handleOut = () => {
+ ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
.then(() => {
proxy.download("/purchase/ledger/export", {}, "閲囪喘鍙拌处.xlsx");
})
.catch(() => {
proxy.$modal.msg("宸插彇娑�");
});
- };
- // 鍒犻櫎
- const handleDelete = () => {
- let ids = [];
- if (selectedRows.value.length > 0) {
- ids = selectedRows.value.filter(item => item.salesLedgerId === null).map(item => item.id);
- } else {
- proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
- return;
- }
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
+};
+// 鍒犻櫎
+const handleDelete = () => {
+ let ids = [];
+ if (selectedRows.value.length > 0) {
+ ids = selectedRows.value.filter(item => item.salesLedgerId === null).map(item => item.id);
+ } else {
+ proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+ return;
+ }
+ ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
.then(() => {
delPurchase(ids).then(res => {
proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
@@ -1612,172 +1604,172 @@
.catch(() => {
proxy.$modal.msg("宸插彇娑�");
});
- };
- // 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
- function getCurrentDate() {
- const today = new Date();
- const year = today.getFullYear();
- const month = String(today.getMonth() + 1).padStart(2, "0"); // 鏈堜唤浠�0寮�濮�
- const day = String(today.getDate()).padStart(2, "0");
- return `${year}-${month}-${day}`;
- }
- const mathNum = () => {
- if (!productForm.value.taxRate) {
- proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
- return;
- }
- if (!productForm.value.taxInclusiveUnitPrice) {
- return;
- }
- if (!productForm.value.quantity) {
- return;
- }
- // 鍚◣鎬讳环璁$畻
- productForm.value.taxInclusiveTotalPrice =
- proxy.calculateTaxIncludeTotalPrice(
- productForm.value.taxInclusiveUnitPrice,
- productForm.value.quantity
- );
- if (productForm.value.taxRate) {
- // 涓嶅惈绋庢�讳环璁$畻
- productForm.value.taxExclusiveTotalPrice =
- proxy.calculateTaxExclusiveTotalPrice(
- productForm.value.taxInclusiveTotalPrice,
- productForm.value.taxRate
- );
- }
- };
- const reverseMathNum = field => {
- if (!productForm.value.taxRate) {
- proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
- return;
- }
- const taxRate = Number(productForm.value.taxRate);
- if (!taxRate) return;
+};
- // 纭繚杈撳叆鍊间笉涓鸿礋鏁�
- if (
+// 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
+function getCurrentDate() {
+ const today = new Date();
+ const year = today.getFullYear();
+ const month = String(today.getMonth() + 1).padStart(2, "0"); // 鏈堜唤浠�0寮�濮�
+ const day = String(today.getDate()).padStart(2, "0");
+ return `${year}-${month}-${day}`;
+}
+
+const mathNum = () => {
+ if (!productForm.value.taxRate) {
+ proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
+ return;
+ }
+ if (!productForm.value.taxInclusiveUnitPrice) {
+ return;
+ }
+ if (!productForm.value.quantity) {
+ return;
+ }
+ // 鍚◣鎬讳环璁$畻
+ productForm.value.taxInclusiveTotalPrice =
+ proxy.calculateTaxIncludeTotalPrice(
+ productForm.value.taxInclusiveUnitPrice,
+ productForm.value.quantity
+ );
+ if (productForm.value.taxRate) {
+ // 涓嶅惈绋庢�讳环璁$畻
+ productForm.value.taxExclusiveTotalPrice =
+ proxy.calculateTaxExclusiveTotalPrice(
+ productForm.value.taxInclusiveTotalPrice,
+ productForm.value.taxRate
+ );
+ }
+};
+const reverseMathNum = field => {
+ if (!productForm.value.taxRate) {
+ proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
+ return;
+ }
+ const taxRate = Number(productForm.value.taxRate);
+ if (!taxRate) return;
+
+ // 纭繚杈撳叆鍊间笉涓鸿礋鏁�
+ if (
field === "taxInclusiveTotalPrice" ||
field === "taxExclusiveTotalPrice"
- ) {
- const value = Number(productForm.value[field]);
- if (value < 0) {
- productForm.value[field] = "0";
- proxy.$modal.msgWarning("鍊间笉鑳藉皬浜�0");
- return;
- }
- }
-
- if (field === "taxInclusiveTotalPrice") {
- // 宸茬煡鍚◣鎬讳环鍜屾暟閲忥紝鍙嶇畻鍚◣鍗曚环
- if (productForm.value.quantity) {
- productForm.value.taxInclusiveUnitPrice = (
- Number(productForm.value.taxInclusiveTotalPrice) /
- Number(productForm.value.quantity)
- ).toFixed(2);
- // 纭繚缁撴灉涓嶄负璐熸暟
- if (Number(productForm.value.taxInclusiveUnitPrice) < 0) {
- productForm.value.taxInclusiveUnitPrice = "0";
- }
- }
- // 宸茬煡鍚◣鎬讳环鍜屽惈绋庡崟浠凤紝鍙嶇畻鏁伴噺
- else if (productForm.value.taxInclusiveUnitPrice) {
- productForm.value.quantity = (
- Number(productForm.value.taxInclusiveTotalPrice) /
- Number(productForm.value.taxInclusiveUnitPrice)
- ).toFixed(2);
- // 纭繚缁撴灉涓嶄负璐熸暟
- if (Number(productForm.value.quantity) < 0) {
- productForm.value.quantity = "0";
- }
- }
- // 鍙嶇畻涓嶅惈绋庢�讳环
- productForm.value.taxExclusiveTotalPrice = (
- Number(productForm.value.taxInclusiveTotalPrice) /
- (1 + taxRate / 100)
- ).toFixed(2);
- // 纭繚缁撴灉涓嶄负璐熸暟
- if (Number(productForm.value.taxExclusiveTotalPrice) < 0) {
- productForm.value.taxExclusiveTotalPrice = "0";
- }
- } else if (field === "taxExclusiveTotalPrice") {
- // 鍙嶇畻鍚◣鎬讳环
- productForm.value.taxInclusiveTotalPrice = (
- Number(productForm.value.taxExclusiveTotalPrice) *
- (1 + taxRate / 100)
- ).toFixed(2);
- // 纭繚缁撴灉涓嶄负璐熸暟
- if (Number(productForm.value.taxInclusiveTotalPrice) < 0) {
- productForm.value.taxInclusiveTotalPrice = "0";
- }
- // 宸茬煡鏁伴噺锛屽弽绠楀惈绋庡崟浠�
- if (productForm.value.quantity) {
- productForm.value.taxInclusiveUnitPrice = (
- Number(productForm.value.taxInclusiveTotalPrice) /
- Number(productForm.value.quantity)
- ).toFixed(2);
- // 纭繚缁撴灉涓嶄负璐熸暟
- if (Number(productForm.value.taxInclusiveUnitPrice) < 0) {
- productForm.value.taxInclusiveUnitPrice = "0";
- }
- }
- // 宸茬煡鍚◣鍗曚环锛屽弽绠楁暟閲�
- else if (productForm.value.taxInclusiveUnitPrice) {
- productForm.value.quantity = (
- Number(productForm.value.taxInclusiveTotalPrice) /
- Number(productForm.value.taxInclusiveUnitPrice)
- ).toFixed(2);
- // 纭繚缁撴灉涓嶄负璐熸暟
- if (Number(productForm.value.quantity) < 0) {
- productForm.value.quantity = "0";
- }
- }
- }
- };
- // 閿�鍞悎鍚岄�夋嫨鏀瑰彉鏂规硶
- const salesLedgerChange = async row => {
- console.log("row", row);
- var index = salesContractList.value.findIndex(item => item.id == row);
- console.log("index", index);
- if (index > -1) {
- await querygProductInfoByContractNo();
- }
- };
-
- const querygProductInfoByContractNo = async () => {
- const { code, data } = await getProductInfoByContractNo({
- contractNo: form.value.salesLedgerId,
- });
- if (code == 200) {
- productData.value = data;
- }
- };
-
- const fileListRef = ref(null);
- const fileListDialogVisible = ref(false);
- const downLoadFile = row => {
- if (fileListRef.value) {
- fileListRef.value.open(row.salesLedgerFiles);
- }
- };
-
- // 鑾峰彇妯℃澘淇℃伅
- const getTemplateList = async () => {
- let res = await getPurchaseTemplateList();
- if (res && res.code === 200 && Array.isArray(res.data)) {
- templateList.value = res.data;
- }
- };
-
- // 鍒犻櫎妯℃澘
- const handleDeleteTemplate = async (item) => {
- if (!item.id) {
- proxy.$modal.msgWarning("鏃犳硶鍒犻櫎璇ユā鏉�");
+ ) {
+ const value = Number(productForm.value[field]);
+ if (value < 0) {
+ productForm.value[field] = "0";
+ proxy.$modal.msgWarning("鍊间笉鑳藉皬浜�0");
return;
}
-
- try {
- await ElMessageBox.confirm(
+ }
+
+ if (field === "taxInclusiveTotalPrice") {
+ // 宸茬煡鍚◣鎬讳环鍜屾暟閲忥紝鍙嶇畻鍚◣鍗曚环
+ if (productForm.value.quantity) {
+ productForm.value.taxInclusiveUnitPrice = (
+ Number(productForm.value.taxInclusiveTotalPrice) /
+ Number(productForm.value.quantity)
+ ).toFixed(2);
+ // 纭繚缁撴灉涓嶄负璐熸暟
+ if (Number(productForm.value.taxInclusiveUnitPrice) < 0) {
+ productForm.value.taxInclusiveUnitPrice = "0";
+ }
+ }
+ // 宸茬煡鍚◣鎬讳环鍜屽惈绋庡崟浠凤紝鍙嶇畻鏁伴噺
+ else if (productForm.value.taxInclusiveUnitPrice) {
+ productForm.value.quantity = (
+ Number(productForm.value.taxInclusiveTotalPrice) /
+ Number(productForm.value.taxInclusiveUnitPrice)
+ ).toFixed(2);
+ // 纭繚缁撴灉涓嶄负璐熸暟
+ if (Number(productForm.value.quantity) < 0) {
+ productForm.value.quantity = "0";
+ }
+ }
+ // 鍙嶇畻涓嶅惈绋庢�讳环
+ productForm.value.taxExclusiveTotalPrice = (
+ Number(productForm.value.taxInclusiveTotalPrice) /
+ (1 + taxRate / 100)
+ ).toFixed(2);
+ // 纭繚缁撴灉涓嶄负璐熸暟
+ if (Number(productForm.value.taxExclusiveTotalPrice) < 0) {
+ productForm.value.taxExclusiveTotalPrice = "0";
+ }
+ } else if (field === "taxExclusiveTotalPrice") {
+ // 鍙嶇畻鍚◣鎬讳环
+ productForm.value.taxInclusiveTotalPrice = (
+ Number(productForm.value.taxExclusiveTotalPrice) *
+ (1 + taxRate / 100)
+ ).toFixed(2);
+ // 纭繚缁撴灉涓嶄负璐熸暟
+ if (Number(productForm.value.taxInclusiveTotalPrice) < 0) {
+ productForm.value.taxInclusiveTotalPrice = "0";
+ }
+ // 宸茬煡鏁伴噺锛屽弽绠楀惈绋庡崟浠�
+ if (productForm.value.quantity) {
+ productForm.value.taxInclusiveUnitPrice = (
+ Number(productForm.value.taxInclusiveTotalPrice) /
+ Number(productForm.value.quantity)
+ ).toFixed(2);
+ // 纭繚缁撴灉涓嶄负璐熸暟
+ if (Number(productForm.value.taxInclusiveUnitPrice) < 0) {
+ productForm.value.taxInclusiveUnitPrice = "0";
+ }
+ }
+ // 宸茬煡鍚◣鍗曚环锛屽弽绠楁暟閲�
+ else if (productForm.value.taxInclusiveUnitPrice) {
+ productForm.value.quantity = (
+ Number(productForm.value.taxInclusiveTotalPrice) /
+ Number(productForm.value.taxInclusiveUnitPrice)
+ ).toFixed(2);
+ // 纭繚缁撴灉涓嶄负璐熸暟
+ if (Number(productForm.value.quantity) < 0) {
+ productForm.value.quantity = "0";
+ }
+ }
+ }
+};
+// 閿�鍞悎鍚岄�夋嫨鏀瑰彉鏂规硶
+const salesLedgerChange = async row => {
+ console.log("row", row);
+ var index = salesContractList.value.findIndex(item => item.id == row);
+ console.log("index", index);
+ if (index > -1) {
+ await querygProductInfoByContractNo();
+ }
+};
+
+const querygProductInfoByContractNo = async () => {
+ const {code, data} = await getProductInfoByContractNo({
+ contractNo: form.value.salesLedgerId,
+ });
+ if (code == 200) {
+ productData.value = data;
+ }
+};
+
+// 鑾峰彇妯℃澘淇℃伅
+const getTemplateList = async () => {
+ let res = await getPurchaseTemplateList();
+ if (res && res.code === 200 && Array.isArray(res.data)) {
+ templateList.value = res.data;
+ }
+};
+
+// 鎵撳紑闄勪欢寮规
+const openFileDialog = async (row) => {
+ recordId.value = row.id
+ fileListDialogVisible.value = true
+}
+
+// 鍒犻櫎妯℃澘
+const handleDeleteTemplate = async (item) => {
+ if (!item.id) {
+ proxy.$modal.msgWarning("鏃犳硶鍒犻櫎璇ユā鏉�");
+ return;
+ }
+
+ try {
+ await ElMessageBox.confirm(
`纭畾瑕佸垹闄ゆā鏉�"${item.templateName}"鍚楋紵`,
"鍒犻櫎纭",
{
@@ -1785,118 +1777,122 @@
cancelButtonText: "鍙栨秷",
type: "warning",
}
- );
-
- const res = await delPurchaseTemplate([item.id]);
- if (res && res.code === 200) {
- ElMessage({
- message: "鍒犻櫎鎴愬姛",
- type: "success",
- });
- // 濡傛灉鍒犻櫎鐨勬槸褰撳墠閫変腑鐨勬ā鏉匡紝娓呯┖閫夋嫨
- if (templateName.value === item.templateName) {
- templateName.value = "";
- filterInputValue.value = "";
- }
- // 閲嶆柊鑾峰彇妯℃澘鍒楄〃
- await getTemplateList();
- } else {
- ElMessage({
- message: res?.msg || "鍒犻櫎澶辫触",
- type: "error",
- });
- }
- } catch (error) {
- if (error !== "cancel") {
- console.error("鍒犻櫎妯℃澘澶辫触:", error);
- ElMessage({
- message: "鍒犻櫎澶辫触锛岃绋嶅悗閲嶈瘯",
- type: "error",
- });
- }
- }
- };
+ );
- onMounted(() => {
- getList();
- getTemplateList();
- });
+ const res = await delPurchaseTemplate([item.id]);
+ if (res && res.code === 200) {
+ ElMessage({
+ message: "鍒犻櫎鎴愬姛",
+ type: "success",
+ });
+ // 濡傛灉鍒犻櫎鐨勬槸褰撳墠閫変腑鐨勬ā鏉匡紝娓呯┖閫夋嫨
+ if (templateName.value === item.templateName) {
+ templateName.value = "";
+ filterInputValue.value = "";
+ }
+ // 閲嶆柊鑾峰彇妯℃澘鍒楄〃
+ await getTemplateList();
+ } else {
+ ElMessage({
+ message: res?.msg || "鍒犻櫎澶辫触",
+ type: "error",
+ });
+ }
+ } catch (error) {
+ if (error !== "cancel") {
+ console.error("鍒犻櫎妯℃澘澶辫触:", error);
+ ElMessage({
+ message: "鍒犻櫎澶辫触锛岃绋嶅悗閲嶈瘯",
+ type: "error",
+ });
+ }
+ }
+};
+
+onMounted(() => {
+ getList();
+ getTemplateList();
+});
</script>
<style scoped lang="scss">
- .invalid-row {
- opacity: 0.6;
- background-color: #f5f7fa;
+.invalid-row {
+ opacity: 0.6;
+ background-color: #f5f7fa;
+}
+
+.el-row {
+ justify-content: space-between;
+ align-items: center;
+}
+
+.no-arrow-select {
+ --el-select-suffix-icon-color: transparent; /* 闅愯棌榛樿涓嬫媺绠ご */
+}
+
+.select-button-group {
+ display: flex;
+ align-items: center;
+}
+
+// 瀹℃壒浜鸿妭鐐瑰鍣ㄦ牱寮�
+.approver-nodes-container {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 16px;
+ padding: 16px;
+ background-color: #f8f9fa;
+ border-radius: 4px;
+ border: 1px solid #e4e7ed;
+}
+
+.approver-node-item {
+ flex: 0 0 calc(33.333% - 12px);
+ min-width: 200px;
+ padding: 12px;
+ background-color: #fff;
+ border-radius: 4px;
+ border: 1px solid #dcdfe6;
+ transition: all 0.3s;
+
+ &:hover {
+ border-color: #409eff;
+ box-shadow: 0 2px 8px rgba(64, 158, 255, 0.1);
}
- .el-row {
- justify-content: space-between;
- align-items: center;
- }
- .no-arrow-select {
- --el-select-suffix-icon-color: transparent; /* 闅愯棌榛樿涓嬫媺绠ご */
- }
- .select-button-group {
- display: flex;
- align-items: center;
- }
-
- // 瀹℃壒浜鸿妭鐐瑰鍣ㄦ牱寮�
- .approver-nodes-container {
- display: flex;
- flex-wrap: wrap;
- gap: 16px;
- padding: 16px;
- background-color: #f8f9fa;
- border-radius: 4px;
- border: 1px solid #e4e7ed;
- }
-
+}
+
+.approver-node-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 8px;
+}
+
+.approver-node-label {
+ font-size: 13px;
+ font-weight: 500;
+ color: #606266;
+}
+
+@media (max-width: 1200px) {
.approver-node-item {
- flex: 0 0 calc(33.333% - 12px);
- min-width: 200px;
- padding: 12px;
- background-color: #fff;
- border-radius: 4px;
- border: 1px solid #dcdfe6;
- transition: all 0.3s;
-
- &:hover {
- border-color: #409eff;
- box-shadow: 0 2px 8px rgba(64, 158, 255, 0.1);
- }
+ flex: 0 0 calc(50% - 8px);
}
-
- .approver-node-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 8px;
+}
+
+@media (max-width: 768px) {
+ .approver-node-item {
+ flex: 0 0 100%;
}
-
- .approver-node-label {
- font-size: 13px;
- font-weight: 500;
- color: #606266;
+}
+
+// 鍒犻櫎鍥炬爣鏍峰紡
+.delete-icon {
+ transition: all 0.3s;
+
+ &:hover {
+ color: #f56c6c !important;
+ transform: scale(1.2);
}
-
- @media (max-width: 1200px) {
- .approver-node-item {
- flex: 0 0 calc(50% - 8px);
- }
- }
-
- @media (max-width: 768px) {
- .approver-node-item {
- flex: 0 0 100%;
- }
- }
-
- // 鍒犻櫎鍥炬爣鏍峰紡
- .delete-icon {
- transition: all 0.3s;
- &:hover {
- color: #f56c6c !important;
- transform: scale(1.2);
- }
- }
+}
</style>
diff --git a/src/views/productionManagement/processRoute/index.vue b/src/views/productionManagement/processRoute/index.vue
index 4a713dc..43425c6 100644
--- a/src/views/productionManagement/processRoute/index.vue
+++ b/src/views/productionManagement/processRoute/index.vue
@@ -61,7 +61,8 @@
import EditProcess from "@/views/productionManagement/processRoute/Edit.vue";
import RouteItemForm from "@/views/productionManagement/processRoute/ItemsForm.vue";
import { listPage, del } from "@/api/productionManagement/processRoute.js";
- import FileList from "@/components/Dialog/FileList.vue";
+ const FileList = defineAsyncComponent(() => import("@/components/Dialog/FileList.vue"));
+
import { useRouter } from "vue-router";
import { ElMessage, ElMessageBox } from "element-plus";
diff --git a/src/views/productionManagement/processRoute/processRouteItem/index.vue b/src/views/productionManagement/processRoute/processRouteItem/index.vue
index fd1a6a8..6d64c30 100644
--- a/src/views/productionManagement/processRoute/processRouteItem/index.vue
+++ b/src/views/productionManagement/processRoute/processRouteItem/index.vue
@@ -68,7 +68,8 @@
style="margin-right: 10px;">
鍗$墖瑙嗗浘
</el-button>
- <el-button type="primary"
+ <el-button v-if="editable"
+ type="primary"
@click="handleAdd">鏂板</el-button>
</div>
</div>
@@ -133,12 +134,12 @@
link
size="small"
@click="handleEdit(scope.row)"
- :disabled="scope.row.isComplete">缂栬緫</el-button>
+ :disabled="scope.row.isComplete || !editable">缂栬緫</el-button>
<el-button type="danger"
link
size="small"
@click="handleDelete(scope.row)"
- :disabled="scope.row.isComplete">鍒犻櫎</el-button>
+ :disabled="scope.row.isComplete || !editable">鍒犻櫎</el-button>
</template>
</el-table-column>
</el-table>
@@ -152,7 +153,8 @@
style="margin-right: 10px;">
琛ㄦ牸瑙嗗浘
</el-button>
- <el-button type="primary"
+ <el-button v-if="editable"
+ type="primary"
@click="handleAdd">鏂板</el-button>
</div>
</div>
@@ -196,7 +198,7 @@
link
size="small"
@click="handleEdit(item)"
- :disabled="item.isComplete">缂栬緫</el-button>
+ :disabled="item.isComplete || !editable">缂栬緫</el-button>
<el-button type="info"
link
size="small"
@@ -205,7 +207,7 @@
link
size="small"
@click="handleDelete(item)"
- :disabled="item.isComplete">鍒犻櫎</el-button>
+ :disabled="item.isComplete || !editable">鍒犻櫎</el-button>
</div>
</div>
</div>
@@ -216,7 +218,7 @@
style="margin-top: 20px;">
<div class="section-title">BOM 缁撴瀯</div>
<div class="section-actions"
- v-if="pageType === 'order'">
+ v-if="pageType === 'order' && editable">
<el-button v-if="!bomDataValue.isEdit"
type="primary"
@click="bomDataValue.isEdit = true">
@@ -447,7 +449,6 @@
@confirm="handleProductSelect"
single />
<!-- 鍙傛暟鍒楄〃瀵硅瘽妗� -->
- <!-- :editable="!routeInfo.status" -->
<ProcessParamListDialog v-model="showParamListDialog"
:title="`${currentProcess ? (currentProcess.processName || currentProcess.technologyOperationName || currentProcess.operationName) : ''} - 鍙傛暟鍒楄〃`"
:route-id="routeId"
@@ -455,6 +456,7 @@
:process="currentProcess"
:page-type="pageType"
:param-list="paramList"
+ :editable="editable"
@getsyncProcessParamItem="getsyncProcessParamItem"
@refresh="refreshParamList" />
</div>
@@ -509,6 +511,7 @@
const routeId = computed(() => route.query.id);
const orderId = computed(() => route.query.orderId);
const pageType = computed(() => route.query.type);
+ const editable = computed(() => route.query.editable !== "false");
const tableLoading = ref(false);
const tableData = ref([]);
@@ -878,6 +881,7 @@
// 鍒濆鍖栨嫋鎷芥帓搴�
const initSortable = () => {
destroySortable();
+ if (!editable.value) return;
if (viewMode.value === "table") {
// 琛ㄦ牸瑙嗗浘鐨勬嫋鎷芥帓搴�
diff --git a/src/views/productionManagement/productionOrder/components/MaterialDetailDialog.vue b/src/views/productionManagement/productionOrder/components/MaterialDetailDialog.vue
index e9b2646..370815e 100644
--- a/src/views/productionManagement/productionOrder/components/MaterialDetailDialog.vue
+++ b/src/views/productionManagement/productionOrder/components/MaterialDetailDialog.vue
@@ -55,14 +55,15 @@
controls-position="right"
placeholder="杈撳叆瀹為檯鏁伴噺"
style="width: 100%;"
- :disabled="row.returned"
+ :disabled="row.returned || orderRow?.end"
@change="val => handleActualQtyChange(row, val)" />
</template>
</el-table-column>
</el-table>
<template #footer>
<span class="dialog-footer">
- <el-button type="warning"
+ <el-button v-if="!orderRow?.end"
+ type="warning"
:loading="materialReturnConfirming"
:disabled="!canOpenReturnSummary"
@click="openReturnSummaryDialog">
diff --git a/src/views/productionManagement/productionOrder/index.vue b/src/views/productionManagement/productionOrder/index.vue
index 28356dd..93fc177 100644
--- a/src/views/productionManagement/productionOrder/index.vue
+++ b/src/views/productionManagement/productionOrder/index.vue
@@ -40,6 +40,8 @@
value="3" />
<el-option label="宸插彇娑�"
value="4" />
+ <el-option label="宸茬粨鏉�"
+ value="5" />
</el-select>
</el-form-item>
<el-form-item>
@@ -65,6 +67,7 @@
:tableLoading="tableLoading"
:row-class-name="tableRowClassName"
:isSelection="true"
+ :selectable="row => !row.endOrder"
@selection-change="handleSelectionChange"
@pagination="pagination">
<template #completionStatus="{ row }">
@@ -210,6 +213,7 @@
listProcessBom,
delProductOrder,
getProductOrderSource,
+ updateProductOrder,
} from "@/api/productionManagement/productionOrder.js";
import { listMain as getOrderProcessRouteMain } from "@/api/productionManagement/productProcessRoute.js";
import MaterialLedgerDialog from "@/views/productionManagement/productionOrder/components/MaterialLedgerDialog.vue";
@@ -243,7 +247,7 @@
prop: "npsNo",
width: "150px",
},
- // 1.寰呭紑濮嬨��2.杩涜涓��3.宸插畬鎴愩��4.宸插彇娑�
+ // 1.寰呭紑濮嬨��2.杩涜涓��3.宸插畬鎴愩��4.宸插彇娑堛��5.宸茬粨鏉�
{
label: "鐘舵��",
prop: "status",
@@ -256,6 +260,8 @@
? "杩涜涓�"
: val === 3
? "宸插畬鎴�"
+ : val === 5
+ ? "宸茬粨鏉�"
: "宸插彇娑�",
formatType: val =>
val === 1
@@ -264,7 +270,9 @@
? "warning"
: val === 3
? "success"
- : "danger",
+ : val === 5
+ ? "danger"
+ : "info",
},
{
label: "浜у搧鍚嶇О",
@@ -319,7 +327,7 @@
label: "鎿嶄綔",
align: "center",
fixed: "right",
- width: 260,
+ width: 280,
operation: [
{
name: "宸ヨ壓璺嚎",
@@ -332,7 +340,7 @@
{
name: "缁戝畾宸ヨ壓璺嚎",
type: "text",
- showHide: row => !row.processRouteCode,
+ showHide: row => !row.processRouteCode && !row.endOrder,
clickFun: row => {
openBindRouteDialog(row, "add");
},
@@ -340,7 +348,7 @@
{
name: "鏇存崲宸ヨ壓璺嚎",
type: "text",
- showHide: row => row.processRouteCode,
+ showHide: row => row.processRouteCode && !row.endOrder,
clickFun: row => {
openBindRouteDialog(row, "change");
},
@@ -356,6 +364,7 @@
name: "棰嗘枡",
type: "text",
color: "#5EC7AB",
+ showHide: row => !row.endOrder,
clickFun: row => {
openMaterialDialog(row);
},
@@ -364,6 +373,7 @@
name: "琛ユ枡",
type: "text",
color: "#5EC7AB",
+ showHide: row => !row.endOrder,
clickFun: row => {
openMaterialSupplementDialog(row);
},
@@ -379,9 +389,34 @@
{
name: "鎵撳嵃棰嗘枡鍗�",
type: "text",
- color: "#409eff",
+ color: "#5EC7AB",
+ showHide: row => !row.endOrder,
clickFun: row => {
handlePrint(row);
+ },
+ },
+ {
+ name: "鐢熶骇杩芥函",
+ type: "text",
+ color: "#409eff",
+ clickFun: row => {
+ router.push({
+ path: "/productionManagement/productionTraceability",
+ query: {
+ npsNo: row.npsNo,
+ productName: row.productName,
+ model: row.model,
+ },
+ });
+ },
+ },
+ {
+ name: "缁撴潫璁㈠崟",
+ type: "text",
+ color: "red",
+ showHide: row => !row.endOrder,
+ clickFun: row => {
+ handleEndOrder(row);
},
},
],
@@ -627,6 +662,7 @@
quantity: row.quantity || 0,
orderId,
type: "order",
+ editable: !row.endOrder,
},
});
} catch (e) {
@@ -721,6 +757,26 @@
});
};
+ // 缁撴潫璁㈠崟
+ const handleEndOrder = row => {
+ ElMessageBox.confirm(`鏄惁纭缁撴潫璁㈠崟锛�${row.npsNo}锛焋, "鎻愮ず", {
+ confirmButtonText: "纭畾",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
+ .then(() => {
+ const params = {
+ id: row.id,
+ endOrder: true,
+ };
+ updateProductOrder(params).then(() => {
+ proxy.$modal.msgSuccess("缁撴潫璁㈠崟鎴愬姛");
+ getList();
+ });
+ })
+ .catch(() => {});
+ };
+
const handleConfirmRoute = () => {};
onMounted(() => {
diff --git a/src/views/productionManagement/productionTraceability/index.vue b/src/views/productionManagement/productionTraceability/index.vue
new file mode 100644
index 0000000..e2ac6df
--- /dev/null
+++ b/src/views/productionManagement/productionTraceability/index.vue
@@ -0,0 +1,831 @@
+<template>
+ <div class="app-container">
+ <el-card style="height:82vh;overflow:auto;">
+ <template #header>
+ <div class="card-header">
+ <el-form :inline="true"
+ :model="searchForm"
+ class="search-form">
+ <el-form-item label="鐢熶骇璁㈠崟鍙�">
+ <el-select v-model="selectedNpsNo"
+ filterable
+ remote
+ reserve-keyword
+ placeholder="璇疯緭鍏ョ敓浜ц鍗曞彿"
+ :loading="npsNoLoading"
+ :remote-method="handleNpsNoSearch"
+ @change="handleSearch"
+ style="width: 400px;">
+ <el-option v-for="option in npsNoOptions"
+ :key="option.id"
+ :label="option.npsNo + '-' + option.productName + '-' + option.model"
+ :value="option.id" />
+ </el-select>
+ </el-form-item>
+ <el-form-item>
+ <el-button @click="handleBack">杩斿洖</el-button>
+ </el-form-item>
+ </el-form>
+ </div>
+ </template>
+ <!-- 鍩虹淇℃伅 -->
+ <div v-if="rowData.productionOrderDto"
+ class="detail-section">
+ <h3 class="section-title">鍩虹淇℃伅</h3>
+ <el-descriptions :column="3"
+ border>
+ <el-descriptions-item label="鐢熶骇璁㈠崟鍙�">{{ rowData.productionOrderDto?.npsNo || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="浜у搧鍚嶇О">{{ rowData.productionOrderDto?.productName || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="浜у搧瑙勬牸">{{ rowData.productionOrderDto?.model || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="鐗╂枡缂栫爜">{{ rowData.productionOrderDto?.materialCode || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="璁″垝鏁伴噺">{{ rowData.productionOrderDto?.quantity || 0 }} <span class="unit">{{ rowData.productionOrderDto?.unit || '-' }}</span></el-descriptions-item>
+ <el-descriptions-item label="褰撳墠鐘舵��">
+ <el-tag :type="getStatusType(rowData.productionOrderDto?.status)">
+ {{ getStatusText(rowData.productionOrderDto?.status) }}
+ </el-tag>
+ </el-descriptions-item>
+ <el-descriptions-item label="瀹㈡埛鍚嶇О">{{ rowData.productionOrderDto?.customerName || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="寮�濮嬫棩鏈�">{{ rowData.productionOrderDto?.startTime || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="瀹屾垚杩涘害">
+ <el-progress :percentage="rowData.productionOrderDto?.completionStatus"
+ :color="customColors(rowData.productionOrderDto?.completionStatus)"
+ :status="rowData.productionOrderDto?.completionStatus === 100 ? 'success' : ''"
+ style="width: 120px;" />
+ </el-descriptions-item>
+ </el-descriptions>
+ </div>
+ <el-empty v-else
+ description="璇锋悳绱㈢敓浜ц鍗曞彿" />
+ <!-- 鐢熶骇鎶ュ伐璁板綍 -->
+ <div v-if="rowData.productionRecords && rowData.productionRecords.length > 0"
+ class="progress-container">
+ <div class="progress-section">
+ <h3 class="section-title">宸ュ崟淇℃伅</h3>
+ <div class="order-item">
+ <el-table :data="rowData.productionRecords"
+ border
+ style="width: 100%">
+ <el-table-column prop="productNo"
+ label="宸ュ崟缂栧彿"
+ align="center">
+ </el-table-column>
+ <el-table-column prop="productName"
+ label="浜у搧鍚嶇О"
+ align="center" />
+ <el-table-column prop="model"
+ label="瑙勬牸"
+ align="center" />
+ <el-table-column prop="processName"
+ label="宸ュ簭鍚嶇О"
+ align="center" />
+ <el-table-column prop="requiredQuantity"
+ label="闇�姹傛暟閲�"
+ align="center" />
+ <el-table-column prop="completedQuantity"
+ label="瀹屾垚鏁伴噺"
+ align="center" />
+ <el-table-column label="璇︽儏"
+ align="center"
+ width="200">
+ <template #default="{ row }">
+ <el-link @click="handleClickStep(row)"
+ type="primary">鎶ュ伐璁板綍</el-link>
+ <el-link @click="handleClickQuality(row)"
+ style="margin-left:20px"
+ type="primary">璐ㄦ淇℃伅</el-link>
+ </template>
+ </el-table-column>
+ </el-table>
+ </div>
+ </div>
+ </div>
+ <el-empty v-else-if="rowData.productionOrderDto"
+ description="鏆傛棤鎶ュ伐璁板綍" />
+ </el-card>
+ <!-- 鐢熶骇鎶ュ伐璇︽儏寮圭獥 -->
+ <el-dialog v-model="detailDialogVisible"
+ title="鐢熶骇鎶ュ伐璇︽儏"
+ width="1000px"
+ :close-on-click-modal="false"
+ custom-class="custom-dialog">
+ <div class="detail-container">
+ <!-- 鍩虹淇℃伅 -->
+ <div class="detail-section">
+ <h3 class="section-title">鍩虹淇℃伅</h3>
+ <el-descriptions :column="3"
+ border>
+ <el-descriptions-item label="鐢熶骇宸ュ崟鍙�">{{ detailData.npsNo || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="鐝粍">
+ <el-tag :type="detailData.schedule === '鐧界彮' ? 'primary' : 'warning'">{{ detailData.schedule || '-' }}</el-tag>
+ </el-descriptions-item>
+ <el-descriptions-item label="浜у搧缂栫爜">{{ detailData.materialCode || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="浜у搧鍚嶇О">{{ detailData.productName || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="瑙勬牸">{{ detailData.model || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="鍚堟牸鏁伴噺"><span class="num2">{{ detailData.qualifiedQuantity || 0 }}</span> <span class="unit">{{ detailData.unit || '-' }}</span></el-descriptions-item>
+ <el-descriptions-item label="涓嶅悎鏍兼暟閲�"><span class="num3">{{ detailData.unqualifiedQuantity || 0 }}</span> <span class="unit">{{ detailData.unit || '-' }}</span></el-descriptions-item>
+ <el-descriptions-item label="鎬绘暟閲�"><span class="num1">{{ detailData.quantity || 0 }}</span> <span class="unit">{{ detailData.unit || '-' }}</span></el-descriptions-item>
+ <el-descriptions-item label="寮�濮嬫椂闂�">{{ detailData.reportingTime || '-' }}</el-descriptions-item>
+ </el-descriptions>
+ </div>
+ <div class="detail-section">
+ <h3 class="section-title">鎶ュ伐鏄庣粏</h3>
+ <el-table :data="[detailData]"
+ border
+ style="width: 100%">
+ <el-table-column label="鎶ュ伐鍗曞彿"
+ prop="productNo"
+ align="center" />
+ <el-table-column label="浜у嚭鏁伴噺"
+ prop="qualifiedQuantity"
+ align="center" />
+ <el-table-column label="鎶ュ簾鏁伴噺"
+ prop="unqualifiedQuantity"
+ align="center" />
+ <el-table-column label="鍒涘缓鏃堕棿"
+ prop="reportingTime"
+ align="center" />
+ <el-table-column label="鎿嶄綔"
+ align="center"
+ width="200">
+ <template #default="{ row }">
+ <el-button type="primary"
+ link
+ @click="showInput(row.id)">鏌ョ湅鎶曞叆</el-button>
+ <el-button type="primary"
+ link
+ @click="showParamDetail(row.productionOperationParamList)">鍙傛暟璇︽儏</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+ </div>
+ </div>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button @click="detailDialogVisible = false">鍏抽棴</el-button>
+ </div>
+ </template>
+ </el-dialog>
+ <!-- 鎶曞叆妯℃�佹 -->
+ <input-modal v-if="isShowInput"
+ v-model:visible="isShowInput"
+ :production-product-main-id="isShowingId" />
+ <!-- 鍙傛暟璇︽儏寮圭獥 -->
+ <el-dialog v-model="paramDetailVisible"
+ title="鍙傛暟璇︽儏"
+ width="600px">
+ <div v-if="currentParams && currentParams.length > 0"
+ class="param-detail-list">
+ <el-descriptions :column="1"
+ border>
+ <el-descriptions-item v-for="param in currentParams"
+ :key="param.id"
+ :label="param.paramName">
+ {{ param.inputValue }}
+ <span v-if="param.unit && param.unit !== '/'"
+ class="unit-text">({{ param.unit }})</span>
+ </el-descriptions-item>
+ </el-descriptions>
+ </div>
+ <el-empty v-else
+ description="鏆傛棤鍙傛暟鏁版嵁" />
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button @click="paramDetailVisible = false">鍏抽棴</el-button>
+ </span>
+ </template>
+ </el-dialog>
+ <!-- 璐ㄦ淇℃伅寮圭獥 -->
+ <el-dialog v-model="qualityDialogVisible"
+ title="璐ㄦ璇︽儏"
+ width="1000px"
+ :close-on-click-modal="false"
+ custom-class="custom-dialog">
+ <div class="detail-container">
+ <div v-for="(record, index) in qualityRecords"
+ :key="record.id"
+ class="quality-record-block">
+ <div class="detail-section">
+ <h3 class="section-title">妫�娴嬭褰� {{ index + 1 }} - {{ record.checkTime }}</h3>
+ <el-descriptions :column="3"
+ border>
+ <el-descriptions-item label="妫�娴嬫棩鏈�">{{ record.checkTime || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="鐢熶骇宸ュ崟鍙�">{{ record.workOrderNo || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="宸ュ簭">{{ record.process || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="妫�楠屽憳">{{ record.checkName || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="浜у搧鍚嶇О">{{ record.productName || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="瑙勬牸鍨嬪彿">{{ record.model || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="鏁伴噺">{{ record.quantity || 0 }} {{ record.unit || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="妫�娴嬪崟浣�">{{ record.checkCompany || '-' }}</el-descriptions-item>
+ <el-descriptions-item label="妫�娴嬬粨鏋�">
+ <el-tag :type="record.checkResult === '鍚堟牸' ? 'success' : 'danger'">
+ {{ record.checkResult || '-' }}
+ </el-tag>
+ </el-descriptions-item>
+ </el-descriptions>
+ <h4 class="sub-section-title">妫�楠屾寚鏍囧垪琛�</h4>
+ <el-table :data="record.inspectItems"
+ border
+ style="width: 100%">
+ <el-table-column label="搴忓彿"
+ type="index"
+ width="60"
+ align="center" />
+ <el-table-column label="鎸囨爣"
+ prop="itemName"
+ align="center" />
+ <el-table-column label="鍗曚綅"
+ prop="unit"
+ align="center" />
+ <el-table-column label="鏍囧噯鍊�"
+ prop="standardValue"
+ align="center" />
+ <el-table-column label="鍐呮帶鍊�"
+ prop="controlValue"
+ align="center" />
+ <el-table-column label="瀹為檯鍊�"
+ prop="actualValue"
+ align="center" />
+ </el-table>
+ </div>
+ <!-- <div class="detail-section">
+
+ </div> -->
+ <el-divider v-if="index < qualityRecords.length - 1" />
+ </div>
+ </div>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button @click="qualityDialogVisible = false">鍏抽棴</el-button>
+ </div>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+
+<script setup>
+ import { ref, reactive, onMounted } from "vue";
+ import { useRoute, useRouter } from "vue-router";
+ import { ElMessage } from "element-plus";
+ import InputModal from "@/views/productionManagement/productionReporting/Input.vue";
+
+ const route = useRoute();
+ const router = useRouter();
+
+ // 鎼滅储鐩稿叧
+ const searchForm = reactive({
+ npsNo: "",
+ });
+ const selectedNpsNo = ref(null);
+ const npsNoLoading = ref(false);
+ const npsNoOptions = ref([
+ {
+ id: 1,
+ npsNo: "PO20240301001",
+ productName: "绮惧瘑娑插帇缂�",
+ model: "HG-100/50-500",
+ materialCode: "MAT-2024-001",
+ quantity: 500,
+ unit: "浠�",
+ status: 1,
+ customerName: "閲嶅伐鏈烘鏈夐檺鍏徃",
+ startTime: "2024-03-01",
+ completionStatus: 65,
+ },
+ {
+ id: 2,
+ npsNo: "PO20240301002",
+ productName: "宸ヤ笟浼烘湇鐢垫満",
+ model: "SV-400W-3000",
+ materialCode: "MAT-2024-002",
+ quantity: 200,
+ unit: "鍙�",
+ status: 2,
+ customerName: "鑷姩鍖栬澶囩鎶�鍏徃",
+ startTime: "2024-03-02",
+ completionStatus: 100,
+ },
+ {
+ id: 3,
+ npsNo: "PO20240301003",
+ productName: "楂樺帇瀵嗗皝鍦�",
+ model: "SR-80-5",
+ materialCode: "MAT-2024-003",
+ quantity: 5000,
+ unit: "涓�",
+ status: 0,
+ customerName: "瀵嗗皝绯荤粺閰嶄欢鍘�",
+ startTime: "2024-03-05",
+ completionStatus: 0,
+ },
+ ]);
+
+ // 璇︽儏鏁版嵁
+ const rowData = reactive({
+ productionOrderDto: null,
+ productionRecords: [],
+ });
+
+ // 鎶ュ伐璇︽儏寮圭獥
+ const detailDialogVisible = ref(false);
+ const detailData = ref({});
+
+ // 鎶曞叆妯℃�佹
+ const isShowInput = ref(false);
+ const isShowingId = ref(0);
+ const showInput = id => {
+ isShowInput.value = true;
+ isShowingId.value = id;
+ };
+
+ // 鍙傛暟璇︽儏寮圭獥
+ const paramDetailVisible = ref(false);
+ const currentParams = ref([]);
+ const showParamDetail = params => {
+ currentParams.value = params || [];
+ paramDetailVisible.value = true;
+ };
+
+ // 璐ㄦ淇℃伅寮圭獥
+ const qualityDialogVisible = ref(false);
+ const qualityRecords = ref([]);
+
+ // 鐘舵�佸鐞�
+ const getStatusType = status => {
+ const typeMap = { 0: "info", 1: "primary", 2: "success" };
+ return typeMap[status] || "info";
+ };
+ const getStatusText = status => {
+ const statusMap = { 0: "鏈紑濮�", 1: "鐢熶骇涓�", 2: "宸插畬鎴�" };
+ return statusMap[status] || "鏈煡";
+ };
+ const customColors = percentage => {
+ if (percentage < 30) return "#f56c6c";
+ if (percentage < 70) return "#e6a23c";
+ return "#67c23a";
+ };
+
+ // 妯℃嫙鎼滅储鏂规硶
+ const handleNpsNoSearch = query => {
+ if (query) {
+ npsNoLoading.value = true;
+ setTimeout(() => {
+ npsNoLoading.value = false;
+ }, 300);
+ }
+ };
+
+ const handleSearch = id => {
+ const selected = npsNoOptions.value.find(item => item.id === id);
+ if (selected) {
+ rowData.productionOrderDto = selected;
+ rowData.productionRecords = [
+ {
+ id: 1001,
+ productNo: "MO-2024-001-01",
+ productName: selected.productName,
+ model: selected.model,
+ processName: "姣涘澂鍔犲伐",
+ requiredQuantity: selected.quantity,
+ completedQuantity: Math.floor(selected.quantity * 0.4),
+ qualifiedQuantity: Math.floor(selected.quantity * 0.4) - 2,
+ unqualifiedQuantity: 2,
+ reportingTime: "2024-03-01 10:00:00",
+ schedule: "鐧界彮",
+ postName: "寮犱笁",
+ unit: selected.unit,
+ },
+ {
+ id: 1002,
+ productNo: "MO-2024-001-02",
+ productName: selected.productName,
+ model: selected.model,
+ processName: "绮惧姞宸�",
+ requiredQuantity: Math.floor(selected.quantity * 0.4),
+ completedQuantity: Math.floor(selected.quantity * 0.25),
+ qualifiedQuantity: Math.floor(selected.quantity * 0.25),
+ unqualifiedQuantity: 0,
+ reportingTime: "2024-03-01 16:00:00",
+ schedule: "鐧界彮",
+ postName: "鏉庡洓",
+ unit: selected.unit,
+ },
+ ];
+ }
+ };
+
+ const handleBack = () => {
+ router.back();
+ };
+
+ const handleClickStep = row => {
+ detailData.value = {
+ id: row.id || Math.floor(Math.random() * 1000),
+ productNo: row.productNo,
+ npsNo: rowData.productionOrderDto.npsNo,
+ schedule: row.schedule,
+ postName: row.postName,
+ materialCode: rowData.productionOrderDto.materialCode,
+ productName: row.productName,
+ model: row.model,
+ qualifiedQuantity: row.qualifiedQuantity,
+ unqualifiedQuantity: row.unqualifiedQuantity || 0,
+ quantity: row.completedQuantity,
+ unit: row.unit,
+ reportingTime: row.reportingTime,
+ productionOperationParamList: [
+ { id: 1, paramName: "涓昏酱杞��", inputValue: "2400", unit: "rpm" },
+ { id: 2, paramName: "杩涚粰閫熷害", inputValue: "120", unit: "mm/min" },
+ { id: 3, paramName: "鍒囧墛娣卞害", inputValue: "0.5", unit: "mm" },
+ { id: 4, paramName: "鍐峰嵈娑插帇鍔�", inputValue: "0.6", unit: "Mpa" },
+ ],
+ };
+ detailDialogVisible.value = true;
+ };
+
+ const handleClickQuality = row => {
+ qualityRecords.value = [
+ {
+ id: 2001,
+ checkTime: "2024-03-01 11:30:00",
+ workOrderNo: row.productNo,
+ process: row.processName,
+ checkName: "璐ㄩ噺閮�-鐜嬪缓鍥�",
+ productName: row.productName,
+ model: row.model,
+ unit: row.unit,
+ quantity: row.completedQuantity,
+ checkCompany: "鍐呴儴瀹為獙瀹�",
+ checkResult: "鍚堟牸",
+ inspectItems: [
+ {
+ id: 1,
+ itemName: "澶栧緞灏哄",
+ unit: "mm",
+ standardValue: "100.00卤0.05",
+ controlValue: "100.00卤0.03",
+ actualValue: "100.01",
+ result: "鍚堟牸",
+ },
+ {
+ id: 2,
+ itemName: "鍐呭緞灏哄",
+ unit: "mm",
+ standardValue: "50.00+0.02/-0",
+ controlValue: "50.00+0.01/-0",
+ actualValue: "50.01",
+ result: "鍚堟牸",
+ },
+ {
+ id: 3,
+ itemName: "琛ㄩ潰绮楃硻搴�",
+ unit: "Ra",
+ standardValue: "鈮�1.6",
+ controlValue: "鈮�1.2",
+ actualValue: "0.8",
+ result: "鍚堟牸",
+ },
+ ],
+ },
+ {
+ id: 2001,
+ checkTime: "2024-03-01 11:30:00",
+ workOrderNo: row.productNo,
+ process: row.processName,
+ checkName: "璐ㄩ噺閮�-鐜嬪缓鍥�",
+ productName: row.productName,
+ model: row.model,
+ unit: row.unit,
+ quantity: row.completedQuantity,
+ checkCompany: "鍐呴儴瀹為獙瀹�",
+ checkResult: "鍚堟牸",
+ inspectItems: [
+ {
+ id: 1,
+ itemName: "澶栧緞灏哄",
+ unit: "mm",
+ standardValue: "100.00卤0.05",
+ controlValue: "100.00卤0.03",
+ actualValue: "100.01",
+ result: "鍚堟牸",
+ },
+ {
+ id: 2,
+ itemName: "鍐呭緞灏哄",
+ unit: "mm",
+ standardValue: "50.00+0.02/-0",
+ controlValue: "50.00+0.01/-0",
+ actualValue: "50.01",
+ result: "鍚堟牸",
+ },
+ {
+ id: 3,
+ itemName: "琛ㄩ潰绮楃硻搴�",
+ unit: "Ra",
+ standardValue: "鈮�1.6",
+ controlValue: "鈮�1.2",
+ actualValue: "0.8",
+ result: "鍚堟牸",
+ },
+ ],
+ },
+ ];
+ qualityDialogVisible.value = true;
+ };
+
+ onMounted(() => {
+ if (route.query.npsNo) {
+ const npsNo = route.query.npsNo;
+ const found = npsNoOptions.value.find(item => item.npsNo === npsNo);
+ if (found) {
+ selectedNpsNo.value = found.id;
+ handleSearch(found.id);
+ } else {
+ // 濡傛灉娌℃壘鍒帮紝鍒涘缓涓�涓复鏃剁殑
+ const mockItem = {
+ id: Date.now(),
+ npsNo: npsNo,
+ productName: route.query.productName || "绮惧瘑娑插帇缂�",
+ model: route.query.model || "HG-100/50-500",
+ materialCode: "MAT-2024-MOCK",
+ quantity: 100,
+ unit: "浠�",
+ status: 1,
+ customerName: "妯℃嫙瀹㈡埛",
+ startTime: "2024-03-01",
+ completionStatus: 50,
+ };
+ npsNoOptions.value.push(mockItem);
+ selectedNpsNo.value = mockItem.id;
+ handleSearch(mockItem.id);
+ }
+ }
+ });
+</script>
+
+<style scoped>
+ .app-container {
+ padding: 20px;
+ background-color: #f5f7fa;
+ min-height: 100vh;
+ }
+
+ .card-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 10px;
+ }
+
+ .search-form {
+ width: 100%;
+ }
+
+ .search-form .el-form-item {
+ margin-right: 10px;
+ }
+
+ .detail-section {
+ margin-bottom: 24px;
+ background-color: #ffffff;
+ border-radius: 10px;
+ padding: 24px;
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.08);
+ transition: all 0.3s ease;
+ }
+
+ .detail-section:hover {
+ box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.12);
+ }
+
+ .section-title {
+ font-size: 16px;
+ font-weight: 600;
+ margin-bottom: 20px;
+ color: #1a1a1a;
+ border-bottom: 2px solid #409eff;
+ padding-bottom: 10px;
+ display: flex;
+ align-items: center;
+ }
+
+ .section-title::before {
+ content: "";
+ display: inline-block;
+ width: 4px;
+ height: 16px;
+ background-color: #409eff;
+ margin-right: 8px;
+ border-radius: 2px;
+ }
+
+ .sub-section-title {
+ font-size: 14px;
+ font-weight: 600;
+ margin-bottom: 16px;
+ color: #303133;
+ display: flex;
+ align-items: center;
+ }
+
+ .sub-section-title::before {
+ content: "";
+ display: inline-block;
+ width: 3px;
+ height: 12px;
+ background-color: #67c23a;
+ margin-right: 8px;
+ border-radius: 2px;
+ }
+
+ .unit {
+ font-size: 12px;
+ color: #909399;
+ margin-left: 4px;
+ }
+
+ :deep(.el-descriptions) {
+ border-radius: 8px;
+ overflow: hidden;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
+ }
+
+ :deep(.el-descriptions__row:nth-child(odd)) {
+ background-color: #f9f9f9;
+ }
+
+ :deep(.el-descriptions__label) {
+ font-weight: 500;
+ color: #606266;
+ background-color: #f5f7fa;
+ }
+
+ :deep(.el-descriptions__content) {
+ color: #303133;
+ font-weight: 500;
+ }
+
+ .progress-container {
+ display: flex;
+ gap: 24px;
+ }
+
+ .progress-section {
+ margin-bottom: 24px;
+ background-color: #ffffff;
+ border-radius: 10px;
+ padding: 24px;
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.08);
+ flex: 1;
+ transition: all 0.3s ease;
+ width: 100%;
+ }
+
+ .progress-section:hover {
+ box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.12);
+ }
+
+ .order-item {
+ margin-bottom: 20px;
+ border-radius: 8px;
+ overflow: hidden;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
+ }
+
+ :deep(.el-table) {
+ border-radius: 8px;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
+ }
+
+ :deep(.el-table th) {
+ background-color: #f5f7fa !important;
+ font-weight: 600;
+ color: #606266;
+ }
+
+ :deep(.el-progress-bar__inner) {
+ border-radius: 10px;
+ }
+
+ :deep(.el-tag) {
+ border-radius: 12px;
+ padding: 2px 10px;
+ }
+
+ /* 寮圭獥鏍峰紡 */
+ .detail-container {
+ max-height: 600px;
+ overflow-y: auto;
+ padding: 0 16px;
+ }
+
+ .process-item {
+ margin-bottom: 24px;
+ padding: 20px;
+ background-color: #ffffff;
+ border-radius: 8px;
+ border: 1px solid #ebeef5;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+ }
+
+ .process-header {
+ margin-bottom: 20px;
+ padding-bottom: 12px;
+ border-bottom: 1px solid #f0f2f5;
+ }
+
+ .process-title {
+ font-size: 15px;
+ font-weight: 600;
+ margin-bottom: 12px;
+ color: #1a1a1a;
+ display: flex;
+ align-items: center;
+ }
+
+ .process-title::before {
+ content: "";
+ display: inline-block;
+ width: 4px;
+ height: 16px;
+ background-color: #409eff;
+ margin-right: 8px;
+ border-radius: 2px;
+ }
+
+ .process-info {
+ display: flex;
+ gap: 20px;
+ font-size: 13px;
+ color: #606266;
+ }
+
+ .process-label {
+ padding: 4px 12px;
+ background-color: #ecf5ff;
+ border-radius: 4px;
+ color: #409eff;
+ font-weight: 500;
+ }
+
+ .process-details {
+ margin-bottom: 20px;
+ }
+
+ .num1 {
+ color: #1107cc;
+ font-weight: 600;
+ }
+
+ .num2 {
+ color: #0fcf25;
+ font-weight: 600;
+ }
+
+ .num3 {
+ color: #d31818;
+ font-weight: 600;
+ }
+
+ .dialog-footer {
+ text-align: center;
+ padding: 20px;
+ border-top: 1px solid #ebeef5;
+ }
+
+ .dialog-footer .el-button {
+ min-width: 100px;
+ padding: 8px 20px;
+ }
+
+ /* 鑷畾涔夊璇濇鏍峰紡 */
+ :deep(.custom-dialog) {
+ border-radius: 12px;
+ overflow: hidden;
+ }
+
+ :deep(.custom-dialog .el-dialog__header) {
+ background-color: #f5f7fa;
+ padding: 20px;
+ border-bottom: 1px solid #ebeef5;
+ }
+
+ :deep(.custom-dialog .el-dialog__title) {
+ font-size: 18px;
+ font-weight: 600;
+ color: #1a1a1a;
+ }
+
+ :deep(.custom-dialog .el-dialog__body) {
+ padding: 20px;
+ }
+
+ .unit-text {
+ margin-left: 5px;
+ color: #909399;
+ font-size: 12px;
+ }
+
+ .param-detail-list {
+ padding: 10px;
+ }
+</style>
diff --git a/src/views/productionManagement/workOrderEdit/index.vue b/src/views/productionManagement/workOrderEdit/index.vue
index fe75df3..693fea0 100644
--- a/src/views/productionManagement/workOrderEdit/index.vue
+++ b/src/views/productionManagement/workOrderEdit/index.vue
@@ -204,6 +204,11 @@
width: "140",
},
{
+ label: "鎸囧畾鎶ュ伐浜�",
+ prop: "userNames",
+ width: "180",
+ },
+ {
label: "鎿嶄綔",
width: "200",
align: "center",
diff --git a/src/views/productionManagement/workOrderManagement/index.vue b/src/views/productionManagement/workOrderManagement/index.vue
index c1b0474..dda27fc 100644
--- a/src/views/productionManagement/workOrderManagement/index.vue
+++ b/src/views/productionManagement/workOrderManagement/index.vue
@@ -244,6 +244,7 @@
@refresh="getList" />
<FileList v-if="fileDialogVisible"
v-model:visible="fileDialogVisible"
+ :editable="!currentWorkOrderRow?.endOrder"
:record-type="'production_operation_task'"
:record-id="currentWorkOrderId" />
</div>
@@ -264,8 +265,11 @@
import QRCode from "qrcode";
import { getCurrentInstance, reactive, toRefs } from "vue";
import MaterialDialog from "./components/MaterialDialog.vue";
- import FileList from "@/components/Dialog/FileList.vue";
+ const FileList = defineAsyncComponent(() => import("@/components/Dialog/FileList.vue"));
+
+ import useUserStore from "@/store/modules/user";
const { proxy } = getCurrentInstance();
+ const userStore = useUserStore();
const tableColumn = ref([
{
@@ -368,7 +372,23 @@
clickFun: row => {
showReportDialog(row);
},
- disabled: row => row.planQuantity <= 0,
+ showHide: row => !row.endOrder,
+ disabled: row => {
+ if (row.planQuantity <= 0) return true;
+ if (!row.userIds) return false;
+ try {
+ const userIds =
+ typeof row.userIds === "string"
+ ? JSON.parse(row.userIds)
+ : row.userIds;
+ if (Array.isArray(userIds)) {
+ return !userIds.some(id => String(id) === String(userStore.id));
+ }
+ return true;
+ } catch (e) {
+ return true;
+ }
+ },
},
],
},
@@ -614,9 +634,11 @@
const printTransferCard = () => {
window.print();
};
+ const currentWorkOrderRow = ref(null);
const openWorkOrderFiles = row => {
currentWorkOrderId.value = row.id;
+ currentWorkOrderRow.value = row;
fileDialogVisible.value = true;
};
@@ -801,6 +823,7 @@
};
onMounted(() => {
+ userStore.getInfo();
getList();
// 鑾峰彇鐢ㄦ埛鍒楄〃
userListNoPageByTenantId().then(res => {
diff --git a/src/views/safeProduction/dangerInvestigation/index.vue b/src/views/safeProduction/dangerInvestigation/index.vue
index 12da6da..cb09e52 100644
--- a/src/views/safeProduction/dangerInvestigation/index.vue
+++ b/src/views/safeProduction/dangerInvestigation/index.vue
@@ -415,17 +415,12 @@
</el-row>
</el-form>
</FormDialog>
- <!-- todo 闄勪欢棰勮鐩稿叧 -->
- <FileListDialog ref="fileListRef"
- v-model="fileListDialogVisible"
- :show-upload-button="true"
- :show-delete-button="true"
- :is-show-pagination="true"
- :page="filePagination"
- :upload-method="handleUpload"
- :delete-method="handleFileDelete"
- @pagination="paginationSearch"
- title="闄勪欢鍒楄〃" />
+ <FileListDialog
+ v-if="fileListDialogVisible"
+ :record-id="currentRecordId"
+ record-type="safe_hidden"
+ v-model:visible="fileListDialogVisible"/>
+
</div>
</template>
@@ -436,7 +431,6 @@
import { ElMessageBox, ElMessage } from "element-plus";
import useUserStore from "@/store/modules/user";
import { userListNoPage } from "@/api/system/user.js";
- import FileListDialog from "@/components/Dialog/FileListDialog.vue";
import FormDialog from "@/components/Dialog/FormDialog.vue";
import { getQuotationList } from "@/api/salesManagement/salesQuotation.js";
import {
@@ -445,13 +439,9 @@
safeHiddenUpdate,
safeHiddenDel,
fileListPage,
- safeHiddenFileAdd,
- safeHiddenFileDel,
} from "@/api/safeProduction/dangerInvestigation.js";
import useFormData from "@/hooks/useFormData.js";
- import request from "@/utils/request";
import dayjs from "dayjs";
- import { get } from "@vueuse/core";
const userStore = useUserStore();
const { proxy } = getCurrentInstance();
@@ -459,6 +449,7 @@
const selectedRows = ref([]);
const userList = ref([]);
const tableLoading = ref(false);
+ const currentRecordId = ref(0);
const page = reactive({
current: 1,
size: 100,
@@ -943,18 +934,8 @@
const fileListDialogVisible = ref(false);
const currentFileRow = ref(null);
const downLoadFile = row => {
- currentFileRow.value = row;
- fileListPage({
- safeHiddenId: row.id,
- current: filePagination.value.current,
- size: filePagination.value.size,
- }).then(res => {
- if (fileListRef.value) {
- fileListRef.value.open(res.data.records || []);
- console.log("res.data", res.data);
- filePagination.value.total = res.data.total || 0;
- }
- });
+ currentRecordId.value = row.id;
+ fileListDialogVisible.value = true;
};
const currentUserId = ref("");
const currentUserName = ref("");
@@ -990,147 +971,6 @@
userList.value = res.data;
});
});
- // 涓婁紶闄勪欢
- const handleUpload = async () => {
- if (!currentFileRow.value) {
- proxy.$modal.msgWarning("璇峰厛閫夋嫨鏁版嵁");
- return null;
- }
-
- return new Promise(resolve => {
- // 鍒涘缓涓�涓殣钘忕殑鏂囦欢杈撳叆鍏冪礌
- const input = document.createElement("input");
- input.type = "file";
- input.style.display = "none";
- input.onchange = async e => {
- const file = e.target.files[0];
- if (!file) {
- resolve(null);
- return;
- }
-
- try {
- // 浣跨敤 FormData 涓婁紶鏂囦欢
- const formData = new FormData();
- formData.append("file", file);
-
- const uploadRes = await request({
- url: "/file/upload",
- method: "post",
- data: formData,
- headers: {
- "Content-Type": "multipart/form-data",
- Authorization: `Bearer ${getToken()}`,
- },
- });
-
- if (uploadRes.code === 200) {
- // 淇濆瓨闄勪欢淇℃伅
- const fileData = {
- safeHiddenId: currentFileRow.value.id,
- name: uploadRes.data.originalName || file.name,
- url: uploadRes.data.tempPath || uploadRes.data.url,
- };
-
- const saveRes = await safeHiddenFileAdd(fileData);
- if (saveRes.code === 200) {
- proxy.$modal.msgSuccess("鏂囦欢涓婁紶鎴愬姛");
- // 閲嶆柊鍔犺浇鏂囦欢鍒楄〃
- const listRes = await fileListPage({
- safeHiddenId: currentFileRow.value.id,
- current: filePagination.value.current,
- size: filePagination.value.size,
- });
- if (listRes.code === 200 && fileListRef.value) {
- const fileList = (listRes.data?.records || []).map(item => ({
- name: item.name,
- url: item.url,
- id: item.id,
- ...item,
- }));
- fileListRef.value.setList(fileList);
- filePagination.value.total = listRes.data?.total || 0;
- }
- // 杩斿洖鏂版枃浠朵俊鎭�
- resolve({
- name: fileData.name,
- url: fileData.url,
- id: saveRes.data?.id,
- });
- } else {
- proxy.$modal.msgError(saveRes.msg || "鏂囦欢淇濆瓨澶辫触");
- resolve(null);
- }
- } else {
- proxy.$modal.msgError(uploadRes.msg || "鏂囦欢涓婁紶澶辫触");
- resolve(null);
- }
- } catch (error) {
- proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
- resolve(null);
- } finally {
- document.body.removeChild(input);
- }
- };
-
- document.body.appendChild(input);
- input.click();
- });
- };
- // 鍒嗛〉鏌ヨ鏂囦欢鍒楄〃
- const paginationSearch = async (page, size) => {
- filePagination.value.current = page;
- filePagination.value.size = size;
- const listRes = await fileListPage({
- safeHiddenId: currentFileRow.value.id,
- current: filePagination.value.current,
- size: filePagination.value.size,
- });
- if (listRes.code === 200) {
- const fileList = (listRes.data?.records || []).map(item => ({
- name: item.name,
- url: item.url,
- id: item.id,
- ...item,
- }));
- fileListRef.value.setList(fileList);
- filePagination.value.total = listRes.data?.total || 0;
- }
- };
- // 鍒犻櫎闄勪欢
- const handleFileDelete = async row => {
- try {
- const res = await safeHiddenFileDel([row.id]);
- if (res.code === 200) {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- // 閲嶆柊鍔犺浇鏂囦欢鍒楄〃
- if (currentFileRow.value && fileListRef.value) {
- const listRes = await fileListPage({
- safeHiddenId: currentFileRow.value.id,
- current: filePagination.value.current,
- size: filePagination.value.size,
- });
- if (listRes.code === 200) {
- const fileList = (listRes.data?.records || []).map(item => ({
- name: item.name,
- url: item.url,
- id: item.id,
- ...item,
- }));
- fileListRef.value.setList(fileList);
- filePagination.value.total = listRes.data?.total || 0;
- }
- }
- return true; // 杩斿洖 true 琛ㄧず鍒犻櫎鎴愬姛锛岀粍浠朵細鏇存柊鍒楄〃
- } else {
- proxy.$modal.msgError(res.msg || "鍒犻櫎澶辫触");
- return false;
- }
- } catch (error) {
- proxy.$modal.msgError("鍒犻櫎澶辫触");
- return false;
- }
- };
</script>
<style scoped lang="scss">
diff --git a/src/views/safeProduction/safeQualifications/index.vue b/src/views/safeProduction/safeQualifications/index.vue
index 819c6da..39111be 100644
--- a/src/views/safeProduction/safeQualifications/index.vue
+++ b/src/views/safeProduction/safeQualifications/index.vue
@@ -110,7 +110,7 @@
<el-button link
type="primary"
size="small"
- @click="downLoadFile(scope.row)">闄勪欢</el-button>
+ @click="openFileDialog(scope.row)">闄勪欢</el-button>
</template>
</el-table-column>
</el-table>
@@ -203,16 +203,7 @@
</el-form>
</FormDialog>
<!-- todo 闄勪欢棰勮鐩稿叧 -->
- <FileListDialog ref="fileListRef"
- v-model="fileListDialogVisible"
- :show-upload-button="true"
- :show-delete-button="true"
- :is-show-pagination="true"
- :page="filePagination"
- :upload-method="handleUpload"
- :delete-method="handleFileDelete"
- @pagination="paginationSearch"
- title="闄勪欢鍒楄〃" />
+ <FileList v-if="fileDialogVisible" v-model:visible="fileDialogVisible" record-type="safe_certification" :record-id="recordId" />
</div>
</template>
@@ -223,7 +214,6 @@
import { ElMessageBox, ElMessage } from "element-plus";
import useUserStore from "@/store/modules/user";
import { userListNoPage } from "@/api/system/user.js";
- import FileListDialog from "@/components/Dialog/FileListDialog.vue";
import FormDialog from "@/components/Dialog/FormDialog.vue";
import { getQuotationList } from "@/api/salesManagement/salesQuotation.js";
import {
@@ -238,7 +228,7 @@
import useFormData from "@/hooks/useFormData.js";
import request from "@/utils/request";
import dayjs from "dayjs";
-
+ const FileList = defineAsyncComponent(() => import("@/components/Dialog/FileList.vue"));
const userStore = useUserStore();
const { proxy } = getCurrentInstance();
const tableData = ref([]);
@@ -524,19 +514,17 @@
size: 10,
total: 0,
});
- const downLoadFile = row => {
- currentFileRow.value = row;
- fileListPage({
- safeCertificationId: row.id,
- current: filePagination.value.current,
- size: filePagination.value.size,
- }).then(res => {
- if (fileListRef.value) {
- fileListRef.value.open(res.data.records);
- }
- filePagination.value.total = res.data.total || 0;
- });
- };
+
+ // 鎵撳紑闄勪欢寮圭獥
+ const recordId =ref(0)
+ const fileDialogVisible = ref(false)
+
+ // 鎵撳紑闄勪欢寮规
+ const openFileDialog = async (row) => {
+ recordId.value = row.id
+ fileDialogVisible.value = true
+ }
+
const currentFactoryName = ref("");
const getCurrentFactoryName = async () => {
let res = await userStore.getInfo();
diff --git a/src/views/safeProduction/safetyTrainingAssessment/index.vue b/src/views/safeProduction/safetyTrainingAssessment/index.vue
index b595bf6..2c98308 100644
--- a/src/views/safeProduction/safetyTrainingAssessment/index.vue
+++ b/src/views/safeProduction/safetyTrainingAssessment/index.vue
@@ -239,7 +239,7 @@
<el-descriptions-item label="闄勪欢鍒楄〃:">
<el-button type="primary"
size="small"
- @click="downLoadFile(endform)">闄勪欢鍒楄〃</el-button>
+ @click="openFileDialog(endform)">闄勪欢鍒楄〃</el-button>
</el-descriptions-item>
</el-descriptions>
<!-- <el-divider style="margin: 20px 0;" /> -->
@@ -359,22 +359,12 @@
</template>
</el-dialog>
<!-- todo 闄勪欢棰勮鐩稿叧 -->
- <FileListDialog ref="fileListRef"
- v-model="fileListDialogVisible"
- :show-upload-button="true"
- :show-delete-button="true"
- :is-show-pagination="true"
- :page="filePagination"
- :upload-method="handleUpload"
- :delete-method="handleFileDelete"
- @pagination="paginationSearch"
- title="闄勪欢鍒楄〃" />
+ <FileList v-if="fileDialogVisible" v-model:visible="fileDialogVisible" record-type="safe_training" :record-id="recordId" />
</div>
</template>
<script setup>
import { Search } from "@element-plus/icons-vue";
- import FileListDialog from "@/components/Dialog/FileListDialog.vue";
import {
onMounted,
ref,
@@ -403,6 +393,7 @@
import useUserStore from "@/store/modules/user";
import dayjs from "dayjs";
const userStore = useUserStore();
+ const FileList = defineAsyncComponent(() => import("@/components/Dialog/FileList.vue"));
// 琛ㄥ崟楠岃瘉瑙勫垯
const rules = {
@@ -621,7 +612,7 @@
name: "闄勪欢",
type: "text",
clickFun: row => {
- downLoadFile(row);
+ openFileDialog(row);
},
color: "#007AFF",
},
@@ -783,27 +774,17 @@
form.value.principalMobile = selectedUser.phonenumber;
}
};
- /**
- * 涓嬭浇鏂囦欢
- *
- * @param row 涓嬭浇鏂囦欢鐨勭浉鍏充俊鎭璞�
- */
- const fileListRef = ref(null);
- const fileListDialogVisible = ref(false);
- const currentFileRow = ref(null);
- const downLoadFile = row => {
- currentFileRow.value = row;
- safeTrainingFileListPage({
- safeTrainingId: row.id,
- current: filePagination.value.current,
- size: filePagination.value.size,
- }).then(res => {
- if (fileListRef.value) {
- fileListRef.value.open(res.data.records);
- filePagination.value.total = res.data?.total || 0;
- }
- });
- };
+
+ // 鎵撳紑闄勪欢寮圭獥
+ const recordId =ref(0)
+ const fileDialogVisible = ref(false)
+
+ // 鎵撳紑闄勪欢寮规
+ const openFileDialog = async (row) => {
+ recordId.value = row.id
+ fileDialogVisible.value = true
+ }
+
// 涓婁紶闄勪欢
const handleUpload = async () => {
if (!currentFileRow.value) {
diff --git a/src/views/salesManagement/invoiceLedger/index.vue b/src/views/salesManagement/invoiceLedger/index.vue
index 3827854..444560d 100644
--- a/src/views/salesManagement/invoiceLedger/index.vue
+++ b/src/views/salesManagement/invoiceLedger/index.vue
@@ -44,7 +44,7 @@
<el-table-column fixed="right" label="鎿嶄綔" width="150" align="center">
<template #default="scope">
<el-button link type="primary" @click="openForm(scope.row)">缂栬緫</el-button>
- <el-button link type="primary" @click="downLoadFile(scope.row)">闄勪欢</el-button>
+ <el-button link type="primary" @click="openFileDialog(scope.row)">闄勪欢</el-button>
<el-button link type="primary" @click="delInvoiceLedger(scope.row)">鍒犻櫎</el-button>
</template>
</el-table-column>
@@ -134,7 +134,7 @@
</div>
</template>
</el-dialog>
- <FileListDialog ref="fileListRef" v-model="fileListDialogVisible" />
+ <FileList v-if="fileDialogVisible" v-model:visible="fileDialogVisible" record-type="invoice_registration_product" :record-id="recordId" />
</div>
</template>
@@ -155,8 +155,8 @@
import useUserStore from "@/store/modules/user.js";
import useFormData from "@/hooks/useFormData";
import dayjs from "dayjs";
-import FileListDialog from '@/components/Dialog/FileListDialog.vue';
import { getCurrentDate } from "@/utils/index.js";
+const FileList = defineAsyncComponent(() => import("@/components/Dialog/FileList.vue"));
const { proxy } = getCurrentInstance();
const tableData = ref([]);
@@ -422,17 +422,14 @@
getList();
};
-//闄勪欢鐩稿叧
-const fileListRef = ref(null)
-const fileListDialogVisible = ref(false)
-//鏌ョ湅闄勪欢
-const downLoadFile = (row) => {
- invoiceLedgerProductInfo({ id: row.id }).then((res) => {
- if (fileListRef.value) {
- fileListRef.value.open(res.data.fileList)
- fileListDialogVisible.value = true
- }
- });
+// 鎵撳紑闄勪欢寮圭獥
+const recordId =ref(0)
+const fileDialogVisible = ref(false)
+
+// 鎵撳紑闄勪欢寮规
+const openFileDialog = async (row) => {
+ recordId.value = row.id
+ fileDialogVisible.value = true
}
onMounted(() => {
diff --git a/src/views/salesManagement/salesLedger/index.vue b/src/views/salesManagement/salesLedger/index.vue
index dc648be..1235f94 100644
--- a/src/views/salesManagement/salesLedger/index.vue
+++ b/src/views/salesManagement/salesLedger/index.vue
@@ -231,7 +231,7 @@
:disabled="!scope.row.isEdit || scope.row.hasProductionRecord || !canEditLedger(scope.row)">缂栬緫</el-button>
<el-button link
type="primary"
- @click="downLoadFile(scope.row)">闄勪欢</el-button>
+ @click="openFileDialog(scope.row)">闄勪欢</el-button>
</template>
</el-table-column>
</el-table>
@@ -740,9 +740,7 @@
</FormDialog>
<!-- // todo 闄勪欢棰勮鐩稿叧 -->
<!-- 闄勪欢鍒楄〃寮圭獥 -->
- <FileListDialog ref="fileListRef"
- v-model="fileListDialogVisible"
- title="闄勪欢鍒楄〃" />
+ <FileList v-if="fileDialogVisible" v-model:visible="fileDialogVisible" record-type="sales_ledger" :record-id="recordId" />
<!-- 鎵撳嵃棰勮寮圭獥 -->
<el-dialog v-model="printPreviewVisible"
title="鎵撳嵃棰勮"
@@ -904,10 +902,8 @@
import { onMounted, ref, getCurrentInstance } from "vue";
import { addShippingInfo } from "@/api/salesManagement/deliveryLedger.js";
import { ElMessageBox, ElMessage } from "element-plus";
- import { UploadFilled, Download } from "@element-plus/icons-vue";
import useUserStore from "@/store/modules/user";
import { userListNoPage } from "@/api/system/user.js";
- import FileListDialog from "@/components/Dialog/FileListDialog.vue";
import FormDialog from "@/components/Dialog/FormDialog.vue";
import { getQuotationList } from "@/api/salesManagement/salesQuotation.js";
import {
@@ -929,6 +925,9 @@
import { useRouter, useRoute } from "vue-router";
import { listCustomerPrivatePool } from "@/api/basicData/customerFile.js";
import FileUpload from "@/components/AttachmentUpload/file/index.vue";
+
+ const FileList = defineAsyncComponent(() => import("@/components/Dialog/FileList.vue"));
+
const router = useRouter();
const route = useRoute();
const userStore = useUserStore();
@@ -2440,20 +2439,15 @@
return statusStr === "寰呭彂璐�" || statusStr === "瀹℃牳鎷掔粷";
};
- /**
- * 涓嬭浇鏂囦欢
- *
- * @param row 涓嬭浇鏂囦欢鐨勭浉鍏充俊鎭璞�
- */
- const fileListRef = ref(null);
- const fileListDialogVisible = ref(false);
- const downLoadFile = row => {
- getSalesLedgerWithProducts({ id: row.id, type: 1 }).then(res => {
- if (fileListRef.value) {
- fileListRef.value.open(res.salesLedgerFiles);
- }
- });
- };
+ // 鎵撳紑闄勪欢寮圭獥
+ const recordId =ref(0)
+ const fileDialogVisible = ref(false)
+
+ // 鎵撳紑闄勪欢寮规
+ const openFileDialog = async (row) => {
+ recordId.value = row.id
+ fileDialogVisible.value = true
+ }
// 鎵撳紑鍙戣揣寮规
const openDeliveryForm = row => {
--
Gitblit v1.9.3