| | |
| | | <el-table-column label="单位" prop="unit" /> |
| | | <el-table-column label="数量" prop="quantity" /> |
| | | <el-table-column label="税率(%)" prop="taxRate" /> |
| | | <el-table-column label="含税单价(元)" prop="taxInclusiveUnitPrice" /> |
| | | <el-table-column label="含税总价(元)" prop="taxInclusiveTotalPrice" /> |
| | | <el-table-column label="不含税总价(元)" prop="taxExclusiveTotalPrice" /> |
| | | <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> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column align="center" label="序号" type="index" width="60" /> |
| | | <el-table-column label="采购合同号" prop="purchaseContractNumber" show-overflow-tooltip/> |
| | | <el-table-column label="销售合同号" prop="salesLedgerId" show-overflow-tooltip/> |
| | | <el-table-column label="销售合同号" prop="salesContractNo" show-overflow-tooltip/> |
| | | <el-table-column label="供应商名称" prop="supplierName" show-overflow-tooltip/> |
| | | <el-table-column label="业务员" prop="salesman" show-overflow-tooltip/> |
| | | <el-table-column label="项目名称" prop="projectName" show-overflow-tooltip/> |
| | | <el-table-column label="合同金额(元)" prop="contractAmount" show-overflow-tooltip/> |
| | | <el-table-column label="录入人" prop="recorderId" show-overflow-tooltip/> |
| | | <el-table-column label="合同金额(元)" prop="contractAmount" show-overflow-tooltip :formatter="formattedNumber"/> |
| | | <el-table-column label="录入人" prop="recorderName" show-overflow-tooltip/> |
| | | <el-table-column label="录入日期" prop="entryDate" show-overflow-tooltip/> |
| | | <el-table-column fixed="right" label="操作" min-width="60" align="center"> |
| | | <template #default="scope"> |
| | |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="供应商名称:" prop="supplierName"> |
| | | <el-input v-model="form.supplierName" placeholder="请输入" clearable/> |
| | | <el-form-item label="供应商名称:" prop="supplierId"> |
| | | <el-select v-model="form.supplierId" placeholder="请选择" clearable> |
| | | <el-option v-for="item in supplierList" :key="item.id" :label="item.supplierName" :value="item.id"/> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="录入人:" prop="recorderId"> |
| | | <el-select v-model="form.recorderId" placeholder="请选择" clearable> |
| | | <el-select v-model="form.recorderId" placeholder="请选择" clearable disabled> |
| | | <el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId"/> |
| | | </el-select> |
| | | </el-form-item> |
| | |
| | | <el-col :span="12"> |
| | | <el-form-item label="录入日期:" prop="entryDate"> |
| | | <el-date-picker |
| | | disabled |
| | | style="width: 100%" |
| | | v-model="form.entryDate" |
| | | value-format="YYYY-MM-DD" |
| | |
| | | <el-button plain type="danger" @click="deleteProduct">删除</el-button> |
| | | </el-form-item> |
| | | </el-row> |
| | | <el-table :data="productData" border @selection-change="productSelected"> |
| | | <el-table :data="productData" border @selection-change="productSelected" show-summary :summary-method="summarizeProTable"> |
| | | <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="unit" /> |
| | | <el-table-column label="数量" prop="quantity" /> |
| | | <el-table-column label="税率(%)" prop="taxRate" /> |
| | | <el-table-column label="含税单价(元)" prop="taxInclusiveUnitPrice" /> |
| | | <el-table-column label="含税总价(元)" prop="taxInclusiveTotalPrice" /> |
| | | <el-table-column label="不含税总价(元)" prop="taxExclusiveTotalPrice" /> |
| | | <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 fixed="right" label="操作" min-width="60" align="center"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" size="small" @click="openProductForm('edit', scope.row);">编辑</el-button> |
| | | <el-button link type="primary" size="small" @click="openProductForm('edit', scope.row, scope.$index);">编辑</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | |
| | | <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-select v-model="productForm.productCategory" placeholder="请选择" clearable> |
| | | <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName" :value="item.nickName"/> |
| | | </el-select> |
| | | <el-form-item label="产品大类:" prop="productId"> |
| | | <el-tree-select |
| | | v-model="productForm.productId" |
| | | placeholder="请选择" clearable |
| | | 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="specificationModel"> |
| | | <el-select v-model="productForm.specificationModel" placeholder="请选择" clearable> |
| | | <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName" :value="item.nickName"/> |
| | | <el-form-item label="规格型号:" prop="productModelId"> |
| | | <el-select v-model="productForm.productModelId" placeholder="请选择" clearable @change="getProductModel"> |
| | | <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 :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="含税单价(元):" prop="taxInclusiveUnitPrice"> |
| | | <el-input v-model="productForm.taxInclusiveUnitPrice" placeholder="请输入" clearable/> |
| | | <el-input-number v-model="productForm.taxInclusiveUnitPrice" :precision="2" :step="0.1" clearable style="width: 100%"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="含税总价(元):" prop="taxInclusiveTotalPrice"> |
| | | <el-input v-model="productForm.taxInclusiveTotalPrice" placeholder="请输入" clearable/> |
| | | <el-input-number v-model="productForm.taxInclusiveTotalPrice" :precision="2" :step="0.1" clearable style="width: 100%" @change="mathNum"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="不含税总价(元):" prop="taxExclusiveTotalPrice"> |
| | | <el-input v-model="productForm.taxExclusiveTotalPrice" placeholder="请输入" clearable/> |
| | | <el-input v-model="productForm.taxExclusiveTotalPrice" disabled/> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | delPurchase, |
| | | getSalesNo, |
| | | purchaseList, |
| | | productList, getPurchaseById |
| | | productList, getPurchaseById, getOptions |
| | | } from "@/api/procurementManagement/procurementLedger.js"; |
| | | const { proxy } = getCurrentInstance() |
| | | const tableData = ref([]) |
| | | const productData = ref([]) |
| | | const selectedRows = ref([]) |
| | | const productSelectedRows = ref([]) |
| | | const modelOptions = ref([]) |
| | | const userList = ref([]) |
| | | const productOptions = ref([]) |
| | | const salesContractList = ref([]) |
| | | const supplierList = ref([]) |
| | | const tableLoading = ref(false) |
| | | const page = reactive({ |
| | | current: 1, |
| | |
| | | }) |
| | | const total = ref(0) |
| | | const fileList = ref([]) |
| | | import useUserStore from "@/store/modules/user" |
| | | import {modelList, productTreeList} from "@/api/basicData/product.js"; |
| | | |
| | | const userStore = useUserStore() |
| | | |
| | | // 用户信息表单弹框数据 |
| | | const operationType = ref('') |
| | |
| | | projectName: '', |
| | | recorderId: '', |
| | | entryDate: '', |
| | | productData: [] |
| | | productData: [], |
| | | supplierName: '', |
| | | supplierId: '', |
| | | }, |
| | | rules: { |
| | | purchaseContractNumber: [{ required: true, message: "请输入", trigger: "blur" }], |
| | | salesLedgerId: [{ required: true, message: "请选择", trigger: "change" }], |
| | | projectName: [{ required: true, message: "请输入", trigger: "blur" }], |
| | | recorderId: [{ required: true, message: "请选择", trigger: "change" }], |
| | | entryDate: [{ required: true, message: "请选择", trigger: "change" }], |
| | | supplierId: [{ required: true, message: "请输入", trigger: "blur" }], |
| | | } |
| | | }) |
| | | const { searchForm, form, rules } = toRefs(data) |
| | | // 产品表单弹框数据 |
| | | const productFormVisible = ref(false) |
| | | const productOperationType = ref('') |
| | | const productOperationIndex = ref('') |
| | | const currentId = ref('') |
| | | const productFormData = reactive({ |
| | | productForm: { |
| | | productId: '', |
| | | productCategory: '', |
| | | productModelId: '', |
| | | specificationModel: '', |
| | | unit: '', |
| | | quantity: '', |
| | |
| | | invoiceType: '', |
| | | }, |
| | | productRules: { |
| | | productCategory: [{ required: true, message: "请选择", trigger: "change" }], |
| | | specificationModel: [{ required: true, message: "请选择", trigger: "change" }], |
| | | productId: [{ 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" }], |
| | |
| | | headers: { Authorization: "Bearer " + getToken() }, |
| | | }) |
| | | |
| | | const formattedNumber = (row, column, cellValue) => { |
| | | return parseFloat(cellValue).toFixed(2); |
| | | }; |
| | | // 查询列表 |
| | | /** 搜索按钮操作 */ |
| | | const handleQuery = () => { |
| | | page.current = 1 |
| | | getList() |
| | | } |
| | | // 子表合计方法 |
| | | const summarizeChildrenTable = (param) => { |
| | | return proxy.summarizeTable(param, ['taxInclusiveUnitPrice', 'taxInclusiveTotalPrice', 'taxExclusiveTotalPrice', 'ticketsNum', 'ticketsAmount', 'futureTickets', 'futureTicketsAmount'], { |
| | | ticketsNum: { noDecimal: true }, // 不保留小数 |
| | | futureTickets: { noDecimal: true }, // 不保留小数 |
| | | }); |
| | | }; |
| | | const paginationChange = ({ current, limit }) => { |
| | | page.current = current; |
| | | page.size = limit; |
| | |
| | | }) |
| | | total.value = res.total |
| | | expandedRowKeys.value = [] |
| | | }).catch(() => { |
| | | tableLoading.value = false |
| | | }) |
| | | } |
| | | // 表格选择数据 |
| | |
| | | productList({salesLedgerId: row.id, type: 2}).then(res => { |
| | | const index = tableData.value.findIndex(item => item.id === row.id); |
| | | if (index > -1) { |
| | | tableData.value[index].children = res.rows; |
| | | tableData.value[index].children = res; |
| | | } |
| | | expandedRowKeys.value.push(row.id) |
| | | }) |
| | |
| | | } |
| | | // 主表合计方法 |
| | | const summarizeMainTable = (param) => { |
| | | const { columns, data } = param; |
| | | const sums = []; |
| | | columns.forEach((column, index) => { |
| | | if (index === 0) { |
| | | sums[index] = '合计'; |
| | | return; |
| | | } |
| | | const prop = column.property; |
| | | if (['contractAmount'].includes(prop)) { |
| | | const values = data.map(item => Number(item[prop])); |
| | | if (!values.every(value => isNaN(value))) { |
| | | sums[index] = values.reduce((acc, val) => (!isNaN(val) ? acc + val : acc), 0); |
| | | } else { |
| | | sums[index] = ''; |
| | | } |
| | | } else { |
| | | sums[index] = ''; |
| | | } |
| | | }) |
| | | return sums; |
| | | return proxy.summarizeTable(param, ['contractAmount']); |
| | | }; |
| | | // 子表合计方法 |
| | | const summarizeChildrenTable = (param) => { |
| | | const { columns, data } = param; |
| | | const sums = []; |
| | | columns.forEach((column, index) => { |
| | | if (index === 0) { |
| | | sums[index] = '合计'; |
| | | return; |
| | | } |
| | | const prop = column.property; |
| | | if (['taxInclusiveUnitPrice', 'taxInclusiveTotalPrice', 'taxExclusiveTotalPrice'].includes(prop)) { |
| | | const values = data.map(item => Number(item[prop])); |
| | | if (!values.every(value => isNaN(value))) { |
| | | sums[index] = values.reduce((acc, val) => (!isNaN(val) ? acc + val : acc), 0); |
| | | } else { |
| | | sums[index] = ''; |
| | | } |
| | | } else { |
| | | sums[index] = ''; |
| | | } |
| | | }); |
| | | return sums; |
| | | } |
| | | const summarizeProTable = (param) => { |
| | | return proxy.summarizeTable(param, ['taxInclusiveUnitPrice', 'taxInclusiveTotalPrice', 'taxExclusiveTotalPrice']); |
| | | }; |
| | | // 打开弹框 |
| | | const openForm = (type, row) => { |
| | | operationType.value = type |
| | | form.value = {} |
| | | productData.value = [] |
| | | fileList.value = [] |
| | | userListNoPage().then(res => { |
| | | userList.value = res.data |
| | | }) |
| | | getSalesNo().then(res => { |
| | | salesContractList.value = res |
| | | }) |
| | | getOptions().then(res => { |
| | | supplierList.value = res.data |
| | | }) |
| | | form.value.recorderId = userStore.id |
| | | form.value.entryDate = getCurrentDate(); |
| | | if (type === 'edit') { |
| | | currentId.value = row.id; |
| | | getPurchaseById({id: row.id, type: 2}).then(res => { |
| | |
| | | // 上传前校检 |
| | | function handleBeforeUpload(file) { |
| | | // 校检文件大小 |
| | | if (file.size > 1024 * 1024) { |
| | | if (file.size > 1024 * 1024 * 10) { |
| | | proxy.$modal.msgError('上传文件大小不能超过10MB!') |
| | | return false |
| | | } |
| | |
| | | } |
| | | // 移除文件 |
| | | function handleRemove (file) { |
| | | console.log('handleRemove', file) |
| | | console.log('operationType.value', operationType.value) |
| | | console.log('handleRemove', file.id) |
| | | if (operationType.value === 'edit') { |
| | | let ids = [] |
| | | ids.push(file.value.id) |
| | | ids.push(file.id) |
| | | delLedgerFile(ids).then(res => { |
| | | proxy.$modal.msgSuccess("删除成功") |
| | | }) |
| | |
| | | dialogFormVisible.value = false |
| | | } |
| | | // 打开产品弹框 |
| | | const openProductForm = (type, row) => { |
| | | const openProductForm = (type, row, index) => { |
| | | productOperationType.value = type |
| | | productOperationIndex.value = index |
| | | productForm.value = {} |
| | | proxy.resetForm("productFormRef") |
| | | if (type === 'edit') { |
| | | productForm.value = {...row} |
| | | } |
| | | productFormVisible.value = true |
| | | getProductOptions() |
| | | } |
| | | const getProductOptions = () => { |
| | | productTreeList().then(res => { |
| | | productOptions.value = convertIdToValue(res) |
| | | }) |
| | | } |
| | | 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; |
| | | } else { |
| | | productForm.value.specificationModel = null; |
| | | } |
| | | } |
| | | 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.label; // 在子节点中找到,返回该节点 |
| | | } |
| | | } |
| | | } |
| | | return null; // 没有找到节点,返回null |
| | | }; |
| | | 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 submitProduct = () => { |
| | |
| | | if (operationType.value === "edit") { |
| | | submitProductEdit() |
| | | } else { |
| | | productData.value.push({...productForm.value}) |
| | | if (productOperationType.value === 'add') { |
| | | productData.value.push({...productForm.value}) |
| | | console.log('productData.value---', productData.value) |
| | | } else { |
| | | productData.value[productOperationIndex.value] = {...productForm.value} |
| | | } |
| | | closeProductDia() |
| | | } |
| | | } |
| | |
| | | } |
| | | const submitProductEdit = () => { |
| | | productForm.value.salesLedgerId = currentId.value |
| | | productForm.value.type = 2 |
| | | addOrUpdateSalesLedgerProduct(productForm.value).then(res => { |
| | | proxy.$modal.msgSuccess("提交成功") |
| | | closeProductDia() |
| | | getSalesLedgerWithProducts({id: currentId.value}).then(res => { |
| | | getPurchaseById({id: currentId.value, type: 2}).then(res => { |
| | | productData.value = res.productData |
| | | }) |
| | | }) |
| | |
| | | delProduct(ids).then(res => { |
| | | proxy.$modal.msgSuccess("删除成功") |
| | | closeProductDia() |
| | | getSalesLedgerWithProducts({id: currentId.value}).then(res => { |
| | | getSalesLedgerWithProducts({id: currentId.value, type: 2}).then(res => { |
| | | productData.value = res.productData |
| | | }) |
| | | }) |
| | |
| | | proxy.$modal.msg("已取消") |
| | | }) |
| | | } |
| | | // 获取当前日期并格式化为 YYYY-MM-DD |
| | | function getCurrentDate() { |
| | | const today = new Date(); |
| | | const year = today.getFullYear(); |
| | | const month = String(today.getMonth() + 1).padStart(2, '0'); // 月份从0开始 |
| | | const day = String(today.getDate()).padStart(2, '0'); |
| | | return `${year}-${month}-${day}`; |
| | | } |
| | | const mathNum = (val) => { |
| | | productForm.value.taxExclusiveTotalPrice = proxy.calculateTaxExclusiveTotalPrice(val, productForm.value.taxRate) |
| | | } |
| | | getList() |
| | | </script> |
| | | |