|
@@ -4,150 +4,239 @@ meta:
|
|
|
</route>
|
|
</route>
|
|
|
|
|
|
|
|
<script lang="ts" setup>
|
|
<script lang="ts" setup>
|
|
|
|
|
+import { getModelByList } from '@/api/model/modelApi'
|
|
|
|
|
+import { getObjectByList } from '@/api/model/modelObjectApi'
|
|
|
|
|
+import useSettingsStore from '@/store/modules/settings'
|
|
|
|
|
+
|
|
|
|
|
+const settingsStore = useSettingsStore()
|
|
|
|
|
+const router = useRouter()
|
|
|
|
|
+const tabbar = useTabbar()
|
|
|
|
|
+
|
|
|
|
|
+interface TreeNode {
|
|
|
|
|
+ label: string
|
|
|
|
|
+ isLeaf: boolean
|
|
|
|
|
+ value: number
|
|
|
|
|
+ children?: TreeNode[]
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+interface Object {
|
|
|
|
|
+ modelId: number
|
|
|
|
|
+ objectId: number
|
|
|
|
|
+ objectTitle: string
|
|
|
|
|
+ objectCode: string
|
|
|
|
|
+ comment: string
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
const state = reactive({
|
|
const state = reactive({
|
|
|
- layoutMode: 'model',
|
|
|
|
|
|
|
+ loading: false,
|
|
|
|
|
+ keywords: '',
|
|
|
|
|
+ treeData: [] as TreeNode[],
|
|
|
|
|
+ curObjectId: 0,
|
|
|
|
|
+ objectList: [] as Object[],
|
|
|
|
|
+ dialogState: 1,
|
|
|
|
|
+ search: {
|
|
|
|
|
+ keywords: '',
|
|
|
|
|
+ },
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+const leftTreeRef = ref()
|
|
|
|
|
+const modelRef = ref()
|
|
|
|
|
+const getObjectList = async () => {
|
|
|
|
|
+ const curModelId = state.curObjectId
|
|
|
|
|
+ if (curModelId > 0) {
|
|
|
|
|
+ state.loading = true
|
|
|
|
|
+ const { data } = await getObjectByList({})
|
|
|
|
|
+ state.objectList = data
|
|
|
|
|
+ state.loading = false
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const getObjectData = () => {
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const getModelList = async () => {
|
|
|
|
|
+ const { data } = await getModelByList('')
|
|
|
|
|
+ const models: TreeNode[] = []
|
|
|
|
|
+ data.forEach((item: any) => {
|
|
|
|
|
+ models.push({
|
|
|
|
|
+ label: item.modelTitle,
|
|
|
|
|
+ value: item.modelId,
|
|
|
|
|
+ isLeaf: false,
|
|
|
|
|
+ })
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ state.treeData = models
|
|
|
|
|
+
|
|
|
|
|
+ if (data && data.length > 0) {
|
|
|
|
|
+ state.curObjectId = data[0].value
|
|
|
|
|
+ nextTick(() => {
|
|
|
|
|
+ leftTreeRef.value.setCurrentKey(data[0].value)
|
|
|
|
|
+ })
|
|
|
|
|
+ await getObjectData()
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+onMounted(() => {
|
|
|
|
|
+ getModelList()
|
|
|
})
|
|
})
|
|
|
-const model = ref()
|
|
|
|
|
-const sql = ref()
|
|
|
|
|
-const table = ref()
|
|
|
|
|
-const changeLayout = () => {
|
|
|
|
|
- switch (state.layoutMode) {
|
|
|
|
|
- case 'model':
|
|
|
|
|
- model.value.show()
|
|
|
|
|
- break
|
|
|
|
|
- case 'table':
|
|
|
|
|
- window.console.log(table)
|
|
|
|
|
- break
|
|
|
|
|
- default:
|
|
|
|
|
- window.console.log(sql)
|
|
|
|
|
- break
|
|
|
|
|
|
|
+
|
|
|
|
|
+// 对象选择
|
|
|
|
|
+const onTreeNodeClick = (node: TreeNode) => {
|
|
|
|
|
+ if (node.isLeaf) {
|
|
|
|
|
+ state.curObjectId = node.value
|
|
|
|
|
+ getObjectData()
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+const objectTableRef = ref()
|
|
|
|
|
+const objectRef = ref()
|
|
|
|
|
+
|
|
|
|
|
+// 检索对象
|
|
|
|
|
+const onSearch = () => {
|
|
|
|
|
+ getObjectData()
|
|
|
|
|
+}
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<template>
|
|
<template>
|
|
|
<div class="absolute-container">
|
|
<div class="absolute-container">
|
|
|
<tool-header title="数据仓库">
|
|
<tool-header title="数据仓库">
|
|
|
- <template #center>
|
|
|
|
|
- <el-radio-group v-model="state.layoutMode" @change="changeLayout">
|
|
|
|
|
- <el-radio-button label="model">
|
|
|
|
|
- 基于模型
|
|
|
|
|
- </el-radio-button>
|
|
|
|
|
- <el-radio-button label="table">
|
|
|
|
|
- 基于表
|
|
|
|
|
- </el-radio-button>
|
|
|
|
|
- <el-radio-button label="sql">
|
|
|
|
|
- 基于SQL
|
|
|
|
|
- </el-radio-button>
|
|
|
|
|
- </el-radio-group>
|
|
|
|
|
- </template>
|
|
|
|
|
<template #right>
|
|
<template #right>
|
|
|
- <div>
|
|
|
|
|
- <el-button title="编辑" text>
|
|
|
|
|
- <template #icon>
|
|
|
|
|
- <el-icon>
|
|
|
|
|
- <svg-icon name="ep:printer" />
|
|
|
|
|
- </el-icon>
|
|
|
|
|
- </template>
|
|
|
|
|
- </el-button>
|
|
|
|
|
- </div>
|
|
|
|
|
</template>
|
|
</template>
|
|
|
</tool-header>
|
|
</tool-header>
|
|
|
- <model_data v-if="state.layoutMode === 'model'" ref="model" />
|
|
|
|
|
- <sql_data v-if="state.layoutMode === 'sql'" ref="sql" />
|
|
|
|
|
- <table_data v-if="state.layoutMode === 'table'" ref="table" />
|
|
|
|
|
|
|
+ <div class="page-main">
|
|
|
|
|
+ <LayoutContainer left-side-width="300px" hide-left-side-toggle>
|
|
|
|
|
+ <template #leftSide>
|
|
|
|
|
+ <el-scrollbar class="tree">
|
|
|
|
|
+ <ElTree ref="leftTreeRef" :data="state.treeData" default-expand-all node-key="modelId" @node-click="onTreeNodeClick">
|
|
|
|
|
+ <template #default="{ node, data }">
|
|
|
|
|
+ <div class="custom-tree-node">
|
|
|
|
|
+ <div class="label" :title="node.label">
|
|
|
|
|
+ <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>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </ElTree>
|
|
|
|
|
+ </el-scrollbar>
|
|
|
|
|
+ </template>
|
|
|
|
|
+
|
|
|
|
|
+ <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>
|
|
|
|
|
+ </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="objectTitle" label="名称" header-align="center" align="center" width="200" />
|
|
|
|
|
+
|
|
|
|
|
+ <el-table-column prop="objectCode" label="代码" header-align="center" align="center" width="150" />
|
|
|
|
|
+
|
|
|
|
|
+ <el-table-column prop="objectType" label="类型" header-align="center" align="center" width="150">
|
|
|
|
|
+ <template #default="scope">
|
|
|
|
|
+ <span v-if="scope.row.objectType === 1">实体对象</span>
|
|
|
|
|
+ <span v-else>视图对象</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+
|
|
|
|
|
+ <el-table-column prop="comment" label="说明" header-align="center" align="left" />
|
|
|
|
|
+ </el-table>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </LayoutContainer>
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
- <style lang="scss" scoped>
|
|
|
|
|
- .container {
|
|
|
|
|
- height: 100%;
|
|
|
|
|
|
|
+<style lang="scss" scoped>
|
|
|
|
|
+.container {
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.absolute-container {
|
|
|
|
|
+ :deep(.left-side) {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- .absolute-container {
|
|
|
|
|
- :deep(.left-side) {
|
|
|
|
|
- display: flex;
|
|
|
|
|
- flex-direction: column;
|
|
|
|
|
- height: 100%;
|
|
|
|
|
|
|
+ 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: 26px;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ .add {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- .el-tree-node__expand-icon.is-leaf{
|
|
|
|
|
- padding: 0;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ .tree {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ overflow-y: auto;
|
|
|
|
|
|
|
|
- .is-current > .el-tree-node__content {
|
|
|
|
|
- background-color: var(--el-color-primary-light-9);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ .el-tree {
|
|
|
|
|
+ .el-tree-node__content {
|
|
|
|
|
+ height: 40px;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- .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;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ .is-current > .el-tree-node__content {
|
|
|
|
|
+ background-color: var(--el-color-primary-light-9);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- &:hover {
|
|
|
|
|
- .actions {
|
|
|
|
|
- display: block;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ .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 {
|
|
.actions {
|
|
|
- display: none;
|
|
|
|
|
- position: absolute;
|
|
|
|
|
- right: 10px;
|
|
|
|
|
- top: 50%;
|
|
|
|
|
- transform: translateY(-50%);
|
|
|
|
|
-
|
|
|
|
|
- .el-button {
|
|
|
|
|
- padding: 5px 8px;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ display: block;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- .rightSide{
|
|
|
|
|
- padding: 0 10px;
|
|
|
|
|
- flex: 1;
|
|
|
|
|
- max-height: calc(100vh - 180px);
|
|
|
|
|
- overflow-y: auto;
|
|
|
|
|
- background-color: var(--g-app-bg);
|
|
|
|
|
-
|
|
|
|
|
- .toolBar{
|
|
|
|
|
- text-align: right;
|
|
|
|
|
|
|
+ .actions {
|
|
|
|
|
+ display: none;
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ right: 10px;
|
|
|
|
|
+ top: 50%;
|
|
|
|
|
+ transform: translateY(-50%);
|
|
|
|
|
|
|
|
- .el-icon {
|
|
|
|
|
- color: #606266;
|
|
|
|
|
- margin: 0 20px;
|
|
|
|
|
- font-size: 1.5em;
|
|
|
|
|
- vertical-align: middle;
|
|
|
|
|
|
|
+ .el-button {
|
|
|
|
|
+ padding: 5px 8px;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- </style>
|
|
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|