0905
This commit is contained in:
		| @ -94,3 +94,10 @@ export function getRemoveBind(data: { id: number; clientId: string }) { | |||||||
|     data: data |     data: data | ||||||
|   }); |   }); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | export function getProjectId() { | ||||||
|  |   return request({ | ||||||
|  |     url: 'gps/equipment/getProjectList', | ||||||
|  |     method: 'get' | ||||||
|  |   }); | ||||||
|  | } | ||||||
|  | |||||||
| @ -117,6 +117,10 @@ export interface EquipmentQuery extends PageQuery { | |||||||
|    * 项目ID |    * 项目ID | ||||||
|    */ |    */ | ||||||
|   projectId?: string | number; |   projectId?: string | number; | ||||||
|  |   /** | ||||||
|  |    * 是否绑定 | ||||||
|  |    */ | ||||||
|  |   type?: string | number; | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * 用户id |    * 用户id | ||||||
|  | |||||||
							
								
								
									
										18
									
								
								src/views/equipment/equipmentGPS.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/views/equipment/equipmentGPS.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | |||||||
|  | <template> | ||||||
|  |   <div class="text-center py-10"> | ||||||
|  |     <el-button type="primary" @click="handleGoBack">返回上一页</el-button> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script setup name="EmptyPage" lang="ts"> | ||||||
|  | import { useRouter } from 'vue-router'; | ||||||
|  |  | ||||||
|  | const router = useRouter(); | ||||||
|  |  | ||||||
|  | // 返回上一页 | ||||||
|  | const handleGoBack = () => { | ||||||
|  |   router.go(-1); | ||||||
|  | }; | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style scoped></style> | ||||||
| @ -41,6 +41,12 @@ | |||||||
|           <el-col :span="2"> |           <el-col :span="2"> | ||||||
|             <el-button type="primary" plain @click="handleViewAll" v-hasPermi="['system:equipment:view']">{{ viewAllButtonText }}</el-button> |             <el-button type="primary" plain @click="handleViewAll" v-hasPermi="['system:equipment:view']">{{ viewAllButtonText }}</el-button> | ||||||
|           </el-col> |           </el-col> | ||||||
|  |  | ||||||
|  |           <!-- 新增:跳转空页面按钮 --> | ||||||
|  |           <el-col :span="2"> | ||||||
|  |             <el-button type="primary" plain icon="international" @click="handleGoToEmptyPage"> GPS定位 </el-button> | ||||||
|  |           </el-col> | ||||||
|  |  | ||||||
|           <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |           <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> | ||||||
|         </el-row> |         </el-row> | ||||||
|       </template> |       </template> | ||||||
| @ -48,11 +54,20 @@ | |||||||
|       <el-table v-loading="loading" :data="equipmentList" @selection-change="handleSelectionChange"> |       <el-table v-loading="loading" :data="equipmentList" @selection-change="handleSelectionChange"> | ||||||
|         <el-table-column type="selection" width="55" align="center" /> |         <el-table-column type="selection" width="55" align="center" /> | ||||||
|  |  | ||||||
|         <el-table-column label="项目ID" align="center" prop="projectId" /> |         <el-table-column label="项目名称" align="center" prop="projectName" /> | ||||||
|         <el-table-column label="用户id" align="center" prop="userId" /> |         <el-table-column label="用户名称" align="center" prop="userName" /> | ||||||
|         <el-table-column label="设备标识" align="center" prop="clientId" /> |         <el-table-column label="设备标识" align="center" prop="clientId" /> | ||||||
|  |  | ||||||
|         <!-- 设备名称列(点击触发历史用户弹窗,传入【项目ID+当前用户ID】) --> |         <!-- 绑定状态列 --> | ||||||
|  |         <el-table-column label="绑定状态" align="center"> | ||||||
|  |           <template #default="scope"> | ||||||
|  |             <el-tag :type="scope.row.type === 1 ? 'success' : 'warning'" size="small"> | ||||||
|  |               {{ scope.row.type === 1 ? '已绑定' : '未绑定' }} | ||||||
|  |             </el-tag> | ||||||
|  |           </template> | ||||||
|  |         </el-table-column> | ||||||
|  |  | ||||||
|  |         <!-- 设备名称列 --> | ||||||
|         <el-table-column label="设备名称" align="center"> |         <el-table-column label="设备名称" align="center"> | ||||||
|           <template #default="scope"> |           <template #default="scope"> | ||||||
|             <el-button |             <el-button | ||||||
| @ -85,12 +100,12 @@ | |||||||
|             <el-tooltip content="删除" placement="top"> |             <el-tooltip content="删除" placement="top"> | ||||||
|               <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['gps:equipment:remove']"></el-button> |               <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['gps:equipment:remove']"></el-button> | ||||||
|             </el-tooltip> |             </el-tooltip> | ||||||
|             <el-tooltip :content="scope.row.userId ? '取消绑定' : '绑定用户'" placement="top"> |             <el-tooltip :content="scope.row.type === 1 ? '取消绑定' : '绑定用户'" placement="top"> | ||||||
|               <el-button |               <el-button | ||||||
|                 link |                 link | ||||||
|                 type="primary" |                 type="primary" | ||||||
|                 icon="User" |                 icon="User" | ||||||
|                 @click="scope.row.userId ? handleUnbindUser(scope.row) : handleBindUser(scope.row)" |                 @click="scope.row.type === 1 ? handleUnbindUser(scope.row) : handleBindUser(scope.row)" | ||||||
|                 v-hasPermi="['gps:equipment:bindUser']" |                 v-hasPermi="['gps:equipment:bindUser']" | ||||||
|               > |               > | ||||||
|               </el-button> |               </el-button> | ||||||
| @ -120,9 +135,10 @@ | |||||||
|     <!-- 绑定用户对话框 --> |     <!-- 绑定用户对话框 --> | ||||||
|     <el-dialog title="绑定用户" v-model="bindDialogVisible" width="500px" append-to-body> |     <el-dialog title="绑定用户" v-model="bindDialogVisible" width="500px" append-to-body> | ||||||
|       <el-form ref="bindUserFormRef" :model="bindForm" :rules="bindRules" label-width="80px"> |       <el-form ref="bindUserFormRef" :model="bindForm" :rules="bindRules" label-width="80px"> | ||||||
|  |         <!-- 绑定用户对话框 - 项目选择下拉框 --> | ||||||
|         <el-form-item label="项目选择" prop="projectId" required> |         <el-form-item label="项目选择" prop="projectId" required> | ||||||
|           <el-select v-model="bindForm.projectId" placeholder="请选择项目" clearable @change="handleProjectChange"> |           <el-select v-model="bindForm.projectId" placeholder="请选择项目" clearable @change="handleProjectChange"> | ||||||
|             <el-option v-for="project in projectList" :key="project.id" :label="project.name" :value="project.id" /> |             <el-option v-for="project in projectList" :key="project.projectId" :label="project.projectName" :value="project.projectId" /> | ||||||
|           </el-select> |           </el-select> | ||||||
|         </el-form-item> |         </el-form-item> | ||||||
|         <el-form-item label="设备名称" prop="deviceName"> |         <el-form-item label="设备名称" prop="deviceName"> | ||||||
| @ -143,20 +159,8 @@ | |||||||
|     </el-dialog> |     </el-dialog> | ||||||
|  |  | ||||||
|     <!-- 历史用户弹窗 --> |     <!-- 历史用户弹窗 --> | ||||||
|     <el-dialog |     <el-dialog title="设备历史用户" v-model="historyUserDialogVisible" width="600px" append-to-body @close="() => historyUserList.splice(0)"> | ||||||
|       title="设备历史用户" |  | ||||||
|       v-model="historyUserDialogVisible" |  | ||||||
|       width="600px" |  | ||||||
|       append-to-body |  | ||||||
|       @close=" |  | ||||||
|         () => { |  | ||||||
|           historyUserList.splice(0); |  | ||||||
|         } |  | ||||||
|       " |  | ||||||
|     > |  | ||||||
|       <!-- 加载状态 --> |  | ||||||
|       <div v-loading="historyUserLoading" style="min-height: 200px; padding: 16px"> |       <div v-loading="historyUserLoading" style="min-height: 200px; padding: 16px"> | ||||||
|         <!-- 历史用户列表 --> |  | ||||||
|         <el-table |         <el-table | ||||||
|           :data="historyUserList" |           :data="historyUserList" | ||||||
|           stripe |           stripe | ||||||
| @ -168,15 +172,13 @@ | |||||||
|           <el-table-column label="用户名" align="center" prop="userName" /> |           <el-table-column label="用户名" align="center" prop="userName" /> | ||||||
|           <el-table-column label="状态" align="center" width="120"> |           <el-table-column label="状态" align="center" width="120"> | ||||||
|             <template #default="scope"> |             <template #default="scope"> | ||||||
|               <!-- 通过scope.row.type获取当前行的状态值,判断后显示对应内容 --> |               <el-tag :type="scope.row.type === 0 ? 'success' : 'info'" size="small"> | ||||||
|               <el-tag :type="scope.row.type === 1 ? 'success' : 'info'" size="small"> |                 {{ scope.row.type === 0 ? '当前绑定' : '历史绑定' }} | ||||||
|                 {{ scope.row.type === 1 ? '当前绑定' : '历史绑定' }} |  | ||||||
|               </el-tag> |               </el-tag> | ||||||
|             </template> |             </template> | ||||||
|           </el-table-column> |           </el-table-column> | ||||||
|         </el-table> |         </el-table> | ||||||
|  |  | ||||||
|         <!-- 历史用户弹窗-无数据提示 --> |  | ||||||
|         <div v-if="!historyUserLoading && historyUserList.length === 0" style="text-align: center; padding: 50px 0"> |         <div v-if="!historyUserLoading && historyUserList.length === 0" style="text-align: center; padding: 50px 0"> | ||||||
|           <el-empty description="暂无该设备的历史用户数据"></el-empty> |           <el-empty description="暂无该设备的历史用户数据"></el-empty> | ||||||
|         </div> |         </div> | ||||||
| @ -190,7 +192,6 @@ | |||||||
| </template> | </template> | ||||||
|  |  | ||||||
| <script setup name="Equipment" lang="ts"> | <script setup name="Equipment" lang="ts"> | ||||||
| // 导入历史用户接口(确保API文件中存在该接口) |  | ||||||
| import { | import { | ||||||
|   listEquipment, |   listEquipment, | ||||||
|   getEquipment, |   getEquipment, | ||||||
| @ -200,17 +201,24 @@ import { | |||||||
|   bindUser, |   bindUser, | ||||||
|   getUserId, |   getUserId, | ||||||
|   gethistroyUser, |   gethistroyUser, | ||||||
|   getRemoveBind |   getRemoveBind, | ||||||
|  |   getProjectId | ||||||
| } from '@/api/equipment/index'; | } from '@/api/equipment/index'; | ||||||
| import { listProject } from '@/api/project/project/index'; |  | ||||||
| import { EquipmentVO, EquipmentQuery, EquipmentForm } from '@/api/equipment/types'; | import { EquipmentVO, EquipmentQuery, EquipmentForm } from '@/api/equipment/types'; | ||||||
| import { getCurrentInstance, ComponentInternalInstance, onMounted, ref, reactive, toRefs, watch, computed } from 'vue'; | import { getCurrentInstance, ComponentInternalInstance, onMounted, ref, reactive, toRefs, watch, computed } from 'vue'; | ||||||
| import { useUserStoreHook } from '@/store/modules/user'; | import { useUserStoreHook } from '@/store/modules/user'; | ||||||
| import { Row } from 'element-plus/es/components/table-v2/src/components/index.mjs'; | import { useRouter } from 'vue-router'; // 新增:导入路由钩子 | ||||||
|  |  | ||||||
| const { proxy } = getCurrentInstance() as ComponentInternalInstance; | const { proxy } = getCurrentInstance() as ComponentInternalInstance; | ||||||
|  | const router = useRouter(); // 新增:初始化路由实例 | ||||||
|  |  | ||||||
|  | // 扩展EquipmentVO类型,添加type字段 | ||||||
|  | interface ExtendedEquipmentVO extends EquipmentVO { | ||||||
|  |   type: 1 | 2; // 1=已绑定,2=未绑定 | ||||||
|  | } | ||||||
|  |  | ||||||
| // 设备列表相关 | // 设备列表相关 | ||||||
| const equipmentList = ref<EquipmentVO[]>([]); | const equipmentList = ref<ExtendedEquipmentVO[]>([]); | ||||||
| const buttonLoading = ref(false); | const buttonLoading = ref(false); | ||||||
| const loading = ref(true); | const loading = ref(true); | ||||||
| const showSearch = ref(true); | const showSearch = ref(true); | ||||||
| @ -218,7 +226,6 @@ const ids = ref<Array<string | number>>([]); | |||||||
| const single = ref(true); | const single = ref(true); | ||||||
| const multiple = ref(true); | const multiple = ref(true); | ||||||
| const total = ref(0); | const total = ref(0); | ||||||
| const isViewAll = ref(false); // 标记是否处于查看全部模式 |  | ||||||
|  |  | ||||||
| // 表单相关引用 | // 表单相关引用 | ||||||
| const queryFormRef = ref<ElFormInstance>(); | const queryFormRef = ref<ElFormInstance>(); | ||||||
| @ -228,12 +235,12 @@ const bindUserFormRef = ref<ElFormInstance>(); | |||||||
| // 项目和用户相关 | // 项目和用户相关 | ||||||
| const userStore = useUserStoreHook(); | const userStore = useUserStoreHook(); | ||||||
| const currentProject = computed(() => userStore.selectedProject); | const currentProject = computed(() => userStore.selectedProject); | ||||||
| const userList = ref<any[]>([]); // 存储获取到的用户列表 | const userList = ref<any[]>([]); | ||||||
| const projectList = ref<any[]>([]); // 存储获取到的项目列表 | const projectList = ref<any[]>([]); | ||||||
| const projectLoading = ref(false); // 项目列表加载状态 | const projectLoading = ref(false); | ||||||
| const userLoading = ref(false); // 用户列表加载状态 | const userLoading = ref(false); | ||||||
| const viewAllButtonText = computed(() => { | const viewAllButtonText = computed(() => { | ||||||
|   return isViewAll.value ? '查看已绑定设备' : '查看未绑定设备'; |   return queryParams.value.type === 1 ? '查看未绑定设备' : '查看已绑定设备'; | ||||||
| }); | }); | ||||||
|  |  | ||||||
| // 对话框相关 | // 对话框相关 | ||||||
| @ -244,10 +251,10 @@ const dialog = reactive<DialogOption>({ | |||||||
| const bindDialogVisible = ref(false); | const bindDialogVisible = ref(false); | ||||||
| const bindButtonLoading = ref(false); | const bindButtonLoading = ref(false); | ||||||
|  |  | ||||||
| // 历史用户弹窗相关状态(移除无用的currentDeviceId) | // 历史用户弹窗相关 | ||||||
| const historyUserDialogVisible = ref(false); // 历史用户弹窗可见性 | const historyUserDialogVisible = ref(false); | ||||||
| const historyUserList = ref<HistoryUserVO[]>([]); // 历史用户列表 | const historyUserList = ref<HistoryUserVO[]>([]); | ||||||
| const historyUserLoading = ref(false); // 历史用户接口加载状态 | const historyUserLoading = ref(false); | ||||||
|  |  | ||||||
| // 绑定用户表单数据 | // 绑定用户表单数据 | ||||||
| const bindForm = reactive({ | const bindForm = reactive({ | ||||||
| @ -268,7 +275,6 @@ const initFormData: EquipmentForm = { | |||||||
|   id: undefined, |   id: undefined, | ||||||
|   projectId: undefined, |   projectId: undefined, | ||||||
|   userId: undefined, |   userId: undefined, | ||||||
|   clientId: undefined, |  | ||||||
|   deviceName: undefined, |   deviceName: undefined, | ||||||
|   udp: undefined, |   udp: undefined, | ||||||
|   remoteAddressStr: undefined, |   remoteAddressStr: undefined, | ||||||
| @ -282,6 +288,7 @@ const initFormData: EquipmentForm = { | |||||||
| const data = reactive<PageData<EquipmentForm, EquipmentQuery>>({ | const data = reactive<PageData<EquipmentForm, EquipmentQuery>>({ | ||||||
|   form: { ...initFormData }, |   form: { ...initFormData }, | ||||||
|   queryParams: { |   queryParams: { | ||||||
|  |     type: 1, // 默认查询已绑定设备 | ||||||
|     pageNum: 1, |     pageNum: 1, | ||||||
|     pageSize: 10, |     pageSize: 10, | ||||||
|     projectId: undefined, |     projectId: undefined, | ||||||
| @ -302,11 +309,7 @@ const data = reactive<PageData<EquipmentForm, EquipmentQuery>>({ | |||||||
|  |  | ||||||
| const { queryParams, form, rules } = toRefs(data); | const { queryParams, form, rules } = toRefs(data); | ||||||
|  |  | ||||||
| /** | /** 格式化日期时间 */ | ||||||
|  * 格式化日期时间 |  | ||||||
|  * @param timestamp 时间戳、日期字符串或自定义的 yyyyMMddHHmmss 格式数字 |  | ||||||
|  * @returns 格式化后的日期时间字符串(yyyy-MM-dd HH:mm:ss) |  | ||||||
|  */ |  | ||||||
| const formatDateTime = (timestamp: any): string => { | const formatDateTime = (timestamp: any): string => { | ||||||
|   if (!timestamp) return '-'; |   if (!timestamp) return '-'; | ||||||
|  |  | ||||||
| @ -365,21 +368,20 @@ const formatDateTime = (timestamp: any): string => { | |||||||
|   return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; |   return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | /** 获取设备列表 */ | ||||||
| const getList = async () => { | const getList = async () => { | ||||||
|   loading.value = true; |   loading.value = true; | ||||||
|   try { |   try { | ||||||
|     // 仅当projectId有实际值(非undefined、非null)时,才退出未绑定模式 |     // 已绑定设备默认关联当前项目 | ||||||
|     if (queryParams.value.projectId !== undefined && queryParams.value.projectId !== null) { |     if (queryParams.value.type === 1 && currentProject.value?.id && !queryParams.value.projectId) { | ||||||
|       isViewAll.value = false; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // 已绑定模式下:若未选项目,自动用当前项目补全筛选 |  | ||||||
|     if (!isViewAll.value && currentProject.value?.id && queryParams.value.projectId === undefined) { |  | ||||||
|       queryParams.value.projectId = currentProject.value.id; |       queryParams.value.projectId = currentProject.value.id; | ||||||
|  |     } else if (queryParams.value.type === 2) { | ||||||
|  |       // 未绑定设备清空项目筛选 | ||||||
|  |       queryParams.value.projectId = undefined; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     const res = await listEquipment(queryParams.value); |     const res = await listEquipment(queryParams.value); | ||||||
|     equipmentList.value = res.rows; |     equipmentList.value = res.rows as ExtendedEquipmentVO[]; | ||||||
|     total.value = res.total; |     total.value = res.total; | ||||||
|   } catch (error) { |   } catch (error) { | ||||||
|     console.error('获取设备列表失败:', error); |     console.error('获取设备列表失败:', error); | ||||||
| @ -392,10 +394,31 @@ const getList = async () => { | |||||||
| const getProjects = async () => { | const getProjects = async () => { | ||||||
|   projectLoading.value = true; |   projectLoading.value = true; | ||||||
|   try { |   try { | ||||||
|     const res = await listProject(); |     const res = await getProjectId(); | ||||||
|     projectList.value = res.rows || []; |     console.log('getProjectId接口原始返回:', res); | ||||||
|  |  | ||||||
|  |     // 从res.data中获取数组(适配外层包裹的接口格式) | ||||||
|  |     const rawProjects = res?.data || []; | ||||||
|  |  | ||||||
|  |     // 验证数据类型,确保是数组 | ||||||
|  |     if (!Array.isArray(rawProjects)) { | ||||||
|  |       console.warn('接口返回的项目数据不是数组,已自动修正为空数组'); | ||||||
|  |       projectList.value = []; | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // 处理项目数据(使用projectId和projectName) | ||||||
|  |     projectList.value = rawProjects | ||||||
|  |       .map((project) => ({ | ||||||
|  |         projectId: project.projectId, | ||||||
|  |         projectName: project.projectName || '未命名项目' | ||||||
|  |       })) | ||||||
|  |       .filter((project) => project.projectId); | ||||||
|  |  | ||||||
|  |     console.log('处理后项目列表:', projectList.value); | ||||||
|   } catch (error) { |   } catch (error) { | ||||||
|     console.error('获取项目列表失败:', error); |     console.error('获取项目列表失败:', error); | ||||||
|  |     proxy?.$modal.msgError('获取项目列表失败,请重试'); | ||||||
|   } finally { |   } finally { | ||||||
|     projectLoading.value = false; |     projectLoading.value = false; | ||||||
|   } |   } | ||||||
| @ -422,30 +445,40 @@ const getUsersByProjectId = async (projectId: any) => { | |||||||
|  |  | ||||||
| /** 项目选择变化时触发 */ | /** 项目选择变化时触发 */ | ||||||
| const handleProjectChange = (projectId: any) => { | const handleProjectChange = (projectId: any) => { | ||||||
|   isViewAll.value = false; |  | ||||||
|   bindForm.userId = undefined; |   bindForm.userId = undefined; | ||||||
|   getUsersByProjectId(projectId); |   getUsersByProjectId(projectId); | ||||||
|  |  | ||||||
|  |   // 仅已绑定设备需要更新项目筛选 | ||||||
|  |   if (queryParams.value.type === 1) { | ||||||
|     queryParams.value.projectId = projectId; |     queryParams.value.projectId = projectId; | ||||||
|     getList(); |     getList(); | ||||||
|  |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /** 切换:查看未绑定设备(无projectId) / 查看已绑定设备(有projectId) */ | /** 切换查看已绑定/未绑定设备 */ | ||||||
| const handleViewAll = () => { | const handleViewAll = () => { | ||||||
|   queryParams.value.pageNum = 1; |   queryParams.value.pageNum = 1; | ||||||
|  |  | ||||||
|   if (!isViewAll.value) { |   if (queryParams.value.type === 1) { | ||||||
|     queryParams.value.projectId = null; |     // 切换到未绑定设备 | ||||||
|     isViewAll.value = true; |     queryParams.value.type = 2; | ||||||
|     proxy?.$modal.msgSuccess('已切换到查看未绑定设备模式(仅显示无项目设备)'); |     proxy?.$modal.msgSuccess('已切换到查看未绑定设备模式'); | ||||||
|   } else { |   } else { | ||||||
|  |     // 切换到已绑定设备 | ||||||
|  |     queryParams.value.type = 1; | ||||||
|     queryParams.value.projectId = currentProject.value?.id; |     queryParams.value.projectId = currentProject.value?.id; | ||||||
|     isViewAll.value = false; |     proxy?.$modal.msgSuccess('已切换到查看已绑定设备模式'); | ||||||
|     proxy?.$modal.msgSuccess('已切换到查看已绑定设备模式(仅显示当前项目设备)'); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   getList(); |   getList(); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | const handleGoToEmptyPage = () => { | ||||||
|  |   router.push({ | ||||||
|  |     path: './equipmentGPS' | ||||||
|  |   }); | ||||||
|  | }; | ||||||
|  |  | ||||||
| /** 取消按钮 */ | /** 取消按钮 */ | ||||||
| const cancel = () => { | const cancel = () => { | ||||||
|   reset(); |   reset(); | ||||||
| @ -460,28 +493,27 @@ const reset = () => { | |||||||
|  |  | ||||||
| /** 搜索按钮操作 */ | /** 搜索按钮操作 */ | ||||||
| const handleQuery = () => { | const handleQuery = () => { | ||||||
|   isViewAll.value = false; |  | ||||||
|   queryParams.value.pageNum = 1; |   queryParams.value.pageNum = 1; | ||||||
|   getList(); |   getList(); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /** 重置按钮操作 */ | /** 重置按钮操作 */ | ||||||
| const resetQuery = () => { | const resetQuery = () => { | ||||||
|   isViewAll.value = false; |  | ||||||
|   queryFormRef.value?.resetFields(); |   queryFormRef.value?.resetFields(); | ||||||
|  |   queryParams.value.type = 1; | ||||||
|   queryParams.value.projectId = currentProject.value?.id; |   queryParams.value.projectId = currentProject.value?.id; | ||||||
|   handleQuery(); |   handleQuery(); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /** 多选框选中数据 */ | /** 多选框选中数据 */ | ||||||
| const handleSelectionChange = (selection: EquipmentVO[]) => { | const handleSelectionChange = (selection: ExtendedEquipmentVO[]) => { | ||||||
|   ids.value = selection.map((item) => item.id); |   ids.value = selection.map((item) => item.id); | ||||||
|   single.value = selection.length != 1; |   single.value = selection.length != 1; | ||||||
|   multiple.value = !selection.length; |   multiple.value = !selection.length; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /** 修改按钮操作 */ | /** 修改按钮操作 */ | ||||||
| const handleUpdate = async (row?: EquipmentVO) => { | const handleUpdate = async (row?: ExtendedEquipmentVO) => { | ||||||
|   reset(); |   reset(); | ||||||
|   const _id = row?.id || ids.value[0]; |   const _id = row?.id || ids.value[0]; | ||||||
|   try { |   try { | ||||||
| @ -495,6 +527,7 @@ const handleUpdate = async (row?: EquipmentVO) => { | |||||||
|   } |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | /** 提交表单 */ | ||||||
| const submitForm = () => { | const submitForm = () => { | ||||||
|   equipmentFormRef.value?.validate(async (valid: boolean) => { |   equipmentFormRef.value?.validate(async (valid: boolean) => { | ||||||
|     if (valid) { |     if (valid) { | ||||||
| @ -519,7 +552,7 @@ const submitForm = () => { | |||||||
| }; | }; | ||||||
|  |  | ||||||
| /** 删除按钮操作 */ | /** 删除按钮操作 */ | ||||||
| const handleDelete = async (row?: EquipmentVO) => { | const handleDelete = async (row?: ExtendedEquipmentVO) => { | ||||||
|   const _ids = row?.id || ids.value; |   const _ids = row?.id || ids.value; | ||||||
|   try { |   try { | ||||||
|     await proxy?.$modal.confirm('是否确认删除GPS设备详细编号为"' + _ids + '"的数据项?'); |     await proxy?.$modal.confirm('是否确认删除GPS设备详细编号为"' + _ids + '"的数据项?'); | ||||||
| @ -540,7 +573,7 @@ const handleBindUser = async (row?: EquipmentVO) => { | |||||||
|     id: undefined, |     id: undefined, | ||||||
|     projectId: undefined, |     projectId: undefined, | ||||||
|     userId: undefined, |     userId: undefined, | ||||||
|     clientId: row?.clientId, // 从行数据中获取clientId并保存到bindForm |     clientId: row?.clientId, | ||||||
|     deviceName: undefined |     deviceName: undefined | ||||||
|   }); |   }); | ||||||
|   bindUserFormRef.value?.resetFields(); |   bindUserFormRef.value?.resetFields(); | ||||||
| @ -550,10 +583,8 @@ const handleBindUser = async (row?: EquipmentVO) => { | |||||||
|   try { |   try { | ||||||
|     const res = await getEquipment(_id); |     const res = await getEquipment(_id); | ||||||
|     const equipmentData = res.data; |     const equipmentData = res.data; | ||||||
|  |  | ||||||
|     bindForm.id = equipmentData.id; |     bindForm.id = equipmentData.id; | ||||||
|     bindForm.deviceName = equipmentData.deviceName; |     bindForm.deviceName = equipmentData.deviceName; | ||||||
|     // 确保clientId正确赋值,优先使用行数据中的值 |  | ||||||
|     bindForm.clientId = row?.clientId || equipmentData.clientId; |     bindForm.clientId = row?.clientId || equipmentData.clientId; | ||||||
|  |  | ||||||
|     if (projectList.value.length === 0) { |     if (projectList.value.length === 0) { | ||||||
| @ -577,10 +608,8 @@ const handleBindUser = async (row?: EquipmentVO) => { | |||||||
|  |  | ||||||
| /** 提交绑定用户 */ | /** 提交绑定用户 */ | ||||||
| const submitBindUser = () => { | const submitBindUser = () => { | ||||||
|   // 移除多余的row参数,因为方法没有接收该参数 |  | ||||||
|   bindUserFormRef.value?.validate(async (valid: boolean) => { |   bindUserFormRef.value?.validate(async (valid: boolean) => { | ||||||
|     if (valid) { |     if (valid) { | ||||||
|       // 验证clientId是否存在 |  | ||||||
|       if (!bindForm.clientId) { |       if (!bindForm.clientId) { | ||||||
|         proxy?.$modal.msgWarning('设备标识clientId不存在,无法完成绑定'); |         proxy?.$modal.msgWarning('设备标识clientId不存在,无法完成绑定'); | ||||||
|         bindButtonLoading.value = false; |         bindButtonLoading.value = false; | ||||||
| @ -593,11 +622,10 @@ const submitBindUser = () => { | |||||||
|           id: bindForm.id, |           id: bindForm.id, | ||||||
|           projectId: bindForm.projectId, |           projectId: bindForm.projectId, | ||||||
|           userId: bindForm.userId, |           userId: bindForm.userId, | ||||||
|           clientId: bindForm.clientId, // 从bindForm获取clientId |           clientId: bindForm.clientId, | ||||||
|           deviceName: bindForm.deviceName |           deviceName: bindForm.deviceName | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         // 打印参数日志,确认clientId已正确传递 |  | ||||||
|         console.log('提交绑定用户参数:', bindData); |         console.log('提交绑定用户参数:', bindData); | ||||||
|  |  | ||||||
|         await bindUser(bindData); |         await bindUser(bindData); | ||||||
| @ -614,29 +642,19 @@ const submitBindUser = () => { | |||||||
|   }); |   }); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /** 取消绑定用户 */ | /** 取消绑定用户对话框 */ | ||||||
| const cancelBindUser = () => { | const cancelBindUser = () => { | ||||||
|   bindDialogVisible.value = false; |   bindDialogVisible.value = false; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /** 取消用户绑定操作 */ | /** 取消用户绑定操作 */ | ||||||
| const handleUnbindUser = async (row: EquipmentVO) => { | const handleUnbindUser = async (row: ExtendedEquipmentVO) => { | ||||||
|   try { |   try { | ||||||
|     // 1. 打印完整行数据用于调试 |  | ||||||
|     console.log('解除绑定 - 原始行数据:', { |  | ||||||
|       rowId: row.id, |  | ||||||
|       rowIdType: typeof row.id, |  | ||||||
|       clientId: row.clientId, |  | ||||||
|       clientIdType: typeof row.clientId |  | ||||||
|     }); |  | ||||||
|  |  | ||||||
|     // 2. 严格验证参数 |  | ||||||
|     if (!row) { |     if (!row) { | ||||||
|       proxy?.$modal.msgWarning('未获取到设备信息'); |       proxy?.$modal.msgWarning('未获取到设备信息'); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // 验证id |  | ||||||
|     if (row.id === undefined || row.id === null || row.id === '') { |     if (row.id === undefined || row.id === null || row.id === '') { | ||||||
|       proxy?.$modal.msgWarning('设备ID不能为空'); |       proxy?.$modal.msgWarning('设备ID不能为空'); | ||||||
|       return; |       return; | ||||||
| @ -647,66 +665,41 @@ const handleUnbindUser = async (row: EquipmentVO) => { | |||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // 验证clientId |  | ||||||
|     if (!row.clientId || typeof row.clientId !== 'string' || row.clientId.trim() === '') { |     if (!row.clientId || typeof row.clientId !== 'string' || row.clientId.trim() === '') { | ||||||
|       proxy?.$modal.msgWarning(`设备标识clientId格式错误,必须是非空字符串,当前值: ${row.clientId}`); |       proxy?.$modal.msgWarning(`设备标识clientId格式错误,必须是非空字符串,当前值: ${row.clientId}`); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|     const clientId = row.clientId.trim(); |     const clientId = row.clientId.trim(); | ||||||
|  |  | ||||||
|     // 3. 构建符合要求的参数对象 |  | ||||||
|     const unbindParams = { |     const unbindParams = { | ||||||
|       id: deviceId, // 确保是数字类型 |       id: deviceId, | ||||||
|       clientId: clientId // 确保是字符串类型 |       clientId: clientId | ||||||
|     }; |     }; | ||||||
|     console.log('解除绑定 - 发送参数:', unbindParams); |  | ||||||
|     console.log('解除绑定 - 参数类型:', { |  | ||||||
|       idType: typeof unbindParams.id, |  | ||||||
|       clientIdType: typeof unbindParams.clientId |  | ||||||
|     }); |  | ||||||
|  |  | ||||||
|     // 4. 确认对话框 |  | ||||||
|     await proxy?.$modal.confirm('是否确认解除该设备的用户绑定?'); |     await proxy?.$modal.confirm('是否确认解除该设备的用户绑定?'); | ||||||
|  |  | ||||||
|     // 5. 调用接口并记录请求详情 |  | ||||||
|     console.log('解除绑定 - 开始调用接口:', '/equipment/removeBind'); |  | ||||||
|     const response = await getRemoveBind(unbindParams); |     const response = await getRemoveBind(unbindParams); | ||||||
|  |  | ||||||
|     // 6. 记录接口响应 |  | ||||||
|     console.log('解除绑定 - 接口响应:', response); |  | ||||||
|  |  | ||||||
|     // 7. 验证响应是否成功 |  | ||||||
|     if (response && response.code === 200) { |     if (response && response.code === 200) { | ||||||
|       // 根据实际接口成功标识调整 |  | ||||||
|       proxy?.$modal.msgSuccess('解除绑定成功'); |       proxy?.$modal.msgSuccess('解除绑定成功'); | ||||||
|       await getList(); |       await getList(); | ||||||
|     } else { |     } else { | ||||||
|       throw new Error(`接口返回非成功状态: ${JSON.stringify(response)}`); |       throw new Error(`接口返回非成功状态: ${JSON.stringify(response)}`); | ||||||
|     } |     } | ||||||
|   } catch (error) { |   } catch (error) { | ||||||
|     // 详细错误信息记录 |  | ||||||
|     console.error('解除绑定 - 错误详情:', error); |     console.error('解除绑定 - 错误详情:', error); | ||||||
|     console.error('解除绑定 - 错误堆栈:', error instanceof Error ? error.stack : '无堆栈信息'); |  | ||||||
|  |  | ||||||
|     // 区分不同错误类型 |  | ||||||
|     if (error === 'cancel' || (error instanceof Error && error.message.includes('cancel'))) { |     if (error === 'cancel' || (error instanceof Error && error.message.includes('cancel'))) { | ||||||
|       console.log('用户取消了解除绑定操作'); |       console.log('用户取消了解除绑定操作'); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // 显示更具体的错误信息 |  | ||||||
|     const errorMsg = error instanceof Error ? error.message : typeof error === 'string' ? error : '未知错误'; |     const errorMsg = error instanceof Error ? error.message : typeof error === 'string' ? error : '未知错误'; | ||||||
|     proxy?.$modal.msgError(`解除绑定失败: ${errorMsg}`); |     proxy?.$modal.msgError(`解除绑定失败: ${errorMsg}`); | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /** | /** 打开历史用户弹窗 */ | ||||||
|  * 打开历史用户弹窗(修改后:传入clientId和当前用户ID) |  | ||||||
|  * @param clientId 设备标识(原deviceId参数替换为clientId) |  | ||||||
|  * @param currentUserId 当前绑定的用户ID |  | ||||||
|  */ |  | ||||||
| const handleOpenHistoryUser = async (clientId: string | number | undefined, currentUserId: string | number | undefined) => { | const handleOpenHistoryUser = async (clientId: string | number | undefined, currentUserId: string | number | undefined) => { | ||||||
|   // 边界校验:改为校验clientId是否存在(而非原deviceId) |  | ||||||
|   if (!clientId) { |   if (!clientId) { | ||||||
|     proxy?.$modal.msgWarning('设备标识(clientId)不存在,无法获取历史用户'); |     proxy?.$modal.msgWarning('设备标识(clientId)不存在,无法获取历史用户'); | ||||||
|     return; |     return; | ||||||
| @ -717,16 +710,13 @@ const handleOpenHistoryUser = async (clientId: string | number | undefined, curr | |||||||
|   historyUserList.value = []; |   historyUserList.value = []; | ||||||
|  |  | ||||||
|   try { |   try { | ||||||
|     // 关键修改:接口调用时传递 clientId(而非原deviceId) |  | ||||||
|     // 注意:需确认后端接口接收「设备标识」的参数名(此处假设为 clientId,若后端仍用 id 则改为 id: clientId) |  | ||||||
|     const res = await gethistroyUser({ |     const res = await gethistroyUser({ | ||||||
|       clientId: clientId, // 传递设备标识(参数名需与后端接口一致,如后端用id则改为 id: clientId) |       clientId: clientId, | ||||||
|       userId: currentUserId || '' // 保持当前用户ID不变 |       userId: currentUserId || '' | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     const rawUserList = res.data || []; |     const rawUserList = res.data || []; | ||||||
|     if (currentUserId && rawUserList.length > 0) { |     if (currentUserId && rawUserList.length > 0) { | ||||||
|       // 分离当前用户和历史用户(当前用户置顶) |  | ||||||
|       const currentUser = rawUserList.find((user: HistoryUserVO) => user.sysUserId === currentUserId); |       const currentUser = rawUserList.find((user: HistoryUserVO) => user.sysUserId === currentUserId); | ||||||
|       const historyUsers = rawUserList.filter((user: HistoryUserVO) => user.sysUserId !== currentUserId); |       const historyUsers = rawUserList.filter((user: HistoryUserVO) => user.sysUserId !== currentUserId); | ||||||
|       historyUserList.value = currentUser ? [currentUser, ...historyUsers] : historyUsers; |       historyUserList.value = currentUser ? [currentUser, ...historyUsers] : historyUsers; | ||||||
| @ -742,17 +732,16 @@ const handleOpenHistoryUser = async (clientId: string | number | undefined, curr | |||||||
|   } |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | /** 页面挂载时初始化 */ | ||||||
| onMounted(() => { | onMounted(() => { | ||||||
|   getProjects().then(() => { |  | ||||||
|   getList(); |   getList(); | ||||||
|   }); |  | ||||||
| }); | }); | ||||||
|  |  | ||||||
| // 监听项目id刷新数据 | /** 监听项目变化 */ | ||||||
| const listeningProject = watch( | const listeningProject = watch( | ||||||
|   () => currentProject.value?.id, |   () => currentProject.value?.id, | ||||||
|   (nid) => { |   (nid) => { | ||||||
|     if (!isViewAll.value) { |     if (queryParams.value.type === 1) { | ||||||
|       queryParams.value.projectId = nid; |       queryParams.value.projectId = nid; | ||||||
|       form.value.projectId = nid; |       form.value.projectId = nid; | ||||||
|       getList(); |       getList(); | ||||||
| @ -760,11 +749,12 @@ const listeningProject = watch( | |||||||
|   } |   } | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  | /** 页面卸载时清理 */ | ||||||
| onUnmounted(() => { | onUnmounted(() => { | ||||||
|   listeningProject(); |   listeningProject(); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| // 类型补充 | // 类型定义 | ||||||
| interface DialogOption { | interface DialogOption { | ||||||
|   visible: boolean; |   visible: boolean; | ||||||
|   title: string; |   title: string; | ||||||
| @ -776,13 +766,11 @@ interface PageData<T, Q> { | |||||||
|   rules: Record<string, any[]>; |   rules: Record<string, any[]>; | ||||||
| } | } | ||||||
|  |  | ||||||
| // 历史用户类型定义(根据后端返回字段调整) |  | ||||||
| interface HistoryUserVO { | interface HistoryUserVO { | ||||||
|   sysUserId: string | number; // 用户ID(与绑定用户的userId字段一致) |   sysUserId: string | number; | ||||||
|   userName: string; // 用户名 |   userName: string; | ||||||
|   lastUseTime?: number | string; // 最后使用时间 |   lastUseTime?: number | string; | ||||||
|   bindTime?: number | string; // 绑定时间 |   bindTime?: number | string; | ||||||
|   type?: number; // 1:当前绑定,其他:历史绑定 |   type?: number; // 1:当前绑定,其他:历史绑定 | ||||||
|   // 其他后端返回字段... |  | ||||||
| } | } | ||||||
| </script> | </script> | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user