src/api/basicData/customerFile.js
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,52 @@ // å®¢æ·æ¡£æ¡é¡µé¢æ¥å£ import request from '@/utils/request' // å页æ¥è¯¢ export function listCustomer(query) { return request({ url: '/basic/customer/list', method: 'get', params: query }) } // æ¥è¯¢å®¢æ·æ¡£æ¡è¯¦ç» export function getCustomer(id) { return request({ url: '/basic/customer/' + id, method: 'get' }) } // æ°å¢å®¢æ·æ¡£æ¡ export function addCustomer(data) { return request({ url: '/basic/customer/addCustomer', method: 'post', data: data }) } // ä¿®æ¹å®¢æ·æ¡£æ¡ export function updateCustomer(data) { return request({ url: '/basic/customer/updateCustomer', method: 'post', data: data }) } // 导åºå®¢æ·æ¡£æ¡ export function exportCustomer(query) { return request({ url: '/basic/customer/export', method: 'get', params: query, responseType: 'blob' }) } // å é¤å®¢æ·æ¡£æ¡ export function delCustomer(ids) { return request({ url: '/basic/customer/delCustomer', method: 'delete', data: ids }) } 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 }) } 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 }) } 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, }); } 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, }); } 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", }); } 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, }); } 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", }); } 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, }); } 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, }); } 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": "æµè§ç½é¡µ" 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' 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('è§£æç¼è¾æ°æ®å¤±è´¥:', 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> 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> 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('è§£æç¼è¾æ°æ®å¤±è´¥:', 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> 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, })); }); };