| src/views/basicData/product/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/equipmentManagement/inspectionManagement/components/formDia.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/equipmentManagement/inspectionManagement/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/inventoryManagement/dispatchLog/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/inventoryManagement/issueManagement/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/inventoryManagement/receiptManagement/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/inventoryManagement/stockManagement/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/procurementManagement/invoiceEntry/components/Modal.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/reportAnalysis/dataDashboard/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/salesManagement/invoiceRegistration/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/views/basicData/product/index.vue
@@ -155,6 +155,18 @@ </el-row> <el-row> <el-col :span="24"> <el-form-item label="其他规格型号:" prop="otherModel"> <el-input v-model="modelForm.otherModel" placeholder="请输入其他规格型号" clearable @keydown.enter.prevent /> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="24"> <el-form-item label="单位:" prop="unit"> <el-input v-model="modelForm.unit" @@ -266,21 +278,22 @@ productName: [{ required: true, message: "请输入", trigger: "blur" }], }, modelForm: { otherModel:'', model: "", unit: "", speculativeTradingName: [], }, modelRules: { model: [ { required: true, message: "请输入", trigger: "blur" }, // { required: true, message: "请输入", trigger: "blur" }, { pattern: /^[0-9*]*$/, message: "只能输入数字和*号", trigger: "blur" } ], unit: [{ required: true, message: "请输入", trigger: "blur" }], speculativeTradingName: [{ required: false, message: "请选择绑定机器", trigger: "change" }], // unit: [{ required: true, message: "请输入", trigger: "blur" }], // speculativeTradingName: [{ required: false, message: "请选择绑定机器", trigger: "change" }], }, }); const { form, rules, modelForm, modelRules } = toRefs(data); @@ -394,9 +407,15 @@ const submitModelForm = () => { proxy.$refs.modelFormRef.validate((valid) => { if (valid) { let _modelForm = { ...modelForm.value }; if(_modelForm.otherModel){ _modelForm.model = _modelForm.otherModel; } delete _modelForm.otherModel; // 将选中的机器数组转换为逗号分隔的字符串 const submitData = { ...modelForm.value, ..._modelForm, productId: currentId.value, speculativeTradingName: modelForm.value.speculativeTradingName.join(',') }; src/views/equipmentManagement/inspectionManagement/components/formDia.vue
@@ -1,109 +1,116 @@ <template> <div> <el-dialog :title="operationType === 'add' ? '新增巡检任务' : '编辑巡检任务'" v-model="dialogVisitable" width="800px" @close="cancel"> <el-form ref="formRef" :model="form" :rules="rules" label-width="120px"> <el-row> <el-col :span="12"> <el-form-item label="巡检任务" prop="taskName"> <el-input v-model="form.taskName" placeholder="请输入巡检任务" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="巡检人" prop="inspector"> <el-select v-model="form.inspector" filterable default-first-option :reserve-keyword="false" placeholder="请选择" multiple clearable> <el-option v-for="item in userList" :label="item.nickName" :value="item.userId" :key="item.userId"/> </el-select> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="12"> <el-form-item label="备注" prop="remarks"> <el-input v-model="form.remarks" placeholder="请输入备注" type="textarea" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="登记时间" prop="dateStr"> <el-date-picker v-model="form.dateStr" type="date" placeholder="选择登记日期" format="YYYY-MM-DD" value-format="YYYY-MM-DD" style="width: 100%" /> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="12"> <el-form-item label="任务频率" prop="frequencyType"> <el-select v-model="form.frequencyType" placeholder="请选择" clearable> <el-option label="每日" value="DAILY"/> <el-option label="每周" value="WEEKLY"/> <el-option label="每月" value="MONTHLY"/> <!-- <el-option label="季度" value="QUARTERLY"/> --> </el-select> </el-form-item> </el-col> <el-col :span="12" v-if="form.frequencyType === 'DAILY' && form.frequencyType"> <el-form-item label="日期" prop="frequencyDetail"> <el-time-picker v-model="form.frequencyDetail" placeholder="选择时间" format="HH:mm" value-format="HH:mm" /> </el-form-item> </el-col> <el-col :span="12" v-if="form.frequencyType === 'WEEKLY' && form.frequencyType"> <el-form-item label="日期" prop="frequencyDetail"> <el-select v-model="form.week" placeholder="请选择" clearable style="width: 50%"> <el-option label="周一" value="MON"/> <el-option label="周二" value="TUE"/> <el-option label="周三" value="WED"/> <el-option label="周四" value="THU"/> <el-option label="周五" value="FRI"/> <el-option label="周六" value="SAT"/> <el-option label="周日" value="SUN"/> </el-select> <el-time-picker v-model="form.time" placeholder="选择时间" format="HH:mm" value-format="HH:mm" style="width: 50%"/> </el-form-item> </el-col> <el-col :span="12" v-if="form.frequencyType === 'MONTHLY' && form.frequencyType"> <el-form-item label="日期" prop="frequencyDetail"> <el-date-picker v-model="form.frequencyDetail" type="datetime" clearable placeholder="选择开始日期" format="DD,HH:mm" value-format="DD,HH:mm" /> </el-form-item> </el-col> <el-col :span="12" v-if="form.frequencyType === 'QUARTERLY' && form.frequencyType"> <el-form-item label="日期" prop="frequencyDetail"> <el-date-picker v-model="form.frequencyDetail" type="datetime" clearable placeholder="选择开始日期" format="MM,DD,HH:mm" value-format="MM,DD,HH:mm" /> </el-form-item> </el-col> </el-row> </el-form> <template #footer> <div class="dialog-footer"> <el-button @click="cancel">取消</el-button> <el-button type="primary" @click="submitForm">保存</el-button> </div> </template> </el-dialog> </div> <div> <el-dialog :title="operationType === 'add' ? '新增巡检任务' : '编辑巡检任务'" v-model="dialogVisitable" width="800px" @close="cancel"> <el-form ref="formRef" :model="form" :rules="rules" label-width="120px"> <el-row> <el-col :span="12"> <el-form-item label="设备名称" prop="taskId"> <el-select v-model="form.taskId" @change="setDeviceModel" filterable> <el-option v-for="(item, index) in deviceOptions" :key="index" :label="item.deviceName" :value="item.id" ></el-option> </el-select> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="巡检人" prop="inspector"> <el-select v-model="form.inspector" filterable default-first-option :reserve-keyword="false" placeholder="请选择" multiple clearable> <el-option v-for="item in userList" :label="item.nickName" :value="item.userId" :key="item.userId"/> </el-select> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="12"> <el-form-item label="备注" prop="remarks"> <el-input v-model="form.remarks" placeholder="请输入备注" type="textarea" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="登记时间" prop="dateStr"> <el-date-picker v-model="form.dateStr" type="date" placeholder="选择登记日期" format="YYYY-MM-DD" value-format="YYYY-MM-DD" style="width: 100%" /> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="12"> <el-form-item label="任务频率" prop="frequencyType"> <el-select v-model="form.frequencyType" placeholder="请选择" clearable> <el-option label="每日" value="DAILY"/> <el-option label="每周" value="WEEKLY"/> <el-option label="每月" value="MONTHLY"/> <!-- <el-option label="季度" value="QUARTERLY"/> --> </el-select> </el-form-item> </el-col> <el-col :span="12" v-if="form.frequencyType === 'DAILY' && form.frequencyType"> <el-form-item label="日期" prop="frequencyDetail"> <el-time-picker v-model="form.frequencyDetail" placeholder="选择时间" format="HH:mm" value-format="HH:mm" /> </el-form-item> </el-col> <el-col :span="12" v-if="form.frequencyType === 'WEEKLY' && form.frequencyType"> <el-form-item label="日期" prop="frequencyDetail"> <el-select v-model="form.week" placeholder="请选择" clearable style="width: 50%"> <el-option label="周一" value="MON"/> <el-option label="周二" value="TUE"/> <el-option label="周三" value="WED"/> <el-option label="周四" value="THU"/> <el-option label="周五" value="FRI"/> <el-option label="周六" value="SAT"/> <el-option label="周日" value="SUN"/> </el-select> <el-time-picker v-model="form.time" placeholder="选择时间" format="HH:mm" value-format="HH:mm" style="width: 50%"/> </el-form-item> </el-col> <el-col :span="12" v-if="form.frequencyType === 'MONTHLY' && form.frequencyType"> <el-form-item label="日期" prop="frequencyDetail"> <el-date-picker v-model="form.frequencyDetail" type="datetime" clearable placeholder="选择开始日期" format="DD,HH:mm" value-format="DD,HH:mm" /> </el-form-item> </el-col> <el-col :span="12" v-if="form.frequencyType === 'QUARTERLY' && form.frequencyType"> <el-form-item label="日期" prop="frequencyDetail"> <el-date-picker v-model="form.frequencyDetail" type="datetime" clearable placeholder="选择开始日期" format="MM,DD,HH:mm" value-format="MM,DD,HH:mm" /> </el-form-item> </el-col> </el-row> </el-form> <template #footer> <div class="dialog-footer"> <el-button @click="cancel">取消</el-button> <el-button type="primary" @click="submitForm">保存</el-button> </div> </template> </el-dialog> </div> </template> <script setup> @@ -120,120 +127,117 @@ const operationType = ref('add'); const deviceOptions = ref([]); const data = reactive({ form: { form: { taskId: undefined, taskName: undefined, taskName: undefined, inspector: '', inspectorIds: '', remarks: '', frequencyType: '', frequencyDetail: '', week: '', time: '', inspector: '', inspectorIds: '', remarks: '', frequencyType: '', frequencyDetail: '', week: '', time: '', dateStr: '' }, rules: { taskName: [{ required: true, message: "请选择设备", trigger: "blur" },], inspector: [{ required: true, message: "请输入巡检人", trigger: "blur" },], }, rules: { taskId: [{ required: true, message: "请选择设备", trigger: "change" },], inspector: [{ required: true, message: "请输入巡检人", trigger: "blur" },], dateStr: [{ required: true, message: "请选择登记时间", trigger: "change" }] } } }) const { form, rules } = toRefs(data) const userList = ref([]) const loadDeviceName = async () => { const { data } = await getDeviceLedger(); deviceOptions.value = data; const { data } = await getDeviceLedger(); deviceOptions.value = data; }; const setDeviceModel = (id) => { const option = deviceOptions.value.find((item) => item.id === id); if (option) { form.value.taskName = option.deviceName; } const option = deviceOptions.value.find((item) => item.id === id); if (option) { form.value.taskName = option.deviceName; } } // 打开弹框 const openDialog = async (type, row) => { dialogVisitable.value = true operationType.value = type // 重置表单 resetForm(); // 加载用户列表 userListNoPageByTenantId().then((res) => { userList.value = res.data; }); // 加载设备列表 await loadDeviceName(); if (type === 'edit' && row) { form.value = {...row} form.value.inspector = form.value.inspectorIds.split(',').map(Number) } dialogVisitable.value = true operationType.value = type // 重置表单 resetForm(); // 加载用户列表 userListNoPageByTenantId().then((res) => { userList.value = res.data; }); // 加载设备列表 await loadDeviceName(); if (type === 'edit' && row) { form.value = {...row} form.value.inspector = form.value.inspectorIds.split(',').map(Number) // 如果有设备ID,自动设置设备信息 if (form.value.taskId) { setDeviceModel(form.value.taskId); } } } // 关闭对话框 const cancel = () => { resetForm() dialogVisitable.value = false emit('closeDia') resetForm() dialogVisitable.value = false emit('closeDia') } // 重置表单函数 const resetForm = () => { if (proxy.$refs.formRef) { proxy.$refs.formRef.resetFields() } // 重置表单数据确保设备信息正确重置 form.value = { taskName: '', inspector: '', inspectorIds: '', remarks: '', frequencyType: '', frequencyDetail: '', week: '', time: '', dateStr: '' } if (proxy.$refs.formRef) { proxy.$refs.formRef.resetFields() } // 重置表单数据确保设备信息正确重置 form.value = { taskId: undefined, taskName: undefined, inspector: '', inspectorIds: '', remarks: '', frequencyType: '', frequencyDetail: '', week: '', time: '' } } // 提交表单 const submitForm = () => { proxy.$refs["formRef"].validate(async valid => { if (valid) { try { // 创建提交数据的副本 const submitData = {...form.value} submitData.inspectorIds = submitData.inspector.join(',') delete submitData.inspector // 编辑模式下不传递登记时间 if (operationType.value === 'edit') { delete submitData.createTime } if (submitData.frequencyType === 'WEEKLY') { let frequencyDetail = '' frequencyDetail = submitData.week + ',' + submitData.time submitData.frequencyDetail = frequencyDetail } let res = await userStore.getInfo() submitData.registrantId = res.user.userId await addOrEditTimingTask(submitData) cancel() proxy.$modal.msgSuccess('提交成功') } catch (error) { proxy.$modal.msgError('提交失败,请重试') } } }) proxy.$refs["formRef"].validate(async valid => { if (valid) { try { form.value.inspectorIds = form.value.inspector.join(',') delete form.value.inspector if (form.value.frequencyType === 'WEEKLY') { let frequencyDetail = '' frequencyDetail = form.value.week + ',' + form.value.time form.value.frequencyDetail = frequencyDetail } let res = await userStore.getInfo() form.value.registrantId = res.user.userId await addOrEditTimingTask(form.value) cancel() proxy.$modal.msgSuccess('提交成功') } catch (error) { proxy.$modal.msgError('提交失败,请重试') } } }) } defineExpose({ openDialog }) </script> src/views/equipmentManagement/inspectionManagement/index.vue
@@ -1,80 +1,80 @@ <template> <div class="app-container"> <el-form :inline="true" :model="queryParams" class="search-form"> <el-form-item label="搜索"> <el-input v-model="queryParams.searchAll" placeholder="请输入关键字" clearable :style="{ width: '100%' }" /> </el-form-item> <el-form-item> <el-button type="primary" @click="handleQuery">查询</el-button> <el-button @click="resetQuery">重置</el-button> </el-form-item> </el-form> <el-card> <div style="display: flex;flex-direction: row;justify-content: space-between;margin-bottom: 10px;"> <el-radio-group v-model="activeRadio" @change="radioChange"> <el-radio-button v-for="tab in radios" :key="tab.name" :label="tab.label" :value="tab.name"/> </el-radio-group> <!-- 操作按钮区 --> <el-space v-if="activeRadio !== 'task'"> <el-button type="primary" :icon="Plus" @click="handleAdd(undefined)">新建</el-button> <el-button type="danger" :icon="Delete" @click="handleDelete">删除</el-button> <el-button @click="handleOut">导出</el-button> </el-space> <el-space v-else> <el-button @click="handleOut">导出</el-button> </el-space> </div> <div> <div> <PIMTable :table-loading="tableLoading" :table-data="tableData" :column="tableColumns" @selection-change="handleSelectionChange" :is-selection="true" :border="true" :table-style="{ width: '100%', height: 'calc(100vh - 23em)' }" > <template #inspector="{ row }"> <div class="person-tags"> <!-- 调试信息,上线时删除 --> <!-- {{ console.log('inspector data:', row.inspector) }} --> <template v-if="row.inspector && row.inspector.length > 0"> <el-tag v-for="(person, index) in row.inspector" :key="index" size="small" type="primary" class="person-tag" > {{ person }} </el-tag> </template> <span v-else class="no-data">--</span> </div> </template> </PIMTable> </div> <pagination v-if="total>0" :page="pageNum" :limit="pageSize" :total="total" @pagination="handlePagination" :layout="'total, prev, pager, next, jumper'" /> </div> </el-card> <form-dia ref="formDia" @closeDia="handleQuery"></form-dia> <view-files ref="viewFiles"></view-files> </div> <div class="app-container"> <el-form :inline="true" :model="queryParams" class="search-form"> <el-form-item label="搜索"> <el-input v-model="queryParams.searchAll" placeholder="请输入关键字" clearable :style="{ width: '100%' }" /> </el-form-item> <el-form-item> <el-button type="primary" @click="handleQuery">查询</el-button> <el-button @click="resetQuery">重置</el-button> </el-form-item> </el-form> <el-card> <div style="display: flex;flex-direction: row;justify-content: space-between;margin-bottom: 10px;"> <el-radio-group v-model="activeRadio" @change="radioChange"> <el-radio-button v-for="tab in radios" :key="tab.name" :label="tab.label" :value="tab.name"/> </el-radio-group> <!-- 操作按钮区 --> <el-space v-if="activeRadio !== 'task'"> <el-button type="primary" :icon="Plus" @click="handleAdd(undefined)">新建</el-button> <el-button type="danger" :icon="Delete" @click="handleDelete">删除</el-button> <el-button @click="handleOut">导出</el-button> </el-space> <el-space v-else> <el-button @click="handleOut">导出</el-button> </el-space> </div> <div> <div> <PIMTable :table-loading="tableLoading" :table-data="tableData" :column="tableColumns" @selection-change="handleSelectionChange" :is-selection="true" :border="true" :table-style="{ width: '100%', height: 'calc(100vh - 23em)' }" > <template #inspector="{ row }"> <div class="person-tags"> <!-- 调试信息,上线时删除 --> <!-- {{ console.log('inspector data:', row.inspector) }} --> <template v-if="row.inspector && row.inspector.length > 0"> <el-tag v-for="(person, index) in row.inspector" :key="index" size="small" type="primary" class="person-tag" > {{ person }} </el-tag> </template> <span v-else class="no-data">--</span> </div> </template> </PIMTable> </div> <pagination v-if="total>0" :page="pageNum" :limit="pageSize" :total="total" @pagination="handlePagination" :layout="'total, prev, pager, next, jumper'" /> </div> </el-card> <form-dia ref="formDia" @closeDia="handleQuery"></form-dia> <view-files ref="viewFiles"></view-files> </div> </template> <script setup> @@ -90,9 +90,9 @@ // 接口引入 import { delTimingTask, inspectionTaskList, timingTaskList delTimingTask, inspectionTaskList, timingTaskList } from "@/api/inspectionManagement/index.js"; // 全局变量 @@ -102,14 +102,14 @@ // 查询参数 const queryParams = reactive({ searchAll: "", searchAll: "", }); // 单选框配置 const activeRadio = ref("taskManage"); const radios = reactive([ { name: "taskManage", label: "定时任务管理" }, { name: "task", label: "定时任务记录" }, { name: "taskManage", label: "定时任务管理" }, { name: "task", label: "定时任务记录" }, ]); // 表格数据 @@ -124,102 +124,102 @@ // 列配置 const columns = ref([ { prop: "taskName", label: "巡检任务名称", minWidth: 160 }, { prop: "remarks", label: "备注", minWidth: 150 }, { prop: "inspector", label: "执行巡检人", minWidth: 150, slot: "inspector" }, { prop: "frequencyType", label: "频次", minWidth: 150, formatter: (_, __, val) => ({ DAILY: "每日", WEEKLY: "每周", MONTHLY: "每月", QUARTERLY: "季度" }[val] || "") }, { prop: "frequencyDetail", label: "开始日期与时间", minWidth: 150, formatter: (row, column, cellValue) => { // 先判断是否是字符串 if (typeof cellValue !== 'string') return ''; let val = cellValue; const replacements = { MON: '周一', TUE: '周二', WED: '周三', THU: '周四', FRI: '周五', SAT: '周六', SUN: '周日' }; // 使用正则一次性替换所有匹配项 return val.replace(/MON|TUE|WED|THU|FRI|SAT|SUN/g, match => replacements[match]); } }, { prop: "registrant", label: "登记人", minWidth: 100 }, { prop: "dateStr", label: "登记日期", minWidth: 100 }, { prop: "taskName", label: "巡检任务名称", minWidth: 160 }, { prop: "remarks", label: "备注", minWidth: 150 }, { prop: "inspector", label: "执行巡检人", minWidth: 150, slot: "inspector" }, { prop: "frequencyType", label: "频次", minWidth: 150, formatter: (_, __, val) => ({ DAILY: "每日", WEEKLY: "每周", MONTHLY: "每月", QUARTERLY: "季度" }[val] || "") }, { prop: "frequencyDetail", label: "开始日期与时间", minWidth: 150, formatter: (row, column, cellValue) => { // 先判断是否是字符串 if (typeof cellValue !== 'string') return ''; let val = cellValue; const replacements = { MON: '周一', TUE: '周二', WED: '周三', THU: '周四', FRI: '周五', SAT: '周六', SUN: '周日' }; // 使用正则一次性替换所有匹配项 return val.replace(/MON|TUE|WED|THU|FRI|SAT|SUN/g, match => replacements[match]); } }, { prop: "registrant", label: "登记人", minWidth: 100 }, { prop: "dateStr", label: "登记日期", minWidth: 100 }, ]); // 操作列配置 const getOperationColumn = (operations) => { if (!operations || operations.length === 0) return null; const operationConfig = { label: "操作", width: 130, fixed: "right", dataType: "action", operation: operations.map(op => { switch (op) { case 'edit': return { name: "编辑", clickFun: handleAdd, color: "#409EFF" }; case 'viewFile': return { name: "查看附件", clickFun: viewFile, color: "#67C23A" }; default: return null; } }).filter(Boolean) }; return operationConfig; if (!operations || operations.length === 0) return null; const operationConfig = { label: "操作", width: 130, fixed: "right", dataType: "action", operation: operations.map(op => { switch (op) { case 'edit': return { name: "编辑", clickFun: handleAdd, color: "#409EFF" }; case 'viewFile': return { name: "查看附件", clickFun: viewFile, color: "#67C23A" }; default: return null; } }).filter(Boolean) }; return operationConfig; }; onMounted(() => { radioChange('taskManage'); radioChange('taskManage'); }); // 单选变化 const radioChange = (value) => { if (value === "taskManage") { const operationColumn = getOperationColumn(['edit']); tableColumns.value = [...columns.value, ...(operationColumn ? [operationColumn] : [])]; operationsArr.value = ['edit']; } else if (value === "task") { const operationColumn = getOperationColumn(['viewFile']); tableColumns.value = [...columns.value, ...(operationColumn ? [operationColumn] : [])]; operationsArr.value = ['viewFile']; } pageNum.value = 1; pageSize.value = 10; getList(); if (value === "taskManage") { const operationColumn = getOperationColumn(['edit']); tableColumns.value = [...columns.value, ...(operationColumn ? [operationColumn] : [])]; operationsArr.value = ['edit']; } else if (value === "task") { const operationColumn = getOperationColumn(['viewFile']); tableColumns.value = [...columns.value, ...(operationColumn ? [operationColumn] : [])]; operationsArr.value = ['viewFile']; } pageNum.value = 1; pageSize.value = 10; getList(); }; // 查询操作 const handleQuery = () => { pageNum.value = 1; pageSize.value = 10; getList(); pageNum.value = 1; pageSize.value = 10; getList(); }; // 分页处理 const handlePagination = (val) => { @@ -229,129 +229,129 @@ }; // 获取列表数据 const getList = () => { tableLoading.value = true; const params = { ...queryParams, size: pageSize.value, current: pageNum.value }; let apiCall; if (activeRadio.value === "task") { apiCall = inspectionTaskList(params); } else { apiCall = timingTaskList(params); } apiCall.then(res => { const rawData = res.data.records || []; // 处理 inspector 字段,将字符串转换为数组(适用于所有情况) tableData.value = rawData.map(item => { const processedItem = { ...item }; // 处理 inspector 字段 if (processedItem.inspector) { if (typeof processedItem.inspector === 'string') { // 字符串按逗号分割 processedItem.inspector = processedItem.inspector.split(',').map(s => s.trim()).filter(s => s); } else if (!Array.isArray(processedItem.inspector)) { // 非数组转为数组 processedItem.inspector = [processedItem.inspector]; } } else { // 空值设为空数组 processedItem.inspector = []; } return processedItem; }); total.value = res.data.total || 0; }).finally(() => { tableLoading.value = false; }); tableLoading.value = true; const params = { ...queryParams, size: pageSize.value, current: pageNum.value }; let apiCall; if (activeRadio.value === "task") { apiCall = inspectionTaskList(params); } else { apiCall = timingTaskList(params); } apiCall.then(res => { const rawData = res.data.records || []; // 处理 inspector 字段,将字符串转换为数组(适用于所有情况) tableData.value = rawData.map(item => { const processedItem = { ...item }; // 处理 inspector 字段 if (processedItem.inspector) { if (typeof processedItem.inspector === 'string') { // 字符串按逗号分割 processedItem.inspector = processedItem.inspector.split(',').map(s => s.trim()).filter(s => s); } else if (!Array.isArray(processedItem.inspector)) { // 非数组转为数组 processedItem.inspector = [processedItem.inspector]; } } else { // 空值设为空数组 processedItem.inspector = []; } return processedItem; }); total.value = res.data.total || 0; }).finally(() => { tableLoading.value = false; }); }; // 重置查询 const resetQuery = () => { for (const key in queryParams) { if (!["pageNum", "pageSize"].includes(key)) { queryParams[key] = ""; } } handleQuery(); for (const key in queryParams) { if (!["pageNum", "pageSize"].includes(key)) { queryParams[key] = ""; } } handleQuery(); }; // 新增 / 编辑 const handleAdd = (row) => { const type = row ? 'edit' : 'add'; nextTick(() => { formDia.value?.openDialog(type, row); }); const type = row ? 'edit' : 'add'; nextTick(() => { formDia.value?.openDialog(type, row); }); }; // 查看附件 const viewFile = (row) => { nextTick(() => { viewFiles.value?.openDialog(row); }); nextTick(() => { viewFiles.value?.openDialog(row); }); }; // 删除操作 const handleDelete = () => { if (!selectedRows.value.length) { proxy.$modal.msgWarning("请选择要删除的数据"); return; } const deleteIds = selectedRows.value.map(item => item.id); proxy.$modal.confirm('是否确认删除所选数据项?').then(() => { return delTimingTask(deleteIds); }).then(() => { proxy.$modal.msgSuccess("删除成功"); handleQuery(); }).catch(() => {}); if (!selectedRows.value.length) { proxy.$modal.msgWarning("请选择要删除的数据"); return; } const deleteIds = selectedRows.value.map(item => item.id); proxy.$modal.confirm('是否确认删除所选数据项?').then(() => { return delTimingTask(deleteIds); }).then(() => { proxy.$modal.msgSuccess("删除成功"); handleQuery(); }).catch(() => {}); }; // 多选变更 const handleSelectionChange = (selection) => { selectedRows.value = selection; selectedRows.value = selection; }; // 导出 const handleOut = () => { ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", { confirmButtonText: "确认", cancelButtonText: "取消", type: "warning", }) .then(() => { // 根据当前选中的标签页调用不同的导出接口 if (activeRadio.value === "taskManage") { // 定时任务管理 proxy.download("/timingTask/export", {}, "定时任务管理.xlsx"); } else if (activeRadio.value === "task") { // 定时任务记录 proxy.download("/inspectionTask/export", {}, "定时任务记录.xlsx"); } }) .catch(() => { proxy.$modal.msg("已取消"); }); ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", { confirmButtonText: "确认", cancelButtonText: "取消", type: "warning", }) .then(() => { // 根据当前选中的标签页调用不同的导出接口 if (activeRadio.value === "taskManage") { // 定时任务管理 proxy.download("/timingTask/export", {}, "定时任务管理.xlsx"); } else if (activeRadio.value === "task") { // 定时任务记录 proxy.download("/inspectionTask/export", {}, "定时任务记录.xlsx"); } }) .catch(() => { proxy.$modal.msg("已取消"); }); }; </script> <style scoped> .person-tags { display: flex; flex-wrap: wrap; gap: 4px; display: flex; flex-wrap: wrap; gap: 4px; } .person-tag { margin-right: 4px; margin-bottom: 2px; margin-right: 4px; margin-bottom: 2px; } .no-data { color: #909399; font-size: 14px; color: #909399; font-size: 14px; } </style> src/views/inventoryManagement/dispatchLog/index.vue
@@ -23,6 +23,13 @@ clearable @change="handleQuery" /> <span class="search_title ml10">产品大类:</span> <el-input v-model="searchForm.productCategory" style="width: 240px" placeholder="请输入" clearable /> <el-button type="primary" @click="handleQuery" style="margin-left: 10px">搜索</el-button> </div> <div> @@ -91,6 +98,13 @@ clearable @change="handleQuery" /> <span class="search_title ml10">产品大类:</span> <el-input v-model="searchForm.productCategory" style="width: 240px" placeholder="请输入" clearable /> <el-button type="primary" @click="handleQuery" style="margin-left: 10px">搜索</el-button> </div> <div> @@ -158,6 +172,13 @@ format="YYYY-MM-DD" clearable @change="handleQuery" /> <span class="search_title ml10">产品大类:</span> <el-input v-model="searchForm.productCategory" style="width: 240px" placeholder="请输入" clearable /> <el-button type="primary" @click="handleQuery" style="margin-left: 10px">搜索</el-button> </div> @@ -358,6 +379,7 @@ searchForm: { supplierName: "", customerName: "", productCategory:'', timeStr: getCurrentDate(), }, form: { @@ -403,6 +425,7 @@ params.supplierName = searchForm.value.supplierName params.timeStr = searchForm.value.timeStr } params.productCategory = searchForm.value.productCategory // 根据不同的 tab 类型调用不同的接口 const apiCall = activeTab.value === 'production' @@ -431,6 +454,7 @@ searchForm.value.customerName = '' searchForm.value.timeStr = '' selectedRows.value = [] searchForm.value.productCategory = '' getList() }; src/views/inventoryManagement/issueManagement/index.vue
@@ -17,6 +17,13 @@ clearable @change="handleQuery" /> <span class="search_title ml10">产品大类:</span> <el-input v-model="searchForm.productCategory" style="width: 240px" placeholder="请输入" clearable /> <el-button type="primary" @click="handleQuery" style="margin-left: 10px">搜索</el-button> </div> <div> @@ -67,6 +74,13 @@ clearable @change="handleQuery" /> <span class="search_title ml10">产品大类:</span> <el-input v-model="searchForm.productCategory" style="width: 240px" placeholder="请输入" clearable /> <el-button type="primary" @click="handleQuery" style="margin-left: 10px">搜索</el-button> </div> <div> @@ -117,6 +131,13 @@ format="YYYY-MM-DD" clearable @change="handleQuery" /> <span class="search_title ml10">产品大类:</span> <el-input v-model="searchForm.productCategory" style="width: 240px" placeholder="请输入" clearable /> <el-button type="primary" @click="handleQuery" style="margin-left: 10px">搜索</el-button> </div> @@ -223,6 +244,7 @@ inboundTime:'', nickName: '', userId: '', productCategory:'', timeStr: getCurrentDate(), }, form: { @@ -257,6 +279,7 @@ params.supplierName = searchForm.value.supplierName params.timeStr = searchForm.value.timeStr } params.productCategory = searchForm.value.productCategory let apiCall if (activeTab.value === 'production') { apiCall = getStockInPageByProduction(params) @@ -280,6 +303,7 @@ searchForm.value.customerName = '' searchForm.value.timeStr = '' selectedRows.value = [] searchForm.value.productCategory = '' getList() } src/views/inventoryManagement/receiptManagement/index.vue
@@ -17,6 +17,13 @@ clearable @change="handleQuery" /> <span class="search_title ml10">产品大类:</span> <el-input v-model="searchForm.productCategory" style="width: 240px" placeholder="请输入" clearable /> <el-button type="primary" @click="handleQuery" style="margin-left: 10px">搜索</el-button> </div> <div> @@ -62,6 +69,13 @@ clearable @change="handleQuery" /> <span class="search_title ml10">产品大类:</span> <el-input v-model="searchForm.productCategory" style="width: 240px" placeholder="请输入" clearable /> <el-button type="primary" @click="handleQuery" style="margin-left: 10px">搜索</el-button> </div> <div> @@ -114,6 +128,13 @@ format="YYYY-MM-DD" clearable @change="handleQuery" /> <span class="search_title ml10">产品大类:</span> <el-input v-model="searchForm.productCategory" style="width: 240px" placeholder="请输入" clearable /> <el-button type="primary" @click="handleQuery" style="margin-left: 10px">搜索</el-button> </div> @@ -200,6 +221,7 @@ searchForm: { supplierName: '', customerName: '', productCategory:'', timeStr: getCurrentDate(), }, }) @@ -227,6 +249,7 @@ params.supplierName = searchForm.value.supplierName params.timeStr = searchForm.value.timeStr } params.productCategory = searchForm.value.productCategory // 根据不同的 tab 类型调用不同的接口 const apiCall = activeTab.value === 'production' @@ -251,6 +274,7 @@ searchForm.value.supplierName = '' searchForm.value.customerName = '' searchForm.value.timeStr = '' searchForm.value.productCategory = '' getList() } src/views/inventoryManagement/stockManagement/index.vue
@@ -17,6 +17,13 @@ clearable @change="handleQuery" /> <span class="search_title ml10">产品大类:</span> <el-input v-model="searchForm.productCategory" style="width: 240px" placeholder="请输入" clearable /> <el-button type="primary" @click="handleQuery" style="margin-left: 10px">搜索</el-button> </div> <div> @@ -68,6 +75,13 @@ clearable @change="handleQuery" /> <span class="search_title ml10">产品大类:</span> <el-input v-model="searchForm.productCategory" style="width: 240px" placeholder="请输入" clearable /> <el-button type="primary" @click="handleQuery" style="margin-left: 10px">搜索</el-button> </div> <div> @@ -118,6 +132,13 @@ clearable @change="handleQuery" /> <span class="search_title ml10">产品大类:</span> <el-input v-model="searchForm.productCategory" style="width: 240px" placeholder="请输入" clearable /> <el-button type="primary" @click="handleQuery" style="margin-left: 10px">搜索</el-button> </div> <div> @@ -309,6 +330,7 @@ const data = reactive({ searchForm: { // supplierName: '', productCategory:'', customerName: '', timeStr: getCurrentDate(), }, @@ -368,6 +390,7 @@ ...page, timeStr: searchForm.value.timeStr, } params.productCategory = searchForm.value.productCategory if (activeTab.value === 'production') { params.customerName = searchForm.value.customerName } else { @@ -405,6 +428,7 @@ searchForm.value.customerName = '' searchForm.value.timeStr = '' selectedRows.value = [] searchForm.value.productCategory = '' getList() } src/views/procurementManagement/invoiceEntry/components/Modal.vue
@@ -586,45 +586,45 @@ proxy.$modal.msgError("批量登记失败"); }); } else { // 单个合同提交逻辑 const singleContract = selectedContracts.value[0]; const singleForm = { // 基础表单数据 invoiceNumber: form.invoiceNumber, invoiceAmount: form.invoiceAmount, entryDate: form.entryDate, enterDate: form.enterDate, issUerId: form.issUerId, // 录入人id issUer: form.issUer, // 录入人 tempFileIds: form.tempFileIds, // 单个合同提交逻辑 - 以数组格式传递 const singleContract = selectedContracts.value[0]; const singleFormArray = [{ // 基础表单数据 invoiceNumber: form.invoiceNumber, invoiceAmount: form.invoiceAmount, entryDate: form.entryDate, enterDate: form.enterDate, issUerId: form.issUerId, // 录入人id issUer: form.issUer, // 录入人 tempFileIds: form.tempFileIds, // 合同实际信息 purchaseLedgerId: singleContract.id, // 使用id作为字段名,值为purchaseLedgerId purchaseContractNumber: singleContract.purchaseContractNumber, // 使用实际的采购合同号 salesContractNo: singleContract.salesContractNo, // 使用实际的销售合同号 supplierName: singleContract.supplierName, // 使用实际的供应商名称 projectName: singleContract.projectName, // 使用实际的项目名称 // 产品数据 productData: proxy.HaveJson(form.productData), // 批量标识 isBatch: false, type: 4 }]; // 合同实际信息 purchaseLedgerId: singleContract.id, // 使用id作为字段名,值为purchaseLedgerId purchaseContractNumber: singleContract.purchaseContractNumber, // 使用实际的采购合同号 salesContractNo: singleContract.salesContractNo, // 使用实际的销售合同号 supplierName: singleContract.supplierName, // 使用实际的供应商名称 projectName: singleContract.projectName, // 使用实际的项目名称 // 产品数据 productData: proxy.HaveJson(form.productData), // 批量标识 isBatch: false, type: 4 }; modalLoading.value = true; addOrUpdateRegistration(singleForm).then((res) => { modalLoading.value = false; if (res.code === 200) { proxy.$modal.msgSuccess("登记成功"); closeAndRefresh(); } }).catch(() => { modalLoading.value = false; proxy.$modal.msgError("登记失败"); }); } modalLoading.value = true; addOrUpdateRegistration(singleFormArray).then((res) => { modalLoading.value = false; if (res.code === 200) { proxy.$modal.msgSuccess("登记成功"); closeAndRefresh(); } }).catch(() => { modalLoading.value = false; proxy.$modal.msgError("登记失败"); }); } } }); }; src/views/reportAnalysis/dataDashboard/index.vue
@@ -54,7 +54,7 @@ <!-- 质量统计 --> <div class="panel-header"> <span class="panel-title">本周质量统计</span> <span class="panel-title">近4月质量统计</span> </div> <div class="main-panel"> <div class="panel-item-customers"> @@ -174,7 +174,7 @@ </div> <div class="financial-header"> <span class="financial-title">本周财务分析</span> <span class="financial-title">近4月财务分析</span> </div> <div class="main-panel"> <div class="panel-item-customers"> @@ -412,7 +412,7 @@ const barLegend = { show: true, textStyle: { color: '#B8C8E0' }, data: ['原材料不合格数', '过程不合格数', '出厂不合格数'] data: ['原材料合格数', '过程合格数', '出不合格数'] } const barLegend1 = { show: true, @@ -487,7 +487,7 @@ ]) const barSeries1 = ref([ { name: '原材料不合格数', name: '原材料合格数', type: 'bar', barGap: 0, emphasis: { @@ -509,7 +509,7 @@ data: [] }, { name: '过程不合格数', name: '过程合格数', type: 'bar', emphasis: { focus: 'series' @@ -530,7 +530,7 @@ data: [] }, { name: '出厂不合格数', name: '出厂合格数', type: 'bar', emphasis: { focus: 'series' src/views/salesManagement/invoiceRegistration/index.vue
@@ -1,369 +1,382 @@ <template> <div class="app-container"> <div class="search_form"> <el-form :inline="true" :model="searchForm"> <el-form-item label="客户名称"> <el-input v-model="searchForm.customerName" style="width: 240px" placeholder="请输入名称搜索" clearable :prefix-icon="Search" @change="handleQuery" /> </el-form-item> <el-form-item> <el-checkbox v-model="searchForm.status" label="不显示未开票金额为0" @change="handleQuery" /> </el-form-item> <el-form-item> <el-button type="primary" @click="handleQuery"> 搜索 </el-button> <el-button @click="resetForm"> 重置 </el-button> <el-button @click="handleExport" style="margin-right: 10px">导出</el-button> </el-form-item> </el-form> </div> <div class="table_list"> <div class="flex justify-between"> <div></div> <div> <el-button type="primary" @click="openForm" style="margin-bottom: 8px"> 新增登记 </el-button> </div> </div> <el-table :data="tableData" :border="true" height="calc(100vh - 21em)" v-loading="tableLoading" :expand-row-keys="expandedRowKeys" :row-key="(row) => row.id" show-summary :summary-method="summarizeMainTable" @expand-change="expandChange" @selection-change="handleSelectionChange" > <el-table-column align="center" type="selection" width="55" /> <el-table-column type="expand"> <template #default="props"> <el-table :data="props.row.children" border show-summary :summary-method="summarizeChildrenTable" > <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" /> <el-table-column label="含税总价(元)" prop="taxInclusiveTotalPrice" :formatter="formattedNumber" /> <el-table-column label="不含税总价(元)" prop="taxExclusiveTotalPrice" :formatter="formattedNumber" /> <el-table-column label="开票数" prop="invoiceNum" :formatter="formattedNumber" /> <el-table-column label="开票金额(元)" prop="invoiceAmount" :formatter="formattedNumber" /> <el-table-column label="未开票数" prop="noInvoiceNum" :formatter="formattedNumber" /> <el-table-column label="未开票金额(元)" prop="noInvoiceAmount" :formatter="formattedNumber" /> </el-table> </template> </el-table-column> <el-table-column align="center" label="序号" type="index" width="60" /> <el-table-column label="销售合同号" prop="salesContractNo" show-overflow-tooltip /> <el-table-column label="客户名称" prop="customerName" show-overflow-tooltip /> <el-table-column label="业务员" prop="salesman" show-overflow-tooltip width="90"/> <el-table-column label="合同金额(元)" prop="contractAmount" show-overflow-tooltip :formatter="formattedNumber" <div class="app-container"> <div class="search_form"> <el-form :inline="true" :model="searchForm"> <el-form-item label="客户名称"> <el-input v-model="searchForm.customerName" style="width: 240px" placeholder="请输入名称搜索" clearable :prefix-icon="Search" @change="handleQuery" /> </el-form-item> <el-form-item> <el-checkbox v-model="searchForm.status" label="不显示未开票金额为0" @change="handleQuery" /> </el-form-item> <el-form-item> <el-button type="primary" @click="handleQuery"> 搜索 </el-button> <el-button @click="resetForm"> 重置 </el-button> <el-button @click="handleExport" style="margin-right: 10px">导出</el-button> </el-form-item> </el-form> </div> <div class="table_list"> <div class="flex justify-between"> <div></div> <div> <el-button type="primary" @click="openForm" style="margin-bottom: 8px"> 新增登记 </el-button> </div> </div> <el-table :data="tableData" :border="true" height="calc(100vh - 21em)" v-loading="tableLoading" :expand-row-keys="expandedRowKeys" :row-key="(row) => row.id" show-summary :summary-method="summarizeMainTable" @expand-change="expandChange" @selection-change="handleSelectionChange" > <el-table-column align="center" type="selection" width="55" /> <el-table-column type="expand"> <template #default="props"> <el-table :data="props.row.children" border show-summary :summary-method="summarizeChildrenTable" > <el-table-column align="center" label="序号" type="index" width="60" /> <el-table-column label="产品大类" prop="productCategory" /> <el-table-column label="规格型号" prop="specificationModel" width="150" /> <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" /> <el-table-column label="含税总价(元)" prop="taxInclusiveTotalPrice" :formatter="formattedNumber" /> <el-table-column label="不含税总价(元)" prop="taxExclusiveTotalPrice" :formatter="formattedNumber" /> <el-table-column label="开票数" prop="invoiceNum" :formatter="formattedNumber" /> <el-table-column label="开票金额(元)" prop="invoiceAmount" :formatter="formattedNumber" /> <el-table-column label="未开票数" prop="noInvoiceNum" :formatter="formattedNumber" /> <el-table-column label="未开票金额(元)" prop="noInvoiceAmount" :formatter="formattedNumber" /> </el-table> </template> </el-table-column> <el-table-column align="center" label="序号" type="index" width="60" /> <el-table-column label="销售合同号" prop="salesContractNo" show-overflow-tooltip width="200" /> <el-table-column label="客户合同号" prop="customerContractNo" width="200" show-overflow-tooltip /> <el-table-column label="客户名称" prop="customerName" show-overflow-tooltip width="240" /> <el-table-column label="业务员" prop="salesman" show-overflow-tooltip width="90"/> <el-table-column label="合同金额(元)" prop="contractAmount" show-overflow-tooltip :formatter="formattedNumber" width="220" /> <el-table-column label="已开票金额(元)" prop="invoiceTotal" show-overflow-tooltip :formatter="formattedNumber" width="120" /> <el-table-column label="未开票金额(元)" prop="noInvoiceAmountTotal" show-overflow-tooltip width="120" > <template #default="{ row, column }"> <el-text type="danger"> {{ formattedNumber(row, column, row.noInvoiceAmountTotal) }} </el-text> </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" /> </div> <el-dialog v-model="dialogFormVisible" title="新增开票登记页面" width="85%" @close="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="salesContractNo"> <el-input v-model="form.salesContractNo" disabled></el-input> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="客户名称:" prop="customerName"> <el-input v-model="form.customerName" placeholder="自动填充" disabled ></el-input> </el-form-item> </el-col> </el-row> <el-row :gutter="30"> <el-col :span="12"> <el-form-item label="业务员:" prop="salesman"> <el-input v-model="form.salesman" placeholder="自动填充" disabled /> </el-form-item> </el-col> </el-row> <el-row :gutter="30"> <el-col :span="12"> <el-form-item label="录入人" prop="createUer"> <el-input v-model="form.createUer" placeholder="请输入录入人" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="开票日期" prop="issueDate"> <el-date-picker style="width: 100%" v-model="form.issueDate" type="date" placeholder="请选择" clearable format="YYYY-MM-DD" value-format="YYYY-MM-DD" /> </el-form-item> </el-col> </el-row> <el-row :gutter="30"> <el-col :span="12"> <el-form-item label="录入日期:" prop="createTime"> <el-date-picker style="width: 100%" v-model="form.createTime" type="date" placeholder="请选择" clearable /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="发票号码:" prop="invoiceNo"> <el-input v-model="form.invoiceNo" placeholder="请输入" clearable /> </el-form-item> </el-col> </el-row> <el-row> <el-form-item label="产品信息:" prop="entryDate"> </el-form-item> </el-row> <el-table :data="productData" border show-summary :summary-method="summarizeChildrenTable" > <el-table-column align="center" label="序号" type="index" width="60" /> <el-table-column label="产品大类" prop="productCategory" /> <el-table-column label="规格型号" prop="specificationModel" width="150" /> <el-table-column label="单位" prop="unit" /> <el-table-column label="数量" prop="quantity" width="70" /> <el-table-column label="税率(%)" prop="taxRate" width="80" /> <el-table-column label="含税单价(元)" prop="taxInclusiveUnitPrice" :formatter="formattedNumber" /> <el-table-column label="已开票金额(元)" prop="invoiceTotal" show-overflow-tooltip :formatter="formattedNumber" width="120" /> <el-table-column label="未开票金额(元)" prop="noInvoiceAmountTotal" show-overflow-tooltip width="120" > <template #default="{ row, column }"> <el-text type="danger"> {{ formattedNumber(row, column, row.noInvoiceAmountTotal) }} </el-text> </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" /> </div> <el-dialog v-model="dialogFormVisible" title="新增开票登记页面" width="85%" @close="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="salesContractNo"> <el-input v-model="form.salesContractNo" disabled placeholder="多合同批量处理(具体合同号见产品列表)"></el-input> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="客户名称:" prop="customerName"> <el-input v-model="form.customerName" placeholder="自动填充" disabled ></el-input> </el-form-item> </el-col> </el-row> <el-row :gutter="30"> <el-col :span="12"> <el-form-item label="业务员:" prop="salesman"> <el-input v-model="form.salesman" placeholder="自动填充" disabled /> </el-form-item> </el-col> </el-row> <el-row :gutter="30"> <el-col :span="12"> <el-form-item label="录入人" prop="createUer"> <el-input v-model="form.createUer" placeholder="请输入录入人" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="开票日期" prop="issueDate"> <el-date-picker style="width: 100%" v-model="form.issueDate" type="date" placeholder="请选择" clearable format="YYYY-MM-DD" value-format="YYYY-MM-DD" /> </el-form-item> </el-col> </el-row> <el-row :gutter="30"> <el-col :span="12"> <el-form-item label="录入日期:" prop="createTime"> <el-date-picker style="width: 100%" v-model="form.createTime" type="date" placeholder="请选择" clearable /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="发票号码:" prop="invoiceNo"> <el-input v-model="form.invoiceNo" placeholder="请输入" clearable /> </el-form-item> </el-col> </el-row> <el-row> <el-form-item label="产品信息:" prop="entryDate"> </el-form-item> </el-row> <el-table :data="productData" border show-summary :summary-method="summarizeChildrenTable" > <el-table-column align="center" label="序号" type="index" width="60" /> <el-table-column label="所属合同" prop="salesContractNo" width="200"> <template #default="{ row }"> <el-tag type="primary">{{ row.salesContractNo }}</el-tag> </template> </el-table-column> <el-table-column label="产品大类" prop="productCategory" /> <el-table-column label="规格型号" prop="specificationModel" width="150" /> <el-table-column label="单位" prop="unit" /> <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="200" /> <el-table-column label="含税总价(元)" prop="taxInclusiveTotalPrice" :formatter="formattedNumber" /> <el-table-column label="含税总价(元)" prop="taxInclusiveTotalPrice" :formatter="formattedNumber" width="200" /> <el-table-column label="不含税总价(元)" prop="taxExclusiveTotalPrice" :formatter="formattedNumber" width="150" /> <el-table-column label="本次开票数" prop="currentInvoiceNum" width="180"> <template #default="scope"> <el-input-number :step="0.1" :min="0" style="width: 100%" /> <el-table-column label="不含税总价(元)" prop="taxExclusiveTotalPrice" :formatter="formattedNumber" width="150" /> <el-table-column label="本次开票数" prop="currentInvoiceNum" width="180"> <template #default="scope"> <el-input-number :step="0.1" :min="0" style="width: 100%" :precision="2" v-model="scope.row.currentInvoiceNum" @change="invoiceNumBlur(scope.row)" ></el-input-number> </template> </el-table-column> <el-table-column label="本次开票金额(元)" prop="currentInvoiceAmount" width="180" > <template #default="scope"> <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="scope.row.currentInvoiceNum" @change="invoiceNumBlur(scope.row)" ></el-input-number> </template> </el-table-column> <el-table-column label="本次开票金额(元)" prop="currentInvoiceAmount" width="180" > <template #default="scope"> <el-input-number :step="0.01" :min="0" style="width: 100%" :precision="2" v-model="scope.row.currentInvoiceAmount" @change="invoiceAmountBlur(scope.row)" ></el-input-number> </template> </el-table-column> <el-table-column label="未开票数" prop="noInvoiceNum" width="120"> <template #default="scope"> <el-input type="number" min="0" disabled v-model="scope.row.noInvoiceNum" ></el-input> </template> </el-table-column> <el-table-column label="未开票金额(元)" prop="noInvoiceAmount" width="200" > <template #default="scope"> <el-input type="number" min="0" disabled v-model="scope.row.noInvoiceAmount" :formatter="formattedInputNumber" :precision="2" :step="0.01" ></el-input> </template> </el-table-column> <el-table-column label="登记人" prop="register" width="100"> <!-- <template #default="{ row }"> <el-input v-model="row.register" placeholder="请输入登记人" disabled /> </template> --> </el-table-column> <el-table-column label="登记日期" prop="registerDate" width="150"> <!-- <template #default="{ row }"> <el-date-picker style="width: 100%" v-model="row.registerDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="date" placeholder="请选择" clearable disabled /> </template> --> </el-table-column> </el-table> </el-form> <template #footer> <div class="dialog-footer"> <el-button type="primary" @click="submitForm">确认</el-button> <el-button @click="closeDia">取消</el-button> </div> </template> </el-dialog> </div> v-model="scope.row.currentInvoiceAmount" @change="invoiceAmountBlur(scope.row)" ></el-input-number> </template> </el-table-column> <el-table-column label="未开票数" prop="noInvoiceNum" width="120"> <template #default="scope"> <el-input type="number" min="0" disabled v-model="scope.row.noInvoiceNum" ></el-input> </template> </el-table-column> <el-table-column label="未开票金额(元)" prop="noInvoiceAmount" width="200" > <template #default="scope"> <el-input type="number" min="0" disabled v-model="scope.row.noInvoiceAmount" :formatter="formattedInputNumber" :precision="2" :step="0.01" ></el-input> </template> </el-table-column> <el-table-column label="登记人" prop="register" width="100"> <!-- <template #default="{ row }"> <el-input v-model="row.register" placeholder="请输入登记人" disabled /> </template> --> </el-table-column> <el-table-column label="登记日期" prop="registerDate" width="150"> <!-- <template #default="{ row }"> <el-date-picker style="width: 100%" v-model="row.registerDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="date" placeholder="请选择" clearable disabled /> </template> --> </el-table-column> </el-table> </el-form> <template #footer> <div class="dialog-footer"> <el-button type="primary" @click="submitForm">确认</el-button> <el-button @click="closeDia">取消</el-button> </div> </template> </el-dialog> </div> </template> <script setup> @@ -373,9 +386,9 @@ import { ElMessageBox } from "element-plus"; // import {userListNoPage} from "@/api/system/user.js"; import { getSalesLedgerWithProducts, ledgerListPage, productList, getSalesLedgerWithProducts, ledgerListPage, productList, } from "@/api/salesManagement/salesLedger.js"; import { invoiceRegistrationSave } from "@/api/salesManagement/invoiceRegistration.js"; import useFormData from "@/hooks/useFormData"; @@ -389,261 +402,377 @@ const selectedRows = ref([]); const tableLoading = ref(false); const page = reactive({ current: 1, size: 100, current: 1, size: 100, }); const total = ref(0); // 用户信息表单弹框数据 const operationType = ref(""); const dialogFormVisible = ref(false); const data = reactive({ searchForm: { customerName: "", status: false, customerContractNo: undefined, // 客户合同号 projectName: undefined, // 项目名称 createUer: undefined, // 登记人 issueDate: undefined, // 开票日期 createTime: undefined, // 录入日期: }, form: { salesLedgerId: "", customerName: "", salesman: "", projectName: "", productData: [], invoiceNo: "", createUer: userStore.nickName, issueDate: dayjs().format("YYYY-MM-DD"), }, rules: { salesLedgerId: [{ required: true, message: "请选择", trigger: "change" }], createUer: [{ required: true, message: "请选择", trigger: "blur" }], issueDate: [{ required: true, message: "请选择", trigger: "change" }], invoiceNo: [{ required: true, message: "请输入", trigger: "change" }], createTime: [{ required: true, message: "请选择", trigger: "change" }], }, searchForm: { customerName: "", status: false, customerContractNo: undefined, // 客户合同号 projectName: undefined, // 项目名称 createUer: undefined, // 登记人 issueDate: undefined, // 开票日期 createTime: undefined, // 录入日期: productCategory: "", isInvoice: 1 }, form: { salesLedgerId: "", customerName: "", salesman: "", projectName: "", productData: [], invoiceNo: "", createUer: userStore.nickName, issueDate: dayjs().format("YYYY-MM-DD"), selectedContractIds: [], // 新增:存储所有选中的合同ID isBatch: false // 新增:标识是否为批量操作 }, rules: { createUer: [{ required: true, message: "请选择", trigger: "blur" }], issueDate: [{ required: true, message: "请选择", trigger: "change" }], invoiceNo: [{ required: true, message: "请输入", trigger: "change" }], createTime: [{ required: true, message: "请选择", trigger: "change" }], }, }); const { form, rules } = toRefs(data); const { form: searchForm, resetForm } = useFormData(data.searchForm); const formattedNumber = (row, column, cellValue) => { if (cellValue == 0) { return parseFloat(cellValue).toFixed(2); } if (cellValue) { return parseFloat(cellValue).toFixed(2); } else { return cellValue; } if (cellValue == 0) { return parseFloat(cellValue).toFixed(2); } if (cellValue) { return parseFloat(cellValue).toFixed(2); } else { return cellValue; } }; const formattedInputNumber = (value) => { return value ? parseFloat(value).toFixed(2) : 0; return value ? parseFloat(value).toFixed(2) : 0; }; // 查询列表 /** 搜索按钮操作 */ const handleQuery = () => { page.current = 1; getList(); page.current = 1; getList(); }; const paginationChange = (obj) => { page.current = obj.page; page.size = obj.limit; getList(); page.current = obj.page; page.size = obj.limit; getList(); }; const getList = () => { tableLoading.value = true; ledgerListPage({ ...searchForm, ...page }).then((res) => { tableLoading.value = false; tableData.value = res.records; total.value = res.total; expandedRowKeys.value = []; }); tableLoading.value = true; ledgerListPage({ ...searchForm, ...page }).then((res) => { tableLoading.value = false; tableData.value = res.records; total.value = res.total; expandedRowKeys.value = []; }); }; // 表格选择数据 const handleSelectionChange = (selection) => { console.log("selection", selection); selectedRows.value = selection.filter( (item) => item.salesContractNo !== undefined ); console.log("selection", selection); selectedRows.value = selection.filter( (item) => item.salesContractNo !== undefined ); }; 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 = []; } 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 summarizeMainTable = (param) => { return proxy.summarizeTable(param, [ "contractAmount", "invoiceTotal", "noInvoiceAmountTotal", ]); return proxy.summarizeTable(param, [ "contractAmount", "invoiceTotal", "noInvoiceAmountTotal", ]); }; // 子表合计方法 const summarizeChildrenTable = (param) => { return proxy.summarizeTable(param, [ "taxInclusiveUnitPrice", "taxInclusiveTotalPrice", "taxExclusiveTotalPrice", "invoiceNum", "invoiceAmount", "currentInvoiceAmount", "noInvoiceNum", "noInvoiceAmount", "currentInvoiceNum", ]); return proxy.summarizeTable(param, [ "taxInclusiveUnitPrice", "taxInclusiveTotalPrice", "taxExclusiveTotalPrice", "invoiceNum", "invoiceAmount", "currentInvoiceAmount", "noInvoiceNum", "noInvoiceAmount", "currentInvoiceNum", ]); }; // 打开弹框 const openForm = () => { // 判断是否多选 if (selectedRows.value.length != 1) { proxy.$modal.msgError("请选择一条合同"); return; } form.value = {}; productData.value = []; getSalesLedgerWithProducts({ id: selectedRows.value[0].id }).then((res) => { form.value = { ...res }; form.value.createTime = dayjs().format("YYYY-MM-DD"); form.value.issueDate = dayjs().format("YYYY-MM-DD"); form.value.createUer = userStore.nickName; productData.value = form.value.productData.map((item) => { return item; }); dialogFormVisible.value = true; console.log("productData.value ", productData.value); }); // 判断是否选择了合同 if (selectedRows.value.length === 0) { proxy.$modal.msgError("请至少选择一条合同"); return; } // 检查所有选择的合同是否具有相同的客户名称 const firstRow = selectedRows.value[0]; const isSameCustomer = selectedRows.value.every(row => row.customerName === firstRow.customerName ); if (!isSameCustomer) { proxy.$modal.msgError("请选择相同客户名称的合同"); return; } // 允许不同的销售合同号批量处理,无需检查重复 form.value = {}; productData.value = []; // 加载所有选中合同的产品数据 const promises = selectedRows.value.map(row => getSalesLedgerWithProducts({ id: row.id }) ); Promise.all(promises).then(results => { // 合并所有合同的产品数据,并为每个产品添加对应的合同信息 const allProductData = []; results.forEach((result, index) => { const contract = selectedRows.value[index]; const contractId = contract.id; if (result.productData) { result.productData.forEach(item => { allProductData.push({ ...item, id: contractId, // 明确设置合同ID salesContractNo: contract.salesContractNo, // 添加销售合同号 customerName: contract.customerName, // 添加客户名称 customerContractNo: contract.customerContractNo // 添加客户合同号 }); }); } }); // 设置表单数据(使用第一个合同的基本信息,销售合同号留空) form.value = { ...results[0] }; form.value.createTime = dayjs().format("YYYY-MM-DD"); form.value.issueDate = dayjs().format("YYYY-MM-DD"); form.value.createUer = userStore.nickName; form.value.selectedContractIds = selectedRows.value.map(row => row.id); // 存储所有选中的合同ID form.value.salesContractNo = ""; // 销售合同号留空,因为会在产品表格中分别显示 productData.value = allProductData; dialogFormVisible.value = true; console.log("productData.value ", productData.value); }); }; // 提交表单 const submitForm = () => { proxy.$refs["formRef"].validate((valid) => { if (valid) { form.value.productData = proxy.HaveJson(productData.value); invoiceRegistrationSave(form.value).then((res) => { proxy.$modal.msgSuccess("提交成功"); closeDia(); getList(); }); } }); proxy.$refs["formRef"].validate((valid) => { if (valid) { // 如果是批量操作,将所有合同的数据放在一个数组里,只调用一次接口 if (selectedRows.value.length > 1) { // 创建包含所有合同数据的数组 const batchData = selectedRows.value.map(contract => { // 筛选出属于当前合同的产品数据 const contractProductData = productData.value.filter(item => item.salesLedgerId === contract.id ); // 为每个销售合同号创建独立的对象 return { // 基础表单数据 issueDate: form.value.issueDate, createTime: form.value.createTime, createUer: form.value.createUer, invoiceNo: form.value.invoiceNo, // 合同实际信息 id: contract.id, // 使用id作为字段名,值为salesLedgerId salesContractNo: contract.salesContractNo, // 使用实际的销售合同号 customerName: contract.customerName, // 使用实际的客户名称 customerId: contract.customerId, // 添加客户ID customerContractNo: contract.customerContractNo, // 使用实际的客户合同号 projectName: contract.projectName, // 使用实际的项目名称 salesman: contract.salesman, // 使用实际的业务员 // 产品数据 productData: proxy.HaveJson(contractProductData), // 批量标识 isBatch: true }; }); // 只调用一次接口,传递包含所有合同数据的数组 invoiceRegistrationSave(batchData).then(() => { proxy.$modal.msgSuccess("批量新增成功"); closeDia(); getList(); }); } else { // 单个合同提交逻辑 - 也以数组形式传递 const singleContract = selectedRows.value[0]; const singleFormArray = [ { // 基础表单数据 issueDate: form.value.issueDate, createTime: form.value.createTime, createUer: form.value.createUer, invoiceNo: form.value.invoiceNo, // 合同实际信息 id: singleContract.id, // 使用id作为字段名,值为salesLedgerId salesContractNo: singleContract.salesContractNo, // 使用实际的销售合同号 customerName: singleContract.customerName, // 使用实际的客户名称 customerId: singleContract.customerId, // 添加客户ID customerContractNo: singleContract.customerContractNo, // 使用实际的客户合同号 projectName: singleContract.projectName, // 使用实际的项目名称 salesman: singleContract.salesman, // 使用实际的业务员 // 产品数据 productData: proxy.HaveJson(productData.value), // 批量标识 isBatch: false } ]; invoiceRegistrationSave(singleFormArray).then((res) => { proxy.$modal.msgSuccess("提交成功"); closeDia(); getList(); }); } } }); }; // 关闭弹框 const closeDia = () => { proxy.resetForm("formRef"); dialogFormVisible.value = false; proxy.resetForm("formRef"); dialogFormVisible.value = false; }; // 导出 const handleOut = () => { ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", { confirmButtonText: "确认", cancelButtonText: "取消", type: "warning", }) .then(() => { proxy.download("/invoiceRegistration/export", {}, "开票登记信息.xlsx"); }) .catch(() => { proxy.$modal.msg("已取消"); }); ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", { confirmButtonText: "确认", cancelButtonText: "取消", type: "warning", }) .then(() => { proxy.download("/invoiceRegistration/export", {}, "开票登记信息.xlsx"); }) .catch(() => { proxy.$modal.msg("已取消"); }); }; // 导出销售台账 const handleExport = () => { ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", { confirmButtonText: "确认", cancelButtonText: "取消", type: "warning", }) .then(() => { proxy.download("/sales/ledger/exportOne", { ...searchForm, ...page }, "开票登记.xlsx"); }) .catch(() => { proxy.$modal.msg("已取消"); }); ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", { confirmButtonText: "确认", cancelButtonText: "取消", type: "warning", }) .then(() => { proxy.download("/sales/ledger/exportOne", { ...searchForm, ...page }, "开票登记.xlsx"); }) .catch(() => { proxy.$modal.msg("已取消"); }); }; //本次开票失焦操作 const invoiceNumBlur = (row) => { if (!row.currentInvoiceNum) { row.currentInvoiceNum = 0; } if (row.currentInvoiceNum > row.tempNoInvoiceNum) { proxy.$modal.msgWarning("本次开票数不得大于未开票数"); row.currentInvoiceNum = 0; } // 计算本次开票金额 row.currentInvoiceAmount = ( row.currentInvoiceNum * row.taxInclusiveUnitPrice ).toFixed(2); // 计算未开票数 row.noInvoiceNum = (row.originalNoInvoiceNum - row.currentInvoiceNum).toFixed( 2 ); // 计算未开票金额 row.noInvoiceAmount = ( row.tempnoInvoiceAmount - row.currentInvoiceAmount ).toFixed(2); if (!row.currentInvoiceNum) { row.currentInvoiceNum = 0; } if (row.currentInvoiceNum > row.tempNoInvoiceNum) { proxy.$modal.msgWarning("本次开票数不得大于未开票数"); row.currentInvoiceNum = 0; } // 计算本次开票金额 row.currentInvoiceAmount = ( row.currentInvoiceNum * row.taxInclusiveUnitPrice ).toFixed(2); // 计算未开票数 row.noInvoiceNum = (row.originalNoInvoiceNum - row.currentInvoiceNum).toFixed( 2 ); // 计算未开票金额 row.noInvoiceAmount = ( row.tempnoInvoiceAmount - row.currentInvoiceAmount ).toFixed(2); }; // 本次开票金额失焦操作 const invoiceAmountBlur = (row) => { if (!row.currentInvoiceAmount) { row.currentInvoiceAmount = 0; } // 计算是否超过开票总金额 if (row.currentInvoiceAmount > row.tempnoInvoiceAmount) { proxy.$modal.msgWarning("本次开票金额不得大于未开票金额"); row.currentInvoiceAmount = 0; } // 计算本次开票数 row.currentInvoiceNum = ( row.currentInvoiceAmount / row.taxInclusiveUnitPrice ).toFixed(2); console.log("row.currentInvoiceNum ", row.currentInvoiceNum); console.log(" row.originalNoInvoiceNum ", row.originalNoInvoiceNum); // 计算未开票数 row.noInvoiceNum = (row.originalNoInvoiceNum - row.currentInvoiceNum).toFixed( 2 ); // 计算未开票金额 row.noInvoiceAmount = ( row.tempnoInvoiceAmount - row.currentInvoiceAmount ).toFixed(2); if (!row.currentInvoiceAmount) { row.currentInvoiceAmount = 0; } // 计算是否超过开票总金额 if (row.currentInvoiceAmount > row.tempnoInvoiceAmount) { proxy.$modal.msgWarning("本次开票金额不得大于未开票金额"); row.currentInvoiceAmount = 0; } // 计算本次开票数 row.currentInvoiceNum = ( row.currentInvoiceAmount / row.taxInclusiveUnitPrice ).toFixed(2); console.log("row.currentInvoiceNum ", row.currentInvoiceNum); console.log(" row.originalNoInvoiceNum ", row.originalNoInvoiceNum); // 计算未开票数 row.noInvoiceNum = (row.originalNoInvoiceNum - row.currentInvoiceNum).toFixed( 2 ); // 计算未开票金额 row.noInvoiceAmount = ( row.tempnoInvoiceAmount - row.currentInvoiceAmount ).toFixed(2); }; onMounted(() => { getList(); getList(); }); </script> <style scoped lang="scss"> .table_list { margin-top: unset; margin-top: unset; } .flex { display: flex; display: flex; } .justify-between { justify-content: space-between; justify-content: space-between; } ::v-deep(.el-checkbox__label) { font-weight: bold; font-weight: bold; } </style>