<template>
|
<div>
|
<FormDialog v-model="dialogVisible"
|
title="新增采购台账页面"
|
:width="'70%'"
|
operation-type="add"
|
@close="closeDia"
|
@confirm="submitForm"
|
@cancel="closeDia">
|
<el-form :model="form"
|
label-width="140px"
|
label-position="top"
|
:rules="rules"
|
ref="formRef">
|
<el-row :gutter="30">
|
<el-col :span="12">
|
<el-form-item label="采购合同号:" prop="purchaseContractNumber">
|
<el-input v-model="form.purchaseContractNumber" placeholder="请输入" clearable />
|
</el-form-item>
|
</el-col>
|
<el-col v-if="showSalesContractBinding" :span="12">
|
<el-form-item label="销售合同号:" prop="salesLedgerId">
|
<el-select v-model="form.salesLedgerId"
|
placeholder="请选择"
|
filterable
|
clearable
|
@change="salesLedgerChange">
|
<el-option v-for="item in salesContractList"
|
:key="item.id"
|
:label="item.salesContractNo"
|
: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="supplierId">
|
<el-select v-model="form.supplierId" placeholder="请选择" filterable clearable>
|
<el-option v-for="item in supplierList"
|
:key="item.id"
|
:label="item.supplierName"
|
:value="item.id">
|
{{ item.supplierName }}
|
</el-option>
|
</el-select>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="项目名称" prop="projectName">
|
<el-input v-model="form.projectName" placeholder="请输入" clearable />
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-row :gutter="30">
|
<el-col :span="12">
|
<el-form-item label="付款方式">
|
<el-input v-model="form.paymentMethod" placeholder="请输入" clearable />
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="签订日期:" prop="executionDate">
|
<el-date-picker v-model="form.executionDate"
|
style="width: 100%"
|
value-format="YYYY-MM-DD"
|
format="YYYY-MM-DD"
|
type="date"
|
placeholder="请选择"
|
clearable />
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-row :gutter="30">
|
<el-col :span="12">
|
<el-form-item label="录入人:" prop="recorderId">
|
<el-select v-model="form.recorderId"
|
placeholder="请选择"
|
clearable
|
filterable
|
disabled>
|
<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 v-model="form.entryDate"
|
style="width: 100%"
|
value-format="YYYY-MM-DD"
|
format="YYYY-MM-DD"
|
type="date"
|
placeholder="请选择"
|
clearable />
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-row>
|
<el-form-item label="产品信息:">
|
<el-button type="primary" @click="openProductForm('add')">添加</el-button>
|
<el-button plain type="danger" @click="deleteProduct">删除</el-button>
|
</el-form-item>
|
<div class="select-button-group">
|
<el-select v-model="templateName"
|
filterable
|
allow-create
|
:reserve-keyword="true"
|
:default-first-option="false"
|
clearable
|
:input-value="filterInputValue"
|
@filter-change="onTemplateFilterChange"
|
@change="onTemplateChange"
|
@focus="getTemplateList"
|
placeholder="请选择模版或者输入新的模版名称后选择"
|
class="no-arrow-select template-select">
|
<el-option v-for="item in templateList"
|
:key="item.id || item.value"
|
:label="item.templateName"
|
:value="item.templateName">
|
<div class="template-option">
|
<span>{{ item.templateName }}</span>
|
<el-icon v-if="item.id"
|
class="delete-icon"
|
@click.stop="handleDeleteTemplate(item)">
|
<Delete />
|
</el-icon>
|
</div>
|
</el-option>
|
</el-select>
|
<el-button size="small"
|
class="template-save-button"
|
:disabled="!templateName || templateName.trim() === '' || (!currentTemplateId && isTemplateNameDuplicate)"
|
@click="handleButtonClick">
|
保存
|
</el-button>
|
</div>
|
</el-row>
|
<el-table :data="productData"
|
border
|
show-summary
|
:summary-method="summarizeProTable"
|
@selection-change="productSelected">
|
<el-table-column align="center" type="selection" width="55" />
|
<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" width="70" />
|
<el-table-column label="数量" prop="quantity" width="70" />
|
<el-table-column label="税率(%)" prop="taxRate" width="80" />
|
<el-table-column label="含税单价(元)" prop="taxInclusiveUnitPrice" :formatter="formattedNumber" width="150" />
|
<el-table-column label="含税总价(元)" prop="taxInclusiveTotalPrice" :formatter="formattedNumber" width="150" />
|
<el-table-column label="不含税总价(元)" prop="taxExclusiveTotalPrice" :formatter="formattedNumber" width="150" />
|
<el-table-column label="是否质检" prop="isChecked" width="150">
|
<template #default="{ row }">
|
<el-tag :type="row.isChecked ? 'success' : 'info'">
|
{{ row.isChecked ? '是' : '否' }}
|
</el-tag>
|
</template>
|
</el-table-column>
|
<el-table-column fixed="right" label="操作" min-width="60" align="center">
|
<template #default="{ row, $index }">
|
<el-button link type="primary" @click="openProductForm('edit', row, $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" />
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-row :gutter="30">
|
<el-col :span="24">
|
<el-form-item label="附件材料:" prop="purchaseLedgerFiles">
|
<FileUpload v-model:file-list="fileList" />
|
</el-form-item>
|
</el-col>
|
</el-row>
|
</el-form>
|
</FormDialog>
|
|
<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="12">
|
<el-form-item label="产品大类:" prop="productCategory">
|
<el-input v-model="productForm.productCategory"
|
placeholder="点击选择"
|
readonly
|
style="cursor:pointer"
|
@click="showProductSelectDialog = true" />
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="规格型号:" prop="productModelId">
|
<el-input v-model="productForm.specificationModel"
|
placeholder="点击选择"
|
readonly
|
style="cursor:pointer"
|
@click="showProductSelectDialog = true" />
|
</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>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="税率(%):" prop="taxRate">
|
<el-select v-model="productForm.taxRate" placeholder="请选择" clearable @change="mathNum">
|
<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 v-model="productForm.taxInclusiveUnitPrice"
|
:precision="6"
|
:step="0.000001"
|
:min="0"
|
clearable
|
style="width: 100%"
|
@change="mathNum" />
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="数量:" prop="quantity">
|
<el-input-number v-model="productForm.quantity"
|
:step="0.1"
|
clearable
|
:precision="2"
|
:min="0"
|
style="width: 100%"
|
placeholder="请输入"
|
@change="mathNum" />
|
</el-form-item>
|
</el-col>
|
</el-row>
|
<el-row :gutter="30">
|
<el-col :span="12">
|
<el-form-item label="含税总价(元):" prop="taxInclusiveTotalPrice">
|
<el-input-number v-model="productForm.taxInclusiveTotalPrice"
|
:precision="6"
|
:step="0.000001"
|
:min="0"
|
clearable
|
style="width: 100%"
|
@change="reverseMathNum('taxInclusiveTotalPrice')" />
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="不含税总价(元):" prop="taxExclusiveTotalPrice">
|
<el-input-number v-model="productForm.taxExclusiveTotalPrice"
|
:precision="6"
|
:step="0.000001"
|
:min="0"
|
clearable
|
style="width: 100%"
|
@change="reverseMathNum('taxExclusiveTotalPrice')" />
|
</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-select>
|
</el-form-item>
|
</el-col>
|
<el-col :span="12">
|
<el-form-item label="是否质检:" prop="isChecked">
|
<el-radio-group v-model="productForm.isChecked">
|
<el-radio label="是" :value="true" />
|
<el-radio label="否" :value="false" />
|
</el-radio-group>
|
</el-form-item>
|
</el-col>
|
</el-row>
|
</el-form>
|
</FormDialog>
|
|
<ProductSelectDialog v-model="showProductSelectDialog"
|
@confirm="handleProductSelect"
|
single />
|
</div>
|
</template>
|
|
<script setup>
|
import { computed, getCurrentInstance, nextTick, reactive, ref, toRefs } from "vue";
|
import { Delete } from "@element-plus/icons-vue";
|
import { ElMessage, ElMessageBox } from "element-plus";
|
import FormDialog from "@/components/Dialog/FormDialog.vue";
|
import FileUpload from "@/components/AttachmentUpload/file/index.vue";
|
import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
|
import useUserStore from "@/store/modules/user";
|
import { userListNoPage } from "@/api/system/user.js";
|
import { getProductInfoByContractNo } from "@/api/salesManagement/salesLedger.js";
|
import {
|
addOrEditPurchase,
|
addPurchaseTemplate,
|
createPurchaseNo,
|
delPurchaseTemplate,
|
getOptions,
|
getPurchaseTemplateList,
|
getSalesNo,
|
updatePurchaseTemplate,
|
} from "@/api/procurementManagement/procurementLedger.js";
|
import { tableAmountFormatter, formatDecimal, buildAmountSummaryFormat } from "@/utils/numberFormat";
|
|
const props = defineProps({
|
modelValue: { type: Boolean, default: false },
|
initialProducts: { type: Array, default: () => [] },
|
});
|
const emit = defineEmits(["update:modelValue", "saved"]);
|
|
const dialogVisible = computed({
|
get: () => props.modelValue,
|
set: val => emit("update:modelValue", val),
|
});
|
|
const { proxy } = getCurrentInstance();
|
const { tax_rate } = proxy.useDict("tax_rate");
|
const userStore = useUserStore();
|
const showSalesContractBinding = false;
|
|
const productData = ref([]);
|
const productSelectedRows = ref([]);
|
const userList = ref([]);
|
const salesContractList = ref([]);
|
const supplierList = ref([]);
|
const fileList = ref([]);
|
const productFormVisible = ref(false);
|
const showProductSelectDialog = ref(false);
|
const productOperationType = ref("");
|
const productOperationIndex = ref(-1);
|
const templateName = ref("");
|
const filterInputValue = ref("");
|
const templateList = ref([]);
|
const isTemplateNameDuplicate = ref(false);
|
const currentTemplateId = ref(null);
|
let duplicateCheckTimer = null;
|
|
const data = reactive({
|
form: {
|
purchaseContractNumber: "",
|
salesLedgerId: "",
|
projectName: "",
|
recorderId: "",
|
entryDate: "",
|
productData: [],
|
supplierName: "",
|
supplierId: "",
|
paymentMethod: "",
|
executionDate: "",
|
isChecked: false,
|
},
|
rules: {
|
purchaseContractNumber: [{ required: true, message: "请输入", trigger: "blur" }],
|
projectName: [{ required: true, message: "请输入项目名称", trigger: "blur" }],
|
supplierId: [{ required: true, message: "请输入", trigger: "blur" }],
|
entryDate: [{ required: true, message: "请选择", trigger: "change" }],
|
executionDate: [{ required: true, message: "请选择", trigger: "change" }],
|
},
|
});
|
const { form, rules } = toRefs(data);
|
|
const productFormData = reactive({
|
productForm: {
|
productId: "",
|
productCategory: "",
|
productModelId: "",
|
specificationModel: "",
|
unit: "",
|
quantity: "",
|
taxInclusiveUnitPrice: "",
|
taxRate: "",
|
taxInclusiveTotalPrice: "",
|
taxExclusiveTotalPrice: "",
|
invoiceType: "",
|
warnNum: "",
|
isChecked: false,
|
},
|
productRules: {
|
productCategory: [{ required: true, message: "请选择产品大类", trigger: "change" }],
|
productModelId: [{ 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" }],
|
isChecked: [{ required: true, message: "请选择", trigger: "change" }],
|
},
|
});
|
const { productForm, productRules } = toRefs(productFormData);
|
|
const formattedNumber = tableAmountFormatter;
|
|
const getCurrentDate = () => {
|
const today = new Date();
|
const year = today.getFullYear();
|
const month = String(today.getMonth() + 1).padStart(2, "0");
|
const day = String(today.getDate()).padStart(2, "0");
|
return `${year}-${month}-${day}`;
|
};
|
|
const normalizeProductRow = row => ({
|
productId: row.productId || "",
|
productCategory: row.productCategory || row.materialName || row.productName || "",
|
productModelId: row.productModelId || row.materialModelId || row.modelId || "",
|
specificationModel: row.specificationModel || row.materialModel || row.model || "",
|
unit: row.unit || "",
|
quantity: row.quantity || "",
|
taxInclusiveUnitPrice: row.taxInclusiveUnitPrice || "",
|
taxRate: row.taxRate || "",
|
taxInclusiveTotalPrice: row.taxInclusiveTotalPrice || "",
|
taxExclusiveTotalPrice: row.taxExclusiveTotalPrice || "",
|
invoiceType: row.invoiceType || "",
|
warnNum: row.warnNum || "",
|
isChecked: row.isChecked ?? false,
|
});
|
|
const resetDialogState = () => {
|
form.value = {
|
purchaseContractNumber: "",
|
salesLedgerId: "",
|
projectName: "",
|
recorderId: "",
|
entryDate: "",
|
productData: [],
|
supplierName: "",
|
supplierId: "",
|
paymentMethod: "",
|
executionDate: "",
|
isChecked: false,
|
};
|
productData.value = [];
|
productSelectedRows.value = [];
|
fileList.value = [];
|
templateName.value = "";
|
filterInputValue.value = "";
|
isTemplateNameDuplicate.value = false;
|
currentTemplateId.value = null;
|
};
|
|
const open = async products => {
|
resetDialogState();
|
await Promise.all([
|
getTemplateList(),
|
userListNoPage().then(res => {
|
userList.value = res.data || [];
|
}),
|
getSalesNo().then(res => {
|
salesContractList.value = res || [];
|
}),
|
getOptions().then(res => {
|
supplierList.value = (res.data || []).filter(item => item.isWhite === 0);
|
}),
|
]);
|
|
form.value.entryDate = getCurrentDate();
|
form.value.recorderId = userStore.id;
|
try {
|
const purchaseNoRes = await createPurchaseNo();
|
if (purchaseNoRes?.data) {
|
form.value.purchaseContractNumber = purchaseNoRes.data;
|
}
|
} catch (error) {
|
console.error("生成采购合同号失败:", error);
|
proxy.$modal.msgWarning("生成采购合同号失败");
|
}
|
|
const sourceProducts = Array.isArray(products) ? products : props.initialProducts;
|
productData.value = sourceProducts.map(normalizeProductRow);
|
dialogVisible.value = true;
|
await nextTick();
|
if (productData.value.length > 0) {
|
ElMessage.warning("已按所选领料行生成产品信息,请编辑补全数量、税率、单价、发票类型等必填项后再提交采购台账");
|
}
|
};
|
|
defineExpose({ open });
|
|
const checkTemplateNameDuplicate = name => {
|
if (!name || name.trim() === "") {
|
isTemplateNameDuplicate.value = false;
|
return false;
|
}
|
const isDuplicate = templateList.value.some(item => item.templateName === name.trim());
|
isTemplateNameDuplicate.value = isDuplicate;
|
return isDuplicate;
|
};
|
|
const onTemplateFilterChange = val => {
|
filterInputValue.value = val ?? "";
|
if (duplicateCheckTimer) {
|
clearTimeout(duplicateCheckTimer);
|
}
|
if (val && val.trim()) {
|
duplicateCheckTimer = setTimeout(() => {
|
if (checkTemplateNameDuplicate(val)) {
|
ElMessage.warning("模板名称已存在,请更换模板名称");
|
}
|
}, 300);
|
} else {
|
isTemplateNameDuplicate.value = false;
|
}
|
};
|
|
const onTemplateChange = async val => {
|
if (typeof val === "string") {
|
filterInputValue.value = val;
|
checkTemplateNameDuplicate(val);
|
}
|
const matchedTemplate = templateList.value.find(item => item.templateName === val);
|
if (matchedTemplate?.id) {
|
currentTemplateId.value = matchedTemplate.id;
|
isTemplateNameDuplicate.value = false;
|
form.value.supplierId = matchedTemplate.supplierId || form.value.supplierId;
|
form.value.supplierName = matchedTemplate.supplierName || form.value.supplierName;
|
form.value.projectName = matchedTemplate.projectName || form.value.projectName;
|
form.value.paymentMethod = matchedTemplate.paymentMethod || form.value.paymentMethod;
|
productData.value = matchedTemplate.productList || matchedTemplate.productData || [];
|
} else {
|
currentTemplateId.value = null;
|
}
|
};
|
|
const getTemplateList = async () => {
|
const res = await getPurchaseTemplateList();
|
if (res && res.code === 200 && Array.isArray(res.data)) {
|
templateList.value = res.data;
|
}
|
};
|
|
const handleButtonClick = async () => {
|
if (!templateName.value || templateName.value.trim() === "") {
|
ElMessage.warning("请输入模板名称");
|
return;
|
}
|
if (!currentTemplateId.value && checkTemplateNameDuplicate(templateName.value)) {
|
ElMessage.warning("模板名称已存在,请更换模板名称");
|
return;
|
}
|
if (!form.value.supplierId) {
|
ElMessage.warning("请先选择供应商");
|
return;
|
}
|
if (!productData.value || productData.value.length === 0) {
|
ElMessage.warning("请先添加产品信息");
|
return;
|
}
|
|
const params = {
|
productData: proxy.HaveJson(productData.value),
|
supplierId: form.value.supplierId,
|
paymentMethod: form.value.paymentMethod,
|
recorderId: form.value.recorderId,
|
projectName: form.value.projectName,
|
templateName: templateName.value.trim(),
|
};
|
const res = currentTemplateId.value
|
? await updatePurchaseTemplate({ id: currentTemplateId.value, ...params })
|
: await addPurchaseTemplate(params);
|
if (res && res.code === 200) {
|
ElMessage.success(currentTemplateId.value ? "模板更新成功" : "模板保存成功");
|
await getTemplateList();
|
templateName.value = "";
|
filterInputValue.value = "";
|
isTemplateNameDuplicate.value = false;
|
currentTemplateId.value = null;
|
} else {
|
ElMessage.error(res?.msg || "模板保存失败");
|
}
|
};
|
|
const productSelected = selectedRows => {
|
productSelectedRows.value = selectedRows;
|
};
|
|
const openProductForm = (type, row, index) => {
|
productOperationType.value = type;
|
productOperationIndex.value = index ?? -1;
|
proxy.resetForm("productFormRef");
|
productForm.value = type === "edit" ? { ...row } : { isChecked: false };
|
productFormVisible.value = true;
|
};
|
|
const handleProductSelect = products => {
|
if (!products || !products.length) return;
|
const p = products[0];
|
productForm.value.productId = p.productId || "";
|
productForm.value.productCategory = p.productName || p.topProductName || "";
|
productForm.value.productModelId = p.id;
|
productForm.value.specificationModel = p.model || "";
|
productForm.value.unit = p.unit || "";
|
showProductSelectDialog.value = false;
|
};
|
|
const closeProductDia = () => {
|
proxy.resetForm("productFormRef");
|
productFormVisible.value = false;
|
};
|
|
const submitProduct = () => {
|
proxy.$refs["productFormRef"].validate(valid => {
|
if (!valid) return;
|
if (productOperationType.value === "add") {
|
productData.value.push({ ...productForm.value });
|
} else if (productOperationIndex.value > -1) {
|
productData.value[productOperationIndex.value] = { ...productForm.value };
|
}
|
closeProductDia();
|
});
|
};
|
|
const deleteProduct = () => {
|
if (productSelectedRows.value.length === 0) {
|
proxy.$modal.msgWarning("请选择数据");
|
return;
|
}
|
productData.value = productData.value.filter(item => !productSelectedRows.value.includes(item));
|
productSelectedRows.value = [];
|
};
|
|
const summarizeProTable = param => proxy.summarizeTable(
|
param,
|
["taxInclusiveUnitPrice", "taxInclusiveTotalPrice", "taxExclusiveTotalPrice"],
|
buildAmountSummaryFormat(["taxInclusiveUnitPrice", "taxInclusiveTotalPrice", "taxExclusiveTotalPrice"])
|
);
|
|
const mathNum = () => {
|
if (!productForm.value.taxRate) {
|
proxy.$modal.msgWarning("请先选择税率");
|
return;
|
}
|
if (!productForm.value.taxInclusiveUnitPrice || !productForm.value.quantity) return;
|
productForm.value.taxInclusiveTotalPrice = proxy.calculateTaxIncludeTotalPrice(
|
productForm.value.taxInclusiveUnitPrice,
|
productForm.value.quantity
|
);
|
productForm.value.taxExclusiveTotalPrice = proxy.calculateTaxExclusiveTotalPrice(
|
productForm.value.taxInclusiveTotalPrice,
|
productForm.value.taxRate
|
);
|
};
|
|
const reverseMathNum = field => {
|
if (!productForm.value.taxRate) {
|
proxy.$modal.msgWarning("请先选择税率");
|
return;
|
}
|
const taxRate = Number(productForm.value.taxRate);
|
if (!taxRate) return;
|
if (field === "taxInclusiveTotalPrice") {
|
if (productForm.value.quantity) {
|
productForm.value.taxInclusiveUnitPrice = formatDecimal(
|
Number(productForm.value.taxInclusiveTotalPrice) / Number(productForm.value.quantity)
|
);
|
} else if (productForm.value.taxInclusiveUnitPrice) {
|
productForm.value.quantity = (
|
Number(productForm.value.taxInclusiveTotalPrice) / Number(productForm.value.taxInclusiveUnitPrice)
|
).toFixed(2);
|
}
|
productForm.value.taxExclusiveTotalPrice = formatDecimal(
|
Number(productForm.value.taxInclusiveTotalPrice) / (1 + taxRate / 100)
|
);
|
} else if (field === "taxExclusiveTotalPrice") {
|
productForm.value.taxInclusiveTotalPrice = formatDecimal(
|
Number(productForm.value.taxExclusiveTotalPrice) * (1 + taxRate / 100)
|
);
|
if (productForm.value.quantity) {
|
productForm.value.taxInclusiveUnitPrice = formatDecimal(
|
Number(productForm.value.taxInclusiveTotalPrice) / Number(productForm.value.quantity)
|
);
|
} else if (productForm.value.taxInclusiveUnitPrice) {
|
productForm.value.quantity = (
|
Number(productForm.value.taxInclusiveTotalPrice) / Number(productForm.value.taxInclusiveUnitPrice)
|
).toFixed(2);
|
}
|
}
|
};
|
|
const salesLedgerChange = async () => {
|
await querygProductInfoByContractNo();
|
};
|
|
const querygProductInfoByContractNo = async () => {
|
const { code, data } = await getProductInfoByContractNo({
|
contractNo: form.value.salesLedgerId,
|
});
|
if (code === 200) {
|
productData.value = data;
|
}
|
};
|
|
const validateProductRows = () => {
|
if (productData.value.length === 0) {
|
return "请添加产品信息";
|
}
|
const requiredFields = [
|
["productCategory", "产品大类"],
|
["productModelId", "规格型号"],
|
["unit", "单位"],
|
["quantity", "数量"],
|
["taxRate", "税率"],
|
["taxInclusiveUnitPrice", "含税单价"],
|
["taxInclusiveTotalPrice", "含税总价"],
|
["taxExclusiveTotalPrice", "不含税总价"],
|
["invoiceType", "发票类型"],
|
];
|
for (let i = 0; i < productData.value.length; i++) {
|
const row = productData.value[i];
|
const missing = requiredFields.find(([field]) => row[field] === "" || row[field] === null || row[field] === undefined);
|
if (missing) {
|
return `第${i + 1}行产品信息缺少${missing[1]},请编辑完再提交`;
|
}
|
}
|
return "";
|
};
|
|
const submitForm = () => {
|
proxy.$refs["formRef"].validate(valid => {
|
if (!valid) return;
|
const productMessage = validateProductRows();
|
if (productMessage) {
|
proxy.$modal.msgWarning(productMessage);
|
return;
|
}
|
|
const processedProductData = productData.value.map(product => {
|
const { id, ...rest } = product;
|
return rest;
|
});
|
const submitData = {
|
...form.value,
|
productData: proxy.HaveJson(processedProductData),
|
storageBlobDTOS: fileList.value,
|
type: 2,
|
};
|
if (!submitData.salesLedgerId) {
|
submitData.salesContractNo = "";
|
}
|
delete submitData.id;
|
|
addOrEditPurchase(submitData).then(() => {
|
proxy.$modal.msgSuccess("提交成功");
|
closeDia();
|
emit("saved");
|
});
|
});
|
};
|
|
const closeDia = () => {
|
proxy.resetForm("formRef");
|
dialogVisible.value = false;
|
};
|
|
const handleDeleteTemplate = async item => {
|
if (!item.id) {
|
proxy.$modal.msgWarning("无法删除该模板");
|
return;
|
}
|
try {
|
await ElMessageBox.confirm(`确定要删除模板"${item.templateName}"吗?`, "删除确认", {
|
confirmButtonText: "确定",
|
cancelButtonText: "取消",
|
type: "warning",
|
});
|
const res = await delPurchaseTemplate([item.id]);
|
if (res && res.code === 200) {
|
ElMessage.success("删除成功");
|
if (templateName.value === item.templateName) {
|
templateName.value = "";
|
filterInputValue.value = "";
|
}
|
await getTemplateList();
|
} else {
|
ElMessage.error(res?.msg || "删除失败");
|
}
|
} catch (error) {
|
if (error !== "cancel") {
|
ElMessage.error("删除失败,请稍后重试");
|
}
|
}
|
};
|
</script>
|
|
<style scoped lang="scss">
|
.el-row {
|
justify-content: space-between;
|
align-items: center;
|
}
|
|
.select-button-group {
|
display: flex;
|
align-items: center;
|
width: 500px;
|
margin: 20px 0;
|
}
|
|
.template-select {
|
width: 500px;
|
}
|
|
.template-save-button {
|
height: 32px;
|
margin-left: 8px;
|
}
|
|
.template-option {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
}
|
|
.no-arrow-select {
|
--el-select-suffix-icon-color: transparent;
|
}
|
|
.delete-icon {
|
cursor: pointer;
|
color: #f56c6c;
|
font-size: 14px;
|
margin-left: 8px;
|
transition: all 0.3s;
|
|
&:hover {
|
color: #f56c6c !important;
|
transform: scale(1.2);
|
}
|
}
|
</style>
|