From adeb8b768926ed50a3fb0857f366d6a0308d2cc0 Mon Sep 17 00:00:00 2001 From: gaoluyang <2820782392@qq.com> Date: 星期五, 29 八月 2025 17:45:57 +0800 Subject: [PATCH] 修改组件 --- src/pages/procurementManagement/invoiceEntry/add.vue | 547 ++++++++++++------------------------------------------ 1 files changed, 123 insertions(+), 424 deletions(-) diff --git a/src/pages/procurementManagement/invoiceEntry/add.vue b/src/pages/procurementManagement/invoiceEntry/add.vue index 2fdcb2b..8b4e229 100644 --- a/src/pages/procurementManagement/invoiceEntry/add.vue +++ b/src/pages/procurementManagement/invoiceEntry/add.vue @@ -1,440 +1,139 @@ <template> - <view class="account-detail"> - <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 --> - <PageHeader title="鏂板鏉ョエ鐧昏" @back="goBack" /> - - <!-- 琛ㄥ崟鍐呭 --> - <van-form @submit="submitForm" ref="formRef" label-width="110px" input-align="right" error-message-align="right" scroll-to-error scroll-to-error-position="center"> - <!-- 鍩烘湰淇℃伅 --> - <van-cell-group title="鍩烘湰淇℃伅" inset> - <van-field - v-model="form.purchaseLedgerNo" - label="閲囪喘鍚堝悓鍙�" - readonly - placeholder="鑷姩濉厖" - /> - <van-field - v-model="form.salesContractNo" - label="閿�鍞悎鍚屽彿" - readonly - placeholder="鑷姩濉厖" - /> - <van-field - v-model="form.supplierName" - label="渚涘簲鍟嗗悕绉�" - readonly - placeholder="鑷姩濉厖" - /> - <van-field - v-model="form.projectName" - label="椤圭洰鍚嶇О" - readonly - placeholder="鑷姩濉厖" - /> - <van-field - v-model="form.issUer" - label="褰曞叆浜�" - readonly - placeholder="璇疯緭鍏ュ綍鍏ヤ汉" - /> - <van-field - v-model="form.enterDate" - label="褰曞叆鏃ユ湡" - readonly - placeholder="璇烽�夋嫨褰曞叆鏃ユ湡" - @click="showCreateTimePicker = true" - /> - <van-field - v-model="form.invoiceNumber" - label="鍙戠エ鍙风爜" - required - placeholder="璇疯緭鍏ュ彂绁ㄥ彿鐮�" - :rules="[{ required: true, message: '璇疯緭鍏ュ彂绁ㄥ彿鐮�' }]" - /> - <van-field - v-model="form.invoiceAmount" - label="鍙戠エ閲戦(鍏�)" - required - readonly - placeholder="鑷姩濉厖" - :rules="[{ required: true, message: '璇疯緭鍏ュ彂绁ㄥ彿鐮�' }]" - /> - <van-field - v-model="form.issueDate" - label="鏉ョエ鏃ユ湡" - readonly - placeholder="璇烽�夋嫨鏉ョエ鏃ユ湡" - required - @click="showIssueDatePicker = true" - :rules="[{ required: true, message: '璇烽�夋嫨鏉ョエ鏃ユ湡' }]" - /> - </van-cell-group> - - <!-- 浜у搧淇℃伅 --> - <view class="product-section"> - <view class="section-header"> - <text class="section-title">浜у搧淇℃伅</text> - </view> - - <view v-if="productData.length === 0" class="empty-state"> - <van-empty description="鏆傛棤浜у搧鏁版嵁" /> - </view> - - <view v-else class="product-list"> - <view - v-for="(item, index) in productData" - :key="index" - class="product-card" - > - <!-- 浜у搧澶撮儴 --> - <view class="product-header"> - <view class="product-title"> - <van-icon name="description" color="#2979ff" size="15" /> - <text class="product-productCategory">浜у搧 {{ index + 1 }}</text> - </view> - </view> - - <!-- 浜у搧淇℃伅琛ㄥ崟 --> - <view class="product-form"> - <van-field - v-model="item.productCategory" - label="浜у搧澶х被" - readonly - /> - <van-field - v-model="item.specificationModel" - label="瑙勬牸鍨嬪彿" - readonly - /> - <van-field - v-model="item.unit" - label="鍗曚綅" - readonly - /> - <van-field - v-model="item.quantity" - label="鏁伴噺" - readonly - /> - <van-field - v-model="item.taxRate" - label="绋庣巼(%)" - readonly - /> - <van-field - v-model="item.taxInclusiveUnitPrice" - label="鍚◣鍗曚环(鍏�)" - readonly - /> - <van-field - v-model="item.taxInclusiveTotalPrice" - label="鍚◣鎬讳环(鍏�)" - readonly - /> - <van-field - v-model="item.taxExclusiveTotalPrice" - label="涓嶅惈绋庢�讳环(鍏�)" - readonly - /> - - <!-- 鏈鏉ョエ淇℃伅 --> - <van-field - v-model="item.ticketsNum" - label="鏈鏉ョエ鏁�" - type="number" - placeholder="璇疯緭鍏ユ潵绁ㄦ暟閲�" - @blur="invoiceNumBlur(item)" - /> - <van-field - v-model="item.ticketsAmount" - label="鏈鏉ョエ閲戦(鍏�)" - type="number" - placeholder="璇疯緭鍏ユ潵绁ㄩ噾棰�" - @blur="invoiceAmountBlur(item)" - /> - - <!-- 鏈潵绁ㄤ俊鎭� --> - <van-field - v-model="item.futureTickets" - label="鏈潵绁ㄦ暟" - readonly - /> - <van-field - v-model="item.futureTicketsAmount" - label="鏈潵绁ㄩ噾棰�(鍏�)" - readonly - /> - </view> - </view> - </view> - </view> - - <!-- 鎻愪氦鎸夐挳 --> - <view class="footer-btns"> - <van-button class="cancel-btn" @click="goBack">鍙栨秷</van-button> - <van-button class="save-btn" native-type="submit" form-type="submit">淇濆瓨</van-button> + <view class="invoice-add"> + <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 --> + <PageHeader title="鏂板鍙戠エ" @back="goBack" /> + + <!-- 琛ㄥ崟鍐呭 --> + <u-form @submit="submitForm" ref="formRef" label-width="110" input-align="right" error-message-align="right"> + <!-- 鍩烘湰淇℃伅 --> + <u-cell-group title="鍩烘湰淇℃伅"> + <u-form-item label="閲囪喘鍚堝悓鍙�" prop="contractNo" required border-bottom> + <u-input v-model="form.contractNo" placeholder="璇疯緭鍏ラ噰璐悎鍚屽彿" clearable /> + </u-form-item> + <u-form-item label="渚涘簲鍟嗗悕绉�" prop="supplierName" required border-bottom> + <u-input v-model="form.supplierName" placeholder="璇疯緭鍏ヤ緵搴斿晢鍚嶇О" clearable /> + </u-form-item> + <u-form-item label="鍙戠エ鍙�" prop="invoiceNo" required border-bottom> + <u-input v-model="form.invoiceNo" placeholder="璇疯緭鍏ュ彂绁ㄥ彿" clearable /> + </u-form-item> + <u-form-item label="鍙戠エ閲戦" prop="invoiceAmount" required border-bottom> + <u-input v-model="form.invoiceAmount" type="number" placeholder="璇疯緭鍏ュ彂绁ㄩ噾棰�" clearable /> + </u-form-item> + <u-form-item label="绋庣巼" prop="taxRate" required border-bottom> + <u-input v-model="form.taxRate" placeholder="璇疯緭鍏ョ◣鐜�" clearable /> + </u-form-item> + <u-form-item label="寮�绁ㄦ棩鏈�" prop="issueDate" required border-bottom> + <u-input v-model="form.issueDate" placeholder="璇烽�夋嫨寮�绁ㄦ棩鏈�" readonly @click="showIssueDatePicker = true" clearable /> + </u-form-item> + <u-form-item label="褰曞叆浜�" border-bottom> + <u-input v-model="form.recorder" placeholder="鑷姩濉厖" readonly /> + </u-form-item> + <u-form-item label="鍒涘缓鏃堕棿" border-bottom> + <u-input v-model="form.createTime" placeholder="璇烽�夋嫨鍒涘缓鏃堕棿" readonly @click="showCreateTimePicker = true" clearable /> + </u-form-item> + </u-cell-group> + + <!-- 浜у搧淇℃伅 --> + <view class="product-section" v-if="!productData || productData.length === 0"> + <u-empty description="鏆傛棤浜у搧鏁版嵁" /> </view> - </van-form> + + <!-- 浜у搧鍒楄〃 --> + <view class="product-list" v-if="productData && productData.length > 0"> + <view class="product-card" v-for="(product, idx) in productData" :key="idx"> + <view class="product-header"> + <view class="product-title"> + <u-icon name="file-text" color="#2979ff" size="15" /> + <text class="product-name">浜у搧 {{ idx + 1 }}</text> + </view> + </view> + + <!-- 浜у搧淇℃伅琛ㄥ崟 --> + <view class="product-form"> + <u-form-item label="浜у搧鍚嶇О" border-bottom> + <u-input v-model="product.productName" placeholder="璇疯緭鍏ヤ骇鍝佸悕绉�" /> + </u-form-item> + <u-form-item label="瑙勬牸鍨嬪彿" border-bottom> + <u-input v-model="product.specification" placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�" /> + </u-form-item> + <u-form-item label="鍗曚綅" border-bottom> + <u-input v-model="product.unit" placeholder="璇疯緭鍏ュ崟浣�" /> + </u-form-item> + <u-form-item label="鏁伴噺" border-bottom> + <u-input v-model="product.quantity" type="number" placeholder="璇疯緭鍏ユ暟閲�" /> + </u-form-item> + <u-form-item label="鍗曚环" border-bottom> + <u-input v-model="product.unitPrice" type="number" placeholder="璇疯緭鍏ュ崟浠�" /> + </u-form-item> + <u-form-item label="閲戦" border-bottom> + <u-input v-model="product.amount" type="number" placeholder="璇疯緭鍏ラ噾棰�" /> + </u-form-item> + <u-form-item label="绋庣巼" border-bottom> + <u-input v-model="product.taxRate" placeholder="璇疯緭鍏ョ◣鐜�" /> + </u-form-item> + <u-form-item label="绋庨" border-bottom> + <u-input v-model="product.taxAmount" type="number" placeholder="璇疯緭鍏ョ◣棰�" /> + </u-form-item> + <u-form-item label="鍚◣閲戦" border-bottom> + <u-input v-model="product.totalAmount" type="number" placeholder="璇疯緭鍏ュ惈绋庨噾棰�" /> + </u-form-item> + <u-form-item label="澶囨敞" border-bottom> + <u-textarea v-model="product.remark" placeholder="璇疯緭鍏ュ娉�" :maxlength="200" count :autoHeight="true" /> + </u-form-item> + </view> + </view> + </view> + + <!-- 鎻愪氦鎸夐挳 --> + <view class="footer-btns"> + <u-button class="cancel-btn" @click="goBack">鍙栨秷</u-button> + <u-button class="save-btn" type="primary" @click="submitForm">淇濆瓨</u-button> + </view> + </u-form> - <!-- 鏃ユ湡閫夋嫨鍣� --> - <van-popup v-model:show="showIssueDatePicker" position="bottom"> - <van-date-picker - v-model="currentIssueDate" - title="閫夋嫨鏉ョエ鏃ユ湡" - @confirm="onIssueDateConfirm" - @cancel="showIssueDatePicker = false" - /> - </van-popup> + <!-- 寮�绁ㄦ棩鏈熼�夋嫨鍣� --> + <u-popup v-model="showIssueDatePicker" mode="bottom"> + <u-datetime-picker + v-model="issueDateValue" + title="閫夋嫨寮�绁ㄦ棩鏈�" + @confirm="onIssueDateConfirm" + @cancel="showIssueDatePicker = false" + /> + </u-popup> - <van-popup v-model:show="showCreateTimePicker" position="bottom"> - <van-date-picker - v-model="currentCreateTime" - title="閫夋嫨褰曞叆鏃ユ湡" - @confirm="onCreateTimeConfirm" - @cancel="showCreateTimePicker = false" - /> - </van-popup> - </view> + <!-- 鍒涘缓鏃堕棿閫夋嫨鍣� --> + <u-popup v-model="showCreateTimePicker" mode="bottom"> + <u-datetime-picker + v-model="createTimeValue" + title="閫夋嫨鍒涘缓鏃堕棿" + @confirm="onCreateTimeConfirm" + @cancel="showCreateTimePicker = false" + /> + </u-popup> + </view> </template> <script setup> -import { ref, onMounted } from 'vue' -import { showToast, showLoadingToast, closeToast } from 'vant' -import useUserStore from '@/store/modules/user' -import {addOrUpdateRegistration, getPurchaseNoById} from "@/api/procurementManagement/invoiceEntry"; -import {getInfo} from "@/api/procurementManagement/invoiceEntry.js"; +// 鏇挎崲 Vant 鐨� toast 鏂规硶 +// import { showToast, showLoadingToast, closeToast } from 'vant' -const userStore = useUserStore() -const editData = ref(null); - -// 琛ㄥ崟寮曠敤 -const formRef = ref() - -// 琛ㄥ崟鏁版嵁 -let form = ref({ - purchaseLedgerNo: '', - salesContractNo: '', - supplierName: '', - projectName: '', - issUer: '', - issueDate: '', - enterDate: '', - invoiceAmount: '', - invoiceNumber: '' -}) - -// 浜у搧鏁版嵁 -const productData = ref([]) - -// 鏃ユ湡閫夋嫨鍣ㄧ姸鎬� -const showIssueDatePicker = ref(false) -const showCreateTimePicker = ref(false) -const currentIssueDate = ref([new Date().getFullYear(), new Date().getMonth() + 1, new Date().getDate()]) -const currentCreateTime = ref([new Date().getFullYear(), new Date().getMonth() + 1, new Date().getDate()]) - -// 鎻愪氦鐘舵�� -const submitting = ref(false) - -// 杩斿洖涓婁竴椤� -const goBack = () => { - // 娓呯悊鏈湴瀛樺偍鐨勬暟鎹� - uni.removeStorageSync('editData'); - uni.navigateBack() +// 鏇挎崲 toast 鏂规硶 +const showToast = (message) => { + uni.showToast({ + title: message, + icon: 'none' + }) } -// 鏍煎紡鍖栨暟瀛� -const formatNumber = (value, precision = 2) => { - if (!value && value !== 0) return '0.00' - return Number(value).toFixed(precision) +const showLoadingToast = (message) => { + uni.showLoading({ + title: message || '鍔犺浇涓�...' + }) } -// 鏉ョエ鏁伴噺鍙樺寲澶勭悊 -const invoiceNumBlur = (row) => { - if (!row.ticketsNum || row.ticketsNum === "") { - row.ticketsNum = 0; - } - if (Number(row.ticketsNum) > Number(row.tempFutureTickets)) { - showToast('鏈鏉ョエ鏁颁笉寰楀ぇ浜庢湭鏉ョエ鏁�'); - row.ticketsNum = 0; - return; - } - // 璁$畻鏈鏉ョエ閲戦 - row.ticketsAmount = (row.ticketsNum * row.taxInclusiveUnitPrice).toFixed(2) - // 璁$畻鏈潵绁ㄦ暟 - row.futureTickets = (row.tempFutureTickets - row.ticketsNum).toFixed(2) - // 璁$畻鏈潵绁ㄩ噾棰� - row.futureTicketsAmount = (row.tempFutureTicketsAmount - row.ticketsAmount).toFixed(2) - calculateinvoiceAmount(); +const closeToast = () => { + uni.hideLoading() } - -// 鏉ョエ閲戦鍙樺寲澶勭悊 -const invoiceAmountBlur = (row) => { - if (!row.ticketsAmount) { - row.ticketsAmount = 0; - } - // 璁$畻鏄惁瓒呰繃鏉ョエ鎬婚噾棰� - if (row.ticketsAmount > row.tempFutureTicketsAmount) { - showToast('鏈鏉ョエ閲戦涓嶅緱澶т簬鏈潵绁ㄩ噾棰�'); - row.ticketsAmount = 0; - } - // 璁$畻鏈鏉ョエ鏁� - row.ticketsNum = Number( - (row.ticketsAmount / row.taxInclusiveUnitPrice).toFixed(2) - ); - // 璁$畻鏈潵绁ㄦ暟 - row.futureTickets = (row.tempFutureTickets - row.ticketsNum).toFixed(2) - // 璁$畻鏈潵绁ㄩ噾棰� - row.futureTicketsAmount = (row.tempFutureTicketsAmount - row.ticketsAmount).toFixed(2) - calculateinvoiceAmount(); -} - -const calculateinvoiceAmount = () => { - let invoiceAmountTotal = 0; - productData.value.forEach((item) => { - if (item.ticketsAmount) { - invoiceAmountTotal += Number(item.ticketsAmount); - } - }); - form.value.invoiceAmount = invoiceAmountTotal.toFixed(2); -}; - -// 鏉ョエ鏃ユ湡纭 -const onIssueDateConfirm = ({ selectedValues }) => { - form.value.issueDate = selectedValues.join('-'); - currentIssueDate.value = selectedValues; - showIssueDatePicker.value = false; -}; - -// 褰曞叆鏃ユ湡纭 -const onCreateTimeConfirm = (value) => { - try { - // 澶勭悊涓嶅悓鐨勫�兼牸寮� - let year, month, day; - - if (Array.isArray(value)) { - // 鏁扮粍鏍煎紡 [year, month, day] - [year, month, day] = value; - } else if (value && typeof value === 'object') { - // Date瀵硅薄鏍煎紡 - year = value.getFullYear(); - month = value.getMonth() + 1; - day = value.getDate(); - } else { - // 鍏朵粬鏍煎紡锛屼娇鐢ㄥ綋鍓嶆棩鏈� - const now = new Date(); - year = now.getFullYear(); - month = now.getMonth() + 1; - day = now.getDate(); - } - - form.value.enterDate = `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`; - form.value.issueDate = `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`; - showCreateTimePicker.value = false; - } catch (error) { - console.error('鏃ユ湡澶勭悊閿欒:', error); - showToast('鏃ユ湡閫夋嫨澶辫触锛岃閲嶈瘯'); - } -} - -// 鏍煎紡鍖栨棩鏈� -const formatDate = (date) => { - const year = date.getFullYear() - const month = String(date.getMonth() + 1).padStart(2, '0') - const day = String(date.getDate()).padStart(2, '0') - return `${year}-${month}-${day}` -} - -// 鑾峰彇浜у搧鍒楄〃 -const getProductList = async () => { - try { - showLoadingToast('鍔犺浇涓�...') - const res = await getPurchaseNoById({ id: editData.value.id }) - form.value.purchaseLedgerNo = res.data.purchaseContractNumber; - form.value.invoiceAmount = res.data.invoiceAmount; - form.value.invoiceNumber = res.data.invoiceNumber; - const data = await getInfo({ id: editData.value.id }); - productData.value = data.data.productData; - form.value.salesContractNo = data.data.salesContractNo; - form.value.projectName = data.data.projectName; - form.value.supplierName = data.data.supplierName; - form.value.productData = data.data.productData; - // 璁剧疆榛樿褰曞叆浜� - form.value.issUer = userStore.nickName - - // 璁剧疆榛樿鏃ユ湡 - const today = new Date() - form.value.enterDate = formatDate(today) - form.value.issueDate = formatDate(today) - - closeToast() - } catch (error) { - closeToast() - showToast('鑾峰彇浜у搧鍒楄〃澶辫触') - } -} - -// 鎻愪氦琛ㄥ崟 -const submitForm = async () => { - try { - submitting.value = true - - // 楠岃瘉浜у搧鏁版嵁 - if (productData.value.length === 0) { - showToast('璇峰厛娣诲姞浜у搧淇℃伅') - return - } - - // 楠岃瘉鏉ョエ鏁版嵁 - const hasInvoiceData = productData.value.some(item => { - const num = parseFloat(item.ticketsNum) || 0 - const amount = parseFloat(item.ticketsAmount) || 0 - return num > 0 || amount > 0 - }) - - if (!hasInvoiceData) { - showToast('璇疯嚦灏戣緭鍏ヤ竴涓骇鍝佺殑鏉ョエ淇℃伅') - return - } - - const submitData = { - ...form.value, - productData: productData.value - } - - await addOrUpdateRegistration(submitData) - showToast('鎻愪氦鎴愬姛') - - // 杩斿洖涓婁竴椤� - setTimeout(() => { - goBack() - }, 800) - - } catch (error) { - showToast('鎻愪氦澶辫触锛岃閲嶈瘯') - } finally { - submitting.value = false - } -} - -// 椤甸潰鍔犺浇鏃跺垵濮嬪寲鏁版嵁 -onMounted(() => { - // 浠庨〉闈㈠弬鏁版垨缂撳瓨涓幏鍙栭攢鍞悎鍚屼俊鎭� - const contractInfo = uni.getStorageSync('editData') - if (contractInfo) { - editData.value = JSON.parse(contractInfo); - const contract = JSON.parse(contractInfo) - form.value.purchaseLedgerNo = contract.purchaseLedgerNo || '' - form.value.salesContractNo = contract.salesContractNo || '' - form.value.supplierName = contract.supplierName || '' - form.value.projectName = contract.projectName || '' - form.value.invoiceAmount = contract.invoiceAmount || '' - form.value.invoiceNumber = contract.invoiceNumber || '' - form.value.purchaseLedgerId = contract.id || '' - - // 鑾峰彇浜у搧鍒楄〃 - getProductList() - } -}) </script> <style scoped lang="scss"> -- Gitblit v1.9.3