Quellcode durchsuchen

页面功能调整

lipenghui vor 4 Monaten
Ursprung
Commit
5f39a61dbd

+ 4 - 1
src/api/pms/info/index.ts

@@ -31,7 +31,10 @@ export const IotInfoClassifyApi = {
   updateIotInfoClassify: async (data: IotInfoClassifyVO) => {
     return await request.put({ url: `/rq/iot-info-classify/update`, data })
   },
-
+  // 修改资料分类
+  removeIotInfoClassify: async (data: IotInfoClassifyVO) => {
+    return await request.put({ url: `/rq/iot-info-classify/update/remove`, data })
+  },
   // 删除设备分类
   deleteIotInfoClassify: async (id: number) => {
     return await request.delete({ url: `/rq/iot-info-classify/delete?id=` + id })

+ 36 - 0
src/components/ContentWrap/src/ContentWrapNoBottom.vue

@@ -0,0 +1,36 @@
+<script lang="ts" setup>
+import { propTypes } from '@/utils/propTypes'
+import { useDesign } from '@/hooks/web/useDesign'
+
+defineOptions({ name: 'ContentWrap' })
+
+const { getPrefixCls } = useDesign()
+
+const prefixCls = getPrefixCls('content-wrap')
+
+defineProps({
+  title: propTypes.string.def(''),
+  message: propTypes.string.def(''),
+  bodyStyle: propTypes.object.def({ padding: '10px' })
+})
+</script>
+
+<template>
+  <ElCard :body-style="bodyStyle" :class="[prefixCls]" shadow="never">
+    <template v-if="title" #header>
+      <div class="flex items-center">
+        <span class="text-16px font-700">{{ title }}</span>
+        <ElTooltip v-if="message" effect="dark" placement="right">
+          <template #content>
+            <div class="max-w-200px">{{ message }}</div>
+          </template>
+          <Icon :size="14" class="ml-5px" icon="ep:question-filled" />
+        </ElTooltip>
+        <div class="flex flex-grow pl-20px">
+          <slot name="header"></slot>
+        </div>
+      </div>
+    </template>
+    <slot></slot>
+  </ElCard>
+</template>

+ 1 - 1
src/router/modules/remaining.ts

@@ -87,7 +87,7 @@ const remainingRouter: AppRouteRecordRaw[] = [
           noCache: false,
           hidden: true,
           canTo: true,
-          activeMenu: ''
+          activeMenu: '/template/info'
         }
       }
     ]

+ 21 - 17
src/views/pms/device/DeviceInfo.vue

@@ -2,9 +2,14 @@
   <ContentWrap>
     <div style="display: flex; flex-direction: row; height: 12em; margin-top: 2px">
       <div style="flex: 1; height: 12em; margin-left: 20px">
-        <img :src="formData.picUrl" style="width: 35em; height: 12em" />
+        <el-image
+          :key="index"
+          :src="formData.picUrl"
+          style="width: 35em; height: 12em"
+          @click="imagePreview(formData.picUrl)"
+        />
       </div>
-      <div style="flex: 2; height: 12em">
+      <div style="flex: 2; height: 12em; margin-top: 23px">
         <el-form ref="formRef" :disabled="false" :model="formData" label-width="120px">
           <el-row>
             <el-col :span="8">
@@ -59,8 +64,8 @@
   <ContentWrap v-loading="formLoading">
     <el-tabs v-model="activeName">
       <el-tab-pane label="基础信息" name="info">
-        <el-form style="margin-top: 5px; margin-left: 15px">
-          <el-row>
+        <el-form style="margin-top: 5px; margin-left: 35px;margin-right: 35px;">
+          <el-row style="border-bottom: 1px solid #dcdfe6;">
             <el-col :span="6">
               <el-form-item label="制造商:" prop="manufacturerId">
                 {{ formData.zzName }}
@@ -81,15 +86,13 @@
                 {{ formData.nameplate ? formData.nameplate : '-' }}
               </el-form-item>
             </el-col>
-          </el-row>
-          <el-row>
             <el-col :span="6">
               <el-form-item label="质保到期:" prop="expires">
                 {{ formData.expires ? formatDate(formData.expires, 'YYYY-MM-DD') : '-' }}
               </el-form-item>
             </el-col>
           </el-row>
-          <el-row>
+          <el-row style="margin-top:20px;border-bottom: 1px solid #dcdfe6;">
             <el-col :span="6">
               <el-form-item label="采购价格:" prop="plPrice">
                 {{ formData.plPrice ? formData.plPrice : '-' }}
@@ -110,9 +113,6 @@
                 {{ formData.plStartDate ? formatDate(formData.plStartDate, 'YYYY-MM-DD') : '-' }}
               </el-form-item>
             </el-col>
-          </el-row>
-
-          <el-row>
             <el-col :span="6">
               <el-form-item label="已提折旧月数:" prop="plMonthed">
                 {{ formData.plMonthed ? formData.plMonthed : '-' }}
@@ -129,7 +129,7 @@
               </el-form-item>
             </el-col>
           </el-row>
-          <el-row>
+          <el-row style="margin-top:20px">
             <el-col v-for="field in list" :key="field.sort" :span="6">
               <el-form-item :label="field.name" :prop="field.identifier" >
                 {{ field.value }}
@@ -145,11 +145,9 @@
         />
       </el-tab-pane>
       <el-tab-pane label="设备BOM" name="bom">
-        <ContactList
-          ref="contactRef"
+        <DeviceUpload
+          ref="fileRef"
           v-model:activeName="activeName"
-          :propFormData="formData"
-          :ifAlone="false"
         />
       </el-tab-pane>
       <el-tab-pane label="维修记录" name="servicing">
@@ -187,6 +185,7 @@ import { IotDeviceApi, IotDeviceVO } from '@/api/pms/device'
 import { DICT_TYPE, getDictLabel } from '@/utils/dict'
 import { formatDate } from '../../../utils/formatTime'
 import DeviceUpload from "@/views/pms/device/DeviceUpload.vue";
+import {createImageViewer} from "@/components/ImageViewer";
 
 
 defineOptions({ name: 'DeviceDetailInfo' })
@@ -220,7 +219,7 @@ const formData = ref({
   remark: undefined,
   deptName: undefined
 })
