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