From 78f67775cd8d880dacd5e8d5be6e17cc9fcbf77c Mon Sep 17 00:00:00 2001
From: liding <756868258@qq.com>
Date: 星期二, 26 五月 2026 14:53:07 +0800
Subject: [PATCH] feat(forms): 统一表单创建时间和编号生成逻辑
---
src/views/procurementManagement/qualityInspection/index.vue | 30
src/views/procurementManagement/purchaseOrder/index.vue | 16
src/views/basicData/parameterMaintenance/index.vue | 12
src/views/financialManagement/receivable/receipt.vue | 18
src/views/salesManagement/salesLedger/index.vue | 4769 +++++++++++++++++++++++++++++---------------------------
src/views/financialManagement/receivable/invoiceApply.vue | 21
src/views/financialManagement/assets/fixedAssets.vue | 14
src/views/productManagement/productIdentifier/index.vue | 14
src/views/financialManagement/payable/paymentApply.vue | 34
src/views/procurementManagement/procurementPlan/index.vue | 14
src/views/productionPlan/productionPlan/index.vue | 20
src/views/financialManagement/assets/intangibleAssets.vue | 14
src/views/safeProduction/safetyTrainingAssessment/index.vue | 18
src/views/safeProduction/dangerInvestigation/index.vue | 2
14 files changed, 2,641 insertions(+), 2,355 deletions(-)
diff --git a/src/views/basicData/parameterMaintenance/index.vue b/src/views/basicData/parameterMaintenance/index.vue
index 2dbf5df..bd73467 100644
--- a/src/views/basicData/parameterMaintenance/index.vue
+++ b/src/views/basicData/parameterMaintenance/index.vue
@@ -50,7 +50,7 @@
prop="paramCode">
<el-input v-model="formData.paramCode"
disabled
- placeholder="鑷姩鐢熸垚" />
+ placeholder="淇濆瓨鍚庤嚜鍔ㄧ敓鎴�" />
</el-form-item>
<el-form-item label="鍙傛暟鍚嶇О"
prop="paramName">
@@ -82,6 +82,14 @@
value="2" />
</el-select>
</el-form-item> -->
+ <el-form-item label="鍒涘缓鏃堕棿"
+ prop="createTime">
+ <el-date-picker v-model="formData.createTime"
+ type="date"
+ placeholder="閫夋嫨鏃ユ湡"
+ value-format="YYYY-MM-DD"
+ style="width: 100%" />
+ </el-form-item>
<el-form-item label="鍗曚綅"
prop="unit">
<el-input v-model="formData.unit"
@@ -341,6 +349,7 @@
remark: "",
isRequired: 0,
paramFormat: "",
+ createTime: "",
});
const rules = reactive({
paramName: [{ required: true, message: "璇疯緭鍏ュ弬鏁板悕绉�", trigger: "blur" }],
@@ -519,6 +528,7 @@
formData.unit = "";
formData.remark = "";
formData.isRequired = 0;
+ formData.createTime = new Date().toISOString().split("T")[0];
dialogVisible.value = true;
};
diff --git a/src/views/financialManagement/assets/fixedAssets.vue b/src/views/financialManagement/assets/fixedAssets.vue
index 24b4cc3..de0f8c8 100644
--- a/src/views/financialManagement/assets/fixedAssets.vue
+++ b/src/views/financialManagement/assets/fixedAssets.vue
@@ -82,7 +82,7 @@
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="璧勪骇缂栧彿" prop="assetCode">
- <el-input v-model="form.assetCode" placeholder="绯荤粺鑷姩鐢熸垚" disabled />
+ <el-input v-model="form.assetCode" placeholder="淇濆瓨鍚庤嚜鍔ㄧ敓鎴�" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
@@ -175,6 +175,13 @@
</el-form-item>
</el-col>
</el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="鍒涘缓鏃堕棿" prop="createTime">
+ <el-date-picker v-model="form.createTime" type="date" placeholder="閫夋嫨鏃ユ湡" value-format="YYYY-MM-DD" style="width: 100%;" />
+ </el-form-item>
+ </el-col>
+ </el-row>
<el-form-item label="澶囨敞" prop="remark">
<el-input v-model="form.remark" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ娉�" />
</el-form-item>
@@ -258,6 +265,7 @@
keeper: "",
status: "in_use",
remark: "",
+ createTime: "",
});
const form = reactive({
@@ -356,16 +364,14 @@
getTableData();
};
-const buildAssetCode = () => `GD${Date.now().toString().slice(-10)}`;
-
const add = () => {
isEdit.value = false;
isView.value = false;
currentId.value = null;
dialogTitle.value = "鏂板鍥哄畾璧勪骇";
Object.assign(form, createDefaultForm(), {
- assetCode: buildAssetCode(),
purchaseDate: new Date().toISOString().split('T')[0],
+ createTime: new Date().toISOString().split('T')[0],
});
dialogVisible.value = true;
};
diff --git a/src/views/financialManagement/assets/intangibleAssets.vue b/src/views/financialManagement/assets/intangibleAssets.vue
index 4642166..167ae6b 100644
--- a/src/views/financialManagement/assets/intangibleAssets.vue
+++ b/src/views/financialManagement/assets/intangibleAssets.vue
@@ -83,7 +83,7 @@
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="璧勪骇缂栧彿" prop="assetCode">
- <el-input v-model="form.assetCode" placeholder="绯荤粺鑷姩鐢熸垚" disabled />
+ <el-input v-model="form.assetCode" placeholder="淇濆瓨鍚庤嚜鍔ㄧ敓鎴�" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
@@ -162,6 +162,13 @@
<el-option label="闂茬疆" value="idle" />
<el-option label="宸叉憡閿�瀹屾瘯" value="amortized" />
</el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="鍒涘缓鏃堕棿" prop="createTime">
+ <el-date-picker v-model="form.createTime" type="date" placeholder="閫夋嫨鏃ユ湡" value-format="YYYY-MM-DD" style="width: 100%;" />
</el-form-item>
</el-col>
</el-row>
@@ -250,6 +257,7 @@
status: "in_use",
description: "",
remark: "",
+ createTime: "",
});
const form = reactive({
@@ -354,16 +362,14 @@
getTableData();
};
-const buildAssetCode = () => `WX${Date.now().toString().slice(-10)}`;
-
const add = () => {
isEdit.value = false;
isView.value = false;
currentId.value = null;
dialogTitle.value = "鏂板鏃犲舰璧勪骇";
Object.assign(form, createDefaultForm(), {
- assetCode: buildAssetCode(),
acquisitionDate: new Date().toISOString().split('T')[0],
+ createTime: new Date().toISOString().split('T')[0],
});
dialogVisible.value = true;
};
diff --git a/src/views/financialManagement/payable/paymentApply.vue b/src/views/financialManagement/payable/paymentApply.vue
index 3937e96..b83eb58 100644
--- a/src/views/financialManagement/payable/paymentApply.vue
+++ b/src/views/financialManagement/payable/paymentApply.vue
@@ -97,7 +97,7 @@
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="鐢宠鍗曞彿" prop="invoiceApplicationNo">
- <el-input v-model="form.invoiceApplicationNo" placeholder="绯荤粺鑷姩鐢熸垚" disabled />
+ <el-input v-model="form.invoiceApplicationNo" placeholder="淇濆瓨鍚庤嚜鍔ㄧ敓鎴�" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
@@ -158,6 +158,18 @@
</el-row>
<el-row :gutter="20">
<el-col :span="12">
+ <el-form-item label="鍒涘缓鏃堕棿" prop="createTime">
+ <el-date-picker
+ v-model="form.createTime"
+ type="date"
+ placeholder="閫夋嫨鏃ユ湡"
+ value-format="YYYY-MM-DD"
+ style="width: 100%;"
+ :disabled="isView"
+ />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
<el-form-item label="浠樻閲戦" prop="paymentAmount">
<el-input-number
v-model="form.paymentAmount"
@@ -217,7 +229,7 @@
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="浠樻鍗曞彿" prop="paymentNumber">
- <el-input v-model="paymentForm.paymentNumber" placeholder="绯荤粺鑷姩鐢熸垚" disabled />
+ <el-input v-model="paymentForm.paymentNumber" placeholder="淇濆瓨鍚庤嚜鍔ㄧ敓鎴�" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
@@ -245,6 +257,17 @@
</el-col>
</el-row>
<el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="鍒涘缓鏃堕棿" prop="createTime">
+ <el-date-picker
+ v-model="paymentForm.createTime"
+ type="date"
+ placeholder="閫夋嫨鏃ユ湡"
+ value-format="YYYY-MM-DD"
+ style="width: 100%;"
+ />
+ </el-form-item>
+ </el-col>
<el-col :span="12">
<el-form-item label="浠樻閲戦" prop="paymentAmount">
<el-input-number
@@ -407,6 +430,7 @@
bankAccount: "",
bankName: "",
remark: "",
+ createTime: "",
});
const paymentRules = {
@@ -429,6 +453,7 @@
stockInRecordIds: [],
inboundBatches: "",
status: 0,
+ createTime: "",
});
const rules = {
@@ -563,6 +588,7 @@
stockInRecordIds,
inboundBatches: formatInboundBatches(row.inboundBatches),
status: normalizeStatus(row.status),
+ createTime: row.createTime ?? "",
});
};
@@ -580,6 +606,7 @@
remark: row.remark ?? "",
status: statusOverride !== undefined ? statusOverride : normalizeStatus(row.status),
paymentAmount: Number(row.paymentAmount ?? row.amount ?? 0),
+ createTime: row.createTime,
});
const buildSubmitPayload = (forUpdate = false) => {
@@ -703,6 +730,7 @@
stockInRecordIds: [],
inboundBatches: "",
status: 0,
+ createTime: new Date().toISOString().split("T")[0],
});
inboundBatchList.value = [];
inboundBatchOptions.value = [];
@@ -781,6 +809,7 @@
bankAccount: row.bankAccountNum ?? row.bankAccount ?? "",
bankName: row.bankAccountName ?? row.bankName ?? "",
remark: "",
+ createTime: new Date().toISOString().split("T")[0],
});
paymentDialogVisible.value = true;
nextTick(() => {
@@ -800,6 +829,7 @@
paymentAmount: paymentForm.paymentAmount,
paymentNumber: paymentForm.paymentNumber || "",
remark: paymentForm.remark || "",
+ createTime: paymentForm.createTime,
})
.then((res) => {
if (res.code === 200) {
diff --git a/src/views/financialManagement/receivable/invoiceApply.vue b/src/views/financialManagement/receivable/invoiceApply.vue
index 31b6345..d5ab6dc 100644
--- a/src/views/financialManagement/receivable/invoiceApply.vue
+++ b/src/views/financialManagement/receivable/invoiceApply.vue
@@ -98,7 +98,7 @@
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="鐢宠鍗曞彿" prop="applyCode">
- <el-input v-model="form.applyCode" placeholder="绯荤粺鑷姩鐢熸垚" disabled />
+ <el-input v-model="form.applyCode" placeholder="淇濆瓨鍚庤嚜鍔ㄧ敓鎴�" disabled />
</el-form-item>
</el-col>
</el-row>
@@ -180,6 +180,20 @@
<el-form-item label="鐢宠鏃ユ湡" prop="applyDate">
<el-date-picker
v-model="form.applyDate"
+ type="date"
+ placeholder="閫夋嫨鏃ユ湡"
+ value-format="YYYY-MM-DD"
+ style="width: 100%;"
+ :disabled="isView"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="鍒涘缓鏃堕棿" prop="createTime">
+ <el-date-picker
+ v-model="form.createTime"
type="date"
placeholder="閫夋嫨鏃ユ湡"
value-format="YYYY-MM-DD"
@@ -524,6 +538,7 @@
applyDate: "",
content: "",
remark: "",
+ createTime: "",
});
const rules = {
@@ -714,7 +729,7 @@
isView.value = false;
dialogTitle.value = "鏂板寮�绁ㄧ敵璇�";
Object.assign(form, {
- applyCode: "KP" + Date.now().toString().slice(-8),
+ applyCode: "",
customerId: "",
outboundBatchNos: [],
outboundBatches: "",
@@ -724,6 +739,7 @@
applyDate: new Date().toISOString().split("T")[0],
content: "",
remark: "",
+ createTime: new Date().toISOString().split("T")[0],
});
outboundBatchList.value = [];
outboundBatchOptions.value = [];
@@ -752,6 +768,7 @@
invoiceAmount: form.amount,
taxRate: form.taxRate,
status: 0,
+ createTime: form.createTime,
};
if (forUpdate) {
payload.id = currentId.value;
diff --git a/src/views/financialManagement/receivable/receipt.vue b/src/views/financialManagement/receivable/receipt.vue
index 6ddb3fe..1c84594 100644
--- a/src/views/financialManagement/receivable/receipt.vue
+++ b/src/views/financialManagement/receivable/receipt.vue
@@ -111,7 +111,7 @@
<el-form-item label="鏀舵鍗曞彿"
prop="receiptCode">
<el-input v-model="form.receiptCode"
- placeholder="绯荤粺鑷姩鐢熸垚"
+ placeholder="淇濆瓨鍚庤嚜鍔ㄧ敓鎴�"
disabled />
</el-form-item>
</el-col>
@@ -191,6 +191,17 @@
:label="item.label"
:value="item.value" />
</el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鍒涘缓鏃堕棿"
+ prop="createTime">
+ <el-date-picker v-model="form.createTime"
+ type="date"
+ placeholder="閫夋嫨鏃ユ湡"
+ value-format="YYYY-MM-DD"
+ style="width: 100%;"
+ :disabled="isView" />
</el-form-item>
</el-col>
</el-row>
@@ -379,6 +390,7 @@
stockOutRecordIds: [],
outboundBatches: "",
remark: "",
+ createTime: "",
});
const rules = {
@@ -658,6 +670,7 @@
collectionNumber: form.receiptCode || "",
remark: form.remark || "",
stockOutRecordIds: (form.stockOutRecordIds || []).join(","),
+ createTime: form.createTime,
};
if (forUpdate) {
payload.id = currentId.value;
@@ -746,7 +759,7 @@
isView.value = false;
dialogTitle.value = "鏂板鏀舵";
Object.assign(form, {
- receiptCode: "SK" + Date.now().toString().slice(-8),
+ receiptCode: "",
customerId: "",
receiptDate: new Date().toISOString().split("T")[0],
amount: 0,
@@ -754,6 +767,7 @@
stockOutRecordIds: [],
outboundBatches: "",
remark: "",
+ createTime: new Date().toISOString().split("T")[0],
});
outboundBatchList.value = [];
outboundBatchOptions.value = [];
diff --git a/src/views/procurementManagement/procurementPlan/index.vue b/src/views/procurementManagement/procurementPlan/index.vue
index 2232272..5be6ffe 100644
--- a/src/views/procurementManagement/procurementPlan/index.vue
+++ b/src/views/procurementManagement/procurementPlan/index.vue
@@ -147,7 +147,7 @@
<el-form-item label="缂栫爜"
prop="code">
<el-input v-model="formData.code"
- placeholder="绯荤粺鑷姩鐢熸垚"
+ placeholder="淇濆瓨鍚庤嚜鍔ㄧ敓鎴�"
disabled />
</el-form-item>
</el-col>
@@ -182,8 +182,12 @@
</el-form-item>
</el-col>
<el-col :span="12">
- <el-form-item label="鏄惁绯荤粺棰勭疆">
- <el-checkbox v-model="formData.isSystemPreset">鏄�</el-checkbox>
+ <el-form-item label="鍒涘缓鏃堕棿" prop="createTime">
+ <el-date-picker v-model="formData.createTime"
+ type="date"
+ placeholder="閫夋嫨鏃ユ湡"
+ value-format="YYYY-MM-DD"
+ style="width: 100%" />
</el-form-item>
</el-col>
</el-row>
@@ -415,6 +419,7 @@
status: "",
isSystemPreset: false,
formula: "",
+ createTime: "",
// 璁$畻鍙傛暟
considerExistingStock: false,
warehouseControl: false,
@@ -505,8 +510,7 @@
const handleAdd = () => {
dialogType.value = "add";
resetForm();
- // 鑷姩鐢熸垚缂栫爜
- formData.code = "CGJH" + String(Date.now()).slice(-4);
+ formData.createTime = new Date().toISOString().split("T")[0];
dialogVisible.value = true;
};
diff --git a/src/views/procurementManagement/purchaseOrder/index.vue b/src/views/procurementManagement/purchaseOrder/index.vue
index 7e56cb4..71d6caa 100644
--- a/src/views/procurementManagement/purchaseOrder/index.vue
+++ b/src/views/procurementManagement/purchaseOrder/index.vue
@@ -56,6 +56,13 @@
<el-option label="渚涘簲鍟咮" value="渚涘簲鍟咮" />
</el-select>
</el-form-item>
+ <el-form-item label="鍒涘缓鏃堕棿">
+ <el-date-picker v-model="formData.createTime"
+ type="date"
+ placeholder="閫夋嫨鏃ユ湡"
+ value-format="YYYY-MM-DD"
+ style="width: 100%" />
+ </el-form-item>
<el-form-item label="澶囨敞">
<el-input v-model="formData.remark" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�" />
</el-form-item>
@@ -81,7 +88,8 @@
const formData = reactive({
supplierName: '',
- remark: ''
+ remark: '',
+ createTime: ''
})
const mockData = [
@@ -124,7 +132,7 @@
if (type === 'edit' && row.id) {
Object.assign(formData, { supplierName: row.supplierName, remark: row.remark })
} else {
- Object.assign(formData, { supplierName: '', remark: '' })
+ Object.assign(formData, { supplierName: '', remark: '', createTime: new Date().toISOString().split('T')[0] })
}
dialogVisible.value = true
}
@@ -133,11 +141,11 @@
if (dialogType.value === 'add') {
const newOrder = {
id: Date.now(),
- orderNo: `PO${Date.now()}`,
+ orderNo: '',
supplierName: formData.supplierName,
status: 'draft',
totalAmount: 0,
- createTime: new Date().toLocaleString(),
+ createTime: formData.createTime,
remark: formData.remark
}
tableData.value.unshift(newOrder)
diff --git a/src/views/procurementManagement/qualityInspection/index.vue b/src/views/procurementManagement/qualityInspection/index.vue
index 7628839..fde8c68 100644
--- a/src/views/procurementManagement/qualityInspection/index.vue
+++ b/src/views/procurementManagement/qualityInspection/index.vue
@@ -116,6 +116,18 @@
<el-input v-model="formData.inspector" placeholder="璇疯緭鍏ヨ川妫�鍛樺鍚�" />
</el-form-item>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="鍒涘缓鏃堕棿">
+ <el-date-picker v-model="formData.createTime"
+ type="date"
+ placeholder="閫夋嫨鏃ユ湡"
+ value-format="YYYY-MM-DD"
+ style="width: 100%" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+
<el-form-item label="澶囨敞">
<el-input v-model="formData.remark" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�" />
</el-form-item>
@@ -144,7 +156,8 @@
supplierName: '',
products: [],
inspector: '',
- remark: ''
+ remark: '',
+ createTime: ''
})
const mockData = [
@@ -193,12 +206,13 @@
remark: row.remark
})
} else {
- Object.assign(formData, {
- arrivalNo: '',
- supplierName: '',
+ Object.assign(formData, {
+ arrivalNo: '',
+ supplierName: '',
products: [],
- inspector: '',
- remark: ''
+ inspector: '',
+ remark: '',
+ createTime: new Date().toISOString().split('T')[0]
})
}
dialogVisible.value = true
@@ -228,13 +242,13 @@
if (dialogType.value === 'add') {
const newInspection = {
id: Date.now(),
- inspectionNo: `QI${Date.now()}`,
+ inspectionNo: '',
arrivalNo: formData.arrivalNo,
supplierName: formData.supplierName,
status: 'pending',
qualifiedQuantity: totalQualified,
unqualifiedQuantity: totalUnqualified,
- inspectionTime: new Date().toLocaleString(),
+ inspectionTime: formData.createTime,
inspector: formData.inspector,
remark: formData.remark
}
diff --git a/src/views/productManagement/productIdentifier/index.vue b/src/views/productManagement/productIdentifier/index.vue
index 94359e4..2eceb31 100644
--- a/src/views/productManagement/productIdentifier/index.vue
+++ b/src/views/productManagement/productIdentifier/index.vue
@@ -239,6 +239,13 @@
<el-form-item label="鏍囪瘑绫诲瀷">
<span>{{ currentProduct.identifierType }}</span>
</el-form-item>
+ <el-form-item label="鍒涘缓鏃堕棿">
+ <el-date-picker v-model="createTime"
+ type="date"
+ placeholder="閫夋嫨鏃ユ湡"
+ value-format="YYYY-MM-DD"
+ style="width: 100%"></el-date-picker>
+ </el-form-item>
<el-form-item label="鐢熸垚鏁伴噺"
prop="generateQuantity">
<el-input-number v-model="generateQuantity"
@@ -442,6 +449,7 @@
const generateQuantity = ref(1);
const codeRule = ref("");
const customPrefix = ref("");
+ const createTime = ref(new Date().toISOString().split('T')[0]);
const newBatchNo = ref("");
const reassignReason = ref("");
const formRef = ref();
@@ -659,9 +667,9 @@
currentProduct.value.batchNo
}_${String(i).padStart(3, "0")}`;
} else if (codeRule.value === "鏃堕棿鎴�+闅忔満鏁�") {
- identifierCode = `TS_${Date.now()}_${Math.floor(Math.random() * 1000)}`;
+ identifierCode = "";
} else if (codeRule.value === "鑷畾涔夎鍒�") {
- identifierCode = `${customPrefix.value || "CUSTOM"}_${Date.now()}_${i}`;
+ identifierCode = "";
}
newIdentifiers.push({
@@ -672,7 +680,7 @@
identifierType: currentProduct.value.identifierType,
identifierCode: identifierCode,
status: "宸茬敓鎴�",
- generateTime: new Date().toLocaleString(),
+ generateTime: createTime.value,
remark: "鎵归噺鐢熸垚",
});
}
diff --git a/src/views/productionPlan/productionPlan/index.vue b/src/views/productionPlan/productionPlan/index.vue
index f4127ae..78d9870 100644
--- a/src/views/productionPlan/productionPlan/index.vue
+++ b/src/views/productionPlan/productionPlan/index.vue
@@ -139,6 +139,12 @@
@change="onBlur"
style="width: 100%" />
</el-form-item>
+ <el-form-item label="鍒涘缓鏃堕棿">
+ <el-date-picker v-model="mergeForm.createTime"
+ type="date"
+ value-format="YYYY-MM-DD"
+ style="width: 100%" />
+ </el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
@@ -173,7 +179,7 @@
prop="mpsNo">
<el-input v-model="form.mpsNo"
disabled
- placeholder="鏂板鍚庤嚜鍔ㄧ敓鎴�" />
+ placeholder="淇濆瓨鍚庤嚜鍔ㄧ敓鎴�" />
</el-form-item>
<el-form-item label="浜у搧鍚嶇О"
prop="productId">
@@ -226,6 +232,14 @@
value-format="YYYY-MM-DD"
style="width: 100%"
placeholder="璇烽�夋嫨鎵胯鏃ユ湡" />
+ </el-form-item>
+ <el-form-item label="鍒涘缓鏃堕棿"
+ prop="createTime">
+ <el-date-picker v-model="form.createTime"
+ type="date"
+ value-format="YYYY-MM-DD"
+ style="width: 100%"
+ placeholder="璇烽�夋嫨鍒涘缓鏃堕棿" />
</el-form-item>
<el-form-item label="澶囨敞"
prop="remark">
@@ -430,6 +444,7 @@
Number(row.qtyRequired || 0) - Number(row.quantityIssued || 0);
mergeForm.planCompleteTime = row.requiredDate || "";
mergeForm.productId = row.productId || "";
+ mergeForm.createTime = new Date().toISOString().split("T")[0];
mergeForm.ids = [row.id];
sumAssignedQuantity.value =
Number(row.qtyRequired || 0) - Number(row.quantityIssued || 0);
@@ -473,6 +488,7 @@
totalAssignedQuantity: 0,
planCompleteTime: "",
productId: "",
+ createTime: "",
});
// 瀵煎叆鐩稿叧
@@ -503,6 +519,7 @@
requiredDate: "",
promisedDeliveryDate: "",
remark: "",
+ createTime: "",
});
const rules = reactive({
productId: [{ required: true, message: "璇烽�夋嫨浜у搧", trigger: "change" }],
@@ -889,6 +906,7 @@
requiredDate: "",
promisedDeliveryDate: "",
remark: "",
+ createTime: new Date().toISOString().split("T")[0],
});
dialogVisible.value = true;
fetchProductOptions();
diff --git a/src/views/safeProduction/dangerInvestigation/index.vue b/src/views/safeProduction/dangerInvestigation/index.vue
index cb09e52..a278058 100644
--- a/src/views/safeProduction/dangerInvestigation/index.vue
+++ b/src/views/safeProduction/dangerInvestigation/index.vue
@@ -160,7 +160,7 @@
<el-form-item label="闅愭偅缂栧彿锛�"
prop="hiddenCode">
<el-input v-model="form.hiddenCode"
- placeholder="鑷姩鐢熸垚"
+ placeholder="淇濆瓨鍚庤嚜鍔ㄧ敓鎴�"
disabled
clearable />
</el-form-item>
diff --git a/src/views/safeProduction/safetyTrainingAssessment/index.vue b/src/views/safeProduction/safetyTrainingAssessment/index.vue
index 2c98308..ff09589 100644
--- a/src/views/safeProduction/safetyTrainingAssessment/index.vue
+++ b/src/views/safeProduction/safetyTrainingAssessment/index.vue
@@ -76,7 +76,21 @@
prop="courseCode">
<el-input v-model="form.courseCode"
disabled
- placeholder="鑷姩鐢熸垚" />
+ placeholder="淇濆瓨鍚庤嚜鍔ㄧ敓鎴�" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="鍒涘缓鏃堕棿"
+ prop="createTime">
+ <el-date-picker style="width: 100%"
+ v-model="form.createTime"
+ value-format="YYYY-MM-DD"
+ format="YYYY-MM-DD"
+ type="date"
+ placeholder="璇烽�夋嫨"
+ clearable />
</el-form-item>
</el-col>
</el-row>
@@ -445,6 +459,7 @@
trainingMode: "", // 鍩硅鏂瑰紡
placeTraining: "", // 鍩硅鍦扮偣
classHour: "", // 璇炬椂
+ createTime: "", // 鍒涘缓鏃堕棿
},
dialogVisible: false,
dialogTitle: "",
@@ -1025,6 +1040,7 @@
trainingMode: "", // 鍩硅鏂瑰紡
placeTraining: "", // 鍩硅鍦扮偣
classHour: "", // 璇炬椂
+ createTime: new Date().toISOString().split("T")[0], // 鍒涘缓鏃堕棿
});
} else if (type === "edit" && row) {
dialogTitle.value = "缂栬緫鍩硅";
diff --git a/src/views/salesManagement/salesLedger/index.vue b/src/views/salesManagement/salesLedger/index.vue
index 2e58391..4c13d3d 100644
--- a/src/views/salesManagement/salesLedger/index.vue
+++ b/src/views/salesManagement/salesLedger/index.vue
@@ -1,42 +1,47 @@
<template>
<div class="app-container">
<div class="search_form">
- <el-form :model="searchForm"
- :inline="true">
+ <el-form :model="searchForm" :inline="true">
<el-form-item label="瀹㈡埛鍚嶇О锛�">
- <el-input v-model="searchForm.customerName"
- placeholder="璇疯緭鍏�"
- clearable
- prefix-icon="Search"
- @change="handleQuery" />
+ <el-input
+ v-model="searchForm.customerName"
+ placeholder="璇疯緭鍏�"
+ clearable
+ prefix-icon="Search"
+ @change="handleQuery"
+ />
</el-form-item>
<el-form-item label="閿�鍞悎鍚屽彿锛�">
- <el-input v-model="searchForm.salesContractNo"
- placeholder="璇疯緭鍏�"
- clearable
- prefix-icon="Search"
- @change="handleQuery" />
+ <el-input
+ v-model="searchForm.salesContractNo"
+ placeholder="璇疯緭鍏�"
+ clearable
+ prefix-icon="Search"
+ @change="handleQuery"
+ />
</el-form-item>
<el-form-item label="椤圭洰鍚嶇О锛�">
- <el-input v-model="searchForm.projectName"
- placeholder="璇疯緭鍏�"
- clearable
- prefix-icon="Search"
- @change="handleQuery" />
+ <el-input
+ v-model="searchForm.projectName"
+ placeholder="璇疯緭鍏�"
+ clearable
+ prefix-icon="Search"
+ @change="handleQuery"
+ />
</el-form-item>
<el-form-item label="褰曞叆鏃ユ湡锛�">
- <el-date-picker v-model="searchForm.entryDate"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- type="daterange"
- placeholder="璇烽�夋嫨"
- clearable
- @change="changeDaterange" />
+ <el-date-picker
+ v-model="searchForm.entryDate"
+ value-format="YYYY-MM-DD"
+ format="YYYY-MM-DD"
+ type="daterange"
+ placeholder="璇烽�夋嫨"
+ clearable
+ @change="changeDaterange"
+ />
</el-form-item>
<el-form-item>
- <el-button type="primary"
- @click="handleQuery"> 鎼滅储
- </el-button>
+ <el-button type="primary" @click="handleQuery"> 鎼滅储 </el-button>
</el-form-item>
</el-form>
</div>
@@ -44,139 +49,131 @@
<div class="actions">
<div></div>
<div>
- <el-button type="primary"
- @click="openForm('add')">
+ <el-button type="primary" @click="openForm('add')">
鏂板鍙拌处
</el-button>
- <el-button type="primary"
- plain
- @click="handleImport">瀵煎叆
+ <el-button type="primary" plain @click="handleImport"
+ >瀵煎叆
</el-button>
<el-button @click="handleOut">瀵煎嚭</el-button>
- <el-button type="danger"
- plain
- @click="handleDelete">鍒犻櫎
- </el-button>
- <el-button type="primary"
- plain
- @click="handlePrint">鎵撳嵃
- </el-button>
+ <el-button type="danger" plain @click="handleDelete">鍒犻櫎 </el-button>
+ <el-button type="primary" plain @click="handlePrint">鎵撳嵃 </el-button>
</div>
</div>
- <el-table :data="tableData"
- border
- v-loading="tableLoading"
- @selection-change="handleSelectionChange"
- :expand-row-keys="expandedRowKeys"
- :row-key="(row) => row.id"
- :row-class-name="tableRowClassName"
- show-summary
- style="width: 100%"
- :summary-method="summarizeMainTable"
- @expand-change="expandChange"
- height="calc(100vh - 18.5em)">
- <el-table-column align="center"
- type="selection"
- width="55"
- fixed="left" />
- <el-table-column type="expand"
- width="60"
- fixed="left">
+ <el-table
+ :data="tableData"
+ border
+ v-loading="tableLoading"
+ @selection-change="handleSelectionChange"
+ :expand-row-keys="expandedRowKeys"
+ :row-key="(row) => row.id"
+ :row-class-name="tableRowClassName"
+ show-summary
+ style="width: 100%"
+ :summary-method="summarizeMainTable"
+ @expand-change="expandChange"
+ height="calc(100vh - 18.5em)"
+ >
+ <el-table-column
+ align="center"
+ type="selection"
+ width="55"
+ fixed="left"
+ />
+ <el-table-column type="expand" width="60" fixed="left">
<template #default="props">
- <el-table :data="props.row.children"
- border
- show-summary
- :summary-method="(param) => summarizeChildrenTable(param, props.row)">
- <el-table-column align="center"
- label="搴忓彿"
- type="index" />
- <el-table-column label="浜у搧澶х被"
- prop="productCategory" />
- <el-table-column label="瑙勬牸鍨嬪彿"
- prop="specificationModel" />
- <el-table-column label="鍗曚綅"
- prop="unit" />
- <el-table-column label="浜у搧鐘舵��"
- width="100px"
- align="center">
+ <el-table
+ :data="props.row.children"
+ border
+ show-summary
+ :summary-method="
+ (param) => summarizeChildrenTable(param, props.row)
+ "
+ >
+ <el-table-column align="center" label="搴忓彿" type="index" />
+ <el-table-column label="浜у搧澶х被" prop="productCategory" />
+ <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
+ <el-table-column label="鍗曚綅" prop="unit" />
+ <el-table-column label="浜у搧鐘舵��" width="100px" align="center">
<template #default="scope">
- <el-tag v-if="scope.row.approveStatus === 1 "
- type="success">鍏呰冻
+ <el-tag v-if="scope.row.approveStatus === 1" type="success"
+ >鍏呰冻
</el-tag>
- <el-tag v-else-if="scope.row.approveStatus === 0 && scope.row.noQuantity === 0"
- type="success">宸插嚭搴�
+ <el-tag
+ v-else-if="
+ scope.row.approveStatus === 0 &&
+ scope.row.noQuantity === 0
+ "
+ type="success"
+ >宸插嚭搴�
</el-tag>
- <el-tag v-else
- type="danger">涓嶈冻
- </el-tag>
+ <el-tag v-else type="danger">涓嶈冻 </el-tag>
</template>
</el-table-column>
- <el-table-column label="鍙戣揣鐘舵��"
- width="140"
- align="center">
+ <el-table-column label="鍙戣揣鐘舵��" width="140" align="center">
<template #default="scope">
- <el-tag :type="getShippingStatusType(scope.row)"
- size="small">
+ <el-tag :type="getShippingStatusType(scope.row)" size="small">
{{ getShippingStatusText(scope.row) }}
</el-tag>
</template>
</el-table-column>
- <el-table-column label="蹇�掑叕鍙�"
- prop="expressCompany"
- show-overflow-tooltip />
- <el-table-column label="蹇�掑崟鍙�"
- prop="expressNumber"
- show-overflow-tooltip />
- <el-table-column label="鍙戣揣杞︾墝"
- minWidth="100px"
- align="center">
+ <el-table-column
+ label="蹇�掑叕鍙�"
+ prop="expressCompany"
+ show-overflow-tooltip
+ />
+ <el-table-column
+ label="蹇�掑崟鍙�"
+ prop="expressNumber"
+ show-overflow-tooltip
+ />
+ <el-table-column label="鍙戣揣杞︾墝" minWidth="100px" align="center">
<template #default="scope">
<div>
- <el-tag type="success"
- v-if="scope.row.shippingCarNumber">{{ scope.row.shippingCarNumber }}
+ <el-tag type="success" v-if="scope.row.shippingCarNumber"
+ >{{ scope.row.shippingCarNumber }}
</el-tag>
- <el-tag v-else
- type="info">-
- </el-tag>
+ <el-tag v-else type="info">- </el-tag>
</div>
</template>
</el-table-column>
- <el-table-column label="鍙戣揣鏃ユ湡"
- minWidth="100px"
- align="center">
+ <el-table-column label="鍙戣揣鏃ユ湡" minWidth="100px" align="center">
<template #default="scope">
<div>
- <div v-if="scope.row.shippingDate">{{ scope.row.shippingDate }}</div>
- <el-tag v-else
- type="info">-
- </el-tag>
+ <div v-if="scope.row.shippingDate">
+ {{ scope.row.shippingDate }}
+ </div>
+ <el-tag v-else type="info">- </el-tag>
</div>
</template>
</el-table-column>
- <el-table-column label="鏁伴噺"
- prop="quantity" />
- <el-table-column label="寰呭彂璐ф暟閲�"
- prop="noQuantity" />
- <el-table-column label="绋庣巼(%)"
- prop="taxRate" />
- <el-table-column label="鍚◣鍗曚环(鍏�)"
- prop="taxInclusiveUnitPrice"
- :formatter="sensitiveAmountFormatter" />
- <el-table-column label="鍚◣鎬讳环(鍏�)"
- prop="taxInclusiveTotalPrice"
- :formatter="sensitiveAmountFormatter" />
- <el-table-column label="涓嶅惈绋庢�讳环(鍏�)"
- prop="taxExclusiveTotalPrice"
- :formatter="sensitiveAmountFormatter" />
+ <el-table-column label="鏁伴噺" prop="quantity" />
+ <el-table-column label="寰呭彂璐ф暟閲�" prop="noQuantity" />
+ <el-table-column label="绋庣巼(%)" prop="taxRate" />
+ <el-table-column
+ label="鍚◣鍗曚环(鍏�)"
+ prop="taxInclusiveUnitPrice"
+ :formatter="sensitiveAmountFormatter"
+ />
+ <el-table-column
+ label="鍚◣鎬讳环(鍏�)"
+ prop="taxInclusiveTotalPrice"
+ :formatter="sensitiveAmountFormatter"
+ />
+ <el-table-column
+ label="涓嶅惈绋庢�讳环(鍏�)"
+ prop="taxExclusiveTotalPrice"
+ :formatter="sensitiveAmountFormatter"
+ />
<!--鎿嶄綔-->
- <el-table-column Width="60px"
- label="鎿嶄綔"
- align="center">
+ <el-table-column Width="60px" label="鎿嶄綔" align="center">
<template #default="scope">
- <el-button link
- type="primary"
- :disabled="!canShip(scope.row)"
- @click="openDeliveryForm(scope.row)">
+ <el-button
+ link
+ type="primary"
+ :disabled="!canShip(scope.row)"
+ @click="openDeliveryForm(scope.row)"
+ >
鍙戣揣
</el-button>
</template>
@@ -184,150 +181,198 @@
</el-table>
</template>
</el-table-column>
- <el-table-column align="center"
- label="搴忓彿"
- type="index"
- width="60" />
- <el-table-column label="閿�鍞悎鍚屽彿"
- prop="salesContractNo"
- width="180"
- show-overflow-tooltip />
- <el-table-column label="瀹㈡埛鍚嶇О"
- prop="customerName"
- width="300"
- show-overflow-tooltip />
- <el-table-column label="涓氬姟鍛�"
- prop="salesman"
- width="100"
- show-overflow-tooltip />
- <el-table-column label="椤圭洰鍚嶇О"
- prop="projectName"
- width="180"
- show-overflow-tooltip />
- <el-table-column label="浠樻鏂瑰紡"
- prop="paymentMethod"
- show-overflow-tooltip />
- <el-table-column label="鍚堝悓閲戦(鍏�)"
- prop="contractAmount"
- width="220"
- show-overflow-tooltip
- :formatter="formattedNumber" />
- <el-table-column label="褰曞叆浜�"
- prop="entryPersonName"
- width="100"
- show-overflow-tooltip />
- <el-table-column label="褰曞叆鏃ユ湡"
- prop="entryDate"
- width="120"
- show-overflow-tooltip />
- <el-table-column label="绛捐鏃ユ湡"
- prop="executionDate"
- width="120"
- show-overflow-tooltip />
- <el-table-column label="浜や粯鏃ユ湡"
- prop="deliveryDate"
- width="120"
- show-overflow-tooltip />
- <el-table-column label="澶囨敞"
- prop="remarks"
- width="200"
- show-overflow-tooltip />
- <el-table-column fixed="right"
- label="鎿嶄綔"
- width="220"
- align="center">
+ <el-table-column align="center" label="搴忓彿" type="index" width="60" />
+ <el-table-column
+ label="閿�鍞悎鍚屽彿"
+ prop="salesContractNo"
+ width="180"
+ show-overflow-tooltip
+ />
+ <el-table-column
+ label="瀹㈡埛鍚嶇О"
+ prop="customerName"
+ width="300"
+ show-overflow-tooltip
+ />
+ <el-table-column
+ label="涓氬姟鍛�"
+ prop="salesman"
+ width="100"
+ show-overflow-tooltip
+ />
+ <el-table-column
+ label="椤圭洰鍚嶇О"
+ prop="projectName"
+ width="180"
+ show-overflow-tooltip
+ />
+ <el-table-column
+ label="浠樻鏂瑰紡"
+ prop="paymentMethod"
+ show-overflow-tooltip
+ />
+ <el-table-column
+ label="鍚堝悓閲戦(鍏�)"
+ prop="contractAmount"
+ width="220"
+ show-overflow-tooltip
+ :formatter="formattedNumber"
+ />
+ <el-table-column
+ label="褰曞叆浜�"
+ prop="entryPersonName"
+ width="100"
+ show-overflow-tooltip
+ />
+ <el-table-column
+ label="褰曞叆鏃ユ湡"
+ prop="entryDate"
+ width="120"
+ show-overflow-tooltip
+ />
+ <el-table-column
+ label="绛捐鏃ユ湡"
+ prop="executionDate"
+ width="120"
+ show-overflow-tooltip
+ />
+ <el-table-column
+ label="浜や粯鏃ユ湡"
+ prop="deliveryDate"
+ width="120"
+ show-overflow-tooltip
+ />
+ <el-table-column
+ label="澶囨敞"
+ prop="remarks"
+ width="200"
+ show-overflow-tooltip
+ />
+ <el-table-column fixed="right" label="鎿嶄綔" width="220" align="center">
<template #default="scope">
- <el-button link
- type="primary"
- @click="openForm('view', scope.row)">璇︽儏
+ <el-button link type="primary" @click="openForm('view', scope.row)"
+ >璇︽儏
</el-button>
- <el-button link
- type="primary"
- @click="openForm('edit', scope.row)"
- :disabled="!scope.row.isEdit || scope.row.hasProductionRecord || !canEditLedger(scope.row)">缂栬緫
+ <el-button
+ link
+ type="primary"
+ @click="openForm('edit', scope.row)"
+ :disabled="
+ !scope.row.isEdit ||
+ scope.row.hasProductionRecord ||
+ !canEditLedger(scope.row)
+ "
+ >缂栬緫
</el-button>
- <el-button link
- type="primary"
- @click="openFileDialog(scope.row)">闄勪欢
+ <el-button link type="primary" @click="openFileDialog(scope.row)"
+ >闄勪欢
</el-button>
</template>
</el-table-column>
</el-table>
- <pagination v-show="total > 0"
- :total="total"
- layout="total, sizes, prev, pager, next, jumper"
- :page="page.current"
- :limit="page.size"
- @pagination="paginationChange" />
+ <pagination
+ v-show="total > 0"
+ :total="total"
+ layout="total, sizes, prev, pager, next, jumper"
+ :page="page.current"
+ :limit="page.size"
+ @pagination="paginationChange"
+ />
</div>
- <FormDialog v-model="dialogFormVisible"
- :title="operationType === 'add' ? '鏂板閿�鍞彴璐﹂〉闈�' : (operationType === 'edit' ? '缂栬緫閿�鍞彴璐﹂〉闈�' : '閿�鍞彴璐﹁鎯�')"
- :width="'70%'"
- :operation-type="operationType"
- @close="closeDia"
- @confirm="submitForm"
- @cancel="closeDia">
- <el-form :model="form"
- label-width="140px"
- label-position="top"
- :rules="rules"
- ref="formRef">
+ <FormDialog
+ v-model="dialogFormVisible"
+ :title="
+ operationType === 'add'
+ ? '鏂板閿�鍞彴璐﹂〉闈�'
+ : operationType === 'edit'
+ ? '缂栬緫閿�鍞彴璐﹂〉闈�'
+ : '閿�鍞彴璐﹁鎯�'
+ "
+ :width="'70%'"
+ :operation-type="operationType"
+ @close="closeDia"
+ @confirm="submitForm"
+ @cancel="closeDia"
+ >
+ <el-form
+ :model="form"
+ label-width="140px"
+ label-position="top"
+ :rules="rules"
+ ref="formRef"
+ >
<!-- 鎶ヤ环鍗曞鍏ュ叆鍙o細鏀惧湪琛ㄥ崟椤堕儴锛岄�夋嫨鍚庡弽鏄惧鎴�/涓氬姟鍛樼瓑 -->
- <el-row v-if="operationType === 'add'"
- style="margin-bottom: 10px;">
- <el-col :span="24"
- style="text-align: right;">
- <el-button type="primary"
- plain
- @click="openQuotationDialog">
+ <el-row v-if="operationType === 'add'" style="margin-bottom: 10px">
+ <el-col :span="24" style="text-align: right">
+ <el-button type="primary" plain @click="openQuotationDialog">
浠庨攢鍞姤浠峰鍏�
</el-button>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
- <el-form-item label="閿�鍞悎鍚屽彿锛�"
- prop="salesContractNo">
- <div style="display: flex; align-items: center; gap: 12px;width: 100%;">
- <el-checkbox v-model="form.autoGenerateContractNo"
- v-if="operationType === 'add'">鑷姩鐢熸垚
+ <el-form-item label="閿�鍞悎鍚屽彿锛�" prop="salesContractNo">
+ <div
+ style="
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ width: 100%;
+ "
+ >
+ <el-checkbox
+ v-model="form.autoGenerateContractNo"
+ v-if="operationType === 'add'"
+ >鑷姩鐢熸垚
</el-checkbox>
- <el-input v-model="form.salesContractNo"
- :placeholder="form.autoGenerateContractNo ? '鑷姩鐢熸垚' : '璇疯緭鍏�'"
- clearable
- :disabled="form.autoGenerateContractNo || operationType === 'view'" />
+ <el-input
+ v-model="form.salesContractNo"
+ :placeholder="
+ form.autoGenerateContractNo ? '淇濆瓨鍚庤嚜鍔ㄧ敓鎴�' : '璇疯緭鍏�'
+ "
+ clearable
+ :disabled="
+ form.autoGenerateContractNo || operationType === 'view'
+ "
+ />
</div>
</el-form-item>
</el-col>
<el-col :span="12">
- <el-form-item label="涓氬姟鍛橈細"
- prop="salesman">
- <el-select v-model="form.salesman"
- placeholder="璇烽�夋嫨"
- clearable
- :disabled="operationType === 'view'"
- filterable>
- <el-option v-for="item in userList"
- :key="item.nickName"
- :label="item.nickName"
- :value="item.nickName" />
+ <el-form-item label="涓氬姟鍛橈細" prop="salesman">
+ <el-select
+ v-model="form.salesman"
+ placeholder="璇烽�夋嫨"
+ clearable
+ :disabled="operationType === 'view'"
+ filterable
+ >
+ <el-option
+ v-for="item in userList"
+ :key="item.nickName"
+ :label="item.nickName"
+ :value="item.nickName"
+ />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
- <el-form-item label="瀹㈡埛鍚嶇О锛�"
- prop="customerId">
- <el-select v-model="form.customerId"
- placeholder="璇烽�夋嫨"
- clearable
- :disabled="operationType === 'view'"
- filterable>
- <el-option v-for="item in customerOption"
- :key="item.id"
- :label="item.customerName"
- :value="item.id">
+ <el-form-item label="瀹㈡埛鍚嶇О锛�" prop="customerId">
+ <el-select
+ v-model="form.customerId"
+ placeholder="璇烽�夋嫨"
+ clearable
+ :disabled="operationType === 'view'"
+ filterable
+ >
+ <el-option
+ v-for="item in customerOption"
+ :key="item.id"
+ :label="item.customerName"
+ :value="item.id"
+ >
{{
item.customerName + "鈥斺��" + item.taxpayerIdentificationNumber
}}
@@ -336,400 +381,453 @@
</el-form-item>
</el-col>
<el-col :span="12">
- <el-form-item label="椤圭洰鍚嶇О锛�"
- prop="projectName">
- <el-input v-model="form.projectName"
- placeholder="璇疯緭鍏�"
- clearable
- :disabled="operationType === 'view'" />
+ <el-form-item label="椤圭洰鍚嶇О锛�" prop="projectName">
+ <el-input
+ v-model="form.projectName"
+ placeholder="璇疯緭鍏�"
+ clearable
+ :disabled="operationType === 'view'"
+ />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
- <el-form-item label="绛捐鏃ユ湡锛�"
- prop="executionDate">
- <el-date-picker style="width: 100%"
- v-model="form.executionDate"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- type="date"
- placeholder="璇烽�夋嫨"
- clearable
- :disabled="operationType === 'view'" />
+ <el-form-item label="绛捐鏃ユ湡锛�" prop="executionDate">
+ <el-date-picker
+ style="width: 100%"
+ v-model="form.executionDate"
+ value-format="YYYY-MM-DD"
+ format="YYYY-MM-DD"
+ type="date"
+ placeholder="璇烽�夋嫨"
+ clearable
+ :disabled="operationType === 'view'"
+ />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="浠樻鏂瑰紡">
- <el-input v-model="form.paymentMethod"
- placeholder="璇疯緭鍏�"
- clearable
- :disabled="operationType === 'view'" />
+ <el-input
+ v-model="form.paymentMethod"
+ placeholder="璇疯緭鍏�"
+ clearable
+ :disabled="operationType === 'view'"
+ />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
- <el-form-item label="褰曞叆浜猴細"
- prop="entryPerson">
- <el-select v-model="form.entryPerson"
- filterable
- default-first-option
- :reserve-keyword="false"
- placeholder="璇烽�夋嫨"
- clearable
- :disabled="operationType === 'view'"
- @change="changs">
- <el-option v-for="item in userList"
- :key="item.userId"
- :label="item.nickName"
- :value="item.userId" />
+ <el-form-item label="褰曞叆浜猴細" prop="entryPerson">
+ <el-select
+ v-model="form.entryPerson"
+ filterable
+ default-first-option
+ :reserve-keyword="false"
+ placeholder="璇烽�夋嫨"
+ clearable
+ :disabled="operationType === 'view'"
+ @change="changs"
+ >
+ <el-option
+ v-for="item in userList"
+ :key="item.userId"
+ :label="item.nickName"
+ :value="item.userId"
+ />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
- <el-form-item label="褰曞叆鏃ユ湡锛�"
- prop="entryDate">
- <el-date-picker style="width: 100%"
- v-model="form.entryDate"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- type="date"
- placeholder="璇烽�夋嫨"
- clearable
- :disabled="operationType === 'view'" />
+ <el-form-item label="褰曞叆鏃ユ湡锛�" prop="entryDate">
+ <el-date-picker
+ style="width: 100%"
+ v-model="form.entryDate"
+ value-format="YYYY-MM-DD"
+ format="YYYY-MM-DD"
+ type="date"
+ placeholder="璇烽�夋嫨"
+ clearable
+ :disabled="operationType === 'view'"
+ />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
- <el-form-item label="浜よ揣鏃ユ湡锛�"
- prop="entryDate">
- <el-date-picker style="width: 100%"
- v-model="form.deliveryDate"
- value-format="YYYY-MM-DD"
- format="YYYY-MM-DD"
- type="date"
- placeholder="璇烽�夋嫨"
- clearable
- :disabled="operationType === 'view'" />
+ <el-form-item label="浜よ揣鏃ユ湡锛�" prop="entryDate">
+ <el-date-picker
+ style="width: 100%"
+ v-model="form.deliveryDate"
+ value-format="YYYY-MM-DD"
+ format="YYYY-MM-DD"
+ type="date"
+ placeholder="璇烽�夋嫨"
+ clearable
+ :disabled="operationType === 'view'"
+ />
</el-form-item>
</el-col>
</el-row>
<el-row>
- <el-form-item label="浜у搧淇℃伅锛�"
- prop="entryDate">
- <el-button v-if="operationType !== 'view'"
- type="primary"
- @click="openProductForm('add')">娣诲姞
+ <el-form-item label="浜у搧淇℃伅锛�" prop="entryDate">
+ <el-button
+ v-if="operationType !== 'view'"
+ type="primary"
+ @click="openProductForm('add')"
+ >娣诲姞
</el-button>
- <el-button v-if="operationType !== 'view'"
- plain
- type="danger"
- @click="deleteProduct">鍒犻櫎
+ <el-button
+ v-if="operationType !== 'view'"
+ plain
+ type="danger"
+ @click="deleteProduct"
+ >鍒犻櫎
</el-button>
</el-form-item>
</el-row>
- <el-table :data="productData"
- border
- @selection-change="productSelected"
- show-summary
- :summary-method="summarizeMainTable">
- <el-table-column align="center"
- type="selection"
- width="55"
- v-if="operationType !== 'view'"
- :selectable="(row) => !isProductShipped(row)" />
- <el-table-column align="center"
- label="搴忓彿"
- type="index"
- width="60" />
- <el-table-column label="浜у搧澶х被"
- prop="productCategory" />
- <el-table-column label="瑙勬牸鍨嬪彿"
- prop="specificationModel" />
- <el-table-column label="鍗曚綅"
- prop="unit" />
- <el-table-column label="鏁伴噺"
- prop="quantity" />
- <el-table-column label="绋庣巼(%)"
- prop="taxRate" />
- <el-table-column label="鍚◣鍗曚环(鍏�)"
- prop="taxInclusiveUnitPrice"
- :formatter="formattedNumber" />
- <el-table-column label="鍚◣鎬讳环(鍏�)"
- prop="taxInclusiveTotalPrice"
- :formatter="formattedNumber" />
- <el-table-column label="涓嶅惈绋庢�讳环(鍏�)"
- prop="taxExclusiveTotalPrice"
- :formatter="formattedNumber" />
- <el-table-column label="鏄惁鐢熶骇"
- prop="isProduction"
- width="150">
+ <el-table
+ :data="productData"
+ border
+ @selection-change="productSelected"
+ show-summary
+ :summary-method="summarizeMainTable"
+ >
+ <el-table-column
+ align="center"
+ type="selection"
+ width="55"
+ v-if="operationType !== 'view'"
+ :selectable="(row) => !isProductShipped(row)"
+ />
+ <el-table-column
+ align="center"
+ label="搴忓彿"
+ type="index"
+ width="60"
+ />
+ <el-table-column label="浜у搧澶х被" prop="productCategory" />
+ <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
+ <el-table-column label="鍗曚綅" prop="unit" />
+ <el-table-column label="鏁伴噺" prop="quantity" />
+ <el-table-column label="绋庣巼(%)" prop="taxRate" />
+ <el-table-column
+ label="鍚◣鍗曚环(鍏�)"
+ prop="taxInclusiveUnitPrice"
+ :formatter="formattedNumber"
+ />
+ <el-table-column
+ label="鍚◣鎬讳环(鍏�)"
+ prop="taxInclusiveTotalPrice"
+ :formatter="formattedNumber"
+ />
+ <el-table-column
+ label="涓嶅惈绋庢�讳环(鍏�)"
+ prop="taxExclusiveTotalPrice"
+ :formatter="formattedNumber"
+ />
+ <el-table-column label="鏄惁鐢熶骇" prop="isProduction" width="150">
<template #default="scope">
<el-tag :type="scope.row.isProduction ? 'success' : 'info'">
- {{ scope.row.isProduction ? '鏄�' : '鍚�' }}
+ {{ scope.row.isProduction ? "鏄�" : "鍚�" }}
</el-tag>
</template>
</el-table-column>
- <el-table-column fixed="right"
- label="鎿嶄綔"
- min-width="60"
- align="center"
- v-if="operationType !== 'view'">
+ <el-table-column
+ fixed="right"
+ label="鎿嶄綔"
+ min-width="60"
+ align="center"
+ v-if="operationType !== 'view'"
+ >
<template #default="scope">
- <el-button link
- type="primary"
- size="small"
- :disabled="isProductShipped(scope.row)"
- @click="openProductForm('edit', scope.row,scope.$index)">缂栬緫
+ <el-button
+ link
+ type="primary"
+ size="small"
+ :disabled="isProductShipped(scope.row)"
+ @click="openProductForm('edit', scope.row, scope.$index)"
+ >缂栬緫
</el-button>
</template>
</el-table-column>
</el-table>
<el-row :gutter="30">
<el-col :span="24">
- <el-form-item label="澶囨敞锛�"
- prop="remarks">
- <el-input v-model="form.remarks"
- placeholder="璇疯緭鍏�"
- clearable
- type="textarea"
- :rows="2"
- :disabled="operationType === 'view'" />
+ <el-form-item label="澶囨敞锛�" prop="remarks">
+ <el-input
+ v-model="form.remarks"
+ placeholder="璇疯緭鍏�"
+ clearable
+ type="textarea"
+ :rows="2"
+ :disabled="operationType === 'view'"
+ />
</el-form-item>
</el-col>
</el-row>
- <el-row v-if="operationType !== 'view'"
- :gutter="30">
+ <el-row v-if="operationType !== 'view'" :gutter="30">
<el-col :span="24">
- <el-form-item label="闄勪欢鏉愭枡锛�"
- prop="salesLedgerFiles">
- <FileUpload v-model:file-list="fileList"
- :disabled="operationType === 'view'" />
+ <el-form-item label="闄勪欢鏉愭枡锛�" prop="salesLedgerFiles">
+ <FileUpload
+ v-model:file-list="fileList"
+ :disabled="operationType === 'view'"
+ />
</el-form-item>
</el-col>
</el-row>
</el-form>
</FormDialog>
<!-- 浠庢姤浠峰崟瀵煎叆锛堜粎瀹℃壒閫氳繃锛� -->
- <el-dialog v-model="quotationDialogVisible"
- title="閫夋嫨瀹℃壒閫氳繃鐨勯攢鍞姤浠峰崟"
- width="80%"
- :close-on-click-modal="false">
- <div style="margin-bottom: 12px; display:flex; gap: 12px; align-items:center;">
- <el-input v-model="quotationSearchForm.quotationNo"
- placeholder="璇疯緭鍏ユ姤浠峰崟鍙�"
- clearable
- style="max-width: 260px;"
- @change="fetchQuotationList" />
- <el-input v-model="quotationSearchForm.customer"
- placeholder="璇疯緭鍏ュ鎴峰悕绉�"
- clearable
- style="max-width: 260px;"
- @change="fetchQuotationList" />
- <el-button type="primary"
- @click="fetchQuotationList">鎼滅储
- </el-button>
+ <el-dialog
+ v-model="quotationDialogVisible"
+ title="閫夋嫨瀹℃壒閫氳繃鐨勯攢鍞姤浠峰崟"
+ width="80%"
+ :close-on-click-modal="false"
+ >
+ <div
+ style="
+ margin-bottom: 12px;
+ display: flex;
+ gap: 12px;
+ align-items: center;
+ "
+ >
+ <el-input
+ v-model="quotationSearchForm.quotationNo"
+ placeholder="璇疯緭鍏ユ姤浠峰崟鍙�"
+ clearable
+ style="max-width: 260px"
+ @change="fetchQuotationList"
+ />
+ <el-input
+ v-model="quotationSearchForm.customer"
+ placeholder="璇疯緭鍏ュ鎴峰悕绉�"
+ clearable
+ style="max-width: 260px"
+ @change="fetchQuotationList"
+ />
+ <el-button type="primary" @click="fetchQuotationList">鎼滅储 </el-button>
<el-button @click="resetQuotationSearch">閲嶇疆</el-button>
</div>
- <el-table :data="quotationList"
- border
- stripe
- v-loading="quotationLoading"
- height="420px">
- <el-table-column align="center"
- label="搴忓彿"
- type="index"
- width="60" />
- <el-table-column prop="quotationNo"
- label="鎶ヤ环鍗曞彿"
- width="180"
- show-overflow-tooltip />
- <el-table-column prop="customer"
- label="瀹㈡埛鍚嶇О"
- min-width="220"
- show-overflow-tooltip />
- <el-table-column prop="salesperson"
- label="涓氬姟鍛�"
- width="120"
- show-overflow-tooltip />
- <el-table-column prop="quotationDate"
- label="鎶ヤ环鏃ユ湡"
- width="140" />
- <el-table-column prop="status"
- label="瀹℃壒鐘舵��"
- width="120"
- align="center" />
- <el-table-column prop="totalAmount"
- label="鎶ヤ环閲戦(鍏�)"
- width="160"
- align="right">
+ <el-table
+ :data="quotationList"
+ border
+ stripe
+ v-loading="quotationLoading"
+ height="420px"
+ >
+ <el-table-column align="center" label="搴忓彿" type="index" width="60" />
+ <el-table-column
+ prop="quotationNo"
+ label="鎶ヤ环鍗曞彿"
+ width="180"
+ show-overflow-tooltip
+ />
+ <el-table-column
+ prop="customer"
+ label="瀹㈡埛鍚嶇О"
+ min-width="220"
+ show-overflow-tooltip
+ />
+ <el-table-column
+ prop="salesperson"
+ label="涓氬姟鍛�"
+ width="120"
+ show-overflow-tooltip
+ />
+ <el-table-column prop="quotationDate" label="鎶ヤ环鏃ユ湡" width="140" />
+ <el-table-column
+ prop="status"
+ label="瀹℃壒鐘舵��"
+ width="120"
+ align="center"
+ />
+ <el-table-column
+ prop="totalAmount"
+ label="鎶ヤ环閲戦(鍏�)"
+ width="160"
+ align="right"
+ >
<template #default="scope">
{{ Number(scope.row.totalAmount ?? 0).toFixed(2) }}
</template>
</el-table-column>
- <el-table-column fixed="right"
- label="鎿嶄綔"
- width="120"
- align="center">
+ <el-table-column fixed="right" label="鎿嶄綔" width="120" align="center">
<template #default="scope">
- <el-button type="primary"
- link
- @click="applyQuotation(scope.row)">閫夋嫨
+ <el-button type="primary" link @click="applyQuotation(scope.row)"
+ >閫夋嫨
</el-button>
</template>
</el-table-column>
</el-table>
- <pagination v-show="quotationPage.total > 0"
- :total="quotationPage.total"
- layout="total, sizes, prev, pager, next, jumper"
- :page="quotationPage.current"
- :limit="quotationPage.size"
- @pagination="quotationPaginationChange" />
+ <pagination
+ v-show="quotationPage.total > 0"
+ :total="quotationPage.total"
+ layout="total, sizes, prev, pager, next, jumper"
+ :page="quotationPage.current"
+ :limit="quotationPage.size"
+ @pagination="quotationPaginationChange"
+ />
<template #footer>
<el-button @click="quotationDialogVisible = false">鍏抽棴</el-button>
</template>
</el-dialog>
- <FormDialog v-model="productFormVisible"
- :title="productOperationType === 'add' ? '鏂板浜у搧' : '缂栬緫浜у搧'"
- :width="'40%'"
- :operation-type="productOperationType"
- @close="closeProductDia"
- @confirm="submitProduct"
- @cancel="closeProductDia">
- <el-form :model="productForm"
- label-width="140px"
- label-position="top"
- :rules="productRules"
- ref="productFormRef">
+ <FormDialog
+ v-model="productFormVisible"
+ :title="productOperationType === 'add' ? '鏂板浜у搧' : '缂栬緫浜у搧'"
+ :width="'40%'"
+ :operation-type="productOperationType"
+ @close="closeProductDia"
+ @confirm="submitProduct"
+ @cancel="closeProductDia"
+ >
+ <el-form
+ :model="productForm"
+ label-width="140px"
+ label-position="top"
+ :rules="productRules"
+ ref="productFormRef"
+ >
<el-row :gutter="30">
<el-col :span="24">
- <el-form-item label="浜у搧澶х被锛�"
- prop="productCategory">
- <el-tree-select v-model="productForm.productCategory"
- placeholder="璇烽�夋嫨"
- clearable
- filterable
- check-strictly
- @change="getModels"
- :data="productOptions"
- :render-after-expand="false"
- style="width: 100%" />
+ <el-form-item label="浜у搧澶х被锛�" prop="productCategory">
+ <el-tree-select
+ v-model="productForm.productCategory"
+ placeholder="璇烽�夋嫨"
+ clearable
+ filterable
+ check-strictly
+ @change="getModels"
+ :data="productOptions"
+ :render-after-expand="false"
+ style="width: 100%"
+ />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="24">
- <el-form-item label="瑙勬牸鍨嬪彿锛�"
- prop="productModelId">
- <el-select v-model="productForm.productModelId"
- placeholder="璇烽�夋嫨"
- clearable
- @change="getProductModel"
- filterable>
- <el-option v-for="item in modelOptions"
- :key="item.id"
- :label="item.model"
- :value="item.id" />
+ <el-form-item label="瑙勬牸鍨嬪彿锛�" prop="productModelId">
+ <el-select
+ v-model="productForm.productModelId"
+ placeholder="璇烽�夋嫨"
+ clearable
+ @change="getProductModel"
+ filterable
+ >
+ <el-option
+ v-for="item in modelOptions"
+ :key="item.id"
+ :label="item.model"
+ :value="item.id"
+ />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
- <el-form-item label="鍗曚綅锛�"
- prop="unit">
- <el-input v-model="productForm.unit"
- placeholder="璇疯緭鍏�"
- clearable />
+ <el-form-item label="鍗曚綅锛�" prop="unit">
+ <el-input
+ v-model="productForm.unit"
+ placeholder="璇疯緭鍏�"
+ clearable
+ />
</el-form-item>
</el-col>
<el-col :span="12">
- <el-form-item label="绋庣巼(%)锛�"
- prop="taxRate">
- <el-select v-model="productForm.taxRate"
- placeholder="璇烽�夋嫨"
- clearable
- @change="calculateFromTaxRate">
- <el-option v-for="dict in tax_rate"
- :key="dict.value"
- :label="dict.label"
- :value="dict.value" />
+ <el-form-item label="绋庣巼(%)锛�" prop="taxRate">
+ <el-select
+ v-model="productForm.taxRate"
+ placeholder="璇烽�夋嫨"
+ clearable
+ @change="calculateFromTaxRate"
+ >
+ <el-option
+ v-for="dict in tax_rate"
+ :key="dict.value"
+ :label="dict.label"
+ :value="dict.value"
+ />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
- <el-form-item label="鍚◣鍗曚环(鍏�)锛�"
- prop="taxInclusiveUnitPrice">
- <el-input-number :step="0.01"
- :min="0"
- v-model="productForm.taxInclusiveUnitPrice"
- style="width: 100%"
- :precision="2"
- placeholder="璇疯緭鍏�"
- clearable
- @change="calculateFromUnitPrice" />
+ <el-form-item label="鍚◣鍗曚环(鍏�)锛�" prop="taxInclusiveUnitPrice">
+ <el-input-number
+ :step="0.01"
+ :min="0"
+ v-model="productForm.taxInclusiveUnitPrice"
+ style="width: 100%"
+ :precision="2"
+ placeholder="璇疯緭鍏�"
+ clearable
+ @change="calculateFromUnitPrice"
+ />
</el-form-item>
</el-col>
<el-col :span="12">
- <el-form-item label="鏁伴噺锛�"
- prop="quantity">
- <el-input-number :step="0.1"
- :min="0"
- v-model="productForm.quantity"
- placeholder="璇疯緭鍏�"
- clearable
- :precision="2"
- @change="calculateFromQuantity"
- style="width: 100%" />
+ <el-form-item label="鏁伴噺锛�" prop="quantity">
+ <el-input-number
+ :step="0.1"
+ :min="0"
+ v-model="productForm.quantity"
+ placeholder="璇疯緭鍏�"
+ clearable
+ :precision="2"
+ @change="calculateFromQuantity"
+ style="width: 100%"
+ />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
- <el-form-item label="鍚◣鎬讳环(鍏�)锛�"
- prop="taxInclusiveTotalPrice">
- <el-input v-model="productForm.taxInclusiveTotalPrice"
- placeholder="璇疯緭鍏�"
- clearable
- @change="calculateFromTotalPrice" />
+ <el-form-item label="鍚◣鎬讳环(鍏�)锛�" prop="taxInclusiveTotalPrice">
+ <el-input
+ v-model="productForm.taxInclusiveTotalPrice"
+ placeholder="璇疯緭鍏�"
+ clearable
+ @change="calculateFromTotalPrice"
+ />
</el-form-item>
</el-col>
<el-col :span="12">
- <el-form-item label="涓嶅惈绋庢�讳环(鍏�)锛�"
- prop="taxExclusiveTotalPrice">
- <el-input v-model="productForm.taxExclusiveTotalPrice"
- placeholder="璇疯緭鍏�"
- clearable
- @change="calculateFromExclusiveTotalPrice" />
+ <el-form-item
+ label="涓嶅惈绋庢�讳环(鍏�)锛�"
+ prop="taxExclusiveTotalPrice"
+ >
+ <el-input
+ v-model="productForm.taxExclusiveTotalPrice"
+ placeholder="璇疯緭鍏�"
+ clearable
+ @change="calculateFromExclusiveTotalPrice"
+ />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="12">
- <el-form-item label="鍙戠エ绫诲瀷锛�"
- prop="invoiceType">
- <el-select v-model="productForm.invoiceType"
- placeholder="璇烽�夋嫨"
- clearable>
- <el-option label="澧炴櫘绁�"
- value="澧炴櫘绁�" />
- <el-option label="澧炰笓绁�"
- value="澧炰笓绁�" />
+ <el-form-item label="鍙戠エ绫诲瀷锛�" prop="invoiceType">
+ <el-select
+ v-model="productForm.invoiceType"
+ placeholder="璇烽�夋嫨"
+ clearable
+ >
+ <el-option label="澧炴櫘绁�" value="澧炴櫘绁�" />
+ <el-option label="澧炰笓绁�" value="澧炰笓绁�" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
- <el-form-item label="鏄惁鐢熶骇锛�"
- prop="isProduction">
+ <el-form-item label="鏄惁鐢熶骇锛�" prop="isProduction">
<el-radio-group v-model="productForm.isProduction">
- <el-radio label="鏄�"
- :value="true" />
- <el-radio label="鍚�"
- :value="false" />
+ <el-radio label="鏄�" :value="true" />
+ <el-radio label="鍚�" :value="false" />
</el-radio-group>
</el-form-item>
</el-col>
@@ -737,34 +835,35 @@
</el-form>
</FormDialog>
<!-- 瀵煎叆寮圭獥 -->
- <FormDialog v-model="importUpload.open"
- :title="importUpload.title"
- :width="'600px'"
- @close="importUpload.open = false"
- @confirm="submitImportFile"
- @cancel="importUpload.open = false">
- <el-upload ref="importUploadRef"
- :limit="1"
- accept=".xlsx,.xls"
- :action="importUpload.url"
- :headers="importUpload.headers"
- :before-upload="importUpload.beforeUpload"
- :on-success="importUpload.onSuccess"
- :on-error="importUpload.onError"
- :on-progress="importUpload.onProgress"
- :on-change="importUpload.onChange"
- :auto-upload="false"
- drag>
+ <FormDialog
+ v-model="importUpload.open"
+ :title="importUpload.title"
+ :width="'600px'"
+ @close="importUpload.open = false"
+ @confirm="submitImportFile"
+ @cancel="importUpload.open = false"
+ >
+ <el-upload
+ ref="importUploadRef"
+ :limit="1"
+ accept=".xlsx,.xls"
+ :action="importUpload.url"
+ :headers="importUpload.headers"
+ :before-upload="importUpload.beforeUpload"
+ :on-success="importUpload.onSuccess"
+ :on-error="importUpload.onError"
+ :on-progress="importUpload.onProgress"
+ :on-change="importUpload.onChange"
+ :auto-upload="false"
+ drag
+ >
<i class="el-icon-upload"></i>
- <div class="el-upload__text">
- 灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em>
- </div>
+ <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
<template #tip>
<div class="el-upload__tip">
浠呮敮鎸� xls/xlsx锛屽ぇ灏忎笉瓒呰繃 10MB銆�
- <el-button link
- type="primary"
- @click="downloadTemplate">涓嬭浇瀵煎叆妯℃澘
+ <el-button link type="primary" @click="downloadTemplate"
+ >涓嬭浇瀵煎叆妯℃澘
</el-button>
</div>
</template>
@@ -772,35 +871,50 @@
</FormDialog>
<!-- // todo 闄勪欢棰勮鐩稿叧 -->
<!-- 闄勪欢鍒楄〃寮圭獥 -->
- <FileList v-if="fileDialogVisible"
- v-model:visible="fileDialogVisible"
- record-type="sales_ledger"
- :record-id="recordId" />
+ <FileList
+ v-if="fileDialogVisible"
+ v-model:visible="fileDialogVisible"
+ record-type="sales_ledger"
+ :record-id="recordId"
+ />
<!-- 鎵撳嵃棰勮寮圭獥 -->
- <el-dialog v-model="printPreviewVisible"
- title="鎵撳嵃棰勮"
- width="90%"
- :close-on-click-modal="false"
- class="print-preview-dialog">
+ <el-dialog
+ v-model="printPreviewVisible"
+ title="鎵撳嵃棰勮"
+ width="90%"
+ :close-on-click-modal="false"
+ class="print-preview-dialog"
+ >
<div class="print-preview-container">
<div class="print-preview-header">
- <el-button type="primary"
- @click="executePrint">鎵ц鎵撳嵃
- </el-button>
+ <el-button type="primary" @click="executePrint">鎵ц鎵撳嵃 </el-button>
<el-button @click="printPreviewVisible = false">鍏抽棴棰勮</el-button>
</div>
<div class="print-preview-content">
- <div v-if="printData.length === 0"
- style="text-align: center; padding: 50px; color: #999;">
+ <div
+ v-if="printData.length === 0"
+ style="text-align: center; padding: 50px; color: #999"
+ >
鏆傛棤鎵撳嵃鏁版嵁
</div>
- <div v-else
- style="text-align: center; padding: 10px; color: #666; font-size: 14px; background: #e8f4fd; margin-bottom: 10px;">
+ <div
+ v-else
+ style="
+ text-align: center;
+ padding: 10px;
+ color: #666;
+ font-size: 14px;
+ background: #e8f4fd;
+ margin-bottom: 10px;
+ "
+ >
鍏� {{ printData.length }} 鏉℃暟鎹緟鎵撳嵃
</div>
- <div v-for="(item, index) in printData"
- :key="index"
- class="print-page">
+ <div
+ v-for="(item, index) in printData"
+ :key="index"
+ class="print-page"
+ >
<div class="delivery-note">
<div class="header">
<div class="document-title">闆跺敭鍙戣揣鍗�</div>
@@ -838,18 +952,17 @@
</tr>
</thead>
<tbody>
- <tr v-for="product in item.products"
- :key="product.id">
- <td>{{ product.productCategory || '' }}</td>
- <td>{{ product.specificationModel || '' }}</td>
- <td>{{ product.unit || '' }}</td>
- <td>{{ product.taxInclusiveUnitPrice || '0' }}</td>
- <td>{{ product.quantity || '0' }}</td>
- <td>{{ product.taxInclusiveTotalPrice || '0' }}</td>
+ <tr v-for="product in item.products" :key="product.id">
+ <td>{{ product.productCategory || "" }}</td>
+ <td>{{ product.specificationModel || "" }}</td>
+ <td>{{ product.unit || "" }}</td>
+ <td>{{ product.taxInclusiveUnitPrice || "0" }}</td>
+ <td>{{ product.quantity || "0" }}</td>
+ <td>{{ product.taxInclusiveTotalPrice || "0" }}</td>
</tr>
<tr v-if="!item.products || item.products.length === 0">
- <td colspan="6"
- style="text-align: center; color: #999;">鏆傛棤浜у搧鏁版嵁
+ <td colspan="6" style="text-align: center; color: #999">
+ 鏆傛棤浜у搧鏁版嵁
</td>
</tr>
</tbody>
@@ -859,8 +972,12 @@
<td class="total-value"></td>
<td class="total-value"></td>
<td class="total-value"></td>
- <td class="total-value">{{ getTotalQuantity(item.products) }}</td>
- <td class="total-value">{{ getTotalAmount(item.products) }}</td>
+ <td class="total-value">
+ {{ getTotalQuantity(item.products) }}
+ </td>
+ <td class="total-value">
+ {{ getTotalAmount(item.products) }}
+ </td>
</tr>
</tfoot>
</table>
@@ -883,7 +1000,9 @@
<div class="footer-row">
<div class="footer-item">
<span class="label">鎿嶄綔鍛橈細</span>
- <span class="value">{{ userStore.nickName || '鎾曞紑鍓�' }}</span>
+ <span class="value">{{
+ userStore.nickName || "鎾曞紑鍓�"
+ }}</span>
</div>
<div class="footer-item">
<span class="label">鎵撳嵃鏃ユ湡锛�</span>
@@ -897,116 +1016,127 @@
</div>
</el-dialog>
<!-- 鍙戣揣寮规 -->
- <el-dialog v-model="deliveryFormVisible"
- title="鍙戣揣淇℃伅"
- width="40%"
- @close="closeDeliveryDia">
- <el-form :model="deliveryForm"
- label-width="120px"
- label-position="top"
- :rules="deliveryRules"
- ref="deliveryFormRef">
+ <el-dialog
+ v-model="deliveryFormVisible"
+ title="鍙戣揣淇℃伅"
+ width="40%"
+ @close="closeDeliveryDia"
+ >
+ <el-form
+ :model="deliveryForm"
+ label-width="120px"
+ label-position="top"
+ :rules="deliveryRules"
+ ref="deliveryFormRef"
+ >
<el-row :gutter="30">
<el-col :span="24">
- <el-form-item label="鍙戣揣绫诲瀷锛�"
- prop="type">
- <el-select v-model="deliveryForm.type"
- placeholder="璇烽�夋嫨鍙戣揣绫诲瀷"
- style="width: 100%"
- @change="handleDeliveryTypeChange">
- <el-option label="璐ц溅"
- value="璐ц溅" />
- <el-option label="蹇��"
- value="蹇��" />
+ <el-form-item label="鍙戣揣绫诲瀷锛�" prop="type">
+ <el-select
+ v-model="deliveryForm.type"
+ placeholder="璇烽�夋嫨鍙戣揣绫诲瀷"
+ style="width: 100%"
+ @change="handleDeliveryTypeChange"
+ >
+ <el-option label="璐ц溅" value="璐ц溅" />
+ <el-option label="蹇��" value="蹇��" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="寰呭彂璐ф暟閲忥細">
- <el-input :model-value="currentDeliveryRow?.noQuantity"
- disabled />
+ <el-input
+ :model-value="currentDeliveryRow?.noQuantity"
+ disabled
+ />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
- <el-col :span="24"
- v-if="deliveryForm.type === '璐ц溅'">
- <el-form-item label="鍙戣揣杞︾墝鍙凤細"
- prop="shippingCarNumber">
- <el-input v-model="deliveryForm.shippingCarNumber"
- placeholder="璇疯緭鍏ュ彂璐ц溅鐗屽彿"
- clearable />
+ <el-col :span="24" v-if="deliveryForm.type === '璐ц溅'">
+ <el-form-item label="鍙戣揣杞︾墝鍙凤細" prop="shippingCarNumber">
+ <el-input
+ v-model="deliveryForm.shippingCarNumber"
+ placeholder="璇疯緭鍏ュ彂璐ц溅鐗屽彿"
+ clearable
+ />
</el-form-item>
</el-col>
- <el-col :span="24"
- v-else>
- <el-form-item label="蹇�掑叕鍙革細"
- prop="expressCompany">
- <el-input v-model="deliveryForm.expressCompany"
- placeholder="璇疯緭鍏ュ揩閫掑叕鍙�"
- clearable />
+ <el-col :span="24" v-else>
+ <el-form-item label="蹇�掑叕鍙革細" prop="expressCompany">
+ <el-input
+ v-model="deliveryForm.expressCompany"
+ placeholder="璇疯緭鍏ュ揩閫掑叕鍙�"
+ clearable
+ />
</el-form-item>
</el-col>
</el-row>
- <el-row :gutter="30"
- v-if="deliveryForm.type === '蹇��'">
+ <el-row :gutter="30" v-if="deliveryForm.type === '蹇��'">
<el-col :span="24">
- <el-form-item label="蹇�掑崟鍙凤細"
- prop="expressNumber">
- <el-input v-model="deliveryForm.expressNumber"
- placeholder="璇疯緭鍏ュ揩閫掑崟鍙�"
- clearable />
+ <el-form-item label="蹇�掑崟鍙凤細" prop="expressNumber">
+ <el-input
+ v-model="deliveryForm.expressNumber"
+ placeholder="璇疯緭鍏ュ揩閫掑崟鍙�"
+ clearable
+ />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="24">
<el-form-item label="鍙戣揣鍥剧墖锛�">
- <ImageUpload v-model:file-list="deliveryFileList"
- :limit="9" />
+ <ImageUpload v-model:file-list="deliveryFileList" :limit="9" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="30">
<el-col :span="24">
- <el-form-item label="搴撳瓨锛�"
- prop="batchNo">
- <el-table :data="deliveryForm.batchNoList"
- border
- size="small"
- max-height="260"
- style="width: 100%;">
- <el-table-column label="鎵瑰彿"
- prop="batchNo"
- min-width="180" />
- <el-table-column label="浜у搧澶х被"
- prop="productName"
- min-width="100" />
- <el-table-column label="瑙勬牸鍨嬪彿"
- prop="model"
- min-width="100" />
- <el-table-column label="鍗曚綅"
- prop="unit"
- min-width="100" />
- <el-table-column label="搴撳瓨鏁伴噺"
- min-width="120"
- align="center">
+ <el-form-item label="搴撳瓨锛�" prop="batchNo">
+ <el-table
+ :data="deliveryForm.batchNoList"
+ border
+ size="small"
+ max-height="260"
+ style="width: 100%"
+ >
+ <el-table-column label="鎵瑰彿" prop="batchNo" min-width="180" />
+ <el-table-column
+ label="浜у搧澶х被"
+ prop="productName"
+ min-width="100"
+ />
+ <el-table-column
+ label="瑙勬牸鍨嬪彿"
+ prop="model"
+ min-width="100"
+ />
+ <el-table-column label="鍗曚綅" prop="unit" min-width="100" />
+ <el-table-column
+ label="搴撳瓨鏁伴噺"
+ min-width="120"
+ align="center"
+ >
<template #default="scope">
{{ getDeliveryBatchQuantity(scope.row) }}
</template>
</el-table-column>
- <el-table-column label="鍙戣揣鏁伴噺"
- min-width="160"
- align="center">
+ <el-table-column
+ label="鍙戣揣鏁伴噺"
+ min-width="160"
+ align="center"
+ >
<template #default="scope">
- <el-input-number v-model="scope.row.deliveryQuantity"
- :min="0"
- :max="getDeliveryBatchDeliveryMax(scope.row)"
- :precision="2"
- :step="0.01"
- controls-position="right"
- @change="handleDeliveryBatchQuantityChange(scope.row)"
- style="width: 100%;" />
+ <el-input-number
+ v-model="scope.row.deliveryQuantity"
+ :min="0"
+ :max="getDeliveryBatchDeliveryMax(scope.row)"
+ :precision="2"
+ :step="0.01"
+ controls-position="right"
+ @change="handleDeliveryBatchQuantityChange(scope.row)"
+ style="width: 100%"
+ />
</template>
</el-table-column>
</el-table>
@@ -1016,8 +1146,8 @@
</el-form>
<template #footer>
<div class="dialog-footer">
- <el-button type="primary"
- @click="submitDelivery">纭鍙戣揣
+ <el-button type="primary" @click="submitDelivery"
+ >纭鍙戣揣
</el-button>
<el-button @click="closeDeliveryDia">鍙栨秷</el-button>
</div>
@@ -1027,1059 +1157,1062 @@
</template>
<script setup>
- import { getToken } from "@/utils/auth";
- import pagination from "@/components/PIMTable/Pagination.vue";
- import { onMounted, ref, getCurrentInstance } from "vue";
- import { addShippingInfo } from "@/api/salesManagement/deliveryLedger.js";
- import { ElMessageBox, ElMessage } from "element-plus";
- import useUserStore from "@/store/modules/user";
- import { userListNoPage } from "@/api/system/user.js";
- import FormDialog from "@/components/Dialog/FormDialog.vue";
- import { getQuotationList } from "@/api/salesManagement/salesQuotation.js";
- import {
- ledgerListPage,
- productList,
- customerList,
- addOrUpdateSalesLedger,
- getSalesLedgerWithProducts,
- delLedger,
- addOrUpdateSalesLedgerProduct,
- delProduct,
- delLedgerFile,
- getProductInventory,
- } from "@/api/salesManagement/salesLedger.js";
- import { getStockInventoryByModelId } from "@/api/inventoryManagement/stockInventory.js";
- import { modelList, productTreeList } from "@/api/basicData/product.js";
- import useFormData from "@/hooks/useFormData.js";
- import dayjs from "dayjs";
- import FileUpload from "@/components/AttachmentUpload/file/index.vue";
- import ImageUpload from "@/components/AttachmentUpload/image/index.vue";
- import { getCurrentDate } from "@/utils/index.js";
- import { listCustomer } from "@/api/basicData/customer.js";
+import { getToken } from "@/utils/auth";
+import pagination from "@/components/PIMTable/Pagination.vue";
+import { onMounted, ref, getCurrentInstance } from "vue";
+import { addShippingInfo } from "@/api/salesManagement/deliveryLedger.js";
+import { ElMessageBox, ElMessage } from "element-plus";
+import useUserStore from "@/store/modules/user";
+import { userListNoPage } from "@/api/system/user.js";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
+import { getQuotationList } from "@/api/salesManagement/salesQuotation.js";
+import {
+ ledgerListPage,
+ productList,
+ customerList,
+ addOrUpdateSalesLedger,
+ getSalesLedgerWithProducts,
+ delLedger,
+ addOrUpdateSalesLedgerProduct,
+ delProduct,
+ delLedgerFile,
+ getProductInventory,
+} from "@/api/salesManagement/salesLedger.js";
+import { getStockInventoryByModelId } from "@/api/inventoryManagement/stockInventory.js";
+import { modelList, productTreeList } from "@/api/basicData/product.js";
+import useFormData from "@/hooks/useFormData.js";
+import dayjs from "dayjs";
+import FileUpload from "@/components/AttachmentUpload/file/index.vue";
+import ImageUpload from "@/components/AttachmentUpload/image/index.vue";
+import { getCurrentDate } from "@/utils/index.js";
+import { listCustomer } from "@/api/basicData/customer.js";
- const FileList = defineAsyncComponent(() =>
- import("@/components/Dialog/FileList.vue")
+const FileList = defineAsyncComponent(() =>
+ import("@/components/Dialog/FileList.vue")
+);
+
+const router = useRouter();
+const route = useRoute();
+const userStore = useUserStore();
+const { proxy } = getCurrentInstance();
+const { tax_rate } = proxy.useDict("tax_rate");
+const tableData = ref([]);
+const productData = ref([]);
+const selectedRows = ref([]);
+const productSelectedRows = ref([]);
+const userList = ref([]);
+const customerOption = ref([]);
+const productOptions = ref([]);
+const modelOptions = ref([]);
+const tableLoading = ref(false);
+const page = reactive({
+ current: 1,
+ size: 100,
+});
+const total = ref(0);
+const fileList = ref([]);
+const deliveryFileList = ref([]);
+
+// 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
+const operationType = ref("");
+const dialogFormVisible = ref(false);
+const data = reactive({
+ searchForm: {
+ customerName: "", // 瀹㈡埛鍚嶇О
+ salesContractNo: "", // 閿�鍞悎鍚岀紪鍙�
+ entryDate: null, // 褰曞叆鏃ユ湡
+ entryDateStart: undefined,
+ entryDateEnd: undefined,
+ },
+ form: {
+ salesContractNo: "",
+ autoGenerateContractNo: true,
+ salesman: "",
+ customerId: "",
+ entryPerson: "",
+ entryDate: "",
+ deliveryDate: "",
+ maintenanceTime: "",
+ productData: [],
+ executionDate: "",
+ hasProductionRecord: false,
+ createTime: "",
+ },
+ rules: {
+ salesman: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+ customerId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+ entryPerson: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+ entryDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+ deliveryDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+ executionDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+ },
+});
+const { form, rules } = toRefs(data);
+const { form: searchForm } = useFormData(data.searchForm);
+// 浜у搧琛ㄥ崟寮规鏁版嵁
+const productFormVisible = ref(false);
+const productOperationType = ref("");
+const currentId = ref("");
+const productFormData = reactive({
+ productForm: {
+ productCategory: "",
+ specificationModel: "",
+ unit: "",
+ quantity: "",
+ taxInclusiveUnitPrice: "",
+ taxRate: "",
+ taxInclusiveTotalPrice: "",
+ taxExclusiveTotalPrice: "",
+ invoiceType: "",
+ isProduction: false,
+ },
+ productRules: {
+ productCategory: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+ productModelId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+ specificationModel: [
+ { required: true, message: "璇烽�夋嫨", trigger: "change" },
+ ],
+ unit: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ quantity: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ taxInclusiveUnitPrice: [
+ { required: true, message: "璇疯緭鍏�", trigger: "blur" },
+ ],
+ taxRate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+ taxInclusiveTotalPrice: [
+ { required: true, message: "璇疯緭鍏�", trigger: "blur" },
+ ],
+ taxExclusiveTotalPrice: [
+ { required: true, message: "璇疯緭鍏�", trigger: "blur" },
+ ],
+ invoiceType: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+ isProduction: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+ },
+});
+const { productForm, productRules } = toRefs(productFormData);
+// 闃叉寰幆璁$畻鐨勬爣蹇�
+const isCalculating = ref(false);
+// 鎵撳嵃鐩稿叧
+const printPreviewVisible = ref(false);
+const printData = ref([]);
+
+// 鎶ヤ环鍗曞鍏ョ浉鍏�
+const quotationDialogVisible = ref(false);
+const quotationLoading = ref(false);
+const quotationList = ref([]);
+const quotationSearchForm = reactive({
+ quotationNo: "",
+ customer: "",
+});
+// 鎶ヤ环鍗曞脊妗嗗垎椤�
+const quotationPage = reactive({
+ current: 1,
+ size: 10,
+ total: 0,
+});
+const selectedQuotation = ref(null);
+
+// 鍙戣揣鐩稿叧
+const deliveryFormVisible = ref(false);
+const currentDeliveryRow = ref(null);
+const getDeliveryBatchQuantity = (item) => {
+ const quantity =
+ item?.qualitity ??
+ item?.quantity ??
+ item?.unLockedQuantity ??
+ item?.qualifiedUnLockedQuantity ??
+ item?.qualifiedQuantity ??
+ item?.stockQuantity;
+ return quantity ?? 0;
+};
+const getCurrentDeliveryRowQuantity = () => {
+ return Number(currentDeliveryRow.value?.noQuantity || 0);
+};
+const getDeliveryBatchDeliveryMax = (row) => {
+ const productQuantity = getCurrentDeliveryRowQuantity();
+ const batchQuantity = Number(getDeliveryBatchQuantity(row) || 0);
+ const otherBatchTotal = (deliveryForm.value.batchNoList || []).reduce(
+ (sum, item) => {
+ if (item?.id === row?.id) return sum;
+ return sum + Number(item?.deliveryQuantity || 0);
+ },
+ 0
);
+ const remainingProductQuantity = Math.max(
+ 0,
+ productQuantity - otherBatchTotal
+ );
+ return Math.max(0, Math.min(batchQuantity, remainingProductQuantity));
+};
+const handleDeliveryBatchQuantityChange = (row) => {
+ const productQuantity = getCurrentDeliveryRowQuantity();
+ const batchQuantity = Number(getDeliveryBatchQuantity(row) || 0);
+ const otherBatchTotal = (deliveryForm.value.batchNoList || []).reduce(
+ (sum, item) => {
+ if (item?.id === row?.id) return sum;
+ return sum + Number(item?.deliveryQuantity || 0);
+ },
+ 0
+ );
+ const remainingProductQuantity = Math.max(
+ 0,
+ productQuantity - otherBatchTotal
+ );
+ const currentValue = Number(row?.deliveryQuantity || 0);
- const router = useRouter();
- const route = useRoute();
- const userStore = useUserStore();
- const { proxy } = getCurrentInstance();
- const { tax_rate } = proxy.useDict("tax_rate");
- const tableData = ref([]);
- const productData = ref([]);
- const selectedRows = ref([]);
- const productSelectedRows = ref([]);
- const userList = ref([]);
- const customerOption = ref([]);
- const productOptions = ref([]);
- const modelOptions = ref([]);
- const tableLoading = ref(false);
- const page = reactive({
- current: 1,
- size: 100,
- });
- const total = ref(0);
- const fileList = ref([]);
- const deliveryFileList = ref([]);
-
- // 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
- const operationType = ref("");
- const dialogFormVisible = ref(false);
- const data = reactive({
- searchForm: {
- customerName: "", // 瀹㈡埛鍚嶇О
- salesContractNo: "", // 閿�鍞悎鍚岀紪鍙�
- entryDate: null, // 褰曞叆鏃ユ湡
- entryDateStart: undefined,
- entryDateEnd: undefined,
- },
- form: {
- salesContractNo: "",
- autoGenerateContractNo: true,
- salesman: "",
- customerId: "",
- entryPerson: "",
- entryDate: "",
- deliveryDate: "",
- maintenanceTime: "",
- productData: [],
- executionDate: "",
- hasProductionRecord: false,
- },
- rules: {
- salesman: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- customerId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- entryPerson: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- entryDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- deliveryDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- executionDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- },
- });
- const { form, rules } = toRefs(data);
- const { form: searchForm } = useFormData(data.searchForm);
- // 浜у搧琛ㄥ崟寮规鏁版嵁
- const productFormVisible = ref(false);
- const productOperationType = ref("");
- const currentId = ref("");
- const productFormData = reactive({
- productForm: {
- productCategory: "",
- specificationModel: "",
- unit: "",
- quantity: "",
- taxInclusiveUnitPrice: "",
- taxRate: "",
- taxInclusiveTotalPrice: "",
- taxExclusiveTotalPrice: "",
- invoiceType: "",
- isProduction: false,
- },
- productRules: {
- productCategory: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- productModelId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- specificationModel: [
- { required: true, message: "璇烽�夋嫨", trigger: "change" },
- ],
- unit: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- quantity: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- taxInclusiveUnitPrice: [
- { required: true, message: "璇疯緭鍏�", trigger: "blur" },
- ],
- taxRate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- taxInclusiveTotalPrice: [
- { required: true, message: "璇疯緭鍏�", trigger: "blur" },
- ],
- taxExclusiveTotalPrice: [
- { required: true, message: "璇疯緭鍏�", trigger: "blur" },
- ],
- invoiceType: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- isProduction: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
- },
- });
- const { productForm, productRules } = toRefs(productFormData);
- // 闃叉寰幆璁$畻鐨勬爣蹇�
- const isCalculating = ref(false);
- // 鎵撳嵃鐩稿叧
- const printPreviewVisible = ref(false);
- const printData = ref([]);
-
- // 鎶ヤ环鍗曞鍏ョ浉鍏�
- const quotationDialogVisible = ref(false);
- const quotationLoading = ref(false);
- const quotationList = ref([]);
- const quotationSearchForm = reactive({
- quotationNo: "",
- customer: "",
- });
- // 鎶ヤ环鍗曞脊妗嗗垎椤�
- const quotationPage = reactive({
- current: 1,
- size: 10,
- total: 0,
- });
- const selectedQuotation = ref(null);
-
- // 鍙戣揣鐩稿叧
- const deliveryFormVisible = ref(false);
- const currentDeliveryRow = ref(null);
- const getDeliveryBatchQuantity = item => {
- const quantity =
- item?.qualitity ??
- item?.quantity ??
- item?.unLockedQuantity ??
- item?.qualifiedUnLockedQuantity ??
- item?.qualifiedQuantity ??
- item?.stockQuantity;
- return quantity ?? 0;
- };
- const getCurrentDeliveryRowQuantity = () => {
- return Number(currentDeliveryRow.value?.noQuantity || 0);
- };
- const getDeliveryBatchDeliveryMax = row => {
- const productQuantity = getCurrentDeliveryRowQuantity();
- const batchQuantity = Number(getDeliveryBatchQuantity(row) || 0);
- const otherBatchTotal = (deliveryForm.value.batchNoList || []).reduce(
- (sum, item) => {
- if (item?.id === row?.id) return sum;
- return sum + Number(item?.deliveryQuantity || 0);
- },
- 0
- );
- const remainingProductQuantity = Math.max(
- 0,
- productQuantity - otherBatchTotal
- );
- return Math.max(0, Math.min(batchQuantity, remainingProductQuantity));
- };
- const handleDeliveryBatchQuantityChange = row => {
- const productQuantity = getCurrentDeliveryRowQuantity();
- const batchQuantity = Number(getDeliveryBatchQuantity(row) || 0);
- const otherBatchTotal = (deliveryForm.value.batchNoList || []).reduce(
- (sum, item) => {
- if (item?.id === row?.id) return sum;
- return sum + Number(item?.deliveryQuantity || 0);
- },
- 0
- );
- const remainingProductQuantity = Math.max(
- 0,
- productQuantity - otherBatchTotal
- );
- const currentValue = Number(row?.deliveryQuantity || 0);
-
- if (currentValue > batchQuantity) {
- row.deliveryQuantity = batchQuantity;
- proxy.$modal.msgWarning("鍙戣揣鏁伴噺涓嶈兘澶т簬搴撳瓨鏁伴噺");
- } else if (currentValue > remainingProductQuantity) {
- row.deliveryQuantity = remainingProductQuantity;
- proxy.$modal.msgWarning("鎵�鏈夋壒娆″彂璐ф暟閲忎箣鍜屼笉鑳藉ぇ浜庡緟鍙戣揣鏁伴噺");
- }
- };
- const getSelectedDeliveryBatchRows = () => {
- return (deliveryForm.value.batchNoList || []).filter(
- item => Number(item?.deliveryQuantity || 0) > 0
- );
- };
- const getDeliveryBatchNoList = async productModelId => {
- if (!productModelId) return [];
- const res = await getStockInventoryByModelId(productModelId);
- const rawList = Array.isArray(res?.data)
- ? res.data
- : res?.data?.records || res?.data?.rows || [];
- const seenIds = new Set();
- return rawList
- .filter(item => {
- if (!item?.id || !item?.batchNo || seenIds.has(item.id)) {
- return false;
- }
- seenIds.add(item.id);
- return true;
- })
- .map(item => ({
- ...item,
- deliveryQuantity: 0,
- }));
- };
- const validateDeliveryShippingCarNumber = (_rule, value, callback) => {
- if (deliveryForm.value.type === "璐ц溅" && !value) {
- return callback(new Error("璇疯緭鍏ュ彂璐ц溅鐗屽彿"));
- }
- callback();
- };
- const validateDeliveryExpressCompany = (_rule, value, callback) => {
- if (deliveryForm.value.type === "蹇��" && !value) {
- return callback(new Error("璇疯緭鍏ュ揩閫掑叕鍙�"));
- }
- callback();
- };
- const deliveryFormData = reactive({
- deliveryForm: {
- shippingCarNumber: "",
- expressCompany: "",
- expressNumber: "",
- type: "璐ц溅", // 璐ц溅, 蹇��
- },
- deliveryRules: {
- shippingCarNumber: [
- { validator: validateDeliveryShippingCarNumber, trigger: "blur" },
- ],
- expressCompany: [
- { validator: validateDeliveryExpressCompany, trigger: "blur" },
- ],
- type: [{ required: true, message: "璇烽�夋嫨鍙戣揣绫诲瀷", trigger: "change" }],
- },
- });
- const { deliveryForm, deliveryRules } = toRefs(deliveryFormData);
-
- // 瀵煎叆鐩稿叧
- const importUploadRef = ref(null);
- const importUpload = reactive({
- title: "瀵煎叆閿�鍞彴璐�",
- open: false,
- url: import.meta.env.VITE_APP_BASE_API + "/sales/ledger/import",
- headers: { Authorization: "Bearer " + getToken() },
- isUploading: false,
- beforeUpload: file => {
- const isExcel = file.name.endsWith(".xlsx") || file.name.endsWith(".xls");
- const isLt10M = file.size / 1024 / 1024 < 10;
- if (!isExcel) {
- proxy.$modal.msgError("涓婁紶鏂囦欢鍙兘鏄� xlsx/xls 鏍煎紡!");
+ if (currentValue > batchQuantity) {
+ row.deliveryQuantity = batchQuantity;
+ proxy.$modal.msgWarning("鍙戣揣鏁伴噺涓嶈兘澶т簬搴撳瓨鏁伴噺");
+ } else if (currentValue > remainingProductQuantity) {
+ row.deliveryQuantity = remainingProductQuantity;
+ proxy.$modal.msgWarning("鎵�鏈夋壒娆″彂璐ф暟閲忎箣鍜屼笉鑳藉ぇ浜庡緟鍙戣揣鏁伴噺");
+ }
+};
+const getSelectedDeliveryBatchRows = () => {
+ return (deliveryForm.value.batchNoList || []).filter(
+ (item) => Number(item?.deliveryQuantity || 0) > 0
+ );
+};
+const getDeliveryBatchNoList = async (productModelId) => {
+ if (!productModelId) return [];
+ const res = await getStockInventoryByModelId(productModelId);
+ const rawList = Array.isArray(res?.data)
+ ? res.data
+ : res?.data?.records || res?.data?.rows || [];
+ const seenIds = new Set();
+ return rawList
+ .filter((item) => {
+ if (!item?.id || !item?.batchNo || seenIds.has(item.id)) {
return false;
}
- if (!isLt10M) {
- proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃 10MB!");
- return false;
- }
+ seenIds.add(item.id);
return true;
- },
- onChange: (file, fileList) => {
- console.log("鏂囦欢鐘舵�佹敼鍙�", file, fileList);
- },
- onProgress: (event, file, fileList) => {
- console.log("涓婁紶涓�...", event.percent);
- },
- onSuccess: (response, file, fileList) => {
- console.log("涓婁紶鎴愬姛", response, file, fileList);
- importUpload.isUploading = false;
- if (response.code === 200) {
- proxy.$modal.msgSuccess("瀵煎叆鎴愬姛");
- importUpload.open = false;
- if (importUploadRef.value) {
- importUploadRef.value.clearFiles();
- }
- getList();
- } else {
- proxy.$modal.msgError(response.msg || "瀵煎叆澶辫触");
- }
- },
- onError: (error, file, fileList) => {
- console.error("涓婁紶澶辫触", error, file, fileList);
- importUpload.isUploading = false;
- proxy.$modal.msgError("瀵煎叆澶辫触锛岃閲嶈瘯");
- },
- });
+ })
+ .map((item) => ({
+ ...item,
+ deliveryQuantity: 0,
+ }));
+};
+const validateDeliveryShippingCarNumber = (_rule, value, callback) => {
+ if (deliveryForm.value.type === "璐ц溅" && !value) {
+ return callback(new Error("璇疯緭鍏ュ彂璐ц溅鐗屽彿"));
+ }
+ callback();
+};
+const validateDeliveryExpressCompany = (_rule, value, callback) => {
+ if (deliveryForm.value.type === "蹇��" && !value) {
+ return callback(new Error("璇疯緭鍏ュ揩閫掑叕鍙�"));
+ }
+ callback();
+};
+const deliveryFormData = reactive({
+ deliveryForm: {
+ shippingCarNumber: "",
+ expressCompany: "",
+ expressNumber: "",
+ type: "璐ц溅", // 璐ц溅, 蹇��
+ },
+ deliveryRules: {
+ shippingCarNumber: [
+ { validator: validateDeliveryShippingCarNumber, trigger: "blur" },
+ ],
+ expressCompany: [
+ { validator: validateDeliveryExpressCompany, trigger: "blur" },
+ ],
+ type: [{ required: true, message: "璇烽�夋嫨鍙戣揣绫诲瀷", trigger: "change" }],
+ },
+});
+const { deliveryForm, deliveryRules } = toRefs(deliveryFormData);
- const changeDaterange = value => {
- if (value) {
- searchForm.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
- searchForm.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
- } else {
- searchForm.entryDateStart = undefined;
- searchForm.entryDateEnd = undefined;
+// 瀵煎叆鐩稿叧
+const importUploadRef = ref(null);
+const importUpload = reactive({
+ title: "瀵煎叆閿�鍞彴璐�",
+ open: false,
+ url: import.meta.env.VITE_APP_BASE_API + "/sales/ledger/import",
+ headers: { Authorization: "Bearer " + getToken() },
+ isUploading: false,
+ beforeUpload: (file) => {
+ const isExcel = file.name.endsWith(".xlsx") || file.name.endsWith(".xls");
+ const isLt10M = file.size / 1024 / 1024 < 10;
+ if (!isExcel) {
+ proxy.$modal.msgError("涓婁紶鏂囦欢鍙兘鏄� xlsx/xls 鏍煎紡!");
+ return false;
}
- handleQuery();
- };
-
- // 鏌ヨ鍒楄〃
- /** 鎼滅储鎸夐挳鎿嶄綔 */
- const handleQuery = () => {
- // 鍙湁鍦ㄧ偣鍑绘悳绱㈡寜閽椂鎵嶉噸缃〉鐮佸埌绗竴椤�
- // 閬垮厤琛ㄥ崟瀛楁change浜嬩欢骞叉壈鍒嗛〉
- if (arguments.length === 0) {
- page.current = 1;
- }
- expandedRowKeys.value = [];
- getList();
- };
- const paginationChange = obj => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
- };
- const getList = () => {
- tableLoading.value = true;
- const { entryDate, ...rest } = searchForm;
- // 灏嗚寖鍥存棩鏈熷瓧娈典紶閫掔粰鍚庣
- const params = { ...rest, ...page };
- // 绉婚櫎褰曞叆鏃ユ湡鐨勯粯璁ゅ�艰缃紝鍙繚鐣欒寖鍥存棩鏈熷瓧娈�
- delete params.entryDate;
- return ledgerListPage(params)
- .then(res => {
- tableLoading.value = false;
- tableData.value = res.records;
- tableData.value.map(item => {
- item.children = [];
- });
- total.value = res.total;
- return res;
- })
- .catch(() => {
- tableLoading.value = false;
- });
- };
- // 鑾峰彇浜у搧澶х被tree鏁版嵁
- const getProductOptions = () => {
- // 杩斿洖 Promise锛屼究浜庡湪缂栬緫浜у搧鏃剁瓑寰呭姞杞藉畬鎴�
- return productTreeList().then(res => {
- productOptions.value = convertIdToValue(res);
- return productOptions.value;
- });
- };
- const formattedNumber = (row, column, cellValue) => {
- if (cellValue === undefined || cellValue === null || cellValue === "") {
- return "0.00";
- }
- return parseFloat(cellValue).toFixed(2);
- };
- const findLedgerRecordByRow = row => {
- if (!row) return null;
- if (
- row.maintainer !== undefined ||
- row.maintainerName !== undefined ||
- row.entryPerson !== undefined ||
- row.entryPersonName !== undefined
- ) {
- return row;
- }
- if (row.salesLedgerId !== undefined && row.salesLedgerId !== null) {
- return (
- tableData.value.find(
- item => String(item.id) === String(row.salesLedgerId)
- ) || null
- );
- }
- return null;
- };
- const isCurrentUserMaintainer = row => {
- const ledgerRecord = findLedgerRecordByRow(row);
- if (!ledgerRecord) return true;
- const currentUserId = String(userStore.id ?? "");
- const currentNickName = String(userStore.nickName ?? "").trim();
- const maintainerId = ledgerRecord.maintainerId ?? ledgerRecord.entryPerson;
- const maintainerName =
- ledgerRecord.maintainerName ??
- ledgerRecord.maintainer ??
- ledgerRecord.entryPersonName;
- if (
- maintainerId !== undefined &&
- maintainerId !== null &&
- String(maintainerId) !== ""
- ) {
- return String(maintainerId) === currentUserId;
- }
- if (
- maintainerName !== undefined &&
- maintainerName !== null &&
- String(maintainerName).trim() !== ""
- ) {
- return String(maintainerName).trim() === currentNickName;
+ if (!isLt10M) {
+ proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃 10MB!");
+ return false;
}
return true;
- };
- const canEditLedger = row => isCurrentUserMaintainer(row);
- const canDeleteLedger = row => isCurrentUserMaintainer(row);
- const sensitiveAmountFormatter = (row, column, cellValue) => {
- if (!isCurrentUserMaintainer(row)) {
- return "*****";
- }
- return formattedNumber(row, column, cellValue);
- };
- // 鑾峰彇tree瀛愭暟鎹�
- const getModels = value => {
- productForm.value.productCategory = findNodeById(productOptions.value, value);
- modelList({ id: value }).then(res => {
- modelOptions.value = res;
- });
- };
- const getProductModel = value => {
- const index = modelOptions.value.findIndex(item => item.id === value);
- if (index !== -1) {
- productForm.value.specificationModel = modelOptions.value[index].model;
- productForm.value.unit = modelOptions.value[index].unit;
+ },
+ onChange: (file, fileList) => {
+ console.log("鏂囦欢鐘舵�佹敼鍙�", file, fileList);
+ },
+ onProgress: (event, file, fileList) => {
+ console.log("涓婁紶涓�...", event.percent);
+ },
+ onSuccess: (response, file, fileList) => {
+ console.log("涓婁紶鎴愬姛", response, file, fileList);
+ importUpload.isUploading = false;
+ if (response.code === 200) {
+ proxy.$modal.msgSuccess("瀵煎叆鎴愬姛");
+ importUpload.open = false;
+ if (importUploadRef.value) {
+ importUploadRef.value.clearFiles();
+ }
+ getList();
} else {
- productForm.value.specificationModel = null;
- productForm.value.unit = null;
+ proxy.$modal.msgError(response.msg || "瀵煎叆澶辫触");
}
- };
- const findNodeById = (nodes, productId) => {
- for (let i = 0; i < nodes.length; i++) {
- if (nodes[i].value === productId) {
- return nodes[i].label; // 鎵惧埌鑺傜偣锛岃繑鍥炶鑺傜偣
- }
- if (nodes[i].children && nodes[i].children.length > 0) {
- const foundNode = findNodeById(nodes[i].children, productId);
- if (foundNode) {
- return foundNode; // 鍦ㄥ瓙鑺傜偣涓壘鍒帮紝杩斿洖璇ヨ妭鐐�
- }
- }
- }
- return null; // 娌℃湁鎵惧埌鑺傜偣锛岃繑鍥瀗ull
- };
+ },
+ onError: (error, file, fileList) => {
+ console.error("涓婁紶澶辫触", error, file, fileList);
+ importUpload.isUploading = false;
+ proxy.$modal.msgError("瀵煎叆澶辫触锛岃閲嶈瘯");
+ },
+});
- function convertIdToValue(data) {
- return data.map(item => {
- const { id, children, ...rest } = item;
- const newItem = {
- ...rest,
- value: id, // 灏� id 鏀逛负 value
- };
- if (children && children.length > 0) {
- newItem.children = convertIdToValue(children);
- }
-
- return newItem;
- });
+const changeDaterange = (value) => {
+ if (value) {
+ searchForm.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
+ searchForm.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
+ } else {
+ searchForm.entryDateStart = undefined;
+ searchForm.entryDateEnd = undefined;
}
+ handleQuery();
+};
- // 鏍规嵁鍚嶇О鍙嶆煡浜у搧澶х被 id锛屼究浜庝粎瀛樺悕绉版椂鐨勫弽鏄�
- function findNodeIdByLabel(nodes, label) {
- if (!label) return null;
- for (let i = 0; i < nodes.length; i++) {
- const node = nodes[i];
- if (node.label === label) return node.value;
- if (node.children && node.children.length > 0) {
- const found = findNodeIdByLabel(node.children, label);
- if (found !== null && found !== undefined) return found;
- }
- }
- return null;
+// 鏌ヨ鍒楄〃
+/** 鎼滅储鎸夐挳鎿嶄綔 */
+const handleQuery = () => {
+ // 鍙湁鍦ㄧ偣鍑绘悳绱㈡寜閽椂鎵嶉噸缃〉鐮佸埌绗竴椤�
+ // 閬垮厤琛ㄥ崟瀛楁change浜嬩欢骞叉壈鍒嗛〉
+ if (arguments.length === 0) {
+ page.current = 1;
}
-
- // 琛ㄦ牸閫夋嫨鏁版嵁
- const handleSelectionChange = selection => {
- // 杩囨护鎺夊瓙鏁版嵁
- selectedRows.value = selection.filter(item => item.children !== undefined);
- console.log("selection", selectedRows.value);
- };
- const productSelected = selectedRows => {
- productSelectedRows.value = selectedRows;
- };
- const expandedRowKeys = ref([]);
- // 灞曞紑琛�
- const expandChange = (row, expandedRows) => {
- if (expandedRows.length > 0) {
- expandedRowKeys.value = [];
- try {
- productList({ salesLedgerId: row.id, type: 1 }).then(res => {
- const index = tableData.value.findIndex(item => item.id === row.id);
- if (index > -1) {
- tableData.value[index].children = res.data;
- }
- expandedRowKeys.value.push(row.id);
- });
- } catch (error) {
- console.log(error);
- }
- } else {
- expandedRowKeys.value = [];
- }
- };
-
- // 娣诲姞琛ㄨ绫诲悕鏂规硶
- const tableRowClassName = ({ row }) => {
- if (!row.deliveryDate) return "";
- if (row.isFh) return "";
-
- const diff = row.deliveryDaysDiff;
- if (diff === 15) {
- return "yellow";
- } else if (diff === 10) {
- return "pink";
- } else if (diff === 2) {
- return "purple";
- } else if (diff < 2) {
- return "red";
- }
- };
- // 涓昏〃鍚堣鏂规硶
- const summarizeMainTable = param => {
- return proxy.summarizeTable(param, [
- "contractAmount",
- "taxInclusiveTotalPrice",
- "taxExclusiveTotalPrice",
- ]);
- };
- // 瀛愯〃鍚堣鏂规硶
- const summarizeChildrenTable = (param, parentRow) => {
- if (!isCurrentUserMaintainer(parentRow)) {
- const { columns } = param;
- return columns.map((column, index) => {
- if (index === 0) {
- return "鍚堣";
- }
- if (
- [
- "taxInclusiveUnitPrice",
- "taxInclusiveTotalPrice",
- "taxExclusiveTotalPrice",
- ].includes(column.property)
- ) {
- return "*****";
- }
- return "";
+ expandedRowKeys.value = [];
+ getList();
+};
+const paginationChange = (obj) => {
+ page.current = obj.page;
+ page.size = obj.limit;
+ getList();
+};
+const getList = () => {
+ tableLoading.value = true;
+ const { entryDate, ...rest } = searchForm;
+ // 灏嗚寖鍥存棩鏈熷瓧娈典紶閫掔粰鍚庣
+ const params = { ...rest, ...page };
+ // 绉婚櫎褰曞叆鏃ユ湡鐨勯粯璁ゅ�艰缃紝鍙繚鐣欒寖鍥存棩鏈熷瓧娈�
+ delete params.entryDate;
+ return ledgerListPage(params)
+ .then((res) => {
+ tableLoading.value = false;
+ tableData.value = res.records;
+ tableData.value.map((item) => {
+ item.children = [];
});
- }
- return proxy.summarizeTable(param, [
- "taxInclusiveUnitPrice",
- "taxInclusiveTotalPrice",
- "taxExclusiveTotalPrice",
- ]);
- };
- // 鎵撳紑寮规
- const openForm = async (type, row) => {
- if (type === "edit" && row && !canEditLedger(row)) {
- proxy.$modal.msgWarning("褰撳墠绯荤粺鐧诲綍浜轰笉鏄淮鎶や汉锛屼笉鑳界紪杈戞暟鎹�");
- return;
- }
- operationType.value = type;
- form.value = {};
- productData.value = [];
- selectedQuotation.value = null;
- let userLists = await userListNoPage();
- userList.value = userLists.data;
- listCustomer({ current: -1, size: -1, type: 0 }).then(res => {
- customerOption.value = res.data.records;
- });
- form.value.entryPerson = userStore.id;
- if (type === "add") {
- // 鏂板鏃惰缃綍鍏ユ棩鏈熶负褰撳ぉ
- form.value.entryDate = getCurrentDate();
- // 绛捐鏃ユ湡榛樿涓哄綋澶�
- form.value.executionDate = getCurrentDate();
- // 榛樿鑷姩鐢熸垚閿�鍞悎鍚屽彿
- form.value.autoGenerateContractNo = true;
- } else {
- currentId.value = row.id;
- getSalesLedgerWithProducts({ id: row.id, type: 1 }).then(res => {
- form.value = { ...res };
- form.value.entryPerson = Number(res.entryPerson);
- productData.value = form.value.productData;
- fileList.value = form.value.storageBlobVOs;
- // 缂栬緫鏃惰缃嚜鍔ㄧ敓鎴愪负false锛屽厑璁告墜鍔ㄤ慨鏀�
- form.value.autoGenerateContractNo = false;
- });
- }
- // let userAll = await userStore.getInfo()
- // userList.value.forEach(element => {
- // if(userAll.user.nickName === element.nickName && userAll.user.userName === element.userName) {
- // form.value.entryPerson = userAll.user.userId // 璁剧疆榛樿涓氬姟鍛樹负褰撳墠鐢ㄦ埛
- // }
- // });
- form.value.entryDate = getCurrentDate(); // 璁剧疆榛樿褰曞叆鏃ユ湡涓哄綋鍓嶆棩鏈�
- dialogFormVisible.value = true;
- };
-
- // 鎵撳紑鎶ヤ环鍗曢�夋嫨寮圭獥锛堜粎瀹℃壒閫氳繃锛�
- const openQuotationDialog = async () => {
- if (operationType.value === "view") return;
- quotationDialogVisible.value = true;
- // 鎵撳紑寮圭獥鏃堕噸缃垎椤靛埌绗竴椤�
- quotationPage.current = 1;
- // 鍏堢‘淇濆鎴峰垪琛ㄥ凡鍔犺浇锛屼究浜庡悗缁洖濉� customerId
- if (!customerOption.value || customerOption.value.length === 0) {
- try {
- listCustomer({ current: -1, size: -1 }).then(res => {
- customerOption.value = res.data.records;
- });
- } catch (e) {
- // ignore锛屽厑璁哥敤鎴峰悗缁墜鍔ㄩ�夋嫨瀹㈡埛
- }
- }
- await fetchQuotationList();
- };
-
- const fetchQuotationList = async () => {
- quotationLoading.value = true;
- try {
- const params = {
- // 鍚庣鍒嗛〉瀛楁锛歝urrent / size
- current: quotationPage.current,
- size: quotationPage.size,
- ...quotationSearchForm,
- status: "閫氳繃",
- };
- const res = await getQuotationList(params);
- quotationList.value = res?.data?.records || [];
- quotationPage.total = res?.data?.total || 0;
- } finally {
- quotationLoading.value = false;
- }
- };
-
- const resetQuotationSearch = async () => {
- quotationSearchForm.quotationNo = "";
- quotationSearchForm.customer = "";
- quotationPage.current = 1;
- await fetchQuotationList();
- };
-
- // 鎶ヤ环鍗曞脊妗嗗垎椤靛垏鎹�
- const quotationPaginationChange = obj => {
- quotationPage.current = obj.page;
- quotationPage.size = obj.limit;
- fetchQuotationList();
- };
-
- // 閫変腑鎶ヤ环鍗曞悗鍥炲~鍒板彴璐﹁〃鍗�
- const applyQuotation = row => {
- if (!row) return;
- selectedQuotation.value = row;
-
- // 涓氬姟鍛�
- form.value.salesman = (row.salesperson || "").trim();
-
- // 瀹㈡埛鍚嶇О -> customerId
- const qCustomerName = String(row.customer || "").trim();
- const customer = (customerOption.value || []).find(c => {
- const name = String(c.customerName || "").trim();
- return (
- name === qCustomerName ||
- name.includes(qCustomerName) ||
- qCustomerName.includes(name)
- );
- });
- if (customer?.id) {
- form.value.customerId = customer.id;
- } else {
- // 濡傛灉鎵句笉鍒帮紝淇濈暀鍘熷�硷紙鍏佽鐢ㄦ埛鎵嬪姩閫夋嫨/涓嶆墦鏂凡鏈夎緭鍏ワ級
- form.value.customerId = form.value.customerId || "";
- }
-
- // 浜у搧淇℃伅鏄犲皠锛氭姤浠� products -> 鍙拌处 productData
- const products = Array.isArray(row.products) ? row.products : [];
- productData.value = products.map(p => {
- const quantity = Number(p.quantity ?? 0) || 0;
- const unitPrice = Number(p.unitPrice ?? 0) || 0;
- const taxRate = "13"; // 榛樿 13%锛屼究浜庣洿鎺ユ彁浜わ紙濡傞渶鍙湪浜у搧涓嚜琛屼慨鏀癸級
- const taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
- const taxExclusiveTotalPrice = proxy.calculateTaxExclusiveTotalPrice(
- taxInclusiveTotalPrice,
- taxRate
- );
- return {
- // 鍙拌处瀛楁
- productCategory: p.product || p.productName || "",
- specificationModel: p.specification || "",
- unit: p.unit || "",
- quantity: quantity,
- taxRate: taxRate,
- taxInclusiveUnitPrice: unitPrice.toFixed(2),
- taxInclusiveTotalPrice: taxInclusiveTotalPrice,
- taxExclusiveTotalPrice: taxExclusiveTotalPrice,
- invoiceType: "澧炴櫘绁�",
- isProduction: true,
- productId: p.productId,
- productModelId: p.productModelId,
- };
- });
-
- quotationDialogVisible.value = false;
- };
-
- function changs(val) {
- console.log(val);
- }
-
- // 鎻愪氦琛ㄥ崟
- const submitForm = () => {
- proxy.$refs["formRef"].validate(valid => {
- if (valid) {
- console.log("productData.value--", productData.value);
- if (productData.value !== null && productData.value.length > 0) {
- form.value.productData = proxy.HaveJson(productData.value);
- } else {
- proxy.$modal.msgWarning("璇锋坊鍔犱骇鍝佷俊鎭�");
- return;
- }
- form.value.storageBlobDTOs = fileList;
- form.value.type = 1;
- if (form.value.autoGenerateContractNo) {
- form.value.salesContractNo = "";
- }
- addOrUpdateSalesLedger(form.value).then(res => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeDia();
- expandedRowKeys.value = [];
- getList();
- });
- }
- });
- };
- // 鍏抽棴寮规
- const closeDia = () => {
- proxy.resetForm("formRef");
- dialogFormVisible.value = false;
- };
-
- const productIndex = ref(0);
- // 鎵撳紑浜у搧寮规
- const openProductForm = async (type, row, index) => {
- // 缂栬緫鏃舵鏌ヤ骇鍝佹槸鍚﹀凡鍙戣揣鎴栧鏍搁�氳繃
- if (type === "edit" && isProductShipped(row)) {
- proxy.$modal.msgWarning("宸插彂璐ф垨瀹℃牳閫氳繃鐨勪骇鍝佷笉鑳界紪杈�");
- return;
- }
-
- productOperationType.value = type;
- productForm.value = {};
- if (type === "add") {
- productForm.value.isProduction = true;
- }
- proxy.resetForm("productFormRef");
- if (type === "edit") {
- productForm.value = { ...row };
- productIndex.value = index;
- // 缂栬緫鏃舵牴鎹骇鍝佸ぇ绫诲悕绉板弽鏌� tree 鑺傜偣 id锛屽苟鍔犺浇瑙勬牸鍨嬪彿鍒楄〃
- try {
- const options =
- productOptions.value && productOptions.value.length > 0
- ? productOptions.value
- : await getProductOptions();
- const categoryId = findNodeIdByLabel(
- options,
- productForm.value.productCategory
- );
- if (categoryId) {
- const models = await modelList({ id: categoryId });
- modelOptions.value = models || [];
- // 鏍规嵁褰撳墠瑙勬牸鍨嬪彿鍚嶇О鍙嶆煡骞惰缃� productModelId锛屼究浜庝笅鎷夋鏄剧ず宸查�夊��
- const currentModel = (modelOptions.value || []).find(
- m => m.model === productForm.value.specificationModel
- );
- if (currentModel) {
- productForm.value.productModelId = currentModel.id;
- }
- }
- } catch (e) {
- // 鍔犺浇澶辫触鏃朵繚鎸佸彲缂栬緫锛屼笉涓柇寮圭獥
- console.error("鍔犺浇浜у搧瑙勬牸鍨嬪彿澶辫触", e);
- }
- } else {
- getProductOptions();
- }
- productFormVisible.value = true;
- };
- // 鎻愪氦浜у搧琛ㄥ崟
- const submitProduct = () => {
- proxy.$refs["productFormRef"].validate(valid => {
- if (valid) {
- if (operationType.value === "edit") {
- submitProductEdit();
- } else {
- if (productOperationType.value === "add") {
- productData.value.push({ ...productForm.value });
- } else {
- productData.value[productIndex.value] = { ...productForm.value };
- }
- closeProductDia();
- }
- }
- });
- };
- const submitProductEdit = () => {
- productForm.value.salesLedgerId = currentId.value;
- productForm.value.type = 1;
- addOrUpdateSalesLedgerProduct(productForm.value).then(res => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeProductDia();
- getSalesLedgerWithProducts({ id: currentId.value, type: 1 }).then(res => {
- productData.value = res.productData;
- });
- });
- };
- // 鍒犻櫎浜у搧
- const deleteProduct = () => {
- if (productSelectedRows.value.length === 0) {
- proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
- return;
- }
-
- // 妫�鏌ユ槸鍚︽湁宸插彂璐ф垨瀹℃牳閫氳繃鐨勪骇鍝�
- const shippedProducts = productSelectedRows.value.filter(row =>
- isProductShipped(row)
- );
- if (shippedProducts.length > 0) {
- proxy.$modal.msgWarning("宸插彂璐ф垨瀹℃牳閫氳繃鐨勪骇鍝佷笉鑳藉垹闄�");
- return;
- }
-
- if (operationType.value === "add") {
- productData.value = productData.value.filter(
- item => !productSelectedRows.value.includes(item)
- );
- productSelectedRows.value = [];
- } else {
- let ids = [];
- if (productSelectedRows.value.length > 0) {
- ids = productSelectedRows.value.map(item => item.id);
- }
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- delProduct(ids).then(res => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- closeProductDia();
- getSalesLedgerWithProducts({ id: currentId.value, type: 1 }).then(
- res => {
- productData.value = res.productData;
- }
- );
- });
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
- }
- };
- // 鍏抽棴浜у搧寮规
- const closeProductDia = () => {
- proxy.resetForm("productFormRef");
- productFormVisible.value = false;
- };
- // 瀵煎叆
- const handleImport = () => {
- importUpload.title = "瀵煎叆閿�鍞彴璐�";
- importUpload.open = true;
- if (importUploadRef.value) {
- importUploadRef.value.clearFiles();
- }
- };
-
- // 涓嬭浇瀵煎叆妯℃澘
- const downloadTemplate = () => {
- proxy.download("/sales/ledger/exportTemplate", {}, "閿�鍞彴璐﹀鍏ユā鏉�.xlsx");
- };
-
- // 鎻愪氦瀵煎叆鏂囦欢
- const submitImportFile = () => {
- importUpload.isUploading = true;
- proxy.$refs["importUploadRef"].submit();
- };
-
- // 瀵煎嚭
- const handleOut = () => {
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
+ total.value = res.total;
+ return res;
})
- .then(() => {
- proxy.download("/sales/ledger/export", {}, "閿�鍞彴璐�.xlsx");
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
- };
- /** 鍒ゆ柇鍗曚釜浜у搧鏄惁宸插彂璐э紙鏍规嵁shippingStatus鍒ゆ柇锛屽凡鍙戣揣鎴栧鏍搁�氳繃涓嶅彲缂栬緫鍜屽垹闄わ級 */
- const isProductShipped = product => {
- if (!product) return false;
- const status = String(product.shippingStatus || "").trim();
- // 濡傛灉鍙戣揣鐘舵�佹槸"宸插彂璐�"鎴�"瀹℃牳閫氳繃"锛屽垯涓嶅彲缂栬緫鍜屽垹闄�
- return status === "宸插彂璐�" || status === "瀹℃牳閫氳繃";
- };
-
- /** 鍒ゆ柇閿�鍞鍗曚笅鏄惁瀛樺湪宸插彂璐�/鍙戣揣瀹屾垚鐨勪骇鍝侊紙涓嶅彲鍒犻櫎锛� */
- const hasShippedProducts = products => {
- if (!products || !products.length) return false;
- return products.some(p => {
- const status = String(p.shippingStatus || "").trim();
- // 鏈夊彂璐ф棩鏈熸垨杞︾墝鍙疯涓哄凡鍙戣揣
- if (p.shippingDate || p.shippingCarNumber) return true;
- // 宸茶繘琛屽彂璐с�佸彂璐у畬鎴愩�佸凡鍙戣揣 鍧囦笉鍙垹闄�
- return (
- status === "宸茶繘琛屽彂璐�" || status === "鍙戣揣瀹屾垚" || status === "宸插彂璐�"
- );
+ .catch(() => {
+ tableLoading.value = false;
});
- };
-
- // 鍒犻櫎
- const handleDelete = async () => {
- if (selectedRows.value.length === 0) {
- proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
- return;
- }
- const unauthorizedRows = selectedRows.value.filter(
- row => !canDeleteLedger(row)
+};
+// 鑾峰彇浜у搧澶х被tree鏁版嵁
+const getProductOptions = () => {
+ // 杩斿洖 Promise锛屼究浜庡湪缂栬緫浜у搧鏃剁瓑寰呭姞杞藉畬鎴�
+ return productTreeList().then((res) => {
+ productOptions.value = convertIdToValue(res);
+ return productOptions.value;
+ });
+};
+const formattedNumber = (row, column, cellValue) => {
+ if (cellValue === undefined || cellValue === null || cellValue === "") {
+ return "0.00";
+ }
+ return parseFloat(cellValue).toFixed(2);
+};
+const findLedgerRecordByRow = (row) => {
+ if (!row) return null;
+ if (
+ row.maintainer !== undefined ||
+ row.maintainerName !== undefined ||
+ row.entryPerson !== undefined ||
+ row.entryPersonName !== undefined
+ ) {
+ return row;
+ }
+ if (row.salesLedgerId !== undefined && row.salesLedgerId !== null) {
+ return (
+ tableData.value.find(
+ (item) => String(item.id) === String(row.salesLedgerId)
+ ) || null
);
- if (unauthorizedRows.length > 0) {
- proxy.$modal.msgWarning("褰撳墠鐧诲綍鐢ㄦ埛涓嶆槸褰曞叆浜猴紝涓嶈兘鍒犻櫎璇ユ暟鎹�");
- return;
+ }
+ return null;
+};
+const isCurrentUserMaintainer = (row) => {
+ const ledgerRecord = findLedgerRecordByRow(row);
+ if (!ledgerRecord) return true;
+ const currentUserId = String(userStore.id ?? "");
+ const currentNickName = String(userStore.nickName ?? "").trim();
+ const maintainerId = ledgerRecord.maintainerId ?? ledgerRecord.entryPerson;
+ const maintainerName =
+ ledgerRecord.maintainerName ??
+ ledgerRecord.maintainer ??
+ ledgerRecord.entryPersonName;
+ if (
+ maintainerId !== undefined &&
+ maintainerId !== null &&
+ String(maintainerId) !== ""
+ ) {
+ return String(maintainerId) === currentUserId;
+ }
+ if (
+ maintainerName !== undefined &&
+ maintainerName !== null &&
+ String(maintainerName).trim() !== ""
+ ) {
+ return String(maintainerName).trim() === currentNickName;
+ }
+ return true;
+};
+const canEditLedger = (row) => isCurrentUserMaintainer(row);
+const canDeleteLedger = (row) => isCurrentUserMaintainer(row);
+const sensitiveAmountFormatter = (row, column, cellValue) => {
+ if (!isCurrentUserMaintainer(row)) {
+ return "*****";
+ }
+ return formattedNumber(row, column, cellValue);
+};
+// 鑾峰彇tree瀛愭暟鎹�
+const getModels = (value) => {
+ productForm.value.productCategory = findNodeById(productOptions.value, value);
+ modelList({ id: value }).then((res) => {
+ modelOptions.value = res;
+ });
+};
+const getProductModel = (value) => {
+ const index = modelOptions.value.findIndex((item) => item.id === value);
+ if (index !== -1) {
+ productForm.value.specificationModel = modelOptions.value[index].model;
+ productForm.value.unit = modelOptions.value[index].unit;
+ } else {
+ productForm.value.specificationModel = null;
+ productForm.value.unit = null;
+ }
+};
+const findNodeById = (nodes, productId) => {
+ for (let i = 0; i < nodes.length; i++) {
+ if (nodes[i].value === productId) {
+ return nodes[i].label; // 鎵惧埌鑺傜偣锛岃繑鍥炶鑺傜偣
}
- const ids = selectedRows.value.map(item => item.id);
+ if (nodes[i].children && nodes[i].children.length > 0) {
+ const foundNode = findNodeById(nodes[i].children, productId);
+ if (foundNode) {
+ return foundNode; // 鍦ㄥ瓙鑺傜偣涓壘鍒帮紝杩斿洖璇ヨ妭鐐�
+ }
+ }
+ }
+ return null; // 娌℃湁鎵惧埌鑺傜偣锛岃繑鍥瀗ull
+};
- // 妫�鏌ユ槸鍚︽湁宸茶繘琛屽彂璐ф垨鍙戣揣瀹屾垚鐨勯攢鍞鍗曪紝鑻ユ湁鍒欎笉鍏佽鍒犻櫎
- const cannotDeleteNames = [];
- for (const row of selectedRows.value) {
- let products =
- row.children && row.children.length > 0 ? row.children : null;
- if (!products) {
- try {
- const res = await productList({ salesLedgerId: row.id, type: 1 });
- products = res.data || [];
- } catch {
- products = [];
+function convertIdToValue(data) {
+ return data.map((item) => {
+ const { id, children, ...rest } = item;
+ const newItem = {
+ ...rest,
+ value: id, // 灏� id 鏀逛负 value
+ };
+ if (children && children.length > 0) {
+ newItem.children = convertIdToValue(children);
+ }
+
+ return newItem;
+ });
+}
+
+// 鏍规嵁鍚嶇О鍙嶆煡浜у搧澶х被 id锛屼究浜庝粎瀛樺悕绉版椂鐨勫弽鏄�
+function findNodeIdByLabel(nodes, label) {
+ if (!label) return null;
+ for (let i = 0; i < nodes.length; i++) {
+ const node = nodes[i];
+ if (node.label === label) return node.value;
+ if (node.children && node.children.length > 0) {
+ const found = findNodeIdByLabel(node.children, label);
+ if (found !== null && found !== undefined) return found;
+ }
+ }
+ return null;
+}
+
+// 琛ㄦ牸閫夋嫨鏁版嵁
+const handleSelectionChange = (selection) => {
+ // 杩囨护鎺夊瓙鏁版嵁
+ selectedRows.value = selection.filter((item) => item.children !== undefined);
+ console.log("selection", selectedRows.value);
+};
+const productSelected = (selectedRows) => {
+ productSelectedRows.value = selectedRows;
+};
+const expandedRowKeys = ref([]);
+// 灞曞紑琛�
+const expandChange = (row, expandedRows) => {
+ if (expandedRows.length > 0) {
+ expandedRowKeys.value = [];
+ try {
+ productList({ salesLedgerId: row.id, type: 1 }).then((res) => {
+ const index = tableData.value.findIndex((item) => item.id === row.id);
+ if (index > -1) {
+ tableData.value[index].children = res.data;
+ }
+ expandedRowKeys.value.push(row.id);
+ });
+ } catch (error) {
+ console.log(error);
+ }
+ } else {
+ expandedRowKeys.value = [];
+ }
+};
+
+// 娣诲姞琛ㄨ绫诲悕鏂规硶
+const tableRowClassName = ({ row }) => {
+ if (!row.deliveryDate) return "";
+ if (row.isFh) return "";
+
+ const diff = row.deliveryDaysDiff;
+ if (diff === 15) {
+ return "yellow";
+ } else if (diff === 10) {
+ return "pink";
+ } else if (diff === 2) {
+ return "purple";
+ } else if (diff < 2) {
+ return "red";
+ }
+};
+// 涓昏〃鍚堣鏂规硶
+const summarizeMainTable = (param) => {
+ return proxy.summarizeTable(param, [
+ "contractAmount",
+ "taxInclusiveTotalPrice",
+ "taxExclusiveTotalPrice",
+ ]);
+};
+// 瀛愯〃鍚堣鏂规硶
+const summarizeChildrenTable = (param, parentRow) => {
+ if (!isCurrentUserMaintainer(parentRow)) {
+ const { columns } = param;
+ return columns.map((column, index) => {
+ if (index === 0) {
+ return "鍚堣";
+ }
+ if (
+ [
+ "taxInclusiveUnitPrice",
+ "taxInclusiveTotalPrice",
+ "taxExclusiveTotalPrice",
+ ].includes(column.property)
+ ) {
+ return "*****";
+ }
+ return "";
+ });
+ }
+ return proxy.summarizeTable(param, [
+ "taxInclusiveUnitPrice",
+ "taxInclusiveTotalPrice",
+ "taxExclusiveTotalPrice",
+ ]);
+};
+// 鎵撳紑寮规
+const openForm = async (type, row) => {
+ if (type === "edit" && row && !canEditLedger(row)) {
+ proxy.$modal.msgWarning("褰撳墠绯荤粺鐧诲綍浜轰笉鏄淮鎶や汉锛屼笉鑳界紪杈戞暟鎹�");
+ return;
+ }
+ operationType.value = type;
+ form.value = {};
+ productData.value = [];
+ selectedQuotation.value = null;
+ let userLists = await userListNoPage();
+ userList.value = userLists.data;
+ listCustomer({ current: -1, size: -1, type: 0 }).then((res) => {
+ customerOption.value = res.data.records;
+ });
+ form.value.entryPerson = userStore.id;
+ if (type === "add") {
+ // 鏂板鏃惰缃綍鍏ユ棩鏈熶负褰撳ぉ
+ form.value.entryDate = getCurrentDate();
+ // 绛捐鏃ユ湡榛樿涓哄綋澶�
+ form.value.executionDate = getCurrentDate();
+ // 鍒涘缓鏃堕棿榛樿涓哄綋澶�
+ form.value.createTime = getCurrentDate();
+ // 榛樿鑷姩鐢熸垚閿�鍞悎鍚屽彿
+ form.value.autoGenerateContractNo = true;
+ } else {
+ currentId.value = row.id;
+ getSalesLedgerWithProducts({ id: row.id, type: 1 }).then((res) => {
+ form.value = { ...res };
+ form.value.entryPerson = Number(res.entryPerson);
+ productData.value = form.value.productData;
+ fileList.value = form.value.storageBlobVOs;
+ // 缂栬緫鏃惰缃嚜鍔ㄧ敓鎴愪负false锛屽厑璁告墜鍔ㄤ慨鏀�
+ form.value.autoGenerateContractNo = false;
+ });
+ }
+ // let userAll = await userStore.getInfo()
+ // userList.value.forEach(element => {
+ // if(userAll.user.nickName === element.nickName && userAll.user.userName === element.userName) {
+ // form.value.entryPerson = userAll.user.userId // 璁剧疆榛樿涓氬姟鍛樹负褰撳墠鐢ㄦ埛
+ // }
+ // });
+ form.value.entryDate = getCurrentDate(); // 璁剧疆榛樿褰曞叆鏃ユ湡涓哄綋鍓嶆棩鏈�
+ dialogFormVisible.value = true;
+};
+
+// 鎵撳紑鎶ヤ环鍗曢�夋嫨寮圭獥锛堜粎瀹℃壒閫氳繃锛�
+const openQuotationDialog = async () => {
+ if (operationType.value === "view") return;
+ quotationDialogVisible.value = true;
+ // 鎵撳紑寮圭獥鏃堕噸缃垎椤靛埌绗竴椤�
+ quotationPage.current = 1;
+ // 鍏堢‘淇濆鎴峰垪琛ㄥ凡鍔犺浇锛屼究浜庡悗缁洖濉� customerId
+ if (!customerOption.value || customerOption.value.length === 0) {
+ try {
+ listCustomer({ current: -1, size: -1 }).then((res) => {
+ customerOption.value = res.data.records;
+ });
+ } catch (e) {
+ // ignore锛屽厑璁哥敤鎴峰悗缁墜鍔ㄩ�夋嫨瀹㈡埛
+ }
+ }
+ await fetchQuotationList();
+};
+
+const fetchQuotationList = async () => {
+ quotationLoading.value = true;
+ try {
+ const params = {
+ // 鍚庣鍒嗛〉瀛楁锛歝urrent / size
+ current: quotationPage.current,
+ size: quotationPage.size,
+ ...quotationSearchForm,
+ status: "閫氳繃",
+ };
+ const res = await getQuotationList(params);
+ quotationList.value = res?.data?.records || [];
+ quotationPage.total = res?.data?.total || 0;
+ } finally {
+ quotationLoading.value = false;
+ }
+};
+
+const resetQuotationSearch = async () => {
+ quotationSearchForm.quotationNo = "";
+ quotationSearchForm.customer = "";
+ quotationPage.current = 1;
+ await fetchQuotationList();
+};
+
+// 鎶ヤ环鍗曞脊妗嗗垎椤靛垏鎹�
+const quotationPaginationChange = (obj) => {
+ quotationPage.current = obj.page;
+ quotationPage.size = obj.limit;
+ fetchQuotationList();
+};
+
+// 閫変腑鎶ヤ环鍗曞悗鍥炲~鍒板彴璐﹁〃鍗�
+const applyQuotation = (row) => {
+ if (!row) return;
+ selectedQuotation.value = row;
+
+ // 涓氬姟鍛�
+ form.value.salesman = (row.salesperson || "").trim();
+
+ // 瀹㈡埛鍚嶇О -> customerId
+ const qCustomerName = String(row.customer || "").trim();
+ const customer = (customerOption.value || []).find((c) => {
+ const name = String(c.customerName || "").trim();
+ return (
+ name === qCustomerName ||
+ name.includes(qCustomerName) ||
+ qCustomerName.includes(name)
+ );
+ });
+ if (customer?.id) {
+ form.value.customerId = customer.id;
+ } else {
+ // 濡傛灉鎵句笉鍒帮紝淇濈暀鍘熷�硷紙鍏佽鐢ㄦ埛鎵嬪姩閫夋嫨/涓嶆墦鏂凡鏈夎緭鍏ワ級
+ form.value.customerId = form.value.customerId || "";
+ }
+
+ // 浜у搧淇℃伅鏄犲皠锛氭姤浠� products -> 鍙拌处 productData
+ const products = Array.isArray(row.products) ? row.products : [];
+ productData.value = products.map((p) => {
+ const quantity = Number(p.quantity ?? 0) || 0;
+ const unitPrice = Number(p.unitPrice ?? 0) || 0;
+ const taxRate = "13"; // 榛樿 13%锛屼究浜庣洿鎺ユ彁浜わ紙濡傞渶鍙湪浜у搧涓嚜琛屼慨鏀癸級
+ const taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
+ const taxExclusiveTotalPrice = proxy.calculateTaxExclusiveTotalPrice(
+ taxInclusiveTotalPrice,
+ taxRate
+ );
+ return {
+ // 鍙拌处瀛楁
+ productCategory: p.product || p.productName || "",
+ specificationModel: p.specification || "",
+ unit: p.unit || "",
+ quantity: quantity,
+ taxRate: taxRate,
+ taxInclusiveUnitPrice: unitPrice.toFixed(2),
+ taxInclusiveTotalPrice: taxInclusiveTotalPrice,
+ taxExclusiveTotalPrice: taxExclusiveTotalPrice,
+ invoiceType: "澧炴櫘绁�",
+ isProduction: true,
+ productId: p.productId,
+ productModelId: p.productModelId,
+ };
+ });
+
+ quotationDialogVisible.value = false;
+};
+
+function changs(val) {
+ console.log(val);
+}
+
+// 鎻愪氦琛ㄥ崟
+const submitForm = () => {
+ proxy.$refs["formRef"].validate((valid) => {
+ if (valid) {
+ console.log("productData.value--", productData.value);
+ if (productData.value !== null && productData.value.length > 0) {
+ form.value.productData = proxy.HaveJson(productData.value);
+ } else {
+ proxy.$modal.msgWarning("璇锋坊鍔犱骇鍝佷俊鎭�");
+ return;
+ }
+ form.value.storageBlobDTOs = fileList;
+ form.value.type = 1;
+ if (form.value.autoGenerateContractNo) {
+ form.value.salesContractNo = "";
+ }
+ addOrUpdateSalesLedger(form.value).then((res) => {
+ proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+ closeDia();
+ expandedRowKeys.value = [];
+ getList();
+ });
+ }
+ });
+};
+// 鍏抽棴寮规
+const closeDia = () => {
+ proxy.resetForm("formRef");
+ dialogFormVisible.value = false;
+};
+
+const productIndex = ref(0);
+// 鎵撳紑浜у搧寮规
+const openProductForm = async (type, row, index) => {
+ // 缂栬緫鏃舵鏌ヤ骇鍝佹槸鍚﹀凡鍙戣揣鎴栧鏍搁�氳繃
+ if (type === "edit" && isProductShipped(row)) {
+ proxy.$modal.msgWarning("宸插彂璐ф垨瀹℃牳閫氳繃鐨勪骇鍝佷笉鑳界紪杈�");
+ return;
+ }
+
+ productOperationType.value = type;
+ productForm.value = {};
+ if (type === "add") {
+ productForm.value.isProduction = true;
+ }
+ proxy.resetForm("productFormRef");
+ if (type === "edit") {
+ productForm.value = { ...row };
+ productIndex.value = index;
+ // 缂栬緫鏃舵牴鎹骇鍝佸ぇ绫诲悕绉板弽鏌� tree 鑺傜偣 id锛屽苟鍔犺浇瑙勬牸鍨嬪彿鍒楄〃
+ try {
+ const options =
+ productOptions.value && productOptions.value.length > 0
+ ? productOptions.value
+ : await getProductOptions();
+ const categoryId = findNodeIdByLabel(
+ options,
+ productForm.value.productCategory
+ );
+ if (categoryId) {
+ const models = await modelList({ id: categoryId });
+ modelOptions.value = models || [];
+ // 鏍规嵁褰撳墠瑙勬牸鍨嬪彿鍚嶇О鍙嶆煡骞惰缃� productModelId锛屼究浜庝笅鎷夋鏄剧ず宸查�夊��
+ const currentModel = (modelOptions.value || []).find(
+ (m) => m.model === productForm.value.specificationModel
+ );
+ if (currentModel) {
+ productForm.value.productModelId = currentModel.id;
}
}
- if (hasShippedProducts(products)) {
- cannotDeleteNames.push(row.salesContractNo || `ID:${row.id}`);
+ } catch (e) {
+ // 鍔犺浇澶辫触鏃朵繚鎸佸彲缂栬緫锛屼笉涓柇寮圭獥
+ console.error("鍔犺浇浜у搧瑙勬牸鍨嬪彿澶辫触", e);
+ }
+ } else {
+ getProductOptions();
+ }
+ productFormVisible.value = true;
+};
+// 鎻愪氦浜у搧琛ㄥ崟
+const submitProduct = () => {
+ proxy.$refs["productFormRef"].validate((valid) => {
+ if (valid) {
+ if (operationType.value === "edit") {
+ submitProductEdit();
+ } else {
+ if (productOperationType.value === "add") {
+ productData.value.push({ ...productForm.value });
+ } else {
+ productData.value[productIndex.value] = { ...productForm.value };
+ }
+ closeProductDia();
}
}
- if (cannotDeleteNames.length > 0) {
- proxy.$modal.msgWarning(
- "宸茶繘琛屽彂璐ф垨鍙戣揣瀹屾垚鐨勯攢鍞鍗曚笉鑳藉垹闄わ細" + cannotDeleteNames.join("銆�")
- );
- return;
- }
+ });
+};
+const submitProductEdit = () => {
+ productForm.value.salesLedgerId = currentId.value;
+ productForm.value.type = 1;
+ addOrUpdateSalesLedgerProduct(productForm.value).then((res) => {
+ proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+ closeProductDia();
+ getSalesLedgerWithProducts({ id: currentId.value, type: 1 }).then((res) => {
+ productData.value = res.productData;
+ });
+ });
+};
+// 鍒犻櫎浜у搧
+const deleteProduct = () => {
+ if (productSelectedRows.value.length === 0) {
+ proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+ return;
+ }
+ // 妫�鏌ユ槸鍚︽湁宸插彂璐ф垨瀹℃牳閫氳繃鐨勪骇鍝�
+ const shippedProducts = productSelectedRows.value.filter((row) =>
+ isProductShipped(row)
+ );
+ if (shippedProducts.length > 0) {
+ proxy.$modal.msgWarning("宸插彂璐ф垨瀹℃牳閫氳繃鐨勪骇鍝佷笉鑳藉垹闄�");
+ return;
+ }
+
+ if (operationType.value === "add") {
+ productData.value = productData.value.filter(
+ (item) => !productSelectedRows.value.includes(item)
+ );
+ productSelectedRows.value = [];
+ } else {
+ let ids = [];
+ if (productSelectedRows.value.length > 0) {
+ ids = productSelectedRows.value.map((item) => item.id);
+ }
ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
confirmButtonText: "纭",
cancelButtonText: "鍙栨秷",
type: "warning",
})
.then(() => {
- delLedger(ids).then(res => {
+ delProduct(ids).then((res) => {
proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getList();
+ closeProductDia();
+ getSalesLedgerWithProducts({ id: currentId.value, type: 1 }).then(
+ (res) => {
+ productData.value = res.productData;
+ }
+ );
});
})
.catch(() => {
proxy.$modal.msg("宸插彇娑�");
});
- };
+ }
+};
+// 鍏抽棴浜у搧寮规
+const closeProductDia = () => {
+ proxy.resetForm("productFormRef");
+ productFormVisible.value = false;
+};
+// 瀵煎叆
+const handleImport = () => {
+ importUpload.title = "瀵煎叆閿�鍞彴璐�";
+ importUpload.open = true;
+ if (importUploadRef.value) {
+ importUploadRef.value.clearFiles();
+ }
+};
- // 鎵撳嵃鍔熻兘
- const handlePrint = async () => {
- if (selectedRows.value.length === 0) {
- proxy.$modal.msgWarning("璇烽�夋嫨瑕佹墦鍗扮殑鏁版嵁");
- return;
- }
+// 涓嬭浇瀵煎叆妯℃澘
+const downloadTemplate = () => {
+ proxy.download("/sales/ledger/exportTemplate", {}, "閿�鍞彴璐﹀鍏ユā鏉�.xlsx");
+};
- // 鏄剧ず鍔犺浇鐘舵��
- proxy.$modal.loading("姝e湪鑾峰彇浜у搧鏁版嵁锛岃绋嶅��...");
+// 鎻愪氦瀵煎叆鏂囦欢
+const submitImportFile = () => {
+ importUpload.isUploading = true;
+ proxy.$refs["importUploadRef"].submit();
+};
- try {
- // 涓烘瘡涓�変腑鐨勯攢鍞彴璐﹁褰曟煡璇㈠搴旂殑浜у搧鏁版嵁
- const printDataWithProducts = [];
+// 瀵煎嚭
+const handleOut = () => {
+ ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
+ .then(() => {
+ proxy.download("/sales/ledger/export", {}, "閿�鍞彴璐�.xlsx");
+ })
+ .catch(() => {
+ proxy.$modal.msg("宸插彇娑�");
+ });
+};
+/** 鍒ゆ柇鍗曚釜浜у搧鏄惁宸插彂璐э紙鏍规嵁shippingStatus鍒ゆ柇锛屽凡鍙戣揣鎴栧鏍搁�氳繃涓嶅彲缂栬緫鍜屽垹闄わ級 */
+const isProductShipped = (product) => {
+ if (!product) return false;
+ const status = String(product.shippingStatus || "").trim();
+ // 濡傛灉鍙戣揣鐘舵�佹槸"宸插彂璐�"鎴�"瀹℃牳閫氳繃"锛屽垯涓嶅彲缂栬緫鍜屽垹闄�
+ return status === "宸插彂璐�" || status === "瀹℃牳閫氳繃";
+};
- for (const row of selectedRows.value) {
- try {
- // 璋冪敤productList鎺ュ彛鏌ヨ浜у搧鏁版嵁
- const productRes = await productList({
- salesLedgerId: row.id,
- type: 1,
- });
+/** 鍒ゆ柇閿�鍞鍗曚笅鏄惁瀛樺湪宸插彂璐�/鍙戣揣瀹屾垚鐨勪骇鍝侊紙涓嶅彲鍒犻櫎锛� */
+const hasShippedProducts = (products) => {
+ if (!products || !products.length) return false;
+ return products.some((p) => {
+ const status = String(p.shippingStatus || "").trim();
+ // 鏈夊彂璐ф棩鏈熸垨杞︾墝鍙疯涓哄凡鍙戣揣
+ if (p.shippingDate || p.shippingCarNumber) return true;
+ // 宸茶繘琛屽彂璐с�佸彂璐у畬鎴愩�佸凡鍙戣揣 鍧囦笉鍙垹闄�
+ return (
+ status === "宸茶繘琛屽彂璐�" || status === "鍙戣揣瀹屾垚" || status === "宸插彂璐�"
+ );
+ });
+};
- // 灏嗕骇鍝佹暟鎹暣鍚堝埌閿�鍞彴璐﹁褰曚腑
- const rowWithProducts = {
- ...row,
- products: productRes.data || [],
- };
+// 鍒犻櫎
+const handleDelete = async () => {
+ if (selectedRows.value.length === 0) {
+ proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+ return;
+ }
+ const unauthorizedRows = selectedRows.value.filter(
+ (row) => !canDeleteLedger(row)
+ );
+ if (unauthorizedRows.length > 0) {
+ proxy.$modal.msgWarning("褰撳墠鐧诲綍鐢ㄦ埛涓嶆槸褰曞叆浜猴紝涓嶈兘鍒犻櫎璇ユ暟鎹�");
+ return;
+ }
+ const ids = selectedRows.value.map((item) => item.id);
- printDataWithProducts.push(rowWithProducts);
- } catch (error) {
- console.error(`鑾峰彇閿�鍞彴璐� ${row.id} 鐨勪骇鍝佹暟鎹け璐�:`, error);
- // 鍗充娇鏌愪釜璁板綍鐨勪骇鍝佹暟鎹幏鍙栧け璐ワ紝涔熻鍖呭惈璇ヨ褰�
- printDataWithProducts.push({
- ...row,
- products: [],
- });
- }
+ // 妫�鏌ユ槸鍚︽湁宸茶繘琛屽彂璐ф垨鍙戣揣瀹屾垚鐨勯攢鍞鍗曪紝鑻ユ湁鍒欎笉鍏佽鍒犻櫎
+ const cannotDeleteNames = [];
+ for (const row of selectedRows.value) {
+ let products =
+ row.children && row.children.length > 0 ? row.children : null;
+ if (!products) {
+ try {
+ const res = await productList({ salesLedgerId: row.id, type: 1 });
+ products = res.data || [];
+ } catch {
+ products = [];
}
-
- printData.value = printDataWithProducts;
- console.log("鎵撳嵃鏁版嵁锛堝寘鍚骇鍝侊級:", printData.value);
- printPreviewVisible.value = true;
- } catch (error) {
- console.error("鑾峰彇浜у搧鏁版嵁澶辫触:", error);
- proxy.$modal.msgError("鑾峰彇浜у搧鏁版嵁澶辫触锛岃閲嶈瘯");
- } finally {
- proxy.$modal.closeLoading();
}
- };
- // 鎵ц鎵撳嵃
- const executePrint = () => {
- console.log("寮�濮嬫墽琛屾墦鍗帮紝鏁版嵁鏉℃暟:", printData.value.length);
- console.log("鎵撳嵃鏁版嵁:", printData.value);
+ if (hasShippedProducts(products)) {
+ cannotDeleteNames.push(row.salesContractNo || `ID:${row.id}`);
+ }
+ }
+ if (cannotDeleteNames.length > 0) {
+ proxy.$modal.msgWarning(
+ "宸茶繘琛屽彂璐ф垨鍙戣揣瀹屾垚鐨勯攢鍞鍗曚笉鑳藉垹闄わ細" + cannotDeleteNames.join("銆�")
+ );
+ return;
+ }
- // 鍒涘缓涓�涓柊鐨勬墦鍗扮獥鍙�
- const printWindow = window.open("", "_blank", "width=800,height=600");
+ ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
+ .then(() => {
+ delLedger(ids).then((res) => {
+ proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+ getList();
+ });
+ })
+ .catch(() => {
+ proxy.$modal.msg("宸插彇娑�");
+ });
+};
- // 鏋勫缓鎵撳嵃鍐呭
- let printContent = `
+// 鎵撳嵃鍔熻兘
+const handlePrint = async () => {
+ if (selectedRows.value.length === 0) {
+ proxy.$modal.msgWarning("璇烽�夋嫨瑕佹墦鍗扮殑鏁版嵁");
+ return;
+ }
+
+ // 鏄剧ず鍔犺浇鐘舵��
+ proxy.$modal.loading("姝e湪鑾峰彇浜у搧鏁版嵁锛岃绋嶅��...");
+
+ try {
+ // 涓烘瘡涓�変腑鐨勯攢鍞彴璐﹁褰曟煡璇㈠搴旂殑浜у搧鏁版嵁
+ const printDataWithProducts = [];
+
+ for (const row of selectedRows.value) {
+ try {
+ // 璋冪敤productList鎺ュ彛鏌ヨ浜у搧鏁版嵁
+ const productRes = await productList({
+ salesLedgerId: row.id,
+ type: 1,
+ });
+
+ // 灏嗕骇鍝佹暟鎹暣鍚堝埌閿�鍞彴璐﹁褰曚腑
+ const rowWithProducts = {
+ ...row,
+ products: productRes.data || [],
+ };
+
+ printDataWithProducts.push(rowWithProducts);
+ } catch (error) {
+ console.error(`鑾峰彇閿�鍞彴璐� ${row.id} 鐨勪骇鍝佹暟鎹け璐�:`, error);
+ // 鍗充娇鏌愪釜璁板綍鐨勪骇鍝佹暟鎹幏鍙栧け璐ワ紝涔熻鍖呭惈璇ヨ褰�
+ printDataWithProducts.push({
+ ...row,
+ products: [],
+ });
+ }
+ }
+
+ printData.value = printDataWithProducts;
+ console.log("鎵撳嵃鏁版嵁锛堝寘鍚骇鍝侊級:", printData.value);
+ printPreviewVisible.value = true;
+ } catch (error) {
+ console.error("鑾峰彇浜у搧鏁版嵁澶辫触:", error);
+ proxy.$modal.msgError("鑾峰彇浜у搧鏁版嵁澶辫触锛岃閲嶈瘯");
+ } finally {
+ proxy.$modal.closeLoading();
+ }
+};
+// 鎵ц鎵撳嵃
+const executePrint = () => {
+ console.log("寮�濮嬫墽琛屾墦鍗帮紝鏁版嵁鏉℃暟:", printData.value.length);
+ console.log("鎵撳嵃鏁版嵁:", printData.value);
+
+ // 鍒涘缓涓�涓柊鐨勬墦鍗扮獥鍙�
+ const printWindow = window.open("", "_blank", "width=800,height=600");
+
+ // 鏋勫缓鎵撳嵃鍐呭
+ let printContent = `
<!DOCTYPE html>
<html>
<head>
@@ -2214,9 +2347,9 @@
<body>
`;
- // 涓烘瘡鏉℃暟鎹敓鎴愭墦鍗伴〉闈�
- printData.value.forEach((item, index) => {
- printContent += `
+ // 涓烘瘡鏉℃暟鎹敓鎴愭墦鍗伴〉闈�
+ printData.value.forEach((item, index) => {
+ printContent += `
<div class="print-page">
<div class="delivery-note">
<div class="header">
@@ -2268,7 +2401,9 @@
0
? item.products
.map(
- product => `
+ (
+ product
+ ) => `
<tr>
<td>${
product.productCategory ||
@@ -2354,694 +2489,694 @@
</div>
</div>
`;
- });
+ });
- printContent += `
+ printContent += `
</body>
</html>
`;
- // 鍐欏叆鍐呭鍒版柊绐楀彛
- printWindow.document.write(printContent);
- printWindow.document.close();
+ // 鍐欏叆鍐呭鍒版柊绐楀彛
+ printWindow.document.write(printContent);
+ printWindow.document.close();
- // 绛夊緟鍐呭鍔犺浇瀹屾垚鍚庢墦鍗�
- printWindow.onload = () => {
- setTimeout(() => {
- printWindow.print();
- printWindow.close();
- printPreviewVisible.value = false;
- }, 500);
- };
+ // 绛夊緟鍐呭鍔犺浇瀹屾垚鍚庢墦鍗�
+ printWindow.onload = () => {
+ setTimeout(() => {
+ printWindow.print();
+ printWindow.close();
+ printPreviewVisible.value = false;
+ }, 500);
};
- // 鏍煎紡鍖栨棩鏈�
- const formatDate = dateString => {
- if (!dateString) return getCurrentDate();
- const date = new Date(dateString);
- 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 formatDateTime = date => {
- const year = date.getFullYear();
- const month = String(date.getMonth() + 1).padStart(2, "0");
- const day = String(date.getDate()).padStart(2, "0");
- const hours = String(date.getHours()).padStart(2, "0");
- const minutes = String(date.getMinutes()).padStart(2, "0");
- const seconds = String(date.getSeconds()).padStart(2, "0");
- return `${year}/${month}/${day} ${hours}:${minutes}:${seconds}`;
- };
- // 璁$畻浜у搧鎬绘暟閲�
- const getTotalQuantity = products => {
- if (!products || products.length === 0) return "0";
- const total = products.reduce((sum, product) => {
- return sum + (parseFloat(product.quantity) || 0);
- }, 0);
- return total.toFixed(2);
- };
+};
+// 鏍煎紡鍖栨棩鏈�
+const formatDate = (dateString) => {
+ if (!dateString) return getCurrentDate();
+ const date = new Date(dateString);
+ 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 formatDateTime = (date) => {
+ const year = date.getFullYear();
+ const month = String(date.getMonth() + 1).padStart(2, "0");
+ const day = String(date.getDate()).padStart(2, "0");
+ const hours = String(date.getHours()).padStart(2, "0");
+ const minutes = String(date.getMinutes()).padStart(2, "0");
+ const seconds = String(date.getSeconds()).padStart(2, "0");
+ return `${year}/${month}/${day} ${hours}:${minutes}:${seconds}`;
+};
+// 璁$畻浜у搧鎬绘暟閲�
+const getTotalQuantity = (products) => {
+ if (!products || products.length === 0) return "0";
+ const total = products.reduce((sum, product) => {
+ return sum + (parseFloat(product.quantity) || 0);
+ }, 0);
+ return total.toFixed(2);
+};
- // 璁$畻浜у搧鎬婚噾棰�
- const getTotalAmount = products => {
- if (!products || products.length === 0) return "0";
- const total = products.reduce((sum, product) => {
- return sum + (parseFloat(product.taxInclusiveTotalPrice) || 0);
- }, 0);
- return total.toFixed(2);
- };
+// 璁$畻浜у搧鎬婚噾棰�
+const getTotalAmount = (products) => {
+ if (!products || products.length === 0) return "0";
+ const total = products.reduce((sum, product) => {
+ return sum + (parseFloat(product.taxInclusiveTotalPrice) || 0);
+ }, 0);
+ return total.toFixed(2);
+};
- // 鐢ㄤ簬鎵撳嵃鐨勮绠楀嚱鏁�
- const getTotalQuantityForPrint = products => {
- if (!products || products.length === 0) return "0";
- const total = products.reduce((sum, product) => {
- return sum + (parseFloat(product.quantity) || 0);
- }, 0);
- return total.toFixed(2);
- };
+// 鐢ㄤ簬鎵撳嵃鐨勮绠楀嚱鏁�
+const getTotalQuantityForPrint = (products) => {
+ if (!products || products.length === 0) return "0";
+ const total = products.reduce((sum, product) => {
+ return sum + (parseFloat(product.quantity) || 0);
+ }, 0);
+ return total.toFixed(2);
+};
- const getTotalAmountForPrint = products => {
- if (!products || products.length === 0) return "0";
- const total = products.reduce((sum, product) => {
- return sum + (parseFloat(product.taxInclusiveTotalPrice) || 0);
- }, 0);
- return total.toFixed(2);
- };
+const getTotalAmountForPrint = (products) => {
+ if (!products || products.length === 0) return "0";
+ const total = products.reduce((sum, product) => {
+ return sum + (parseFloat(product.taxInclusiveTotalPrice) || 0);
+ }, 0);
+ return total.toFixed(2);
+};
- const mathNum = () => {
- console.log("productForm.value", productForm.value);
- if (!productForm.value.taxInclusiveUnitPrice) {
- return;
- }
- if (!productForm.value.quantity) {
- return;
- }
- // 鍚◣鎬讳环璁$畻
- productForm.value.taxInclusiveTotalPrice =
- proxy.calculateTaxIncludeTotalPrice(
- productForm.value.taxInclusiveUnitPrice,
- productForm.value.quantity
- );
- if (productForm.value.taxRate) {
- // 涓嶅惈绋庢�讳环璁$畻
- productForm.value.taxExclusiveTotalPrice =
- proxy.calculateTaxExclusiveTotalPrice(
- productForm.value.taxInclusiveTotalPrice,
- productForm.value.taxRate
- );
- }
- };
-
- // 鏍规嵁鍚◣鎬讳环璁$畻鍚◣鍗曚环鍜屾暟閲�
- const calculateFromTotalPrice = () => {
- if (isCalculating.value) return;
-
- const totalPrice = parseFloat(productForm.value.taxInclusiveTotalPrice);
- const quantity = parseFloat(productForm.value.quantity);
-
- if (!totalPrice || !quantity || quantity <= 0) {
- return;
- }
-
- isCalculating.value = true;
-
- // 璁$畻鍚◣鍗曚环 = 鍚◣鎬讳环 / 鏁伴噺
- productForm.value.taxInclusiveUnitPrice = (totalPrice / quantity).toFixed(2);
-
- // 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
- if (productForm.value.taxRate) {
- productForm.value.taxExclusiveTotalPrice =
- proxy.calculateTaxExclusiveTotalPrice(
- totalPrice,
- productForm.value.taxRate
- );
- }
-
- isCalculating.value = false;
- };
-
- // 鏍规嵁涓嶅惈绋庢�讳环璁$畻鍚◣鍗曚环鍜屾暟閲�
- const calculateFromExclusiveTotalPrice = () => {
- if (!productForm.value.taxRate) {
- proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
- return;
- }
- if (isCalculating.value) return;
-
- const exclusiveTotalPrice = parseFloat(
- productForm.value.taxExclusiveTotalPrice
+const mathNum = () => {
+ console.log("productForm.value", productForm.value);
+ if (!productForm.value.taxInclusiveUnitPrice) {
+ return;
+ }
+ if (!productForm.value.quantity) {
+ return;
+ }
+ // 鍚◣鎬讳环璁$畻
+ productForm.value.taxInclusiveTotalPrice =
+ proxy.calculateTaxIncludeTotalPrice(
+ productForm.value.taxInclusiveUnitPrice,
+ productForm.value.quantity
);
- const quantity = parseFloat(productForm.value.quantity);
- const taxRate = parseFloat(productForm.value.taxRate);
-
- if (!exclusiveTotalPrice || !quantity || quantity <= 0 || !taxRate) {
- return;
- }
-
- isCalculating.value = true;
-
- // 鍏堣绠楀惈绋庢�讳环 = 涓嶅惈绋庢�讳环 / (1 - 绋庣巼/100)
- const taxRateDecimal = taxRate / 100;
- const inclusiveTotalPrice = exclusiveTotalPrice / (1 - taxRateDecimal);
- productForm.value.taxInclusiveTotalPrice = inclusiveTotalPrice.toFixed(2);
-
- // 璁$畻鍚◣鍗曚环 = 鍚◣鎬讳环 / 鏁伴噺
- productForm.value.taxInclusiveUnitPrice = (
- inclusiveTotalPrice / quantity
- ).toFixed(2);
-
- isCalculating.value = false;
- };
-
- // 鏍规嵁鏁伴噺鍙樺寲璁$畻鎬讳环
- const calculateFromQuantity = () => {
- if (!productForm.value.taxRate) {
- proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
- return;
- }
- if (isCalculating.value) return;
-
- const quantity = parseFloat(productForm.value.quantity);
- const unitPrice = parseFloat(productForm.value.taxInclusiveUnitPrice);
-
- if (!quantity || quantity <= 0 || !unitPrice) {
- return;
- }
-
- isCalculating.value = true;
-
- // 璁$畻鍚◣鎬讳环
- productForm.value.taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
-
- // 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
- if (productForm.value.taxRate) {
- productForm.value.taxExclusiveTotalPrice =
- proxy.calculateTaxExclusiveTotalPrice(
- productForm.value.taxInclusiveTotalPrice,
- productForm.value.taxRate
- );
- }
-
- isCalculating.value = false;
- };
-
- // 鏍规嵁鍚◣鍗曚环鍙樺寲璁$畻鎬讳环
- const calculateFromUnitPrice = () => {
- if (!productForm.value.taxRate) {
- proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
- return;
- }
- if (isCalculating.value) return;
-
- const quantity = parseFloat(productForm.value.quantity);
- const unitPrice = parseFloat(productForm.value.taxInclusiveUnitPrice);
-
- if (!quantity || quantity <= 0 || !unitPrice) {
- return;
- }
-
- isCalculating.value = true;
-
- // 璁$畻鍚◣鎬讳环
- productForm.value.taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
-
- // 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
- if (productForm.value.taxRate) {
- productForm.value.taxExclusiveTotalPrice =
- proxy.calculateTaxExclusiveTotalPrice(
- productForm.value.taxInclusiveTotalPrice,
- productForm.value.taxRate
- );
- }
-
- isCalculating.value = false;
- };
-
- // 鏍规嵁绋庣巼鍙樺寲璁$畻涓嶅惈绋庢�讳环
- const calculateFromTaxRate = () => {
- if (!productForm.value.taxRate) {
- proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
- return;
- }
- if (isCalculating.value) return;
-
- const inclusiveTotalPrice = parseFloat(
- productForm.value.taxInclusiveTotalPrice
- );
- const taxRate = parseFloat(productForm.value.taxRate);
-
- if (!inclusiveTotalPrice || !taxRate) {
- return;
- }
-
- isCalculating.value = true;
-
- // 璁$畻涓嶅惈绋庢�讳环
+ if (productForm.value.taxRate) {
+ // 涓嶅惈绋庢�讳环璁$畻
productForm.value.taxExclusiveTotalPrice =
- proxy.calculateTaxExclusiveTotalPrice(inclusiveTotalPrice, taxRate);
-
- isCalculating.value = false;
- };
- /**
- * 鑾峰彇鍙戣揣鐘舵�佹枃鏈�
- * @param row 琛屾暟鎹�
- */
- const getShippingStatusText = row => {
- // 濡傛灉宸插彂璐э紙鏈夊彂璐ф棩鏈熸垨杞︾墝鍙凤級锛屾樉绀�"宸插彂璐�"
- // if (row.shippingDate || row.shippingCarNumber) {
- // return "宸插彂璐�";
- // }
-
- // 鑾峰彇鍙戣揣鐘舵�佸瓧娈�
- const status = row.shippingStatus;
-
- // 濡傛灉鐘舵�佷负绌烘垨鏈畾涔夛紝榛樿涓�"寰呭彂璐�"
- if (status === null || status === undefined || status === "") {
- return "寰呭彂璐�";
- }
-
- // 鐘舵�佹槸瀛楃涓�
- const statusStr = String(status).trim();
- const statusTextMap = {
- 寰呭彂璐�: "寰呭彂璐�",
- 寰呭鏍�: "寰呭鏍�",
- 瀹℃牳涓�: "瀹℃牳涓�",
- 瀹℃牳鎷掔粷: "瀹℃牳鎷掔粷",
- 瀹℃牳閫氳繃: "瀹℃牳閫氳繃",
- 宸插彂璐�: "宸插彂璐�",
- 閮ㄥ垎鍙戣揣: "閮ㄥ垎鍙戣揣",
- };
- return statusTextMap[statusStr] || "寰呭彂璐�";
- };
-
- /**
- * 鑾峰彇鍙戣揣鐘舵�佹爣绛剧被鍨嬶紙棰滆壊锛�
- * @param row 琛屾暟鎹�
- */
- const getShippingStatusType = row => {
- // 濡傛灉宸插彂璐э紙鏈夊彂璐ф棩鏈熸垨杞︾墝鍙凤級锛屾樉绀虹豢鑹�
- if (row.shippingStatus === "宸插彂璐�") {
- return "success";
- }
-
- // 鑾峰彇鍙戣揣鐘舵�佸瓧娈�
- const status = row.shippingStatus;
-
- // 濡傛灉鐘舵�佷负绌烘垨鏈畾涔夛紝榛樿涓虹伆鑹诧紙寰呭彂璐э級
- if (status === null || status === undefined || status === "") {
- return "info";
- }
-
- // 鐘舵�佹槸瀛楃涓�
- const statusStr = String(status).trim();
- const typeTextMap = {
- 寰呭彂璐�: "info",
- 寰呭鏍�: "info",
- 瀹℃牳涓�: "warning",
- 瀹℃牳鎷掔粷: "danger",
- 瀹℃牳閫氳繃: "success",
- 宸插彂璐�: "success",
- 閮ㄥ垎鍙戣揣: "warning",
- };
- return typeTextMap[statusStr] || "info";
- };
-
- /**
- * 鍒ゆ柇鏄惁鍙互鍙戣揣
- * 鍙湁鍦ㄤ骇鍝佺姸鎬佹槸鍏呰冻锛屽彂璐х姸鎬佹槸寰呭彂璐у拰瀹℃牳鎷掔粷鐨勬椂鍊欐墠鍙互鍙戣揣
- * @param row 琛屾暟鎹�
- */
- const canShip = row => {
- // 浜у搧鐘舵�佸繀椤绘槸鍏呰冻锛坅pproveStatus === 1锛�
- if (row.approveStatus !== 1) {
- return false;
- }
-
- // 鑾峰彇鍙戣揣鐘舵��
- const shippingStatus = row.shippingStatus;
-
- // 濡傛灉宸插彂璐э紙鏈夊彂璐ф棩鏈熸垨杞︾墝鍙凤級锛屼笉鑳藉啀娆″彂璐�
- if (shippingStatus === "宸插彂璐�") {
- return false;
- }
-
- // 鍙戣揣鐘舵�佸繀椤绘槸"寰呭彂璐�"鎴�"瀹℃牳鎷掔粷"
- const statusStr = shippingStatus ? String(shippingStatus).trim() : "";
- return (
- statusStr === "寰呭彂璐�" ||
- statusStr === "瀹℃牳鎷掔粷" ||
- statusStr === "閮ㄥ垎鍙戣揣"
- );
- };
-
- // 鎵撳紑闄勪欢寮圭獥
- const recordId = ref(0);
- const fileDialogVisible = ref(false);
-
- // 鎵撳紑闄勪欢寮规
- const openFileDialog = async row => {
- recordId.value = row.id;
- fileDialogVisible.value = true;
- };
-
- // 鎵撳紑鍙戣揣寮规
- const openDeliveryForm = async row => {
- // 妫�鏌ユ槸鍚﹀彲浠ュ彂璐�
- if (!canShip(row)) {
- proxy.$modal.msgWarning(
- "鍙湁鍦ㄤ骇鍝佺姸鎬佹槸鍏呰冻锛屽彂璐х姸鎬佹槸寰呭彂璐ф垨瀹℃牳鎷掔粷鐨勬椂鍊欐墠鍙互鍙戣揣"
+ proxy.calculateTaxExclusiveTotalPrice(
+ productForm.value.taxInclusiveTotalPrice,
+ productForm.value.taxRate
);
- return;
- }
+ }
+};
- currentDeliveryRow.value = row;
- const batchNoList = await getDeliveryBatchNoList(
- row.productModelId || row.modelId
+// 鏍规嵁鍚◣鎬讳环璁$畻鍚◣鍗曚环鍜屾暟閲�
+const calculateFromTotalPrice = () => {
+ if (isCalculating.value) return;
+
+ const totalPrice = parseFloat(productForm.value.taxInclusiveTotalPrice);
+ const quantity = parseFloat(productForm.value.quantity);
+
+ if (!totalPrice || !quantity || quantity <= 0) {
+ return;
+ }
+
+ isCalculating.value = true;
+
+ // 璁$畻鍚◣鍗曚环 = 鍚◣鎬讳环 / 鏁伴噺
+ productForm.value.taxInclusiveUnitPrice = (totalPrice / quantity).toFixed(2);
+
+ // 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
+ if (productForm.value.taxRate) {
+ productForm.value.taxExclusiveTotalPrice =
+ proxy.calculateTaxExclusiveTotalPrice(
+ totalPrice,
+ productForm.value.taxRate
+ );
+ }
+
+ isCalculating.value = false;
+};
+
+// 鏍规嵁涓嶅惈绋庢�讳环璁$畻鍚◣鍗曚环鍜屾暟閲�
+const calculateFromExclusiveTotalPrice = () => {
+ if (!productForm.value.taxRate) {
+ proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
+ return;
+ }
+ if (isCalculating.value) return;
+
+ const exclusiveTotalPrice = parseFloat(
+ productForm.value.taxExclusiveTotalPrice
+ );
+ const quantity = parseFloat(productForm.value.quantity);
+ const taxRate = parseFloat(productForm.value.taxRate);
+
+ if (!exclusiveTotalPrice || !quantity || quantity <= 0 || !taxRate) {
+ return;
+ }
+
+ isCalculating.value = true;
+
+ // 鍏堣绠楀惈绋庢�讳环 = 涓嶅惈绋庢�讳环 / (1 - 绋庣巼/100)
+ const taxRateDecimal = taxRate / 100;
+ const inclusiveTotalPrice = exclusiveTotalPrice / (1 - taxRateDecimal);
+ productForm.value.taxInclusiveTotalPrice = inclusiveTotalPrice.toFixed(2);
+
+ // 璁$畻鍚◣鍗曚环 = 鍚◣鎬讳环 / 鏁伴噺
+ productForm.value.taxInclusiveUnitPrice = (
+ inclusiveTotalPrice / quantity
+ ).toFixed(2);
+
+ isCalculating.value = false;
+};
+
+// 鏍规嵁鏁伴噺鍙樺寲璁$畻鎬讳环
+const calculateFromQuantity = () => {
+ if (!productForm.value.taxRate) {
+ proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
+ return;
+ }
+ if (isCalculating.value) return;
+
+ const quantity = parseFloat(productForm.value.quantity);
+ const unitPrice = parseFloat(productForm.value.taxInclusiveUnitPrice);
+
+ if (!quantity || quantity <= 0 || !unitPrice) {
+ return;
+ }
+
+ isCalculating.value = true;
+
+ // 璁$畻鍚◣鎬讳环
+ productForm.value.taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
+
+ // 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
+ if (productForm.value.taxRate) {
+ productForm.value.taxExclusiveTotalPrice =
+ proxy.calculateTaxExclusiveTotalPrice(
+ productForm.value.taxInclusiveTotalPrice,
+ productForm.value.taxRate
+ );
+ }
+
+ isCalculating.value = false;
+};
+
+// 鏍规嵁鍚◣鍗曚环鍙樺寲璁$畻鎬讳环
+const calculateFromUnitPrice = () => {
+ if (!productForm.value.taxRate) {
+ proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
+ return;
+ }
+ if (isCalculating.value) return;
+
+ const quantity = parseFloat(productForm.value.quantity);
+ const unitPrice = parseFloat(productForm.value.taxInclusiveUnitPrice);
+
+ if (!quantity || quantity <= 0 || !unitPrice) {
+ return;
+ }
+
+ isCalculating.value = true;
+
+ // 璁$畻鍚◣鎬讳环
+ productForm.value.taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
+
+ // 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
+ if (productForm.value.taxRate) {
+ productForm.value.taxExclusiveTotalPrice =
+ proxy.calculateTaxExclusiveTotalPrice(
+ productForm.value.taxInclusiveTotalPrice,
+ productForm.value.taxRate
+ );
+ }
+
+ isCalculating.value = false;
+};
+
+// 鏍规嵁绋庣巼鍙樺寲璁$畻涓嶅惈绋庢�讳环
+const calculateFromTaxRate = () => {
+ if (!productForm.value.taxRate) {
+ proxy.$modal.msgWarning("璇峰厛閫夋嫨绋庣巼");
+ return;
+ }
+ if (isCalculating.value) return;
+
+ const inclusiveTotalPrice = parseFloat(
+ productForm.value.taxInclusiveTotalPrice
+ );
+ const taxRate = parseFloat(productForm.value.taxRate);
+
+ if (!inclusiveTotalPrice || !taxRate) {
+ return;
+ }
+
+ isCalculating.value = true;
+
+ // 璁$畻涓嶅惈绋庢�讳环
+ productForm.value.taxExclusiveTotalPrice =
+ proxy.calculateTaxExclusiveTotalPrice(inclusiveTotalPrice, taxRate);
+
+ isCalculating.value = false;
+};
+/**
+ * 鑾峰彇鍙戣揣鐘舵�佹枃鏈�
+ * @param row 琛屾暟鎹�
+ */
+const getShippingStatusText = (row) => {
+ // 濡傛灉宸插彂璐э紙鏈夊彂璐ф棩鏈熸垨杞︾墝鍙凤級锛屾樉绀�"宸插彂璐�"
+ // if (row.shippingDate || row.shippingCarNumber) {
+ // return "宸插彂璐�";
+ // }
+
+ // 鑾峰彇鍙戣揣鐘舵�佸瓧娈�
+ const status = row.shippingStatus;
+
+ // 濡傛灉鐘舵�佷负绌烘垨鏈畾涔夛紝榛樿涓�"寰呭彂璐�"
+ if (status === null || status === undefined || status === "") {
+ return "寰呭彂璐�";
+ }
+
+ // 鐘舵�佹槸瀛楃涓�
+ const statusStr = String(status).trim();
+ const statusTextMap = {
+ 寰呭彂璐�: "寰呭彂璐�",
+ 寰呭鏍�: "寰呭鏍�",
+ 瀹℃牳涓�: "瀹℃牳涓�",
+ 瀹℃牳鎷掔粷: "瀹℃牳鎷掔粷",
+ 瀹℃牳閫氳繃: "瀹℃牳閫氳繃",
+ 宸插彂璐�: "宸插彂璐�",
+ 閮ㄥ垎鍙戣揣: "閮ㄥ垎鍙戣揣",
+ };
+ return statusTextMap[statusStr] || "寰呭彂璐�";
+};
+
+/**
+ * 鑾峰彇鍙戣揣鐘舵�佹爣绛剧被鍨嬶紙棰滆壊锛�
+ * @param row 琛屾暟鎹�
+ */
+const getShippingStatusType = (row) => {
+ // 濡傛灉宸插彂璐э紙鏈夊彂璐ф棩鏈熸垨杞︾墝鍙凤級锛屾樉绀虹豢鑹�
+ if (row.shippingStatus === "宸插彂璐�") {
+ return "success";
+ }
+
+ // 鑾峰彇鍙戣揣鐘舵�佸瓧娈�
+ const status = row.shippingStatus;
+
+ // 濡傛灉鐘舵�佷负绌烘垨鏈畾涔夛紝榛樿涓虹伆鑹诧紙寰呭彂璐э級
+ if (status === null || status === undefined || status === "") {
+ return "info";
+ }
+
+ // 鐘舵�佹槸瀛楃涓�
+ const statusStr = String(status).trim();
+ const typeTextMap = {
+ 寰呭彂璐�: "info",
+ 寰呭鏍�: "info",
+ 瀹℃牳涓�: "warning",
+ 瀹℃牳鎷掔粷: "danger",
+ 瀹℃牳閫氳繃: "success",
+ 宸插彂璐�: "success",
+ 閮ㄥ垎鍙戣揣: "warning",
+ };
+ return typeTextMap[statusStr] || "info";
+};
+
+/**
+ * 鍒ゆ柇鏄惁鍙互鍙戣揣
+ * 鍙湁鍦ㄤ骇鍝佺姸鎬佹槸鍏呰冻锛屽彂璐х姸鎬佹槸寰呭彂璐у拰瀹℃牳鎷掔粷鐨勬椂鍊欐墠鍙互鍙戣揣
+ * @param row 琛屾暟鎹�
+ */
+const canShip = (row) => {
+ // 浜у搧鐘舵�佸繀椤绘槸鍏呰冻锛坅pproveStatus === 1锛�
+ if (row.approveStatus !== 1) {
+ return false;
+ }
+
+ // 鑾峰彇鍙戣揣鐘舵��
+ const shippingStatus = row.shippingStatus;
+
+ // 濡傛灉宸插彂璐э紙鏈夊彂璐ф棩鏈熸垨杞︾墝鍙凤級锛屼笉鑳藉啀娆″彂璐�
+ if (shippingStatus === "宸插彂璐�") {
+ return false;
+ }
+
+ // 鍙戣揣鐘舵�佸繀椤绘槸"寰呭彂璐�"鎴�"瀹℃牳鎷掔粷"
+ const statusStr = shippingStatus ? String(shippingStatus).trim() : "";
+ return (
+ statusStr === "寰呭彂璐�" ||
+ statusStr === "瀹℃牳鎷掔粷" ||
+ statusStr === "閮ㄥ垎鍙戣揣"
+ );
+};
+
+// 鎵撳紑闄勪欢寮圭獥
+const recordId = ref(0);
+const fileDialogVisible = ref(false);
+
+// 鎵撳紑闄勪欢寮规
+const openFileDialog = async (row) => {
+ recordId.value = row.id;
+ fileDialogVisible.value = true;
+};
+
+// 鎵撳紑鍙戣揣寮规
+const openDeliveryForm = async (row) => {
+ // 妫�鏌ユ槸鍚﹀彲浠ュ彂璐�
+ if (!canShip(row)) {
+ proxy.$modal.msgWarning(
+ "鍙湁鍦ㄤ骇鍝佺姸鎬佹槸鍏呰冻锛屽彂璐х姸鎬佹槸寰呭彂璐ф垨瀹℃牳鎷掔粷鐨勬椂鍊欐墠鍙互鍙戣揣"
);
- deliveryForm.value = {
- shippingCarNumber: "",
- expressCompany: "",
- expressNumber: "",
- type: "璐ц溅",
- batchNo: [],
- batchNoList,
- };
- deliveryFileList.value = [];
- deliveryFormVisible.value = true;
- };
+ return;
+ }
- // 鎻愪氦鍙戣揣琛ㄥ崟
- const submitDelivery = () => {
- proxy.$refs["deliveryFormRef"].validate(valid => {
- if (valid) {
- const selectedBatchRows = getSelectedDeliveryBatchRows();
- if (selectedBatchRows.length === 0) {
- proxy.$modal.msgWarning("璇疯嚦灏戝~鍐欎竴涓壒鍙风殑鍙戣揣鏁伴噺");
- return;
- }
- const totalDeliveryQuantity = selectedBatchRows.reduce(
- (sum, item) => sum + Number(item.deliveryQuantity || 0),
- 0
- );
- const currentRowNoQuantity = Number(
- currentDeliveryRow.value?.noQuantity || 0
- );
- if (
- currentRowNoQuantity > 0 &&
- totalDeliveryQuantity > currentRowNoQuantity
- ) {
- proxy.$modal.msgWarning("鎵瑰彿鍙戣揣鎬绘暟涓嶈兘瓒呰繃寰呭彂璐ф暟閲�");
- return;
- }
- // 淇濆瓨褰撳墠灞曞紑鐨勮ID锛屼互渚垮彂璐у悗閲嶆柊鍔犺浇瀛愯〃鏍兼暟鎹�
- const currentExpandedKeys = [...expandedRowKeys.value];
- const salesLedgerId = currentDeliveryRow.value.salesLedgerId;
- deliveryForm.value.batchNo = selectedBatchRows.map(item => item.id);
- const productModelId =
- currentDeliveryRow.value.productModelId ||
- currentDeliveryRow.value.modelId;
- addShippingInfo({
- salesLedgerId: salesLedgerId,
- salesLedgerProductId: currentDeliveryRow.value.id,
- type: deliveryForm.value.type,
- shippingCarNumber:
- deliveryForm.value.type === "璐ц溅"
- ? deliveryForm.value.shippingCarNumber
- : "",
- expressCompany:
- deliveryForm.value.type === "蹇��"
- ? deliveryForm.value.expressCompany
- : "",
- expressNumber:
- deliveryForm.value.type === "蹇��"
- ? deliveryForm.value.expressNumber
- : "",
- storageBlobDTOs: deliveryFileList.value || [],
- batchNo: deliveryForm.value.batchNo,
- batchNoDetailList: selectedBatchRows.map(item => ({
- stockInventoryId: item.id,
- batchNo: item.batchNo,
- quantity: Number(item.deliveryQuantity || 0),
- productModelId: productModelId,
- })),
- }).then(() => {
- proxy.$modal.msgSuccess("鍙戣揣鎴愬姛");
- closeDeliveryDia();
- // 鍒锋柊涓昏〃鏁版嵁
- getList().then(() => {
- // 濡傛灉涔嬪墠鏈夊睍寮�鐨勮锛岄噸鏂板姞杞借繖浜涜鐨勫瓙琛ㄦ牸鏁版嵁
- if (currentExpandedKeys.length > 0) {
- // 浣跨敤 Promise.all 骞惰鍔犺浇鎵�鏈夊睍寮�琛岀殑瀛愯〃鏍兼暟鎹�
- const loadPromises = currentExpandedKeys.map(ledgerId => {
- return productList({ salesLedgerId: ledgerId, type: 1 }).then(
- res => {
- const index = tableData.value.findIndex(
- item => item.id === ledgerId
- );
- if (index > -1) {
- tableData.value[index].children = res.data;
- }
- }
- );
- });
- Promise.all(loadPromises).then(() => {
- // 鎭㈠灞曞紑鐘舵��
- expandedRowKeys.value = currentExpandedKeys;
- });
- }
- });
- });
+ currentDeliveryRow.value = row;
+ const batchNoList = await getDeliveryBatchNoList(
+ row.productModelId || row.modelId
+ );
+ deliveryForm.value = {
+ shippingCarNumber: "",
+ expressCompany: "",
+ expressNumber: "",
+ type: "璐ц溅",
+ batchNo: [],
+ batchNoList,
+ };
+ deliveryFileList.value = [];
+ deliveryFormVisible.value = true;
+};
+
+// 鎻愪氦鍙戣揣琛ㄥ崟
+const submitDelivery = () => {
+ proxy.$refs["deliveryFormRef"].validate((valid) => {
+ if (valid) {
+ const selectedBatchRows = getSelectedDeliveryBatchRows();
+ if (selectedBatchRows.length === 0) {
+ proxy.$modal.msgWarning("璇疯嚦灏戝~鍐欎竴涓壒鍙风殑鍙戣揣鏁伴噺");
+ return;
}
- });
- };
-
- // 鍏抽棴鍙戣揣寮规
- const handleDeliveryTypeChange = val => {
- if (val === "璐ц溅") {
- deliveryForm.value.expressCompany = "";
- deliveryForm.value.expressNumber = "";
- } else {
- deliveryForm.value.shippingCarNumber = "";
+ const totalDeliveryQuantity = selectedBatchRows.reduce(
+ (sum, item) => sum + Number(item.deliveryQuantity || 0),
+ 0
+ );
+ const currentRowNoQuantity = Number(
+ currentDeliveryRow.value?.noQuantity || 0
+ );
+ if (
+ currentRowNoQuantity > 0 &&
+ totalDeliveryQuantity > currentRowNoQuantity
+ ) {
+ proxy.$modal.msgWarning("鎵瑰彿鍙戣揣鎬绘暟涓嶈兘瓒呰繃寰呭彂璐ф暟閲�");
+ return;
+ }
+ // 淇濆瓨褰撳墠灞曞紑鐨勮ID锛屼互渚垮彂璐у悗閲嶆柊鍔犺浇瀛愯〃鏍兼暟鎹�
+ const currentExpandedKeys = [...expandedRowKeys.value];
+ const salesLedgerId = currentDeliveryRow.value.salesLedgerId;
+ deliveryForm.value.batchNo = selectedBatchRows.map((item) => item.id);
+ const productModelId =
+ currentDeliveryRow.value.productModelId ||
+ currentDeliveryRow.value.modelId;
+ addShippingInfo({
+ salesLedgerId: salesLedgerId,
+ salesLedgerProductId: currentDeliveryRow.value.id,
+ type: deliveryForm.value.type,
+ shippingCarNumber:
+ deliveryForm.value.type === "璐ц溅"
+ ? deliveryForm.value.shippingCarNumber
+ : "",
+ expressCompany:
+ deliveryForm.value.type === "蹇��"
+ ? deliveryForm.value.expressCompany
+ : "",
+ expressNumber:
+ deliveryForm.value.type === "蹇��"
+ ? deliveryForm.value.expressNumber
+ : "",
+ storageBlobDTOs: deliveryFileList.value || [],
+ batchNo: deliveryForm.value.batchNo,
+ batchNoDetailList: selectedBatchRows.map((item) => ({
+ stockInventoryId: item.id,
+ batchNo: item.batchNo,
+ quantity: Number(item.deliveryQuantity || 0),
+ productModelId: productModelId,
+ })),
+ }).then(() => {
+ proxy.$modal.msgSuccess("鍙戣揣鎴愬姛");
+ closeDeliveryDia();
+ // 鍒锋柊涓昏〃鏁版嵁
+ getList().then(() => {
+ // 濡傛灉涔嬪墠鏈夊睍寮�鐨勮锛岄噸鏂板姞杞借繖浜涜鐨勫瓙琛ㄦ牸鏁版嵁
+ if (currentExpandedKeys.length > 0) {
+ // 浣跨敤 Promise.all 骞惰鍔犺浇鎵�鏈夊睍寮�琛岀殑瀛愯〃鏍兼暟鎹�
+ const loadPromises = currentExpandedKeys.map((ledgerId) => {
+ return productList({ salesLedgerId: ledgerId, type: 1 }).then(
+ (res) => {
+ const index = tableData.value.findIndex(
+ (item) => item.id === ledgerId
+ );
+ if (index > -1) {
+ tableData.value[index].children = res.data;
+ }
+ }
+ );
+ });
+ Promise.all(loadPromises).then(() => {
+ // 鎭㈠灞曞紑鐘舵��
+ expandedRowKeys.value = currentExpandedKeys;
+ });
+ }
+ });
+ });
}
- };
-
- const closeDeliveryDia = () => {
- proxy.resetForm("deliveryFormRef");
- deliveryFileList.value = [];
- deliveryFormVisible.value = false;
- currentDeliveryRow.value = null;
- };
- const currentFactoryName = ref("");
- const getCurrentFactoryName = async () => {
- let res = await userStore.getInfo();
- currentFactoryName.value = res.user.currentFactoryName;
- };
- onMounted(() => {
- searchForm.salesContractNo = route.query.salesContractNo;
- getList();
- userListNoPage().then(res => {
- userList.value = res.data;
- });
- getCurrentFactoryName();
});
+};
+
+// 鍏抽棴鍙戣揣寮规
+const handleDeliveryTypeChange = (val) => {
+ if (val === "璐ц溅") {
+ deliveryForm.value.expressCompany = "";
+ deliveryForm.value.expressNumber = "";
+ } else {
+ deliveryForm.value.shippingCarNumber = "";
+ }
+};
+
+const closeDeliveryDia = () => {
+ proxy.resetForm("deliveryFormRef");
+ deliveryFileList.value = [];
+ deliveryFormVisible.value = false;
+ currentDeliveryRow.value = null;
+};
+const currentFactoryName = ref("");
+const getCurrentFactoryName = async () => {
+ let res = await userStore.getInfo();
+ currentFactoryName.value = res.user.currentFactoryName;
+};
+onMounted(() => {
+ searchForm.salesContractNo = route.query.salesContractNo;
+ getList();
+ userListNoPage().then((res) => {
+ userList.value = res.data;
+ });
+ getCurrentFactoryName();
+});
</script>
<style scoped lang="scss">
- .ml-10 {
- margin-left: 10px;
+.ml-10 {
+ margin-left: 10px;
+}
+
+:deep(.yellow) {
+ background-color: #faf0de;
+}
+
+:deep(.pink) {
+ background-color: #fae1de;
+}
+
+:deep(.red) {
+ background-color: #fae1de;
+}
+
+:deep(.purple) {
+ background-color: #f4defa;
+}
+
+.table_list {
+ margin-top: unset;
+}
+
+.actions {
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: 10px;
+}
+
+.print-preview-dialog {
+ .el-dialog__body {
+ padding: 0;
+ max-height: 80vh;
+ overflow-y: auto;
}
+}
- :deep(.yellow) {
- background-color: #faf0de;
- }
-
- :deep(.pink) {
- background-color: #fae1de;
- }
-
- :deep(.red) {
- background-color: #fae1de;
- }
-
- :deep(.purple) {
- background-color: #f4defa;
- }
-
- .table_list {
- margin-top: unset;
- }
-
- .actions {
- display: flex;
- justify-content: space-between;
- margin-bottom: 10px;
- }
-
- .print-preview-dialog {
- .el-dialog__body {
- padding: 0;
- max-height: 80vh;
- overflow-y: auto;
- }
- }
-
- .print-preview-container {
- .print-preview-header {
- padding: 15px;
- border-bottom: 1px solid #e4e7ed;
- text-align: center;
-
- .el-button {
- margin: 0 10px;
- }
- }
-
- .print-preview-content {
- padding: 20px;
- background-color: #f5f5f5;
- min-height: 400px;
- }
- }
-
- .print-page {
- width: 220mm;
- height: 90mm;
- padding: 10mm;
- margin: 0 auto;
- background: white;
- box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
- margin-bottom: 10px;
- box-sizing: border-box;
- }
-
- .delivery-note {
- width: 100%;
- height: 100%;
- font-family: "SimSun", serif;
- font-size: 10px;
- line-height: 1.2;
- display: flex;
- flex-direction: column;
- }
-
- .header {
+.print-preview-container {
+ .print-preview-header {
+ padding: 15px;
+ border-bottom: 1px solid #e4e7ed;
text-align: center;
- margin-bottom: 8px;
- .company-name {
- font-size: 18px;
- font-weight: bold;
- margin-bottom: 4px;
- }
-
- .document-title {
- font-size: 16px;
- font-weight: bold;
+ .el-button {
+ margin: 0 10px;
}
}
- .info-section {
- margin-bottom: 8px;
- display: flex;
- justify-content: space-between;
- align-items: center;
+ .print-preview-content {
+ padding: 20px;
+ background-color: #f5f5f5;
+ min-height: 400px;
+ }
+}
- .info-row {
- line-height: 20px;
+.print-page {
+ width: 220mm;
+ height: 90mm;
+ padding: 10mm;
+ margin: 0 auto;
+ background: white;
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
+ margin-bottom: 10px;
+ box-sizing: border-box;
+}
+
+.delivery-note {
+ width: 100%;
+ height: 100%;
+ font-family: "SimSun", serif;
+ font-size: 10px;
+ line-height: 1.2;
+ display: flex;
+ flex-direction: column;
+}
+
+.header {
+ text-align: center;
+ margin-bottom: 8px;
+
+ .company-name {
+ font-size: 18px;
+ font-weight: bold;
+ margin-bottom: 4px;
+ }
+
+ .document-title {
+ font-size: 16px;
+ font-weight: bold;
+ }
+}
+
+.info-section {
+ margin-bottom: 8px;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+
+ .info-row {
+ line-height: 20px;
+
+ .label {
+ font-weight: bold;
+ width: 60px;
+ font-size: 14px;
+ }
+
+ .value {
+ margin-right: 20px;
+ min-width: 80px;
+ font-size: 14px;
+ }
+ }
+}
+
+.table-section {
+ margin-bottom: 4px;
+ flex: 1;
+
+ .product-table {
+ width: 100%;
+ border-collapse: collapse;
+ border: 1px solid #000;
+
+ th,
+ td {
+ border: 1px solid #000;
+ padding: 6px;
+ text-align: center;
+ font-size: 14px;
+ line-height: 1.4;
+ }
+
+ th {
+ font-weight: bold;
+ }
+
+ .total-label {
+ text-align: right;
+ font-weight: bold;
+ }
+
+ .total-value {
+ font-weight: bold;
+ }
+ }
+}
+
+.footer-section {
+ .footer-row {
+ display: flex;
+ margin-bottom: 3px;
+ line-height: 20px;
+ justify-content: space-between;
+
+ .footer-item {
+ display: flex;
+ margin-right: 20px;
.label {
font-weight: bold;
- width: 60px;
+ width: 80px;
font-size: 14px;
}
.value {
- margin-right: 20px;
min-width: 80px;
font-size: 14px;
}
- }
- }
- .table-section {
- margin-bottom: 4px;
- flex: 1;
-
- .product-table {
- width: 100%;
- border-collapse: collapse;
- border: 1px solid #000;
-
- th,
- td {
- border: 1px solid #000;
- padding: 6px;
- text-align: center;
- font-size: 14px;
- line-height: 1.4;
- }
-
- th {
- font-weight: bold;
- }
-
- .total-label {
- text-align: right;
- font-weight: bold;
- }
-
- .total-value {
- font-weight: bold;
- }
- }
- }
-
- .footer-section {
- .footer-row {
- display: flex;
- margin-bottom: 3px;
- line-height: 20px;
- justify-content: space-between;
-
- .footer-item {
- display: flex;
- margin-right: 20px;
-
- .label {
- font-weight: bold;
- width: 80px;
- font-size: 14px;
- }
-
- .value {
- min-width: 80px;
- font-size: 14px;
- }
-
- &.address-item {
- .address-value {
- min-width: 200px;
- }
+ &.address-item {
+ .address-value {
+ min-width: 200px;
}
}
}
}
+}
- @media print {
- .app-container {
- display: none;
- }
-
- .print-page {
- box-shadow: none;
- margin: 0;
- padding: 10mm;
- padding-left: 20mm;
- page-break-inside: avoid;
- page-break-after: always;
- }
- .print-page:last-child {
- page-break-after: avoid;
- }
+@media print {
+ .app-container {
+ display: none;
}
-</style>
\ No newline at end of file
+
+ .print-page {
+ box-shadow: none;
+ margin: 0;
+ padding: 10mm;
+ padding-left: 20mm;
+ page-break-inside: avoid;
+ page-break-after: always;
+ }
+ .print-page:last-child {
+ page-break-after: avoid;
+ }
+}
+</style>
--
Gitblit v1.9.3