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 @@
商务与采购信息
+
-
+
{{ item.value }}{{ item.desc }}
-
-
-
+
+
+
+
+
+
@@ -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