| 
									
										
										
										
											2025-08-20 10:28:23 +08:00
										 |  |  | <template> | 
					
						
							|  |  |  |   <div class="p-2"> | 
					
						
							|  |  |  |     <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> | 
					
						
							|  |  |  |       <el-card shadow="always"> | 
					
						
							|  |  |  |         <el-form :model="queryForm" :inline="true"> | 
					
						
							| 
									
										
										
										
											2025-08-20 14:28:04 +08:00
										 |  |  |           <!-- <el-form-item label="版本号" prop="versions"> | 
					
						
							|  |  |  |             <el-select v-model="queryForm.versions" placeholder="选择版本号" @change="changeVersions"> | 
					
						
							|  |  |  |               <el-option v-for="item in options" :key="item" :label="item" :value="item" /> | 
					
						
							| 
									
										
										
										
											2025-08-20 10:28:23 +08:00
										 |  |  |             </el-select> | 
					
						
							| 
									
										
										
										
											2025-08-20 14:28:04 +08:00
										 |  |  |           </el-form-item> --> | 
					
						
							| 
									
										
										
										
											2025-08-20 10:28:23 +08:00
										 |  |  |           <el-form-item label="表名" prop="sheet"> | 
					
						
							|  |  |  |             <el-select v-model="queryForm.sheet" placeholder="选择表名" @change="changeSheet"> | 
					
						
							|  |  |  |               <el-option v-for="item in sheets" :key="item" :label="item" :value="item" /> | 
					
						
							|  |  |  |             </el-select> | 
					
						
							|  |  |  |           </el-form-item> | 
					
						
							|  |  |  |           <el-form-item> | 
					
						
							| 
									
										
										
										
											2025-08-20 14:28:04 +08:00
										 |  |  |             <el-button type="primary" @click="toggleExpandAll(true)">一键展开</el-button> | 
					
						
							| 
									
										
										
										
											2025-08-20 10:28:23 +08:00
										 |  |  |           </el-form-item> | 
					
						
							|  |  |  |           <el-form-item> | 
					
						
							| 
									
										
										
										
											2025-08-20 14:28:04 +08:00
										 |  |  |             <el-button type="primary" @click="toggleExpandAll(false)">一键收起</el-button> | 
					
						
							| 
									
										
										
										
											2025-08-20 10:28:23 +08:00
										 |  |  |           </el-form-item> | 
					
						
							| 
									
										
										
										
											2025-08-20 15:17:37 +08:00
										 |  |  |           <el-form-item> | 
					
						
							| 
									
										
										
										
											2025-08-20 21:02:24 +08:00
										 |  |  |             <el-upload | 
					
						
							|  |  |  |               ref="uploadRef" | 
					
						
							|  |  |  |               class="upload-demo" | 
					
						
							|  |  |  |               :http-request="importExcel" | 
					
						
							|  |  |  |               :show-file-list="false" | 
					
						
							|  |  |  |               v-hasPermi="['tender:billofquantitiesLimitList:importExcelFile']" | 
					
						
							|  |  |  |             > | 
					
						
							| 
									
										
										
										
											2025-08-20 15:17:37 +08:00
										 |  |  |               <template #trigger> | 
					
						
							|  |  |  |                 <el-button type="primary">导入excel</el-button> | 
					
						
							|  |  |  |               </template> | 
					
						
							|  |  |  |             </el-upload> | 
					
						
							|  |  |  |           </el-form-item> | 
					
						
							| 
									
										
										
										
											2025-08-20 21:02:24 +08:00
										 |  |  |           <el-form-item> | 
					
						
							|  |  |  |             <el-button type="primary" @click="handleExport()" v-hasPermi="['tender:billofquantitiesLimitList:export']">导出excel</el-button> | 
					
						
							|  |  |  |           </el-form-item> | 
					
						
							| 
									
										
										
										
											2025-08-20 10:28:23 +08:00
										 |  |  |         </el-form> | 
					
						
							|  |  |  |       </el-card> | 
					
						
							|  |  |  |     </transition> | 
					
						
							|  |  |  |     <el-card shadow="never" class="mb8"> | 
					
						
							| 
									
										
										
										
											2025-08-20 21:02:24 +08:00
										 |  |  |       <el-table ref="tableRef" v-loading="loading" :data="tableData" row-key="id" border lazy default-expand-all> | 
					
						
							| 
									
										
										
										
											2025-08-20 10:28:23 +08:00
										 |  |  |         <el-table-column prop="num" label="编号" /> | 
					
						
							|  |  |  |         <el-table-column prop="name" label="工程或费用名称" /> | 
					
						
							|  |  |  |         <el-table-column prop="unit" label="单位" /> | 
					
						
							|  |  |  |         <el-table-column prop="quantity" label="数量" /> | 
					
						
							| 
									
										
										
										
											2025-08-20 14:28:04 +08:00
										 |  |  |         <el-table-column prop="remark" label="单价" align="center"> | 
					
						
							|  |  |  |           <template #default="scope"> | 
					
						
							|  |  |  |             <el-input-number | 
					
						
							| 
									
										
										
										
											2025-08-20 15:15:46 +08:00
										 |  |  |               :model-value="scope.row.unitPrice" | 
					
						
							|  |  |  |               @change="(val) => (scope.row.unitPrice = val)" | 
					
						
							| 
									
										
										
										
											2025-08-20 14:28:04 +08:00
										 |  |  |               :precision="2" | 
					
						
							|  |  |  |               :step="0.1" | 
					
						
							|  |  |  |               :controls="false" | 
					
						
							|  |  |  |               v-if="scope.row.quantity && scope.row.quantity != 0" | 
					
						
							|  |  |  |             /> | 
					
						
							|  |  |  |           </template> | 
					
						
							|  |  |  |         </el-table-column> | 
					
						
							|  |  |  |         <el-table-column prop="price" label="总价" align="center"> | 
					
						
							|  |  |  |           <template #default="scope"> | 
					
						
							|  |  |  |             {{ scope.row.price }} | 
					
						
							|  |  |  |           </template> | 
					
						
							|  |  |  |         </el-table-column> | 
					
						
							|  |  |  |         <el-table-column prop="price" label="操作" align="center"> | 
					
						
							|  |  |  |           <template #default="scope"> | 
					
						
							| 
									
										
										
										
											2025-08-20 21:02:24 +08:00
										 |  |  |             <el-button | 
					
						
							|  |  |  |               type="primary" | 
					
						
							|  |  |  |               size="small" | 
					
						
							|  |  |  |               @click="handleSave(scope.row)" | 
					
						
							|  |  |  |               v-if="scope.row.quantity && scope.row.quantity != 0" | 
					
						
							|  |  |  |               v-hasPermi="['tender:billofquantitiesLimitList:edit']" | 
					
						
							| 
									
										
										
										
											2025-08-21 00:03:52 +08:00
										 |  |  |               >确定</el-button | 
					
						
							| 
									
										
										
										
											2025-08-20 14:28:04 +08:00
										 |  |  |             > | 
					
						
							|  |  |  |           </template> | 
					
						
							|  |  |  |         </el-table-column> | 
					
						
							| 
									
										
										
										
											2025-08-20 10:28:23 +08:00
										 |  |  |       </el-table> | 
					
						
							|  |  |  |     </el-card> | 
					
						
							|  |  |  |   </div> | 
					
						
							|  |  |  | </template> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <script setup lang="ts"> | 
					
						
							|  |  |  | import { useUserStoreHook } from '@/store/modules/user'; | 
					
						
							| 
									
										
										
										
											2025-08-20 21:02:24 +08:00
										 |  |  | import { listBillofquantitiesLimitList, obtainAllVersionNumbers, sheetList, updatePrice, importExcelFile } from '@/api/contract/index'; | 
					
						
							| 
									
										
										
										
											2025-08-20 10:28:23 +08:00
										 |  |  | const { proxy } = getCurrentInstance() as ComponentInternalInstance; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const userStore = useUserStoreHook(); | 
					
						
							|  |  |  | const currentProject = computed(() => userStore.selectedProject); | 
					
						
							|  |  |  | const queryForm = ref({ | 
					
						
							|  |  |  |   versions: '', | 
					
						
							|  |  |  |   sheet: '' | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | const loading = ref(false); | 
					
						
							|  |  |  | const options = ref<any[]>([]); | 
					
						
							|  |  |  | const sheets = ref<any[]>([]); | 
					
						
							|  |  |  | const tableData = ref<any[]>([]); | 
					
						
							| 
									
										
										
										
											2025-08-20 14:28:04 +08:00
										 |  |  | const isExpandAll = ref(false); | 
					
						
							| 
									
										
										
										
											2025-08-20 10:28:23 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | //获取版本号
 | 
					
						
							|  |  |  | const getVersionNums = async () => { | 
					
						
							|  |  |  |   try { | 
					
						
							|  |  |  |     const params = { | 
					
						
							|  |  |  |       projectId: currentProject.value?.id, | 
					
						
							|  |  |  |       pageSize: 1000, | 
					
						
							|  |  |  |       pageNum: 1 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const res = await obtainAllVersionNumbers(params); | 
					
						
							|  |  |  |     if (res.code == 200) { | 
					
						
							| 
									
										
										
										
											2025-08-20 14:28:04 +08:00
										 |  |  |       options.value = res.data; | 
					
						
							|  |  |  |       if (res.data.length > 0) { | 
					
						
							|  |  |  |         queryForm.value.versions = res.data[0]; | 
					
						
							| 
									
										
										
										
											2025-08-20 10:28:23 +08:00
										 |  |  |         getSheetName(); | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         queryForm.value.versions = ''; | 
					
						
							|  |  |  |         ElMessage({ | 
					
						
							|  |  |  |           message: '获取版本号失败', | 
					
						
							|  |  |  |           type: 'warning' | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } catch (error) { | 
					
						
							|  |  |  |     console.log(error); | 
					
						
							|  |  |  |     ElMessage({ | 
					
						
							|  |  |  |       message: '获取版本号失败', | 
					
						
							|  |  |  |       type: 'warning' | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2025-08-20 14:28:04 +08:00
										 |  |  | //选择版本号
 | 
					
						
							|  |  |  | const changeVersions = () => { | 
					
						
							|  |  |  |   getSheetName(); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-20 10:28:23 +08:00
										 |  |  | //选择表名
 | 
					
						
							|  |  |  | const changeSheet = () => { | 
					
						
							|  |  |  |   getTableData(); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //获取表名
 | 
					
						
							|  |  |  | const getSheetName = async () => { | 
					
						
							|  |  |  |   try { | 
					
						
							|  |  |  |     const params = { | 
					
						
							|  |  |  |       projectId: currentProject.value?.id | 
					
						
							|  |  |  |       // versions: queryForm.value.versions
 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     const res = await sheetList(params); | 
					
						
							|  |  |  |     if (res.code == 200) { | 
					
						
							|  |  |  |       sheets.value = res.data; | 
					
						
							|  |  |  |       if (res.data.length > 0) { | 
					
						
							|  |  |  |         queryForm.value.sheet = res.data[0]; | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         queryForm.value.sheet = ''; | 
					
						
							|  |  |  |         ElMessage({ | 
					
						
							|  |  |  |           message: '获取表名失败', | 
					
						
							|  |  |  |           type: 'warning' | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       getTableData(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } catch (error) { | 
					
						
							|  |  |  |     console.log(error); | 
					
						
							|  |  |  |     ElMessage({ | 
					
						
							|  |  |  |       message: '获取表名失败', | 
					
						
							|  |  |  |       type: 'warning' | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | //获取表格
 | 
					
						
							|  |  |  | const getTableData = async () => { | 
					
						
							| 
									
										
										
										
											2025-08-20 14:28:04 +08:00
										 |  |  |   try { | 
					
						
							|  |  |  |     loading.value = true; | 
					
						
							|  |  |  |     const params = { | 
					
						
							|  |  |  |       projectId: currentProject.value?.id, | 
					
						
							|  |  |  |       versions: queryForm.value.versions, | 
					
						
							|  |  |  |       sheet: queryForm.value.sheet | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     const res = await listBillofquantitiesLimitList(params); | 
					
						
							|  |  |  |     if (res.code == 200) { | 
					
						
							|  |  |  |       tableData.value = [res.data[0]]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } catch (error) { | 
					
						
							|  |  |  |     console.log(error); | 
					
						
							|  |  |  |     ElMessage({ | 
					
						
							|  |  |  |       message: '获取表格失败', | 
					
						
							|  |  |  |       type: 'error' | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     tableData.value = []; | 
					
						
							| 
									
										
										
										
											2025-08-20 21:02:24 +08:00
										 |  |  |     loading.value = false; | 
					
						
							| 
									
										
										
										
											2025-08-20 14:28:04 +08:00
										 |  |  |   } finally { | 
					
						
							|  |  |  |     loading.value = false; | 
					
						
							| 
									
										
										
										
											2025-08-20 10:28:23 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2025-08-20 14:28:04 +08:00
										 |  |  | //修改单价
 | 
					
						
							|  |  |  | const handleSave = (row: any) => { | 
					
						
							|  |  |  |   try { | 
					
						
							|  |  |  |     if (!row.unitPrice) { | 
					
						
							|  |  |  |       ElMessage({ | 
					
						
							|  |  |  |         message: '请输入单价', | 
					
						
							|  |  |  |         type: 'warning' | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     loading.value = true; | 
					
						
							|  |  |  |     updatePrice(row).then((res) => { | 
					
						
							|  |  |  |       if (res.code == 200) { | 
					
						
							|  |  |  |         ElMessage({ | 
					
						
							|  |  |  |           message: '修改成功', | 
					
						
							|  |  |  |           type: 'success' | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |         getTableData(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } catch (error) { | 
					
						
							|  |  |  |     ElMessage({ | 
					
						
							|  |  |  |       message: '修改失败', | 
					
						
							|  |  |  |       type: 'error' | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | const tableRef = ref<any>(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const toggleExpandAll = (isExpand: boolean) => { | 
					
						
							|  |  |  |   tableData.value.forEach((row) => { | 
					
						
							|  |  |  |     tableRef.value.toggleRowExpansion(row, isExpand); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   isExpandAll.value = isExpand; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2025-08-20 15:17:37 +08:00
										 |  |  | //导入
 | 
					
						
							|  |  |  | const importExcel = (options: any): any => { | 
					
						
							| 
									
										
										
										
											2025-08-20 21:02:24 +08:00
										 |  |  |   let formData = new FormData(); | 
					
						
							|  |  |  |   formData.append('file', options.file); | 
					
						
							|  |  |  |   loading.value = true; | 
					
						
							|  |  |  |   importExcelFile({ projectId: currentProject.value?.id }, formData) | 
					
						
							|  |  |  |     .then((res) => { | 
					
						
							|  |  |  |       const { code } = res; | 
					
						
							|  |  |  |       if (code == 200) { | 
					
						
							|  |  |  |         proxy.$modal.msgSuccess(res.msg || '导入成功'); | 
					
						
							|  |  |  |         getTableData(); | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         proxy.$modal.msgError(res.msg || '导入失败'); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |     .catch((err) => { | 
					
						
							|  |  |  |       proxy.$modal.msgError(err.msg || '导入失败'); | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |     .finally(() => { | 
					
						
							|  |  |  |       loading.value = false; | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2025-08-20 15:17:37 +08:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2025-08-20 10:28:23 +08:00
										 |  |  | //监听项目id刷新数据
 | 
					
						
							|  |  |  | const listeningProject = watch( | 
					
						
							|  |  |  |   () => currentProject.value?.id, | 
					
						
							|  |  |  |   (nid, oid) => { | 
					
						
							|  |  |  |     getVersionNums(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | ); | 
					
						
							| 
									
										
										
										
											2025-08-20 21:02:24 +08:00
										 |  |  | const handleExport = () => { | 
					
						
							|  |  |  |   proxy?.download( | 
					
						
							|  |  |  |     '/tender/billofquantitiesLimitList/export', | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       projectId: currentProject.value?.id, | 
					
						
							|  |  |  |       sheet: queryForm.value.sheet | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     `限价一览表${queryForm.value.sheet}.xlsx` | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2025-08-20 10:28:23 +08:00
										 |  |  | onUnmounted(() => { | 
					
						
							|  |  |  |   listeningProject(); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | onMounted(() => { | 
					
						
							|  |  |  |   // getVersionNums();
 | 
					
						
							|  |  |  |   getSheetName(); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | </script> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <style scoped></style> |