-
+const pics = ref([])
 /** 获得详情 */
 const getDetail = async () => {
   if (id) {
@@ -228,8 +227,8 @@ const getDetail = async () => {
     try {
       const res = (await IotDeviceApi.getIotDevice(id)) as IotDeviceVO
       formData.value = res
+      pics.value.push(res.picUrl)
       if (res) {
-        debugger
         if (res.templateJson) {
           list.value = JSON.parse(res.templateJson)
         }
@@ -239,6 +238,11 @@ const getDetail = async () => {
     }
   }
 }
+const imagePreview = (imgUrl: string) => {
+  createImageViewer({
+    urlList: [imgUrl]
+  })
+}
 /** 初始化 */
 onMounted(async () => {
   await getDetail()

+ 193 - 121
src/views/pms/device/DeviceUpload.vue

@@ -1,114 +1,121 @@
 <template>
-  <el-row :gutter="20">
-    <el-col :span="5" :xs="24">
-      <ContentWrap class="h-1/1">
-            <FileTree @node-click="handleFileNodeClick" :deviceId="id" />
-      </ContentWrap>
-    </el-col>
-    <el-col :span="19">
-      <ContentWrap>
-        <el-form
-          class="-mb-15px"
-          :model="queryParams"
-          ref="queryFormRef"
-          :inline="true"
-          label-width="68px"
-        >
-          <el-form-item label="文件名称" prop="fileName">
-            <el-input
-              v-model="queryParams.fileName"
-              placeholder="请输入文件名称"
-              clearable
-              @keyup.enter="handleQuery"
-              class="!w-240px"
+  <div class="container-tree" ref="container">
+    <el-row>
+      <div class="left-tree" :style="{ width: leftWidth + 'px' }">
+        <ContentWrapNoBottom>
+          <FileTree @node-click="handleFileNodeClick" :deviceId="id" />
+        </ContentWrapNoBottom>
+      </div>
+      <div class="divider-tree" @mousedown="startDrag"></div>
+      <div class="right-tree" :style="{ width: rightWidth + 'px' }">
+        <ContentWrap>
+          <el-form
+            class="-mb-15px"
+            :model="queryParams"
+            ref="queryFormRef"
+            :inline="true"
+            label-width="68px"
+          >
+            <el-form-item label="文件名称" prop="fileName">
+              <el-input
+                v-model="queryParams.fileName"
+                placeholder="请输入文件名称"
+                clearable
+                @keyup.enter="handleQuery"
+                class="!w-240px"
+              />
+            </el-form-item>
+            <el-form-item>
+              <el-button @click="handleQuery"><Icon icon="ep:search" />搜索</el-button>
+              <el-button @click="resetQuery"><Icon icon="ep:refresh" />重置</el-button>
+              <el-button type="primary" plain @click="openForm('create')">
+                <Icon icon="ep:plus" /> 文件上传
+              </el-button>
+            </el-form-item>
+          </el-form>
+        </ContentWrap>
+        <ContentWrap>
+          <el-table
+            v-loading="formLoading"
+            :data="list"
+            :stripe="true"
+            :show-overflow-tooltip="true"
+          >
+            <!--          <el-table-column label="设备名称" align="center" prop="deviceId" />-->
+            <!--          <el-table-column label="资料分类" align="center" prop="classId" />-->
+            <el-table-column label="文件名称" align="center" prop="filename" />
+            <el-table-column label="文件类型" align="center" prop="fileType" />
+            <el-table-column label="查看预览" align="center" prop="filePath" >
+              <template #default="scope">
+                <el-button link type="primary" @click="openWeb(scope.row.filePath)"> <Icon size="19" icon="ep:view"  /> </el-button>
+              </template>
+            </el-table-column>
+            <el-table-column label="备注" align="center" prop="remark" />
+            <el-table-column
+              label="创建时间"
+              align="center"
+              prop="createTime"
+              :formatter="dateFormatter"
+              width="180px"
             />
-          </el-form-item>
-          <el-form-item>
-            <el-button @click="handleQuery"><Icon icon="ep:search" />搜索</el-button>
-            <el-button @click="resetQuery"><Icon icon="ep:refresh" />重置</el-button>
-            <el-button type="primary" plain @click="openForm('create')">
-              <Icon icon="ep:plus" /> 文件上传
-            </el-button>
-          </el-form-item>
-        </el-form>
-      </ContentWrap>
-      <ContentWrap>
-        <el-table v-loading="formLoading" :data="list" :stripe="true" :show-overflow-tooltip="true">
-<!--          <el-table-column label="设备名称" align="center" prop="deviceId" />-->
-<!--          <el-table-column label="资料分类" align="center" prop="classId" />-->
-          <el-table-column label="文件名称" align="center" prop="filename" />
-          <el-table-column label="文件类型" align="center" prop="fileType" />
-          <el-table-column label="文件路径" align="center" prop="filePath" />
-          <el-table-column label="备注" align="center" prop="remark" />
-          <el-table-column
-            label="创建时间"
-            align="center"
-            prop="createTime"
-            :formatter="dateFormatter"
-            width="180px"
+            <el-table-column label="操作" align="center" width="160">
+              <template #default="scope">
+                <div class="flex items-center justify-center">
+                  <el-button type="primary" link @click="openForm('update', scope.row.id)">
+                    <Icon icon="ep:edit" />修改
+                  </el-button>
+                  <el-dropdown
+                    @command="(command) => handleCommand(command, scope.row)"
+                    v-hasPermi="[
+                      'system:user:delete',
+                      'system:user:update-password',
+                      'system:permission:assign-user-role'
+                    ]"
+                  >
+                    <el-button type="primary" link><Icon icon="ep:d-arrow-right" /> 更多</el-button>
+                    <template #dropdown>
+                      <el-dropdown-menu>
+                        <el-dropdown-item command="handleDelete">
+                          <Icon icon="ep:delete" />删除
+                        </el-dropdown-item>
+<!--                        <el-dropdown-item command="fileView">-->
+<!--                          <Icon icon="ep:view" />预览-->
+<!--                        </el-dropdown-item>-->
+                        <el-dropdown-item command="fileDownload">
+                          <Icon icon="ep:view" />下载
+                        </el-dropdown-item>
+                      </el-dropdown-menu>
+                    </template>
+                  </el-dropdown>
+                </div>
+              </template>
+            </el-table-column>
+          </el-table>
+          <Pagination
+            :total="total"
+            v-model:page="queryParams.pageNo"
+            v-model:limit="queryParams.pageSize"
+            @pagination="getList"
           />
-          <el-table-column label="操作" align="center" width="160">
-            <template #default="scope">
-              <div class="flex items-center justify-center">
-                <el-button
-                  type="primary"
-                  link
-                  @click="openForm('update', scope.row.id)"
-                >
-                  <Icon icon="ep:edit" />修改
-                </el-button>
-                <el-dropdown
-                  @command="(command) => handleCommand(command, scope.row)"
-                  v-hasPermi="[
-                    'system:user:delete',
-                    'system:user:update-password',
-                    'system:permission:assign-user-role'
-                  ]"
-                >
-                  <el-button type="primary" link><Icon icon="ep:d-arrow-right" /> 更多</el-button>
-                  <template #dropdown>
-                    <el-dropdown-menu>
-                      <el-dropdown-item
-                        command="handleDelete"
-                      >
-                        <Icon icon="ep:delete" />删除
-                      </el-dropdown-item>
-                      <el-dropdown-item
-                        command="fileView"
-                      >
-                        <Icon icon="ep:view" />预览
-                      </el-dropdown-item>
-                      <el-dropdown-item
-                        command="fileDownload"
-                      >
-                        <Icon icon="ep:view" />下载
-                      </el-dropdown-item>
-                    </el-dropdown-menu>
-                  </template>
-                </el-dropdown>
-              </div>
-            </template>
-          </el-table-column>
-        </el-table>
-        <Pagination
-          :total="total"
-          v-model:page="queryParams.pageNo"
-          v-model:limit="queryParams.pageSize"
-          @pagination="getList"
-        />
-      </ContentWrap>
-    </el-col>
-  </el-row>
-  <IotInfoForm ref="formRef" @success="getList" :deviceId="deviceId" :classId="queryParams.classId"/>
+        </ContentWrap> </div
+    ></el-row>
+  </div>
+  <IotInfoForm
+    ref="formRef"
+    @success="getList"
+    :deviceId="deviceId"
+    :classId="queryParams.classId"
+  />
 </template>
 <script lang="ts" setup>
 import { IotDeviceApi, IotDeviceVO } from '@/api/pms/device'
 import FileTree from '@/views/pms/device/FileTree.vue'
 import { dateFormatter } from '@/utils/formatTime'
-import IotInfoForm from "@/views/pms/iotinfo/IotInfoForm.vue";
+import IotInfoForm from '@/views/pms/iotinfo/IotInfoForm.vue'
 import * as IotInfoApi from '@/api/pms/iotinfo'
-import {SupplierVO} from "@/api/supplier/base";
-import {IotInfoVO} from "@/api/pms/iotinfo";
+import { IotInfoVO } from '@/api/pms/iotinfo'
+import { onMounted, ref } from 'vue'
+
 defineOptions({ name: 'DeviceUpload' })
 const queryFormRef = ref() // 搜索的表单
 const { t } = useI18n() // 国际化
@@ -119,13 +126,45 @@ const formLoading = ref(false) // 表单的加载中:1)修改时的数据加
 const list = ref<IotDeviceVO[]>([]) // 列表的数据
 const total = ref(0) // 列表的总页数
 const id = params.id as unknown as number
+
+const container = ref(null)
+const leftWidth = ref(350) // 初始左侧宽度
+const rightWidth = ref(window.innerWidth * 0.69)
+let isDragging = false
+const openWeb = (url) => {
+  window.open('http://1.94.244.160:8012/onlinePreview?url='+encodeURIComponent(Base64.encode(url)));
+}
+const startDrag = (e) => {
+  isDragging = true
+  document.addEventListener('mousemove', onDrag)
+  document.addEventListener('mouseup', stopDrag)
+}
+
+const onDrag = (e) => {
+  if (!isDragging) return
+
+  const containerRect = container.value.getBoundingClientRect()
+  const newWidth = e.clientX - containerRect.left
+
+  // 设置最小和最大宽度限制
+  if (newWidth > 300 && newWidth < containerRect.width - 100) {
+    leftWidth.value = newWidth
+  }
+}
+
+const stopDrag = () => {
+  isDragging = false
+  document.removeEventListener('mousemove', onDrag)
+  document.removeEventListener('mouseup', stopDrag)
+}
+
 const queryParams = reactive({
   pageNo: 1,
   pageSize: 10,
   fileName: null,
   createTime: [],
   deviceId: null,
-  classId: null,
+  classId: null
 })
 // SPU 表单数据
 const formData = ref({
@@ -136,7 +175,7 @@ const formData = ref({
   fileType: undefined,
   filePath: undefined,
   remark: undefined,
-  classId: undefined,
+  classId: undefined
 })
 const handleCommand = (command: string, row: IotInfoVO) => {
   switch (command) {
@@ -158,27 +197,30 @@ const handleCommand = (command: string, row: IotInfoVO) => {
 }
 const handleDownload = async (url) => {
   try {
-    const response = await fetch(url);
-    const blob = await response.blob();
-    const downloadUrl = window.URL.createObjectURL(blob);
+    const response = await fetch(url)
+    const blob = await response.blob()
+    const downloadUrl = window.URL.createObjectURL(blob)
 
-    const link = document.createElement('a');
-    link.href = downloadUrl;
-    link.download = url.split('/').pop(); // 自动获取文件名‌:ml-citation{ref="3" data="citationList"}
-    link.click();
+    const link = document.createElement('a')
+    link.href = downloadUrl
+    link.download = url.split('/').pop() // 自动获取文件名‌:ml-citation{ref="3" data="citationList"}
+    link.click()
 
-    URL.revokeObjectURL(downloadUrl);
+    URL.revokeObjectURL(downloadUrl)
   } catch (error) {
-    console.error('下载失败:', error);
+    console.error('下载失败:', error)
   }
 }
 const handleFileView = (url: string) => {
-  window.open('http://1.94.244.160:8012/onlinePreview?url='+encodeURIComponent(Base64.encode(url)));
+  window.open(
+    'http://1.94.244.160:8012/onlinePreview?url=' + encodeURIComponent(Base64.encode(url))
+  )
 }
 const handleDelete = async (id: number) => {
   try {
     // 删除的二次确认
     await message.delConfirm()
+
     // 发起删除
     await IotInfoApi.IotInfoApi.deleteIotInfo(id)
     message.success(t('common.delSuccess'))
@@ -188,8 +230,8 @@ const handleDelete = async (id: number) => {
 }
 const formRef = ref()
 const openForm = (type: string, id?: number) => {
-  if (!queryParams.classId){
-    message.error("请选择左侧资料分类")
+  if (!queryParams.classId) {
+    message.error('请选择左侧资料分类')
     return
   }
   formRef.value.open(type, id)
@@ -212,14 +254,14 @@ const getDetail = async () => {
 }
 /** 查询列表 */
 const getList = async () => {
-  loading.value = true
+  formLoading.value = true
   try {
     queryParams.deviceId = deviceId.value
     const data = await IotInfoApi.IotInfoApi.getIotInfoPage(queryParams)
     list.value = data.list
     total.value = data.total
   } finally {
-    loading.value = false
+    formLoading.value = false
   }
 }
 /** 搜索按钮操作 */
@@ -236,9 +278,39 @@ const resetQuery = () => {
 /** 初始化 */
 onMounted(async () => {
   await getDetail()
-
+  await getList()
   deviceId.value = params.id as unknown as number
-
 })
 </script>
-<style scoped></style>
+<style scoped>
+.container-tree {
+  display: flex;
+  height: 100%;
+  user-select: none; /* 防止拖动时选中文本 */
+}
+
+.left-tree {
+  background: #f0f0f0;
+  height: 100%;
+  overflow: auto;
+}
+
+.right-tree {
+  flex: 1;
+  background: #fff;
+  height: 100%;
+  overflow: auto;
+  margin-left: 5px;
+}
+
+.divider-tree {
+  width: 2px;
+  background: #ccc;
+  cursor: col-resize;
+  position: relative;
+}
+
+.divider-tree:hover {
+  background: #666;
+}
+</style>

+ 125 - 6
src/views/pms/device/FileTree.vue

@@ -1,12 +1,12 @@
 <template>
-  <div class="head-container">
+  <div>
     <el-input v-model="deptName" class="mb-20px" clearable placeholder="请输入资料分类名称">
       <template #prefix>
         <Icon icon="ep:search" />
       </template>
     </el-input>
   </div>
-  <div class="head-container">
+  <div ref="treeContainer" class="tree-container">
     <el-tree
       ref="treeRef"
       :data="fileList"
@@ -18,7 +18,14 @@
       node-key="id"
       @node-click="handleNodeClick"
       @node-contextmenu="handleRightClick"
-      style="height: 35em"
+      style="height: 33em"
+      draggable
+      :allow-drop="allowDrop"
+      @node-drop="handleNodeDrop"
+      @node-drag-start="handleDragStart"
+      @node-drag-over="handleDragOver"
+      @node-drag-end="handleDragEnd"
+
     >
       <template #default="{ node}">
         <div style="display: flex; justify-content: space-between;align-items: center;width: 100%">
@@ -32,12 +39,16 @@
         </div>
       </template>
     </el-tree>
+    <div v-if="dragTip.visible" class="drag-tip" :style="dragTip.style">
+      移动到 {{ dragTip.text }}
+    </div>
   </div>
   <div v-show="menuVisible" ref="contextMenuRef" class="custom-menu" :style="{ left: menuX + 'px', top: menuY + 'px' }">
     <ul>
       <li style="border-bottom: 1px solid #ccc;" @click="handleMenuClick('add')">新增子节点</li>
       <li style="border-bottom: 1px solid #ccc;" @click="handleMenuClick('edit')">编辑节点</li>
       <li @click="handleMenuClick('delete')">删除节点</li>
+      <li @click="handleMenuClick('copy')">复制</li>
     </ul>
   </div>
 
@@ -87,6 +98,66 @@ const formRef = ref() // 搜索的表单
 const openForm = (type: string, id?: number) => {
   formRef.value.open(type, id)
 }
+const handleDragStart = (node) => {
+  highlightedNode.value = null;
+  dragTip.value.visible = true;
+};
+const highlightedNode = ref(null);
+const handleDragOver = (dragNode, targetNode, event) => {
+  // 高亮目标节点
+  highlightedNode.value = targetNode;
+
+  // 更新提示位置和内容
+  dragTip.value.text = targetNode.label;
+  dragTip.value.style = {
+    left: `${event.clientX + 15}px`,
+    top: `${event.clientY}px`
+  };
+};
+const handleDragEnd = () => {
+  highlightedNode.value = null;
+  dragTip.value.visible = false;
+};
+const dragTip = ref({
+  visible: false,
+  text: '',
+  style: {}
+});
+const handleNodeDrop = async (draggingNode, dropNode, dropType, event) => {
+  // 获取拖拽后的新父节点ID和目标位置
+  const newParentId = dropNode.data.id;
+  const targetIndex = dropNode.parent.childNodes.findIndex(n => n.data.id === dropNode.data.id);
+  // 更新本地数据
+  draggingNode.data.parentId = newParentId;
+  debugger
+  console.log(JSON.stringify(draggingNode.data))
+  await InfoClassifyApi.IotInfoClassifyApi.removeIotInfoClassify(draggingNode.data)
+};
+const allowDrop = (draggingNode, dropNode, type) => {
+  // 禁止拖拽到非文件夹节点内部
+  //if (dropNode.data.type === 'dept') return false;
+
+  // 限制最大层级(如不超过3层)
+  return true
+};
+// 动态高度计算
+const treeContainer = ref(null);
+const setHeight = () => {
+  if (!treeContainer.value) return;
+  const windowHeight = window.innerHeight;
+  const containerTop = treeContainer.value.offsetTop;
+  treeContainer.value.style.height = `${windowHeight *0.50}px`; // 60px 底部预留
+};
+
+onMounted(async () => {
+  await getTree()
+  setHeight();
+  window.addEventListener('resize', setHeight);
+});
+
+onUnmounted(() => {
+  window.removeEventListener('resize', setHeight);
+});
 
 const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
 const formType = ref('') // 表单的类型:create - 新增;update - 修改
@@ -241,9 +312,9 @@ onBeforeUnmount(() => {
   document.removeEventListener('click', handleClickOutside)
 })
 /** 初始化 */
-onMounted(async () => {
-  await getTree()
-})
+// onMounted(async () => {
+//   await getTree()
+// })
 </script>
 <style lang="scss" scoped>
 .custom-menu {
@@ -267,5 +338,53 @@ onMounted(async () => {
 .custom-menu li:hover {
   background: #77a0ec;
 }
+.tree-container {
+  overflow-y: auto;
+  min-width: 100%;
+  border: 1px solid #e4e7ed;
+  border-radius: 4px;
+}
+/* 自定义滚动条(可选) */
+.tree-container::-webkit-scrollbar {
+  width: 6px;
+}
+.tree-container::-webkit-scrollbar-thumb {
+  background: #c0c4cc;
+  border-radius: 3px;
+}
+.highlight {
+  background-color: #f0f9ff;
+  color: #409eff;
+  padding: 2px 5px;
+  border-radius: 3px;
+}
+
+/* 拖拽提示框样式 */
+.drag-tip {
+  position: fixed;
+  background: #fff;
+  border: 1px solid #409eff;
+  padding: 5px 10px;
+  border-radius: 4px;
+  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
+  z-index: 9999;
+}
 
+/* 调整拖拽指示线样式 */
+:deep(.el-tree-node__content) .el-tree-node__expand-icon {
+  position: relative;
+}
+
+:deep(.el-tree-node__drop-indicator) {
+  background-color: #409eff;
+  height: 2px;
+}
+
+/* 禁止拖拽到内部时的缩进 */
+:deep(.is-drop-inner) .el-tree-node__drop-indicator {
+  background-color: #409eff;
+  height: 100%;
+  width: 4px;
+  left: -8px !important;
+}
 </style>

+ 12 - 12
src/views/pms/device/IotDeviceForm.vue

@@ -184,56 +184,56 @@
       <div class="cw-expandable-content" :class="{ 'is-expanded': cwIsExpanded }">
         <el-row>
           <el-col :span="6">
-            <el-form-item label="采购价格" prop="plPrice">
+            <el-form-item :label="formData.assetProperty==='zy'?'采购价格':'租赁价格'" prop="plPrice">
               <el-input
                 v-model="formData.plPrice"
                 @input="handleInput(formData.plPrice, 'plPrice')"
-                placeholder="请输入采购/租赁价格"
+                :placeholder="formData.assetProperty==='zy'?'请输入采购价格':'请输入租赁价格'"
               />
             </el-form-item>
           </el-col>
           <el-col :span="6">
-            <el-form-item label="采购日期" prop="plDate">
+            <el-form-item :label="formData.assetProperty==='zy'?'采购日期':'租赁日期'" prop="plDate">
               <el-date-picker
                 style="width: 150%"
                 v-model="formData.plDate"
                 type="date"
                 value-format="x"
-                placeholder="选择采购日期"
+                :placeholder="formData.assetProperty==='zy'?'请输入采购日期':'请输入租赁日期'"
               />
             </el-form-item>
           </el-col>
           <el-col :span="6">
-            <el-form-item label="折旧年限" prop="plYear">
-              <el-input v-model="formData.plYear" type="number" placeholder="请输入折旧年限" />
+            <el-form-item :label="formData.assetProperty==='zy'?'折旧年限':'租赁年限'" prop="plYear">
+              <el-input v-model="formData.plYear" type="number" :placeholder="formData.assetProperty==='zy'?'请输入折旧年限':'请输入租赁年限'" />
             </el-form-item>
           </el-col>
           <el-col :span="6">
-            <el-form-item label="折旧开始日期" prop="plStartDate">
+            <el-form-item :label="formData.assetProperty==='zy'?'折旧开始日期':'租赁开始日期'" prop="plStartDate">
               <el-date-picker
                 style="width: 150%"
                 v-model="formData.plStartDate"
                 type="date"
                 value-format="x"
-                placeholder="选择折旧开始日期"
+                :placeholder="formData.assetProperty==='zy'?'请选择折旧开始日期':'请选择租赁开始日期'"
               />
             </el-form-item>
           </el-col>
           <el-col :span="6">
-            <el-form-item label="已提折旧月数" prop="plMonthed">
+            <el-form-item :label="formData.assetProperty==='zy'?'已提折旧月数':'已租赁月数'" prop="plMonthed">
               <el-input
                 v-model="formData.plMonthed"
                 type="number"
-                placeholder="请输入已提折旧月数"
+                :placeholder="formData.assetProperty==='zy'?'请输入已提折旧月数':'请输入已租赁月数'"
               />
             </el-form-item>
           </el-col>
           <el-col :span="6">
-            <el-form-item label="已提折旧金额" prop="plAmounted">
+            <el-form-item :label="formData.assetProperty==='zy'?'已提折旧金额':'已租赁金额'" prop="plAmounted">
               <el-input
                 v-model="formData.plAmounted"
                 @input="handleInput(formData.plAmounted, 'plAmounted')"
-                placeholder="请输入已提折旧金额"
+                :placeholder="formData.assetProperty==='zy'?'请输入已提折旧金额':'已租赁金额'"
               />
             </el-form-item>
           </el-col>

+ 1 - 1
src/views/pms/device/index.vue

@@ -153,7 +153,7 @@
           </el-button>
           <el-button
             link
-            type="info"
+            type="warning"
             @click="handleUpload(scope.row.id)"
           >
             资料上传

+ 9 - 7
src/views/pms/iotinfo/IotInfoForm.vue

@@ -7,9 +7,9 @@
       label-width="100px"
       v-loading="formLoading"
     >
-      <el-form-item label="文件名称" prop="filename">
-        <el-input v-model="formData.filename" placeholder="请输入文件名称" />
-      </el-form-item>
+<!--      <el-form-item label="文件名称" prop="filename">-->
+<!--        <el-input v-model="formData.filename" placeholder="请输入文件名称" />-->
+<!--      </el-form-item>-->
       <el-form-item label="文件类型" prop="fileType">
         <el-select v-model="formData.fileType" placeholder="请选择">
           <el-option
@@ -21,7 +21,7 @@
         </el-select>
       </el-form-item>
       <el-form-item label="附件" prop="filePath">
-        <UploadFile :is-show-tip="false" v-model="formData.filePath" :limit="1" />
+        <UploadFile :is-show-tip="false" v-model="formData.filePath" :multiple="formType.value==='create'?true:1" />
       </el-form-item>
       <el-form-item label="备注" prop="remark">
         <el-input v-model="formData.remark" type="textarea" placeholder="请输入备注" />
@@ -59,7 +59,7 @@ const formData = ref({
 const formRules = reactive({
   // deviceId: [{ required: true, message: '设备不能为空', trigger: 'blur' }],
   // orgId: [{ required: true, message: '部门不能为空', trigger: 'blur' }],
-  filename: [{ required: true, message: '文件名称不能为空', trigger: 'blur' }],
+  // filename: [{ required: true, message: '文件名称不能为空', trigger: 'blur' }],
   // fileType: [{ required: true, message: '文件类型不能为空', trigger: 'change' }],
   filePath: [{ required: true, message: '文件不能为空', trigger: 'blur' }],
 })
@@ -95,9 +95,11 @@ const submitForm = async () => {
   formLoading.value = true
   try {
     const data = formData.value as unknown as IotInfoVO
-    data.classId = props.classId
-    data.deviceId = props.deviceId
+    debugger
     if (formType.value === 'create') {
+      data.classId = props.classId
+      data.deviceId = props.deviceId
+      data.filePath = data.filePath.join(',')
       await IotInfoApi.createIotInfo(data)
       message.success(t('common.createSuccess'))
     } else {

+ 25 - 25
src/views/supplier/base/index.vue

@@ -133,33 +133,33 @@
       </el-table-column>
       <el-table-column label="供应商编号" align="center" prop="code" />
       <el-table-column label="供应商名称" align="center" prop="name" />
-      <el-table-column label="供应商分类" align="center" prop="classification" >
-        <template #default="scope">
-          <dict-tag :type="DICT_TYPE.SUPPLIER_TYPE" :value="scope.row.classification" />
-        </template>
-      </el-table-column>
-      <el-table-column label="公司类型" align="center" prop="type" >
-        <template #default="scope">
-          <dict-tag :type="DICT_TYPE.SUPPLIER_COMPANY_TYPE" :value="scope.row.type" />
-        </template>
-      </el-table-column>
-      <el-table-column label="供应商性质" align="center" prop="nature" >
-        <template #default="scope">
-          <dict-tag :type="DICT_TYPE.SUPPLIER_NATURE" :value="scope.row.nature" />
-        </template>
-      </el-table-column>
-      <el-table-column label="社会信用代码" align="center" prop="creditCode" />
+<!--      <el-table-column label="供应商分类" align="center" prop="classification" >-->
+<!--        <template #default="scope">-->
+<!--          <dict-tag :type="DICT_TYPE.SUPPLIER_TYPE" :value="scope.row.classification" />-->
+<!--        </template>-->
+<!--      </el-table-column>-->
+<!--      <el-table-column label="公司类型" align="center" prop="type" >-->
+<!--        <template #default="scope">-->
+<!--          <dict-tag :type="DICT_TYPE.SUPPLIER_COMPANY_TYPE" :value="scope.row.type" />-->
+<!--        </template>-->
+<!--      </el-table-column>-->
+<!--      <el-table-column label="供应商性质" align="center" prop="nature" >-->
+<!--        <template #default="scope">-->
+<!--          <dict-tag :type="DICT_TYPE.SUPPLIER_NATURE" :value="scope.row.nature" />-->
+<!--        </template>-->
+<!--      </el-table-column>-->
+<!--      <el-table-column label="社会信用代码" align="center" prop="creditCode" />-->
 <!--      <el-table-column label="纳税人识别号" align="center" prop="tin" />-->
 <!--      <el-table-column label="法人" align="center" prop="corporation" />-->
-      <el-table-column
-        label="审核状态"
-        align="center"
-        prop="auditStatus"
-      >
-        <template #default="scope">
-          <dict-tag :type="DICT_TYPE.CRM_AUDIT_STATUS" :value="scope.row.auditStatus" />
-        </template>
-      </el-table-column>
+<!--      <el-table-column-->
+<!--        label="审核状态"-->
+<!--        align="center"-->
+<!--        prop="auditStatus"-->
+<!--      >-->
+<!--        <template #default="scope">-->
+<!--          <dict-tag :type="DICT_TYPE.CRM_AUDIT_STATUS" :value="scope.row.auditStatus" />-->
+<!--        </template>-->
+<!--      </el-table-column>-->
 <!--      <el-table-column label="公司地址" align="center" prop="address" />-->
 <!--      <el-table-column label="经营范围" align="center" prop="bizScope" />-->
 <!--      <el-table-column label="注册资金(万元)" align="center" prop="registeredCapital" />-->

+ 100 - 98
src/views/system/tree/PmsTree.vue

@@ -1,12 +1,12 @@
 <template>
   <div class="head-container">
-    <el-input v-model="deptName" class="mb-20px" clearable placeholder="请输入名称">
+    <el-input v-model="deptName" class="mb-15px" clearable placeholder="请输入名称">
       <template #prefix>
         <Icon icon="ep:search" />
       </template>
     </el-input>
   </div>
-  <div class="head-container">
+  <div ref="treeContainer" class="tree-container">
     <el-tree
       ref="treeRef"
       :data="treeList"
@@ -18,70 +18,82 @@
       node-key="id"
       @node-click="handleNodeClick"
       @node-contextmenu="handleRightClick"
-      style="height: 35em"
+      style="height: 52em"
     >
-      <template #default="{ node}">
-        <div style="display: flex; justify-content: space-between;align-items: center;width: 100%">
+      <template #default="{ node }">
+        <div
+          style="display: flex; justify-content: space-between; align-items: center; width: 100%"
+        >
           <div>
-            <Icon style="vertical-align: middle" v-if="node.data.type==='dept'" icon="ep:operation"/>
-            <Icon style="vertical-align: middle" v-if="node.data.type==='device'" icon="fa:wrench"/>
-            <el-icon v-if="node.data.type==='file'" style="vertical-align: middle"><Folder /></el-icon>    <!-- 文件夹图标 -->
-            <span style="vertical-align: middle;margin-left: 3px">{{ node.data.name}}</span>
+            <Icon
+              style="vertical-align: middle"
+              v-if="node.data.type === 'dept'"
+              icon="ep:operation"
+            />
+            <Icon
+              style="vertical-align: middle"
+              v-if="node.data.type === 'device'"
+              icon="fa:wrench"
+            />
+            <el-icon v-if="node.data.type === 'file'" style="vertical-align: middle"
+              ><Folder
+            /></el-icon>
+            <!-- 文件夹图标 -->
+            <span style="vertical-align: middle; margin-left: 3px">{{ node.data.name }}</span>
           </div>
-<!--          <div>-->
-<!--            <icon style="vertical-align: middle" @click="handleRightClick" icon="ep:edit" />-->
-<!--          </div>-->
+          <!--          <div>-->
+          <!--            <icon style="vertical-align: middle" @click="handleRightClick" icon="ep:edit" />-->
+          <!--          </div>-->
         </div>
       </template>
     </el-tree>
   </div>
-<!--  <div v-show="menuVisible" ref="contextMenuRef" class="custom-menu" :style="{ left: menuX + 'px', top: menuY + 'px' }">-->
-<!--    <ul>-->
-<!--      <li style="border-bottom: 1px solid #ccc;" @click="handleMenuClick('add')">新增子节点</li>-->
-<!--      <li style="border-bottom: 1px solid #ccc;" @click="handleMenuClick('edit')">编辑节点</li>-->
-<!--      <li @click="handleMenuClick('delete')">删除节点</li>-->
-<!--    </ul>-->
-<!--  </div>-->
+  <!--  <div v-show="menuVisible" ref="contextMenuRef" class="custom-menu" :style="{ left: menuX + 'px', top: menuY + 'px' }">-->
+  <!--    <ul>-->
+  <!--      <li style="border-bottom: 1px solid #ccc;" @click="handleMenuClick('add')">新增子节点</li>-->
+  <!--      <li style="border-bottom: 1px solid #ccc;" @click="handleMenuClick('edit')">编辑节点</li>-->
+  <!--      <li @click="handleMenuClick('delete')">删除节点</li>-->
+  <!--    </ul>-->
+  <!--  </div>-->
 
-<!--  <Dialog v-model="dialogVisible" :title="dialogTitle" style="width: 40em">-->
-<!--    <el-form-->
-<!--      ref="formRef"-->
-<!--      v-loading="formLoading"-->
-<!--      :model="formData"-->
-<!--      :rules="formRules"-->
-<!--      label-width="80px"-->
-<!--    >-->
-<!--      <el-form-item label="资料分类名称" prop="name" label-width="110px">-->
-<!--        <el-input v-model="formData.name" placeholder="请输入资料分类名称" />-->
-<!--      </el-form-item>-->
-<!--      <el-form-item label="显示排序" prop="sort" label-width="110px">-->
-<!--        <el-input-number v-model="formData.sort" :min="0" controls-position="right" />-->
-<!--      </el-form-item>-->
-<!--      <el-form-item label="备注" prop="remark" label-width="110px">-->
-<!--        <el-input-->
-<!--          v-model="formData.remark"-->
-<!--          maxlength="11"-->
-<!--          placeholder="请输入备注"-->
-<!--          type="textarea"-->
-<!--        />-->
-<!--      </el-form-item>-->
-<!--    </el-form>-->
-<!--    <template #footer>-->
-<!--      <el-button type="primary" @click="submitForm">确 定</el-button>-->
-<!--      <el-button @click="dialogVisible = false">取 消</el-button>-->
-<!--    </template>-->
-<!--  </Dialog>-->
+  <!--  <Dialog v-model="dialogVisible" :title="dialogTitle" style="width: 40em">-->
+  <!--    <el-form-->
+  <!--      ref="formRef"-->
+  <!--      v-loading="formLoading"-->
+  <!--      :model="formData"-->
+  <!--      :rules="formRules"-->
+  <!--      label-width="80px"-->
+  <!--    >-->
+  <!--      <el-form-item label="资料分类名称" prop="name" label-width="110px">-->
+  <!--        <el-input v-model="formData.name" placeholder="请输入资料分类名称" />-->
+  <!--      </el-form-item>-->
+  <!--      <el-form-item label="显示排序" prop="sort" label-width="110px">-->
+  <!--        <el-input-number v-model="formData.sort" :min="0" controls-position="right" />-->
+  <!--      </el-form-item>-->
+  <!--      <el-form-item label="备注" prop="remark" label-width="110px">-->
+  <!--        <el-input-->
+  <!--          v-model="formData.remark"-->
+  <!--          maxlength="11"-->
+  <!--          placeholder="请输入备注"-->
+  <!--          type="textarea"-->
+  <!--        />-->
+  <!--      </el-form-item>-->
+  <!--    </el-form>-->
+  <!--    <template #footer>-->
+  <!--      <el-button type="primary" @click="submitForm">确 定</el-button>-->
+  <!--      <el-button @click="dialogVisible = false">取 消</el-button>-->
+  <!--    </template>-->
+  <!--  </Dialog>-->
 </template>
 
 <script lang="ts" setup>
-import { ElTree, FormRules } from 'element-plus'
-import * as FileClassifyApi from '@/api/pms/info'
-import * as InfoClassifyApi from '@/api/pms/info'
+import { ElTree } from 'element-plus'
 import { defaultProps, handleTree } from '@/utils/tree'
 import { CommonStatusEnum } from '@/utils/constants'
 // import {IotInfoClassifyApi} from "@/api/pms/info";
-import {IotTreeApi} from "@/api/system/tree";
-import { Document, Folder, Search } from '@element-plus/icons-vue'
+import { IotTreeApi } from '@/api/system/tree'
+import { Folder } from '@element-plus/icons-vue'
+
 const { t } = useI18n() // 国际化
 const message = useMessage() // 消息弹窗
 const dialogVisible = ref(false) // 弹窗的是否展示
@@ -91,49 +103,6 @@ const openForm = (type: string, id?: number) => {
   formRef.value.open(type, id)
 }
 
-// const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
-// const formType = ref('') // 表单的类型:create - 新增;update - 修改
-// const formData = ref({
-//   id: undefined,
-//   parentId: undefined,
-//   deviceId: undefined,
-//   name: undefined,
-//   sort: undefined,
-//   status: CommonStatusEnum.ENABLE,
-//   remark: undefined
-// })
-// const formRules = reactive<FormRules>({
-//   name: [{ required: true, message: '资料分类名称不能为空', trigger: 'blur' }],
-//   sort: [{ required: true, message: '显示排序不能为空', trigger: 'blur' }],
-//   status: [{ required: true, message: '状态不能为空', trigger: 'blur' }]
-// })
-// const submitForm = async () => {
-//   // 校验表单
-//   if (!formRef) return
-//   const valid = await formRef.value.validate()
-//   if (!valid) return
-//   // 提交请求
-//   formLoading.value = true
-//   try {
-//     const data = formData.value as unknown as InfoClassifyApi.IotInfoClassifyVO
-//     debugger
-//     if (formType.value === 'create') {
-//       data.parentId = nodeInfo.value.id
-//       data.deviceId = props.deviceId
-//       await InfoClassifyApi.IotInfoClassifyApi.createIotInfoClassify(data)
-//       message.success(t('common.createSuccess'))
-//     } else {
-//       await InfoClassifyApi.IotInfoClassifyApi.updateIotInfoClassify(data)
-//       message.success(t('common.updateSuccess'))
-//     }
-//     dialogVisible.value = false
-//
-//   } finally {
-//     await getTree()
-//     formLoading.value = false
-//   }
-// }
-
 /** 重置表单 */
 const resetForm = () => {
   formData.value = {
@@ -162,8 +131,28 @@ const menuX = ref(0)
 const menuY = ref(0)
 const contextMenuRef = ref(null) // 弹窗DOM引用
 let selectedNode = null
+
+// 动态高度计算
+const treeContainer = ref(null)
+const setHeight = () => {
+  if (!treeContainer.value) return
+  const windowHeight = window.innerHeight
+  const containerTop = treeContainer.value.offsetTop
+  treeContainer.value.style.height = `${windowHeight * 0.78}px` // 60px 底部预留
+}
+
+onMounted(async () => {
+  await getTreeInfo()
+  setHeight()
+  window.addEventListener('resize', setHeight)
+})
+
+onUnmounted(() => {
+  window.removeEventListener('resize', setHeight)
+})
+
 const handleRightClick = (event, node, data) => {
-  nodeInfo.value = node;
+  nodeInfo.value = node
   console.log(JSON.stringify(nodeInfo.value))
   event.preventDefault()
   menuX.value = event.clientX
@@ -265,10 +254,23 @@ onMounted(async () => {
   padding: 8px 20px;
   cursor: pointer;
   font-size: 14px;
-  margin: 5px
+  margin: 5px;
 }
 .custom-menu li:hover {
   background: #77a0ec;
 }
-
+.tree-container {
+  overflow-y: auto;
+  min-width: 100%;
+  border: 1px solid #e4e7ed;
+  border-radius: 4px;
+}
+/* 自定义滚动条(可选) */
+.tree-container::-webkit-scrollbar {
+  width: 6px;
+}
+.tree-container::-webkit-scrollbar-thumb {
+  background: #c0c4cc;
+  border-radius: 3px;
+}
 </style>

+ 178 - 100
src/views/system/tree/index.vue

@@ -1,94 +1,105 @@
 <template>
-  <el-row :gutter="20">
-    <el-col :span="5" :xs="24">
-      <ContentWrap class="h-1/1">
+  <div class="container-tree" ref="container">
+  <el-row >
+    <div class="left-tree" :style="{ width: leftWidth + 'px' }">
+      <ContentWrapNoBottom >
         <PmsTree @node-click="handleFileNodeClick" :deviceId="id" />
-      </ContentWrap>
-    </el-col>
-    <el-col :span="19">
-      <ContentWrap>
-        <el-form
-          class="-mb-15px"
-          :model="queryParams"
-          ref="queryFormRef"
-          :inline="true"
-          label-width="68px"
-        >
-          <el-form-item label="文件名称" prop="fileName">
-            <el-input
-              v-model="queryParams.fileName"
-              placeholder="请输入文件名称"
-              clearable
-              @keyup.enter="handleQuery"
-              class="!w-240px"
+      </ContentWrapNoBottom>
+    </div>
+<!--    </el-col>-->
+      <div
+        class="divider-tree"
+        @mousedown="startDrag"
+      ></div>
+      <div class="right-tree" :style="{ width: rightWidth + 'px' }">
+        <ContentWrap>
+          <el-form
+            class="-mb-15px"
+            :model="queryParams"
+            ref="queryFormRef"
+            :inline="true"
+            label-width="68px"
+          >
+            <el-form-item label="文件名称" prop="fileName">
+              <el-input
+                v-model="queryParams.fileName"
+                placeholder="请输入文件名称"
+                clearable
+                @keyup.enter="handleQuery"
+                class="!w-240px"
+              />
+            </el-form-item>
+            <el-form-item>
+              <el-button @click="handleQuery"><Icon icon="ep:search" />搜索</el-button>
+              <el-button @click="resetQuery"><Icon icon="ep:refresh" />重置</el-button>
+              <el-button type="primary" plain @click="openForm('create')">
+                <Icon icon="ep:plus" /> 文件上传
+              </el-button>
+            </el-form-item>
+          </el-form>
+        </ContentWrap>
+        <ContentWrap>
+          <el-table v-loading="formLoading" :data="list" :stripe="true" :show-overflow-tooltip="true">
+            <!--          <el-table-column label="设备名称" align="center" prop="deviceId" />-->
+            <!--          <el-table-column label="资料分类" align="center" prop="classId" />-->
+            <el-table-column label="文件名称" align="center" prop="filename" />
+            <el-table-column label="文件类型" align="center" prop="fileType" />
+            <el-table-column label="查看预览" align="center" prop="filePath" >
+              <template #default="scope">
+                <el-button link type="primary" @click="openWeb(scope.row.filePath)"> <Icon size="19" icon="ep:view"  /> </el-button>
+              </template>
+            </el-table-column>
+            <el-table-column label="备注" align="center" prop="remark" />
+            <el-table-column
+              label="创建时间"
+              align="center"
+              prop="createTime"
+              :formatter="dateFormatter"
+              width="180px"
             />
-          </el-form-item>
-          <el-form-item>
-            <el-button @click="handleQuery"><Icon icon="ep:search" />搜索</el-button>
-            <el-button @click="resetQuery"><Icon icon="ep:refresh" />重置</el-button>
-            <el-button type="primary" plain @click="openForm('create')">
-              <Icon icon="ep:plus" /> 文件上传
-            </el-button>
-          </el-form-item>
-        </el-form>
-      </ContentWrap>
-      <ContentWrap>
-        <el-table v-loading="formLoading" :data="list" :stripe="true" :show-overflow-tooltip="true">
-          <!--          <el-table-column label="设备名称" align="center" prop="deviceId" />-->
-          <!--          <el-table-column label="资料分类" align="center" prop="classId" />-->
-          <el-table-column label="文件名称" align="center" prop="filename" />
-          <el-table-column label="文件类型" align="center" prop="fileType" />
-          <el-table-column label="文件路径" align="center" prop="filePath" />
-          <el-table-column label="备注" align="center" prop="remark" />
-          <el-table-column
-            label="创建时间"
-            align="center"
-            prop="createTime"
-            :formatter="dateFormatter"
-            width="180px"
+            <el-table-column label="操作" align="center" width="160">
+              <template #default="scope">
+                <div class="flex items-center justify-center">
+                  <el-button type="primary" link @click="handleDownload( scope.row.filePath)">
+                    <Icon icon="ep:download" />下载
+                  </el-button>
+<!--                  <el-dropdown-->
+<!--                    @command="(command) => handleCommand(command, scope.row)"-->
+<!--                    v-hasPermi="[-->
+<!--                      'system:user:delete',-->
+<!--                      'system:user:update-password',-->
+<!--                      'system:permission:assign-user-role'-->
+<!--                    ]"-->
+<!--                  >-->
+<!--                    <el-button type="primary" link><Icon icon="ep:d-arrow-right" /> 更多</el-button>-->
+<!--                    <template #dropdown>-->
+<!--                      <el-dropdown-menu>-->
+<!--                        <el-dropdown-item command="handleDelete">-->
+<!--                          <Icon icon="ep:delete" />删除-->
+<!--                        </el-dropdown-item>-->
+<!--                        <el-dropdown-item command="fileView">-->
+<!--                          <Icon icon="ep:view" />预览-->
+<!--                        </el-dropdown-item>-->
+<!--                        <el-dropdown-item command="fileDownload">-->
+<!--                          <Icon icon="ep:view" />下载-->
+<!--                        </el-dropdown-item>-->
+<!--                      </el-dropdown-menu>-->
+<!--                    </template>-->
+<!--                  </el-dropdown>-->
+                </div>
+              </template>
+            </el-table-column>
+          </el-table>
+          <Pagination
+            :total="total"
+            v-model:page="queryParams.pageNo"
+            v-model:limit="queryParams.pageSize"
+            @pagination="getList"
           />
-          <el-table-column label="操作" align="center" width="160">
-            <template #default="scope">
-              <div class="flex items-center justify-center">
-                <el-button type="primary" link @click="openForm('update', scope.row.id)">
-                  <Icon icon="ep:edit" />修改
-                </el-button>
-                <el-dropdown
-                  @command="(command) => handleCommand(command, scope.row)"
-                  v-hasPermi="[
-                    'system:user:delete',
-                    'system:user:update-password',
-                    'system:permission:assign-user-role'
-                  ]"
-                >
-                  <el-button type="primary" link><Icon icon="ep:d-arrow-right" /> 更多</el-button>
-                  <template #dropdown>
-                    <el-dropdown-menu>
-                      <el-dropdown-item command="handleDelete">
-                        <Icon icon="ep:delete" />删除
-                      </el-dropdown-item>
-                      <el-dropdown-item command="fileView">
-                        <Icon icon="ep:view" />预览
-                      </el-dropdown-item>
-                      <el-dropdown-item command="fileDownload">
-                        <Icon icon="ep:view" />下载
-                      </el-dropdown-item>
-                    </el-dropdown-menu>
-                  </template>
-                </el-dropdown>
-              </div>
-            </template>
-          </el-table-column>
-        </el-table>
-        <Pagination
-          :total="total"
-          v-model:page="queryParams.pageNo"
-          v-model:limit="queryParams.pageSize"
-          @pagination="getList"
-        />
-      </ContentWrap>
-    </el-col>
+        </ContentWrap>
+      </div>
   </el-row>
+  </div>
   <IotInfoForm
     ref="formRef"
     @success="getList"
@@ -102,9 +113,45 @@ import { dateFormatter } from '@/utils/formatTime'
 import IotInfoForm from '@/views/pms/iotinfo/IotInfoForm.vue'
 import * as IotInfoApi from '@/api/pms/iotinfo'
 import { IotInfoVO } from '@/api/pms/iotinfo'
+import { ref, onMounted, onUnmounted } from 'vue'
 
 import PmsTree from '@/views/system/tree/PmsTree.vue'
 defineOptions({ name: 'IotTree' })
+
+const container = ref(null)
+const leftWidth = ref(350) // 初始左侧宽度
+const rightWidth = ref(window.innerWidth * 0.8)
+let isDragging = false
+const openWeb = (url) => {
+  window.open('http://1.94.244.160:8012/onlinePreview?url='+encodeURIComponent(Base64.encode(url)));
+}
+
+const startDrag = (e) => {
+  isDragging = true
+  document.addEventListener('mousemove', onDrag)
+  document.addEventListener('mouseup', stopDrag)
+}
+
+const onDrag = (e) => {
+  if (!isDragging) return
+
+  const containerRect = container.value.getBoundingClientRect()
+  const newWidth = e.clientX - containerRect.left
+
+  // 设置最小和最大宽度限制
+  if (newWidth > 300 && newWidth < containerRect.width - 100) {
+    leftWidth.value = newWidth
+  }
+}
+
+const stopDrag = () => {
+  isDragging = false
+  document.removeEventListener('mousemove', onDrag)
+  document.removeEventListener('mouseup', stopDrag)
+}
+
+
+
 const queryFormRef = ref() // 搜索的表单
 const { t } = useI18n() // 国际化
 const message = useMessage() // 消息弹窗
@@ -197,26 +244,26 @@ const handleFileNodeClick = async (row) => {
   await getList()
 }
 /** 获得详情 */
-const getDetail = async () => {
-  if (id) {
-    formLoading.value = true
-    try {
-      formData.value = (await IotDeviceApi.getIotDevice(id)) as IotDeviceVO
-    } finally {
-      formLoading.value = false
-    }
-  }
-}
+// const getDetail = async () => {
+//   if (id) {
+//     formLoading.value = true
+//     try {
+//       formData.value = (await IotDeviceApi.getIotDevice(id)) as IotDeviceVO
+//     } finally {
+//       formLoading.value = false
+//     }
+//   }
+// }
 /** 查询列表 */
 const getList = async () => {
-  loading.value = true
+  formLoading.value = true
   try {
     queryParams.deviceId = deviceId.value
     const data = await IotInfoApi.IotInfoApi.getIotInfoFilePage(queryParams)
     list.value = data.list
     total.value = data.total
   } finally {
-    loading.value = false
+    formLoading.value = false
   }
 }
 /** 搜索按钮操作 */
@@ -233,8 +280,39 @@ const resetQuery = () => {
 /** 初始化 */
 onMounted(async () => {
   // await getDetail()
-  //
+  await getList()
   // deviceId.value = params.id as unknown as number
 })
 </script>
-<style scoped></style>
+<style scoped>
+.container-tree {
+  display: flex;
+  height: 100%;
+  user-select: none; /* 防止拖动时选中文本 */
+}
+
+.left-tree {
+  background: #f0f0f0;
+  height: 100%;
+  overflow: auto;
+}
+
+.right-tree {
+  flex: 1;
+  background: #fff;
+  height: 100%;
+  overflow: auto;
+  margin-left: 5px;
+}
+
+.divider-tree {
+  width: 2px;
+  background: #ccc;
+  cursor: col-resize;
+  position: relative;
+}
+
+.divider-tree:hover {
+  background: #666;
+}
+</style>