Merge remote-tracking branch 'origin/main' into main
This commit is contained in:
commit
410ac96f57
6
.gitmodules
vendored
6
.gitmodules
vendored
@ -1,6 +0,0 @@
|
||||
[submodule "dataease-plugins"]
|
||||
path = dataease-plugins
|
||||
url = git@github.com:dataease/dataease-plugins.git
|
||||
[submodule "dataease-plugin-xpack"]
|
||||
path = dataease-plugin-xpack
|
||||
url = git@github.com:dataease/dataease-plugin-xpack.git
|
||||
378
README.md
378
README.md
@ -1,21 +1,37 @@
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
# DataEase - 人人可用的开源数据可视化分析工具
|
||||
|
||||
<p align="center"><a href="https://dataease.io"><img src="https://dataease.oss-cn-hangzhou.aliyuncs.com/img/dataease-logo.png" alt="DataEase" width="300" /></a></p>
|
||||
<h3 align="center">人人可用的开源数据可视化分析工具</h3>
|
||||
<p align="center">
|
||||
<a href="https://www.gnu.org/licenses/old-licenses/gpl-2.0"><img src="https://img.shields.io/github/license/dataease/dataease?color=%231890FF&style=flat-square" alt="License: GPL v2"></a>
|
||||
<a href="https://app.codacy.com/gh/metersphere/metersphere?utm_source=github.com&utm_medium=referral&utm_content=metersphere/metersphere&utm_campaign=Badge_Grade_Dashboard"><img src="https://api.codacy.com/project/badge/Grade/176186d132df448b955f8bdd5e6ef9c0" alt="Codacy"></a>
|
||||
<a href="https://github.com/dataease/dataease/releases/latest"><img src="https://img.shields.io/github/v/release/dataease/dataease" alt="Latest release"></a>
|
||||
<a href="https://github.com/dataease/dataease"><img src="https://img.shields.io/github/stars/dataease/dataease?color=%231890FF&style=flat-square" alt="Stars"></a>
|
||||
<a href="https://github.com/dataease/dataease/releases/latest"><img src="https://img.shields.io/github/downloads/dataease/dataease/total" alt="Downloads"></a>
|
||||
</p>
|
||||
<hr />
|
||||
DataEase 是开源的数据可视化分析工具,帮助用户快速分析数据并洞察业务趋势,从而实现业务的改进与优化。DataEase 支持丰富的数据源连接,能够通过拖拉拽方式快速制作图表,并可以方便的与他人分享。
|
||||
|
||||
- 图表展示: 支持 PC 端、移动端及大屏;
|
||||
- 图表制作: 支持丰富的图表类型(基于 Apache ECharts 实现)、支持拖拉拽方式快速制作仪表板;
|
||||
- 数据引擎: 支持直连模式、本地模式(基于 Apache Doris / Kettle 实现);
|
||||
- 数据连接: 支持关系型数据库、Excel 等文件、Hadoop 等大数据平台、NoSQL 等各种数据源。
|
||||
### DataEase 的功能:
|
||||
|
||||
- 图表展示:支持 PC 端、移动端及大屏;
|
||||
- 图表制作:支持丰富的图表类型(基于 Apache ECharts 实现)、支持拖拉拽方式快速制作仪表板;
|
||||
- 数据引擎:支持直连模式、本地模式(基于 Apache Doris / Kettle 实现);
|
||||
- 数据连接:支持关系型数据库、Excel 等文件、Hadoop 等大数据平台、NoSQL 等各种数据源。
|
||||
|
||||
### DataEase 的优势:
|
||||
|
||||
- 开源开放:零门槛,线上快速获取和安装;快速获取用户反馈、按月发布新版本;
|
||||
- 简单易用:极易上手,通过鼠标点击和拖拽即可完成分析;
|
||||
- 秒级响应:集成 Apache Doris,超大数据量下秒级查询返回延时;
|
||||
- 安全分享:支持多种数据分享方式,确保数据安全。
|
||||
|
||||
## UI 展示
|
||||
|
||||

|
||||
|
||||
## 功能架构
|
||||
|
||||

|
||||
|
||||
## 在线体验
|
||||
|
||||
- 环境地址:<https://demo.dataease.io/>
|
||||
@ -40,343 +56,13 @@ curl -sSL https://github.com/dataease/dataease/releases/latest/download/quick_st
|
||||
|
||||

