diff --git a/src/api/materials/company/index.ts b/src/api/materials/company/index.ts index da21b9f..1996df8 100644 --- a/src/api/materials/company/index.ts +++ b/src/api/materials/company/index.ts @@ -14,6 +14,18 @@ export const listCompany = (query?: CompanyQuery): AxiosPromise => method: 'get', params: query }); +}; /** + * 查询材料提供商 + * @param query + * @returns {*} + */ + +export const supplierInputGet = (query?) => { + return request({ + url: '/supplierInput/supplierInput/getList', + method: 'get', + params: query + }); }; /** diff --git a/src/views/biddingManagemen/biddingLimit/index.vue b/src/views/biddingManagemen/biddingLimit/index.vue index f54a5cd..98c5781 100644 --- a/src/views/biddingManagemen/biddingLimit/index.vue +++ b/src/views/biddingManagemen/biddingLimit/index.vue @@ -58,9 +58,10 @@ - - - + + + + - + @@ -92,48 +79,57 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - -
-

{{ item.label }}

- -
-
+ + + + + + + + + + + + + + + + + + + + +
+

{{ item.label }}

+ +
+ 注意:请上传pdf格式文件 +
+ @@ -104,39 +112,53 @@ import { updateMaterialsUseRecord } from '@/api/materials/materialsUseRecord'; import { MaterialsUseRecordVO, MaterialsUseRecordQuery, MaterialsUseRecordForm } from '@/api/materials/materialsUseRecord/types'; -import { getCurrentInstance, ComponentInternalInstance, onMounted, ref, reactive, toRefs, computed } from 'vue'; +import { getCurrentInstance, ComponentInternalInstance, onMounted, ref, reactive, toRefs, computed, watch, WatchStopHandle } from 'vue'; import { ElFormInstance, ElTable } from 'element-plus'; import useUserStore from '@/store/modules/user'; import { get } from 'lodash'; -// 类型定义补充(若项目中无全局DialogOption类型需添加) +// 类型定义补充 interface DialogOption { visible: boolean; title: string; } +// 子列表状态接口:为每个父行存储独立数据 +interface ChildRowState { + list: MaterialsUseRecordVO[]; + queryParams: MaterialsUseRecordQuery & { + pageNum: number; + pageSize: number; + inventoryId: number; + projectId?: number; + }; + loading: boolean; + total: number; +} + const { proxy } = getCurrentInstance() as ComponentInternalInstance; const userStore = useUserStore(); const currentProject = computed(() => userStore.selectedProject); // 核心数据响应式定义 -const materialsUseRecordList = ref([]); -const materialsUseInventoryList = ref([]); // 外层列表数据类型可根据实际接口返回调整 +const materialsUseInventoryList = ref([]); const buttonLoading = ref(false); const loading = ref(true); -const loadingChild = ref(true); const showSearch = ref(true); const ids = ref>([]); const single = ref(true); const multiple = ref(true); const total = ref(0); -const totalChild = ref(0); +const expandedRowKeys = ref([]); // 控制展开行的ID集合 + +// 子列表状态管理:使用对象存储不同父行的子数据,key为inventoryId +const childRowStates = ref>({}); // 组件Ref定义 const queryFormRef = ref(); const materialsUseRecordFormRef = ref(); -const outerTableRef = ref | undefined>(undefined); // 外层表格Ref(控制展开) -const currentExpandInventoryId = ref(undefined); // 存储当前展开行的inventoryId +const outerTableRef = ref | undefined>(undefined); +const currentOperateInventoryId = ref(undefined); // 当前操作的父行ID // 对话框与表单数据 const dialog = reactive({ @@ -160,72 +182,132 @@ const data = reactive({ pageSize: 10, projectId: currentProject.value?.id, outPut: 1, - usePart: undefined // 补充usePart字段(与表单prop对应) - } as MaterialsUseRecordQuery & { outPut?: number; usePart?: string }, - queryParamsChild: { - pageNum: 1, - pageSize: 10, - inventoryId: undefined, - usePart: undefined, - useNumber: undefined, - residueNumber: undefined - } as MaterialsUseRecordQuery, + materialsName: undefined, + usePart: undefined + } as MaterialsUseRecordQuery & { + outPut?: number; + materialsName?: string; + usePart?: string; + }, rules: { - id: [{ required: true, message: '主键ID不能为空', trigger: 'blur' }], projectId: [{ required: true, message: '项目ID不能为空', trigger: 'blur' }], inventoryId: [{ required: true, message: '库存ID不能为空', trigger: 'blur' }], usePart: [{ required: true, message: '使用部位不能为空', trigger: 'blur' }], - useNumber: [{ required: true, message: '使用数量不能为空', trigger: 'blur' }], - residueNumber: [{ required: true, message: '剩余量不能为空', trigger: 'blur' }] + useNumber: [{ required: true, message: '使用数量不能为空', trigger: 'blur' }] } }); -const { queryParams, form, rules, queryParamsChild } = toRefs(data); +const { form, rules } = toRefs(data); +const queryParams = ref({ ...data.queryParams }); -/** 查询材料使用登记列表(外层列表) */ +// ------------------------------ 子列表状态工具函数 ------------------------------ +/** 获取或初始化指定父行的子列表状态 */ +const getOrInitChildState = (inventoryId: number): ChildRowState => { + if (!childRowStates.value[inventoryId]) { + childRowStates.value[inventoryId] = { + list: [], + loading: false, + total: 0, + queryParams: { + pageNum: 1, + pageSize: 10, + inventoryId, + projectId: currentProject.value?.id + } + }; + } + return childRowStates.value[inventoryId]; +}; + +/** 获取指定父行的子列表数据 */ +const getChildData = (inventoryId: number): MaterialsUseRecordVO[] => { + return getOrInitChildState(inventoryId).list; +}; + +/** 获取指定父行的子列表加载状态 */ +const getChildLoading = (inventoryId: number): boolean => { + return getOrInitChildState(inventoryId).loading; +}; + +/** 获取指定父行的子列表总条数 */ +const getChildTotal = (inventoryId: number): number => { + return getOrInitChildState(inventoryId).total; +}; + +/** 获取指定父行的子分页参数 */ +const getChildQueryParams = (inventoryId: number) => { + return getOrInitChildState(inventoryId).queryParams; +}; + +// ------------------------------ 核心业务逻辑 ------------------------------ +/** 查询外层列表数据 */ const getList = async () => { loading.value = true; try { const res = await listMaterialsUseInventory(queryParams.value); materialsUseInventoryList.value = res.rows; total.value = res.total; + // 保持已展开行的状态 + if (expandedRowKeys.value.length > 0 && outerTableRef.value) { + expandedRowKeys.value.forEach((id) => { + const targetRow = materialsUseInventoryList.value.find((item) => item.id === id); + targetRow && outerTableRef.value!.toggleRowExpansion(targetRow, true); + }); + } } finally { loading.value = false; } }; -/** 处理外层表格展开/折叠:记录当前展开行的inventoryId */ -const handleExpandChange = (row: any) => { - currentExpandInventoryId.value = row.id; // 记录展开行ID - queryParamsChild.value.inventoryId = row.id; - getListChild(); +/** 处理外层表格展开/折叠 */ +const handleExpandChange = async (row: any, expandedRows: any[]) => { + const inventoryId = row.id; + // 更新展开行ID集合 + expandedRowKeys.value = expandedRows.map((item) => item.id); + + // 展开时加载子数据(仅首次加载) + const childState = getOrInitChildState(inventoryId); + if (expandedRows.some((item) => item.id === inventoryId) && childState.list.length === 0) { + await getListChild(inventoryId); + } }; -/** 查询材料子级登记列表(内层列表) */ -const getListChild = async () => { - loadingChild.value = true; +/** 查询指定父行的子列表数据 */ +const getListChild = async (inventoryId: number) => { + const childState = getOrInitChildState(inventoryId); + childState.loading = true; + try { - const res = await listMaterialsUseRecord(queryParamsChild.value); - materialsUseRecordList.value = res.rows; + const res = await listMaterialsUseRecord(childState.queryParams); + childState.list = res.rows; // 控制首行删除按钮显示 - if (res.rows.length > 0) { - materialsUseRecordList.value[0].ishow = true; + if (childState.list.length > 0) { + childState.list[0].ishow = true; } - totalChild.value = res.total; + childState.total = res.total; } finally { - loadingChild.value = false; + childState.loading = false; } }; +/** 处理子列表分页变化 */ +const handleChildPagination = async (inventoryId: number, page: number, limit: number) => { + const childState = getOrInitChildState(inventoryId); + childState.queryParams.pageNum = page; + childState.queryParams.pageSize = limit; + await getListChild(inventoryId); +}; + /** 取消按钮 */ const cancel = () => { reset(); dialog.visible = false; + currentOperateInventoryId.value = undefined; }; /** 表单重置 */ const reset = () => { - form.value = { ...initFormData }; + form.value = { ...initFormData, projectId: currentProject.value?.id }; materialsUseRecordFormRef.value?.resetFields(); }; @@ -238,10 +320,16 @@ const handleQuery = () => { /** 重置按钮操作 */ const resetQuery = () => { queryFormRef.value?.resetFields(); + queryParams.value = { + ...data.queryParams, + pageNum: 1, + pageSize: 10, + projectId: currentProject.value?.id + }; handleQuery(); }; -/** 多选框选中数据(当前模板未使用,保留原逻辑) */ +/** 多选框选中数据处理 */ const handleSelectionChange = (selection: MaterialsUseRecordVO[]) => { ids.value = selection.map((item) => item.id); single.value = selection.length !== 1; @@ -252,75 +340,85 @@ const handleSelectionChange = (selection: MaterialsUseRecordVO[]) => { const handleAdd = async (row: any) => { reset(); form.value.inventoryId = row.id; + currentOperateInventoryId.value = row.id; dialog.visible = true; dialog.title = '添加材料使用登记'; }; -/** 修改按钮操作(当前模板未使用,保留原逻辑) */ +/** 修改按钮操作 */ const handleUpdate = async (row?: MaterialsUseRecordVO) => { + if (!row && ids.value.length === 0) return; + reset(); const _id = row?.id || ids.value[0]; const res = await getMaterialsUseRecord(_id); Object.assign(form.value, res.data); + currentOperateInventoryId.value = form.value.inventoryId; dialog.visible = true; dialog.title = '修改材料使用登记'; }; -/** 提交按钮:核心优化逻辑(刷新外层列表+保留展开状态) */ +/** 提交表单操作 */ const submitForm = () => { materialsUseRecordFormRef.value?.validate(async (valid: boolean) => { - if (valid) { - buttonLoading.value = true; - try { - // 1. 执行添加/修改接口请求 - await addMaterialsUseRecord(form.value); - // 2. 刷新外层列表(确保外层数据同步,如剩余量) - await getList(); - // 3. 刷新当前展开行的子列表 - await getListChild(); - // 4. 恢复展开状态:根据记录的inventoryId重新展开行 - if (currentExpandInventoryId.value && outerTableRef.value) { - const targetRow = materialsUseInventoryList.value.find((item) => item.id === currentExpandInventoryId.value); - if (targetRow) { - outerTableRef.value.toggleRowExpansion(targetRow, true); - } - } - proxy?.$modal.msgSuccess('操作成功'); - dialog.visible = false; - } finally { - buttonLoading.value = false; - } + if (!valid || !currentOperateInventoryId.value) return; + + buttonLoading.value = true; + try { + // 执行添加或修改操作 + const apiFn = form.value.id ? updateMaterialsUseRecord : addMaterialsUseRecord; + await apiFn(form.value); + + // 刷新外层列表和当前操作行的子列表 + await getList(); + await getListChild(currentOperateInventoryId.value); + + proxy?.$modal.msgSuccess('操作成功'); + dialog.visible = false; + } finally { + buttonLoading.value = false; } }); }; -/** 删除按钮操作 */ -const handleDelete = async (row?: MaterialsUseRecordVO) => { - const _ids = row?.id || ids.value; +/** 删除操作 */ +const handleDelete = async (row: MaterialsUseRecordVO, inventoryId: number) => { try { - await proxy?.$modal.confirm(`是否确认删除材料使用登记编号为"${_ids}"的数据项?`); - await delMaterialsUseRecord(_ids); + await proxy?.$modal.confirm(`是否确认删除该记录?`); + await delMaterialsUseRecord(row.id); await getList(); - await getListChild(); - if (currentExpandInventoryId.value && outerTableRef.value) { - const targetRow = materialsUseInventoryList.value.find((item) => item.id === currentExpandInventoryId.value); - if (targetRow) { - outerTableRef.value.toggleRowExpansion(targetRow, true); - } - } + await getListChild(inventoryId); proxy?.$modal.msgSuccess('删除成功'); - await getListChild(); - } finally { - loading.value = false; + } catch (error) { + // 取消删除时不做处理 } }; -/** 导出按钮操作(保留原逻辑) */ +/** 导出操作 */ const handleExport = () => { proxy?.download('materials/materialsUseRecord/export', { ...queryParams.value }, `materialsUseRecord_${new Date().getTime()}.xlsx`); }; -/** 页面挂载时加载外层列表 */ +// 监听项目ID变化刷新数据 +const listeningProject: WatchStopHandle = watch( + () => currentProject.value?.id, + (newId) => { + queryParams.value.projectId = newId; + form.value.projectId = newId; + // 更新所有子列表的项目ID + Object.values(childRowStates.value).forEach((state) => { + state.queryParams.projectId = newId; + }); + getList(); + } +); + +// 页面卸载时清理监听 +onUnmounted(() => { + listeningProject(); +}); + +// 页面挂载时加载数据 onMounted(() => { getList(); }); diff --git a/src/views/materials/overallPlanMaterialSupply/index copy.vue b/src/views/materials/overallPlanMaterialSupply/index copy.vue new file mode 100644 index 0000000..ec294ab --- /dev/null +++ b/src/views/materials/overallPlanMaterialSupply/index copy.vue @@ -0,0 +1,619 @@ + + + + + diff --git a/src/views/materials/overallPlanMaterialSupply/index.vue b/src/views/materials/overallPlanMaterialSupply/index.vue index 52b060a..5cf03d9 100644 --- a/src/views/materials/overallPlanMaterialSupply/index.vue +++ b/src/views/materials/overallPlanMaterialSupply/index.vue @@ -1,6 +1,5 @@ + + diff --git a/src/views/tender/plan/index.vue b/src/views/tender/plan/index.vue index 5fc4b41..ba71c3a 100644 --- a/src/views/tender/plan/index.vue +++ b/src/views/tender/plan/index.vue @@ -195,7 +195,9 @@ (scope.row.useQuantity ? Number(scope.row.useQuantity) : 0) - (scope.row.selectNum ? Number(scope.row.selectNum) : 0) == 0 - ? '' + ? activeTab == 2 + ? 0 + : '' : (scope.row.quantity ? Number(scope.row.quantity) : 0) - (scope.row.selectNum ? Number(scope.row.selectNum) : 0) - (scope.row.useQuantity ? Number(scope.row.useQuantity) : 0) @@ -613,17 +615,21 @@ const changeBiddingTime = (value: any, row: any) => { }; //修改合同金额 const changeContractPrice = (value: any, row: any) => { - updateTenderPlan({ - ...row - }).then((res) => { - if (res.code == 200) { - ElMessage({ - message: '修改成功', - type: 'success' - }); - getList(); - } - }); + if (value <= Number(row.price)) { + updateTenderPlan({ + ...row + }).then((res) => { + if (res.code == 200) { + ElMessage({ + message: '修改成功', + type: 'success' + }); + getList(); + } + }); + } else { + ElMessage.error('合同金额不能大于限价金额'); + } }; //上传投标文件 diff --git a/src/views/tender/supplierInput/indexEdit.vue b/src/views/tender/supplierInput/indexEdit.vue index ac24516..4429c53 100644 --- a/src/views/tender/supplierInput/indexEdit.vue +++ b/src/views/tender/supplierInput/indexEdit.vue @@ -104,8 +104,9 @@ - + + +