Merge branch 'lt' of https://gitee.com/TheNightHunters/plus-ui into ljj
This commit is contained in:
		| @ -23,7 +23,7 @@ | ||||
|           <el-form | ||||
|             ref="leaveFormRef" | ||||
|             v-loading="loading" | ||||
|             :disabled="routeParams.type === 'view'" | ||||
|             :disabled="routeParams.type === 'view' || form.status == 'waiting'" | ||||
|             :model="form" | ||||
|             :rules="rules" | ||||
|             label-width="100px" | ||||
|  | ||||
| @ -8,7 +8,6 @@ | ||||
|         <el-button @click="disabledForm = false" class="px-8 py-2.5 transition-all duration-300 font-medium" v-if="disabledForm"> | ||||
|           点击编辑 | ||||
|         </el-button> | ||||
|         <!-- ,带 <span class="text-red-300">*</span> 为必填项 --> | ||||
|       </div> | ||||
|       <!-- 表单内容区域 --> | ||||
|       <el-form ref="leaveFormRef" :model="form" :disabled="disabledForm" :rules="rules" label-width="120px" class="p-6 space-y-6"> | ||||
| @ -46,15 +45,23 @@ | ||||
|               class="flex-1 mr-3" | ||||
|             > | ||||
|               <div class="grid grid-cols-1 md:grid-cols-2 gap-4"> | ||||
|                 <!-- 设计人员专业选择(绑定重复校验) --> | ||||
|                 <el-select | ||||
|                   v-model="designer.userMajor" | ||||
|                   placeholder="请选择专业" | ||||
|                   class="transition-all duration-300 border-gray-300" | ||||
|                   :rules="{ required: true, message: '请选择专业', trigger: 'change' }" | ||||
|                   @change="() => checkDuplicate(designer, 'designers', index)" | ||||
|                 > | ||||
|                   <el-option v-for="item in des_user_major" :key="item.value" :label="item.label" :value="item.value" /> | ||||
|                 </el-select> | ||||
|                 <el-select v-model="designer.userId" placeholder="请选择设计人员" class="transition-all duration-300 border-gray-300"> | ||||
|                 <!-- 设计人员选择(绑定重复校验) --> | ||||
|                 <el-select | ||||
|                   v-model="designer.userId" | ||||
|                   placeholder="请选择设计人员" | ||||
|                   class="transition-all duration-300 border-gray-300" | ||||
|                   @change="() => checkDuplicate(designer, 'designers', index)" | ||||
|                 > | ||||
|                   <el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" /> | ||||
|                 </el-select> | ||||
|               </div> | ||||
| @ -97,15 +104,23 @@ | ||||
|               class="flex-1 mr-3" | ||||
|             > | ||||
|               <div class="grid grid-cols-1 md:grid-cols-2 gap-4"> | ||||
|                 <!-- 校审人员专业选择(绑定重复校验) --> | ||||
|                 <el-select | ||||
|                   v-model="reviewer.userMajor" | ||||
|                   placeholder="请选择专业" | ||||
|                   class="transition-all duration-300 border-gray-300" | ||||
|                   :rules="{ required: true, message: '请选择专业', trigger: 'change' }" | ||||
|                   @change="() => checkDuplicate(reviewer, 'reviewers', index)" | ||||
|                 > | ||||
|                   <el-option v-for="item in des_user_major" :key="item.value" :label="item.label" :value="item.value" /> | ||||
|                 </el-select> | ||||
|                 <el-select v-model="reviewer.userId" placeholder="请选择校审人员" class="transition-all duration-300 border-gray-300"> | ||||
|                 <!-- 校审人员选择(绑定重复校验) --> | ||||
|                 <el-select | ||||
|                   v-model="reviewer.userId" | ||||
|                   placeholder="请选择校审人员" | ||||
|                   class="transition-all duration-300 border-gray-300" | ||||
|                   @change="() => checkDuplicate(reviewer, 'reviewers', index)" | ||||
|                 > | ||||
|                   <el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" /> | ||||
|                 </el-select> | ||||
|               </div> | ||||
| @ -146,7 +161,7 @@ | ||||
| </template> | ||||
|  | ||||
| <script setup name="PersonnelForm" lang="ts"> | ||||
| import { ref, reactive, computed, onMounted, toRefs } from 'vue'; | ||||
| import { ref, reactive, computed, onMounted, toRefs, watch, WatchStopHandle } from 'vue'; | ||||
| import { getCurrentInstance } from 'vue'; | ||||
| import type { ComponentInternalInstance } from 'vue'; | ||||
| import { useUserStoreHook } from '@/store/modules/user'; | ||||
| @ -184,11 +199,11 @@ const userList = ref([]); | ||||
| // 表单引用 | ||||
| const leaveFormRef = ref(); | ||||
| const disabledForm = ref(false); //控制提交按钮状态 | ||||
|  | ||||
| /** 查询当前部门的所有用户 */ | ||||
| const getDeptAllUser = async (deptId: any) => { | ||||
|   try { | ||||
|     const res = await systemUserList({ deptId }); | ||||
|     // 实际项目中使用接口返回的数据 | ||||
|     userList.value = res.rows; | ||||
|   } catch (error) { | ||||
|     ElMessage.error('获取用户列表失败'); | ||||
| @ -217,37 +232,20 @@ const designUser = async () => { | ||||
|       // 处理返回的数据,进行回显 | ||||
|       res.rows.forEach((item: any) => { | ||||
|         if (item.userType == 1) { | ||||
|           item.userType = 'designLeader'; | ||||
|           form.designLeader = item.userId; | ||||
|         } else if (item.userType == 2) { | ||||
|           item.userType = 'designer'; | ||||
|           form.designers.push({ | ||||
|             userId: item.userId, | ||||
|             userMajor: item.userMajor || null | ||||
|           }); | ||||
|         } else if (item.userType == 3) { | ||||
|           item.userType = 'reviewer'; | ||||
|         } | ||||
|         // 根据userType区分不同类型的人员 | ||||
|         switch (item.userType) { | ||||
|           case 'designLeader': | ||||
|           case 1: | ||||
|             form.designLeader = item.userId; | ||||
|             break; | ||||
|  | ||||
|           case 'designer': | ||||
|           case 2: | ||||
|             form.designers.push({ | ||||
|               userId: item.userId, | ||||
|               userMajor: item.userMajor || null | ||||
|             }); | ||||
|             break; | ||||
|  | ||||
|           case 'reviewer': | ||||
|           case 3: | ||||
|             form.reviewers.push({ | ||||
|               userId: item.userId, | ||||
|               userMajor: item.userMajor || null | ||||
|             }); | ||||
|             break; | ||||
|           form.reviewers.push({ | ||||
|             userId: item.userId, | ||||
|             userMajor: item.userMajor || null | ||||
|           }); | ||||
|         } | ||||
|       }); | ||||
|       // 如果没有设计人员或校审人员,添加一个空项 | ||||
|       // 补全默认空项 | ||||
|       if (form.designers.length === 0) { | ||||
|         form.designers.push({ userId: null, userMajor: null }); | ||||
|       } | ||||
| @ -261,7 +259,6 @@ const designUser = async () => { | ||||
|     } | ||||
|   } catch (error) { | ||||
|     ElMessage.error('获取配置数据失败'); | ||||
|     // 添加默认空项 | ||||
|     form.designers.push({ userId: null, userMajor: null }); | ||||
|     form.reviewers.push({ userId: null, userMajor: null }); | ||||
|   } finally { | ||||
| @ -272,7 +269,7 @@ const designUser = async () => { | ||||
| /** 添加人员 */ | ||||
| const addPerson = (type: 'designers' | 'reviewers') => { | ||||
|   form[type].push({ userId: null, userMajor: null }); | ||||
|   // 滚动到最后一个新增的元素 | ||||
|   // 滚动到最后一个新增元素 | ||||
|   setTimeout(() => { | ||||
|     const elements = document.querySelectorAll(`[data-v-${proxy?.$options.__scopeId}] .el-select`); | ||||
|     if (elements.length > 0) { | ||||
| @ -290,48 +287,112 @@ const removePerson = (type: 'designers' | 'reviewers', index: number) => { | ||||
|   form[type].splice(index, 1); | ||||
| }; | ||||
|  | ||||
| /** 提交表单 */ | ||||
| // ===================== 核心修改:重复校验逻辑 ===================== | ||||
| /** | ||||
|  * 校验同一角色内(设计/校审)的「专业+人员」组合唯一性 | ||||
|  * @param current 当前操作的人员对象 | ||||
|  * @param role 角色类型(designers/reviewers) | ||||
|  * @param currentIndex 当前操作的索引 | ||||
|  */ | ||||
| const checkDuplicate = (current: { userId: number | null; userMajor: string | null }, role: 'designers' | 'reviewers', currentIndex: number) => { | ||||
|   // 未选完专业/人员时不校验 | ||||
|   if (!current.userId || !current.userMajor) return; | ||||
|  | ||||
|   // 只获取当前角色的所有人员(设计只查设计,校审只查校审) | ||||
|   const targetList = form[role]; | ||||
|   // 生成当前「专业+人员」唯一标识 | ||||
|   const currentKey = `${current.userMajor}-${current.userId}`; | ||||
|  | ||||
|   // 检查当前角色内是否有重复 | ||||
|   const duplicateItem = targetList.find((item, index) => { | ||||
|     // 排除当前操作项本身 | ||||
|     if (index === currentIndex) return false; | ||||
|     // 对比「专业+人员」组合 | ||||
|     return `${item.userMajor}-${item.userId}` === currentKey; | ||||
|   }); | ||||
|  | ||||
|   // 存在重复时提示并清空当前选择 | ||||
|   if (duplicateItem) { | ||||
|     ElMessage.warning(`当前「${getMajorLabel(current.userMajor)}+${getUserName(current.userId)}」组合已存在,请重新选择`); | ||||
|     // 清空当前项的选择 | ||||
|     current.userId = null; | ||||
|     current.userMajor = null; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| /** 辅助函数:通过专业值获取专业名称 */ | ||||
| const getMajorLabel = (majorValue: string | null) => { | ||||
|   if (!majorValue || !des_user_major.value) return ''; | ||||
|   const major = des_user_major.value.find((item: any) => item.value === majorValue); | ||||
|   return major ? major.label : majorValue; | ||||
| }; | ||||
|  | ||||
| /** 辅助函数:通过用户ID获取用户名 */ | ||||
| const getUserName = (userId: number | null) => { | ||||
|   if (!userId || !userList.value.length) return ''; | ||||
|   const user = userList.value.find((item: any) => item.userId === userId); | ||||
|   return user ? user.nickName : userId; | ||||
| }; | ||||
|  | ||||
| /** 提交表单(补充提交前重复校验) */ | ||||
| const submitForm = async () => { | ||||
|   if (!leaveFormRef.value) return; | ||||
|   try { | ||||
|     // 表单验证 | ||||
|     // 1. 先做基础表单验证 | ||||
|     await leaveFormRef.value.validate(); | ||||
|     // 构建提交数据 - 所有人员信息放在一个数组中 | ||||
|  | ||||
|     // 2. 提交前二次校验:确保当前角色内无重复(防止手动修改数据绕过实时校验) | ||||
|     let hasDuplicate = false; | ||||
|     // 校验设计人员 | ||||
|     const designKeys = form.designers.map((item) => `${item.userMajor}-${item.userId}`); | ||||
|     if (new Set(designKeys).size !== designKeys.length) { | ||||
|       hasDuplicate = true; | ||||
|       ElMessage.error('设计人员中存在重复的「专业+人员」组合,请检查'); | ||||
|     } | ||||
|     // 校验校审人员(不校验设计与校审之间) | ||||
|     if (!hasDuplicate) { | ||||
|       const reviewKeys = form.reviewers.map((item) => `${item.userMajor}-${item.userId}`); | ||||
|       if (new Set(reviewKeys).size !== reviewKeys.length) { | ||||
|         hasDuplicate = true; | ||||
|         ElMessage.error('校审人员中存在重复的「专业+人员」组合,请检查'); | ||||
|       } | ||||
|     } | ||||
|     // 有重复则终止提交 | ||||
|     if (hasDuplicate) return; | ||||
|  | ||||
|     // 3. 构建提交数据(原有逻辑不变) | ||||
|     const submitData = { | ||||
|       projectId: form.projectId, | ||||
|       personnel: [ | ||||
|         // 设计负责人 | ||||
|         { | ||||
|           userId: form.designLeader, | ||||
|           userType: 'designLeader', // 设计负责人类型标识 | ||||
|           userMajor: null // 负责人不需要专业 | ||||
|           userType: 'designLeader', | ||||
|           userMajor: null | ||||
|         }, | ||||
|         // 设计人员 | ||||
|         ...form.designers.map((designer) => ({ | ||||
|           userId: designer.userId, | ||||
|           userType: 'designer', // 设计人员类型标识 | ||||
|           userMajor: designer.userMajor // 包含专业信息 | ||||
|           userType: 'designer', | ||||
|           userMajor: designer.userMajor | ||||
|         })), | ||||
|         // 校审人员 | ||||
|         ...form.reviewers.map((reviewer) => ({ | ||||
|           userId: reviewer.userId, | ||||
|           userType: 'reviewer', // 校审人员类型标识 | ||||
|           userMajor: reviewer.userMajor // 包含专业信息 | ||||
|           userType: 'reviewer', | ||||
|           userMajor: reviewer.userMajor | ||||
|         })) | ||||
|       ] | ||||
|     }; | ||||
|  | ||||
|     // 数据处理 | ||||
|     // 数据处理(原有逻辑不变) | ||||
|     const arr = []; | ||||
|     userList.value.forEach((item) => { | ||||
|       submitData.personnel.forEach((item1) => { | ||||
|         if (item1.userId === item.userId) { | ||||
|           let userType = 1; // 默认为设计负责人 | ||||
|           if (item1.userType === 'designer') { | ||||
|             userType = 2; // 设计人员 | ||||
|           } else if (item1.userType === 'reviewer') { | ||||
|             userType = 3; // 校审人员 | ||||
|           } | ||||
|           let userType = 1; | ||||
|           if (item1.userType === 'designer') userType = 2; | ||||
|           else if (item1.userType === 'reviewer') userType = 3; | ||||
|           arr.push({ | ||||
|             userName: item.nickName, | ||||
|             projectId: submitData.projectId, | ||||
| @ -343,7 +404,8 @@ const submitForm = async () => { | ||||
|       }); | ||||
|     }); | ||||
|  | ||||
|     // 提交到后端 | ||||
|     // 4. 提交到后端(原有逻辑不变) | ||||
|     const loading = ElLoading.service({ text: '提交中...', background: 'rgba(255,255,255,0.7)' }); | ||||
|     const res = await designUserAdd({ | ||||
|       list: arr, | ||||
|       projectId: currentProject.value?.id | ||||
| @ -357,7 +419,6 @@ const submitForm = async () => { | ||||
|   } catch (error) { | ||||
|     ElMessage.error('请完善表单信息后再提交'); | ||||
|   } finally { | ||||
|     // 关闭加载状态 | ||||
|     ElLoading.service().close(); | ||||
|   } | ||||
| }; | ||||
| @ -371,22 +432,22 @@ const resetForm = () => { | ||||
|     ElMessage.info('表单已重置'); | ||||
|   } | ||||
| }; | ||||
| //监听项目id刷新数据 | ||||
| const listeningProject = watch( | ||||
|  | ||||
| // 监听项目ID刷新数据 | ||||
| const listeningProject: WatchStopHandle = watch( | ||||
|   () => currentProject.value?.id, | ||||
|   (nid, oid) => { | ||||
|   () => { | ||||
|     getDeptAllUser(userStore.deptId).then(() => { | ||||
|       designUser(); | ||||
|     }); | ||||
|   } | ||||
| ); | ||||
|  | ||||
| // 页面生命周期 | ||||
| onUnmounted(() => { | ||||
|   listeningProject(); | ||||
|   listeningProject(); // 修复原代码watchStopHandle调用问题 | ||||
| }); | ||||
| // 页面挂载时初始化数据 | ||||
| onMounted(() => { | ||||
|   // 先获取用户列表,再加载表单数据 | ||||
|   getDeptAllUser(userStore.deptId).then(() => { | ||||
|     designUser(); | ||||
|   }); | ||||
|  | ||||
| @ -70,8 +70,9 @@ | ||||
|           :row-class-name="state.tableData.length === 0 ? 'table-null' : ''" | ||||
|           style="width: 100%; margin-bottom: 20px; height: calc(100vh - 305px)" | ||||
|           row-key="id" | ||||
|           lazy | ||||
|           border | ||||
|           :default-expand-all="state.isOpen" | ||||
|           :default-expand-all="true" | ||||
|         > | ||||
|           <el-table-column prop="num" label="编号" /> | ||||
|           <el-table-column prop="name" label="工程或费用名称" /> | ||||
| @ -132,10 +133,6 @@ const state = reactive({ | ||||
|   error: null, | ||||
|   // 前三个 | ||||
|   tableData: [], | ||||
|   // 物质设备清单 | ||||
|   // tableData_sdsqd: [], | ||||
|   // 展开收起 | ||||
|   isOpen: true, | ||||
|   // 版本号 | ||||
|   versionsData: {} | ||||
| }); | ||||
| @ -155,7 +152,6 @@ const handleTabChange = (tab) => { | ||||
| }; | ||||
| onMounted(async () => { | ||||
|   await getVersionNums(); | ||||
|   openTable(true, state.work_order_type); | ||||
| }); | ||||
| // 获取版本号 | ||||
| async function getVersionNums(isSheet = true) { | ||||
| @ -268,18 +264,19 @@ function importExcel(options) { | ||||
|       if (code == 200) { | ||||
|         proxy.$modal.msgSuccess(res.msg || '导入成功'); | ||||
|         // 更新列表 | ||||
|         getVersionNums(false); | ||||
|         if (state.work_order_type == 3) { | ||||
|           getVersionNums(false);  | ||||
|         }else{ | ||||
|           getVersionNums();  | ||||
|         } | ||||
|       } else { | ||||
|         getVersionNums(); | ||||
|         proxy.$modal.msgError(res.msg || '导入失败'); | ||||
|       } | ||||
|     }) | ||||
|     .finally(() => { | ||||
|     }).catch(()=>{ | ||||
|       proxy.$modal.msgError(res.msg || '导入失败'); | ||||
|     }).finally(() => { | ||||
|       state.loading.list = false; | ||||
|     }) | ||||
|     .finally(() => { | ||||
|       // loading.close(); | ||||
|     }); | ||||
| } | ||||
| // 切换表名 | ||||
| function handleChange(sheet) { | ||||
| @ -299,6 +296,7 @@ function openTable(flag, index) { | ||||
|   nextTick(() => { | ||||
|     // 通过索引获取当前标签页的表格实例 | ||||
|     const currentTable = tableRef.value[index]; | ||||
|     console.log(currentTable, index); | ||||
|     if (currentTable) { | ||||
|       handleArr(state.tableData, flag, currentTable); | ||||
|     } | ||||
|  | ||||
| @ -22,7 +22,7 @@ | ||||
|           <el-form | ||||
|             ref="leaveFormRef" | ||||
|             v-loading="loading" | ||||
|             :disabled="routeParams.type === 'view'" | ||||
|             :disabled="routeParams.type === 'view' || form.status == 'waiting'" | ||||
|             :model="form" | ||||
|             :rules="rules" | ||||
|             label-width="100px" | ||||
|  | ||||
| @ -22,7 +22,7 @@ | ||||
|           <el-form | ||||
|             ref="leaveFormRef" | ||||
|             v-loading="loading" | ||||
|             :disabled="routeParams.type === 'view'" | ||||
|             :disabled="routeParams.type === 'view' || form.status == 'waiting'" | ||||
|             :model="form" | ||||
|             :rules="rules" | ||||
|             label-width="100px" | ||||
|  | ||||
| @ -27,7 +27,7 @@ | ||||
|               <el-date-picker clearable v-model="queryParams.submitDate" type="date" value-format="YYYY-MM-DD" placeholder="请选择提出日期" /> | ||||
|             </el-form-item> | ||||
|             <el-form-item> | ||||
|               <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button> | ||||
|               <el-button type="primary" icon="Search" @click="handleQuery" v-hasPermi="['design:designChange:list']">搜索</el-button> | ||||
|               <el-button icon="Refresh" @click="resetQuery">重置</el-button> | ||||
|             </el-form-item> | ||||
|           </el-form> | ||||
| @ -89,12 +89,23 @@ | ||||
|               v-if="scope.row.status == 'draft' || scope.row.status == 'back'" | ||||
|               >上传</el-button | ||||
|             > | ||||
|             <el-button type="success" link icon="View" v-if="scope.row.status != 'draft'" @click="handleViewInfo(scope.row)">查看</el-button> | ||||
|             <el-button type="success" link icon="View" @click="handleViewDetail(scope.row)">通知单</el-button> | ||||
|             <el-button | ||||
|               type="success" | ||||
|               link | ||||
|               icon="View" | ||||
|               v-if="scope.row.status != 'draft'" | ||||
|               v-hasPermi="['design:designChange:query']" | ||||
|               @click="handleViewInfo(scope.row)" | ||||
|               >查看</el-button | ||||
|             > | ||||
|             <el-button type="success" link icon="View" v-hasPermi="['design:designChange:query']" @click="handleViewDetail(scope.row)" | ||||
|               >通知单</el-button | ||||
|             > | ||||
|             <el-button | ||||
|               type="warning" | ||||
|               link | ||||
|               icon="View" | ||||
|               v-hasPermi="['design:designChange:query']" | ||||
|               v-if="scope.row.status == 'draft' || scope.row.status == 'termination'" | ||||
|               @click="handleViewHistory(scope.row)" | ||||
|               >查看单据</el-button | ||||
|  | ||||
| @ -12,7 +12,14 @@ | ||||
|           <h3 class="text-lg font-semibold text-gray-800">下发变更通知信息</h3> | ||||
|         </div> | ||||
|         <div class="p-6"> | ||||
|           <el-form ref="leaveFormRef" :disabled="routeParams.type === 'view'" :model="form" :rules="rules" label-width="100px" class="space-y-4"> | ||||
|           <el-form | ||||
|             ref="leaveFormRef" | ||||
|             :disabled="routeParams.type === 'view' || form.status == 'waiting'" | ||||
|             :model="form" | ||||
|             :rules="rules" | ||||
|             label-width="100px" | ||||
|             class="space-y-4" | ||||
|           > | ||||
|             <div class="grid grid-cols-1 gap-4"> | ||||
|               <el-row> | ||||
|                 <el-col :span="12"> | ||||
|  | ||||
| @ -19,7 +19,14 @@ | ||||
|           <h3 class="text-lg font-semibold text-gray-800">变更图纸信息</h3> | ||||
|         </div> | ||||
|         <div class="p-6"> | ||||
|           <el-form ref="leaveFormRef" :disabled="routeParams.type === 'view'" :model="form" :rules="rules" label-width="100px" class="space-y-4"> | ||||
|           <el-form | ||||
|             ref="leaveFormRef" | ||||
|             :disabled="routeParams.type === 'view' || form.status == 'waiting'" | ||||
|             :model="form" | ||||
|             :rules="rules" | ||||
|             label-width="100px" | ||||
|             class="space-y-4" | ||||
|           > | ||||
|             <div class="grid grid-cols-1 md:grid-cols-2 gap-4"> | ||||
|               <el-form-item label="图纸文件" prop="fileId" class="mb-2 md:col-span-2"> | ||||
|                 <file-upload :fileType="['pdf']" :fileSize="''" v-model="form.fileId" class="w-full"></file-upload> | ||||
|  | ||||
| @ -19,23 +19,20 @@ | ||||
|           <h3 class="text-lg font-semibold text-gray-800">图纸评审</h3> | ||||
|         </div> | ||||
|         <div class="p-6"> | ||||
|           <el-form | ||||
|             ref="leaveFormRef" | ||||
|             v-loading="loading" | ||||
|             :disabled="routeParams.type === 'view'" | ||||
|             :model="form" | ||||
|             :rules="rules" | ||||
|             label-width="100px" | ||||
|             class="space-y-4" | ||||
|           > | ||||
|             <div class="grid grid-cols-1 gap-4"> | ||||
|               <el-form ref="leaveFormRef" :disabled="routeParams.type === 'view'" :model="form" :rules="rules" label-width="100px" class="space-y-4"> | ||||
|                 <el-form-item label="图纸文件" v-for="value in form.fileVoList" :key="value.id" prop="fileId" class="mb-2 md:col-span-2"> | ||||
|                   <el-input v-model="value.fileName" disabled placeholder="图纸名称" /> | ||||
|                 </el-form-item> | ||||
|               </el-form> | ||||
|             </div> | ||||
|           </el-form> | ||||
|           <div class="grid grid-cols-1 gap-4"> | ||||
|             <el-form | ||||
|               ref="leaveFormRef" | ||||
|               :disabled="routeParams.type === 'view' || form.auditStatus == 'waiting'" | ||||
|               :model="form" | ||||
|               :rules="rules" | ||||
|               label-width="100px" | ||||
|               class="space-y-4" | ||||
|             > | ||||
|               <el-form-item label="图纸文件" v-for="value in form.fileVoList" :key="value.id" prop="fileId" class="mb-2 md:col-span-2"> | ||||
|                 <el-input v-model="value.fileName" disabled placeholder="图纸名称" /> | ||||
|               </el-form-item> | ||||
|             </el-form> | ||||
|           </div> | ||||
|         </div> | ||||
|       </el-card> | ||||
|       <!-- 提交组件 --> | ||||
|  | ||||
| @ -8,7 +8,7 @@ | ||||
|               <el-input v-model="queryParams.fileName" placeholder="请输入文件名称" clearable @keyup.enter="handleQuery" /> | ||||
|             </el-form-item> | ||||
|             <el-form-item> | ||||
|               <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button> | ||||
|               <el-button type="primary" icon="Search" @click="handleQuery" v-hasPermi="['design:prelimScheme:list']">搜索</el-button> | ||||
|               <el-button icon="Refresh" @click="resetQuery">重置</el-button> | ||||
|             </el-form-item> | ||||
|           </el-form> | ||||
| @ -20,7 +20,7 @@ | ||||
|       <template #header> | ||||
|         <el-row :gutter="10" class="mb8"> | ||||
|           <el-col :span="1.5"> | ||||
|             <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['design:scheme:add']">新增</el-button> | ||||
|             <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['design:prelimScheme:add']">新增</el-button> | ||||
|           </el-col> | ||||
|           <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> | ||||
|         </el-row> | ||||
| @ -48,7 +48,7 @@ | ||||
|               v-if="scope.row.status !== 'draft'" | ||||
|               icon="Edit" | ||||
|               @click="handleView(scope.row)" | ||||
|               v-hasPermi="['design:PrelimScheme:edit']" | ||||
|               v-hasPermi="['design:PrelimScheme:query']" | ||||
|               >查看流程</el-button | ||||
|             > | ||||
|             <el-button | ||||
| @ -60,7 +60,7 @@ | ||||
|               v-hasPermi="['design:PrelimScheme:edit']" | ||||
|               >修改</el-button | ||||
|             > | ||||
|             <el-button | ||||
|             <!-- <el-button | ||||
|               link | ||||
|               type="primary" | ||||
|               v-if="scope.row.status === 'draft'" | ||||
| @ -68,7 +68,7 @@ | ||||
|               @click="handleDelete(scope.row)" | ||||
|               v-hasPermi="['design:PrelimScheme:remove']" | ||||
|               >删除</el-button | ||||
|             > | ||||
|             > --> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|       </el-table> | ||||
|  | ||||
| @ -23,7 +23,7 @@ | ||||
|           <el-form | ||||
|             ref="leaveFormRef" | ||||
|             v-loading="loading" | ||||
|             :disabled="routeParams.type === 'view'" | ||||
|             :disabled="routeParams.type === 'view' || form.status == 'waiting' || form.status == 'waiting'" | ||||
|             :model="form" | ||||
|             :rules="rules" | ||||
|             label-width="120px" | ||||
|  | ||||
| @ -23,7 +23,7 @@ | ||||
|           <el-form | ||||
|             ref="leaveFormRef" | ||||
|             v-loading="loading" | ||||
|             :disabled="routeParams.type === 'view'" | ||||
|             :disabled="routeParams.type === 'view' || form.status == 'waiting'" | ||||
|             :model="form" | ||||
|             :rules="rules" | ||||
|             label-width="120px" | ||||
|  | ||||
| @ -23,7 +23,7 @@ | ||||
|           <el-form | ||||
|             ref="leaveFormRef" | ||||
|             v-loading="loading" | ||||
|             :disabled="routeParams.type === 'view'" | ||||
|             :disabled="routeParams.type === 'view' || form.status == 'waiting'" | ||||
|             :model="form" | ||||
|             :rules="rules" | ||||
|             label-width="120px" | ||||
|  | ||||
| @ -22,7 +22,7 @@ | ||||
|           <el-col :span="1.5"> | ||||
|             <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['design:subcontract:add']">新增</el-button> | ||||
|           </el-col> | ||||
|           <el-col :span="1.5"> | ||||
|           <!-- <el-col :span="1.5"> | ||||
|             <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['design:subcontract:edit']" | ||||
|               >修改</el-button | ||||
|             > | ||||
| @ -34,7 +34,7 @@ | ||||
|           </el-col> | ||||
|           <el-col :span="1.5"> | ||||
|             <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['design:subcontract:export']">导出</el-button> | ||||
|           </el-col> | ||||
|           </el-col> --> | ||||
|           <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> | ||||
|         </el-row> | ||||
|       </template> | ||||
| @ -45,12 +45,8 @@ | ||||
|         <el-table-column label="分包内容" align="center" prop="subContent" /> | ||||
|         <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | ||||
|           <template #default="scope"> | ||||
|             <el-tooltip content="修改" placement="top"> | ||||
|               <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['design:subcontract:edit']"></el-button> | ||||
|             </el-tooltip> | ||||
|             <el-tooltip content="删除" placement="top"> | ||||
|               <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['design:subcontract:remove']"></el-button> | ||||
|             </el-tooltip> | ||||
|             <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['design:subcontract:edit']">修改</el-button> | ||||
|             <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['design:subcontract:remove']">删除</el-button> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|       </el-table> | ||||
|  | ||||
| @ -22,7 +22,7 @@ | ||||
|           <el-form | ||||
|             ref="leaveFormRef" | ||||
|             v-loading="loading" | ||||
|             :disabled="routeParams.type === 'view'" | ||||
|             :disabled="routeParams.type === 'view' || form.status == 'waiting'" | ||||
|             :model="form" | ||||
|             :rules="rules" | ||||
|             label-width="100px" | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| <template> | ||||
|   <el-dialog v-model="isShowDialog" title="变更单详情" draggable width="60vw" :close-on-click-modal="false" :destroy-on-close="true"> | ||||
|   <el-dialog v-model="isShowDialog" title="材料设备详情" draggable width="1200px" :close-on-click-modal="false" :destroy-on-close="true"> | ||||
|     <el-card :body-style="{ padding: '20px' }" style="border: none; box-shadow: none"> | ||||
|       <div class="dialog-footer"> | ||||
|         <div class="btn-item" @click="onLoad"> | ||||
| @ -46,26 +46,26 @@ | ||||
|             </tbody> | ||||
|             <thead> | ||||
|               <tr> | ||||
|                 <th width="150">序号</th> | ||||
|                 <th width="150">名称</th> | ||||
|                 <th width="150">规格</th> | ||||
|                 <th width="150">单位</th> | ||||
|                 <th width="150">数量</th> | ||||
|                 <th width="150">验收</th> | ||||
|                 <th width="150">缺件</th> | ||||
|                 <th width="150">备注</th> | ||||
|                 <td width="150">序号</td> | ||||
|                 <td width="150">名称</td> | ||||
|                 <td width="150">规格</td> | ||||
|                 <td width="150">单位</td> | ||||
|                 <td width="150">数量</td> | ||||
|                 <td width="150">验收</td> | ||||
|                 <td width="150">缺件</td> | ||||
|                 <td width="150">备注</td> | ||||
|               </tr> | ||||
|             </thead> | ||||
|             <tbody> | ||||
|               <tr v-for="(item, i) of formData.itemList" :key="i"> | ||||
|                 <th width="150">{{ i + 1 }}</th> | ||||
|                 <th width="150">{{ item.name }}</th> | ||||
|                 <th width="150">{{ item.specification }}</th> | ||||
|                 <th width="150">{{ item.unit }}</th> | ||||
|                 <th width="150">{{ item.quantity }}</th> | ||||
|                 <th width="150">{{ item.acceptedQuantity }}</th> | ||||
|                 <th width="150">{{ item.shortageQuantity }}</th> | ||||
|                 <th width="150">{{ item.remark }}</th> | ||||
|                 <td width="150">{{ i + 1 }}</td> | ||||
|                 <td width="150">{{ item.name }}</td> | ||||
|                 <td width="150">{{ item.specification }}</td> | ||||
|                 <td width="150">{{ item.unit }}</td> | ||||
|                 <td width="150">{{ item.quantity }}</td> | ||||
|                 <td width="150">{{ item.acceptedQuantity }}</td> | ||||
|                 <td width="150">{{ item.shortageQuantity }}</td> | ||||
|                 <td width="150">{{ item.remark }}</td> | ||||
|               </tr> | ||||
|             </tbody> | ||||
|             <tbody> | ||||
|  | ||||
										
											Binary file not shown.
										
									
								
							| @ -27,6 +27,7 @@ | ||||
|       <el-table-column prop="num" label="编号" /> | ||||
|       <el-table-column prop="name" label="工程或费用名称" width="180" /> | ||||
|       <el-table-column prop="unit" label="单位" /> | ||||
|       <el-table-column prop="specification" label="规格型号" /> | ||||
|       <el-table-column prop="quantity" label="数量" width="60" /> | ||||
|       <el-table-column prop="batchNumber" label="批次号" width="200" /> | ||||
|       <el-table-column prop="brand" label="品牌" /> | ||||
|  | ||||
| @ -3,18 +3,23 @@ | ||||
|     <div class="max-w-4xl mx-auto"> | ||||
|       <!-- 顶部按钮区域 --> | ||||
|       <el-card class="mb-4 rounded-lg shadow-sm bg-white border border-gray-100 transition-all hover:shadow-md"> | ||||
|         <approvalButton @submitForm="submitForm" @approvalVerifyOpen="approvalVerifyOpen" | ||||
|           @handleApprovalRecord="handleApprovalRecord" :buttonLoading="buttonLoading" :id="form.id" | ||||
|           :status="form.status" :pageType="routeParams.type" /> | ||||
|         <approvalButton | ||||
|           @submitForm="submitForm" | ||||
|           @approvalVerifyOpen="approvalVerifyOpen" | ||||
|           @handleApprovalRecord="handleApprovalRecord" | ||||
|           :buttonLoading="buttonLoading" | ||||
|           :id="form.id" | ||||
|           :status="form.status" | ||||
|           :pageType="routeParams.type" | ||||
|         /> | ||||
|       </el-card> | ||||
|       <!-- 表单区域 --> | ||||
|       <el-card | ||||
|         class="rounded-lg shadow-sm bg-white border border-gray-100 transition-all hover:shadow-md overflow-hidden"> | ||||
|       <el-card class="rounded-lg shadow-sm bg-white border border-gray-100 transition-all hover:shadow-md overflow-hidden"> | ||||
|         <div class="p-4 bg-gradient-to-r from-blue-50 to-indigo-50 border-b border-gray-100"> | ||||
|           <h3 class="text-lg font-semibold text-gray-800">设计原则</h3> | ||||
|         </div> | ||||
|         <div class="p-6"> | ||||
|           <!-- <el-form ref="leaveFormRef" v-loading="loading" :disabled="routeParams.type === 'view' || routeParams.type === 'update'" :model="form" | ||||
|           <!-- <el-form ref="leaveFormRef" v-loading="loading" :disabled="routeParams.type === 'view' || form.status == 'waiting' || routeParams.type === 'update'" :model="form" | ||||
|             :rules="rules" label-width="100px" class="space-y-4"> | ||||
|             <el-row :gutter="20"> | ||||
|               <el-col :span="12"> | ||||
| @ -67,7 +72,7 @@ | ||||
|               </el-col> | ||||
|             </el-row> | ||||
|           </el-form> --> | ||||
|           <el-table :data="tableData" v-loading="loading"  row-key="id" border> | ||||
|           <el-table :data="tableData" v-loading="loading" row-key="id" border> | ||||
|             <el-table-column prop="num" label="编号" /> | ||||
|             <el-table-column prop="name" label="名称" /> | ||||
|             <el-table-column prop="specification" label="规格" /> | ||||
| @ -81,8 +86,14 @@ | ||||
|       <submitVerify ref="submitVerifyRef" :task-variables="taskVariables" @submit-callback="submitCallback" /> | ||||
|       <approvalRecord ref="approvalRecordRef"></approvalRecord> | ||||
|       <!-- 流程选择对话框 --> | ||||
|       <el-dialog draggable v-model="dialogVisible.visible" :title="dialogVisible.title" :before-close="handleClose" | ||||
|         width="500" class="rounded-lg shadow-lg"> | ||||
|       <el-dialog | ||||
|         draggable | ||||
|         v-model="dialogVisible.visible" | ||||
|         :title="dialogVisible.title" | ||||
|         :before-close="handleClose" | ||||
|         width="500" | ||||
|         class="rounded-lg shadow-lg" | ||||
|       > | ||||
|         <div class="p-4"> | ||||
|           <p class="text-gray-600 mb-4">请选择要启动的流程:</p> | ||||
|           <el-select v-model="flowCode" placeholder="请选择流程" style="width: 100%"> | ||||
| @ -91,10 +102,12 @@ | ||||
|         </div> | ||||
|         <template #footer> | ||||
|           <div class="dialog-footer p-4 border-t border-gray-100 flex justify-end space-x-3"> | ||||
|             <el-button @click="handleClose" | ||||
|               class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50 transition-colors">取消</el-button> | ||||
|             <el-button type="primary" @click="submitFlow()" | ||||
|               class="px-4 py-2 bg-primary text-white rounded-md hover:bg-primary/90 transition-colors">确认</el-button> | ||||
|             <el-button @click="handleClose" class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50 transition-colors" | ||||
|               >取消</el-button | ||||
|             > | ||||
|             <el-button type="primary" @click="submitFlow()" class="px-4 py-2 bg-primary text-white rounded-md hover:bg-primary/90 transition-colors" | ||||
|               >确认</el-button | ||||
|             > | ||||
|           </div> | ||||
|         </template> | ||||
|       </el-dialog> | ||||
| @ -112,7 +125,7 @@ import { StartProcessBo } from '@/api/workflow/workflowCommon/types'; | ||||
| const { proxy } = getCurrentInstance() as ComponentInternalInstance; | ||||
| import { useUserStoreHook } from '@/store/modules/user'; | ||||
| const { design_change_reason_type } = toRefs<any>(proxy?.useDict('design_change_reason_type')); | ||||
| import { totalsupplyplan,obtainMasterDataList } from '@/api/materials/overallPlanMaterialSupply/index'; | ||||
| import { totalsupplyplan, obtainMasterDataList } from '@/api/materials/overallPlanMaterialSupply/index'; | ||||
| // 获取用户 store | ||||
| const userStore = useUserStoreHook(); | ||||
| // 从 store 中获取项目列表和当前选中的项目 | ||||
|  | ||||
							
								
								
									
										244
									
								
								src/views/materials/purchaseDoc/comm/logisticsDetail.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										244
									
								
								src/views/materials/purchaseDoc/comm/logisticsDetail.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,244 @@ | ||||
| <template> | ||||
|   <el-drawer v-model="drawer" :direction="direction" size="40%" :before-close="handleBeforeClose" title-class="drawer-title"> | ||||
|     <template #header> | ||||
|       <span class="font-bold text-lg text-gray-800">物流信息</span> | ||||
|     </template> | ||||
|     <template #default> | ||||
|       <!-- 物流头部信息 --> | ||||
|       <div class="bg-white rounded-lg shadow-md p-5 mb-6"> | ||||
|         <div class="flex flex-col md:flex-row md:items-center justify-between gap-6"> | ||||
|           <!-- 左侧:快递基本信息 --> | ||||
|           <div class="flex items-center gap-6"> | ||||
|             <div class="w-14 h-14 rounded-md overflow-hidden border border-gray-100 flex items-center justify-center"> | ||||
|               <img | ||||
|                 :src="logisticsData?.result.logo" | ||||
|                 alt="快递公司Logo" | ||||
|                 class="w-full h-full object-contain" | ||||
|                 :onerror="`this.src='https://via.placeholder.com/48x48?text=暂无Logo'`" | ||||
|               /> | ||||
|             </div> | ||||
|             <div class="text-sm"> | ||||
|               <p class="text-gray-500">快递单号</p> | ||||
|               <p class="font-medium text-gray-900">{{ logisticsData?.result.number }}</p> | ||||
|               <p class="text-gray-500 mt-1">{{ logisticsData?.result.expName }} | 最新更新: {{ logisticsData?.result.updateTime }}</p> | ||||
|             </div> | ||||
|             <div class="ml-auto"> | ||||
|               <el-tag :type="getStatusType(logisticsData?.result.deliverystatus)" size="medium" class="px-4 py-1"> | ||||
|                 {{ getStatusText(logisticsData?.result.deliverystatus) }} | ||||
|               </el-tag> | ||||
|               <p class="text-gray-500 text-sm mt-2 text-right">耗时: {{ logisticsData?.result.takeTime || '暂无数据' }}</p> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|  | ||||
|       <!-- 快递员信息(有数据才显示) --> | ||||
|       <div v-if="logisticsData?.result.courier" class="bg-blue-50 rounded-lg p-4 mb-6 border-l-4 border-blue-400"> | ||||
|         <div class="flex items-center justify-between"> | ||||
|           <p class="font-medium text-blue-800">配送信息</p> | ||||
|           <a :href="`tel:${logisticsData?.result.courierPhone}`" class="text-blue-600 hover:text-blue-800 text-sm flex items-center gap-1"> | ||||
|             <el-icon class="el-icon-phone"></el-icon> | ||||
|             联系快递员 | ||||
|           </a> | ||||
|         </div> | ||||
|         <div class="flex flex-wrap gap-x-8 gap-y-3 mt-3 text-gray-700"> | ||||
|           <div class="flex items-center gap-2"> | ||||
|             <el-icon class="el-icon-user text-gray-500"></el-icon> | ||||
|             <span>快递员: {{ logisticsData?.result.courier }}</span> | ||||
|           </div> | ||||
|           <div class="flex items-center gap-2"> | ||||
|             <el-icon class="el-icon-phone-outline text-gray-500"></el-icon> | ||||
|             <span>电话: {{ logisticsData?.result.courierPhone || '暂无' }}</span> | ||||
|           </div> | ||||
|           <div class="flex items-center gap-2"> | ||||
|             <el-icon class="el-icon-service text-gray-500"></el-icon> | ||||
|             <span>客服: {{ logisticsData?.result.expPhone }}</span> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|  | ||||
|       <!-- 物流轨迹列表 --> | ||||
|       <div class="bg-white rounded-lg shadow-md p-5"> | ||||
|         <p class="font-medium text-gray-800 mb-4">物流轨迹({{ logisticsData?.result.list.length || 0 }}条)</p> | ||||
|         <div class="relative" style="border-left: 1px solid #d9d9d9; padding-left: 15px"> | ||||
|           <div v-for="(item, index) in logisticsData?.result.list" :key="index" class="flex mb-8 relative"> | ||||
|             <div class="flex flex-col items-center mr-6 z-10"> | ||||
|               <div | ||||
|                 :class="[ | ||||
|                   'w-8 h-8 rounded-full flex items-center justify-center', | ||||
|                   index === 0 ? 'bg-blue-500 text-white' : 'bg-white border border-gray-300 text-gray-500' | ||||
|                 ]" | ||||
|               > | ||||
|                 <el-icon v-if="index === 0" class="el-icon-check text-xs"></el-icon> | ||||
|                 <span v-else class="text-xs">{{ index + 1 }}</span> | ||||
|               </div> | ||||
|               <p class="text-xs text-gray-500 mt-2">{{ item.time }}</p> | ||||
|             </div> | ||||
|             <div class="flex-1 bg-gray-50 rounded-lg p-4 border border-gray-100 shadow-sm"> | ||||
|               <p class="text-gray-800">{{ item.status }}</p> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </template> | ||||
|  | ||||
|     <template #footer> | ||||
|       <div class="drawer-footer"> | ||||
|         <el-button @click="close" :loading="cancelLoading" class="mr-3">关闭</el-button> | ||||
|       </div> | ||||
|     </template> | ||||
|   </el-drawer> | ||||
| </template> | ||||
|  | ||||
| <script setup lang="ts"> | ||||
| import { ref } from 'vue'; | ||||
| import type { DrawerProps } from 'element-plus'; | ||||
| import { Phone, PhoneOutline, User, Service, Check } from '@element-plus/icons-vue'; | ||||
|  | ||||
| // 抽屉方向 | ||||
| const direction = ref<DrawerProps['direction']>('ltr'); | ||||
| // 加载状态 | ||||
| const cancelLoading = ref(false); | ||||
| const confirmLoading = ref(false); | ||||
| // 抽屉显隐 | ||||
| const drawer = ref(false); | ||||
| // 物流数据(初始化为接口返回格式) | ||||
| const logisticsData = ref({ | ||||
|   status: '0', | ||||
|   msg: 'ok', | ||||
|   result: { | ||||
|     number: '', | ||||
|     type: '', | ||||
|     list: [], | ||||
|     deliverystatus: '0', | ||||
|     issign: '0', | ||||
|     expName: '', | ||||
|     expSite: '', | ||||
|     expPhone: '', | ||||
|     courier: '', | ||||
|     courierPhone: '', | ||||
|     updateTime: '', | ||||
|     takeTime: '', | ||||
|     logo: '' | ||||
|   } | ||||
| }); | ||||
|  | ||||
| /** | ||||
|  * 根据物流状态获取标签类型 | ||||
|  * @param status 物流状态码 | ||||
|  */ | ||||
| const getStatusType = (status?: string) => { | ||||
|   switch (status) { | ||||
|     case '0': // 揽件 | ||||
|       return 'info'; | ||||
|     case '1': // 在途中 | ||||
|       return 'warning'; | ||||
|     case '2': // 派件中 | ||||
|       return 'primary'; | ||||
|     case '3': // 已签收 | ||||
|       return 'success'; | ||||
|     case '4': // 派送失败 | ||||
|     case '5': // 疑难件 | ||||
|       return 'danger'; | ||||
|     case '6': // 退件签收 | ||||
|       return 'error'; | ||||
|     default: | ||||
|       return 'default'; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 根据物流状态获取文本描述 | ||||
|  * @param status 物流状态码 | ||||
|  */ | ||||
| const getStatusText = (status?: string) => { | ||||
|   const statusMap: Record<string, string> = { | ||||
|     '0': '快递收件(揽件)', | ||||
|     '1': '运输途中', | ||||
|     '2': '正在派件', | ||||
|     '3': '已签收', | ||||
|     '4': '派送失败', | ||||
|     '5': '疑难件', | ||||
|     '6': '退件签收' | ||||
|   }; | ||||
|   return statusMap[status || '0'] || '未知状态'; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 打开抽屉并加载物流数据 | ||||
|  */ | ||||
| const open = (data) => { | ||||
|   const mockData = { | ||||
|     result: data | ||||
|   }; | ||||
|   logisticsData.value = mockData; | ||||
|   drawer.value = true; | ||||
| }; | ||||
| /** | ||||
|  * 关闭抽屉 | ||||
|  */ | ||||
| const close = () => { | ||||
|   drawer.value = false; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 抽屉关闭前钩子(可用于拦截关闭逻辑) | ||||
|  */ | ||||
| const handleBeforeClose = (done: () => void) => { | ||||
|   done(); // 直接关闭,如需确认可添加弹窗逻辑 | ||||
| }; | ||||
|  | ||||
| // 暴露加载状态控制方法 | ||||
| const setCancelLoading = (loading: boolean) => { | ||||
|   cancelLoading.value = loading; | ||||
| }; | ||||
| const setConfirmLoading = (loading: boolean) => { | ||||
|   confirmLoading.value = loading; | ||||
| }; | ||||
|  | ||||
| // 暴露方法供父组件调用 | ||||
| defineExpose({ | ||||
|   open, | ||||
|   setCancelLoading, | ||||
|   setConfirmLoading | ||||
| }); | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
| .drawer-title { | ||||
|   padding-bottom: 8px; | ||||
|   border-bottom: 1px solid #f2f2f2; | ||||
| } | ||||
|  | ||||
| .drawer-footer { | ||||
|   display: flex; | ||||
|   justify-content: flex-end; | ||||
|   gap: 12px; | ||||
|   padding: 16px; | ||||
|   border-top: 1px solid #eee; | ||||
| } | ||||
|  | ||||
| :deep(.el-drawer__body) { | ||||
|   padding: 20px; | ||||
|   overflow-y: auto; | ||||
|   max-height: calc(100vh - 160px); | ||||
| } | ||||
|  | ||||
| :deep(.el-tag) { | ||||
|   border-radius: 4px; | ||||
| } | ||||
|  | ||||
| @media (max-width: 768px) { | ||||
|   :deep(.el-drawer) { | ||||
|     width: 95% !important; | ||||
|   } | ||||
|  | ||||
|   .drawer-footer { | ||||
|     flex-direction: column; | ||||
|   } | ||||
|  | ||||
|   :deep(.drawer-footer .el-button) { | ||||
|     width: 100%; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
| @ -31,8 +31,8 @@ | ||||
|         </el-row> | ||||
|       </template> | ||||
|       <el-table v-loading="loading" :data="purchaseDocList" @selection-change="handleSelectionChange"> | ||||
|         <el-table-column type="selection" width="55" align="center" /> | ||||
|         <el-table-column label="采购单编号" align="center" prop="docCode" width="90" /> | ||||
|         <el-table-column type="index" width="60" label="序号" align="center" /> | ||||
|         <el-table-column label="采购单编号" align="center" prop="docCode" width="150" /> | ||||
|         <el-table-column label="批次号" align="center" prop="mrpBaseId"> | ||||
|           <template #default="scope"> | ||||
|             {{ batchOptions.find((item) => item.id == scope.row.mrpBaseId)?.planCode }} | ||||
| @ -220,11 +220,16 @@ | ||||
|       </template> | ||||
|     </el-dialog> | ||||
|     <!-- 查看文件列表 --> | ||||
|     <el-dialog title="文件列表" v-model="viewVisible" width="45%"> | ||||
|     <el-dialog title="物流单号" v-model="viewVisible" width="45%"> | ||||
|       <el-table v-if="fileList.length > 0" :data="fileList" style="width: 100%" border> | ||||
|         <el-table-column label="单号" align="center" prop="ltn" /> | ||||
|         <el-table-column label="数量" align="center" prop="num" /> | ||||
|         <el-table-column label="物资名称" align="center" prop="name" /> | ||||
|         <el-table-column label="规格型号" align="center" prop="specification"> | ||||
|           <template #default="scope"> | ||||
|             <el-button link type="primary" icon="Finished" @click="getDetailList(scope.row.ltn)"> 查看物流信息</el-button></template | ||||
|           > | ||||
|         </el-table-column> | ||||
|       </el-table> | ||||
|       <div v-else class="empty-list text-center">暂无文件</div> | ||||
|       <template #footer> | ||||
| @ -233,17 +238,19 @@ | ||||
|         </span> | ||||
|       </template> | ||||
|     </el-dialog> | ||||
|     <logisticsDetail ref="logisticsDetailRef"></logisticsDetail> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script setup name="PurchaseDoc" lang="ts"> | ||||
| import { getBatch, listBatch } from '@/api/materials/batchPlan'; | ||||
| import { listPurchaseDoc, getPurchaseDoc, listLink, addPurchaseDoc, updatePurchaseDoc } from '@/api/materials/purchaseDoc'; | ||||
| import { listPurchaseDoc, getPurchaseDoc, listLink, addPurchaseDoc, updatePurchaseDoc, logisticsDetial } from '@/api/materials/purchaseDoc'; | ||||
| import { PurchaseDocVO, PurchaseDocQuery, PurchaseDocForm } from '@/api/materials/purchaseDoc/types'; | ||||
| import { listContractor } from '@/api/project/contractor'; | ||||
| import { useUserStoreHook } from '@/store/modules/user'; | ||||
| import { getToken } from '@/utils/auth'; | ||||
|  | ||||
| import logisticsDetail from './comm/logisticsDetail.vue'; | ||||
| import type { DrawerProps } from 'element-plus'; | ||||
| const { proxy } = getCurrentInstance() as ComponentInternalInstance; | ||||
| const route = useRoute(); | ||||
| const router = useRouter(); | ||||
| @ -262,10 +269,11 @@ const single = ref(true); | ||||
| const multiple = ref(true); | ||||
| const total = ref(0); | ||||
| const feedbackUrl = ref(''); | ||||
| // 组件 | ||||
| const logisticsDetailRef = ref<InstanceType<typeof logisticsDetail>>(); | ||||
| const queryFormRef = ref<ElFormInstance>(); | ||||
| const purchaseDocFormRef = ref<ElFormInstance>(); | ||||
| const IP = 'http://192.168.110.151:7788'; | ||||
|  | ||||
| const dialog = reactive<DialogOption>({ | ||||
|   visible: false, | ||||
|   title: '' | ||||
| @ -480,8 +488,8 @@ const handleShare = async (row?: PurchaseDocVO) => { | ||||
|   }); | ||||
|   // 获取当前域名地址 | ||||
|   console.log(location); | ||||
|   textarea.value = IP + '/materials/purchaseDoc/uploadCode?data=' + data; | ||||
|   // textarea.value = location.host + '/materials/purchaseDoc/uploadCode?data=' + data; | ||||
|   // textarea.value = IP + '/materials/purchaseDoc/uploadCode?data=' + data; | ||||
|   textarea.value = location.host + '/materials/purchaseDoc/uploadCode?data=' + data; | ||||
|   textarea.style.position = 'fixed'; | ||||
|   textarea.style.opacity = '0'; | ||||
|   document.body.appendChild(textarea); | ||||
| @ -530,6 +538,12 @@ const handleViewDetail = async (row?: PurchaseDocVO) => { | ||||
|     type: 'view' | ||||
|   }); | ||||
| }; | ||||
| const getDetailList = async (id) => { | ||||
|   let res = await logisticsDetial(id); | ||||
|   if (res.code == 200) { | ||||
|     logisticsDetailRef.value.open(res.data); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| onMounted(() => { | ||||
|   getList(); | ||||
|  | ||||
| @ -13,7 +13,7 @@ | ||||
|         :header-cell-style="{ 'background-color': '#f5f7fa', 'font-weight': 'bold' }" | ||||
|         style="width: 100%; margin-bottom: 20px; height: calc(100vh - 305px)" | ||||
|         :row-class-name="tableRowClassName"> | ||||
|         <el-table-column prop="id" label="ID" width="80" align="center"></el-table-column> | ||||
|         <el-table-column prop="id" label="ID" width="180" align="center"></el-table-column> | ||||
|         <el-table-column prop="name" label="材料名称" min-width="150"></el-table-column> | ||||
|         <el-table-column prop="specification" label="规格" min-width="120"></el-table-column> | ||||
|         <el-table-column prop="supplier" label="供应商" min-width="150"></el-table-column> | ||||
| @ -456,27 +456,4 @@ onMounted(() => { | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
| /* 自定义表格行悬停样式 */ | ||||
| ::v-deep .el-table__row:hover>td { | ||||
|   background-color: #f0f7ff !important; | ||||
| } | ||||
|  | ||||
| /* 表单间距优化 */ | ||||
| ::v-deep .el-form-item { | ||||
|   margin-bottom: 16px; | ||||
| } | ||||
|  | ||||
| /* 对话框动画 */ | ||||
| ::v-deep .el-dialog__wrapper { | ||||
|   backdrop-filter: blur(2px); | ||||
| } | ||||
|  | ||||
| /* 按钮样式优化 */ | ||||
| ::v-deep .el-button--primary { | ||||
|   transition: all 0.2s ease; | ||||
| } | ||||
|  | ||||
| ::v-deep .el-button--primary:hover { | ||||
|   transform: translateY(-2px); | ||||
| } | ||||
| </style> | ||||
| @ -450,27 +450,4 @@ onMounted(() => { | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
| /* 自定义表格行悬停样式 */ | ||||
| ::v-deep .el-table__row:hover>td { | ||||
|   background-color: #f0f7ff !important; | ||||
| } | ||||
|  | ||||
| /* 表单间距优化 */ | ||||
| ::v-deep .el-form-item { | ||||
|   margin-bottom: 16px; | ||||
| } | ||||
|  | ||||
| /* 对话框动画 */ | ||||
| ::v-deep .el-dialog__wrapper { | ||||
|   backdrop-filter: blur(2px); | ||||
| } | ||||
|  | ||||
| /* 按钮样式优化 */ | ||||
| ::v-deep .el-button--primary { | ||||
|   transition: all 0.2s ease; | ||||
| } | ||||
|  | ||||
| ::v-deep .el-button--primary:hover { | ||||
|   transform: translateY(-2px); | ||||
| } | ||||
| </style> | ||||
|  | ||||
| @ -18,7 +18,7 @@ | ||||
|                 <!-- 基础信息列 --> | ||||
|                 <el-table-column prop="id" label="ID" width="180" align="center"></el-table-column> | ||||
|                 <el-table-column prop="batch" label="批次" align="center"></el-table-column> | ||||
|                 <el-table-column prop="physicalsupplyId" label="使用情况ID"  align="center"></el-table-column> | ||||
|                 <el-table-column prop="physicalsupplyId" label="使用情况ID" width="180" align="center"></el-table-column> | ||||
|                 <!-- 时间相关列 --> | ||||
|                 <el-table-column prop="issuanceTime" label="联系单下达时间" min-width="160" align="center"> | ||||
|                     <template #default="scope"> | ||||
|  | ||||
| @ -22,7 +22,7 @@ | ||||
|           <el-form | ||||
|             ref="leaveFormRef" | ||||
|             v-loading="loading" | ||||
|             :disabled="routeParams.type === 'view'" | ||||
|             :disabled="routeParams.type === 'view' || form.auditStatus == 'waiting'" | ||||
|             :model="form" | ||||
|             :rules="rules" | ||||
|             label-width="120px" | ||||
|  | ||||
| @ -22,7 +22,7 @@ | ||||
|           <el-form | ||||
|             ref="leaveFormRef" | ||||
|             v-loading="loading" | ||||
|             :disabled="routeParams.type === 'view'" | ||||
|             :disabled="routeParams.type === 'view' || form.completeAuditStatus == 'waiting'" | ||||
|             :model="form" | ||||
|             :rules="rules" | ||||
|             label-width="120px" | ||||
|  | ||||
| @ -22,7 +22,7 @@ | ||||
|           <el-form | ||||
|             ref="leaveFormRef" | ||||
|             v-loading="loading" | ||||
|             :disabled="routeParams.type === 'view'" | ||||
|             :disabled="routeParams.type === 'view' || form.status == 'waiting'" | ||||
|             :model="form" | ||||
|             :rules="rules" | ||||
|             label-width="120px" | ||||
|  | ||||
| @ -12,7 +12,14 @@ | ||||
|       /> | ||||
|     </el-card> | ||||
|     <el-card shadow="never" style="height: 78vh; overflow-y: auto"> | ||||
|       <el-form ref="leaveFormRef" v-loading="loading" :disabled="routeParams.type === 'view'" :model="form" :rules="rules" label-width="80px"> | ||||
|       <el-form | ||||
|         ref="leaveFormRef" | ||||
|         v-loading="loading" | ||||
|         :disabled="routeParams.type === 'view' || form.status == 'waiting'" | ||||
|         :model="form" | ||||
|         :rules="rules" | ||||
|         label-width="80px" | ||||
|       > | ||||
|         <el-form-item label="请假类型" prop="leaveType"> | ||||
|           <el-select v-model="form.leaveType" placeholder="请选择请假类型" style="width: 100%"> | ||||
|             <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" /> | ||||
| @ -284,7 +291,7 @@ const approvalVerifyOpen = async () => { | ||||
|  | ||||
| onMounted(() => { | ||||
|   console.log(proxy.$route.query); | ||||
|    | ||||
|  | ||||
|   nextTick(async () => { | ||||
|     routeParams.value = proxy.$route.query; | ||||
|     reset(); | ||||
|  | ||||
		Reference in New Issue
	
	Block a user