|
|
@@ -5,9 +5,127 @@ import type { IotTreeVO } from '@/api/system/tree'
|
|
|
import { IotTreeApi } from '@/api/system/tree'
|
|
|
// import { DataLibraryApi } from '@/api/pms/qhse/index'
|
|
|
import { defaultProps, handleTree } from '@/utils/tree'
|
|
|
+import { CommonStatusEnum } from '@/utils/constants'
|
|
|
|
|
|
defineOptions({ name: 'IotTree' })
|
|
|
|
|
|
+const dialogVisible = ref(false) // 弹窗的是否展示
|
|
|
+const dialogTitle = ref('') // 弹窗的标题
|
|
|
+const formRef = ref() // 搜索的表单
|
|
|
+const message = useMessage()
|
|
|
+const nodeInfo = ref({})
|
|
|
+const menuVisible = ref(false)
|
|
|
+const menuX = ref(0)
|
|
|
+const menuY = ref(0)
|
|
|
+const contextMenuRef = ref(null) // 弹窗DOM引用
|
|
|
+const { t } = useI18n()
|
|
|
+let selectedNode = null
|
|
|
+const parentId = ref()
|
|
|
+const formType = ref<'create' | 'update'>('create')
|
|
|
+
|
|
|
+const formData = ref({
|
|
|
+ id: undefined,
|
|
|
+ title: '',
|
|
|
+ parentId: undefined,
|
|
|
+ name: undefined,
|
|
|
+ sort: undefined,
|
|
|
+ leaderUserId: undefined,
|
|
|
+ phone: undefined,
|
|
|
+ email: undefined,
|
|
|
+ status: CommonStatusEnum.ENABLE
|
|
|
+})
|
|
|
+const formRules = ref({
|
|
|
+ name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
|
|
|
+ sort: [{ required: true, message: '请输入排序', trigger: 'blur' }]
|
|
|
+})
|
|
|
+const handleRightClick = (event, node, data) => {
|
|
|
+ console.log('xxxxxxxxxxxxxxxxxxxxx')
|
|
|
+ nodeInfo.value = node
|
|
|
+ event.preventDefault()
|
|
|
+ menuX.value = event.clientX
|
|
|
+ menuY.value = event.clientY
|
|
|
+ selectedNode = data
|
|
|
+ parentId.value = data.data.id
|
|
|
+
|
|
|
+ menuVisible.value = true
|
|
|
+}
|
|
|
+
|
|
|
+const resetForm = () => {
|
|
|
+ formData.value = {
|
|
|
+ id: undefined,
|
|
|
+ title: '',
|
|
|
+ parentId: undefined,
|
|
|
+ name: undefined,
|
|
|
+ sort: undefined,
|
|
|
+ leaderUserId: undefined,
|
|
|
+ phone: undefined,
|
|
|
+ email: undefined,
|
|
|
+ status: CommonStatusEnum.ENABLE
|
|
|
+ }
|
|
|
+ formRef.value?.resetFields()
|
|
|
+}
|
|
|
+
|
|
|
+const handleMenuClick = async (action) => {
|
|
|
+ switch (action) {
|
|
|
+ case 'add':
|
|
|
+ dialogVisible.value = true
|
|
|
+ dialogTitle.value = '新增目录'
|
|
|
+ formType.value = 'create'
|
|
|
+ resetForm()
|
|
|
+ break
|
|
|
+ case 'edit':
|
|
|
+ resetForm()
|
|
|
+ dialogVisible.value = true
|
|
|
+ dialogTitle.value = '编辑目录'
|
|
|
+ formType.value = 'update'
|
|
|
+ formData.value = { ...nodeInfo.value }
|
|
|
+
|
|
|
+ break
|
|
|
+ case 'delete':
|
|
|
+ // 删除的二次确认
|
|
|
+ await message.delConfirm()
|
|
|
+ // 假设存在删除接口
|
|
|
+ await IotTreeApi.deleteIotTree(nodeInfo.value.id)
|
|
|
+ message.success(t('common.delSuccess'))
|
|
|
+ // 刷新列表
|
|
|
+ await getTreeInfo()
|
|
|
+ break
|
|
|
+ }
|
|
|
+
|
|
|
+ menuVisible.value = false
|
|
|
+ // nextTick(() => {
|
|
|
+ // treeRef.value?.setCurrentKey(targetId)
|
|
|
+ // treeRef.value?.getNode(targetId)?.$el?.scrollIntoView({
|
|
|
+ // behavior: 'smooth',
|
|
|
+ // block: 'nearest'
|
|
|
+ // })
|
|
|
+ // })
|
|
|
+}
|
|
|
+
|
|
|
+const submitForm = async () => {
|
|
|
+ // 表单验证逻辑
|
|
|
+
|
|
|
+ try {
|
|
|
+ // formData.value.parentId = parentId.value
|
|
|
+ if (formData.value.parentId === undefined || formData.value.parentId === null) {
|
|
|
+ formData.value.parentId = props.currentId
|
|
|
+ }
|
|
|
+ formData.value.type = 'file'
|
|
|
+ if (formType.value === 'create') {
|
|
|
+ await IotTreeApi.createIotTree(formData.value)
|
|
|
+ } else {
|
|
|
+ await IotTreeApi.updateIotTree(formData.value)
|
|
|
+ }
|
|
|
+ message.success(t(formType.value === 'create' ? '添加成功' : '修改成功'))
|
|
|
+ dialogVisible.value = false
|
|
|
+ menuVisible.value = false
|
|
|
+ await getTreeInfo()
|
|
|
+ } catch (error) {
|
|
|
+ console.error(error)
|
|
|
+ } finally {
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
interface TreeNode extends IotTreeVO {
|
|
|
children?: TreeNode[]
|
|
|
}
|
|
|
@@ -162,6 +280,7 @@ onMounted(getTreeInfo)
|
|
|
:props="defaultProps"
|
|
|
highlight-current
|
|
|
node-key="id"
|
|
|
+ @node-contextmenu="handleRightClick"
|
|
|
@node-click="handleNodeClick">
|
|
|
<template #default="{ node }">
|
|
|
<div class="tree-node">
|
|
|
@@ -172,12 +291,45 @@ onMounted(getTreeInfo)
|
|
|
</div>
|
|
|
</template>
|
|
|
</el-tree>
|
|
|
+
|
|
|
+ <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>
|
|
|
</el-scrollbar>
|
|
|
</template>
|
|
|
</el-auto-resizer>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
+ <Dialog v-model="dialogVisible" :title="dialogTitle" style="width: 40em">
|
|
|
+ <el-form ref="formRef" :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>
|
|
|
+ <template #footer>
|
|
|
+ <el-button type="primary" @click="submitForm">确 定</el-button>
|
|
|
+ <el-button @click="dialogVisible = false">取 消</el-button>
|
|
|
+ </template>
|
|
|
+ </Dialog>
|
|
|
+
|
|
|
<div class="collapse-handle" @click="isCollapsed = !isCollapsed">
|
|
|
<el-icon size="12">
|
|
|
<CaretLeft v-if="!isCollapsed" />
|