From f1bcbcb10006807787247219df78e0408742604b Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期五, 22 八月 2025 10:59:09 +0800
Subject: [PATCH] 1.采购台账开发联调
---
src/pages/index.vue | 5
src/pages/procurementManagement/procurementLedger/index.vue | 342 +++++++++
src/pages.json | 21
src/api/basicData/product.js | 58 +
src/api/procurementManagement/procurementInvoiceLedger.js | 125 +++
src/api/procurementManagement/taxComparison.js | 10
src/api/basicData/customerFile.js | 52 +
src/api/procurementManagement/procurementLedger.js | 74 ++
src/api/basicData/supplierManageFile.js | 52 +
src/api/procurementManagement/paymentEntry.js | 81 ++
src/pages/procurementManagement/procurementLedger/view.vue | 287 ++++++++
src/pages/procurementManagement/procurementLedger/detail.vue | 862 ++++++++++++++++++++++++
src/api/procurementManagement/paymentLedger.js | 19
src/pages/sales/salesAccount/detail.vue | 3
src/api/procurementManagement/projectProfit.js | 10
src/api/procurementManagement/invoiceEntry.js | 69 +
16 files changed, 2,069 insertions(+), 1 deletions(-)
diff --git a/src/api/basicData/customerFile.js b/src/api/basicData/customerFile.js
new file mode 100644
index 0000000..c52b76e
--- /dev/null
+++ b/src/api/basicData/customerFile.js
@@ -0,0 +1,52 @@
+// 瀹㈡埛妗f椤甸潰鎺ュ彛
+import request from '@/utils/request'
+
+// 鍒嗛〉鏌ヨ
+export function listCustomer(query) {
+ return request({
+ url: '/basic/customer/list',
+ method: 'get',
+ params: query
+ })
+}
+// 鏌ヨ瀹㈡埛妗f璇︾粏
+export function getCustomer(id) {
+ return request({
+ url: '/basic/customer/' + id,
+ method: 'get'
+ })
+}
+// 鏂板瀹㈡埛妗f
+export function addCustomer(data) {
+ return request({
+ url: '/basic/customer/addCustomer',
+ method: 'post',
+ data: data
+ })
+}
+// 淇敼瀹㈡埛妗f
+export function updateCustomer(data) {
+ return request({
+ url: '/basic/customer/updateCustomer',
+ method: 'post',
+ data: data
+ })
+}
+// 瀵煎嚭瀹㈡埛妗f
+export function exportCustomer(query) {
+ return request({
+ url: '/basic/customer/export',
+ method: 'get',
+ params: query,
+ responseType: 'blob'
+ })
+}
+// 鍒犻櫎瀹㈡埛妗f
+export function delCustomer(ids) {
+ return request({
+ url: '/basic/customer/delCustomer',
+ method: 'delete',
+ data: ids
+ })
+}
+
diff --git a/src/api/basicData/product.js b/src/api/basicData/product.js
new file mode 100644
index 0000000..10f8fd1
--- /dev/null
+++ b/src/api/basicData/product.js
@@ -0,0 +1,58 @@
+// 浜у搧缁存姢椤甸潰鎺ュ彛
+import request from '@/utils/request'
+
+// 浜у搧鏍戞煡璇�
+export function productTreeList(query) {
+ return request({
+ url: '/basic/product/list',
+ method: 'get',
+ params: query
+ })
+}
+// 浜у搧鏍戞柊澧炰慨鏀�
+export function addOrEditProduct(query) {
+ return request({
+ url: '/basic/product/addOrEditProduct',
+ method: 'post',
+ data: query
+ })
+}
+// 瑙勬牸鍨嬪彿鏂板淇敼
+export function addOrEditProductModel(query) {
+ return request({
+ url: '/basic/product/addOrEditProductModel',
+ method: 'post',
+ data: query
+ })
+}
+// 浜у搧鏍戝垹闄�
+export function delProduct(query) {
+ return request({
+ url: '/basic/product/delProduct',
+ method: 'delete',
+ data: query
+ })
+}
+// 瑙勬牸鍨嬪彿鍒犻櫎
+export function delProductModel(query) {
+ return request({
+ url: '/basic/product/delProductModel',
+ method: 'delete',
+ data: query
+ })
+}
+// 瑙勬牸鍨嬪彿鏌ヨ
+export function modelList(query) {
+ return request({
+ url: '/basic/product/modelList',
+ method: 'get',
+ params: query
+ })
+}
+export function modelListPage(query) {
+ return request({
+ url: '/basic/product/modelListPage',
+ method: 'get',
+ params: query
+ })
+}
diff --git a/src/api/basicData/supplierManageFile.js b/src/api/basicData/supplierManageFile.js
new file mode 100644
index 0000000..3b1ab97
--- /dev/null
+++ b/src/api/basicData/supplierManageFile.js
@@ -0,0 +1,52 @@
+// 渚涘簲鍟嗘。妗堥〉闈㈡帴鍙�
+import request from '@/utils/request'
+
+// 鍒嗛〉鏌ヨ
+export function listSupplier(query) {
+ return request({
+ url: '/system/supplier/listPage',
+ method: 'get',
+ params: query
+ })
+}
+// 鏌ヨ渚涘簲鍟嗕俊鎭缁�
+export function getSupplier(id) {
+ return request({
+ url: '/system/supplier/' + id,
+ method: 'get'
+ })
+}
+// 鏂板渚涘簲鍟嗕俊鎭�
+export function addSupplier(data) {
+ return request({
+ url: '/system/supplier/add',
+ method: 'post',
+ data: data
+ })
+}
+// 淇敼渚涘簲鍟嗕俊鎭�
+export function updateSupplier(data) {
+ return request({
+ url: '/system/supplier/update',
+ method: 'post',
+ data: data
+ })
+}
+// 瀵煎嚭渚涘簲鍟嗕俊鎭�
+export function exportSupplier(query) {
+ return request({
+ url: '/system/supplier/export',
+ method: 'get',
+ params: query,
+ responseType: 'blob'
+ })
+}
+// 鍒犻櫎渚涘簲鍟嗕俊鎭�
+export function delSupplier(ids) {
+ return request({
+ url: '/system/supplier/del',
+ method: 'delete',
+ data: ids
+ })
+}
+
diff --git a/src/api/procurementManagement/invoiceEntry.js b/src/api/procurementManagement/invoiceEntry.js
new file mode 100644
index 0000000..8325aa7
--- /dev/null
+++ b/src/api/procurementManagement/invoiceEntry.js
@@ -0,0 +1,69 @@
+// 閲囪喘-鏉ョエ鐧昏鎺ュ彛
+import request from "@/utils/request";
+
+// 鏌ヨ閲囪喘鍚堝悓鍙�
+export function getProduct(query) {
+ return request({
+ url: "/purchase/ledger/getProduct",
+ method: "get",
+ params: query,
+ });
+}
+
+// 鏌ヨid閲囪喘鍚堝悓鍙�
+export function getPurchaseNoById(query) {
+ return request({
+ url: "/purchase/ledger/getPurchaseNoById",
+ method: "get",
+ params: query,
+ });
+}
+// 鏍规嵁閲囪喘鍚堝悓鍙锋煡璇㈣缁嗕俊鎭�
+export function getInfo(query) {
+ return request({
+ url: "/purchase/ledger/getInfo",
+ method: "get",
+ params: query,
+ });
+}
+// 涓诲垪琛ㄦ煡璇�
+export function gePurchaseList(query) {
+ return request({
+ url: "/purchase/ledger/list",
+ method: "get",
+ params: query,
+ });
+}
+// 涓诲垪琛ㄦ煡璇�
+export function getRegistrationById(query) {
+ return request({
+ url: "/purchase/registration/getRegistrationById",
+ method: "get",
+ params: query,
+ });
+}
+// 鏂板缂栬緫鏉ョエ鐧昏
+export function addOrUpdateRegistration(query) {
+ return request({
+ url: "/purchase/registration/addOrUpdateRegistration",
+ method: "post",
+ data: query,
+ });
+}
+// 鍒犻櫎鏉ョエ鐧昏
+export function delRegistration(query) {
+ return request({
+ url: "/purchase/registration/delRegistration",
+ method: "delete",
+ data: query,
+ });
+}
+
+// 涓诲垪琛ㄦ煡璇�
+export function gePurchaseListPage(query) {
+ return request({
+ url: "/purchase/ledger/listPage",
+ method: "get",
+ params: query,
+ });
+}
diff --git a/src/api/procurementManagement/paymentEntry.js b/src/api/procurementManagement/paymentEntry.js
new file mode 100644
index 0000000..6ef0eb9
--- /dev/null
+++ b/src/api/procurementManagement/paymentEntry.js
@@ -0,0 +1,81 @@
+// 閲囪喘浠樻鐧昏椤甸潰鎺ュ彛
+import request from "@/utils/request";
+
+// 鍒嗛〉鏌ヨ
+export function registrationList(query) {
+ return request({
+ url: "/purchase/paymentRegistration/list",
+ method: "get",
+ params: query,
+ });
+}
+// 鏌ヨ璇︽儏
+export function registrationInfo(query) {
+ return request({
+ url: "/purchase/paymentRegistration/" + query,
+ method: "get",
+ });
+}
+// 鏍规嵁閲囪喘鍚堝悓鍙锋煡璇㈣鎯�
+export function byPurchaseId(query) {
+ return request({
+ url: "/purchase/paymentRegistration/byPurchaseId/" + query,
+ method: "get",
+ });
+}
+// 鏌ヨ閲囪喘鍚堝悓鍙�
+export function getPurchaseNo() {
+ return request({
+ url: "/purchase/ledger/getPurchaseNo",
+ method: "get",
+ });
+}
+// 鏂板
+export function paymentRegistrationAdd(query) {
+ return request({
+ url: "/purchase/paymentRegistration",
+ method: "post",
+ data: query,
+ });
+}
+// 淇敼
+export function paymentRegistrationEdit(query) {
+ return request({
+ url: "/purchase/paymentRegistration",
+ method: "put",
+ data: query,
+ });
+}
+// 鍒犻櫎
+export function paymentRegistrationDel(query) {
+ return request({
+ url: "/purchase/paymentRegistration/delete",
+ method: "delete",
+ data: query,
+ });
+}
+// 鑾峰彇鍙戠エ鍙峰拰鍙戠エ閲戦
+export function getTicketNo(query) {
+ return request({
+ url: "/purchase/registration/getTicketNo",
+ method: "get",
+ params: query,
+ });
+}
+// 鍒嗛〉鏌ヨ
+export function paymentHistoryList(query) {
+ return request({
+ url: "/purchase/paymentRegistration/paymentHistoryList",
+ method: "get",
+ params: query,
+ });
+}
+
+// 鍒嗛〉鏌ヨ
+export function paymentHistoryListPage(query) {
+ return request({
+ url: "/purchase/paymentRegistration/paymentHistoryListPage",
+ method: "get",
+ params: query,
+ });
+}
diff --git a/src/api/procurementManagement/paymentLedger.js b/src/api/procurementManagement/paymentLedger.js
new file mode 100644
index 0000000..3e20b78
--- /dev/null
+++ b/src/api/procurementManagement/paymentLedger.js
@@ -0,0 +1,19 @@
+// 閲囪喘鍙拌处椤甸潰鎺ュ彛
+import request from "@/utils/request";
+
+// 鍒嗛〉鏌ヨ
+export function paymentLedgerList(query) {
+ return request({
+ url: "/purchase/paymentRegistration/paymentLedgerList",
+ method: "get",
+ params: query,
+ });
+}
+
+// 鍒嗛〉鏌ヨ
+export function paymentRecordList(supplierId) {
+ return request({
+ url: "/purchase/paymentRegistration/getPaymentRecordList/" + supplierId,
+ method: "get",
+ });
+}
diff --git a/src/api/procurementManagement/procurementInvoiceLedger.js b/src/api/procurementManagement/procurementInvoiceLedger.js
new file mode 100644
index 0000000..76f8410
--- /dev/null
+++ b/src/api/procurementManagement/procurementInvoiceLedger.js
@@ -0,0 +1,125 @@
+// 閲囪喘-鏉ョエ鍙拌处鎺ュ彛
+import request from "@/utils/request";
+
+// 鏌ヨ鍒楄〃
+export function invoiceList(query) {
+ return request({
+ url: "/purchase/registration/list",
+ method: "get",
+ params: query,
+ });
+}
+// 鏌ヨ璇︽儏
+// export function getInvoiceById(query) {
+// return request({
+// url: "/purchase/registration/getRegistrationById",
+// method: "get",
+// params: query,
+// });
+// }
+// 鏂板銆佺紪杈�
+export function addOrUpdateInvoice(query) {
+ return request({
+ url: "/purchase/invoice/addOrUpdateInvoice",
+ method: "post",
+ data: query,
+ });
+}
+// 鍒犻櫎
+export function delInvoice(query) {
+ return request({
+ url: "/purchase/invoice/delInvoice",
+ method: "delete",
+ data: query,
+ });
+}
+// 鍒犻櫎鏉ョエ鍙拌处
+export function delRegistration(query) {
+ return request({
+ url: "/purchase/registration/delRegistration",
+ method: "delete",
+ data: query,
+ });
+}
+// 鍒犻櫎闄勪欢
+export function delCommonFile(query) {
+ return request({
+ url: "/commonFile/delCommonFile",
+ method: "delete",
+ data: query,
+ });
+}
+// 瀛愯〃鏍兼煡璇�
+export function productRecordList(query) {
+ return request({
+ url: "/purchase/registration/productRecordList",
+ method: "get",
+ params: query,
+ });
+}
+
+// 鏌ヨ鍒楄〃
+export function invoiceListPage(query) {
+ return request({
+ url: "/purchase/registration/listPage",
+ method: "get",
+ params: query,
+ });
+}
+
+export function productRecordPage(query) {
+ return request({
+ url: "/purchase/registration/productRecordPage",
+ method: "get",
+ params: query,
+ });
+}
+
+export function productUploadFile(data) {
+ return request({
+ url: "/file/uploadFile",
+ method: "post",
+ data: data,
+ });
+}
+
+export function getProductRecordById(params) {
+ return request({
+ url: "/purchase/registration/getProductRecordById",
+ method: "get",
+ params: params,
+ });
+}
+
+export function updateRegistration(data) {
+ return request({
+ url: "/purchase/registration/updateRegistration",
+ method: "post",
+ data: data,
+ });
+}
+
+// 鏌ヨ浠樻鐧昏瀛愬垪琛�
+export function registrationListPageGetById(query) {
+ return request({
+ url: "/purchase/registration/getById",
+ method: "get",
+ params: query,
+ });
+}
+// 淇敼浠樻娴佹按
+export function updatePaymentRegistration(query) {
+ return request({
+ url: "/purchase/registration/updatePaymentRegistration",
+ method: "put",
+ data: query,
+ });
+}
+// 鍒犻櫎浠樻娴佹按
+export function delPaymentRegistration(query) {
+ return request({
+ url: "/purchase/registration/delPaymentRegistration",
+ method: "delete",
+ data: query,
+ });
+}
diff --git a/src/api/procurementManagement/procurementLedger.js b/src/api/procurementManagement/procurementLedger.js
new file mode 100644
index 0000000..9fb284e
--- /dev/null
+++ b/src/api/procurementManagement/procurementLedger.js
@@ -0,0 +1,74 @@
+// 閲囪喘鍙拌处椤甸潰鎺ュ彛
+import request from "@/utils/request";
+
+// 鍒嗛〉鏌ヨ
+export function purchaseList(query) {
+ return request({
+ url: "/purchase/ledger/list",
+ method: "get",
+ params: query,
+ });
+}
+// 鏌ヨ鍚堝悓鍙�
+export function getSalesNo(query) {
+ return request({
+ url: "/purchase/ledger/getSalesNo",
+ method: "get",
+ params: query,
+ });
+}
+// 瀛愯〃鏍兼煡璇�
+export function productList(query) {
+ return request({
+ url: "/sales/product/list",
+ method: "get",
+ params: query,
+ });
+}
+// 鏂板銆佺紪杈�
+export function addOrEditPurchase(query) {
+ return request({
+ url: "/purchase/ledger/addOrEditPurchase",
+ method: "post",
+ data: query,
+ });
+}
+// 鍒犻櫎
+export function delPurchase(query) {
+ return request({
+ url: "/purchase/ledger/delPurchase",
+ method: "delete",
+ data: query,
+ });
+}
+// 鏌ヨ璇︽儏
+export function getPurchaseById(query) {
+ return request({
+ url: "/purchase/ledger/getPurchaseById",
+ method: "get",
+ params: query,
+ });
+}
+// 鏌ヨ璇︽儏
+export function getOptions(query) {
+ return request({
+ url: "/system/supplier/getOptions",
+ method: "get",
+ params: query,
+ });
+}
+
+export function purchaseListPage(query) {
+ return request({
+ url: "/purchase/ledger/listPage",
+ method: "get",
+ params: query,
+ });
+}
+
+export function createPurchaseNo() {
+ return request({
+ url: "/purchase/ledger/createPurchaseNo",
+ method: "get",
+ });
+}
diff --git a/src/api/procurementManagement/projectProfit.js b/src/api/procurementManagement/projectProfit.js
new file mode 100644
index 0000000..7fb1660
--- /dev/null
+++ b/src/api/procurementManagement/projectProfit.js
@@ -0,0 +1,10 @@
+import request from "@/utils/request";
+
+// 鍒嗛〉鏌ヨ
+export function getPurchaseList(query) {
+ return request({
+ url: "/purchase/report/list",
+ method: "get",
+ params: query,
+ });
+}
diff --git a/src/api/procurementManagement/taxComparison.js b/src/api/procurementManagement/taxComparison.js
new file mode 100644
index 0000000..726a27f
--- /dev/null
+++ b/src/api/procurementManagement/taxComparison.js
@@ -0,0 +1,10 @@
+import request from "@/utils/request";
+
+// 鍒嗛〉鏌ヨ
+export function getTaxList(query) {
+ return request({
+ url: "/purchase/report/listVat",
+ method: "get",
+ params: query,
+ });
+}
diff --git a/src/pages.json b/src/pages.json
index 4ef84cf..867ffb0 100644
--- a/src/pages.json
+++ b/src/pages.json
@@ -141,6 +141,27 @@
}
},
{
+ "path": "pages/procurementManagement/procurementLedger/index",
+ "style": {
+ "navigationBarTitleText": "閲囪喘鍙拌处",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/procurementManagement/procurementLedger/detail",
+ "style": {
+ "navigationBarTitleText": "淇敼鍙拌处",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/procurementManagement/procurementLedger/view",
+ "style": {
+ "navigationBarTitleText": "鍙拌处璇︽儏",
+ "navigationStyle": "custom"
+ }
+ },
+ {
"path": "pages/common/webview/index",
"style": {
"navigationBarTitleText": "娴忚缃戦〉"
diff --git a/src/pages/index.vue b/src/pages/index.vue
index 42b2cbe..9578b19 100644
--- a/src/pages/index.vue
+++ b/src/pages/index.vue
@@ -318,6 +318,11 @@
url: '/pages/sales/receiptPaymentLedger/index'
});
break;
+ case '閲囪喘鍙拌处':
+ uni.navigateTo({
+ url: '/pages/procurementManagement/procurementLedger/index'
+ });
+ break;
case '鍗忓悓瀹℃壒':
uni.navigateTo({
url: '/pages/cooperativeOffice/collaborativeApproval/index'
diff --git a/src/pages/procurementManagement/procurementLedger/detail.vue b/src/pages/procurementManagement/procurementLedger/detail.vue
new file mode 100644
index 0000000..52aa35c
--- /dev/null
+++ b/src/pages/procurementManagement/procurementLedger/detail.vue
@@ -0,0 +1,862 @@
+<template>
+ <view class="account-detail">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader title="鍙拌处璇︽儏" @back="goBack" />
+
+ <!-- 琛ㄥ崟鍖哄煙 -->
+ <van-form @submit="onSubmit" label-width="110px" input-align="right" style="margin-top: 10px" error-message-align="right" scroll-to-error scroll-to-error-position="center">
+ <van-field label="閲囪喘鍚堝悓鍙�" name="purchaseContractNumber" borderBottom="true" v-model="form.purchaseContractNumber" placeholder="鑷姩鐢熸垚" :rules="[{ required: true, message: '璇疯緭鍏�' }]">
+ </van-field>
+ <van-field
+ v-model="form.salesContractNo"
+ is-link
+ readonly
+ name="salesContractNo"
+ label="閿�鍞悎鍚屽彿"
+ required
+ placeholder="鐐瑰嚮閫夋嫨閿�鍞悎鍚屽彿"
+ :rules="[{ required: true, message: '璇烽�夋嫨閿�鍞悎鍚屽彿' }]"
+ @click="showPicker = true"
+ />
+ <van-field
+ v-model="form.supplierName"
+ is-link
+ readonly
+ required
+ name="supplierName"
+ label="渚涘簲鍟嗗悕绉�"
+ placeholder="鐐瑰嚮閫夋嫨渚涘簲鍟�"
+ :rules="[{ required: true, message: '璇烽�夋嫨渚涘簲鍟�' }]"
+ @click="showCustomerPicker = true"
+ />
+ <van-field label="椤圭洰鍚嶇О" name="projectName" borderBottom="true" v-model="form.projectName" placeholder="璇疯緭鍏ラ」鐩悕绉�" :rules="[{ required: true, message: '椤圭洰鍚嶇О涓嶈兘涓虹┖' }]" required>
+ </van-field>
+ <van-field label="浠樻鏂瑰紡" name="paymentMethod" borderBottom="true" v-model="form.paymentMethod" placeholder="璇疯緭鍏ヤ粯娆炬柟寮�">
+ </van-field>
+ <van-field label="褰曞叆浜�" name="recorderName" borderBottom="true" v-model="form.recorderName" placeholder="璇疯緭鍏�" disabled>
+ </van-field>
+ <van-field label="褰曞叆鏃ユ湡" name="entryDate" borderBottom="true" v-model="form.entryDate" placeholder="璇疯緭鍏�" disabled>
+ </van-field>
+ <van-popup v-model:show="showPicker" destroy-on-close position="bottom">
+ <van-picker
+ :columns="salesContractList"
+ v-model="pickerValue"
+ @confirm="onConfirm"
+ @cancel="showPicker = false"
+ />
+ </van-popup>
+ <van-popup v-model:show="showCustomerPicker" destroy-on-close position="bottom">
+ <van-picker
+ :columns="supplierList"
+ v-model="pickerCustomerValue"
+ @confirm="onCustomerConfirm"
+ @cancel="showCustomerPicker = false"
+ />
+ </van-popup>
+
+ <!-- 浜у搧澶х被閫夋嫨鍣� -->
+ <van-popup v-model:show="showCategoryPicker" destroy-on-close position="bottom">
+ <!-- 澶撮儴鎸夐挳鍖哄煙 -->
+ <view class="popup-header">
+ <view @click="showCategoryPicker = false" class="cancelButton">鍙栨秷</view>
+ <view @click="confirmCategorySelection" class="confirmButton">纭畾</view>
+ </view>
+ <up-tree
+ :data="productOptions"
+ :props="defaultProps"
+ show-checkbox
+ default-expand-all
+ check-strictly
+ @check-change="onCategoryConfirm"
+ />
+ </van-popup>
+
+ <!-- 瑙勬牸鍨嬪彿閫夋嫨鍣� -->
+ <van-popup v-model:show="showSpecificationPicker" destroy-on-close position="bottom">
+ <van-picker
+ :columns="modelOptions"
+ v-model="pickerSpecificationValue"
+ @confirm="onSpecificationConfirm"
+ @cancel="showSpecificationPicker = false"
+ />
+ </van-popup>
+
+ <!-- 绋庣巼閫夋嫨鍣� -->
+ <van-popup v-model:show="showTaxRatePicker" destroy-on-close position="bottom">
+ <van-picker
+ :columns="taxRateOptions"
+ v-model="pickerTaxRateValue"
+ @confirm="onTaxRateConfirm"
+ @cancel="showTaxRatePicker = false"
+ />
+ </van-popup>
+
+ <!-- 鍙戠エ绫诲瀷閫夋嫨鍣� -->
+ <van-popup v-model:show="showInvoiceTypePicker" destroy-on-close position="bottom">
+ <van-picker
+ :columns="invoiceTypeOptions"
+ v-model="pickerInvoiceTypeValue"
+ @confirm="onInvoiceTypeConfirm"
+ @cancel="showInvoiceTypePicker = false"
+ />
+ </van-popup>
+ <!-- 浜у搧淇℃伅 -->
+ <view class="product-section">
+ <view class="section-header">
+ <text class="section-title">浜у搧淇℃伅</text>
+ <van-button type="primary" size="small" @click="addProduct" class="add-btn" icon="plus" v-if="operationType !== 'view'">鏂板</van-button>
+ </view>
+ <view class="product-card" v-for="(product, idx) in productData" :key="idx">
+ <!-- 浜у搧绫� -->
+ <view class="product-header">
+ <view class="product-title">
+ <van-icon name="description" color="#2979ff" size="15" />
+ <text class="product-productCategory">浜у搧 {{ idx + 1 }}</text>
+ </view>
+ <!-- 鎿嶄綔鎸夐挳 -->
+ <view class="product-actions" v-if="operationType !== 'view'">
+ <van-button type="danger" size="mini" @click="removeProduct(idx)" class="del-btn" icon="delete">鍒犻櫎</van-button>
+ </view>
+ </view>
+
+ <!-- 浜у搧淇℃伅琛ㄥ崟 -->
+ <view class="product-form">
+ <!-- 浜у搧澶х被 -->
+ <van-field
+ v-model="product.productCategory"
+ is-link
+ readonly
+ name="productCategory"
+ label="浜у搧澶х被"
+ required
+ placeholder="璇烽�夋嫨"
+ :rules="[{ required: true, message: '璇烽�夋嫨' }]"
+ @click="openCategoryPicker(idx)"
+ />
+
+ <!-- 瑙勬牸鍨嬪彿 -->
+ <van-field
+ v-model="product.specificationModel"
+ is-link
+ readonly
+ name="specificationModel"
+ label="瑙勬牸鍨嬪彿"
+ required
+ :rules="[{ required: true, message: '璇烽�夋嫨' }]"
+ placeholder="璇烽�夋嫨"
+ @click="openSpecificationPicker(idx)"
+ />
+
+ <!-- 鍗曚綅 -->
+ <van-field
+ v-model="product.unit"
+ name="unit"
+ label="鍗曚綅"
+ required
+ :rules="[{ required: true, message: '璇疯緭鍏�' }]"
+ placeholder="璇疯緭鍏�"
+ />
+
+ <!-- 绋庣巼 -->
+ <van-field
+ v-model="product.taxRate"
+ is-link
+ readonly
+ name="taxRate"
+ label="绋庣巼(%)"
+ required
+ :rules="[{ required: true, message: '璇烽�夋嫨' }]"
+ placeholder="璇烽�夋嫨"
+ @click="openTaxRatePicker(idx)"
+ />
+
+ <!-- 鍚◣鍗曚环 -->
+ <van-field
+ v-model="product.taxInclusiveUnitPrice"
+ name="taxInclusiveUnitPrice"
+ label="鍚◣鍗曚环(鍏�)"
+ type="number"
+ required
+ :rules="[{ required: true, message: '璇疯緭鍏�' }]"
+ placeholder="璇疯緭鍏�"
+ @blur="formatTaxPrice(idx)"
+ />
+
+ <!-- 鏁伴噺 -->
+ <van-field
+ v-model="product.quantity"
+ name="quantity"
+ label="鏁伴噺"
+ type="number"
+ :rules="[{ required: true, message: '璇疯緭鍏�' }]"
+ required
+ placeholder="璇疯緭鍏�"
+ @blur="formatAmount(idx)"
+ />
+
+ <!-- 鍚◣鎬讳环 -->
+ <van-field
+ v-model="product.taxInclusiveTotalPrice"
+ name="taxInclusiveTotalPrice"
+ label="鍚◣鎬讳环(鍏�)"
+ type="number"
+ :rules="[{ required: true, message: '璇疯緭鍏�' }]"
+ required
+ placeholder="璇疯緭鍏�"
+ @blur="formatTaxTotal(idx)"
+ />
+
+ <!-- 涓嶅惈绋庢�讳环 -->
+ <van-field
+ v-model="product.taxExclusiveTotalPrice"
+ name="taxExclusiveTotalPrice"
+ label="涓嶅惈绋庢�讳环(鍏�)"
+ type="number"
+ required
+ :rules="[{ required: true, message: '璇疯緭鍏�' }]"
+ placeholder="璇疯緭鍏�"
+ @blur="formatNoTaxTotal(idx)"
+ />
+
+ <!-- 鍙戠エ绫诲瀷 -->
+ <van-field
+ v-model="product.invoiceType"
+ is-link
+ readonly
+ name="invoiceType"
+ label="鍙戠エ绫诲瀷"
+ :rules="[{ required: true, message: '璇烽�夋嫨' }]"
+ required
+ placeholder="璇烽�夋嫨"
+ @click="openInvoiceTypePicker(idx)"
+ />
+ </view>
+ </view>
+ </view>
+ <view class="footer-btns" v-if="operationType !== 'view'">
+ <van-button class="cancel-btn" @click="goBack">鍙栨秷</van-button>
+ <van-button class="save-btn" native-type="submit" form-type="submit">淇濆瓨</van-button>
+ </view>
+ </van-form>
+ </view>
+</template>
+
+<script setup>
+import {onMounted, ref} from 'vue';
+import { modelList, productTreeList } from "@/api/basicData/product.js";
+import useUserStore from "@/store/modules/user";
+import {calculateTaxExclusiveTotalPrice} from "@/utils/summarizeTable";
+import {
+ addOrEditPurchase, createPurchaseNo,
+ getOptions,
+ getPurchaseById,
+ getSalesNo
+} from "@/api/procurementManagement/procurementLedger";
+
+// 鑾峰彇椤甸潰鍙傛暟
+const operationType = ref('');
+const editData = ref(null);
+
+const userStore = useUserStore()
+const form = ref({
+ id: '',
+ salesContractNo: '',
+ purchaseContractNumber: '',
+ supplierId: '',
+ supplierName: '',
+ projectName: '',
+ paymentMethod: '',
+ recorderId: '',
+ recorderName: '',
+ entryDate: '',
+});
+const pickerValue = ref(['']);
+const pickerDateValue = ref([]);
+const showPicker = ref(false);
+const pickerCustomerValue = ref(['']);
+const showCustomerPicker = ref(false);
+const salesContractList = ref([]);
+const supplierList = ref([]);
+const productData = ref([]);
+
+// 閫夋嫨鍣ㄧ浉鍏冲彉閲�
+const showCategoryPicker = ref(false);
+const showSpecificationPicker = ref(false);
+const showTaxRatePicker = ref(false);
+const showInvoiceTypePicker = ref(false);
+const pickerSpecificationValue = ref(['']);
+const pickerTaxRateValue = ref(['']);
+const pickerInvoiceTypeValue = ref(['']);
+const currentProductIndex = ref(0);
+
+// 閫夐」鏁版嵁
+const productOptions = ref([]);
+const selectedCategoryNode = ref(null);
+const defaultProps = ref({
+ children: 'children',
+ label: 'label',
+ nodeKey: 'id'
+});
+
+const modelOptions = ref([]);
+// 闃叉寰幆璁$畻鐨勬爣蹇�
+const taxRateOptions = ref([
+ { text: '1', value: '1' },
+ { text: '6', value: '6' },
+ { text: '13', value: '13' },
+]);
+
+const invoiceTypeOptions = ref([
+ { text: '澧炴櫘绁�', value: '澧炴櫘绁�' },
+ { text: '澧炰笓绁�', value: '澧炰笓绁�' },
+]);
+
+const addProduct = () => {
+ if (productData.value === null) {
+ productData.value = []
+ }
+ productData.value.push({
+ productCategory: '',
+ specificationModel: '',
+ productModelId: '',
+ unit: '',
+ taxRate: '',
+ taxInclusiveUnitPrice: '',
+ quantity: '',
+ taxInclusiveTotalPrice: '',
+ taxExclusiveTotalPrice: '',
+ invoiceType: ''
+ });
+};
+const onConfirm = ({ selectedValues, selectedOptions }) => {
+ form.value.salesContractNo = selectedOptions[0]?.text;
+ form.value.salesLedgerId = selectedOptions[0]?.value;
+ pickerValue.value = [selectedValues[0]];
+ showPicker.value = false;
+};
+const onCustomerConfirm = ({ selectedValues, selectedOptions }) => {
+ form.value.supplierName = selectedOptions[0]?.text;
+ form.value.supplierId = selectedOptions[0]?.value;
+ pickerCustomerValue.value = [selectedValues[0]];
+ showCustomerPicker.value = false;
+};
+const removeProduct = (idx) => {
+ productData.value.splice(idx, 1);
+};
+
+// 鏄剧ず閫夋嫨鍣�
+const openCategoryPicker = (idx) => {
+ currentProductIndex.value = idx;
+ showCategoryPicker.value = true;
+};
+
+const openSpecificationPicker = (idx) => {
+ currentProductIndex.value = idx;
+ showSpecificationPicker.value = true;
+};
+
+const openTaxRatePicker = (idx) => {
+ currentProductIndex.value = idx;
+ showTaxRatePicker.value = true;
+};
+
+const openInvoiceTypePicker = (idx) => {
+ currentProductIndex.value = idx;
+ showInvoiceTypePicker.value = true;
+};
+
+// 閫夋嫨鍣ㄧ‘璁や簨浠�
+const onCategoryConfirm = (node) => {
+ // 鑾峰彇閫変腑鐨勮妭鐐逛俊鎭�
+ console.log('selected node---', node);
+ // 瀛樺偍閫変腑鐨勮妭鐐癸紝鐢ㄤ簬纭鏃惰幏鍙栨暟鎹�
+ selectedCategoryNode.value = node;
+};
+
+// 纭浜у搧澶х被閫夋嫨
+const confirmCategorySelection = () => {
+ if (selectedCategoryNode.value) {
+ // 璁剧疆閫変腑鐨勪骇鍝佸ぇ绫�
+ productData.value[currentProductIndex.value].productCategory = selectedCategoryNode.value.label;
+ const id = selectedCategoryNode.value.id
+ // 閲嶇疆閫変腑鐨勮妭鐐�
+ selectedCategoryNode.value = null;
+ productData.value[currentProductIndex.value].specificationModel = ''
+ productData.value[currentProductIndex.value].productModelId = ''
+ productData.value[currentProductIndex.value].pickerSpecificationValue = ['']
+ getModels(id)
+ }
+ showCategoryPicker.value = false;
+};
+// 鑾峰彇瑙勬牸鍨嬪彿
+const getModels = (value) => {
+ modelList({ id: value }).then((res) => {
+ modelOptions.value = res.map(user => ({
+ text: user.model,
+ value: user.id,
+ unit: user.unit,
+ }));
+ });
+};
+// 閫夋嫨瑙勬牸鍨嬪彿
+const onSpecificationConfirm = ({ selectedValues, selectedOptions }) => {
+ productData.value[currentProductIndex.value].specificationModel = selectedOptions[0]?.text;
+ productData.value[currentProductIndex.value].productModelId = selectedOptions[0]?.value;
+ productData.value[currentProductIndex.value].unit = selectedOptions[0]?.unit;
+ pickerSpecificationValue.value = [selectedValues[0]];
+ showSpecificationPicker.value = false;
+};
+// 閫夋嫨绋庣巼
+const onTaxRateConfirm = ({ selectedValues, selectedOptions }) => {
+ productData.value[currentProductIndex.value].taxRate = selectedOptions[0]?.value;
+ pickerTaxRateValue.value = [selectedValues[0]];
+ showTaxRatePicker.value = false;
+ // if (isCalculating.value) return;
+ const inclusiveTotalPrice = parseFloat(productData.value[currentProductIndex.value].taxInclusiveTotalPrice);
+ const taxRate = parseFloat(productData.value[currentProductIndex.value].taxRate);
+ if (!inclusiveTotalPrice || !taxRate) {
+ return;
+ }
+ // isCalculating.value = true;
+ // 璁$畻涓嶅惈绋庢�讳环
+ productData.value[currentProductIndex.value].taxExclusiveTotalPrice =
+ calculateTaxExclusiveTotalPrice(
+ inclusiveTotalPrice,
+ taxRate
+ );
+ // isCalculating.value = false;
+};
+
+const onInvoiceTypeConfirm = ({ selectedValues, selectedOptions }) => {
+ productData.value[currentProductIndex.value].invoiceType = selectedOptions[0]?.text;
+ pickerInvoiceTypeValue.value = [selectedValues[0]];
+ showInvoiceTypePicker.value = false;
+};
+
+// 鏍煎紡鍖栧嚱鏁� - 鍥哄畾涓や綅灏忔暟
+const formatTaxPrice = (idx) => {
+ if (productData.value[idx].taxInclusiveUnitPrice) {
+ const value = parseFloat(productData.value[idx].taxInclusiveUnitPrice);
+ if (!isNaN(value)) {
+ productData.value[idx].taxInclusiveUnitPrice = value.toFixed(2);
+ }
+ }
+ if (!productData.value[currentProductIndex.value].taxRate) {
+ uni.showToast({
+ title: '璇峰厛閫夋嫨绋庣巼',
+ icon: 'none'
+ });
+ return;
+ }
+ const quantity = parseFloat(productData.value[currentProductIndex.value].quantity);
+ const unitPrice = parseFloat(productData.value[currentProductIndex.value].taxInclusiveUnitPrice);
+
+ if (!quantity || quantity <= 0 || !unitPrice) {
+ return;
+ }
+ // 璁$畻鍚◣鎬讳环
+ productData.value[currentProductIndex.value].taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
+
+ // 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
+ if (productData.value[currentProductIndex.value].taxRate) {
+ productData.value[currentProductIndex.value].taxExclusiveTotalPrice =
+ calculateTaxExclusiveTotalPrice(
+ productData.value[currentProductIndex.value].taxInclusiveTotalPrice,
+ productData.value[currentProductIndex.value].taxRate
+ );
+ }
+};
+// 鏁伴噺杈撳叆妗嗗け鐒�
+const formatAmount = (idx) => {
+ if (productData.value[idx].quantity) {
+ const value = parseFloat(productData.value[idx].quantity);
+ if (!isNaN(value)) {
+ productData.value[idx].quantity = value.toFixed(2);
+ }
+ }
+ if (!productData.value[currentProductIndex.value].taxRate) {
+ uni.showToast({
+ title: '璇峰厛閫夋嫨绋庣巼',
+ icon: 'none'
+ });
+ return;
+ }
+ const quantity = parseFloat(productData.value[currentProductIndex.value].quantity);
+ const unitPrice = parseFloat(productData.value[currentProductIndex.value].taxInclusiveUnitPrice);
+
+ if (!quantity || quantity <= 0 || !unitPrice) {
+ return;
+ }
+ // 璁$畻鍚◣鎬讳环
+ productData.value[currentProductIndex.value].taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
+ // 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
+ if (productData.value[currentProductIndex.value].taxRate) {
+ productData.value[currentProductIndex.value].taxExclusiveTotalPrice =
+ calculateTaxExclusiveTotalPrice(
+ productData.value[currentProductIndex.value].taxInclusiveTotalPrice,
+ productData.value[currentProductIndex.value].taxRate
+ );
+ }
+};
+// 鍚◣鎬讳环澶辩劍锛屾牴鎹惈绋庢�讳环璁$畻鍚◣鍗曚环鍜屾暟閲�
+const formatTaxTotal = (idx) => {
+ if (productData.value[idx].taxInclusiveTotalPrice) {
+ const value = parseFloat(productData.value[idx].taxInclusiveTotalPrice);
+ if (!isNaN(value)) {
+ productData.value[idx].taxInclusiveTotalPrice = value.toFixed(2);
+ }
+ }
+ const totalPrice = parseFloat(productData.value[currentProductIndex.value].taxInclusiveTotalPrice);
+ const quantity = parseFloat(productData.value[currentProductIndex.value].quantity);
+
+ if (!totalPrice || !quantity || quantity <= 0) {
+ return;
+ }
+ // 璁$畻鍚◣鍗曚环 = 鍚◣鎬讳环 / 鏁伴噺
+ productData.value[currentProductIndex.value].taxInclusiveUnitPrice = (totalPrice / quantity).toFixed(2);
+ // 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
+ if (productData.value[currentProductIndex.value].taxRate) {
+ productData.value[currentProductIndex.value].taxExclusiveTotalPrice =
+ calculateTaxExclusiveTotalPrice(
+ totalPrice,
+ productData.value[currentProductIndex.value].taxRate
+ );
+ }
+};
+// 涓嶅惈绋庢�讳环澶辩劍, 鏍规嵁涓嶅惈绋庢�讳环璁$畻鍚◣鍗曚环鍜屾暟閲�
+const formatNoTaxTotal = (idx) => {
+ if (productData.value[idx].taxExclusiveTotalPrice) {
+ const value = parseFloat(productData.value[idx].taxExclusiveTotalPrice);
+ if (!isNaN(value)) {
+ productData.value[idx].taxExclusiveTotalPrice = value.toFixed(2);
+ }
+ }
+ if (!productData.value[currentProductIndex.value].taxRate) {
+ uni.showToast({
+ title: '璇峰厛閫夋嫨绋庣巼',
+ icon: 'none'
+ });
+ return;
+ }
+ const exclusiveTotalPrice = parseFloat(productData.value[currentProductIndex.value].taxExclusiveTotalPrice);
+ const quantity = parseFloat(productData.value[currentProductIndex.value].quantity);
+ const taxRate = parseFloat(productData.value[currentProductIndex.value].taxRate);
+ if (!exclusiveTotalPrice || !quantity || quantity <= 0 || !taxRate) {
+ return;
+ }
+ // 鍏堣绠楀惈绋庢�讳环 = 涓嶅惈绋庢�讳环 / (1 - 绋庣巼/100)
+ const taxRateDecimal = taxRate / 100;
+ const inclusiveTotalPrice = exclusiveTotalPrice / (1 - taxRateDecimal);
+ productData.value[currentProductIndex.value].taxInclusiveTotalPrice = inclusiveTotalPrice.toFixed(2);
+ // 璁$畻鍚◣鍗曚环 = 鍚◣鎬讳环 / 鏁伴噺
+ productData.value[currentProductIndex.value].taxInclusiveUnitPrice = (inclusiveTotalPrice / quantity).toFixed(2);
+};
+const goBack = () => {
+ // 娓呯悊鏈湴瀛樺偍鐨勬暟鎹�
+ uni.removeStorageSync('operationType');
+ uni.removeStorageSync('editData');
+ uni.navigateBack();
+};
+const onSubmit = () => {
+ if (productData.value !== null && productData.value.length > 0) {
+ form.value.productData = JSON.parse(JSON.stringify(productData.value));
+ } else {
+ uni.showToast({
+ title: '璇锋坊鍔犱骇鍝佷俊鎭�',
+ icon: 'none'
+ });
+ return
+ }
+ form.value.type = 2;
+ addOrEditPurchase(form.value).then((res) => {
+ uni.showToast({
+ title: '鎻愪氦鎴愬姛',
+ icon: 'success',
+ });
+ goBack();
+ });
+};
+const setUserInfo = () => {
+ form.value.recorderId = userStore.id;
+ form.value.recorderName = userStore.nickName;
+ // 璁剧疆褰撳ぉ鏃ユ湡
+ const today = new Date()
+ const year = today.getFullYear()
+ const month = String(today.getMonth() + 1).padStart(2, '0')
+ const day = String(today.getDate()).padStart(2, '0')
+ form.value.entryDate = `${year}-${month}-${day}`
+ pickerDateValue.value = [year.toString(), month.toString(), day.toString()]
+}
+// 濉厖琛ㄥ崟鏁版嵁锛堢紪杈戞ā寮忥級
+const fillFormData = () => {
+ if (!editData.value) return;
+ getPurchaseById({ id: editData.value.id, type: 2 }).then((res) => {
+ productData.value = res.productData;
+ });
+ console.log(editData.value)
+ // 濉厖鍩烘湰淇℃伅
+ form.value.salesContractNo = editData.value.salesContractNo || '';
+ form.value.supplierName = editData.value.supplierName || '';
+ form.value.projectName = editData.value.projectName || '';
+ form.value.executionDate = editData.value.executionDate || '';
+ form.value.paymentMethod = editData.value.paymentMethod || '';
+ form.value.salesLedgerId = editData.value.salesLedgerId || '';
+ form.value.recorderId = editData.value.recorderId || '';
+ form.value.recorderName = editData.value.recorderName || '';
+ form.value.entryDate = editData.value.entryDate || '';
+ form.value.id = editData.value.id || '';
+ form.value.supplierId = editData.value.supplierId || '';
+
+ // 璁剧疆閿�鍞悎鍚屽彿閫夋嫨鍣ㄧ殑鍊�
+ if (editData.value.salesContractNo) {
+ const salesmanIndex = salesContractList.value.findIndex(user => user.text === editData.value.salesContractNo);
+ if (salesmanIndex !== -1) {
+ pickerValue.value = [salesContractList.value[salesmanIndex].value];
+ }
+ }
+
+ // 璁剧疆渚涘簲鍟嗛�夋嫨鍣ㄧ殑鍊�
+ if (editData.value.supplierName) {
+ const customerIndex = supplierList.value.findIndex(customer => customer.text === editData.value.supplierName);
+ if (customerIndex !== -1) {
+ pickerCustomerValue.value = [supplierList.value[customerIndex].value]
+ }
+ }
+
+ // 璁剧疆鏃ユ湡閫夋嫨鍣ㄧ殑鍊�
+ if (editData.value.executionDate) {
+ pickerDateValue.value = editData.value.executionDate.split('-').map(num => parseInt(num, 10))
+ console.log(pickerDateValue.value)
+ }
+};
+const getSalesNoList = () => {
+ getSalesNo().then((res) => {
+ // 灏嗙敤鎴锋暟鎹粍瑁呮垚 picker 闇�瑕佺殑鏍煎紡
+ salesContractList.value = res.map(user => ({
+ text: user.salesContractNo,
+ value: user.id
+ }));
+ })
+}
+const getOptionsLIst = () => {
+ getOptions().then((res) => {
+ // 灏嗙敤鎴锋暟鎹粍瑁呮垚 picker 闇�瑕佺殑鏍煎紡
+ supplierList.value = res.data.map(item => ({
+ text: item.supplierName,
+ value: item.id
+ }));
+ })
+}
+const convertIdToValue = (data) => {
+ // 濡傛灉浼犲叆鐨勪笉鏄暟缁勶紝鍒欒繑鍥炵┖鏁扮粍
+ if (!Array.isArray(data)) {
+ return [];
+ }
+ // 閫掑綊鏄犲皠鍑芥暟
+ return data.map(item => {
+ // 鍒涘缓鏂板璞★紝鏄犲皠瀛楁
+ const mappedItem = {
+ label: item.label, // 鍏抽敭锛氬皢 label 鏄犲皠涓� text
+ id: item.id, // 淇濈暀 id
+ };
+ // 濡傛灉瀛樺湪 children 鏁扮粍锛屽垯閫掑綊澶勭悊
+ if (item.children && Array.isArray(item.children) && item.children.length > 0) {
+ mappedItem.children = convertIdToValue(item.children);
+ }
+ return mappedItem;
+ });
+};
+// 鑾峰彇浜у搧澶х被tree鏁版嵁
+const getProductOptions = () => {
+ productTreeList().then((res) => {
+ productOptions.value = convertIdToValue(res);
+ });
+};
+onMounted(() => {
+ // 鑾峰彇椤甸潰鍙傛暟
+ operationType.value = uni.getStorageSync('operationType') || '';
+
+ // 鑾峰彇閿�鍞悎鍚屽彿鍒楄〃
+ getSalesNoList()
+ // 鑾峰彇渚涘簲鍟嗗垪琛�
+ getOptionsLIst()
+ // 鑾峰彇浜у搧澶х被tree鏁版嵁
+ getProductOptions()
+ // 璧嬪�奸粯璁や俊鎭�
+ if (operationType.value === 'add') {
+ setUserInfo()
+ createPurchaseNo().then((res) => {
+ form.value.purchaseContractNumber = res.data;
+ });
+ }
+
+ // 鑾峰彇缂栬緫鏁版嵁骞跺~鍏呰〃鍗�
+ const editDataStr = uni.getStorageSync('editData');
+ if (editDataStr) {
+ try {
+ editData.value = JSON.parse(editDataStr);
+ // 濡傛灉鏄紪杈戞ā寮忥紝绛夊緟鏁版嵁鍔犺浇瀹屾垚鍚庡~鍏呰〃鍗曟暟鎹�
+ if (operationType.value !== 'add' && editData.value) {
+ // 浣跨敤 nextTick 纭繚鏁版嵁鍔犺浇瀹屾垚鍚庡啀濉厖
+ setTimeout(() => {
+ fillFormData();
+ }, 100);
+ }
+ } catch (error) {
+ console.error('瑙f瀽缂栬緫鏁版嵁澶辫触:', error);
+ }
+ }
+});
+</script>
+
+<style scoped lang="scss">
+.account-detail {
+ min-height: 100vh;
+ background: #f8f9fa;
+ padding-bottom: 5rem;
+}
+.header {
+ display: flex;
+ align-items: center;
+ background: #fff;
+ padding: 1rem 1.25rem;
+ border-bottom: 0.0625rem solid #f0f0f0;
+ position: sticky;
+ top: 0;
+ z-index: 100;
+ /* 鍏煎 iOS 鍒樻捣/鐏靛姩宀涘畨鍏ㄥ尯 */
+ padding-top: env(safe-area-inset-top);
+}
+.title {
+ flex: 1;
+ text-align: center;
+ font-size: 1.125rem;
+ font-weight: 600;
+ color: #333;
+}
+.form-section {
+ margin-top: 1rem;
+}
+.van-field {
+ height: 3.4rem;
+}
+.van-cell {
+ align-items: center;
+}
+.product-section {
+ background: #fff;
+ margin-top: 1rem;
+ padding: 1rem;
+ box-shadow: 0 0.125rem 0.5rem rgba(0,0,0,0.04);
+}
+.section-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-bottom: 1rem;
+}
+.section-title {
+ font-size: 1rem;
+ font-weight: 600;
+ color: #333;
+}
+.product-card {
+ background: #FFFFFF;
+ box-shadow: 0 0 1.25rem 0 rgba(0,57,117,0.08);
+ border-radius: 0.5rem 0.5rem 0.5rem 0.5rem;
+ padding: 1rem 0.5rem 0 0.5rem;
+ position: relative;
+}
+.product-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0 0.5rem 0.75rem 0.5rem;
+ border-bottom: 0.0625rem solid #e8e8e8;
+}
+.product-productCategory {
+ margin-left: 0.5rem;
+ font-size: 0.875rem;
+ font-weight: 500;
+ color: #333;
+}
+.info-grid {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 0.75rem;
+ margin-bottom: 1rem;
+}
+.info-item {
+ display: flex;
+ flex-direction: column;
+ gap: 0.25rem;
+}
+.info-label {
+ font-size: 0.75rem;
+ color: #666;
+ font-weight: 400;
+}
+.info-value {
+ font-size: 0.875rem;
+ color: #333;
+ font-weight: 500;
+}
+.info-value.highlight {
+ color: #2979ff;
+ font-weight: 600;
+}
+.product-form {
+ margin-bottom: 1rem;
+}
+.footer-btns {
+ position: fixed;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: #fff;
+ display: flex;
+ justify-content: space-around;
+ align-items: center;
+ padding: 0.75rem 0;
+ box-shadow: 0 -0.125rem 0.5rem rgba(0,0,0,0.05);
+ z-index: 1000;
+}
+.cancel-btn {
+ font-weight: 400;
+ font-size: 1rem;
+ color: #FFFFFF;
+ width: 6.375rem;
+ background: #C7C9CC;
+ box-shadow: 0 0.25rem 0.625rem 0 rgba(3,88,185,0.2);
+ border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+}
+.save-btn {
+ font-weight: 400;
+ font-size: 1rem;
+ color: #FFFFFF;
+ width: 14rem;
+ background: linear-gradient( 140deg, #00BAFF 0%, #006CFB 100%);
+ box-shadow: 0 0.25rem 0.625rem 0 rgba(3,88,185,0.2);
+ border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+}
+
+.popup-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 1rem;
+ background: #fff;
+ position: sticky;
+ top: 0;
+ z-index: 10;
+}
+.cancelButton {
+ color: #969799
+}
+.confirmButton {
+ color: #1989FA
+}
+.u-tree {
+ height: 13rem;
+}
+</style>
diff --git a/src/pages/procurementManagement/procurementLedger/index.vue b/src/pages/procurementManagement/procurementLedger/index.vue
new file mode 100644
index 0000000..495f250
--- /dev/null
+++ b/src/pages/procurementManagement/procurementLedger/index.vue
@@ -0,0 +1,342 @@
+<template>
+ <view class="sales-account">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader title="閲囪喘鍙拌处" @back="goBack" />
+
+ <!-- 鎼滅储鍜岀瓫閫夊尯鍩� -->
+ <view class="search-filter-section">
+ <view class="search-bar">
+ <view class="search-input">
+ <input
+ class="search-text"
+ placeholder="璇疯緭鍏ラ噰璐悎鍚屽彿/瀹㈡埛鍚嶇О"
+ v-model="searchKeyword"
+ />
+ </view>
+ <view class="filter-button" @click="getList">
+ <up-icon name="search" size="24" color="#999"></up-icon>
+ </view>
+ </view>
+ </view>
+
+ <!-- 閲囪喘鍙拌处鐎戝竷娴� -->
+ <view class="ledger-list" v-if="ledgerList.length > 0">
+ <view v-for="(item, index) in ledgerList" :key="index">
+ <view class="ledger-item" @click="handleInfo('edit', item)">
+ <view class="item-header">
+ <view class="item-left">
+ <view class="document-icon">
+ <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
+ </view>
+ <text class="item-id">{{ item.purchaseContractNumber }}</text>
+ </view>
+ <!-- <view class="item-tag">-->
+ <!-- <text class="tag-text">{{ item.recorder }}</text>-->
+ <!-- </view>-->
+ </view>
+ <up-divider></up-divider>
+
+ <view class="item-details">
+ <view class="detail-row">
+ <text class="detail-label">閿�鍞悎鍚屽彿</text>
+ <text class="detail-value">{{ item.salesContractNo }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">渚涘簲鍟嗗悕绉�</text>
+ <text class="detail-value">{{ item.supplierName }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">椤圭洰鍚嶇О</text>
+ <text class="detail-value">{{ item.projectName }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">浠樻鏂瑰紡</text>
+ <text class="detail-value">{{ item.paymentMethod }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍚堝悓閲戦(鍏�)</text>
+ <text class="detail-value highlight">{{ item.contractAmount }}</text>
+ </view>
+ <up-divider></up-divider>
+ <view class="detail-info">
+ <view class="detail-row">
+ <text class="detail-label">褰曞叆浜�</text>
+ <text class="detail-value">{{ item.recorderName }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">褰曞叆鏃ユ湡</text>
+ <text class="detail-value">{{ item.entryDate }}</text>
+ </view>
+ </view>
+ </view>
+ </view>
+ </view>
+ </view>
+ <view v-else class="no-data">
+ <text>鏆傛棤閲囪喘鍙拌处鏁版嵁</text>
+ </view>
+
+ <!-- 娴姩鎿嶄綔鎸夐挳 -->
+ <view class="fab-button" @click="handleInfo('add')">
+ <up-icon name="plus" size="24" color="#ffffff"></up-icon>
+ </view>
+ </view>
+</template>
+
+<script setup>
+import { ref } from 'vue';
+import { onShow } from '@dcloudio/uni-app';
+import useUserStore from "@/store/modules/user";
+import PageHeader from "@/components/PageHeader.vue";
+import {purchaseListPage} from "@/api/procurementManagement/procurementLedger";
+const userStore = useUserStore()
+
+// 鎼滅储鍏抽敭璇�
+const searchKeyword = ref('');
+
+// 閲囪喘鍙拌处鏁版嵁
+const ledgerList = ref([]);
+
+// 杩斿洖涓婁竴椤�
+const goBack = () => {
+ uni.navigateBack();
+};
+// 鏌ヨ鍒楄〃
+const getList = () => {
+ const page = {
+ current: -1,
+ size: -1
+ }
+ purchaseListPage({...page}).then((res) => {
+ ledgerList.value = res.data.records;
+ }).catch(() => {
+ // tableLoading.value = false;
+ });
+};
+
+// 澶勭悊鍙拌处淇℃伅鎿嶄綔锛堟煡鐪�/缂栬緫/鏂板锛�
+const handleInfo = (type, row) => {
+ try {
+ // 璁剧疆鎿嶄綔绫诲瀷
+ uni.setStorageSync('operationType', type);
+
+ // 濡傛灉鏄煡鐪嬫垨缂栬緫鎿嶄綔
+ if (type !== 'add') {
+ // 楠岃瘉琛屾暟鎹槸鍚﹀瓨鍦�
+ if (!row) {
+ uni.showToast({
+ title: '鏁版嵁涓嶅瓨鍦�',
+ icon: 'error'
+ });
+ return;
+ }
+
+ // 妫�鏌ユ潈闄愶細鍙湁褰曞叆浜烘墠鑳界紪杈�
+ if (row.recorderName != userStore.nickName) {
+ // 闈炲綍鍏ヤ汉璺宠浆鍒板彧璇昏鎯呴〉闈�
+ uni.setStorageSync('editData', JSON.stringify(row));
+ uni.navigateTo({
+ url: '/pages/procurementManagement/procurementLedger/view'
+ });
+ return;
+ }
+
+ // 褰曞叆浜虹紪杈戯細瀛樺偍鏁版嵁骞惰烦杞埌缂栬緫椤甸潰
+ uni.setStorageSync('editData', JSON.stringify(row));
+ uni.navigateTo({
+ url: '/pages/procurementManagement/procurementLedger/detail'
+ });
+ return;
+ }
+
+ // 鏂板鎿嶄綔锛氱洿鎺ヨ烦杞埌缂栬緫椤甸潰
+ uni.navigateTo({
+ url: '/pages/procurementManagement/procurementLedger/detail'
+ });
+
+ } catch (error) {
+ console.error('澶勭悊鍙拌处淇℃伅鎿嶄綔澶辫触:', error);
+ uni.showToast({
+ title: '鎿嶄綔澶辫触锛岃閲嶈瘯',
+ icon: 'error'
+ });
+ }
+};
+
+onShow(() => {
+ // 椤甸潰鏄剧ず鏃跺埛鏂板垪琛�
+ getList();
+});
+</script>
+
+<style scoped lang="scss">
+.u-divider {
+ margin: 0 !important;
+}
+.sales-account {
+ min-height: 100vh;
+ background: #f8f9fa;
+ position: relative;
+}
+
+
+
+.search-filter-section {
+ padding: 10px 20px;
+ background: #ffffff;
+}
+
+.search-bar {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+}
+
+.search-input {
+ flex: 1;
+ background: #f5f5f5;
+ border-radius: 24px;
+ padding: 10px 16px;
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.search-text {
+ flex: 1;
+ font-size: 14px;
+ color: #333;
+ background: transparent;
+ border: none;
+ outline: none;
+}
+
+.search-text::placeholder {
+ color: #999;
+}
+
+.filter-button {
+ width: 40px;
+ height: 40px;
+ border-radius: 8px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.ledger-list {
+ padding: 20px;
+}
+
+.ledger-item {
+ background: #ffffff;
+ border-radius: 12px;
+ margin-bottom: 16px;
+ overflow: hidden;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+ padding: 0 16px;
+}
+
+.item-header {
+ padding: 16px 0;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+}
+
+.item-left {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.document-icon {
+ width: 24px;
+ height: 24px;
+ background: #2979ff;
+ border-radius: 4px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.item-id {
+ font-size: 14px;
+ color: #333;
+ font-weight: 500;
+}
+
+.item-tag {
+ background: #4caf50;
+ border-radius: 4px;
+ padding: 2px 4px;
+}
+
+.tag-text {
+ font-size: 11px;
+ color: #ffffff;
+ font-weight: 500;
+}
+
+.item-details {
+ padding: 16px 0;
+}
+
+.detail-row {
+ display: flex;
+ align-items: flex-end;
+ justify-content: space-between;
+ margin-bottom: 8px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+}
+.detail-info {
+ margin-top: 10px;
+ display: flex;
+ align-items: flex-start;
+ justify-content: space-between;
+}
+
+.detail-label {
+ font-size: 12px;
+ color: #777777;
+ min-width: 60px;
+}
+
+.detail-value {
+ font-size: 12px;
+ color: #000000;
+ text-align: right;
+ flex: 1;
+ margin-left: 16px;
+}
+
+.detail-value.highlight {
+ color: #2979ff;
+ font-weight: 500;
+}
+
+.no-data {
+ padding: 40px 0;
+ text-align: center;
+ color: #999;
+}
+
+.fab-button {
+ position: fixed;
+ bottom: calc(30px + env(safe-area-inset-bottom));
+ right: 30px;
+ width: 56px;
+ height: 56px;
+ background: #2979ff;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ box-shadow: 0 4px 16px rgba(41, 121, 255, 0.3);
+ z-index: 1000;
+ /* 纭繚娴姩鎸夐挳涓嶈搴曢儴瀹夊叏鍖哄煙閬尅 */
+}
+</style>
diff --git a/src/pages/procurementManagement/procurementLedger/view.vue b/src/pages/procurementManagement/procurementLedger/view.vue
new file mode 100644
index 0000000..174b8ae
--- /dev/null
+++ b/src/pages/procurementManagement/procurementLedger/view.vue
@@ -0,0 +1,287 @@
+<template>
+ <view class="account-view">
+ <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+ <PageHeader title="鍙拌处璇︽儏" @back="goBack" />
+
+ <!-- 鍩烘湰淇℃伅灞曠ず -->
+ <view class="info-section">
+ <view class="section-title">鍩烘湰淇℃伅</view>
+ <view class="info-grid">
+ <view class="info-item">
+ <text class="info-label">閲囪喘鍚堝悓鍙�</text>
+ <text class="info-value">{{ form.purchaseContractNumber }}</text>
+ </view>
+ <view class="info-item">
+ <text class="info-label">閿�鍞悎鍚屽彿</text>
+ <text class="info-value">{{ form.salesContractNo }}</text>
+ </view>
+ <view class="info-item">
+ <text class="info-label">渚涘簲鍟嗗悕绉�</text>
+ <text class="info-value">{{ form.supplierName }}</text>
+ </view>
+ <view class="info-item">
+ <text class="info-label">椤圭洰鍚嶇О</text>
+ <text class="info-value">{{ form.projectName }}</text>
+ </view>
+ <view class="info-item">
+ <text class="info-label">浠樻鏂瑰紡</text>
+ <text class="info-value">{{ form.paymentMethod }}</text>
+ </view>
+ <view class="info-item">
+ <text class="info-label">褰曞叆浜�</text>
+ <text class="info-value">{{ form.recorderName }}</text>
+ </view>
+ <view class="info-item">
+ <text class="info-label">褰曞叆鏃ユ湡</text>
+ <text class="info-value">{{ form.entryDate }}</text>
+ </view>
+ </view>
+ </view>
+
+ <!-- 浜у搧淇℃伅灞曠ず -->
+ <view class="product-section" v-if="productData && productData.length > 0">
+ <view class="section-title">浜у搧淇℃伅</view>
+ <view class="product-card" v-for="(product, idx) in productData" :key="idx">
+ <view class="product-header">
+ <view class="product-title">
+ <van-icon name="description" color="#2979ff" size="15" />
+ <text class="product-productCategory">浜у搧 {{ idx + 1 }}</text>
+ </view>
+ </view>
+
+ <view class="product-info">
+ <view class="info-grid">
+ <view class="info-item">
+ <text class="info-label">浜у搧澶х被</text>
+ <text class="info-value">{{ product.productCategory }}</text>
+ </view>
+ <view class="info-item">
+ <text class="info-label">瑙勬牸鍨嬪彿</text>
+ <text class="info-value">{{ product.specificationModel }}</text>
+ </view>
+ <view class="info-item">
+ <text class="info-label">鍗曚綅</text>
+ <text class="info-value">{{ product.unit }}</text>
+ </view>
+ <view class="info-item">
+ <text class="info-label">绋庣巼(%)</text>
+ <text class="info-value">{{ product.taxRate }}</text>
+ </view>
+ <view class="info-item">
+ <text class="info-label">鍚◣鍗曚环(鍏�)</text>
+ <text class="info-value highlight">{{ product.taxInclusiveUnitPrice }}</text>
+ </view>
+ <view class="info-item">
+ <text class="info-label">鏁伴噺</text>
+ <text class="info-value highlight">{{ product.quantity }}</text>
+ </view>
+ <view class="info-item">
+ <text class="info-label">鍚◣鎬讳环(鍏�)</text>
+ <text class="info-value highlight">{{ product.taxInclusiveTotalPrice }}</text>
+ </view>
+ <view class="info-item">
+ <text class="info-label">涓嶅惈绋庢�讳环(鍏�)</text>
+ <text class="info-value highlight">{{ product.taxExclusiveTotalPrice }}</text>
+ </view>
+ <view class="info-item">
+ <text class="info-label">鍙戠エ绫诲瀷</text>
+ <text class="info-value">{{ product.invoiceType }}</text>
+ </view>
+ </view>
+ </view>
+ </view>
+ </view>
+
+ <!-- 鏃犱骇鍝佷俊鎭彁绀� -->
+ <view class="no-product" v-else>
+ <text>鏆傛棤浜у搧淇℃伅</text>
+ </view>
+ </view>
+</template>
+
+<script setup>
+import { onMounted, ref } from 'vue';
+import {getPurchaseById} from "@/api/procurementManagement/procurementLedger";
+
+// 琛ㄥ崟鏁版嵁
+const form = ref({
+ id: '',
+ salesContractNo: '',
+ customerContractNo: '',
+ customerId: '',
+ customerName: '',
+ projectName: '',
+ executionDate: '',
+ paymentMethod: '',
+ entryPerson: '',
+ entryPersonName: '',
+ entryDate: '',
+ salesman: ''
+});
+
+// 浜у搧鏁版嵁
+const productData = ref([]);
+
+// 缂栬緫鏁版嵁
+const editData = ref(null);
+
+// 杩斿洖涓婁竴椤�
+const goBack = () => {
+ // 娓呯悊鏈湴瀛樺偍鐨勬暟鎹�
+ uni.removeStorageSync('editData');
+ uni.navigateBack();
+};
+
+// 濉厖琛ㄥ崟鏁版嵁
+const fillFormData = () => {
+ if (!editData.value) return;
+
+ // 鑾峰彇瀹屾暣鐨勪骇鍝佷俊鎭�
+ getPurchaseById({ id: editData.value.id, type: 2 }).then((res) => {
+ productData.value = res.productData || [];
+ form.value = {...res}
+ });
+};
+
+onMounted(() => {
+ // 鑾峰彇缂栬緫鏁版嵁骞跺~鍏呰〃鍗�
+ const editDataStr = uni.getStorageSync('editData');
+ if (editDataStr) {
+ try {
+ editData.value = JSON.parse(editDataStr);
+ // 浣跨敤 nextTick 纭繚鏁版嵁鍔犺浇瀹屾垚鍚庡啀濉厖
+ setTimeout(() => {
+ fillFormData();
+ }, 100);
+ } catch (error) {
+ console.error('瑙f瀽缂栬緫鏁版嵁澶辫触:', error);
+ }
+ }
+});
+</script>
+
+<style scoped lang="scss">
+.account-view {
+ min-height: 100vh;
+ background: #f8f9fa;
+ padding-bottom: 2rem;
+}
+
+.header {
+ display: flex;
+ align-items: center;
+ background: #fff;
+ padding: 1rem 1.25rem;
+ border-bottom: 0.0625rem solid #f0f0f0;
+ position: sticky;
+ top: 0;
+ z-index: 100;
+ /* 鍏煎 iOS 鍒樻捣/鐏靛姩宀涘畨鍏ㄥ尯 */
+ padding-top: env(safe-area-inset-top);
+}
+
+.title {
+ flex: 1;
+ text-align: center;
+ font-size: 1.125rem;
+ font-weight: 600;
+ color: #333;
+}
+
+.info-section {
+ background: #fff;
+ margin: 1rem;
+ padding: 1rem;
+ border-radius: 0.5rem;
+ box-shadow: 0 0.125rem 0.5rem rgba(0,0,0,0.04);
+}
+
+.section-title {
+ font-size: 1rem;
+ font-weight: 600;
+ color: #333;
+ margin-bottom: 1rem;
+ padding-bottom: 1rem;
+ border-bottom: 0.0625rem solid #e8e8e8;
+}
+
+.info-grid {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 0.75rem;
+}
+
+.info-item {
+ display: flex;
+ flex-direction: column;
+ gap: 0.25rem;
+}
+
+.info-label {
+ font-size: 0.75rem;
+ color: #666;
+ font-weight: 400;
+}
+
+.info-value {
+ font-size: 0.875rem;
+ color: #333;
+ font-weight: 500;
+}
+
+.info-value.highlight {
+ color: #2979ff;
+ font-weight: 600;
+}
+
+.product-section {
+ background: #fff;
+ margin: 1rem;
+ padding: 1rem;
+ border-radius: 0.5rem;
+ box-shadow: 0 0.125rem 0.5rem rgba(0,0,0,0.04);
+}
+
+.product-card {
+ background: #f8f9fa;
+ border-radius: 0.5rem;
+ padding: 1rem;
+ margin-bottom: 1rem;
+}
+
+.product-card:last-child {
+ margin-bottom: 0;
+}
+
+.product-header {
+ display: flex;
+ align-items: center;
+ padding-bottom: 0.75rem;
+ border-bottom: 0.0625rem solid #e8e8e8;
+ margin-bottom: 1rem;
+}
+
+.product-title {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+}
+
+.product-productCategory {
+ font-size: 0.875rem;
+ font-weight: 500;
+ color: #333;
+}
+
+.product-info .info-grid {
+ grid-template-columns: 1fr 1fr;
+ gap: 0.5rem;
+}
+
+.no-product {
+ text-align: center;
+ padding: 2rem;
+ color: #999;
+ font-size: 0.875rem;
+}
+</style>
diff --git a/src/pages/sales/salesAccount/detail.vue b/src/pages/sales/salesAccount/detail.vue
index bf3f217..bca5e36 100644
--- a/src/pages/sales/salesAccount/detail.vue
+++ b/src/pages/sales/salesAccount/detail.vue
@@ -425,7 +425,8 @@
modelList({ id: value }).then((res) => {
modelOptions.value = res.map(user => ({
text: user.model,
- value: user.id
+ value: user.id,
+ unit: user.unit,
}));
});
};
--
Gitblit v1.9.3