From 5d51aeded717c667a22096174168e4e5e59bde39 Mon Sep 17 00:00:00 2001 From: gaoluyang <2820782392@qq.com> Date: 星期五, 22 八月 2025 15:38:57 +0800 Subject: [PATCH] 1.来票登记开发联调 --- src/pages/procurementManagement/invoiceEntry/add.vue | 542 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 542 insertions(+), 0 deletions(-) diff --git a/src/pages/procurementManagement/invoiceEntry/add.vue b/src/pages/procurementManagement/invoiceEntry/add.vue new file mode 100644 index 0000000..6935e92 --- /dev/null +++ b/src/pages/procurementManagement/invoiceEntry/add.vue @@ -0,0 +1,542 @@ +<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> + </van-form> + + <!-- 鏃ユ湡閫夋嫨鍣� --> + <van-popup v-model:show="showIssueDatePicker" position="bottom"> + <van-date-picker + v-model="currentIssueDate" + title="閫夋嫨鏉ョエ鏃ユ湡" + @confirm="onIssueDateConfirm" + @cancel="showIssueDatePicker = false" + /> + </van-popup> + + <van-popup v-model:show="showCreateTimePicker" position="bottom"> + <van-date-picker + v-model="currentCreateTime" + title="閫夋嫨褰曞叆鏃ユ湡" + @confirm="onCreateTimeConfirm" + @cancel="showCreateTimePicker = false" + /> + </van-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"; + +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() +} + +// 鏍煎紡鍖栨暟瀛� +const formatNumber = (value, precision = 2) => { + if (!value && value !== 0) return '0.00' + return Number(value).toFixed(precision) +} + +// 鏉ョエ鏁伴噺鍙樺寲澶勭悊 +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 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(() => { + uni.navigateBack() + }, 1500) + + } 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"> +.account-detail { + min-height: 100vh; + background: #f8f9fa; + padding-bottom: 5rem; +} + +.empty-state { + padding: 40px 0; +} + +.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-list { + .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; + margin-bottom: 1rem; + } +} + +.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-title { + display: flex; + align-items: center; +} + +.product-productCategory { + margin-left: 0.5rem; + font-size: 0.875rem; + font-weight: 500; + color: #333; +} + +.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; +} +// 鍝嶅簲寮忚皟鏁� +@media (max-width: 768px) { + .submit-section { + padding: 12px; + } +} +</style> -- Gitblit v1.9.3