|
||||
|
||||
## 功能架构
|
||||
|
||||

|
||||
|
||||
## 产品优势
|
||||
|
||||
- 开源开放:零门槛,线上快速获取和安装;快速获取用户反馈、按月发布新版本;
|
||||
- 简单易用:极易上手,通过鼠标点击和拖拽即可完成分析;
|
||||
- 秒级响应:集成 Apache Doris,超大数据量下秒级查询返回延时;
|
||||
- 安全分享:支持多种数据分享方式,确保数据安全。
|
||||
|
||||
## 功能列表
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td bgcolor="#3779d9" align="middle" style="font-weight:bold;color: white;width: 150px">
|
||||
功能模块
|
||||
</td>
|
||||
<td bgcolor="#3779d9" align="middle" style="font-weight:bold;color: white;width: 170px">
|
||||
功能
|
||||
</td>
|
||||
<td bgcolor="#3779d9" align="middle" style="font-weight:bold;color: white;width: 750px">
|
||||
功能描述
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="19">
|
||||
仪表板
|
||||
</td>
|
||||
<td rowspan="7">
|
||||
仪表板管理
|
||||
</td>
|
||||
<td>
|
||||
支持新建仪表板
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持重命名仪表板
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持删除仪表板
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持在线编辑仪表板
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持以树状形式展示仪表板分组
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持重命名仪表板分组
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持删除仪表板分组
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="10">
|
||||
仪表板制作
|
||||
</td>
|
||||
<td>
|
||||
支持多种组件,视图/时间组件/文本组件/数字组件/样式组件/图片等
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持组件样式设置,如图形属性、组件样式等
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持仪表板背景、以及组件间隙设置等
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持一键切换仪表板主题
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持调整仪表板画布大小
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持撤销、重做、清空画布内容
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持仪表板的全屏预览
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持仪表板模板的导出
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持默认仪表板的设置
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持仪表板的收藏
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="2">
|
||||
仪表板共享
|
||||
</td>
|
||||
<td>
|
||||
支持按组织/角色/用户分享
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持生成分享链接,外部用户可通过密码访问
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="14">
|
||||
视图
|
||||
</td>
|
||||
<td rowspan="6">
|
||||
视图管理
|
||||
</td>
|
||||
<td>
|
||||
支持新增视图
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持编辑视图
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持删除视图
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持对视图进行分组
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持重命名视图分组
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持删除视图分组
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="8">
|
||||
视图制作
|
||||
</td>
|
||||
<td>
|
||||
支持通过简单的拖拉操作,制作视图
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持多种图表类型,明细表/指标卡/基础柱状图/堆叠柱状图/横向柱状图/横向堆叠柱状图/基础折线图/堆叠折线图/饼图/南丁格尔玫瑰图/漏斗图/雷达图/仪表盘等
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持选择图表的样式优先级
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持选择图表的排序方式,根据维度、指标升序、降序展示
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持指标的多种汇总计算方式,如求和、平均、最大值、最小值等
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持对图表类型的图形属性进行设置
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持对图表类型的组件样式进行设置
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持通过过滤条件筛选视图数据
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="8">
|
||||
数据集
|
||||
</td>
|
||||
<td rowspan="8">
|
||||
数据集管理
|
||||
</td>
|
||||
<td>
|
||||
支持多种类型的数据集,数据库数据集/SQL 数据集/Excel 数据集/自定义数据集
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
数据库数据集和 SQL 数据集支持直连和定时同步两种连接方式
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
定时同步类型数据集,支持全量更新和增量更新两种方式
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持创建定时任务,以此控制数据集的更新
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持定时更新任务的查看
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持对数据集的字段类型/字段名/展示字段进行设置
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持创建数据集间的关联关系(1:1,一对一;1:N,一对N;N:1,N对1)
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持 Excel 数据集数据的替换和追加
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="2">
|
||||
数据源
|
||||
</td>
|
||||
<td rowspan="2">
|
||||
数据源管理
|
||||
</td>
|
||||
<td>
|
||||
创建 MySQL数据源
|
||||
</td>
|
||||
</tr>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
校验数据源的有效性
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="5">
|
||||
系统管理
|
||||
</td>
|
||||
<td rowspan="2">
|
||||
用户租户管理
|
||||
</td>
|
||||
<td>
|
||||
支持多级租户体系
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持多种租户角色
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="2">
|
||||
权限管理
|
||||
</td>
|
||||
<td>
|
||||
支持组织/角色/用户三个维度的权限管理
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
支持数据源/数据集/视图/仪表板/菜单和操作权限的细颗粒度权限控制
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
显示设置
|
||||
</td>
|
||||
<td>
|
||||
支持对Logo/系统名/标题等属性的设置
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## 技术栈
|
||||
|
||||
- 后端: [Spring Boot](https://spring.io/projects/spring-boot);
|
||||
- 前端: [Vue.js](https://vuejs.org/);
|
||||
- 中间件: [MySQL](https://www.mysql.com/);
|
||||
- 数据处理: [Kettle](https://github.com/pentaho/pentaho-kettle)、[Apache Doris](https://github.com/apache/incubator-doris/);
|
||||
- 基础设施: [Docker](https://www.docker.com/)。
|
||||
|
||||
## 致谢
|
||||
|
||||
- [Kettle](https://github.com/pentaho/pentaho-kettle/):DataEase 使用了 Kettle 进行数据处理工作;
|
||||
- [Apache Doris](https://doris.apache.org/):DataEase 使用了 Apache Doris 进行快速的数据分析;
|
||||
- [Element](https://element.eleme.cn/):感谢 Element 提供的优秀组件库。
|
||||
|
||||
## 版本说明
|
||||
|
||||
DataEase 版本号命名规则为:v大版本.功能版本.Bug修复版本。比如:
|
||||
|
||||
```text
|
||||
v1.0.1 是 v1.0.0 之后的 Bug 修复版本;
|
||||
v1.1.0 是 v1.0.0 之后的功能版本。
|
||||
```
|
||||
|
||||
像其它优秀开源项目一样,DataEase 将每月发布一个功能版本。
|
||||
- 后端:[Spring Boot](https://spring.io/projects/spring-boot)
|
||||
- 前端:[Vue.js](https://vuejs.org/)、[Element](https://element.eleme.cn/)
|
||||
- 中间件:[MySQL](https://www.mysql.com/)
|
||||
- 数据处理:[Kettle](https://github.com/pentaho/pentaho-kettle)、[Apache Doris](https://github.com/apache/incubator-doris/)
|
||||
- 基础设施:[Docker](https://www.docker.com/)
|
||||
|
||||
## License & Copyright
|
||||
|
||||
|
||||
@ -1 +0,0 @@
|
||||
Subproject commit 9879b705aa4a5105056109ecf5b9da70b783969d
|
||||
@ -1 +0,0 @@
|
||||
Subproject commit 2541de3d2c82f37dcf9916fda70ada0ca3fc6132
|
||||
@ -1083,7 +1083,6 @@ export default {
|
||||
this.element.propValue && this.element.propValue.viewId && eventBus.$emit('resizing', this.element.propValue.viewId)
|
||||
},
|
||||
changeWidth(val) {
|
||||
debugger
|
||||
// console.log('parentWidth', this.parentWidth)
|
||||
// console.log('parentHeight', this.parentHeight)
|
||||
const [newWidth, _] = snapToGrid(this.grid, val, 0, this.scale)
|
||||
|
||||
@ -126,7 +126,6 @@ export default {
|
||||
changeStyleWithScale,
|
||||
getStyle,
|
||||
restore() {
|
||||
debugger
|
||||
const canvasHeight = document.getElementById('canvasInfoTemp').offsetHeight
|
||||
const canvasWidth = document.getElementById('canvasInfoTemp').offsetWidth
|
||||
this.scaleWidth = canvasWidth * 100 / parseInt(this.canvasStyleData.width)// 获取宽度比
|
||||
|
||||
@ -57,7 +57,6 @@ export default {
|
||||
watch: {
|
||||
active: {
|
||||
handler(newVal, oldVla) {
|
||||
debugger
|
||||
this.removeSelectText()
|
||||
},
|
||||
deep: true
|
||||
|
||||
@ -807,7 +807,7 @@ export default {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
resolve(node.data.children)
|
||||
node.data.children && resolve(node.data.children)
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -828,7 +828,7 @@ export default {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
resolve(node.data.children)
|
||||
node.data.children && resolve(node.data.children)
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -447,7 +447,6 @@ export default {
|
||||
this.$store.commit('recordSnapshot')
|
||||
this.clearCurrentInfo()
|
||||
|
||||
debugger
|
||||
// 文字组件
|
||||
if (component.type === 'v-text' || component.type === 'rect-shape') {
|
||||
this.$store.commit('setCurComponent', { component: component, index: this.componentData.length })
|
||||
|
||||
@ -13,52 +13,58 @@
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
<div class="component-result-content filter-common">
|
||||
<el-tree
|
||||
v-if="showDomType === 'tree'"
|
||||
:data="data"
|
||||
:props="defaultProps"
|
||||
:render-content="renderNode"
|
||||
@node-click="handleNodeClick"
|
||||
/>
|
||||
|
||||
<el-table
|
||||
v-else-if="showDomType === 'db'"
|
||||
class="de-filter-data-table"
|
||||
:data="sceneDatas"
|
||||
:show-header="false"
|
||||
size="mini"
|
||||
:highlight-current-row="true"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column prop="name" :label="$t('commons.name')">
|
||||
<template v-if="showDomType === 'db'" :id="scope.row.id" slot-scope="scope">
|
||||
<div class="filter-db-row" @click="showFieldDatas(scope.row)">
|
||||
<i class="el-icon-s-data" />
|
||||
<span> {{ scope.row.name }}</span>
|
||||
<el-col>
|
||||
<el-row>
|
||||
<el-form>
|
||||
<el-form-item class="my-form-item">
|
||||
<el-input
|
||||
v-model="keyWord"
|
||||
size="mini"
|
||||
:placeholder="$t('dataset.search')"
|
||||
prefix-icon="el-icon-search"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-tree
|
||||
v-if="showDomType === 'tree'"
|
||||
:default-expanded-keys="expandedArray"
|
||||
node-key="id"
|
||||
:data="datas"
|
||||
:props="defaultProps"
|
||||
lazy
|
||||
:load="loadTree"
|
||||
@node-click="handleNodeClick"
|
||||
>
|
||||
<div slot-scope="{ node, data }" class="custom-tree-node">
|
||||
<el-button v-if="data.type === 'db'" icon="el-icon-s-data" type="text" size="mini" />
|
||||
<span class="label-span">{{ node.label }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tree>
|
||||
|
||||
<div v-else-if="showDomType === 'field'">
|
||||
<draggable
|
||||
v-model="fieldDatas"
|
||||
:disabled="selectField.length !== 0"
|
||||
:options="{group:{name: 'dimension',pull:'clone'},sort: true}"
|
||||
animation="300"
|
||||
:move="onMove"
|
||||
class="drag-list"
|
||||
@end="end1"
|
||||
@start="start1"
|
||||
>
|
||||
<transition-group>
|
||||
<div v-for="item in fieldDatas" :key="item.id" class="filter-db-row">
|
||||
<i class="el-icon-s-data" />
|
||||
<span> {{ item.name }}</span>
|
||||
</div>
|
||||
</transition-group>
|
||||
</draggable>
|
||||
</div>
|
||||
<div v-if="showDomType === 'field'">
|
||||
<draggable
|
||||
v-model="fieldDatas"
|
||||
:disabled="selectField.length !== 0"
|
||||
:options="{group:{name: 'dimension',pull:'clone'},sort: true}"
|
||||
animation="300"
|
||||
:move="onMove"
|
||||
class="drag-list"
|
||||
@end="end1"
|
||||
@start="start1"
|
||||
>
|
||||
<transition-group>
|
||||
<div v-for="item in fieldDatas.filter(item => !keyWord || (item.name && item.name.toLocaleLowerCase().includes(keyWord)))" :key="item.id" class="filter-db-row">
|
||||
<i class="el-icon-s-data" />
|
||||
<span> {{ item.name }}</span>
|
||||
</div>
|
||||
</transition-group>
|
||||
</draggable>
|
||||
</div>
|
||||
</el-row>
|
||||
</el-col>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :lazy="true" class="de-tab" :label="$t('panel.select_by_module')" name="assembly">
|
||||
@ -72,44 +78,62 @@
|
||||
</div>
|
||||
|
||||
<div class="component-result-content filter-common">
|
||||
<el-table
|
||||
v-if="comShowDomType === 'view'"
|
||||
class="de-filter-data-table"
|
||||
:data="viewInfos"
|
||||
:show-header="false"
|
||||
size="mini"
|
||||
:highlight-current-row="true"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column prop="name" :label="$t('commons.name')">
|
||||
<template v-if="comShowDomType === 'view'" :id="scope.row.id" slot-scope="scope">
|
||||
<div class="filter-db-row" @click="comShowFieldDatas(scope.row)">
|
||||
<i class="el-icon-s-data" />
|
||||
<span> {{ scope.row.name }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div v-else-if="comShowDomType === 'field'">
|
||||
<draggable
|
||||
v-model="comFieldDatas"
|
||||
:disabled="selectField.length !== 0"
|
||||
:options="{group:{name: 'dimension',pull:'clone'},sort: true}"
|
||||
animation="300"
|
||||
:move="onMove"
|
||||
class="drag-list"
|
||||
@end="end1"
|
||||
@start="start1"
|
||||
>
|
||||
<transition-group>
|
||||
<div v-for="item in comFieldDatas" :key="item.id" class="filter-db-row">
|
||||
<i class="el-icon-s-data" />
|
||||
<span> {{ item.name }}</span>
|
||||
</div>
|
||||
</transition-group>
|
||||
</draggable>
|
||||
</div>
|
||||
<el-col>
|
||||
<el-row>
|
||||
<el-form>
|
||||
<el-form-item class="my-form-item">
|
||||
<el-input
|
||||
v-model="viewKeyWord"
|
||||
size="mini"
|
||||
:placeholder="$t('dataset.search')"
|
||||
prefix-icon="el-icon-search"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-table
|
||||
v-if="comShowDomType === 'view'"
|
||||
class="de-filter-data-table"
|
||||
:data="viewInfos.filter(item => !viewKeyWord || item.name.toLocaleLowerCase().includes(viewKeyWord))"
|
||||
:show-header="false"
|
||||
size="mini"
|
||||
:highlight-current-row="true"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column prop="name" :label="$t('commons.name')">
|
||||
<template v-if="comShowDomType === 'view'" :id="scope.row.id" slot-scope="scope">
|
||||
<div class="filter-db-row" @click="comShowFieldDatas(scope.row)">
|
||||
<i class="el-icon-s-data" />
|
||||
<span> {{ scope.row.name }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div v-else-if="comShowDomType === 'field'">
|
||||
<draggable
|
||||
v-model="comFieldDatas"
|
||||
:disabled="selectField.length !== 0"
|
||||
:options="{group:{name: 'dimension',pull:'clone'},sort: true}"
|
||||
animation="300"
|
||||
:move="onMove"
|
||||
class="drag-list"
|
||||
@end="end1"
|
||||
@start="start1"
|
||||
>
|
||||
<transition-group>
|
||||
<div v-for="item in comFieldDatas.filter(item => !viewKeyWord || item.name.toLocaleLowerCase().includes(viewKeyWord))" :key="item.id" class="filter-db-row">
|
||||
<i class="el-icon-s-data" />
|
||||
<span> {{ item.name }}</span>
|
||||
</div>
|
||||
</transition-group>
|
||||
</draggable>
|
||||
</div>
|
||||
</el-row>
|
||||
</el-col>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
@ -212,8 +236,9 @@ import draggable from 'vuedraggable'
|
||||
import DragItem from '@/components/DragItem'
|
||||
import { mapState } from 'vuex'
|
||||
// import { ApplicationContext } from '@/utils/ApplicationContext'
|
||||
import { groupTree, loadTable, fieldList, fieldValues } from '@/api/dataset/dataset'
|
||||
import { groupTree, fieldList, fieldValues, post } from '@/api/dataset/dataset'
|
||||
import { viewsWithIds } from '@/api/panel/view'
|
||||
import { authModel } from '@/api/system/sysAuth'
|
||||
export default {
|
||||
name: 'FilterDialog',
|
||||
components: {
|
||||
@ -246,20 +271,37 @@ export default {
|
||||
componentSetBreads: [
|
||||
{ label: this.$t('panel.component_list'), link: false, type: 'root' }
|
||||
],
|
||||
data: [],
|
||||
datas: [],
|
||||
sceneDatas: [],
|
||||
// viewDatas: [],
|
||||
fieldDatas: [],
|
||||
comFieldDatas: [],
|
||||
defaultProps: {
|
||||
label: 'name',
|
||||
children: 'children',
|
||||
label: 'label'
|
||||
isLeaf: 'isLeaf',
|
||||
id: 'id',
|
||||
parentId: 'pid'
|
||||
},
|
||||
selectField: [],
|
||||
widget: null,
|
||||
fieldValues: [],
|
||||
popovervisible: false,
|
||||
viewInfos: []
|
||||
viewInfos: [],
|
||||
groupForm: {
|
||||
name: '',
|
||||
pid: '0',
|
||||
level: 0,
|
||||
type: '',
|
||||
children: [],
|
||||
sort: 'type desc,name asc'
|
||||
},
|
||||
isTreeSearch: false,
|
||||
defaultDatas: [],
|
||||
keyWord: '',
|
||||
timer: null,
|
||||
expandedArray: [],
|
||||
viewKeyWord: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -296,12 +338,24 @@ export default {
|
||||
this.componentInfo.options.attrs.fieldId = null
|
||||
this.$emit('re-fresh-component', this.componentInfo)
|
||||
}
|
||||
},
|
||||
keyWord(val) {
|
||||
this.expandedArray = []
|
||||
if (this.showDomType === 'field') {
|
||||
return
|
||||
}
|
||||
if (this.timer) {
|
||||
clearTimeout(this.timer)
|
||||
}
|
||||
this.timer = setTimeout(() => {
|
||||
this.getTreeData(val)
|
||||
}, (val && val !== '') ? 1000 : 0)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// this.widget = ApplicationContext.getService(this.widgetId)
|
||||
this.widget = this.widgetInfo
|
||||
this.loadDataSetTree()
|
||||
this.treeNode(this.groupForm)
|
||||
|
||||
if (this.componentInfo && this.componentInfo.options.attrs.dragItems) {
|
||||
this.selectField = this.componentInfo.options.attrs.dragItems
|
||||
@ -310,8 +364,51 @@ export default {
|
||||
},
|
||||
|
||||
methods: {
|
||||
attr() {
|
||||
return 'aaa'
|
||||
getTreeData(val) {
|
||||
if (val) {
|
||||
this.isTreeSearch = true
|
||||
this.searchTree(val)
|
||||
} else {
|
||||
this.isTreeSearch = false
|
||||
this.treeNode(this.groupForm)
|
||||
}
|
||||
},
|
||||
searchTree(val) {
|
||||
this.expandedArray = []
|
||||
const queryCondition = {
|
||||
withExtend: 'parent',
|
||||
modelType: 'dataset',
|
||||
name: val
|
||||
}
|
||||
authModel(queryCondition).then(res => {
|
||||
this.datas = this.buildTree(res.data)
|
||||
})
|
||||
},
|
||||
buildTree(arrs) {
|
||||
const idMapping = arrs.reduce((acc, el, i) => {
|
||||
acc[el[this.defaultProps.id]] = i
|
||||
return acc
|
||||
}, {})
|
||||
const roots = []
|
||||
arrs.forEach(el => {
|
||||
// 判断根节点 ###
|
||||
el.type = el.modelInnerType
|
||||
el.isLeaf = el.leaf
|
||||
if (el[this.defaultProps.parentId] === null || el[this.defaultProps.parentId] === 0 || el[this.defaultProps.parentId] === '0') {
|
||||
roots.push(el)
|
||||
return
|
||||
}
|
||||
// 用映射表找到父元素
|
||||
const parentEl = arrs[idMapping[el[this.defaultProps.parentId]]]
|
||||
// 把当前元素添加到父元素的`children`数组中
|
||||
parentEl.children = [...(parentEl.children || []), el]
|
||||
|
||||
// 设置展开节点 如果没有子节点则不进行展开
|
||||
if (parentEl.children.length > 0) {
|
||||
this.expandedArray.push(parentEl[this.defaultProps.id])
|
||||
}
|
||||
})
|
||||
return roots
|
||||
},
|
||||
loadViews() {
|
||||
const viewIds = this.componentData
|
||||
@ -323,10 +420,32 @@ export default {
|
||||
})
|
||||
},
|
||||
handleNodeClick(data) {
|
||||
if (data.type === 'scene') {
|
||||
this.showSceneTable(data)
|
||||
if (data.type !== 'group') {
|
||||
this.showFieldDatas(data)
|
||||
}
|
||||
},
|
||||
loadTree(node, resolve) {
|
||||
if (!this.isTreeSearch) {
|
||||
if (node.level > 0) {
|
||||
if (node.data.id) {
|
||||
post('/dataset/table/listAndGroup', {
|
||||
sort: 'type asc,name asc,create_time desc',
|
||||
sceneId: node.data.id
|
||||
}).then(res => {
|
||||
resolve(res.data)
|
||||
})
|
||||
}
|
||||
}
|
||||
} else {
|
||||
node.data.children && resolve(node.data.children)
|
||||
}
|
||||
},
|
||||
treeNode(group) {
|
||||
post('/dataset/group/treeNode', group).then(res => {
|
||||
this.defaultDatas = res.data
|
||||
this.datas = res.data
|
||||
})
|
||||
},
|
||||
loadDataSetTree() {
|
||||
groupTree({}).then(res => {
|
||||
const datas = res.data
|
||||
@ -334,25 +453,7 @@ export default {
|
||||
this.data = datas
|
||||
})
|
||||
},
|
||||
renderNode(h, { node, data, store }) {
|
||||
return (
|
||||
<div class='custom-tree-node' >
|
||||
|
||||
{ data.type === 'scene' ? (
|
||||
<el-button icon='el-icon-folder' type='text' size='mini' />
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
<span class='label-span' >{node.label}</span>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
showSceneTable(node) {
|
||||
this.showDomType = 'db'
|
||||
this.setTailLink(node)
|
||||
this.addTail(node)
|
||||
this.loadTable(node.id)
|
||||
},
|
||||
setTailLink(node) {
|
||||
const tail = this.dataSetBreads[this.dataSetBreads.length - 1]
|
||||
tail.type = node.type
|
||||
@ -389,26 +490,34 @@ export default {
|
||||
this.componentSetBreads[this.componentSetBreads.length - 1]['link'] = false
|
||||
},
|
||||
backToLink(bread) {
|
||||
if (bread.type === 'db') {
|
||||
this.showDomType = 'db'
|
||||
} else {
|
||||
this.showDomType = 'tree'
|
||||
}
|
||||
// if (bread.type === 'field') {
|
||||
// this.showDomType = 'db'
|
||||
// } else {
|
||||
// this.showDomType = 'tree'
|
||||
// }
|
||||
this.showDomType = 'tree'
|
||||
|
||||
this.removeTail(bread)
|
||||
this.$nextTick(() => {
|
||||
this.expandedArray = []
|
||||
this.keyWord = ''
|
||||
this.isTreeSearch = false
|
||||
this.datas = JSON.parse(JSON.stringify(this.defaultDatas))
|
||||
})
|
||||
},
|
||||
comBackLink(bread) {
|
||||
this.comShowDomType = 'view'
|
||||
this.viewKeyWord = ''
|
||||
this.comRemoveTail()
|
||||
},
|
||||
loadTable(sceneId) {
|
||||
loadTable({ sceneId: sceneId, sort: 'type asc,create_time desc,name asc' }).then(res => {
|
||||
res && res.data && (this.sceneDatas = res.data.map(tb => {
|
||||
tb.type = 'db'
|
||||
return tb
|
||||
}))
|
||||
})
|
||||
},
|
||||
// loadTable(sceneId) {
|
||||
// loadTable({ sceneId: sceneId, sort: 'type asc,create_time desc,name asc' }).then(res => {
|
||||
// res && res.data && (this.sceneDatas = res.data.map(tb => {
|
||||
// tb.type = 'db'
|
||||
// return tb
|
||||
// }))
|
||||
// })
|
||||
// },
|
||||
|
||||
loadField(tableId) {
|
||||
fieldList(tableId).then(res => {
|
||||
@ -429,12 +538,14 @@ export default {
|
||||
})
|
||||
},
|
||||
showFieldDatas(row) {
|
||||
this.keyWord = ''
|
||||
this.showDomType = 'field'
|
||||
this.setTailLink(row)
|
||||
this.addTail(row)
|
||||
this.loadField(row.id)
|
||||
},
|
||||
comShowFieldDatas(row) {
|
||||
this.viewKeyWord = ''
|
||||
this.comShowDomType = 'field'
|
||||
this.comSetTailLink(row)
|
||||
this.comAddTail(row)
|
||||
@ -505,6 +616,9 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.my-form-item {
|
||||
cursor: text;
|
||||
}
|
||||
.de-dialog-container {
|
||||
height: 50vh !important;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user