|
@@ -1,4 +1,20 @@
|
|
|
<template>
|
|
|
+ <ContentWrap>
|
|
|
+ <div style="display: flex; justify-content: space-between; align-items: center;">
|
|
|
+ <el-breadcrumb separator=">" class="breadcrumb-container">
|
|
|
+ <el-breadcrumb-item
|
|
|
+ v-for="(item, index) in breadcrumbs"
|
|
|
+ :key="index"
|
|
|
+ @click="handleBreadcrumbClick(index)"
|
|
|
+ :class="{ 'current-crumb': index === breadcrumbs.length - 1 }"
|
|
|
+ class="custom-breadcrumb-item"
|
|
|
+ >
|
|
|
+ {{ item.name }}
|
|
|
+ </el-breadcrumb-item>
|
|
|
+ </el-breadcrumb>
|
|
|
+ <el-input :placeholder="'在'+breadcrumbs[breadcrumbs.length - 1].name+'下搜索'" style="width: 250px;height: 30px"/>
|
|
|
+ </div>
|
|
|
+ </ContentWrap>
|
|
|
<div class="container-tree" ref="container">
|
|
|
<el-row >
|
|
|
<div class="left-tree" :style="{ width: leftWidth + 'px' }">
|
|
@@ -40,69 +56,47 @@
|
|
|
</el-form>
|
|
|
</ContentWrap>
|
|
|
<ContentWrap>
|
|
|
- <el-table v-loading="formLoading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
|
|
- <el-table-column :label="t('file.name') " align="center" prop="filename" />
|
|
|
- <el-table-column :label="t('file.fileType') " align="center" prop="fileType" >
|
|
|
+ <el-table v-loading="formLoading" :data="list" :stripe="true" :show-overflow-tooltip="true" @row-dblclick="inContent" class="custom-table">
|
|
|
+ <el-table-column :label="t('file.name') " align="left" prop="filename" min-width="300">
|
|
|
<template #default="scope">
|
|
|
- <dict-tag :type="DICT_TYPE.PMS_FILE_TYPE" :value="scope.row.fileType" />
|
|
|
+ <div style="display: flex; align-items: center; gap: 5px;">
|
|
|
+ <Icon v-if="scope.row.fileType==='content'" icon="fa:folder-open" color="orange"/>
|
|
|
+ <Icon v-else-if="scope.row.fileType==='pic'||scope.row.fileClassify==='jpg'||scope.row.fileClassify==='png'" icon="ep:picture-filled" color="#2183D1"/>
|
|
|
+ <Icon v-else-if="scope.row.fileType==='file'&&scope.row.fileClassify==='pdf'" icon="fa-solid:file-pdf" color="#E20012"/>
|
|
|
+ <Icon v-else-if="scope.row.fileType==='file'&&(scope.row.fileClassify==='doc'||scope.row.fileClassify==='docx')" icon="fa:file-word-o" color="blue"/>
|
|
|
+ <Icon v-else-if="scope.row.fileType==='file'&&(scope.row.fileClassify==='xls'||scope.row.fileClassify==='xlsx')" icon="fa-solid:file-excel" color="#107C41"/>
|
|
|
+ <Icon v-else-if="scope.row.fileType==='file'&&(scope.row.fileClassify==='txt')" icon="fa:file-text-o" />
|
|
|
+ {{scope.row.filename}}
|
|
|
+ </div>
|
|
|
</template>
|
|
|
+
|
|
|
</el-table-column>
|
|
|
- <el-table-column :label="t('file.fileSize') " align="center" prop="fileSize" />
|
|
|
- <el-table-column :label="t('file.preview') " align="center" prop="filePath" >
|
|
|
+ <el-table-column :label="t('file.fileType') " align="center" prop="fileType" >
|
|
|
<template #default="scope">
|
|
|
- <el-button link type="primary" @click="openWeb(scope.row.filePath)"> <Icon size="19" icon="ep:view" /> </el-button>
|
|
|
+ <dict-tag :type="DICT_TYPE.PMS_FILE_TYPE" :value="scope.row.fileType" />
|
|
|
</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-table-column :label="t('file.fileSize') " align="center" prop="fileSize" />
|
|
|
+<!-- <el-table-column :label="t('file.preview') " align="center" prop="filePath" >-->
|
|
|
+<!-- <template #default="scope">-->
|
|
|
+<!-- <el-button v-if="scope.row.fileType!=='content'" link type="primary" @click="openWeb(scope.row.filePath)"> <Icon size="19" icon="ep:view" /> </el-button>-->
|
|
|
+<!-- </template>-->
|
|
|
+<!-- </el-table-column>-->
|
|
|
+ <el-table-column :label="t('file.dept') " align="center" prop="deptName" />
|
|
|
+ <el-table-column :label="t('file.device') " align="center" prop="deviceName" min-width="220"/> />
|
|
|
<el-table-column :label="t('file.operation') " align="center" width="160">
|
|
|
<template #default="scope">
|
|
|
<div class="flex items-center justify-center">
|
|
|
- <el-button type="primary" link @click="handleDownload( scope.row.filePath)" v-hasPermi="['rq:iot-info:download']">
|
|
|
+ <el-button type="primary" v-if="scope.row.fileType!=='content'" link @click="handleDownload( scope.row.filePath)" v-hasPermi="['rq:iot-info:download']">
|
|
|
<Icon icon="ep:download" />{{t('file.dow')}}
|
|
|
</el-button>
|
|
|
- <el-button type="primary" link @click="handleView( scope.row)">
|
|
|
- <Icon icon="ep:view" />{{t('file.preview')}}
|
|
|
- </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>-->
|
|
|
+<!-- <el-button type="primary" link @click="handleView( scope.row)">-->
|
|
|
+<!-- <Icon icon="ep:view" />{{t('file.preview')}}-->
|
|
|
+<!-- </el-button>-->
|
|
|
</div>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
</el-table>
|
|
|
- <Pagination
|
|
|
- :total="total"
|
|
|
- v-model:page="queryParams.pageNo"
|
|
|
- v-model:limit="queryParams.pageSize"
|
|
|
- @pagination="getList"
|
|
|
- />
|
|
|
</ContentWrap>
|
|
|
</div>
|
|
|
</el-row>
|
|
@@ -127,12 +121,14 @@ import PmsTree from '@/views/system/tree/PmsTree.vue'
|
|
|
import {CACHE_KEY, useCache} from "@/hooks/web/useCache";
|
|
|
import {DICT_TYPE} from "@/utils/dict";
|
|
|
import {IotInfoClassifyApi} from "@/api/pms/info";
|
|
|
+import {IotTreeApi} from "@/api/system/tree";
|
|
|
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)));
|
|
|
}
|
|
@@ -144,11 +140,21 @@ const startDrag = (e) => {
|
|
|
document.addEventListener('mousemove', onDrag)
|
|
|
document.addEventListener('mouseup', stopDrag)
|
|
|
}
|
|
|
+const topNodeId = ref('')
|
|
|
const successList = async (id) => {
|
|
|
- //queryParams.classId = id
|
|
|
+ queryParams.classId = id
|
|
|
+ topNodeId.value = id
|
|
|
+ const rootItem = breadcrumbs.value.find(item => item.type === 'root');
|
|
|
+ if (rootItem) {
|
|
|
+ rootItem.id = id;
|
|
|
+ }
|
|
|
+
|
|
|
await getList()
|
|
|
// queryParams.classId = ''
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
const onDrag = (e) => {
|
|
|
if (!isDragging) return
|
|
|
|
|
@@ -176,12 +182,12 @@ const loading = ref(true) // 列表的加载中
|
|
|
const { params } = useRoute() // 查询参数
|
|
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
|
|
const list = ref<IotDeviceVO[]>([]) // 列表的数据
|
|
|
-const total = ref(0) // 列表的总页数
|
|
|
+// const total = ref(0) // 列表的总页数
|
|
|
const id = params.id as unknown as number
|
|
|
const queryParams = reactive({
|
|
|
pageNo: 1,
|
|
|
pageSize: 10,
|
|
|
- fileName: null,
|
|
|
+ filename: null,
|
|
|
createTime: [],
|
|
|
deviceId: null,
|
|
|
classId: null,
|
|
@@ -198,24 +204,6 @@ const formData = ref({
|
|
|
remark: undefined,
|
|
|
classId: undefined
|
|
|
})
|
|
|
-const handleCommand = (command: string, row: IotInfoVO) => {
|
|
|
- switch (command) {
|
|
|
- case 'handleDelete':
|
|
|
- handleDelete(row.id)
|
|
|
- break
|
|
|
- case 'handleUpdate':
|
|
|
- openForm('update', row.id)
|
|
|
- break
|
|
|
- case 'fileView':
|
|
|
- handleFileView(row.filePath)
|
|
|
- break
|
|
|
- case 'fileDownload':
|
|
|
- handleDownload(row.filePath)
|
|
|
- break
|
|
|
- default:
|
|
|
- break
|
|
|
- }
|
|
|
-}
|
|
|
const handleDownload = async (url) => {
|
|
|
try {
|
|
|
const response = await fetch(url)
|
|
@@ -264,7 +252,57 @@ const deviceId = ref('')
|
|
|
const clickNodeId = ref('')
|
|
|
const nodeId = ref('')
|
|
|
const classType = ref('')
|
|
|
+
|
|
|
+const breadcrumbs = ref([
|
|
|
+ { id: null, name: '科瑞石油技术',type:'root' } // 根节点
|
|
|
+])
|
|
|
+
|
|
|
+// 共享的面包屑更新逻辑
|
|
|
+const updateBreadcrumbs = async (node) => {
|
|
|
+ // 查找当前节点是否已在面包屑中
|
|
|
+ const currentIndex = breadcrumbs.value.findIndex(item => item.id === node.id)
|
|
|
+
|
|
|
+ if (currentIndex > -1) {
|
|
|
+ // 如果已存在则截断后面的节点
|
|
|
+ breadcrumbs.value = breadcrumbs.value.slice(0, currentIndex + 1)
|
|
|
+ } else {
|
|
|
+ // 新增节点到面包屑
|
|
|
+ breadcrumbs.value.push({ id: node.id, name: node.filename || node.name })
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新表格数据
|
|
|
+ queryParams.classId = node.id;
|
|
|
+ const data = await IotInfoApi.IotInfoApi.getChildContentFile(queryParams)
|
|
|
+ list.value = data
|
|
|
+}
|
|
|
+
|
|
|
+// 表格行点击事件
|
|
|
+const inContent = async (row) => {
|
|
|
+ debugger
|
|
|
+ if (row.fileType!='content') {
|
|
|
+ window.open('http://1.94.244.160:8012/onlinePreview?url='+encodeURIComponent(Base64.encode(row.filePath)));
|
|
|
+ return
|
|
|
+ }
|
|
|
+ queryParams.filename = ''
|
|
|
+ formLoading.value = true
|
|
|
+ // 调用共享方法更新面包屑和表格
|
|
|
+ await updateBreadcrumbs(row)
|
|
|
+ // 可以添加其他表格行点击需要的逻辑
|
|
|
+ queryParams.classId = row.id;
|
|
|
+ const data = await IotInfoApi.IotInfoApi.getChildContentFile(queryParams)
|
|
|
+ formLoading.value = false
|
|
|
+ list.value = data
|
|
|
+}
|
|
|
+
|
|
|
+// 文件树节点点击事件
|
|
|
const handleFileNodeClick = async (row) => {
|
|
|
+ queryParams.filename = ''
|
|
|
+ const parentItems = await IotTreeApi.getParentIds(row.id);
|
|
|
+ breadcrumbs.value = [];
|
|
|
+ parentItems.forEach(item => {
|
|
|
+ breadcrumbs.value.push({ id: item.id, name: item.name,type:'root' } );
|
|
|
+ })
|
|
|
+
|
|
|
queryParams.classId = row.id
|
|
|
classType.value = row.type
|
|
|
if (row.type==='device') {
|
|
@@ -288,6 +326,55 @@ const handleFileNodeClick = async (row) => {
|
|
|
nodeId.value = row.id
|
|
|
await getList()
|
|
|
}
|
|
|
+
|
|
|
+// 面包屑点击事件
|
|
|
+const handleBreadcrumbClick = async (index) => {
|
|
|
+ queryParams.filename = ''
|
|
|
+ formLoading.value = true
|
|
|
+ // 忽略当前节点的点击
|
|
|
+ if (index === breadcrumbs.value.length - 1) return
|
|
|
+
|
|
|
+ // 截断面包屑到点击的节点
|
|
|
+ const targetBreadcrumbs = breadcrumbs.value.slice(0, index + 1)
|
|
|
+ breadcrumbs.value = targetBreadcrumbs
|
|
|
+
|
|
|
+ // 获取对应节点的数据
|
|
|
+ let targetId = targetBreadcrumbs[index].id
|
|
|
+ if (!targetId){
|
|
|
+ targetId = topNodeId.value
|
|
|
+ }
|
|
|
+ queryParams.classId = targetId
|
|
|
+ const data = await IotInfoApi.IotInfoApi.getChildContentFile(queryParams)
|
|
|
+ list.value = data
|
|
|
+ formLoading.value = false
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+// const handleFileNodeClick = async (row) => {
|
|
|
+// queryParams.classId = row.id
|
|
|
+// classType.value = row.type
|
|
|
+// if (row.type==='device') {
|
|
|
+// deviceId.value = row.originId
|
|
|
+// const queryParam = {
|
|
|
+// deviceId: row.originId,
|
|
|
+// pageNo: 1,
|
|
|
+// pagesize: 10,
|
|
|
+// }
|
|
|
+// const data = await IotInfoClassifyApi.getIotInfoClassifyPage(queryParam)
|
|
|
+// debugger
|
|
|
+// if (data){
|
|
|
+// const target = data.filter((item)=> item.parentId===0)
|
|
|
+// clickNodeId.value = target[0].id
|
|
|
+// }
|
|
|
+// } else if (row.type === 'file'){
|
|
|
+// clickNodeId.value = row.originId
|
|
|
+// } else if (row.type==='dept') {
|
|
|
+// // message.error("请选择设备及文件节点")
|
|
|
+// // return
|
|
|
+// }
|
|
|
+// nodeId.value = row.id
|
|
|
+// await getList()
|
|
|
+// }
|
|
|
/** 获得详情 */
|
|
|
// const getDetail = async () => {
|
|
|
// if (id) {
|
|
@@ -303,10 +390,8 @@ const handleFileNodeClick = async (row) => {
|
|
|
const getList = async () => {
|
|
|
formLoading.value = true
|
|
|
try {
|
|
|
- // queryParams.deviceId = deviceId.value
|
|
|
- const data = await IotInfoApi.IotInfoApi.getIotInfoFilePage(queryParams)
|
|
|
- list.value = data.list
|
|
|
- total.value = data.total
|
|
|
+ const data = await IotInfoApi.IotInfoApi.getChildContentFile(queryParams)
|
|
|
+ list.value = data
|
|
|
} finally {
|
|
|
formLoading.value = false
|
|
|
}
|
|
@@ -332,6 +417,53 @@ onMounted(async () => {
|
|
|
})
|
|
|
</script>
|
|
|
<style scoped>
|
|
|
+::v-deep .breadcrumb-container {
|
|
|
+ padding: 12px 16px;
|
|
|
+ background-color: #f5f7fa;
|
|
|
+ border-radius: 6px;
|
|
|
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.06);
|
|
|
+}
|
|
|
+::v-deep .custom-breadcrumb-item {
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: bold;
|
|
|
+}
|
|
|
+
|
|
|
+/* 面包屑文本样式 */
|
|
|
+::v-deep .el-breadcrumb__item .el-breadcrumb__inner {
|
|
|
+ color: #101010;
|
|
|
+ text-decoration: none;
|
|
|
+ padding: 2px 4px;
|
|
|
+ border-radius: 2px;
|
|
|
+ transition: all 0.2s ease;
|
|
|
+}
|
|
|
+
|
|
|
+/* 可点击项悬停效果 */
|
|
|
+::v-deep .el-breadcrumb__item:not(:last-child) .el-breadcrumb__inner:hover {
|
|
|
+ color: #409eff;
|
|
|
+ background-color: rgba(64, 158, 255, 0.1);
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+
|
|
|
+/* 当前项样式 */
|
|
|
+::v-deep .el-breadcrumb__item:last-child .el-breadcrumb__inner {
|
|
|
+ color: #1890ff;
|
|
|
+ font-weight: 500;
|
|
|
+ cursor: default;
|
|
|
+}
|
|
|
+
|
|
|
+/* 分隔符样式优化 */
|
|
|
+::v-deep .el-breadcrumb__separator {
|
|
|
+ margin: 0 8px;
|
|
|
+ color: #0954f6;
|
|
|
+ font-size: 12px;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+.custom-table {
|
|
|
+ cursor: pointer;
|
|
|
+ --el-table-row-hover-bg-color: #f5f7fa; /* 优化悬停背景色 */
|
|
|
+}
|
|
|
+
|
|
|
.container-tree {
|
|
|
display: flex;
|
|
|
height: 100%;
|