|
|
@@ -1,258 +1,192 @@
|
|
|
<route lang="yaml">
|
|
|
-meta: ''
|
|
|
-enabled: false
|
|
|
-</route>
|
|
|
-
|
|
|
-<script lang="ts" setup name="PagesExampleDictionary">
|
|
|
-import { ElMessageBox } from 'element-plus'
|
|
|
-import type Node from 'element-plus/es/components/tree/src/model/node'
|
|
|
-import dictionaryDialog from './components/dictionaryDialog/index.vue'
|
|
|
-import dictionaryItemDialog from './components/dictionaryItemDialog/index.vue'
|
|
|
-
|
|
|
-interface Dict {
|
|
|
- id: string | number
|
|
|
+meta:
|
|
|
+ enabled: false
|
|
|
+ </route>
|
|
|
+
|
|
|
+<script lang="ts" setup>
|
|
|
+import { ElMessage, ElMessageBox } from 'element-plus'
|
|
|
+import PSModule from './components/Module/index.vue'
|
|
|
+import PSApi from './components/Api/index.vue'
|
|
|
+import { deleteApiById, getApiByList, updateApiStatus } from '@/api/paas/apiApi'
|
|
|
+import { deleteModuleById, getModuleByList } from '@/api/paas/moduleApi'
|
|
|
+
|
|
|
+interface TreeNode {
|
|
|
label: string
|
|
|
- code: string
|
|
|
- children?: Dict[]
|
|
|
+ isLeaf: boolean
|
|
|
+ modId: number
|
|
|
+ children?: TreeNode[]
|
|
|
+}
|
|
|
+
|
|
|
+interface Object {
|
|
|
+ modId: number
|
|
|
+ objectId: number
|
|
|
+ objectTitle: string
|
|
|
+ objectCode: string
|
|
|
+ comment: string
|
|
|
}
|
|
|
-const dictionaryRef = ref()
|
|
|
-const dictionary = ref({
|
|
|
- search: '',
|
|
|
- tree: [] as Dict[],
|
|
|
- currentNode: undefined as Node | undefined,
|
|
|
- currentData: undefined as Dict | undefined,
|
|
|
- dialog: {
|
|
|
- visible: false,
|
|
|
- parentId: '' as Dict['id'],
|
|
|
- id: '' as Dict['id'],
|
|
|
- },
|
|
|
-})
|
|
|
|
|
|
-const { pagination, getParams, onSizeChange, onCurrentChange, onSortChange } = usePagination()
|
|
|
-pagination.value.size = 20
|
|
|
-pagination.value.sizes = [20, 50, 100]
|
|
|
-const dictionaryItemRef = ref()
|
|
|
-const dictionaryItem = ref({
|
|
|
+const state = reactive({
|
|
|
loading: false,
|
|
|
- // 搜索
|
|
|
+ keywords: '',
|
|
|
+ Modules: [] as TreeNode[],
|
|
|
+ curModuleId: 0,
|
|
|
+ objectList: [] as Object[],
|
|
|
+ dialogState: 1,
|
|
|
search: {
|
|
|
- dictionaryId: '' as Dict['id'],
|
|
|
- title: '',
|
|
|
- },
|
|
|
- // 列表数据
|
|
|
- dataList: [],
|
|
|
- selectionDataList: [],
|
|
|
- dialog: {
|
|
|
- visible: false,
|
|
|
- id: '' as string | number,
|
|
|
+ keywords: '',
|
|
|
},
|
|
|
})
|
|
|
|
|
|
-const getDictionaryList = () => {
|
|
|
- dictionaryItem.value.search.dictionaryId = ''
|
|
|
-}
|
|
|
-onMounted(() => {
|
|
|
- getDictionaryList()
|
|
|
-})
|
|
|
-watch(() => dictionary.value.search, (val) => {
|
|
|
- dictionaryRef.value!.filter(val)
|
|
|
-})
|
|
|
-const dictionaryFilter = (value: string, data: Dict) => {
|
|
|
- if (!value) {
|
|
|
- return true
|
|
|
+const leftTreeRef = ref()
|
|
|
+const ModuleRef = ref()
|
|
|
+const getApiData = async () => {
|
|
|
+ const curModuleId = state.curModuleId
|
|
|
+ if (curModuleId > 0) {
|
|
|
+ state.loading = true
|
|
|
+ const { data } = await getApiByList({ modId: curModuleId })
|
|
|
+ state.objectList = data
|
|
|
+ state.loading = false
|
|
|
}
|
|
|
- return data.label.includes(value)
|
|
|
}
|
|
|
-const dictionaryAdd = (data?: Dict) => {
|
|
|
- dictionary.value.currentData = data
|
|
|
- dictionary.value.dialog.parentId = data?.id ?? ''
|
|
|
- dictionary.value.dialog.id = ''
|
|
|
- dictionary.value.dialog.visible = true
|
|
|
-}
|
|
|
-const dictionaryEdit = (node: Node, data: Dict) => {
|
|
|
- dictionary.value.currentNode = node
|
|
|
- dictionary.value.currentData = data
|
|
|
- dictionary.value.dialog.parentId = node.parent.data.id ?? ''
|
|
|
- dictionary.value.dialog.id = data.id
|
|
|
- dictionary.value.dialog.visible = true
|
|
|
-}
|
|
|
-const dictionaryDelete = (node: Node, data: Dict) => {
|
|
|
- ElMessageBox.confirm(`确认删除「${data.label}」吗?`, '确认信息').then(() => {
|
|
|
|
|
|
- })
|
|
|
-}
|
|
|
-// 新增成功后更新树
|
|
|
-const dictionaryAddNode = (data: Dict) => {
|
|
|
- if (dictionary.value.currentData) {
|
|
|
- if (!dictionary.value.currentData.children) {
|
|
|
- dictionary.value.currentData.children = []
|
|
|
- }
|
|
|
- dictionary.value.currentData.children.push({
|
|
|
- id: data.id,
|
|
|
- label: data.label,
|
|
|
- code: data.code,
|
|
|
+const getModuleData = async () => {
|
|
|
+ const { data } = await getModuleByList('')
|
|
|
+ const children: TreeNode[] = []
|
|
|
+ data.forEach((item: any) => {
|
|
|
+ return children.push({
|
|
|
+ label: item.modTitle,
|
|
|
+ modId: item.modId,
|
|
|
+ isLeaf: true,
|
|
|
})
|
|
|
- }
|
|
|
- else {
|
|
|
- dictionary.value.tree.push({
|
|
|
- id: data.id,
|
|
|
- label: data.label,
|
|
|
- code: data.code,
|
|
|
+ })
|
|
|
+ state.Modules = [
|
|
|
+ {
|
|
|
+ label: 'API模块列表',
|
|
|
+ isLeaf: false,
|
|
|
+ modId: -1,
|
|
|
+ children,
|
|
|
+ },
|
|
|
+ ]
|
|
|
+
|
|
|
+ if (data && data.length > 0) {
|
|
|
+ state.curModuleId = data[0].modId
|
|
|
+ nextTick(() => {
|
|
|
+ leftTreeRef.value.setCurrentKey(data[0].modId)
|
|
|
})
|
|
|
+ await getApiData()
|
|
|
}
|
|
|
}
|
|
|
-// 编辑成功后更新树
|
|
|
-const dictionaryEditNode = (data: Dict, parentId: string | number) => {
|
|
|
- if (dictionary.value.currentNode && dictionary.value.currentData) {
|
|
|
- if ((dictionary.value.currentNode.parent.data.id ?? '') === parentId) {
|
|
|
- // 如果 parentId 一致说明节点位置没有变化,直接更新
|
|
|
- dictionary.value.currentData.label = data.label
|
|
|
- dictionary.value.currentData.code = data.code
|
|
|
- }
|
|
|
- else {
|
|
|
- // 先更新原有节点信息
|
|
|
- const parent = dictionary.value.currentNode.parent
|
|
|
- const children: Dict[] = parent.data.children || parent.data
|
|
|
- const index = children.findIndex(item => item.id === data.id)
|
|
|
- children[index].label = data.label
|
|
|
- children[index].code = data.code
|
|
|
- // 然后找到需要移动到的父节点位置,并将原有节点移动过去
|
|
|
- if (parentId) {
|
|
|
- const findDictionary: any = (list: Dict[], parentId: number) => {
|
|
|
- for (const i in list) {
|
|
|
- if (list[i].id === parentId) {
|
|
|
- return list[i]
|
|
|
- }
|
|
|
- else if (list[i].children) {
|
|
|
- const temp = findDictionary(list[i].children, parentId)
|
|
|
- if (temp) {
|
|
|
- return temp
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- const targetNode = findDictionary(dictionary.value.tree, parentId)
|
|
|
- if (!targetNode.children) {
|
|
|
- targetNode.children = []
|
|
|
- }
|
|
|
- targetNode.children.push(children[index])
|
|
|
- }
|
|
|
- else {
|
|
|
- dictionary.value.tree.push(children[index])
|
|
|
- }
|
|
|
- // 最后删除原节点
|
|
|
- children.splice(index, 1)
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-const dictionaryClick = (data: Dict) => {
|
|
|
- pagination.value.page = 1
|
|
|
- dictionaryItem.value.search.dictionaryId = data.id
|
|
|
+// 模型新增
|
|
|
+const onModuleAdd = () => {
|
|
|
+ ModuleRef.value.showAddModule()
|
|
|
}
|
|
|
|
|
|
-watch(() => dictionaryItem.value.search.dictionaryId, () => {
|
|
|
- getDictionaryItemList()
|
|
|
-})
|
|
|
-
|
|
|
-function getDictionaryItemList() {
|
|
|
- dictionaryItem.value.loading = true
|
|
|
- const params = getParams()
|
|
|
- dictionaryItem.value.search.dictionaryId && (params.dictionaryId = dictionaryItem.value.search.dictionaryId)
|
|
|
- dictionaryItem.value.search.title && (params.title = dictionaryItem.value.search.title)
|
|
|
+// 模型编辑
|
|
|
+const onModuleEdit = (data: { ModuleId: number }) => {
|
|
|
+ const ModuleId = data.ModuleId
|
|
|
+ ModuleRef.value.showEditModule(ModuleId)
|
|
|
}
|
|
|
|
|
|
-function onChangeEnable(row: any) {
|
|
|
- return new Promise<boolean>((resolve) => {
|
|
|
- ElMessageBox.confirm(`确认${!row.enable ? '启用' : '禁用'}「${row.name}」吗?`, '确认信息').then(() => {
|
|
|
- row.enableLoading = true
|
|
|
- }).catch(() => {
|
|
|
- return resolve(false)
|
|
|
+// 模型删除
|
|
|
+const onModuleDelete = (data: any) => {
|
|
|
+ ElMessageBox.confirm(`确认删除「${data.modTitle}」吗?`, '确认信息').then(async () => {
|
|
|
+ await deleteModuleById(data.modId)
|
|
|
+ await getModuleData()
|
|
|
+ ElMessage.success({
|
|
|
+ message: '删除成功',
|
|
|
+ center: true,
|
|
|
})
|
|
|
})
|
|
|
}
|
|
|
|
|
|
-// 每页数量切换
|
|
|
-function sizeChange(size: number) {
|
|
|
- onSizeChange(size).then(() => getDictionaryItemList())
|
|
|
+// 模型选择
|
|
|
+const onTreeNodeClick = (node: TreeNode) => {
|
|
|
+ if (node.isLeaf) {
|
|
|
+ state.curModuleId = node.modId
|
|
|
+ getApiData()
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-// 当前页码切换(翻页)
|
|
|
-function currentChange(page = 1) {
|
|
|
- onCurrentChange(page).then(() => getDictionaryItemList())
|
|
|
-}
|
|
|
+const objectTableRef = ref()
|
|
|
+const apiRef = ref()
|
|
|
|
|
|
-// 字段排序
|
|
|
-function sortChange({ prop, order }: { prop: string; order: string }) {
|
|
|
- onSortChange(prop, order).then(() => getDictionaryItemList())
|
|
|
+// 检索对象
|
|
|
+const onSearch = () => {
|
|
|
+ getApiData()
|
|
|
}
|
|
|
|
|
|
-function onCreate() {
|
|
|
- dictionaryItem.value.dialog.id = ''
|
|
|
- dictionaryItem.value.dialog.visible = true
|
|
|
+// 新增API
|
|
|
+const onApiAdd = () => {
|
|
|
+ apiRef.value.showAddApi(state.curModuleId)
|
|
|
}
|
|
|
|
|
|
-function onEdit(row: any) {
|
|
|
- dictionaryItem.value.dialog.id = row.id
|
|
|
- dictionaryItem.value.dialog.visible = true
|
|
|
+// 编辑API
|
|
|
+const onApiEdit = (data: { apiId: number; modId: number }) => {
|
|
|
+ const apiId = data.apiId
|
|
|
+ const modId = data.modId
|
|
|
+ apiRef.value.showEditApi(modId, apiId)
|
|
|
}
|
|
|
|
|
|
-function onDelete(row: any) {
|
|
|
- ElMessageBox.confirm(`确认删除「${row.name}」吗?`, '确认信息').then(() => {
|
|
|
- }).catch(() => {})
|
|
|
+// 删除API
|
|
|
+const onApiDelete = (row: any) => {
|
|
|
+ const { apiId, apiTitle } = row
|
|
|
+ ElMessageBox.confirm(`确认删除「${apiTitle}」吗?`, '确认信息').then(async () => {
|
|
|
+ await deleteApiById(apiId)
|
|
|
+ await getApiData()
|
|
|
+ ElMessage.success({
|
|
|
+ message: '删除成功',
|
|
|
+ center: true,
|
|
|
+ })
|
|
|
+ })
|
|
|
}
|
|
|
-
|
|
|
-function onDeleteMulti(rows: any[]) {
|
|
|
- ElMessageBox.confirm(`确认删除选中的 ${rows.length} 条数据吗?`, '确认信息').then(() => {
|
|
|
- }).catch(() => {})
|
|
|
+async function onChangeStatus(row: { modId: number;apiId: number; status: number }) {
|
|
|
+ await updateApiStatus(row.modId, row.apiId, row.status)
|
|
|
}
|
|
|
+onMounted(() => {
|
|
|
+ getModuleData()
|
|
|
+})
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
|
<div class="absolute-container">
|
|
|
- <page-header title="字典管理" content="页面数据为 Mock 示例数据,非真实数据。" />
|
|
|
+ <tool-header title="API接口">
|
|
|
+ <template #right>
|
|
|
+ <el-button plain @click="onModuleAdd">
|
|
|
+ <template #icon>
|
|
|
+ <el-icon>
|
|
|
+ <svg-icon name="i-ep:plus" />
|
|
|
+ </el-icon>
|
|
|
+ </template>
|
|
|
+ 新增API模块
|
|
|
+ </el-button>
|
|
|
+ </template>
|
|
|
+ </tool-header>
|
|
|
+
|
|
|
<div class="page-main">
|
|
|
- <LayoutContainer hide-left-side-toggle>
|
|
|
+ <LayoutContainer left-side-width="300px" hide-left-side-toggle>
|
|
|
<template #leftSide>
|
|
|
- <el-button-group class="btns">
|
|
|
- <el-button type="primary" class="add" @click="dictionaryAdd()">
|
|
|
- 新增字典
|
|
|
- </el-button>
|
|
|
- <el-button @click="getDictionaryList">
|
|
|
- <template #icon>
|
|
|
- <el-icon>
|
|
|
- <svg-icon name="i-ep:refresh" />
|
|
|
- </el-icon>
|
|
|
- </template>
|
|
|
- </el-button>
|
|
|
- </el-button-group>
|
|
|
- <el-input v-model="dictionary.search" placeholder="请输入关键词筛选字典" clearable class="search" />
|
|
|
<el-scrollbar class="tree">
|
|
|
- <ElTree ref="dictionaryRef" :data="dictionary.tree" :filter-node-method="dictionaryFilter as any" default-expand-all @node-click="dictionaryClick">
|
|
|
+ <ElTree ref="leftTreeRef" :data="state.Modules" default-expand-all node-key="modId" @node-click="onTreeNodeClick">
|
|
|
<template #default="{ node, data }">
|
|
|
<div class="custom-tree-node">
|
|
|
<div class="label" :title="node.label">
|
|
|
- {{ node.label }}
|
|
|
- </div>
|
|
|
- <div class="code">
|
|
|
- {{ data.code }}
|
|
|
+ <el-icon v-if="data.isLeaf" size="16px" style="margin-right: 5px;">
|
|
|
+ <svg-icon name="uim:box" />
|
|
|
+ </el-icon>
|
|
|
+ <div class="text">
|
|
|
+ {{ data.label }}
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- <div class="actions">
|
|
|
+ <div v-if="data.isLeaf" class="actions">
|
|
|
<el-button-group>
|
|
|
- <el-button type="primary" plain size="default" @click.stop="dictionaryAdd(data)">
|
|
|
- <template #icon>
|
|
|
- <el-icon>
|
|
|
- <svg-icon name="i-ep:plus" />
|
|
|
- </el-icon>
|
|
|
- </template>
|
|
|
- </el-button>
|
|
|
- <el-button type="info" plain size="default" @click.stop="dictionaryEdit(node, data)">
|
|
|
+ <el-button type="info" plain size="small" @click.stop="onModuleEdit(data)">
|
|
|
<template #icon>
|
|
|
<el-icon>
|
|
|
<svg-icon name="i-ep:edit" />
|
|
|
</el-icon>
|
|
|
</template>
|
|
|
</el-button>
|
|
|
- <el-button type="danger" plain size="default" @click.stop="dictionaryDelete(node, data)">
|
|
|
+ <el-button type="danger" plain size="small" @click.stop="onModuleDelete(data)">
|
|
|
<template #icon>
|
|
|
<el-icon>
|
|
|
<svg-icon name="i-ep:delete" />
|
|
|
@@ -266,194 +200,147 @@ function onDeleteMulti(rows: any[]) {
|
|
|
</ElTree>
|
|
|
</el-scrollbar>
|
|
|
</template>
|
|
|
- <div v-show="dictionaryItem.search.dictionaryId" class="container">
|
|
|
- <el-space wrap>
|
|
|
- <el-button type="primary" @click="onCreate">
|
|
|
- <template #icon>
|
|
|
- <el-icon>
|
|
|
- <svg-icon name="i-ep:plus" />
|
|
|
- </el-icon>
|
|
|
- </template>
|
|
|
- </el-button>
|
|
|
- <el-button type="danger" :disabled="!dictionaryItem.selectionDataList.length" @click="onDeleteMulti(dictionaryItem.selectionDataList)">
|
|
|
- <template #icon>
|
|
|
- <el-icon>
|
|
|
- <svg-icon name="i-ep:delete" />
|
|
|
- </el-icon>
|
|
|
- </template>
|
|
|
- </el-button>
|
|
|
- <el-input v-model="dictionaryItem.search.title" placeholder="请输入关键词筛选字典项" clearable style="width: 200px;" />
|
|
|
- <el-button @click="getDictionaryItemList">
|
|
|
- <template #icon>
|
|
|
- <el-icon>
|
|
|
- <svg-icon name="i-ep:search" />
|
|
|
- </el-icon>
|
|
|
- </template>
|
|
|
- </el-button>
|
|
|
- </el-space>
|
|
|
- <el-table ref="dictionaryItemRef" v-loading="dictionaryItem.loading" :data="dictionaryItem.dataList" border stripe highlight-current-row height="100%" @sort-change="sortChange" @selection-change="dictionaryItem.selectionDataList = $event">
|
|
|
- <el-table-column type="selection" align="center" fixed />
|
|
|
- <el-table-column prop="name" label="名称" />
|
|
|
- <el-table-column label="键值" align="center" width="150">
|
|
|
- <template #default="scope">
|
|
|
- <el-tag type="info">
|
|
|
- {{ scope.row.value }}
|
|
|
- </el-tag>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- <el-table-column label="状态" width="100" align="center">
|
|
|
- <template #default="scope">
|
|
|
- <el-switch v-model="scope.row.enable" :loading="scope.row.enableLoading" inline-prompt active-text="启用" inactive-text="禁用" :before-change="() => onChangeEnable(scope.row)" />
|
|
|
+
|
|
|
+ <div class="container">
|
|
|
+ <tool-bar>
|
|
|
+ <template #right>
|
|
|
+ <el-input v-model="state.search.keywords" placeholder="请输入名称,支持模糊查询" style="padding-right: 10px;" clearable />
|
|
|
+ <el-button type="primary" @click="onSearch">
|
|
|
+ <template #icon>
|
|
|
+ <el-icon>
|
|
|
+ <svg-icon name="i-ep:search" />
|
|
|
+ </el-icon>
|
|
|
+ </template>
|
|
|
+ </el-button>
|
|
|
+
|
|
|
+ <el-button plain size="default" @click.stop="onApiAdd">
|
|
|
+ <template #icon>
|
|
|
+ <el-icon>
|
|
|
+ <svg-icon name="i-ep:plus" />
|
|
|
+ </el-icon>
|
|
|
+ </template>
|
|
|
+ 新增API
|
|
|
+ </el-button>
|
|
|
+ </template>
|
|
|
+ </tool-bar>
|
|
|
+
|
|
|
+ <el-table ref="objectTableRef" v-loading="state.loading" class="list-table" :data="state.objectList" border stripe highlight-current-row height="100%">
|
|
|
+ <el-table-column type="index" label="序号" header-align="center" align="center" width="70" />
|
|
|
+
|
|
|
+ <el-table-column prop="apiTitle" label="名称" header-align="center" align="center" width="200" />
|
|
|
+
|
|
|
+ <el-table-column prop="apiCode" label="代码" header-align="center" align="center" width="150" />
|
|
|
+ <el-table-column prop="status" label="status" header-align="center" align="center" width="150">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <el-switch
|
|
|
+ v-model="row.status"
|
|
|
+ :active-value="0"
|
|
|
+ :inactive-value="1"
|
|
|
+ inline-prompt
|
|
|
+ active-text="启用"
|
|
|
+ inactive-text="禁用"
|
|
|
+ @change="(status) => onChangeStatus(row)"
|
|
|
+ />
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column label="操作" width="200" align="center">
|
|
|
+
|
|
|
+ <el-table-column prop="apiDesc" label="说明" header-align="center" align="left" />
|
|
|
+
|
|
|
+ <el-table-column label="操作" header-align="center" align="center" width="200">
|
|
|
<template #default="scope">
|
|
|
- <el-button type="primary" size="small" plain @click="onEdit(scope.row)">
|
|
|
+ <el-button type="primary" size="small" plain @click="onApiEdit(scope.row)">
|
|
|
编辑
|
|
|
</el-button>
|
|
|
- <el-button type="danger" size="small" plain @click="onDelete(scope.row)">
|
|
|
+ <el-button type="danger" size="small" plain @click="onApiDelete(scope.row)">
|
|
|
删除
|
|
|
</el-button>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
</el-table>
|
|
|
- <el-pagination :current-page="pagination.page" :total="pagination.total" :page-size="pagination.size" :page-sizes="pagination.sizes" :layout="pagination.layout" :hide-on-single-page="false" class="pagination" background @size-change="sizeChange" @current-change="currentChange" />
|
|
|
- </div>
|
|
|
- <div v-show="!dictionaryItem.search.dictionaryId" class="container">
|
|
|
- <div class="empty">
|
|
|
- 请在左侧新增或选择一个字典
|
|
|
- </div>
|
|
|
</div>
|
|
|
</LayoutContainer>
|
|
|
- <dictionaryDialog v-if="dictionary.dialog.visible" :id="dictionary.dialog.id" v-model="dictionary.dialog.visible" :parent-id="dictionary.dialog.parentId" :tree="dictionary.tree" @add-node="dictionaryAddNode" @edit-node="dictionaryEditNode" />
|
|
|
- <dictionaryItemDialog v-if="dictionaryItem.dialog.visible" :id="dictionaryItem.dialog.id" v-model="dictionaryItem.dialog.visible" :dictionary-id="dictionaryItem.search.dictionaryId" :tree="dictionary.tree" @success="getDictionaryItemList" />
|
|
|
</div>
|
|
|
+ <PSModule ref="ModuleRef" @success="getModuleData" />
|
|
|
+ <PSApi ref="apiRef" @success="getApiData" />
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
-<style lang="scss" scoped>
|
|
|
-.absolute-container {
|
|
|
- position: absolute;
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
-
|
|
|
- .page-header {
|
|
|
- margin-bottom: 0;
|
|
|
- }
|
|
|
-
|
|
|
- .page-main {
|
|
|
- // 让 page-main 的高度自适应
|
|
|
- flex: 1;
|
|
|
- overflow: auto;
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
-
|
|
|
- .flex-container {
|
|
|
- position: static;
|
|
|
+ <style lang="scss" scoped>
|
|
|
+ .container {
|
|
|
+ height: 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
}
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-.flex-container {
|
|
|
- :deep(.left-side) {
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- height: 100%;
|
|
|
|
|
|
- .btns {
|
|
|
- display: inline-flex;
|
|
|
- width: 100%;
|
|
|
-
|
|
|
- .add {
|
|
|
- width: 100%;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .search {
|
|
|
- margin: 15px 0;
|
|
|
- }
|
|
|
+ .absolute-container {
|
|
|
+ :deep(.left-side) {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ height: 100%;
|
|
|
|
|
|
- .tree {
|
|
|
- flex: 1;
|
|
|
- overflow-y: auto;
|
|
|
+ .btns {
|
|
|
+ display: inline-flex;
|
|
|
+ width: 100%;
|
|
|
+ margin-bottom: var(--container-padding);
|
|
|
|
|
|
- .el-tree {
|
|
|
- .el-tree-node__content {
|
|
|
- height: 60px;
|
|
|
- }
|
|
|
-
|
|
|
- .is-current > .el-tree-node__content {
|
|
|
- background-color: var(--el-color-primary-light-9);
|
|
|
+ .add {
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- .custom-tree-node {
|
|
|
+ .tree {
|
|
|
flex: 1;
|
|
|
- position: relative;
|
|
|
- width: 0;
|
|
|
- height: 100%;
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- justify-content: center;
|
|
|
-
|
|
|
- .label {
|
|
|
- width: calc(100% - 10px);
|
|
|
- color: var(--el-text-color-primary);
|
|
|
-
|
|
|
- @include text-overflow;
|
|
|
- }
|
|
|
-
|
|
|
- .code {
|
|
|
- width: calc(100% - 10px);
|
|
|
- color: var(--el-text-color-placeholder);
|
|
|
+ overflow-y: auto;
|
|
|
|
|
|
- @include text-overflow;
|
|
|
- }
|
|
|
+ .el-tree {
|
|
|
+ .el-tree-node__content {
|
|
|
+ height: 40px;
|
|
|
+ }
|
|
|
|
|
|
- &:hover {
|
|
|
- .actions {
|
|
|
- display: block;
|
|
|
+ .is-current > .el-tree-node__content {
|
|
|
+ background-color: var(--el-color-primary-light-9);
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- .actions {
|
|
|
- display: none;
|
|
|
- position: absolute;
|
|
|
- right: 10px;
|
|
|
- top: 50%;
|
|
|
- transform: translateY(-50%);
|
|
|
+ .custom-tree-node {
|
|
|
+ flex: 1;
|
|
|
+ position: relative;
|
|
|
+ width: 0;
|
|
|
+ height: 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: center;
|
|
|
+
|
|
|
+ .label {
|
|
|
+ display: inline-flex;
|
|
|
+ align-items: center;
|
|
|
+ width: calc(100% - 10px);
|
|
|
+ color: var(--el-text-color-primary);
|
|
|
+
|
|
|
+ .text {
|
|
|
+ @include text-overflow;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ .actions {
|
|
|
+ display: block;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .actions {
|
|
|
+ display: none;
|
|
|
+ position: absolute;
|
|
|
+ right: 10px;
|
|
|
+ top: 50%;
|
|
|
+ transform: translateY(-50%);
|
|
|
|
|
|
- .el-button {
|
|
|
- padding: 5px 8px;
|
|
|
+ .el-button {
|
|
|
+ padding: 5px 8px;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- :deep(.main) {
|
|
|
- display: flex;
|
|
|
- justify-content: center;
|
|
|
- }
|
|
|
-
|
|
|
- .container {
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- justify-content: center;
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
-
|
|
|
- .empty {
|
|
|
- text-align: center;
|
|
|
- font-size: 32px;
|
|
|
- color: var(--el-text-color-placeholder);
|
|
|
- }
|
|
|
-
|
|
|
- .el-table {
|
|
|
- margin: 15px 0;
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-</style>
|
|
|
+ </style>
|