From 8f6d0cd40b9a289ed650c33845f8bf23e1190bb6 Mon Sep 17 00:00:00 2001 From: dxc Date: Sat, 28 Feb 2026 09:10:51 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=87=87=E8=B4=AD=E4=BB=B6?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E9=87=91=E9=A2=9D=E6=98=BE=E7=A4=BA=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=9D=83=E9=99=90=E7=AE=A1=E7=90=86=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E9=9D=9E=E5=AD=97=E6=AE=B5=E7=BA=A7=E5=86=85=E5=AE=B9?= =?UTF-8?q?=E5=8F=AF=E8=A7=81=E4=B8=8E=E5=8F=AF=E7=BC=96=E8=BE=91=E8=81=94?= =?UTF-8?q?=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- inventory-web/src/views/stock/inbound/buy.vue | 149 +++++++++++++----- .../src/views/system/PermissionConfig.vue | 7 +- 2 files changed, 119 insertions(+), 37 deletions(-) diff --git a/inventory-web/src/views/stock/inbound/buy.vue b/inventory-web/src/views/stock/inbound/buy.vue index 5747666..82058a1 100644 --- a/inventory-web/src/views/stock/inbound/buy.vue +++ b/inventory-web/src/views/stock/inbound/buy.vue @@ -420,17 +420,21 @@
商务与采购信息
+ - + - - - + + + + + + @@ -439,13 +443,49 @@ - - - - - - + + + + + + + + + + + + + + + + + + + + { if(formRef.value) formRef.value.clearValidate('batch_number') } } -// 价格联动计算 +// 价格联动计算 (精确到小数点后2位,并支持空值) const updatePrices = (source: string) => { const taxMultiplier = 1 + (form.tax_rate || 0) / 100; if (source === 'pre') { - form.post_tax_unit_price = Number((form.unit_price * taxMultiplier).toFixed(4)); + if (form.unit_price !== undefined && form.unit_price !== null) { + form.post_tax_unit_price = Number((form.unit_price * taxMultiplier).toFixed(2)); + } else { + form.post_tax_unit_price = undefined; + } } else if (source === 'post') { - form.unit_price = Number((form.post_tax_unit_price / taxMultiplier).toFixed(4)); + if (form.post_tax_unit_price !== undefined && form.post_tax_unit_price !== null) { + form.unit_price = Number((form.post_tax_unit_price / taxMultiplier).toFixed(2)); + } else { + form.unit_price = undefined; + } } else if (source === 'tax') { - form.post_tax_unit_price = Number((form.unit_price * taxMultiplier).toFixed(4)); + if (form.unit_price !== undefined && form.unit_price !== null) { + form.post_tax_unit_price = Number((form.unit_price * taxMultiplier).toFixed(2)); + } + } + + if (form.in_quantity !== undefined && form.unit_price !== undefined && form.unit_price !== null) { + form.total_price = Number((form.in_quantity * form.unit_price).toFixed(2)); + } else { + form.total_price = undefined; } - form.total_price = Number((form.in_quantity * form.unit_price).toFixed(4)); } -watch(() => [form.in_quantity, form.unit_price], () => { - form.total_price = Number((form.in_quantity * form.unit_price).toFixed(4)); - // 同时更新税后单价 - const taxMultiplier = 1 + (form.tax_rate || 0) / 100; - form.post_tax_unit_price = Number((form.unit_price * taxMultiplier).toFixed(4)); +watch(() => [form.in_quantity, form.unit_price], () => { + if (form.unit_price !== undefined && form.unit_price !== null) { + form.total_price = Number((form.in_quantity * form.unit_price).toFixed(2)); + // 同时更新含税单价 + const taxMultiplier = 1 + (form.tax_rate || 0) / 100; + form.post_tax_unit_price = Number((form.unit_price * taxMultiplier).toFixed(2)); + } else { + form.total_price = undefined; + form.post_tax_unit_price = undefined; + } }) const fetchData = async () => { @@ -1114,17 +1175,20 @@ const handleUpdate = (row: any) => { unit: row.unit, material_type: row.material_type, sku: row.sku, barcode: row.barcode, in_date: row.inbound_date, warehouse_location: row.warehouse_loc, status: row.status, inspection_status: row.inspection_status, in_quantity: Number(row.qty_inbound), stock_quantity: Number(row.qty_stock), available_quantity: Number(row.qty_available), - unit_price: Number(row.unit_price), total_price: Number(row.total_price), + unit_price: (row.unit_price !== null && row.unit_price !== undefined) ? Number(row.unit_price) : undefined, + total_price: (row.total_price !== null && row.total_price !== undefined) ? Number(row.total_price) : undefined, tax_rate: Number(row.tax_rate), currency: row.currency, exchange_rate: Number(row.exchange_rate), supplier_name: row.supplier_name, purchaser: row.purchaser, purchaser_email: row.purchaser_email, source_link: row.source_link, detail_link: row.detail_link, arrival_photo: row.arrival_photo || [], inspection_report: row.inspection_report || [] }) - // 计算税后单价 - const taxMultiplier = 1 + (form.tax_rate || 0) / 100; - form.post_tax_unit_price = Number((form.unit_price * taxMultiplier).toFixed(4)); - + // 计算含税单价 + if (form.unit_price !== undefined && form.unit_price !== null) { + const taxMultiplier = 1 + (form.tax_rate || 0) / 100; + form.post_tax_unit_price = Number((form.unit_price * taxMultiplier).toFixed(2)); + } + arrivalFileList.value = form.arrival_photo.map(url => ({ name: url.split('/').pop(), url: getImageUrl(url) })) const reports = form.inspection_report || [] const reportImgs = reports.filter(r => !isExternalLink(r)) @@ -1147,12 +1211,12 @@ const submitForm = async () => { const onlyImages = finalReportList.filter(item => !isExternalLink(item)) if (inspection_report_url.value) onlyImages.push(inspection_report_url.value) - const payload = { - ...form, - inspection_report: onlyImages, - in_quantity: Number(form.in_quantity), - unit_price: Number(form.unit_price), - post_tax_unit_price: Number(form.post_tax_unit_price) + const payload = { + ...form, + inspection_report: onlyImages, + in_quantity: Number(form.in_quantity || 0), + unit_price: Number(form.unit_price || 0), + post_tax_unit_price: Number(form.post_tax_unit_price || 0) } try { if (dialogStatus.value === 'create') { @@ -1319,14 +1383,22 @@ const resetForm = () => { id: undefined, base_id: undefined, company_name: '', material_name: '', spec_model: '', category: '', unit: '', material_type: '', sku: '', barcode: '', in_date: '', serial_number: '', batch_number: '', status: '在库', inspection_status: '未检', in_quantity: 1, stock_quantity: 1, available_quantity: 1, warehouse_location: '', - unit_price: 0, total_price: 0, + unit_price: undefined, post_tax_unit_price: undefined, total_price: undefined, tax_rate: 0, currency: 'CNY', exchange_rate: 1.00, supplier_name: '', purchaser: '', purchaser_email: '', source_link: '', detail_link: '', arrival_photo: [], inspection_report: [], print_copies: 1 }) } const getStatusType = (status: string) => { const map: any = {'在库': 'success', '出库': 'info', '损耗': 'danger'}; return map[status] || 'warning' } -const formatMoney = (val: any, currency = '¥') => { const num = Number(val); return isNaN(num) ? '-' : `${currency} ${num.toFixed(2)}` } + +// 列表金额显示增加千分位处理,并保留2位小数 +const formatMoney = (val: any, currency = '¥') => { + const num = Number(val); + if (isNaN(num)) return '-'; + const parts = num.toFixed(2).split('.'); + parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); + return `${currency} ${parts.join('.')}`; +} onMounted(() => { // 先根据权限初始化列显示状态 @@ -1511,6 +1583,11 @@ onMounted(() => { .camera-card:hover { border-color: #409EFF; color: #409EFF; } .camera-card .text { font-size: 12px; margin-top: 5px; } .camera-card .el-icon { font-size: 24px; } + +/* 自定义千分位无箭头输入框样式,用于强迫症优化显示 */ +:deep(.el-input-number .el-input__inner) { + text-align: left; +} + \ No newline at end of file diff --git a/inventory-web/src/views/system/PermissionConfig.vue b/inventory-web/src/views/system/PermissionConfig.vue index 403a684..5a3e924 100644 --- a/inventory-web/src/views/system/PermissionConfig.vue +++ b/inventory-web/src/views/system/PermissionConfig.vue @@ -308,6 +308,11 @@ const handleReadChange = (val: boolean, row: PermissionNode) => { // 如果开启可读,默认全选字段 (提升体验) // row.checkedElements = row.elements.map(e => e.code) // updateCheckAllStatus(row) + + // 【新增功能】如果没有字段级控制,且存在操作权限,则自动联动勾选可编辑 + if ((!row.elements || row.elements.length === 0) && row.operationCode) { + row.hasWrite = true + } } // 联动子菜单:如果父级关闭,子级是否关闭?通常不强制,但可以做 @@ -624,4 +629,4 @@ onMounted(() => { padding: 1px 4px; border-radius: 3px; } - + \ No newline at end of file