合并
This commit is contained in:
		
							
								
								
									
										318
									
								
								src/views/biddingManagemen/appointment/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										318
									
								
								src/views/biddingManagemen/appointment/index.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,318 @@ | ||||
| <template> | ||||
|   <div class="p-6 bg-gray-50 main"> | ||||
|     <div class="appWidth1 mx-auto mt-38 bg-white rounded-xl shadow-sm overflow-hidden transition-all duration-300 hover:shadow-md"> | ||||
|       <!-- 表单标题区域 --> | ||||
|       <div class="bg-gradient-to-r from-blue-500 to-blue-600 text-white p-6"> | ||||
|         <h2 class="text-2xl font-bold flex items-center"><i class="el-icon-user-circle mr-3"></i>人员配置</h2> | ||||
|         <p class="text-blue-100 mt-2 opacity-90">请配置投标管理人员信息</p> | ||||
|         <!-- ,带 <span class="text-red-300">*</span> 为必填项 --> | ||||
|         <el-button | ||||
|           @click="isDisabled = false" | ||||
|           class="px-8 py-2.5 transition-all duration-300 font-medium" | ||||
|           v-if="isDisabled" | ||||
|           v-hasPermi="['cailiaoshebei:purchaseUser:addOrUpdate']" | ||||
|         > | ||||
|           点击编辑 | ||||
|         </el-button> | ||||
|       </div> | ||||
|  | ||||
|       <!-- 表单内容区域 --> | ||||
|       <el-form ref="leaveFormRef" :model="form" :rules="rules" label-width="120px" class="p-6 pt30 space-y-6 h75" :disabled="isDisabled"> | ||||
|         <!-- 设计负责人 --> | ||||
|         <div class="fonts w60% ma"> | ||||
|           <el-form-item label="招投标专员" prop="userId" class="mb-4"> | ||||
|             <el-select | ||||
|               v-model="form.userId" | ||||
|               placeholder="请选择招投标专员" | ||||
|               class="w-full transition-all duration-300 border-gray-300 focus:border-blue-400 focus:ring-1 focus:ring-blue-400" | ||||
|             > | ||||
|               <el-option v-for="item in userList" :key="item.userId" :label="item.userName" :value="item.userId" /> | ||||
|             </el-select> | ||||
|           </el-form-item> | ||||
|         </div> | ||||
|  | ||||
|         <!-- 提交按钮区域 --> | ||||
|         <div class="flex justify-center space-x-6 mt-8 pt-6 border-t border-gray-100" v-if="!isDisabled"> | ||||
|           <el-button | ||||
|             type="primary" | ||||
|             @click="submitForm" | ||||
|             icon="Check" | ||||
|             class="px-8 py-2.5 transition-all duration-300 transform hover:scale-105 bg-blue-500 hover:bg-blue-600 text-white font-medium" | ||||
|             v-hasPermi="['cailiaoshebei:purchaseUser:addOrUpdate']" | ||||
|           > | ||||
|             确认提交 | ||||
|           </el-button> | ||||
|           <el-button @click="resetForm" icon="Refresh" class="px-8 py-2.5 transition-all duration-300 border-gray-300 hover:bg-gray-100 font-medium"> | ||||
|             重置 | ||||
|           </el-button> | ||||
|         </div> | ||||
|       </el-form> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script setup name="PersonnelForm" lang="ts"> | ||||
| import { ref, reactive, computed, onMounted, toRefs } from 'vue'; | ||||
| import { getCurrentInstance } from 'vue'; | ||||
| import type { ComponentInternalInstance } from 'vue'; | ||||
| import { useUserStoreHook } from '@/store/modules/user'; | ||||
| import { ElMessage, ElLoading } from 'element-plus'; | ||||
| import { biddingGetUser, AddbiddingUser, biddingUserList } from '@/api/bidding/appointment'; | ||||
|  | ||||
| // 获取当前实例 | ||||
| const { proxy } = getCurrentInstance() as ComponentInternalInstance; | ||||
| // 获取用户 store | ||||
| const userStore = useUserStoreHook(); | ||||
| // 从 store 中获取当前选中的项目 | ||||
| const currentProject = computed(() => userStore.selectedProject); | ||||
| // 专业字典数据 | ||||
| const { des_user_major } = toRefs<any>(proxy?.useDict('des_user_major')); | ||||
| const isDisabled = ref(false); | ||||
|  | ||||
| // 表单数据 | ||||
| const form = reactive({ | ||||
|   id: null, | ||||
|   projectId: currentProject.value?.id, | ||||
|   userId: null // 设计负责人 | ||||
| }); | ||||
|  | ||||
| // 表单验证规则 | ||||
| const rules = reactive({ | ||||
|   userId: [{ required: true, message: '请选择招投标专员', trigger: 'change' }] | ||||
| }); | ||||
|  | ||||
| // 用户列表 | ||||
| const userList = ref([]); | ||||
|  | ||||
| // 表单引用 | ||||
| const leaveFormRef = ref(); | ||||
|  | ||||
| /** 查询当前部门的所有用户 */ | ||||
| const getDeptAllUser = async (deptId: any) => { | ||||
|   const res = await biddingGetUser({}); | ||||
|   userList.value = res.data; | ||||
| }; | ||||
|  | ||||
| /** 查询当前表单数据并回显 */ | ||||
| const getBiddingUser = async () => { | ||||
|   if (!currentProject.value?.id) return; | ||||
|   const loading = ElLoading.service({ | ||||
|     lock: true, | ||||
|     text: '加载配置数据中...', | ||||
|     background: 'rgba(255, 255, 255, 0.7)' | ||||
|   }); | ||||
|   try { | ||||
|     const res = await biddingUserList(currentProject.value?.id); | ||||
|     if (res.code == 200) { | ||||
|       if (!res.data) { | ||||
|         resetForm(); | ||||
|         form.id = null; | ||||
|         isDisabled.value = false; | ||||
|         return; | ||||
|       } | ||||
|       Object.assign(form, res.data); | ||||
|       isDisabled.value = true; | ||||
|     } | ||||
|   } catch (error) { | ||||
|     ElMessage.error('获取配置数据失败'); | ||||
|     // 添加默认空项 | ||||
|   } finally { | ||||
|     loading.close(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| /** 提交表单 */ | ||||
| const submitForm = async () => { | ||||
|   if (!leaveFormRef.value) return; | ||||
|   try { | ||||
|     // 表单验证 | ||||
|     await leaveFormRef.value.validate(); | ||||
|     let userName = userList.value.find((item) => item.userId === form.userId)?.userName; | ||||
|     const data = { | ||||
|       projectId: currentProject.value?.id, | ||||
|       userId: form.userId, | ||||
|       userName, | ||||
|       id: form.id | ||||
|     }; | ||||
|     // 提交到后端 | ||||
|     const res = await AddbiddingUser(data); | ||||
|     if (res.code === 200) { | ||||
|       ElMessage.success('提交成功'); | ||||
|       isDisabled.value = true; | ||||
|     } else { | ||||
|       ElMessage.error(res.msg || '提交失败'); | ||||
|     } | ||||
|   } catch (error) { | ||||
|     ElMessage.error('请完善表单信息后再提交'); | ||||
|   } finally { | ||||
|     // 关闭加载状态 | ||||
|     ElLoading.service().close(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| /** 重置表单 */ | ||||
| const resetForm = () => { | ||||
|   if (leaveFormRef.value) { | ||||
|     leaveFormRef.value.resetFields(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| // 页面挂载时初始化数据 | ||||
| onMounted(() => { | ||||
|   // 先获取用户列表,再加载表单数据 | ||||
|   getDeptAllUser(userStore.deptId).then(() => { | ||||
|     getBiddingUser(); | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| //监听项目id刷新数据 | ||||
| const listeningProject = watch( | ||||
|   () => currentProject.value?.id, | ||||
|   (nid, oid) => { | ||||
|     getDeptAllUser(userStore.deptId).then(() => { | ||||
|       getBiddingUser(); | ||||
|     }); | ||||
|   } | ||||
| ); | ||||
|  | ||||
| onUnmounted(() => { | ||||
|   listeningProject(); | ||||
| }); | ||||
| </script> | ||||
|  | ||||
| <style lang="scss"> | ||||
| .main { | ||||
|   height: calc(100vh - 90px); | ||||
| } | ||||
| .appWidth1 { | ||||
|   width: 50vw; | ||||
|   max-width: 1200px; | ||||
|   .el-select__wrapper { | ||||
|     width: 16vw !important; | ||||
|   } | ||||
|   .el-button--small { | ||||
|     margin-bottom: 10px; | ||||
|   } | ||||
|   .fonts { | ||||
|     .el-form-item--default .el-form-item__label { | ||||
|       font-size: 18px !important; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| // 自定义动画 | ||||
| @keyframes fadeIn { | ||||
|   from { | ||||
|     opacity: 0; | ||||
|     transform: translateY(10px); | ||||
|   } | ||||
|   to { | ||||
|     opacity: 1; | ||||
|     transform: translateY(0); | ||||
|   } | ||||
| } | ||||
|  | ||||
| .animate-fadeIn { | ||||
|   animation: fadeIn 0.3s ease-out forwards; | ||||
| } | ||||
|  | ||||
| // 表单样式优化 | ||||
| ::v-deep .el-form { | ||||
|   --el-form-item-margin-bottom: 0; | ||||
| } | ||||
|  | ||||
| ::v-deep .el-form-item { | ||||
|   margin-bottom: 0; | ||||
|  | ||||
|   &__label { | ||||
|     font-weight: 500; | ||||
|     color: #4e5969; | ||||
|     padding: 0 0 8px 0; | ||||
|   } | ||||
|  | ||||
|   &__content { | ||||
|     padding: 0; | ||||
|   } | ||||
| } | ||||
|  | ||||
| ::v-deep .el-select { | ||||
|   width: 100%; | ||||
|  | ||||
|   .el-input__inner { | ||||
|     border-radius: 6px; | ||||
|     transition: all 0.3s ease; | ||||
|   } | ||||
|  | ||||
|   &:hover .el-input__inner { | ||||
|     border-color: #66b1ff; | ||||
|   } | ||||
|  | ||||
|   &.el-select-focus .el-input__inner { | ||||
|     border-color: #409eff; | ||||
|     box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2); | ||||
|   } | ||||
| } | ||||
|  | ||||
| ::v-deep .el-button { | ||||
|   border-radius: 6px; | ||||
|   padding: 8px 16px; | ||||
|  | ||||
|   &--primary { | ||||
|     background-color: #409eff; | ||||
|     border-color: #409eff; | ||||
|  | ||||
|     &:hover { | ||||
|       background-color: #66b1ff; | ||||
|       border-color: #66b1ff; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   &--danger { | ||||
|     background-color: #f56c6c; | ||||
|     border-color: #f56c6c; | ||||
|  | ||||
|     &:hover { | ||||
|       background-color: #f78989; | ||||
|       border-color: #f78989; | ||||
|     } | ||||
|  | ||||
|     &:disabled { | ||||
|       background-color: #ffcccc; | ||||
|       border-color: #ffbbbb; | ||||
|       cursor: not-allowed; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| // 响应式网格布局 | ||||
| .grid { | ||||
|   display: grid; | ||||
| } | ||||
|  | ||||
| .grid-cols-1 { | ||||
|   grid-template-columns: repeat(1, minmax(0, 1fr)); | ||||
| } | ||||
|  | ||||
| .md\:grid-cols-2 { | ||||
|   grid-template-columns: repeat(2, minmax(0, 1fr)); | ||||
| } | ||||
|  | ||||
| .gap-4 { | ||||
|   gap: 1rem; | ||||
| } | ||||
|  | ||||
| // 适配小屏幕 | ||||
| @media (max-width: 768px) { | ||||
|   .appWidth1 { | ||||
|     width: 95vw; | ||||
|   } | ||||
|  | ||||
|   ::v-deep .el-form { | ||||
|     padding: 4px; | ||||
|   } | ||||
|  | ||||
|   ::v-deep .el-form-item__label { | ||||
|     width: 100px; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										342
									
								
								src/views/biddingManagemen/listOfWinningBids/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										342
									
								
								src/views/biddingManagemen/listOfWinningBids/index.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,342 @@ | ||||
| <template> | ||||
|   <div class="p-2"> | ||||
|     <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> | ||||
|       <div v-show="showSearch" class="mb-[10px]"> | ||||
|         <el-card shadow="hover"> | ||||
|           <el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="110px"> | ||||
|             <el-form-item label="项目名称" prop="projectName"> | ||||
|               <el-input v-model="queryParams.projectName" placeholder="请输入项目名称" clearable @keyup.enter="handleQuery" /> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="建设单位" prop="construction"> | ||||
|               <el-input v-model="queryParams.construction" placeholder="请输入建设单位" clearable @keyup.enter="handleQuery" /> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="立项申请人" prop="projectApplicant"> | ||||
|               <el-input v-model="queryParams.projectApplicant" placeholder="请输入立项申请人" clearable @keyup.enter="handleQuery" /> | ||||
|             </el-form-item> | ||||
|             <el-form-item> | ||||
|               <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button> | ||||
|               <el-button icon="Refresh" @click="resetQuery">重置</el-button> | ||||
|             </el-form-item> | ||||
|           </el-form> | ||||
|         </el-card> | ||||
|       </div> | ||||
|     </transition> | ||||
|     <el-card shadow="never"> | ||||
|       <template #header> | ||||
|         <el-row :gutter="10" class="mb8"> | ||||
|           <el-col :span="1.5"> | ||||
|             <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['bidding:listOfWinningBids:add']">新增</el-button> | ||||
|           </el-col> | ||||
|           <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> | ||||
|         </el-row> | ||||
|       </template> | ||||
|  | ||||
|       <el-table v-loading="loading" :data="listOfWinningBidsList" @selection-change="handleSelectionChange"> | ||||
|         <!-- <el-table-column type="selection" width="55" align="center" /> --> | ||||
|         <el-table-column label="序号" align="center" type="index" width="60" /> | ||||
|         <el-table-column label="项目状态" align="center" prop="projectStatus" /> | ||||
|         <el-table-column label="项目名称" align="center" prop="projectName" /> | ||||
|         <el-table-column label="中标价" align="center" prop="winningBidOriginal" /> | ||||
|         <el-table-column label="汇率" align="center" prop="exchangeRate" /> | ||||
|         <el-table-column label="币种" align="center" prop="currency" /> | ||||
|         <el-table-column label="所属主体" align="center" prop="subject" /> | ||||
|         <el-table-column label="中标价" align="center" prop="winningBid" /> | ||||
|         <el-table-column label="中标日期" align="center" prop="bidWinningDate" width="180"> | ||||
|           <template #default="scope"> | ||||
|             <span>{{ parseTime(scope.row.bidWinningDate, '{y}-{m}-{d}') }}</span> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|         <el-table-column label="投标保证金" align="center" prop="bidDeposit" width="120" /> | ||||
|         <el-table-column label="是否退还" align="center" prop="whetherSendBack" /> | ||||
|         <el-table-column label="建设单位" align="center" prop="construction" /> | ||||
|         <el-table-column label="总造价" align="center" prop="totalCost" /> | ||||
|         <el-table-column label="立项申请人" align="center" prop="projectApplicant" width="120" /> | ||||
|         <el-table-column label="立项部门" align="center" prop="projectApplicantDept" /> | ||||
|         <el-table-column label="立项申请日期" align="center" prop="projectApplicantTime" width="160"> | ||||
|           <template #default="scope"> | ||||
|             <span>{{ parseTime(scope.row.projectApplicantTime, '{y}-{m}-{d}') }}</span> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|         <el-table-column label="流程状态" align="center" prop="processStatus" /> | ||||
|         <el-table-column label="项目编号" align="center" prop="projectNumbering" /> | ||||
|         <el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="200"> | ||||
|           <template #default="scope"> | ||||
|             <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['bidding:listOfWinningBids:edit']" | ||||
|               >修改</el-button | ||||
|             > | ||||
|             <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['bidding:listOfWinningBids:remove']"> | ||||
|               删除</el-button | ||||
|             > | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|       </el-table> | ||||
|       <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" /> | ||||
|     </el-card> | ||||
|     <!-- 添加或修改中标项目一览对话框 --> | ||||
|     <el-dialog :title="dialog.title" v-model="dialog.visible" width="800px" append-to-body> | ||||
|       <el-form ref="listOfWinningBidsFormRef" :model="form" :rules="rules" label-width="110px"> | ||||
|         <el-row :gutter="24"> | ||||
|           <el-col :span="12"> | ||||
|             <el-form-item label="项目名称" prop="projectName"> <el-input v-model="form.projectName" placeholder="请输入项目名称" /> </el-form-item | ||||
|           ></el-col> | ||||
|           <el-col :span="12"> | ||||
|             <el-form-item label="中标价" prop="winningBidOriginal"> | ||||
|               <el-input v-model="form.winningBidOriginal" placeholder="请输入中标价" /> </el-form-item | ||||
|           ></el-col> | ||||
|           <el-col :span="12"> | ||||
|             <el-form-item label="汇率" prop="exchangeRate"> <el-input v-model="form.exchangeRate" placeholder="请输入汇率" /> </el-form-item | ||||
|           ></el-col> | ||||
|           <el-col :span="12"> | ||||
|             <el-form-item label="币种" prop="currency"> <el-input v-model="form.currency" placeholder="请输入币种" /> </el-form-item | ||||
|           ></el-col> | ||||
|           <el-col :span="12"> | ||||
|             <el-form-item label="所属主体" prop="subject"> <el-input v-model="form.subject" placeholder="请输入所属主体" /> </el-form-item | ||||
|           ></el-col> | ||||
|           <el-col :span="12" | ||||
|             ><el-form-item label="中标价" prop="winningBid"> <el-input v-model="form.winningBid" placeholder="请输入中标价" /> </el-form-item | ||||
|           ></el-col> | ||||
|           <el-col :span="12" | ||||
|             ><el-form-item label="中标日期" prop="bidWinningDate"> | ||||
|               <el-date-picker | ||||
|                 clearable | ||||
|                 v-model="form.bidWinningDate" | ||||
|                 type="date" | ||||
|                 format="YYYY-MM-DD" | ||||
|                 value-format="YYYY-MM-DD" | ||||
|                 placeholder="请选择中标日期" | ||||
|               > | ||||
|               </el-date-picker> </el-form-item | ||||
|           ></el-col> | ||||
|           <el-col :span="12"> | ||||
|             <el-form-item label="投标保证金" prop="bidDeposit"> <el-input v-model="form.bidDeposit" placeholder="请输入投标保证金" /> </el-form-item | ||||
|           ></el-col> | ||||
|           <el-col :span="12"> | ||||
|             <el-form-item label="是否退还" prop="whetherSendBack"> | ||||
|               <el-input v-model="form.whetherSendBack" placeholder="请输入是否退还" /> </el-form-item | ||||
|           ></el-col> | ||||
|           <el-col :span="12" | ||||
|             ><el-form-item label="建设单位" prop="construction"> <el-input v-model="form.construction" placeholder="请输入建设单位" /> </el-form-item | ||||
|           ></el-col> | ||||
|           <el-col :span="12"> | ||||
|             <el-form-item label="总造价" prop="totalCost"> <el-input v-model="form.totalCost" placeholder="请输入总造价" /> </el-form-item | ||||
|           ></el-col> | ||||
|           <el-col :span="12"> | ||||
|             <el-form-item label="立项申请人" prop="projectApplicant"> | ||||
|               <el-input v-model="form.projectApplicant" placeholder="请输入立项申请人" /> </el-form-item | ||||
|           ></el-col> | ||||
|           <el-col :span="12" | ||||
|             ><el-form-item label="立项部门" prop="projectApplicantDept"> | ||||
|               <el-input v-model="form.projectApplicantDept" placeholder="请输入立项部门" /> </el-form-item | ||||
|           ></el-col> | ||||
|           <el-col :span="12" | ||||
|             ><el-form-item label="立项申请日期" prop="projectApplicantTime"> | ||||
|               <el-date-picker | ||||
|                 clearable | ||||
|                 v-model="form.projectApplicantTime" | ||||
|                 type="date" | ||||
|                 format="YYYY-MM-DD" | ||||
|                 value-format="YYYY-MM-DD" | ||||
|                 placeholder="请选择立项申请日期" | ||||
|               > | ||||
|               </el-date-picker> </el-form-item | ||||
|           ></el-col> | ||||
|           <el-col :span="12" | ||||
|             ><el-form-item label="项目编号" prop="projectNumbering"> | ||||
|               <el-input v-model="form.projectNumbering" placeholder="请输入项目编号" /> </el-form-item | ||||
|           ></el-col> | ||||
|         </el-row> | ||||
|       </el-form> | ||||
|       <template #footer> | ||||
|         <div class="dialog-footer"> | ||||
|           <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button> | ||||
|           <el-button @click="cancel">取 消</el-button> | ||||
|         </div> | ||||
|       </template> | ||||
|     </el-dialog> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script setup name="ListOfWinningBids" lang="ts"> | ||||
| import { | ||||
|   listListOfWinningBids, | ||||
|   getListOfWinningBids, | ||||
|   delListOfWinningBids, | ||||
|   addListOfWinningBids, | ||||
|   updateListOfWinningBids | ||||
| } from '@/api/bidding/listOfWinningBids'; | ||||
| import { ListOfWinningBidsVO, ListOfWinningBidsQuery, ListOfWinningBidsForm } from '@/api/bidding/listOfWinningBids/types'; | ||||
| import { useUserStoreHook } from '@/store/modules/user'; | ||||
| const { proxy } = getCurrentInstance() as ComponentInternalInstance; | ||||
| // 获取用户 store | ||||
| const userStore = useUserStoreHook(); | ||||
| // 从 store 中获取当前选中的项目 | ||||
| const currentProject = computed(() => userStore.selectedProject); | ||||
| const listOfWinningBidsList = ref<ListOfWinningBidsVO[]>([]); | ||||
| const buttonLoading = ref(false); | ||||
| const loading = ref(true); | ||||
| const showSearch = ref(true); | ||||
| const ids = ref<Array<string | number>>([]); | ||||
| const single = ref(true); | ||||
| const multiple = ref(true); | ||||
| const total = ref(0); | ||||
|  | ||||
| const queryFormRef = ref<ElFormInstance>(); | ||||
| const listOfWinningBidsFormRef = ref<ElFormInstance>(); | ||||
|  | ||||
| const dialog = reactive<DialogOption>({ | ||||
|   visible: false, | ||||
|   title: '' | ||||
| }); | ||||
|  | ||||
| const initFormData: ListOfWinningBidsForm = { | ||||
|   id: undefined, | ||||
|   projectId: currentProject.value?.id, | ||||
|   projectStatus: undefined, | ||||
|   projectName: undefined, | ||||
|   winningBidOriginal: undefined, | ||||
|   exchangeRate: undefined, | ||||
|   currency: undefined, | ||||
|   subject: undefined, | ||||
|   winningBid: undefined, | ||||
|   bidWinningDate: undefined, | ||||
|   bidDeposit: undefined, | ||||
|   whetherSendBack: undefined, | ||||
|   construction: undefined, | ||||
|   totalCost: undefined, | ||||
|   projectApplicant: undefined, | ||||
|   projectApplicantDept: undefined, | ||||
|   projectApplicantTime: undefined, | ||||
|   processStatus: undefined, | ||||
|   projectNumbering: undefined | ||||
| }; | ||||
| const data = reactive<PageData<ListOfWinningBidsForm, ListOfWinningBidsQuery>>({ | ||||
|   form: { ...initFormData }, | ||||
|   queryParams: { | ||||
|     pageNum: 1, | ||||
|     pageSize: 10, | ||||
|     projectId: currentProject.value?.id, | ||||
|     projectStatus: undefined, | ||||
|     projectName: undefined, | ||||
|     winningBidOriginal: undefined, | ||||
|     exchangeRate: undefined, | ||||
|     currency: undefined, | ||||
|     subject: undefined, | ||||
|     winningBid: undefined, | ||||
|     bidWinningDate: undefined, | ||||
|     bidDeposit: undefined, | ||||
|     whetherSendBack: undefined, | ||||
|     construction: undefined, | ||||
|     totalCost: undefined, | ||||
|     projectApplicant: undefined, | ||||
|     projectApplicantDept: undefined, | ||||
|     projectApplicantTime: undefined, | ||||
|     processStatus: undefined, | ||||
|     projectNumbering: undefined, | ||||
|     params: {} | ||||
|   }, | ||||
|   rules: { | ||||
|     id: [{ required: true, message: '不能为空', trigger: 'blur' }], | ||||
|     projectId: [{ required: true, message: '项目id不能为空', trigger: 'blur' }] | ||||
|   } | ||||
| }); | ||||
|  | ||||
| const { queryParams, form, rules } = toRefs(data); | ||||
|  | ||||
| /** 查询中标项目一览列表 */ | ||||
| const getList = async () => { | ||||
|   loading.value = true; | ||||
|   const res = await listListOfWinningBids(queryParams.value); | ||||
|   listOfWinningBidsList.value = res.rows; | ||||
|   total.value = res.total; | ||||
|   loading.value = false; | ||||
| }; | ||||
|  | ||||
| /** 取消按钮 */ | ||||
| const cancel = () => { | ||||
|   reset(); | ||||
|   dialog.visible = false; | ||||
| }; | ||||
|  | ||||
| /** 表单重置 */ | ||||
| const reset = () => { | ||||
|   form.value = { ...initFormData }; | ||||
|   listOfWinningBidsFormRef.value?.resetFields(); | ||||
| }; | ||||
|  | ||||
| /** 搜索按钮操作 */ | ||||
| const handleQuery = () => { | ||||
|   queryParams.value.pageNum = 1; | ||||
|   getList(); | ||||
| }; | ||||
|  | ||||
| /** 重置按钮操作 */ | ||||
| const resetQuery = () => { | ||||
|   queryFormRef.value?.resetFields(); | ||||
|   handleQuery(); | ||||
| }; | ||||
|  | ||||
| /** 多选框选中数据 */ | ||||
| const handleSelectionChange = (selection: ListOfWinningBidsVO[]) => { | ||||
|   ids.value = selection.map((item) => item.id); | ||||
|   single.value = selection.length != 1; | ||||
|   multiple.value = !selection.length; | ||||
| }; | ||||
|  | ||||
| /** 新增按钮操作 */ | ||||
| const handleAdd = () => { | ||||
|   reset(); | ||||
|   dialog.visible = true; | ||||
|   dialog.title = '添加中标项目一览'; | ||||
| }; | ||||
|  | ||||
| /** 修改按钮操作 */ | ||||
| const handleUpdate = async (row?: ListOfWinningBidsVO) => { | ||||
|   reset(); | ||||
|   const _id = row?.id || ids.value[0]; | ||||
|   const res = await getListOfWinningBids(_id); | ||||
|   Object.assign(form.value, res.data); | ||||
|   dialog.visible = true; | ||||
|   dialog.title = '修改中标项目一览'; | ||||
| }; | ||||
|  | ||||
| /** 提交按钮 */ | ||||
| const submitForm = () => { | ||||
|   listOfWinningBidsFormRef.value?.validate(async (valid: boolean) => { | ||||
|     if (valid) { | ||||
|       buttonLoading.value = true; | ||||
|       if (form.value.id) { | ||||
|         await updateListOfWinningBids(form.value).finally(() => (buttonLoading.value = false)); | ||||
|       } else { | ||||
|         await addListOfWinningBids(form.value).finally(() => (buttonLoading.value = false)); | ||||
|       } | ||||
|       proxy?.$modal.msgSuccess('操作成功'); | ||||
|       dialog.visible = false; | ||||
|       await getList(); | ||||
|     } | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| /** 删除按钮操作 */ | ||||
| const handleDelete = async (row?: ListOfWinningBidsVO) => { | ||||
|   const _ids = row?.id || ids.value; | ||||
|   await proxy?.$modal.confirm('是否确认删除中标项目一览编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false)); | ||||
|   await delListOfWinningBids(_ids); | ||||
|   proxy?.$modal.msgSuccess('删除成功'); | ||||
|   await getList(); | ||||
| }; | ||||
|  | ||||
| /** 导出按钮操作 */ | ||||
| const handleExport = () => { | ||||
|   proxy?.download( | ||||
|     'bidding/listOfWinningBids/export', | ||||
|     { | ||||
|       ...queryParams.value | ||||
|     }, | ||||
|     `listOfWinningBids_${new Date().getTime()}.xlsx` | ||||
|   ); | ||||
| }; | ||||
|  | ||||
| onMounted(() => { | ||||
|   getList(); | ||||
| }); | ||||
| </script> | ||||
							
								
								
									
										441
									
								
								src/views/contract/division/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										441
									
								
								src/views/contract/division/index.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,441 @@ | ||||
| <template> | ||||
|   <div class="p-2"> | ||||
|     <el-tabs type="border-card" @tab-change="handleTabChange" v-model="activeTab"> | ||||
|       <el-tab-pane v-for="(item, index) in tabList" :key="item.index" :label="item.label" :name="item.value"> | ||||
|         <el-card shadow="always"> | ||||
|           <el-form :model="queryForm" :inline="true" ref="queryFormRef"> | ||||
|             <el-form-item label="名称" prop="versions"> | ||||
|               <el-input v-model="queryForm.name" placeholder="请输入名称" clearable @keyup.enter="handleQuery" /> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="内容" prop="sheet"> | ||||
|               <el-input v-model="queryForm.content" placeholder="请输入内容" clearable @keyup.enter="handleQuery" /> | ||||
|             </el-form-item> | ||||
|             <el-form-item> | ||||
|               <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button> | ||||
|               <el-button icon="Refresh" @click="resetQuery">重置</el-button> | ||||
|               <el-button type="primary" plain :icon="Plus" @click="openDialog" v-hasPermi="['tender:segmentedIndicatorPlanning:add']">新增</el-button> | ||||
|             </el-form-item> | ||||
|           </el-form> | ||||
|         </el-card> | ||||
|         <el-table :data="tableData" row-key="id" border v-loading="loading"> | ||||
|           <el-table-column prop="id" label="编号" /> | ||||
|           <el-table-column prop="name" label="名称" /> | ||||
|           <el-table-column prop="content" label="内容" /> | ||||
|           <el-table-column prop="plannedBiddingTime" label="计划招标时间" align="center"> | ||||
|             <template #default="scope"> | ||||
|               <el-date-picker v-model="scope.row.plannedBiddingTime" type="date" value-format="YYYY-MM-DD" placeholder="选择时间" /> | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|           <el-table-column prop="price" label="操作" align="center"> | ||||
|             <template #default="scope"> | ||||
|               <el-button type="primary" size="small" @click="handleSave(scope.row)" v-hasPermi="['tender:segmentedIndicatorPlanning:edit']" | ||||
|                 >修改</el-button | ||||
|               > | ||||
|               <el-button type="danger" size="small" @click="delHandle(scope.row)" v-hasPermi="['tender:segmentedIndicatorPlanning:remove']" | ||||
|                 >删除</el-button | ||||
|               > | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|         </el-table> | ||||
|         <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" /> | ||||
|       </el-tab-pane> | ||||
|     </el-tabs> | ||||
|     <el-dialog title="新增" v-model="dialogVisible" width="75%" draggable> | ||||
|       <el-row> | ||||
|         <el-col :span="11"> | ||||
|           <el-form :model="form" :rules="rules" ref="formRef" label-width="80px"> | ||||
|             <el-form-item label="名称" prop="name"> | ||||
|               <el-input v-model="form.name" placeholder="请输入名称" clearable /> | ||||
|             </el-form-item> | ||||
|             <el-form-item label="内容" prop="content"> | ||||
|               <el-input v-model="form.content" placeholder="请输入内容" type="textarea" clearable :rows="4" /> | ||||
|             </el-form-item> | ||||
|           </el-form> | ||||
|         </el-col> | ||||
|       </el-row> | ||||
|       <el-row style="margin-top: 20px"> | ||||
|         <el-col :span="24"> | ||||
|           <el-card shadow="never"> | ||||
|             <el-form :model="treeForm" :inline="true"> | ||||
|               <el-form-item label="表名" prop="sheet"> | ||||
|                 <el-select v-model="treeForm.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> | ||||
|                 <el-button type="primary" @click="toggleExpandAll(true)">一键展开</el-button> | ||||
|               </el-form-item> | ||||
|               <el-form-item> | ||||
|                 <el-button type="primary" @click="toggleExpandAll(false)">一键收起</el-button> | ||||
|               </el-form-item> | ||||
|             </el-form> | ||||
|           </el-card> | ||||
|           <el-table | ||||
|             :data="treeData" | ||||
|             ref="treeTableRef" | ||||
|             v-loading="treeLoading" | ||||
|             row-key="id" | ||||
|             border | ||||
|             lazy | ||||
|             default-expand-all | ||||
|             @selection-change="handleSelection" | ||||
|           > | ||||
|             <el-table-column type="selection" width="55" /> | ||||
|             <el-table-column prop="num" label="编号" /> | ||||
|             <el-table-column prop="name" label="工程或费用名称" /> | ||||
|             <el-table-column prop="unit" label="单位" /> | ||||
|             <el-table-column prop="quantity" label="数量" /> | ||||
|             <el-table-column prop="selectNum" label="选择数量" align="center"> | ||||
|               <template #default="scope"> | ||||
|                 <el-input-number | ||||
|                   :model-value="scope.row.selectNum" | ||||
|                   @change=" | ||||
|                     (val) => { | ||||
|                       scope.row.selectNum = val; | ||||
|                       handleNumberChange(scope.row); | ||||
|                     } | ||||
|                   " | ||||
|                   :precision="2" | ||||
|                   :step="1" | ||||
|                   :controls="false" | ||||
|                   :max="Math.floor(scope.row.quantity)" | ||||
|                   v-if="scope.row.quantity && scope.row.quantity != 0" | ||||
|                 /> | ||||
|               </template> | ||||
|             </el-table-column> | ||||
|             <el-table-column prop="unitPrice" label="单价" align="center" /> | ||||
|             <el-table-column prop="price" label="总价" align="center"> | ||||
|               <template #default="scope"> | ||||
|                 {{ scope.row.price }} | ||||
|               </template> | ||||
|             </el-table-column> | ||||
|           </el-table> | ||||
|         </el-col> | ||||
|       </el-row> | ||||
|       <template #footer> | ||||
|         <el-button @click="closeDialog">取消</el-button> | ||||
|         <el-button type="primary" @click="submitForm(formRef)">确定</el-button> | ||||
|       </template> | ||||
|     </el-dialog> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script setup lang="ts"> | ||||
| import { useUserStoreHook } from '@/store/modules/user'; | ||||
| import { getDicts } from '@/api/system/dict/data'; | ||||
| import { Plus } from '@element-plus/icons-vue'; | ||||
| import { FormInstance } from 'element-plus'; | ||||
| import { treeList, sheetList, segmentedIndicatorPlanning, getPlanningList, updatePlanning, delPlanning } from '@/api/contract/index'; | ||||
|  | ||||
| const userStore = useUserStoreHook(); | ||||
| const currentProject = computed(() => userStore.selectedProject); | ||||
| const tabList = ref<any[]>([]); | ||||
| const tableData = ref<any[]>([]); | ||||
| const queryFormRef = ref(); | ||||
| const formRef = ref(); | ||||
| const activeTab = ref(); | ||||
| const queryParams = ref({ | ||||
|   pageNum: 1, | ||||
|   pageSize: 10 | ||||
| }); | ||||
| const total = ref(0); | ||||
| const queryForm = ref({ | ||||
|   name: '', | ||||
|   content: '' | ||||
| }); | ||||
| const dialogVisible = ref(false); | ||||
| const form = ref({ | ||||
|   name: '', | ||||
|   content: '' | ||||
| }); | ||||
| const rules = ref({ | ||||
|   name: [{ required: true, message: '请输入名称', trigger: 'blur' }], | ||||
|   content: [{ required: true, message: '请输入内容', trigger: 'blur' }] | ||||
| }); | ||||
| const loading = ref(false); | ||||
|  | ||||
| //字典获取数据 | ||||
| const getTabsList = async () => { | ||||
|   const res = await getDicts('subcontracting_type'); | ||||
|   if (res.code == 200) { | ||||
|     activeTab.value = res.data[0].dictValue; | ||||
|     tabList.value = res.data.map((item: any) => { | ||||
|       return { | ||||
|         label: item.dictLabel, | ||||
|         value: item.dictValue | ||||
|       }; | ||||
|     }); | ||||
|     getList(); | ||||
|   } | ||||
| }; | ||||
| //获取表格数据 | ||||
| const getList = async () => { | ||||
|   try { | ||||
|     loading.value = true; | ||||
|     const params = { | ||||
|       projectId: currentProject.value?.id, | ||||
|       ...queryParams.value, | ||||
|       ...queryForm.value, | ||||
|       dictName: activeTab.value | ||||
|     }; | ||||
|     const res = await getPlanningList(params); | ||||
|     if (res.code == 200) { | ||||
|       tableData.value = res.rows; | ||||
|       total.value = res.total; | ||||
|     } | ||||
|   } catch (error) { | ||||
|     console.log(error); | ||||
|     ElMessage({ | ||||
|       message: '获取数据失败', | ||||
|       type: 'error' | ||||
|     }); | ||||
|   } finally { | ||||
|     loading.value = false; | ||||
|   } | ||||
| }; | ||||
| const handleTabChange = (tabs: any) => { | ||||
|   activeTab.value = tabs; | ||||
|   getList(); | ||||
| }; | ||||
| /** 搜索按钮操作 */ | ||||
| const handleQuery = () => { | ||||
|   queryParams.value.pageNum = 1; | ||||
|   getList(); | ||||
| }; | ||||
|  | ||||
| /** 重置按钮操作 */ | ||||
| const resetQuery = () => { | ||||
|   queryForm.value.content = ''; | ||||
|   queryForm.value.name = ''; | ||||
|   handleQuery(); | ||||
| }; | ||||
|  | ||||
| const openDialog = () => { | ||||
|   dialogVisible.value = true; | ||||
|   getSheetName(); | ||||
| }; | ||||
| const closeDialog = () => { | ||||
|   dialogVisible.value = false; | ||||
|   form.value = { | ||||
|     name: '', | ||||
|     content: '' | ||||
|   }; | ||||
|   formRef.value?.resetFields(); | ||||
| }; | ||||
| const treeData = ref<any[]>([]); | ||||
| const treeForm = ref({ | ||||
|   sheet: '' | ||||
| }); | ||||
| const sheets = ref<any[]>([]); | ||||
| const treeTableRef = ref(); | ||||
| const isExpandAll = ref(false); | ||||
| const treeLoading = ref(false); | ||||
| const selectionData = ref<any>([]); | ||||
| //获取表名 | ||||
| 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) { | ||||
|         treeForm.value.sheet = res.data[0]; | ||||
|       } else { | ||||
|         treeForm.value.sheet = ''; | ||||
|         ElMessage({ | ||||
|           message: '获取表名失败', | ||||
|           type: 'warning' | ||||
|         }); | ||||
|       } | ||||
|       getTreeList(); | ||||
|     } | ||||
|   } catch (error) { | ||||
|     console.log(error); | ||||
|     ElMessage({ | ||||
|       message: '获取表名失败', | ||||
|       type: 'warning' | ||||
|     }); | ||||
|   } | ||||
| }; | ||||
| const handleSelection = (selection: any) => { | ||||
|   selectionData.value = selection; | ||||
| }; | ||||
| const handleNumberChange = (row: any) => { | ||||
|   const selectedIds = selectionData.value.map((item) => item.id); | ||||
|   restoreSelections(treeData.value, selectedIds); | ||||
| }; | ||||
| const restoreSelections = (data, selectedIds) => { | ||||
|   const traverse = (nodes) => { | ||||
|     nodes.forEach((node) => { | ||||
|       if (selectedIds.includes(node.id)) { | ||||
|         nextTick(() => { | ||||
|           treeTableRef.value.toggleRowSelection(node, true); | ||||
|         }); | ||||
|       } | ||||
|       if (node.children && node.children.length > 0) { | ||||
|         traverse(node.children); | ||||
|       } | ||||
|     }); | ||||
|   }; | ||||
|   traverse(data); | ||||
| }; | ||||
| watch( | ||||
|   () => selectionData.value, | ||||
|   (newVal, oldVal) => { | ||||
|     console.log(newVal, 55555555555555555); | ||||
|   } | ||||
| ); | ||||
|  | ||||
| //选择表名 | ||||
| const changeSheet = () => { | ||||
|   getTreeList(); | ||||
| }; | ||||
|  | ||||
| const toggleExpandAll = (isExpand: boolean) => { | ||||
|   treeData.value.forEach((row) => { | ||||
|     treeTableRef.value.toggleRowExpansion(row, isExpand); | ||||
|   }); | ||||
|   isExpandAll.value = isExpand; | ||||
| }; | ||||
| //打开获取表数据 | ||||
| const getTreeList = async () => { | ||||
|   try { | ||||
|     treeLoading.value = true; | ||||
|     const params = { | ||||
|       projectId: currentProject.value?.id, | ||||
|       sheet: treeForm.value.sheet | ||||
|     }; | ||||
|     const res = await treeList(params); | ||||
|     if (res.code == 200) { | ||||
|       res.data.forEach((item: any) => { | ||||
|         item.selectNum = ''; | ||||
|       }); | ||||
|       treeData.value = res.data; | ||||
|     } | ||||
|   } catch (error) { | ||||
|     console.log(error); | ||||
|     ElMessage({ | ||||
|       message: '获取表格失败', | ||||
|       type: 'error' | ||||
|     }); | ||||
|   } finally { | ||||
|     treeLoading.value = false; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| const submitForm = async (formEl: FormInstance | undefined) => { | ||||
|   if (!formEl) return; | ||||
|   await formEl.validate(async (valid, fields) => { | ||||
|     if (valid) { | ||||
|       try { | ||||
|         if (selectionData.value.length == 0) { | ||||
|           ElMessage({ | ||||
|             message: '请选择项目材料', | ||||
|             type: 'warning' | ||||
|           }); | ||||
|           return; | ||||
|         } | ||||
|  | ||||
|         if (selectionData.value.some((item) => item.selectNum == '' || item.selectNum == null)) { | ||||
|           ElMessage.error('存在未填写数量的工程或费用名称,请检查'); | ||||
|           return; | ||||
|         } | ||||
|         const limitListBos = selectionData.value.map((item: any) => { | ||||
|           return { | ||||
|             limitListId: item.id, | ||||
|             num: item.selectNum | ||||
|           }; | ||||
|         }); | ||||
|         const params = { | ||||
|           projectId: currentProject.value?.id, | ||||
|           ...form.value, | ||||
|           dictName: activeTab.value, | ||||
|           limitListBos | ||||
|         }; | ||||
|         const res = await segmentedIndicatorPlanning(params); | ||||
|         if (res.code == 200) { | ||||
|           ElMessage({ | ||||
|             message: '新增成功', | ||||
|             type: 'success' | ||||
|           }); | ||||
|           closeDialog(); | ||||
|           getList(); | ||||
|         } | ||||
|       } catch (error) { | ||||
|         console.log(error); | ||||
|         ElMessage({ | ||||
|           message: '新增失败', | ||||
|           type: 'error' | ||||
|         }); | ||||
|       } | ||||
|     } else { | ||||
|       console.log('error submit!', fields); | ||||
|     } | ||||
|   }); | ||||
| }; | ||||
| //确定修改 | ||||
| const handleSave = (row: any) => { | ||||
|   try { | ||||
|     if (!row.plannedBiddingTime) { | ||||
|       ElMessage({ | ||||
|         message: '请输入计划招标时间', | ||||
|         type: 'warning' | ||||
|       }); | ||||
|       return; | ||||
|     } | ||||
|     updatePlanning(row).then((res) => { | ||||
|       if (res.code == 200) { | ||||
|         ElMessage({ | ||||
|           message: '修改成功', | ||||
|           type: 'success' | ||||
|         }); | ||||
|         getList(); | ||||
|       } | ||||
|     }); | ||||
|   } catch (error) { | ||||
|     console.log(error); | ||||
|     ElMessage({ | ||||
|       message: '修改失败', | ||||
|       type: 'error' | ||||
|     }); | ||||
|   } | ||||
| }; | ||||
| //删除 | ||||
| const delHandle = (row: any) => { | ||||
|   try { | ||||
|     const params = { ids: row.id }; | ||||
|     delPlanning(params).then((res) => { | ||||
|       if (res.code == 200) { | ||||
|         ElMessage({ | ||||
|           message: '删除成功', | ||||
|           type: 'success' | ||||
|         }); | ||||
|         getList(); | ||||
|       } | ||||
|     }); | ||||
|   } catch (error) { | ||||
|     console.log(error); | ||||
|     ElMessage({ | ||||
|       message: '删除失败', | ||||
|       type: 'error' | ||||
|     }); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| onMounted(() => { | ||||
|   getTabsList(); | ||||
| }); | ||||
| </script> | ||||
|  | ||||
| <style scoped lang="scss"> | ||||
| .Region { | ||||
|   width: 100%; | ||||
|   height: 100%; | ||||
|   border: 1px solid #ccc; | ||||
|   border-radius: 10px; | ||||
|   padding: 10px; | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										276
									
								
								src/views/contract/limitPrice/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										276
									
								
								src/views/contract/limitPrice/index.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,276 @@ | ||||
| <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"> | ||||
|           <!-- <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" /> | ||||
|             </el-select> | ||||
|           </el-form-item> --> | ||||
|           <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> | ||||
|             <el-button type="primary" @click="toggleExpandAll(true)">一键展开</el-button> | ||||
|           </el-form-item> | ||||
|           <el-form-item> | ||||
|             <el-button type="primary" @click="toggleExpandAll(false)">一键收起</el-button> | ||||
|           </el-form-item> | ||||
|           <el-form-item> | ||||
|             <el-upload | ||||
|               ref="uploadRef" | ||||
|               class="upload-demo" | ||||
|               :http-request="importExcel" | ||||
|               :show-file-list="false" | ||||
|               v-hasPermi="['tender:billofquantitiesLimitList:importExcelFile']" | ||||
|             > | ||||
|               <template #trigger> | ||||
|                 <el-button type="primary">导入excel</el-button> | ||||
|               </template> | ||||
|             </el-upload> | ||||
|           </el-form-item> | ||||
|           <el-form-item> | ||||
|             <el-button type="primary" @click="handleExport()" v-hasPermi="['tender:billofquantitiesLimitList:export']">导出excel</el-button> | ||||
|           </el-form-item> | ||||
|         </el-form> | ||||
|       </el-card> | ||||
|     </transition> | ||||
|     <el-card shadow="never" class="mb8"> | ||||
|       <el-table ref="tableRef" v-loading="loading" :data="tableData" row-key="id" border lazy default-expand-all> | ||||
|         <el-table-column prop="num" label="编号" /> | ||||
|         <el-table-column prop="name" label="工程或费用名称" /> | ||||
|         <el-table-column prop="unit" label="单位" /> | ||||
|         <el-table-column prop="quantity" label="数量" /> | ||||
|         <el-table-column prop="remark" label="单价" align="center"> | ||||
|           <template #default="scope"> | ||||
|             <el-input-number | ||||
|               :model-value="scope.row.unitPrice" | ||||
|               @change="(val) => (scope.row.unitPrice = val)" | ||||
|               :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"> | ||||
|             <el-button | ||||
|               type="primary" | ||||
|               size="small" | ||||
|               @click="handleSave(scope.row)" | ||||
|               v-if="scope.row.quantity && scope.row.quantity != 0" | ||||
|               v-hasPermi="['tender:billofquantitiesLimitList:edit']" | ||||
|               >修改</el-button | ||||
|             > | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|       </el-table> | ||||
|     </el-card> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script setup lang="ts"> | ||||
| import { useUserStoreHook } from '@/store/modules/user'; | ||||
| import { listBillofquantitiesLimitList, obtainAllVersionNumbers, sheetList, updatePrice, importExcelFile } from '@/api/contract/index'; | ||||
| 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[]>([]); | ||||
| const isExpandAll = ref(false); | ||||
|  | ||||
| //获取版本号 | ||||
| const getVersionNums = async () => { | ||||
|   try { | ||||
|     const params = { | ||||
|       projectId: currentProject.value?.id, | ||||
|       pageSize: 1000, | ||||
|       pageNum: 1 | ||||
|     }; | ||||
|  | ||||
|     const res = await obtainAllVersionNumbers(params); | ||||
|     if (res.code == 200) { | ||||
|       options.value = res.data; | ||||
|       if (res.data.length > 0) { | ||||
|         queryForm.value.versions = res.data[0]; | ||||
|         getSheetName(); | ||||
|       } else { | ||||
|         queryForm.value.versions = ''; | ||||
|         ElMessage({ | ||||
|           message: '获取版本号失败', | ||||
|           type: 'warning' | ||||
|         }); | ||||
|       } | ||||
|     } | ||||
|   } catch (error) { | ||||
|     console.log(error); | ||||
|     ElMessage({ | ||||
|       message: '获取版本号失败', | ||||
|       type: 'warning' | ||||
|     }); | ||||
|   } | ||||
| }; | ||||
| //选择版本号 | ||||
| const changeVersions = () => { | ||||
|   getSheetName(); | ||||
| }; | ||||
|  | ||||
| //选择表名 | ||||
| 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 () => { | ||||
|   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 = []; | ||||
|     loading.value = false; | ||||
|   } finally { | ||||
|     loading.value = false; | ||||
|   } | ||||
| }; | ||||
| //修改单价 | ||||
| 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; | ||||
| }; | ||||
| //导入 | ||||
| const importExcel = (options: any): any => { | ||||
|   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; | ||||
|     }); | ||||
| }; | ||||
| //监听项目id刷新数据 | ||||
| const listeningProject = watch( | ||||
|   () => currentProject.value?.id, | ||||
|   (nid, oid) => { | ||||
|     getVersionNums(); | ||||
|   } | ||||
| ); | ||||
| const handleExport = () => { | ||||
|   proxy?.download( | ||||
|     '/tender/billofquantitiesLimitList/export', | ||||
|     { | ||||
|       projectId: currentProject.value?.id, | ||||
|       sheet: queryForm.value.sheet | ||||
|     }, | ||||
|     `限价一览表${queryForm.value.sheet}.xlsx` | ||||
|   ); | ||||
| }; | ||||
| onUnmounted(() => { | ||||
|   listeningProject(); | ||||
| }); | ||||
| onMounted(() => { | ||||
|   // getVersionNums(); | ||||
|   getSheetName(); | ||||
| }); | ||||
| </script> | ||||
|  | ||||
| <style scoped></style> | ||||
| @ -35,46 +35,33 @@ | ||||
|             <dict-tag :options="wf_business_status" :value="scope.row.status" /> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|         <el-table-column label="操作"> | ||||
|         <el-table-column label="操作" align="center"> | ||||
|           <template #default="scope"> | ||||
|             <el-row :gutter="10" class="mb8"> | ||||
|               <el-col :span="1.5" v-if="scope.row.status === 'draft' || scope.row.status === 'cancel' || scope.row.status === 'back'"> | ||||
|                 <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['design:extract:query']">审核</el-button> | ||||
|               </el-col> | ||||
|               <el-col :span="1.5" v-if="scope.row.status === 'finish'"> | ||||
|                 <el-button link type="primary" icon="Download" @click="handleDownload(scope.row)" v-hasPermi="['design:extract:export']" | ||||
|                   >导出</el-button | ||||
|                 > | ||||
|               </el-col> | ||||
|               <el-col :span="1.5"> | ||||
|                 <el-button | ||||
|                   link | ||||
|                   type="warning" | ||||
|                   icon="View" | ||||
|                   v-if="scope.row.status != 'draft'" | ||||
|                   v-hasPermi="['design:extract:query']" | ||||
|                   @click="handleViewInfo(scope.row)" | ||||
|                   >查看流程</el-button | ||||
|                 > | ||||
|               </el-col> | ||||
|               <el-col :span="1.5"> | ||||
|                 <el-button | ||||
|                   link | ||||
|                   type="warning" | ||||
|                   icon="View" | ||||
|                   v-if="scope.row.status != 'draft'" | ||||
|                   v-hasPermi="['design:extract:query']" | ||||
|                   @click="handleFile(scope.row)" | ||||
|                   >查看文件</el-button | ||||
|                 > | ||||
|               </el-col> | ||||
|             </el-row> | ||||
|             <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['design:extract:query']">审核</el-button> | ||||
|             <el-button link type="primary" icon="Download" @click="handleDownload(scope.row)" v-hasPermi="['design:extract:export']">导出</el-button | ||||
|             ><el-button | ||||
|               link | ||||
|               type="warning" | ||||
|               icon="View" | ||||
|               v-if="scope.row.status != 'draft'" | ||||
|               v-hasPermi="['design:extract:query']" | ||||
|               @click="handleViewInfo(scope.row)" | ||||
|               >查看流程</el-button | ||||
|             ><el-button | ||||
|               link | ||||
|               type="warning" | ||||
|               icon="View" | ||||
|               v-if="scope.row.status != 'draft'" | ||||
|               v-hasPermi="['design:extract:query']" | ||||
|               @click="handleFile(scope.row)" | ||||
|               >查看文件</el-button | ||||
|             > | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|       </el-table> | ||||
|       <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" /> | ||||
|     </el-card> | ||||
|     <el-dialog title="提取文件列表" v-model="viewVisible" width="500px"> | ||||
|     <el-dialog title="文件列表" v-model="viewVisible" width="800px"> | ||||
|       <el-table :loading="loadingFlie" :data="fileList" style="width: 100%" border> | ||||
|         <el-table-column prop="fileName" label="文件名称" align="center"> | ||||
|           <template #default="scope"> | ||||
| @ -89,19 +76,17 @@ | ||||
|             </el-link> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|         <el-table-column label="是否变更" align="center" width="120"> | ||||
|         <el-table-column label="版本号" align="center" width="120" prop="version"> </el-table-column> | ||||
|         <el-table-column label="文件类型" width="120" align="center"> | ||||
|           <template #default="scope"> | ||||
|             <el-tag :type="scope.row.type == 1 ? 'success' : 'info'">{{ scope.row.type == 1 ? '否' : '是' }}</el-tag> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|         <el-table-column label="状态" width="120" align="center"> | ||||
|           <template #default="scope"> | ||||
|             <el-tag :type="scope.row.status == 1 ? 'success' : 'info'">{{ scope.row.status == 1 ? '使用中' : '已作废' }}</el-tag> | ||||
|             <el-tag type="success" v-if="scope.row.type == 1">过程图纸</el-tag> | ||||
|             <el-tag type="primary" v-if="scope.row.type == 3">蓝图</el-tag> | ||||
|             <el-tag type="danger" v-if="scope.row.type == 4">作废图纸</el-tag> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|         <el-table-column label="操作" width="170" align="center"> | ||||
|           <template #default="scope"> | ||||
|             <el-button type="success" link icon="View" @click="handleViewFile(scope.row)"> 查看 </el-button> | ||||
|             <el-button type="success" v-if="viewFlie == 'finish'" link icon="View" @click="handleViewFile(scope.row)"> 查看 </el-button> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|       </el-table> | ||||
| @ -131,6 +116,7 @@ const showSearch = ref(true); | ||||
| const loading = ref(false); | ||||
| const loadingFlie = ref(false); | ||||
| const viewVisible = ref(false); //文件列表展示 | ||||
| const viewFlie = ref(''); | ||||
| const fileList = ref([]); | ||||
| const data = reactive({ | ||||
|   queryParams: { | ||||
| @ -205,10 +191,11 @@ const handleDownload = (row) => { | ||||
|   ); | ||||
| }; | ||||
| const handleViewFile = (row) => { | ||||
|   window.open(row.docUrl, '_blank'); | ||||
|   window.open(row.fileUrl, '_blank'); | ||||
| }; | ||||
| const handleFile = async (row) => { | ||||
|   // 查看文件 | ||||
|   viewFlie.value = row.status; | ||||
|   viewVisible.value = true; | ||||
|   loadingFlie.value = true; | ||||
|   let res = await getFileList(row.id); | ||||
|  | ||||
| @ -44,7 +44,11 @@ | ||||
|               </el-select> | ||||
|             </el-form-item> | ||||
|             <el-form-item> | ||||
|               <el-button v-if="Object.keys(state.versionsData).length === 0 || state.versionsData.status == 'cancel'" type="primary">导入excel</el-button> | ||||
|               <el-upload ref="uploadRef" class="upload-demo" :http-request="importExcel" :show-file-list="false" style="margin-right: 10px;"> | ||||
|                 <template #trigger> | ||||
|                   <el-button type="primary">导入excel</el-button> | ||||
|                 </template> | ||||
|               </el-upload> | ||||
|               <el-button v-if="state.versionsData.status == 'draft'" type="primary" con="edit" | ||||
|                 @click="clickApprovalSheet()">审核</el-button> | ||||
|               <el-button v-if="state.versionsData.status == 'waiting' || state.versionsData.status == 'finish'" | ||||
| @ -129,6 +133,7 @@ const handleTabChange = (tab) => { | ||||
|   state.queryForm.sheet = ''; | ||||
|   state.queryForm.versions = ''; | ||||
|   state.work_order_type = tab; | ||||
|   state.versionsData = {}; | ||||
|   if (tab <= 2) { | ||||
|     getVersionNums(); | ||||
|   } else { | ||||
| @ -158,6 +163,7 @@ async function getVersionNums(isSheet = true) { | ||||
|         state.queryForm.versions = state.options[0].versions; | ||||
|         // if (state.work_order_type == 3) { | ||||
|         state.versionsData = state.options[0] || []; | ||||
|         console.log('state.versionsData', state.versionsData); | ||||
|           // console.log('state.versionsData', state.versionsData); | ||||
|         // } | ||||
|         // 等待表名加载完成 | ||||
|  | ||||
| @ -25,7 +25,7 @@ | ||||
|         </el-table-column> | ||||
|         <el-table-column label="操作"> | ||||
|           <template #default="scope"> | ||||
|             <el-button link type="primary" icon="Download" @click="onExport(scope.row.fileUrl)">下载</el-button> | ||||
|             <el-button link type="primary" icon="Download" @click="onExport(scope.row)">下载</el-button> | ||||
|             <el-button type="success" link icon="edit" v-show="scope.row.status == 'draft'" @click="onUpdate(scope.row)">审核</el-button> | ||||
|             <el-button link type="warning" v-show="scope.row.status != 'draft'" icon="View" @click="onView(scope.row)">查看流程</el-button> | ||||
|           </template> | ||||
| @ -117,28 +117,12 @@ const onView = (row) => { | ||||
|     } | ||||
|   }); | ||||
| }; | ||||
| const onExport = (fileUrl) => { | ||||
|   if (!fileUrl) { | ||||
| const onExport = (row) => { | ||||
|   if (!row.fileUrl) { | ||||
|     proxy.$modal.error('文件地址不存在,无法下载'); | ||||
|     return; | ||||
|   } | ||||
|   try { | ||||
|     // 创建一个隐藏的a标签 | ||||
|     const link = document.createElement('a'); | ||||
|     // 设置下载地址 | ||||
|     link.href = fileUrl; | ||||
|     // 从URL中提取文件名作为下载文件名 | ||||
|     const fileName = fileUrl.split('/').pop(); | ||||
|     link.download = fileName || 'download file'; | ||||
|     // 触发点击事件 | ||||
|     link.click(); | ||||
|     // 下载后移除a标签 | ||||
|     document.body.removeChild(link); | ||||
|     // 显示下载成功提示 | ||||
|     proxy.$modal.success('文件开始下载'); | ||||
|   } catch (error) { | ||||
|     // proxy.$modal.error('下载失败,请稍后重试'); | ||||
|   } | ||||
|   proxy.downloadFile(row.fileUrl, row.fileName); | ||||
| }; | ||||
| // 页面挂载时初始化数据 | ||||
| onMounted(() => { | ||||
|  | ||||
| @ -65,8 +65,9 @@ | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|         <el-table-column label="变更内容" align="center" prop="changeContent" width="150" /> | ||||
|         <el-table-column label="备注" align="center" prop="remark" width="150" /> | ||||
|         <el-table-column label="操作" fixed="right" width="300"> | ||||
|         <el-table-column label="创建时间" align="center" prop="createTime" width="150" /> | ||||
|         <el-table-column label="备注" align="center" prop="remark" width="200" /> | ||||
|         <el-table-column label="操作" align="center" fixed="right" width="300"> | ||||
|           <template #default="scope"> | ||||
|             <el-button | ||||
|               type="primary" | ||||
|  | ||||
| @ -242,7 +242,8 @@ const data = reactive({ | ||||
|   }, | ||||
|   rules: { | ||||
|     // 卷册号 | ||||
|     volumeNo: [{ required: true, message: '请请选择卷册号', trigger: 'change' }] | ||||
|     volumeNo: [{ required: true, message: '请请选择卷册号', trigger: 'change' }], | ||||
|     formNo: [{ required: true, message: '申请单编号不能为空', trigger: 'change' }] | ||||
|   } | ||||
| }); | ||||
|  | ||||
|  | ||||
| @ -56,14 +56,14 @@ | ||||
|           <el-table-column label="操作" align="center" prop="remark" width="300"> | ||||
|             <template #default="scope"> | ||||
|               <el-button link type="primary" icon="view" @click="handleViewHis(scope.row)">查阅记录</el-button> | ||||
|               <el-button type="danger" link icon="Download" @click="handleDownload(scope.row)"> 下载 </el-button> | ||||
|               <el-button type="warning" link icon="Download" @click="handleDownload(scope.row)"> 下载 </el-button> | ||||
|             </template> | ||||
|           </el-table-column> | ||||
|         </el-table> | ||||
|         <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" /> | ||||
|       </el-card> | ||||
|     </div> | ||||
|     <el-dialog draggable title="查阅记录" v-model="viewVisible1" width="500px"> | ||||
|     <el-dialog draggable title="查阅记录" v-model="viewVisible1" width="600px"> | ||||
|       <el-table :data="histroyList" style="width: 100%" border> | ||||
|         <el-table-column type="index" label="序号" align="center" width="80"> </el-table-column> | ||||
|         <el-table-column prop="userName" label="用户名称" align="center"> </el-table-column> | ||||
| @ -73,7 +73,7 @@ | ||||
|             <el-tag type="success" v-else>查看</el-tag> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|         <el-table-column prop="createTime" label="查阅时间" align="center"> </el-table-column> | ||||
|         <el-table-column prop="createTime" label="查阅时间" align="center" width="200"> </el-table-column> | ||||
|       </el-table> | ||||
|       <template #footer> | ||||
|         <span> | ||||
|  | ||||
| @ -68,6 +68,7 @@ | ||||
|             <el-input v-model="formData.designer" placeholder="请输入设计人" /> | ||||
|           </el-form-item> | ||||
|         </el-col> | ||||
|         <el-col :span="12"></el-col> | ||||
|         <el-col :span="12"> | ||||
|           <el-form-item label="校审人员" prop="proofreading"> | ||||
|             <el-input v-model="formData.proofreading" placeholder="请输入校审人员" /> | ||||
|  | ||||
							
								
								
									
										468
									
								
								src/views/design/volumeCatalog/codeDetail.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										468
									
								
								src/views/design/volumeCatalog/codeDetail.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,468 @@ | ||||
| <template> | ||||
|   <div | ||||
|     class="min-h-screen bg-gradient-to-b from-gray-50 to-gray-100 dark:from-gray-900 dark:to-gray-850 text-gray-800 dark:text-gray-200 transition-colors duration-300" | ||||
|   > | ||||
|     <!-- 页面头部 --> | ||||
|     <header class="bg-white/90 dark:bg-gray-800/90 backdrop-blur-sm shadow-sm sticky top-0 z-10 border-b border-gray-100 dark:border-gray-700/50"> | ||||
|       <div class="container mx-auto px-4 py-3 flex justify-between items-center"> | ||||
|         <div class="flex items-center gap-2"> | ||||
|           <el-icon style="margin-right: 10px" :size="32" color="#409EFF"> | ||||
|             <Document /> | ||||
|           </el-icon> | ||||
|           <h1 class="text-xl font-bold text-primary">资料详情</h1> | ||||
|         </div> | ||||
|         <button | ||||
|           v-if="info.fileUrl" | ||||
|           @click="handleDownload" | ||||
|           class="flex items-center gap-2 bg-primary hover:bg-primary/90 text-white px-3.5 py-1.5 rounded-lg transition-all duration-200 shadow-sm hover:shadow hover:-translate-y-0.5 active:translate-y-0 text-sm" | ||||
|         > | ||||
|           <i class="fa fa-download"></i> | ||||
|           <span>下载资料</span> | ||||
|         </button> | ||||
|       </div> | ||||
|     </header> | ||||
|  | ||||
|     <!-- 加载状态 --> | ||||
|     <div v-if="loading" class="container mx-auto px-4 py-12 flex justify-center items-center min-h-[40vh]"> | ||||
|       <div class="flex flex-col items-center bg-white dark:bg-gray-800 p-6 rounded-xl shadow-sm"> | ||||
|         <div class="w-12 h-12 border-4 border-primary border-t-transparent rounded-full animate-spin mb-3"></div> | ||||
|         <p class="text-gray-600 dark:text-gray-400 text-base">加载资料信息中...</p> | ||||
|         <p class="text-gray-500 dark:text-gray-500 text-xs mt-1">请稍候,正在获取最新数据</p> | ||||
|       </div> | ||||
|     </div> | ||||
|  | ||||
|     <!-- 错误状态 --> | ||||
|     <div v-if="error" class="container mx-auto px-4 py-12"> | ||||
|       <div class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-sm border border-red-100 dark:border-red-900/30"> | ||||
|         <div class="flex flex-col items-center text-center"> | ||||
|           <div class="w-12 h-12 rounded-full bg-red-100 dark:bg-red-900/20 flex items-center justify-center text-red-500 mb-3"> | ||||
|             <i class="fa fa-exclamation-circle text-xl"></i> | ||||
|           </div> | ||||
|           <h3 class="font-semibold text-red-800 dark:text-red-400 text-lg mb-2">加载失败</h3> | ||||
|           <p class="mt-1 text-red-700 dark:text-red-300 max-w-md mb-4 text-sm">无法获取资料信息,可能是网络问题或数据不存在,请稍后重试</p> | ||||
|           <button | ||||
|             @click="retryLoad" | ||||
|             class="px-5 py-2 bg-primary hover:bg-primary/90 text-white rounded-lg transition-all duration-200 shadow-sm hover:shadow flex items-center gap-2 text-sm" | ||||
|           > | ||||
|             <i class="fa fa-refresh"></i> | ||||
|             <span>重试加载</span> | ||||
|           </button> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|  | ||||
|     <!-- 信息卡片 --> | ||||
|     <main v-if="!loading && !error && Object.keys(info).length" class="container mx-auto px-4 py-5 md:py-6"> | ||||
|       <div | ||||
|         class="bg-white dark:bg-gray-800 rounded-xl shadow-sm overflow-hidden transition-all duration-300 hover:shadow-md transform hover:-translate-y-0.5" | ||||
|       > | ||||
|         <!-- 卡片头部 - 降低背景深度,增强标题对比度 --> | ||||
|         <div | ||||
|           class="bg-gradient-to-r from-primary/1 to-primary/3 dark:from-primary/3 dark:to-primary/6 p-4 md:p-5 border-b border-gray-100 dark:border-gray-700/50" | ||||
|         > | ||||
|           <div class="flex flex-wrap justify-between items-center gap-2"> | ||||
|             <h2 style="color: #fff" class="text-lg md:text-xl font-bold text-primary flex items-center"> | ||||
|               <i class="fa fa-file-text-o mr-2 text-lg"></i> | ||||
|               <span>{{ info.documentName || '资料详情' }}</span> | ||||
|             </h2> | ||||
|             <span :class="typeClass" class="inline-flex items-center px-2.5 py-0.75 rounded-full text-xs font-medium"> | ||||
|               <i class="fa fa-tag mr-1"></i> | ||||
|               {{ typeText }} | ||||
|             </span> | ||||
|           </div> | ||||
|           <!-- 副标题放大,增强可读性 --> | ||||
|           <p class="mt-1.5 text-gray-700 dark:text-gray-300 text-base md:text-lg" style="color: #e5e5e5; font-weight: 600"> | ||||
|             资料名称: {{ info.projectName || '未定义' }} | 卷册号: {{ info.volumeNumber || '未定义' }} | ||||
|           </p> | ||||
|         </div> | ||||
|  | ||||
|         <!-- 基本信息区域 - 缩小间隔,增强label与内容区分 --> | ||||
|         <div class="p-3 md:p-4 border-b border-gray-100 dark:border-gray-700/50"> | ||||
|           <h3 class="text-base md:text-lg font-semibold mb-2 flex items-center text-gray-800 dark:text-gray-200"> | ||||
|             <el-icon style="margin-right: 10px" :size="24" color="#409EFF"> | ||||
|               <Document /> | ||||
|             </el-icon> | ||||
|  | ||||
|             基本信息 | ||||
|           </h3> | ||||
|  | ||||
|           <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-2 md:gap-3"> | ||||
|             <InfoItem label="项目名称" value="projectName" :data="info" /> | ||||
|             <InfoItem label="资料名称" value="documentName" :data="info" /> | ||||
|             <InfoItem label="卷册号" value="volumeNumber" :data="info" /> | ||||
|             <InfoItem label="设计子项名称" value="designSubitem" :data="info" /> | ||||
|             <InfoItem label="专业名称" value="specialtyName" :data="info" /> | ||||
|             <InfoItem label="文件格式" value="fileType" :data="info" /> | ||||
|           </div> | ||||
|         </div> | ||||
|  | ||||
|         <!-- 人员信息区域 --> | ||||
|         <div class="p-3 md:p-4 border-b border-gray-100 dark:border-gray-700/50"> | ||||
|           <h3 class="text-base md:text-lg font-semibold mb-2 flex items-center text-gray-800 dark:text-gray-200"> | ||||
|             <el-icon style="margin-right: 10px" :size="24" color="#409EFF"> | ||||
|               <Document /> | ||||
|             </el-icon> | ||||
|             人员信息 | ||||
|           </h3> | ||||
|  | ||||
|           <div class="grid grid-cols-1 md:grid-cols-2 gap-2 md:gap-3"> | ||||
|             <InfoItem label="负责人" value="principal" :data="info" /> | ||||
|             <InfoItem label="设计人员" value="principalName" :data="info" /> | ||||
|             <InfoItem label="审核人员" value="reviewerName" :data="info" /> | ||||
|             <InfoItem label="创建时间" value="createTime" :data="info" /> | ||||
|           </div> | ||||
|         </div> | ||||
|  | ||||
|         <!-- 状态信息区域 --> | ||||
|         <div class="p-3 md:p-4"> | ||||
|           <h3 class="text-base md:text-lg font-semibold mb-2 flex items-center text-gray-800 dark:text-gray-200"> | ||||
|             <el-icon style="margin-right: 10px" :size="24" color="#409EFF"> | ||||
|               <Document /> | ||||
|             </el-icon> | ||||
|             状态信息 | ||||
|           </h3> | ||||
|  | ||||
|           <div class="grid grid-cols-1 md:grid-cols-2 gap-2 md:gap-3"> | ||||
|             <div class="info-item"> | ||||
|               <span class="info-label">图纸类型</span> | ||||
|               <div class="info-value mt-0.5"> | ||||
|                 <span :class="typeClass" class="inline-flex items-center px-2.5 py-0.75 rounded-full text-xs font-medium"> | ||||
|                   <i class="fa fa-file-image-o mr-1"></i> | ||||
|                   {{ typeText }} | ||||
|                 </span> | ||||
|               </div> | ||||
|             </div> | ||||
|  | ||||
|             <div class="info-item"> | ||||
|               <span class="info-label">是否最新版本</span> | ||||
|               <div class="info-value mt-0.5"> | ||||
|                 <span | ||||
|                   :class=" | ||||
|                     isLatest | ||||
|                       ? 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400' | ||||
|                       : 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300' | ||||
|                   " | ||||
|                   class="inline-flex items-center px-2.5 py-0.75 rounded-full text-xs font-medium" | ||||
|                 > | ||||
|                   <i :class="isLatest ? 'fa fa-check-circle' : 'fa fa-clock-o'" class="mr-1"></i> | ||||
|                   {{ isLatest ? '是 (最新版)' : '否' }} | ||||
|                 </span> | ||||
|               </div> | ||||
|             </div> | ||||
|  | ||||
|             <div class="info-item"> | ||||
|               <span class="info-label">文件大小</span> | ||||
|               <div class="info-value mt-0.5 flex items-center"> | ||||
|                 <i class="fa fa-hdd-o text-gray-400 dark:text-gray-500 mr-1.5"></i> | ||||
|                 {{ info.fileSize || '未知' }} | ||||
|               </div> | ||||
|             </div> | ||||
|  | ||||
|             <div class="info-item"> | ||||
|               <span class="info-label">更新时间</span> | ||||
|               <div class="info-value mt-0.5 flex items-center"> | ||||
|                 <i class="fa fa-calendar-o text-gray-400 dark:text-gray-500 mr-1.5"></i> | ||||
|                 {{ info.updateTime || '未更新' }} | ||||
|               </div> | ||||
|             </div> | ||||
|           </div> | ||||
|  | ||||
|           <!-- 文件信息补充 - 缩小内边距 --> | ||||
|           <div v-if="info.fileUrl" class="mt-3 p-2.5 bg-gray-50 dark:bg-gray-700/30 rounded-lg border border-gray-100 dark:border-gray-700"> | ||||
|             <div class="flex flex-wrap items-center justify-between gap-3"> | ||||
|               <div class="flex items-center"> | ||||
|                 <el-icon style="margin-right: 10px" :size="30" color="#409EFF"> | ||||
|                   <Notebook /> | ||||
|                 </el-icon> | ||||
|                 <div> | ||||
|                   <h4 class="font-medium text-gray-800 dark:text-white text-sm">文件下载</h4> | ||||
|                   <p class="text-xs text-gray-500 dark:text-gray-400">点击按钮下载完整资料文件</p> | ||||
|                 </div> | ||||
|               </div> | ||||
|               <button | ||||
|                 @click="handleDownload" | ||||
|                 class="flex items-center gap-2 bg-primary hover:bg-primary/90 text-white px-4 py-1.5 rounded-lg transition-all duration-200 shadow-sm hover:shadow text-sm" | ||||
|               > | ||||
|                 <i class="fa fa-cloud-download"></i> | ||||
|                 <span>立即下载</span> | ||||
|               </button> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </main> | ||||
|  | ||||
|     <!-- 空状态 --> | ||||
|     <div | ||||
|       v-if="!loading && !error && !Object.keys(info).length" | ||||
|       class="container mx-auto px-4 py-12 flex flex-col items-center justify-center min-h-[40vh]" | ||||
|     > | ||||
|       <div class="bg-white dark:bg-gray-800 p-6 rounded-xl shadow-sm text-center max-w-md w-full"> | ||||
|         <div class="w-16 h-16 rounded-full bg-gray-100 dark:bg-gray-700/50 flex items-center justify-center mb-4"> | ||||
|           <i class="fa fa-file-text-o text-3xl text-gray-400 dark:text-gray-500"></i> | ||||
|         </div> | ||||
|         <h3 class="text-base font-medium text-gray-700 dark:text-gray-300 mb-2">暂无资料信息</h3> | ||||
|         <p class="text-gray-500 dark:text-gray-400 mb-4 text-sm">未找到相关资料的详细信息,请检查访问参数是否正确,或联系管理员获取帮助</p> | ||||
|         <button | ||||
|           @click="goBack" | ||||
|           class="px-5 py-2 bg-gray-100 hover:bg-gray-200 dark:bg-gray-700 dark:hover:bg-gray-600 text-gray-700 dark:text-gray-300 rounded-lg transition-all duration-200 text-sm" | ||||
|         > | ||||
|           <i class="fa fa-arrow-left mr-1.5"></i> | ||||
|           返回上一页 | ||||
|         </button> | ||||
|       </div> | ||||
|     </div> | ||||
|     <footer class="bg-white/80 dark:bg-gray-800/80 backdrop-blur-sm border-t border-gray-100 dark:border-gray-700/50 py-2.5 mt-6"> | ||||
|       <div class="container mx-auto px-4 text-center text-gray-500 dark:text-gray-400 text-xs"> | ||||
|         <p>© 2025 煤科建管平台</p> | ||||
|       </div> | ||||
|     </footer> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script setup lang="ts"> | ||||
| import { ref, onMounted, computed, defineComponent, h } from 'vue'; | ||||
| import { useRoute, useRouter } from 'vue-router'; | ||||
| import { codeInfo } from '@/api/design/volumeCatalog'; | ||||
|  | ||||
| // 使用渲染函数定义InfoItem组件,避免运行时模板编译 | ||||
| const InfoItem = defineComponent({ | ||||
|   props: { | ||||
|     label: { | ||||
|       type: String, | ||||
|       required: true | ||||
|     }, | ||||
|     value: { | ||||
|       type: String, | ||||
|       required: true | ||||
|     }, | ||||
|     data: { | ||||
|       type: Object, | ||||
|       required: true, | ||||
|       default: () => ({}) | ||||
|     } | ||||
|   }, | ||||
|   // 使用渲染函数h()替代template | ||||
|   render() { | ||||
|     const displayValue = this.data[this.value] !== undefined && this.data[this.value] !== null ? this.data[this.value] : '-'; | ||||
|  | ||||
|     return h('div', { class: 'info-item' }, [ | ||||
|       h('span', { class: 'info-label' }, this.label), | ||||
|       h('div', { class: 'info-value mt-0.5 flex items-center' }, [h('span', { class: 'block' }, displayValue)]) | ||||
|     ]); | ||||
|   } | ||||
| }); | ||||
|  | ||||
| const route = useRoute(); | ||||
| const router = useRouter(); | ||||
| const info = ref<Record<string, any>>({}); | ||||
| const loading = ref(true); | ||||
| const error = ref(false); | ||||
|  | ||||
| // 获取用户信息 | ||||
| const getcodeInfo = async (id: string) => { | ||||
|   try { | ||||
|     loading.value = true; | ||||
|     error.value = false; | ||||
|     let res = await codeInfo(id); | ||||
|     if (res && res.data) { | ||||
|       info.value = res.data; | ||||
|       // 补充文件类型和大小信息(模拟数据,实际应从接口获取) | ||||
|       if (info.value.fileUrl) { | ||||
|         const urlParts = info.value.fileUrl.split('.'); | ||||
|         info.value.fileType = urlParts.length > 1 ? urlParts.pop()?.toUpperCase() : 'UNKNOWN'; | ||||
|         info.value.fileSize = info.value.fileSize || `${(Math.random() * 20 + 1).toFixed(1)} MB`; | ||||
|         info.value.createTime = info.value.createTime || new Date(Date.now() - Math.random() * 30 * 24 * 60 * 60 * 1000).toLocaleString(); | ||||
|         info.value.updateTime = info.value.updateTime || new Date(Date.now() - Math.random() * 10 * 24 * 60 * 60 * 1000).toLocaleString(); | ||||
|         info.value.reviewerName = info.value.reviewerName || '张审核'; | ||||
|       } | ||||
|     } else { | ||||
|       info.value = {}; | ||||
|     } | ||||
|   } catch (err) { | ||||
|     console.error('获取信息失败:', err); | ||||
|     error.value = true; | ||||
|     info.value = {}; | ||||
|   } finally { | ||||
|     loading.value = false; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| // 重试加载 | ||||
| const retryLoad = () => { | ||||
|   const data = route.query; | ||||
|   if (data.id && typeof data.id === 'string') { | ||||
|     getcodeInfo(data.id); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| // 返回上一页 | ||||
| const goBack = () => { | ||||
|   router.go(-1); | ||||
| }; | ||||
|  | ||||
| // 处理下载 | ||||
| const handleDownload = () => { | ||||
|   if (info.value.fileUrl) { | ||||
|     const link = document.createElement('a'); | ||||
|     link.href = info.value.fileUrl; | ||||
|     link.download = info.value.documentName || '资料文件'; | ||||
|     // 添加下载动画反馈 | ||||
|     const downloadBtn = document.querySelector('.bg-primary:has(.fa-download), .bg-primary:has(.fa-cloud-download)'); | ||||
|     if (downloadBtn) { | ||||
|       downloadBtn.classList.add('animate-pulse'); | ||||
|     } | ||||
|  | ||||
|     document.body.appendChild(link); | ||||
|     link.click(); | ||||
|     document.body.removeChild(link); | ||||
|  | ||||
|     // 移除动画反馈 | ||||
|     setTimeout(() => { | ||||
|       if (downloadBtn) { | ||||
|         downloadBtn.classList.remove('animate-pulse'); | ||||
|       } | ||||
|     }, 1000); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| // 计算图纸类型文本 | ||||
| const typeText = computed(() => { | ||||
|   const type = typeof info.value.type === 'string' ? parseInt(info.value.type, 10) : info.value.type; | ||||
|  | ||||
|   switch (type) { | ||||
|     case 1: | ||||
|       return '过程图纸'; | ||||
|     case 3: | ||||
|       return '蓝图'; | ||||
|     case 4: | ||||
|       return '作废图纸'; | ||||
|     default: | ||||
|       // 显示实际收到的值,帮助调试 | ||||
|       return `未知类型 (值: ${type})`; | ||||
|   } | ||||
| }); | ||||
|  | ||||
| // 计算图纸类型样式 | ||||
| const typeClass = computed(() => { | ||||
|   switch (info.value.type) { | ||||
|     case 1: | ||||
|       return 'bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-400'; | ||||
|     case 3: | ||||
|       return 'bg-purple-100 text-purple-800 dark:bg-purple-900/30 dark:text-purple-400'; | ||||
|     case 4: | ||||
|       return 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400'; | ||||
|     default: | ||||
|       return 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300'; | ||||
|   } | ||||
| }); | ||||
|  | ||||
| // 计算是否最新 | ||||
| const isLatest = computed(() => { | ||||
|   return info.value.isLatest === true; | ||||
| }); | ||||
|  | ||||
| onMounted(() => { | ||||
|   const data = route.query; | ||||
|   if (data.id && typeof data.id === 'string') { | ||||
|     getcodeInfo(data.id); | ||||
|   } else { | ||||
|     loading.value = false; | ||||
|     error.value = true; | ||||
|   } | ||||
| }); | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
| /* 主色调定义 */ | ||||
| :root { | ||||
|   --primary-color: #165dff; | ||||
|   --shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.05); | ||||
|   --shadow: 0 4px 6px rgba(0, 0, 0, 0.08); | ||||
| } | ||||
|  | ||||
| /* 信息项样式优化 - 增强label与内容颜色区分,缩小间距 */ | ||||
| .info-item { | ||||
|   @apply py-1.5 rounded-lg hover:bg-gray-50/70 dark:hover:bg-gray-700/15 p-2 transition-colors duration-200; | ||||
| } | ||||
|  | ||||
| /* Label颜色加深,与内容形成明显对比 */ | ||||
| .info-label { | ||||
|   @apply text-xs text-gray-500 dark:text-gray-400 font-medium flex items-center; | ||||
|   display: block; | ||||
| } | ||||
|  | ||||
| /* 内容颜色增强可读性 */ | ||||
| .info-value { | ||||
|   @apply text-sm text-gray-900 dark:text-white; | ||||
|   word-break: break-word; | ||||
| } | ||||
|  | ||||
| /* 动画效果 */ | ||||
| .animate-pulse { | ||||
|   animation: pulse 1.5s cubic-bezier(0.4, 0, 0.6, 1) infinite; | ||||
| } | ||||
|  | ||||
| @keyframes pulse { | ||||
|   0%, | ||||
|   100% { | ||||
|     opacity: 1; | ||||
|   } | ||||
|   50% { | ||||
|     opacity: 0.7; | ||||
|   } | ||||
| } | ||||
|  | ||||
| /* 自定义滚动条 */ | ||||
| ::-webkit-scrollbar { | ||||
|   @apply w-2 h-2; | ||||
| } | ||||
|  | ||||
| ::-webkit-scrollbar-track { | ||||
|   @apply bg-gray-100 dark:bg-gray-800 rounded-full; | ||||
| } | ||||
|  | ||||
| ::-webkit-scrollbar-thumb { | ||||
|   @apply bg-gray-300 dark:bg-gray-600 rounded-full hover:bg-gray-400 dark:hover:bg-gray-500 transition-colors; | ||||
| } | ||||
| </style> | ||||
|  | ||||
| <style> | ||||
| /* 全局样式 */ | ||||
| .text-primary { | ||||
|   color: #165dff; | ||||
| } | ||||
|  | ||||
| .bg-primary { | ||||
|   background-color: #165dff; | ||||
| } | ||||
|  | ||||
| /* 平滑滚动 - 增强丝滑感 */ | ||||
| html { | ||||
|   scroll-behavior: smooth; | ||||
| } | ||||
|  | ||||
| /* 响应式调整 */ | ||||
| @media (max-width: 768px) { | ||||
|   .container { | ||||
|     padding-left: 0.75rem !important; | ||||
|     padding-right: 0.75rem !important; | ||||
|   } | ||||
| } | ||||
|  | ||||
| /* 暗色模式优化 */ | ||||
| .dark { | ||||
|   color-scheme: dark; | ||||
| } | ||||
|  | ||||
| /* 卡片悬停效果增强柔和度 */ | ||||
| .bg-white.dark\:bg-gray-800 { | ||||
|   transition: all 0.3s ease-in-out; | ||||
| } | ||||
|  | ||||
| /* 按钮基础样式 - 增强点击反馈 */ | ||||
| button { | ||||
|   cursor: pointer; | ||||
|   transition: all 0.2s ease; | ||||
| } | ||||
| </style> | ||||
| @ -1,15 +1,15 @@ | ||||
| <template> | ||||
|   <div class="volume-catalog-container"> | ||||
|     <div class="history-selector"> | ||||
|     <!-- <div class="history-selector"> | ||||
|       <span>选择历史退回记录:</span> | ||||
|       <el-select v-model="hisId" placeholder="请选择" style="width: 240px" @change="handleShowInfo"> | ||||
|         <el-option v-for="item in hisList" :key="item.id" :label="item.createTime" :value="item.id" /> | ||||
|       </el-select> | ||||
|     </div> | ||||
|     </div> --> | ||||
|  | ||||
|     <div class="volumeCatalog_box" style="margin-top: 20px"> | ||||
|     <div class="volumeCatalog_box"> | ||||
|       <!-- <span style="color: #0d9df5">查看excel文件</span> --> | ||||
|       <div class="table-content" id="table-content" style="margin-top: 20px"> | ||||
|       <div class="table-content" id="table-content"> | ||||
|         <el-row class="mb20" style="display: flex; justify-content: center"> | ||||
|           <h2>设计验证表</h2> | ||||
|         </el-row> | ||||
| @ -165,24 +165,18 @@ const handleShowInfo = async (value: string | number) => { | ||||
| // 日期格式化方法 | ||||
| const dateFormat = (date: string | Date | null): string => { | ||||
|   if (!date) return ''; | ||||
|  | ||||
|   // 处理字符串类型的日期 | ||||
|   if (typeof date === 'string') { | ||||
|     date = new Date(date); | ||||
|   } | ||||
|  | ||||
|   // 检查日期是否有效 | ||||
|   if (isNaN(date.getTime())) { | ||||
|     return ''; | ||||
|   } | ||||
|  | ||||
|   const year = date.getFullYear(); | ||||
|   const month = String(date.getMonth() + 1).padStart(2, '0'); | ||||
|   const day = String(date.getDate()).padStart(2, '0'); | ||||
|   const hours = String(date.getHours()).padStart(2, '0'); | ||||
|   const minutes = String(date.getMinutes()).padStart(2, '0'); | ||||
|  | ||||
|   return `${year}-${month}-${day} ${hours}:${minutes}`; | ||||
|   return `${year}年${month}月${day}日`; | ||||
| }; | ||||
|  | ||||
| // 获取详情 | ||||
|  | ||||
| @ -47,6 +47,8 @@ | ||||
|       </template> | ||||
|       <el-table v-loading="loading" :data="volumeCatalogList"> | ||||
|         <el-table-column label="序号" type="index" width="60" align="center" /> | ||||
|         <el-table-column label="卷册号" align="center" prop="volumeNumber" /> | ||||
|         <el-table-column label="资料名称" align="center" prop="documentName" /> | ||||
|         <el-table-column label="子项名称" align="center" prop="designSubitem" /> | ||||
|         <el-table-column label="设计状态" align="center" prop="designState"> | ||||
|           <template #default="scope"> | ||||
| @ -55,8 +57,6 @@ | ||||
|         </el-table-column> | ||||
|         <el-table-column label="专业" align="center" prop="specialtyName"> </el-table-column> | ||||
|         <el-table-column label="设计人员" align="center" prop="principalName" /> | ||||
|         <el-table-column label="卷册号" align="center" prop="volumeNumber" /> | ||||
|         <el-table-column label="资料名称" align="center" prop="documentName" /> | ||||
|         <el-table-column label="计划出图时间" align="center" prop="plannedCompletion" width="200" /> | ||||
|         <el-table-column label="图纸文件" align="center" prop="remark" width="150"> | ||||
|           <template #default="scope"> | ||||
| @ -68,6 +68,7 @@ | ||||
|             <el-link v-if="scope.row.opinion" :href="scope.row.opinion" target="_blank" type="primary"> 查看文件 </el-link> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|         <el-table-column label="创建时间" align="center" prop="createTime" /> | ||||
|         <el-table-column label="备注" align="center" prop="remark" /> | ||||
|         <el-table-column label="操作" align="center" fixed="right" width="200"> | ||||
|           <template #default="scope"> | ||||
| @ -100,7 +101,7 @@ | ||||
|         </el-form-item> | ||||
|         <el-form-item label="设计人员" prop="principal"> | ||||
|           <el-select v-model="form.principal" placeholder="请选择设计人员" class="transition-all duration-300 border-gray-300"> | ||||
|             <el-option v-for="item in userAppList" :key="item.userId" :label="item.userName" :value="item.userId" /> | ||||
|             <el-option v-for="item in userAppList" :key="item.userId" :label="item.userName" :value="item.userId.toString()" /> | ||||
|           </el-select> | ||||
|         </el-form-item> | ||||
|         <!-- <el-form-item label="设计状态" prop="designState"> | ||||
| @ -183,7 +184,9 @@ | ||||
|               <el-button link type="primary" icon="edit" @click="handleAudit(row)" v-if="row.auditStatus == 'draft' || row.auditStatus == 'back'" | ||||
|                 >审核</el-button | ||||
|               > | ||||
|               <el-button link type="primary" icon="View" v-if="row.status != 'draft'" @click="handleAuditView(row)">查看流程</el-button> | ||||
|               <el-button link type="primary" icon="View" v-if="row.status != '2' && row.auditStatus != 'draft'" @click="handleAuditView(row)" | ||||
|                 >查看流程</el-button | ||||
|               > | ||||
|               <el-button type="danger" link icon="Download" @click="handleDownload(row)"> 下载 </el-button> | ||||
|               <el-button | ||||
|                 type="warning" | ||||
|  | ||||
							
								
								
									
										176
									
								
								src/views/largeScreen/components/centerPage.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										176
									
								
								src/views/largeScreen/components/centerPage.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,176 @@ | ||||
| <template> | ||||
|   <div class="centerPage"> | ||||
|     <div class="centerPage_map"> | ||||
|       <div ref="mapRef" class="map-container" style="width: 100%; height: 100%" /> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script setup lang="ts"> | ||||
| // import { getPowerStationOverview } from '@/api/large'; | ||||
| import * as echarts from 'echarts'; | ||||
| import china from '@/assets/china.json'; | ||||
| const data = ref<any>({}); | ||||
|  | ||||
| // 地图容器引用 | ||||
| const mapRef = ref<HTMLDivElement | null>(null); | ||||
| // ECharts实例 | ||||
| let myChart: any = null; | ||||
|  | ||||
| // 响应窗口大小变化 | ||||
| const handleResize = () => { | ||||
|   if (myChart) { | ||||
|     myChart.resize(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| // 初始化地图 | ||||
| const initEcharts = () => { | ||||
|   if (!mapRef.value) { | ||||
|     console.error('未找到地图容器元素'); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   // 注册地图 | ||||
|   echarts.registerMap('china', china as any); | ||||
|  | ||||
|   // 地图数据 | ||||
|   const mapData: any = [{ name: '田东县', value: 1, itemStyle: { color: '#fff' } }]; | ||||
|  | ||||
|   // 散点数据 | ||||
|   // 散点数据 - 使用图片标记并调整名称位置 | ||||
|   const scatterData: any[] = [ | ||||
|     { | ||||
|       name: '田东光伏智慧生态工地开发项目', | ||||
|       value: [107.15, 23.63], | ||||
|       // 使用图片作为标记(注意:需替换为你的图片实际路径) | ||||
|       symbol: 'diamond', | ||||
|       // 标记颜色 | ||||
|       itemStyle: { | ||||
|         color: '#0166d6' | ||||
|       }, | ||||
|       // 图片标记大小(宽, 高) | ||||
|       symbolSize: [20, 20], | ||||
|       // 名称样式设置 | ||||
|       label: { | ||||
|         show: true, | ||||
|         formatter: '{b}', // 显示名称 | ||||
|         position: 'top', // 名称在图片上方 | ||||
|         color: '#fff', | ||||
|         fontSize: 12, | ||||
|         // 可选:添加文字背景以增强可读性 | ||||
|         backgroundColor: 'rgba(3, 26, 52, 0.7)', | ||||
|         padding: [3, 6], | ||||
|         borderRadius: 3 | ||||
|       } | ||||
|     } | ||||
|   ]; | ||||
|   // 初始化新实例,强制清除缓存 | ||||
|   myChart = echarts.init(mapRef.value, null, { | ||||
|     renderer: 'canvas', // 明确指定渲染器 | ||||
|     useDirtyRect: false // 禁用脏矩形渲染,避免样式缓存 | ||||
|   }); | ||||
|   // 配置项 | ||||
|   const option: any = { | ||||
|     roam: true, // 关键配置:允许鼠标滚轮缩放和拖拽平移 | ||||
|     geo: { | ||||
|       type: 'map', | ||||
|       map: 'china', | ||||
|       zoom: 5, | ||||
|       center: [107.15, 23.63], | ||||
|       label: { | ||||
|         show: false, | ||||
|         color: '#fff' | ||||
|       }, | ||||
|       itemStyle: { | ||||
|         areaColor: '#031a34', // 地图区域底色 | ||||
|         borderColor: '#1e3a6e', // 区域边框颜色 | ||||
|         borderWidth: 1 | ||||
|       } | ||||
|     }, | ||||
|     tooltip: { | ||||
|       trigger: 'item', | ||||
|       formatter: function (params: any) { | ||||
|         return params.name + (params.value ? `:${params.value}` : ''); | ||||
|       } | ||||
|     }, | ||||
|     series: [ | ||||
|       { | ||||
|         type: 'map', | ||||
|         map: 'china', | ||||
|         geoIndex: 0, | ||||
|         // 关键:在series级别定义emphasis,优先级最高 | ||||
|         emphasis: { | ||||
|           areaColor: '#fff', // 强制设置hover颜色 | ||||
|           label: { | ||||
|             show: true, | ||||
|             color: '#fff' | ||||
|           }, | ||||
|           itemStyle: { | ||||
|             areaColor: '#02417e' // 重复设置确保生效 | ||||
|           } | ||||
|         }, | ||||
|         // 确保没有使用默认样式 | ||||
|         select: { | ||||
|           itemStyle: { | ||||
|             areaColor: '#02417e' | ||||
|           } | ||||
|         }, | ||||
|         data: mapData | ||||
|       }, | ||||
|       { | ||||
|         type: 'scatter', | ||||
|         coordinateSystem: 'geo', | ||||
|         data: scatterData | ||||
|       } | ||||
|     ] | ||||
|   }; | ||||
|  | ||||
|   // 设置配置项 | ||||
|   myChart.setOption(option); | ||||
| }; | ||||
|  | ||||
| // 组件挂载时初始化 | ||||
| onMounted(() => { | ||||
|   // 确保DOM渲染完成 | ||||
|   nextTick(() => { | ||||
|     initEcharts(); | ||||
|     window.addEventListener('resize', handleResize); | ||||
|   }); | ||||
| }); | ||||
|  | ||||
| // 组件卸载时清理 | ||||
| onUnmounted(() => { | ||||
|   window.removeEventListener('resize', handleResize); | ||||
|   if (myChart) { | ||||
|     myChart.dispose(); | ||||
|     myChart = null; | ||||
|   } | ||||
| }); | ||||
| // const getDataList = () => { | ||||
| //   getPowerStationOverview().then((res) => { | ||||
| //     console.log(res); | ||||
| //     if (res.code == 200) { | ||||
| //       data.value = res.data; | ||||
| //     } | ||||
| //   }); | ||||
| // }; | ||||
| // getDataList(); | ||||
| </script> | ||||
|  | ||||
| <style scoped lang="scss"> | ||||
| .centerPage { | ||||
|   width: 100%; | ||||
|   height: 100%; | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   justify-content: space-between; | ||||
|   padding: 0 10px 10px 10px; | ||||
|  | ||||
|   box-sizing: border-box; | ||||
|   .centerPage_map { | ||||
|     width: 100%; | ||||
|     height: 100%; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										180
									
								
								src/views/largeScreen/components/header.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										180
									
								
								src/views/largeScreen/components/header.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,180 @@ | ||||
| <template> | ||||
|   <div class="header"> | ||||
|     <div class="header_left"> | ||||
|       <div class="header_left_img"> | ||||
|         <img src="@/assets/large/secure.png" style="width: 100%; height: 100%" /> | ||||
|       </div> | ||||
|       <div style="font-size: 12px; padding-left: 10px">安全生产天数:</div> | ||||
|       <div class="header_left_text"> | ||||
|         1,235 | ||||
|         <span style="font-size: 12px">天</span> | ||||
|       </div> | ||||
|     </div> | ||||
|     <div class="title"> | ||||
|       <div class="title_text">资金管理看板</div> | ||||
|       <div>Fund Management Dashboard</div> | ||||
|     </div> | ||||
|     <div class="right"> | ||||
|       <div class="top-bar"> | ||||
|         <!-- 左侧:天气图标 + 日期文字 --> | ||||
|         <div class="left-section"> | ||||
|           <img src="@/assets/large/weather.png" alt="天气图标" /> | ||||
|  | ||||
|           <span> | ||||
|             <span>多云 9°/18°</span> | ||||
|             <span style="padding-left: 20px"> {{ week[date.week] }} ({{ date.ymd }})</span> | ||||
|           </span> | ||||
|         </div> | ||||
|         <!-- 分割线 --> | ||||
|         <div class="divider"> | ||||
|           <div class="top-block"></div> | ||||
|           <div class="bottom-block"></div> | ||||
|         </div> | ||||
|         <!-- 右侧:管理系统图标 + 文字 --> | ||||
|         <div class="right-section"> | ||||
|           <img src="@/assets/large/setting.png" alt="设置图标" /> | ||||
|           <span>管理系统</span> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script setup lang="ts"> | ||||
| const week = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']; | ||||
| const date = ref({ | ||||
|   ymd: '', | ||||
|   hms: '', | ||||
|   week: 0 | ||||
| }); | ||||
| const setTime = () => { | ||||
|   let date1 = new Date(); | ||||
|   let year: any = date1.getFullYear(); | ||||
|   let month: any = date1.getMonth() + 1; | ||||
|   let day: any = date1.getDate(); | ||||
|   let hours: any = date1.getHours(); | ||||
|   if (hours < 10) { | ||||
|     hours = '0' + hours; | ||||
|   } | ||||
|   let minutes: any = date1.getMinutes(); | ||||
|   if (minutes < 10) { | ||||
|     minutes = '0' + minutes; | ||||
|   } | ||||
|   let seconds: any = date1.getSeconds(); | ||||
|   if (seconds < 10) { | ||||
|     seconds = '0' + seconds; | ||||
|   } | ||||
|   date.value.ymd = year + '-' + month + '-' + day; | ||||
|   date.value.hms = hours + ':' + minutes + ':' + seconds; | ||||
|   date.value.week = date1.getDay(); | ||||
| }; | ||||
| // 添加定时器,每秒更新一次时间 | ||||
| const timer = setInterval(setTime, 1000); | ||||
| // 组件卸载时清除定时器 | ||||
| onUnmounted(() => { | ||||
|   clearInterval(timer); | ||||
| }); | ||||
| </script> | ||||
|  | ||||
| <style scoped lang="scss"> | ||||
| .header { | ||||
|   width: 100%; | ||||
|   height: 80px; | ||||
|   box-sizing: border-box; | ||||
|   padding: 10px; | ||||
|   display: grid; | ||||
|   grid-template-columns: 1fr 1fr 1fr; | ||||
|   color: #fff; | ||||
| } | ||||
| .header_left { | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   .header_left_img { | ||||
|     width: 48px; | ||||
|     height: 48px; | ||||
|     box-sizing: border-box; | ||||
|     // padding-right: 10px; | ||||
|   } | ||||
|   .header_left_text { | ||||
|     font-weight: 500; | ||||
|     text-shadow: 0px 1.24px 6.21px rgba(25, 179, 250, 1); | ||||
|   } | ||||
| } | ||||
| .title { | ||||
|   color: #fff; | ||||
|   font-family: 'AlimamaShuHeiTi', sans-serif; | ||||
|   text-align: center; | ||||
| } | ||||
| .title > div:first-child { | ||||
|   /* 第一个子元素的样式 */ | ||||
|   font-size: 38px; | ||||
|   //   font-weight: 300; | ||||
| } | ||||
|  | ||||
| .title > div:last-child { | ||||
|   /* 最后一个子元素的样式 */ | ||||
|   font-size: 14px; | ||||
|   letter-spacing: 0.3em; /* 调整这个值来控制间距大小 */ | ||||
| } | ||||
| .right { | ||||
|   width: 100%; | ||||
|   height: 100%; | ||||
|   display: flex; | ||||
| } | ||||
| /* 顶部栏容器:Flex 水平布局 + 垂直居中 */ | ||||
| .top-bar { | ||||
|   width: 100%; | ||||
|   height: 100%; | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   justify-content: flex-end; | ||||
|   //   background-color: #1e2128; | ||||
|   color: #fff; | ||||
|   padding: 8px 16px; | ||||
|   font-size: 14px; | ||||
| } | ||||
| /* 左侧区域(天气 + 日期):自身也用 Flex 水平排列,确保元素在一行 */ | ||||
| .left-section { | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   //   margin-right: auto; /* 让右侧元素(管理系统)居右 */ | ||||
| } | ||||
| .left-section img { | ||||
|   width: 32px; | ||||
|   height: 32px; | ||||
|   margin-right: 8px; /* 图标与文字间距 */ | ||||
| } | ||||
| /* 分割线(视觉分隔,可根据需求调整样式) */ | ||||
| .divider { | ||||
|   display: grid; | ||||
|   grid-template-rows: 1fr 1fr; | ||||
|   height: 100%; /* 根据需要调整高度 */ | ||||
|   padding: 14px 10px; | ||||
| } | ||||
|  | ||||
| .divider .top-block { | ||||
|   width: 2px; | ||||
|   height: 7px; | ||||
|   background: #19b5fb; | ||||
|   align-self: start; | ||||
| } | ||||
|  | ||||
| .divider .bottom-block { | ||||
|   width: 2px; | ||||
|   height: 7px; | ||||
|   background: #19b5fb; | ||||
|   align-self: end; | ||||
| } | ||||
| /* 右侧区域(管理系统):图标 + 文字水平排列 */ | ||||
| .right-section { | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   font-family: 'AlimamaShuHeiTi', sans-serif; | ||||
|   font-size: 20px; | ||||
| } | ||||
| .right-section img { | ||||
|   width: 20px; | ||||
|   height: 20px; | ||||
|   margin-right: 6px; /* 图标与文字间距 */ | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										13
									
								
								src/views/largeScreen/components/leftPage.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/views/largeScreen/components/leftPage.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | ||||
| <template> | ||||
|   <div class="leftPage">左边</div> | ||||
| </template> | ||||
|  | ||||
| <script setup lang="ts"></script> | ||||
|  | ||||
| <style scoped lang="scss"> | ||||
| .leftPage { | ||||
|   width: 100%; | ||||
|   height: 100%; | ||||
|   background: #0c1e35; | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										735
									
								
								src/views/largeScreen/components/optionList.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										735
									
								
								src/views/largeScreen/components/optionList.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,735 @@ | ||||
| import * as echarts from 'echarts/core'; | ||||
| // import { PictorialBarChart } from 'echarts/charts' | ||||
| // 客流量图 | ||||
| export const getOption = (xData: any, yData: any) => { | ||||
|   const data = { | ||||
|     xData, | ||||
|     yData | ||||
|   }; | ||||
|   const maxData = Math.ceil(Math.max(...data.yData)); | ||||
|   const barData = data.yData.map((item) => { | ||||
|     return maxData; | ||||
|   }); | ||||
|   const option = { | ||||
|     grid: { | ||||
|       top: '10%', | ||||
|       left: '8%', | ||||
|       right: '5%', | ||||
|       bottom: '20%' | ||||
|       // containLabel: true | ||||
|     }, | ||||
|     xAxis: { | ||||
|       type: 'category', | ||||
|       data: data.xData, | ||||
|       axisLine: { | ||||
|         show: false | ||||
|       }, | ||||
|       axisTick: { | ||||
|         show: true | ||||
|       }, | ||||
|       axisLabel: { | ||||
|         textStyle: { | ||||
|           color: '#fff' | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     yAxis: { | ||||
|       show: true, | ||||
|       type: 'value', | ||||
|       max: maxData, | ||||
|       splitLine: { | ||||
|         show: true, | ||||
|         lineStyle: { | ||||
|           type: 'solid', | ||||
|           color: 'rgba(73, 169, 191, 0.2)' | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     tooltip: { | ||||
|       trigger: 'axis', | ||||
|       backgroundColor: '', | ||||
|       textStyle: { | ||||
|         color: '#fff' | ||||
|       } | ||||
|     }, | ||||
|     dataZoom: [ | ||||
|       { | ||||
|         // show: true, | ||||
|         start: 0, | ||||
|         end: 30, | ||||
|         bottom: 2, // 下滑块距离x轴底部的距离 | ||||
|         height: 23 | ||||
|       }, | ||||
|       { | ||||
|         type: 'inside' | ||||
|       } | ||||
|     ], | ||||
|     series: [ | ||||
|       { | ||||
|         name: '柱图', | ||||
|         type: 'bar', | ||||
|         // barWidth: '10%', | ||||
|         data: barData, | ||||
|         tooltip: { | ||||
|           show: false | ||||
|         }, | ||||
|         barGap: '-50%', | ||||
|         itemStyle: { | ||||
|           normal: { | ||||
|             color: 'rgba(73, 169, 191, 0.2)' | ||||
|           } | ||||
|         } | ||||
|       }, | ||||
|       { | ||||
|         name: '客单价', | ||||
|         type: 'line', | ||||
|         showAllSymbol: true, | ||||
|         symbol: 'circle', | ||||
|         symbolSize: 8, | ||||
|         lineStyle: { | ||||
|           normal: { | ||||
|             color: 'rgba(217, 231, 255, 0.3)', | ||||
|             shadowColor: 'rgba(0, 0, 0, .3)', | ||||
|             shadowBlur: 0 | ||||
|             // shadowOffsetY: 5, | ||||
|             // shadowOffsetX: 5, | ||||
|           } | ||||
|         }, | ||||
|         itemStyle: { | ||||
|           color: 'rgba(224, 194, 22, 1)', | ||||
|           borderWidth: 0, | ||||
|           shadowBlur: 0 | ||||
|         }, | ||||
|         label: { | ||||
|           show: false, // 显示数据标签 | ||||
|           color: 'rgba(255, 208, 59, 1)' | ||||
|         }, | ||||
|         data: data.yData | ||||
|       } | ||||
|     ] | ||||
|   }; | ||||
|   return option; | ||||
| }; | ||||
|  | ||||
| // 上菜分析图 | ||||
| export const getOption2 = (data: any) => { | ||||
|   const maxData = Math.max(...data.yData); | ||||
|   const option = { | ||||
|     // backgroundColor: "#38445E", | ||||
|     grid: { | ||||
|       left: '10%', | ||||
|       top: '13%', | ||||
|       bottom: '16%', | ||||
|       right: '10%' | ||||
|     }, | ||||
|     xAxis: { | ||||
|       data: data.xData, | ||||
|       axisTick: { | ||||
|         show: false | ||||
|       }, | ||||
|       axisLine: { | ||||
|         lineStyle: { | ||||
|           color: 'rgba(255, 129, 109, 0.1)', | ||||
|           width: 1 //这里是为了突出显示加上的 | ||||
|         } | ||||
|       }, | ||||
|       axisLabel: { | ||||
|         textStyle: { | ||||
|           color: '#999', | ||||
|           fontSize: 12 | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     yAxis: [ | ||||
|       { | ||||
|         splitNumber: 2, | ||||
|         axisTick: { | ||||
|           show: false | ||||
|         }, | ||||
|         axisLine: { | ||||
|           lineStyle: { | ||||
|             color: 'rgba(255, 129, 109, 0.1)', | ||||
|             width: 1 //这里是为了突出显示加上的 | ||||
|           } | ||||
|         }, | ||||
|         axisLabel: { | ||||
|           textStyle: { | ||||
|             color: '#999' | ||||
|           } | ||||
|         }, | ||||
|         splitArea: { | ||||
|           areaStyle: { | ||||
|             color: 'rgba(255,255,255,.5)' | ||||
|           } | ||||
|         }, | ||||
|         splitLine: { | ||||
|           show: true, | ||||
|           lineStyle: { | ||||
|             color: 'rgba(255,255,255,.5)', | ||||
|             width: 0.5, | ||||
|             type: 'dashed' | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     ], | ||||
|     dataZoom: [ | ||||
|       { | ||||
|         // show: true, | ||||
|  | ||||
|         start: 0, | ||||
|         end: 30, | ||||
|         bottom: 2, // 下滑块距离x轴底部的距离 | ||||
|         height: 23 | ||||
|       }, | ||||
|       { | ||||
|         type: 'inside' | ||||
|       } | ||||
|     ], | ||||
|     tooltip: { | ||||
|       trigger: 'axis', // 设置为 'item',表示鼠标悬浮在图形上时显示 tooltip | ||||
|       // formatter: function (params) { | ||||
|       //   return `订单数: ${params.data}` // 显示鼠标悬浮项的数量 | ||||
|       // }, | ||||
|       backgroundColor: '', // 设置提示框的背景颜色 | ||||
|       textStyle: { | ||||
|         color: '#fff' // 设置文字颜色 | ||||
|         // fontSize: 14 // 设置文字大小 | ||||
|       } | ||||
|     }, | ||||
|     series: [ | ||||
|       { | ||||
|         name: '订单数', | ||||
|         type: 'pictorialBar', | ||||
|         barCategoryGap: '0%', | ||||
|         symbol: 'path://M0,10 L10,10 C5.5,10 5.5,5 5,0 C4.5,5 4.5,10 0,10 z', | ||||
|         label: { | ||||
|           show: false, | ||||
|           position: 'top', | ||||
|           distance: 15, | ||||
|           color: 'rgba(255, 235, 59, 1)', | ||||
|           // fontWeight: "bolder", | ||||
|           fontSize: 16 | ||||
|         }, | ||||
|         itemStyle: { | ||||
|           normal: { | ||||
|             // color: { | ||||
|             //   type: "linear", | ||||
|             //   x: 0, | ||||
|             //   y: 0, | ||||
|             //   x2: 0, | ||||
|             //   y2: 1, | ||||
|             //   colorStops: [ | ||||
|             //     { | ||||
|             //       offset: 0, | ||||
|             //       color: "rgba(232, 94, 106, .8)", //  0%  处的颜色 | ||||
|             //     }, | ||||
|             //     { | ||||
|             //       offset: 1, | ||||
|             //       color: "rgba(232, 94, 106, .1)", //  100%  处的颜色 | ||||
|             //     }, | ||||
|             //   ], | ||||
|             //   global: false, //  缺省为  false | ||||
|             // }, | ||||
|             color: function (params: any) { | ||||
|               if (params.data === maxData) { | ||||
|                 return 'rgba(255, 219, 103, 0.6)'; | ||||
|               } else { | ||||
|                 return 'rgba(239, 244, 255, 0.45)'; | ||||
|               } | ||||
|             } | ||||
|           }, | ||||
|           emphasis: { | ||||
|             opacity: 1 | ||||
|           } | ||||
|         }, | ||||
|         data: data.yData, | ||||
|         z: 10 | ||||
|       } | ||||
|     ] | ||||
|   }; | ||||
|   return option; | ||||
| }; | ||||
| //食堂周报图 | ||||
| export const getLineOption = (lineData: any) => { | ||||
|   const maxData = Math.ceil(Math.max(...lineData.line1)); | ||||
|   const option = { | ||||
|     backgroundColor: '', | ||||
|     tooltip: { | ||||
|       trigger: 'axis', | ||||
|       backgroundColor: 'transparent', | ||||
|       color: '#7ec7ff', | ||||
|       textStyle: { | ||||
|         color: '#fff' | ||||
|       }, | ||||
|       borderColor: '#7ec7ff' | ||||
|     }, | ||||
|     // legend: { | ||||
|     //   align: 'left', | ||||
|     //   right: '5%', | ||||
|     //   top: '1%', | ||||
|     //   type: 'plain', | ||||
|     //   textStyle: { | ||||
|     //     color: '#fff', | ||||
|     //     fontSize: 12 | ||||
|     //   }, | ||||
|     //   // icon:'rect', | ||||
|     //   itemGap: 15, | ||||
|     //   itemWidth: 18, | ||||
|     //   data: [ | ||||
|     //     { | ||||
|     //       name: '上周销售量' | ||||
|     //     }, | ||||
|     //     { | ||||
|     //       name: '本周销售量' | ||||
|     //     } | ||||
|     //   ] | ||||
|     // }, | ||||
|     grid: { | ||||
|       top: '12%', | ||||
|       left: '1%', | ||||
|       right: '3%', | ||||
|       bottom: '12%', | ||||
|       containLabel: true | ||||
|     }, | ||||
|     xAxis: { | ||||
|       type: 'category', | ||||
|       data: lineData.xLabel, | ||||
|       axisLine: { | ||||
|         show: false | ||||
|       }, | ||||
|       axisTick: { | ||||
|         show: true | ||||
|       }, | ||||
|       axisLabel: { | ||||
|         textStyle: { | ||||
|           color: '#fff' | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     yAxis: { | ||||
|       show: true, | ||||
|       type: 'value', | ||||
|       max: maxData, | ||||
|       splitLine: { | ||||
|         show: true, | ||||
|         lineStyle: { | ||||
|           type: 'solid', | ||||
|           color: 'rgba(73, 169, 191, 0.2)' | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     dataZoom: [ | ||||
|       { | ||||
|         // show: true, | ||||
|         start: 0, | ||||
|         end: 30, | ||||
|         bottom: 2, // 下滑块距离x轴底部的距离 | ||||
|         height: 23 | ||||
|       }, | ||||
|       { | ||||
|         type: 'inside' | ||||
|       } | ||||
|     ], | ||||
|     series: [ | ||||
|       { | ||||
|         name: '逆变器功率', | ||||
|         type: 'line', | ||||
|         symbol: 'circle', // 默认是空心圆(中间是白色的),改成实心圆 | ||||
|         showAllSymbol: false, | ||||
|         symbolSize: 0, | ||||
|         smooth: true, | ||||
|         lineStyle: { | ||||
|           width: 1, | ||||
|           color: 'rgba(80, 164, 225, 1)', // 线条颜色 | ||||
|           borderColor: 'rgba(0,0,0,.4)' | ||||
|         }, | ||||
|         itemStyle: { | ||||
|           color: 'rgba(80, 164, 225, 1)', | ||||
|           borderWidth: 2, | ||||
|           show: false | ||||
|         }, | ||||
|         tooltip: { | ||||
|           show: true | ||||
|         }, | ||||
|         areaStyle: { | ||||
|           //线性渐变,前4个参数分别是x0,y0,x2,y2(范围0~1);相当于图形包围盒中的百分比。如果最后一个参数是‘true’,则该四个值是绝对像素位置。 | ||||
|           color: new echarts.graphic.LinearGradient( | ||||
|             0, | ||||
|             0, | ||||
|             0, | ||||
|             1, | ||||
|             [ | ||||
|               { | ||||
|                 offset: 0, | ||||
|                 color: 'rgba(80, 164, 225, 0.4)' | ||||
|               }, | ||||
|               { | ||||
|                 offset: 1, | ||||
|                 color: 'rgba(80, 164, 225, 0)' | ||||
|               } | ||||
|             ], | ||||
|             false | ||||
|           ), | ||||
|           shadowColor: 'rgba(25,163,223, 0.5)', //阴影颜色 | ||||
|           shadowBlur: 20 //shadowBlur设图形阴影的模糊大小。配合shadowColor,shadowOffsetX/Y, 设置图形的阴影效果。 | ||||
|         }, | ||||
|         data: lineData.line1 | ||||
|       } | ||||
|     ] | ||||
|   }; | ||||
|   return option; | ||||
| }; | ||||
| //#endregion | ||||
|  | ||||
| // 菜品销售图 | ||||
| export const getDishesOption = (data?: any) => { | ||||
|   const res = data; | ||||
|   const dataIndex = 1; | ||||
|   const option = { | ||||
|     xAxis: { | ||||
|       type: 'value', | ||||
|       axisTick: { | ||||
|         show: false | ||||
|       }, | ||||
|       splitLine: { | ||||
|         show: false | ||||
|       }, | ||||
|       axisLabel: { | ||||
|         show: false | ||||
|       } | ||||
|     }, | ||||
|     yAxis: { | ||||
|       type: 'category', | ||||
|       axisTick: { | ||||
|         show: false | ||||
|       }, | ||||
|       axisLabel: { | ||||
|         margin: 10 // 增大标签与轴线间距 | ||||
|       }, | ||||
|       width: 60, // 增大Y轴宽度 | ||||
|       data: res.name, | ||||
|       axisLine: { | ||||
|         lineStyle: { | ||||
|           color: '#93C9C3' | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     grid: { | ||||
|       top: '5%', // 设置网格区域与容器之间的边距 | ||||
|       bottom: '5%', // 同理 | ||||
|       left: '5%', | ||||
|       containLabel: true | ||||
|     }, | ||||
|     series: [ | ||||
|       { | ||||
|         type: 'bar', | ||||
|         data: res.ratio, | ||||
|         barMaxWidth: 25, | ||||
|         itemStyle: { | ||||
|           barBorderRadius: 3, | ||||
|           color: 'rgba(12, 242, 216, 0.2)' | ||||
|         }, | ||||
|         label: { | ||||
|           show: false | ||||
|         } | ||||
|       }, | ||||
|       { | ||||
|         type: 'bar', | ||||
|         data: res.data, | ||||
|         barGap: '-100%', | ||||
|         barMaxWidth: 25, | ||||
|         itemStyle: { | ||||
|           barBorderRadius: 3, | ||||
|           color: function (params: any) { | ||||
|             if (params.data <= 300) { | ||||
|               return new echarts.graphic.LinearGradient(1, 0, 0, 0, [ | ||||
|                 { color: 'rgba(252, 105, 0, 1)', offset: 0 }, | ||||
|                 { color: 'rgba(250, 42, 42, 1)', offset: 1 } | ||||
|               ]); | ||||
|             } else { | ||||
|               return new echarts.graphic.LinearGradient(1, 0, 0, 0, [ | ||||
|                 { color: 'rgba(73, 169, 191, 1)', offset: 0 }, | ||||
|                 { color: 'rgba(108, 248, 236, 1)', offset: 1 } | ||||
|               ]); | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         label: { | ||||
|           show: true, | ||||
|           position: [200, -15], | ||||
|           formatter: function (params: any) { | ||||
|             if (params.data <= 300) { | ||||
|               return `{a| ${params.value}g/${res.ratio[params.dataIndex]}g}`; | ||||
|             } else { | ||||
|               return `{b| ${params.value}g/${res.ratio[params.dataIndex]}g}`; | ||||
|             } | ||||
|           }, | ||||
|           rich: { | ||||
|             a: { | ||||
|               color: 'rgba(255, 78, 51, 1)' | ||||
|             }, | ||||
|             b: { | ||||
|               color: 'rgba(255, 235, 59, 1)' | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     ] | ||||
|   }; | ||||
|   return option; | ||||
| }; | ||||
| // 菜品库存图 | ||||
| export const getInventoryOption = () => { | ||||
|   const res = { | ||||
|       data: [2800, 300, 3900, 3000, 2450, 2670, 3320], | ||||
|       name: ['麻辣牛肉', '水煮肉片', '酸菜鱼', '辣子鸡丁', '烧白', '冬瓜排骨汤', '清炒油麦菜'], | ||||
|       ratio: [4000, 4000, 4000, 4000, 4000, 4000, 4000] | ||||
|     }, | ||||
|     dataIndex = 1; | ||||
|   const option = { | ||||
|     xAxis: { | ||||
|       type: 'value', | ||||
|       axisTick: { | ||||
|         show: false | ||||
|       }, | ||||
|       splitLine: { | ||||
|         show: false | ||||
|       }, | ||||
|       axisLabel: { | ||||
|         show: false | ||||
|       } | ||||
|     }, | ||||
|     yAxis: { | ||||
|       type: 'category', | ||||
|       show: false, | ||||
|       axisTick: { | ||||
|         show: false | ||||
|       }, | ||||
|       axisLabel: { | ||||
|         margin: 10 // 增大标签与轴线间距 | ||||
|       }, | ||||
|       width: 20, // 增大Y轴宽度 | ||||
|       data: res.name, | ||||
|       axisLine: { | ||||
|         show: false, | ||||
|         lineStyle: { | ||||
|           color: '#93C9C3' | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     grid: { | ||||
|       top: '5%', // 设置网格区域与容器之间的边距 | ||||
|       bottom: '5%', // 同理 | ||||
|       left: '5%', | ||||
|       containLabel: true | ||||
|     }, | ||||
|     series: [ | ||||
|       { | ||||
|         type: 'bar', | ||||
|         data: res.ratio, | ||||
|         barMaxWidth: 6, | ||||
|         itemStyle: { | ||||
|           barBorderRadius: 3, | ||||
|           color: 'rgba(12, 242, 216, 0.2)' | ||||
|         }, | ||||
|         label: { | ||||
|           show: true, | ||||
|           position: [0, -15], | ||||
|           fontSize: 14, | ||||
|           color: '#fff', | ||||
|           formatter: function (params: any) { | ||||
|             return params.name; | ||||
|           } | ||||
|           // rich: { | ||||
|           //   a: { | ||||
|           //     color: "rgba(255, 78, 51, 1)", | ||||
|           //   }, | ||||
|           //   b: { | ||||
|           //     color: "rgba(255, 235, 59, 1)", | ||||
|           //   }, | ||||
|           // }, | ||||
|         } | ||||
|       }, | ||||
|       { | ||||
|         type: 'bar', | ||||
|         data: res.data, | ||||
|         barGap: '-100%', | ||||
|         barMaxWidth: 6, | ||||
|         itemStyle: { | ||||
|           barBorderRadius: 0, | ||||
|           color: function (params: any) { | ||||
|             if (params.dataIndex === dataIndex) { | ||||
|               return new echarts.graphic.LinearGradient(1, 0, 0, 0, [ | ||||
|                 { color: 'rgba(255, 78, 51, 1)', offset: 0 }, | ||||
|                 { color: 'rgba(252, 105, 0, 0)', offset: 1 } | ||||
|               ]); | ||||
|             } else { | ||||
|               return new echarts.graphic.LinearGradient(1, 0, 0, 0, [ | ||||
|                 { color: 'rgba(242, 224, 27, 1)', offset: 0 }, | ||||
|                 { color: 'rgba(236, 227, 127, 0.55)', offset: 0.5 }, | ||||
|                 { color: 'rgba(230, 229, 227, 0.1)', offset: 1 } | ||||
|               ]); | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         label: { | ||||
|           show: true, | ||||
|           position: [200, -15], | ||||
|           formatter: function (params: any) { | ||||
|             if (params.dataIndex === dataIndex) { | ||||
|               return `{a| ${params.value}g}`; | ||||
|             } else { | ||||
|               return `{b| ${params.value}g}`; | ||||
|             } | ||||
|           }, | ||||
|           rich: { | ||||
|             a: { | ||||
|               color: 'rgba(255, 78, 51, 1)' | ||||
|             }, | ||||
|             b: { | ||||
|               color: 'rgba(255, 235, 59, 1)' | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     ] | ||||
|   }; | ||||
|   return option; | ||||
| }; | ||||
| export const getBarOptions = (data: any) => { | ||||
|   const option = { | ||||
|     backgroundColor: '', | ||||
|     grid: { | ||||
|       left: '7%', | ||||
|       top: '4%', | ||||
|       bottom: '25%', | ||||
|       right: '2%' | ||||
|     }, | ||||
|     tooltip: { | ||||
|       show: true, | ||||
|       backgroundColor: '', | ||||
|       trigger: 'axis', | ||||
|       formatter: '{b0}:{c0}元', | ||||
|       textStyle: { | ||||
|         color: '#fff' | ||||
|       } | ||||
|       // borderColor: 'rgba(252, 217, 18, 1)' | ||||
|     }, | ||||
|     xAxis: [ | ||||
|       { | ||||
|         type: 'category', | ||||
|         data: data.name, | ||||
|         axisLine: { | ||||
|           lineStyle: { | ||||
|             color: 'rgba(108, 128, 151, 0.3)' | ||||
|           } | ||||
|         }, | ||||
|         axisLabel: { | ||||
|           textStyle: { | ||||
|             color: '#999', | ||||
|             fontSize: 12 | ||||
|           } | ||||
|         }, | ||||
|         axisTick: { | ||||
|           // show: true, | ||||
|         }, | ||||
|         splitLine: { | ||||
|           show: true, | ||||
|           lineStyle: { | ||||
|             color: 'rgba(108, 128, 151, 0.3)', | ||||
|             type: 'dashed' | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     ], | ||||
|     yAxis: [ | ||||
|       { | ||||
|         axisLabel: { | ||||
|           formatter: function (value) { | ||||
|             if (value >= 1000) { | ||||
|               value = (value / 1000).toFixed(1) + 'k'; // 大于等于1000的数字显示为1k、2.5k等 | ||||
|             } | ||||
|             return value; | ||||
|           }, | ||||
|           color: 'rgba(255, 255, 255, 0.8)' | ||||
|         }, | ||||
|         axisTick: { | ||||
|           show: false | ||||
|         }, | ||||
|         axisLine: { | ||||
|           lineStyle: { | ||||
|             color: 'rgba(108, 128, 151, 0.3)' | ||||
|           } | ||||
|         }, | ||||
|         splitLine: { | ||||
|           show: true, | ||||
|           lineStyle: { | ||||
|             color: 'rgba(108, 128, 151, 0.3)', | ||||
|             type: 'dashed' | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     ], | ||||
|     dataZoom: [ | ||||
|       { | ||||
|         // show: true, | ||||
|         start: 0, | ||||
|         end: 30, | ||||
|         bottom: 2, // 下滑块距离x轴底部的距离 | ||||
|         height: 23 | ||||
|       }, | ||||
|       { | ||||
|         type: 'inside' | ||||
|       } | ||||
|     ], | ||||
|     series: [ | ||||
|       { | ||||
|         type: 'bar', | ||||
|         data: data.value, | ||||
|         stack: '合并', | ||||
|         barWidth: '15', | ||||
|         itemStyle: { | ||||
|           color: new echarts.graphic.LinearGradient( | ||||
|             0, | ||||
|             0, | ||||
|             0, | ||||
|             1, | ||||
|             [ | ||||
|               { | ||||
|                 offset: 0, | ||||
|                 color: 'rgba(0, 111, 255, 0)' // 0% 处的颜色 | ||||
|               }, | ||||
|               { | ||||
|                 offset: 0.7, | ||||
|                 color: 'rgba(0, 111, 255, 0.5)' // 0% 处的颜色 | ||||
|               }, | ||||
|               { | ||||
|                 offset: 1, | ||||
|                 color: 'rgba(0, 111, 255, 1)' // 100% 处的颜色 | ||||
|               } | ||||
|             ], | ||||
|             false | ||||
|           ) | ||||
|         }, | ||||
|         label: { | ||||
|           show: true, | ||||
|           formatter: '{c}', | ||||
|           position: 'top', | ||||
|           color: '#fff', | ||||
|           fontSize: 10 | ||||
|           // padding: 5 | ||||
|         } | ||||
|       } | ||||
|       // { | ||||
|       //   type: 'bar', | ||||
|       //   stack: '合并', | ||||
|       //   data: topData, | ||||
|       //   barWidth: '15', | ||||
|       //   itemStyle: { | ||||
|       //     color: 'rgba(252, 217, 18, 1)' | ||||
|       //   } | ||||
|       // } | ||||
|     ] | ||||
|   }; | ||||
|   return option; | ||||
| }; | ||||
							
								
								
									
										13
									
								
								src/views/largeScreen/components/rightPage.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/views/largeScreen/components/rightPage.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | ||||
| <template> | ||||
|   <div class="rightPage">右边</div> | ||||
| </template> | ||||
|  | ||||
| <script setup lang="ts"></script> | ||||
|  | ||||
| <style scoped lang="scss"> | ||||
| .rightPage { | ||||
|   width: 100%; | ||||
|   height: 100%; | ||||
|   background: #0c1e35; | ||||
| } | ||||
| </style> | ||||
							
								
								
									
										43
									
								
								src/views/largeScreen/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/views/largeScreen/index.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | ||||
| <template> | ||||
|   <div class="large-screen"> | ||||
|     <Header /> | ||||
|     <div class="nav"> | ||||
|       <div class="nav_left"> | ||||
|         <leftPage /> | ||||
|       </div> | ||||
|       <div class="nav_center"> | ||||
|         <centerPage /> | ||||
|       </div> | ||||
|       <div class="nav_right"> | ||||
|         <rightPage /> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script setup lang="ts"> | ||||
| import Header from './components/header.vue'; | ||||
| import leftPage from './components/leftPage.vue'; | ||||
| import centerPage from './components/centerPage.vue'; | ||||
| import rightPage from './components/rightPage.vue'; | ||||
| // import '@/assets/styles/element.scss'; | ||||
| </script> | ||||
|  | ||||
| <style scoped lang="scss"> | ||||
| .large-screen { | ||||
|   width: 100vw; | ||||
|   height: 100vh; | ||||
|   background: url('@/assets/large/bg.png') no-repeat; | ||||
|   background-size: 100% 100%; | ||||
|   background-color: rgba(4, 7, 17, 1); | ||||
| } | ||||
| .nav { | ||||
|   width: 100%; | ||||
|   height: calc(100vh - 80px); | ||||
|   box-sizing: border-box; | ||||
|   //   padding: 10px; | ||||
|   display: grid; | ||||
|   grid-template-columns: 1fr 2fr 1fr; | ||||
|   color: #fff; | ||||
| } | ||||
| </style> | ||||
| @ -73,7 +73,7 @@ | ||||
|     </el-form> | ||||
|     <!--  底部  --> | ||||
|     <div class="el-login-footer"> | ||||
|       <span>Copyright © 2018-2024 疯狂的狮子Li All Rights Reserved.</span> | ||||
|       <!-- <span></span> --> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
| @ -95,8 +95,8 @@ const { t } = useI18n(); | ||||
|  | ||||
| const loginForm = ref<LoginData>({ | ||||
|   tenantId: '000000', | ||||
|   username: 'admin', | ||||
|   password: 'admin123', | ||||
|   username: '', | ||||
|   password: '', | ||||
|   rememberMe: false, | ||||
|   code: '', | ||||
|   uuid: '' | ||||
|  | ||||
| @ -63,7 +63,7 @@ | ||||
|         <el-table-column label="供货单位" align="center" prop="supplierUnit" /> | ||||
|         <el-table-column label="设备材料入库/移交" align="center" prop="storageType"> | ||||
|           <template #default="scope"> | ||||
|             <dict-tag :options="storage_type" :value="scope.row.storageType ? scope.row.storageType.split(',') : []" /> | ||||
|             <dict-tag :options="storage_type" :value="scope.row.storageType" /> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|         <el-table-column label="备注" align="center" prop="remark" /> | ||||
| @ -236,11 +236,16 @@ | ||||
|           </el-col> | ||||
|           <el-col :span="24"> | ||||
|             <el-form-item label="设备材料入库/移交" prop="storageType"> | ||||
|               <el-checkbox-group v-model="form.storageType"> | ||||
|               <el-radio-group v-model="form.storageType"> | ||||
|                 <el-radio v-for="dict in storage_type" :key="dict.value" :label="dict.value"> | ||||
|                   {{ dict.label }} | ||||
|                 </el-radio> | ||||
|               </el-radio-group> | ||||
|               <!-- <el-checkbox-group v-model="form.storageType"> | ||||
|                 <el-checkbox v-for="dict in storage_type" :key="dict.value" :label="dict.value"> | ||||
|                   {{ dict.label }} | ||||
|                 </el-checkbox> | ||||
|               </el-checkbox-group> | ||||
|               </el-checkbox-group> --> | ||||
|             </el-form-item> </el-col | ||||
|           ><el-col :span="24" | ||||
|             ><el-form-item label="备注" prop="remark"> | ||||
| @ -318,7 +323,7 @@ const getInitFormData = () => { | ||||
|     techDocCountFileId: undefined, | ||||
|     licenseCount: undefined, | ||||
|     licenseCountFileId: undefined, | ||||
|     storageType: [], | ||||
|     storageType: '', | ||||
|     remark: undefined, | ||||
|     docId: undefined, | ||||
|     docCode: undefined, | ||||
| @ -426,12 +431,6 @@ const handleUpdate = async (row?: MaterialReceiveVO) => { | ||||
|   const _id = row?.id || ids.value[0]; | ||||
|   const res = await getMaterialReceive(_id); | ||||
|   Object.assign(form.value, res.data); | ||||
|   if (form.value.storageType && form.value.storageType.length) { | ||||
|     form.value.storageType = form.value.storageType.split(','); | ||||
|   } else { | ||||
|     form.value.storageType = []; | ||||
|   } | ||||
|  | ||||
|   // 为每个条目添加监听 | ||||
|   form.value.itemList.forEach((_, index) => { | ||||
|     watchItemChanges(index); | ||||
| @ -446,11 +445,10 @@ const submitForm = () => { | ||||
|   materialReceiveFormRef.value?.validate(async (valid: boolean) => { | ||||
|     if (valid) { | ||||
|       buttonLoading.value = true; | ||||
|       form.value.storageType = form.value.storageType.join(','); | ||||
|       if (form.value.id) { | ||||
|         await updateMaterialReceive(form.value).finally(() => (buttonLoading.value = false)); | ||||
|         await updateMaterialReceive({ ...form.value }).finally(() => (buttonLoading.value = false)); | ||||
|       } else { | ||||
|         await addMaterialReceive(form.value).finally(() => (buttonLoading.value = false)); | ||||
|         await addMaterialReceive({ ...form.value }).finally(() => (buttonLoading.value = false)); | ||||
|       } | ||||
|       proxy?.$modal.msgSuccess('操作成功'); | ||||
|       dialog.visible = false; | ||||
|  | ||||
| @ -81,10 +81,10 @@ | ||||
|                 <td colspan="8"> | ||||
|                   <span>是否附带以下随机资料</span> | ||||
|                   <div class="file_detail"> | ||||
|                     <span>(1) 合格证 {{ formData.certCount ? formData.certCount : 0 }} 份</span> | ||||
|                     <span>(2) 出厂报告 {{ formData.reportCount ? formData.reportCount : 0 }} 份</span> | ||||
|                     <span>(3) 技术资料文件 {{ formData.techDocCount ? formData.techDocCount : 0 }} 份</span> | ||||
|                     <span>(4) 厂家资质文件 {{ formData.licenseCount ? formData.licenseCount : 0 }} 份</span> | ||||
|                     <span>(1) 合格证 {{ formData.certCountFile ? formData.certCountFile.length : 0 }} 份</span> | ||||
|                     <span>(2) 出厂报告 {{ formData.reportCountFileId ? formData.reportCountFile.length : 0 }} 份</span> | ||||
|                     <span>(3) 技术资料文件 {{ formData.techDocCountFileId ? formData.techDocCountFile.length : 0 }} 份</span> | ||||
|                     <span>(4) 厂家资质文件 {{ formData.licenseCountFileId ? formData.licenseCountFile.length : 0 }} 份</span> | ||||
|                   </div> | ||||
|                 </td> | ||||
|               </tr> | ||||
|  | ||||
| @ -334,6 +334,9 @@ const data = reactive({ | ||||
|   }, | ||||
|   rules: { | ||||
|     id: [{ required: true, message: '主键ID不能为空', trigger: 'blur' }], | ||||
|     docCode: [{ required: true, message: '采购单编号不能为空', trigger: 'blur' }], | ||||
|     planId: [{ required: true, message: '需求计划不能为空', trigger: 'blur' }], | ||||
|     mrpBaseId: [{ required: true, message: '需求批次号不能为空', trigger: 'blur' }], | ||||
|     // 电话号码验证 | ||||
|     technicalDirectorTel: [ | ||||
|       { required: true, message: '请输入电话', trigger: 'blur' }, | ||||
|  | ||||
| @ -296,7 +296,7 @@ const submitCallback = async () => { | ||||
| }; | ||||
| //审批 | ||||
| const approvalVerifyOpen = async () => { | ||||
|   submitVerifyRef.value.openDialog(routeParams.value.taskId, true, routeParams.value.businessId); | ||||
|   submitVerifyRef.value.openDialog(routeParams.value.taskId, false, routeParams.value.businessId); | ||||
|   // submitVerifyRef.value.openDialog(routeParams.value.taskId); | ||||
| }; | ||||
| // 图纸上传成功之后 开始提交 | ||||
|  | ||||
| @ -67,7 +67,7 @@ | ||||
|     </el-form> | ||||
|     <!--  底部  --> | ||||
|     <div class="el-register-footer"> | ||||
|       <span>Copyright © 2018-2024 疯狂的狮子Li All Rights Reserved.</span> | ||||
|       <span></span> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
		Reference in New Issue
	
	Block a user