Unverified 提交 a6245443 authored 作者: 王嘉豪's avatar 王嘉豪 提交者: GitHub

Merge pull request #1300 from dataease/pr@dev@refactor_panel-speed

refactor: 优化系统响应速度
......@@ -22,4 +22,6 @@ public interface ExtChartViewMapper {
String searchAdviceSceneId(@Param("userId") String userId,@Param("panelId") String panelId);
int checkSameDataSet(@Param("viewIdSource") String viewIdSource,@Param("viewIdTarget") String viewIdTarget);
ChartViewDTO searchOneWithPrivileges(@Param("userId") String userId,@Param("id") String id );
}
......@@ -8,6 +8,13 @@
<result column="privileges" property="privileges"/>
</resultMap>
<select id="searchOneWithPrivileges" resultMap="BaseResultMapDTO">
select
chart_view.*,
get_auths(id,'chart',#{userId}) as `privileges`
from chart_view where id = #{id}
</select>
<select id="searchOne" resultMap="BaseResultMapDTO">
select
id, `name`, scene_id, table_id, `type`, title, create_by, create_time, update_time,
......
......@@ -11,9 +11,8 @@
select
id, `name`, scene_id, data_source_id, `type`, `mode`,`info`, create_by, create_time,
get_auths(id,'dataset',#{userId}) as `privileges`
from (select GET_V_AUTH_MODEL_ID_P_USE (#{userId}, 'dataset') cids) t,dataset_table
from dataset_table
<where>
FIND_IN_SET(dataset_table.id,cids)
<if test="id != null">
and id = #{id,jdbcType=VARCHAR}
</if>
......
......@@ -88,10 +88,6 @@ public class ChartViewController {
public ChartViewDTO getOneWithPermission(@PathVariable String id, @RequestBody ChartExtRequest requestList) throws Exception {
//如果能获取用户 则添加对应的权限
ChartViewDTO dto = chartViewService.getData(id, requestList);
if (dto != null && AuthUtils.getUser() != null) {
ChartViewDTO permissionDto = chartViewService.getOneWithPermission(dto.getId());
dto.setPrivileges(permissionDto.getPrivileges());
}
return dto;
}
......
package io.dataease.controller.request.chart;
import io.dataease.base.domain.ChartViewWithBLOBs;
import io.dataease.dto.chart.ChartViewDTO;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
......@@ -11,7 +12,7 @@ import lombok.Data;
@Data
public class ChartCalRequest {
@ApiModelProperty("视图")
private ChartViewWithBLOBs view;
private ChartViewDTO view;
@ApiModelProperty("额外请求参数")
private ChartExtRequest requestList;
}
......@@ -79,11 +79,6 @@ public class ChartViewService {
Optional.ofNullable(chartView.getId()).ifPresent(id -> {
CacheUtils.remove(JdbcConstants.VIEW_CACHE_KEY, id);
});
try {
calcData(chartView, new ChartExtRequest(), true);
} catch (Exception e) {
}
return getOneWithPermission(chartView.getId());
}
......@@ -167,12 +162,9 @@ public class ChartViewService {
}
public ChartViewDTO getOneWithPermission(String id) {
ChartViewRequest chartViewRequest = new ChartViewRequest();
chartViewRequest.setId(id);
chartViewRequest.setUserId(String.valueOf(AuthUtils.getUser().getUserId()));
return extChartViewMapper.searchOne(chartViewRequest);
String userId = AuthUtils.getUser()!=null?String.valueOf(AuthUtils.getUser().getUserId()):"NONE";
return extChartViewMapper.searchOneWithPrivileges(userId,id);
}
public void delete(String id) {
chartViewMapper.deleteByPrimaryKey(id);
}
......@@ -184,7 +176,7 @@ public class ChartViewService {
}
public ChartViewDTO getData(String id, ChartExtRequest request) throws Exception {
ChartViewWithBLOBs view = chartViewMapper.selectByPrimaryKey(id);
ChartViewDTO view = this.getOneWithPermission(id);
// 如果是从仪表板获取视图数据,则仪表板的查询模式,查询结果的数量,覆盖视图对应的属性
if (CommonConstants.VIEW_QUERY_FROM.PANEL.equals(request.getQueryFrom()) && CommonConstants.VIEW_RESULT_MODE.CUSTOM.equals(request.getResultMode())) {
view.setResultMode(request.getResultMode());
......@@ -193,7 +185,7 @@ public class ChartViewService {
return calcData(view, request, request.isCache());
}
public ChartViewDTO calcData(ChartViewWithBLOBs view, ChartExtRequest requestList, boolean cache) throws Exception {
public ChartViewDTO calcData(ChartViewDTO view, ChartExtRequest requestList, boolean cache) throws Exception {
if (ObjectUtils.isEmpty(view)) {
throw new RuntimeException(Translator.get("i18n_chart_delete"));
}
......
......@@ -80,7 +80,7 @@ export function listDatasource() {
export function getTable(id, hideMsg = false) {
return request({
url: '/dataset/table/get/' + id,
loading: true,
loading: false,
method: 'post',
hideMsg: hideMsg
})
......
<template>
<el-col class="tree-style">
<!-- group -->
<el-col v-if="!sceneMode" v-loading="dsLoading">
<el-col>
<el-row class="title-css">
<span class="title-text">
{{ $t('dataset.datalist') }}
......@@ -9,36 +9,46 @@
</el-row>
<el-divider />
<el-row>
<el-form>
<el-form-item class="form-item">
<el-row style="margin-bottom: 10px">
<el-col :span="16">
<el-input
v-model="search"
v-model="filterText"
size="mini"
:placeholder="$t('dataset.search')"
:placeholder="$t('commons.search')"
prefix-icon="el-icon-search"
clearable
class="main-area-input"
/>
</el-form-item>
</el-form>
</el-col>
<el-col :span="8">
<el-dropdown>
<el-button size="mini" type="primary">
{{ searchMap[searchType] }}<i class="el-icon-arrow-down el-icon--right" />
</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native="searchTypeClick('all')">{{ $t('commons.all') }}</el-dropdown-item>
<el-dropdown-item @click.native="searchTypeClick('folder')">{{ this.$t('commons.folder') }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</el-col>
</el-row>
<el-col class="custom-tree-container">
<div class="block" :style="treeStyle">
<el-tree
ref="datasetTreeRef"
:default-expanded-keys="expandedArray"
:data="data"
node-key="id"
:expand-on-click-node="true"
:load="loadNode"
lazy
:props="treeProps"
highlight-current
:expand-on-click-node="true"
:filter-node-method="filterNode"
@node-click="nodeClick"
>
<span v-if="data.type === 'group'" slot-scope="{ node, data }" class="custom-tree-node">
<span v-if="data.modelInnerType === 'group'" slot-scope="{ node, data }" class="custom-tree-node">
<span style="display: flex;flex: 1;width: 0;">
<span v-if="data.type === 'scene'">
<span v-if="data.modelInnerType === 'scene'">
<svg-icon icon-class="scene" class="ds-icon-scene" />
</span>
<span style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;" :title="data.name">{{ data.name }}</span>
......@@ -47,12 +57,12 @@
<span v-else slot-scope="{ node, data }" class="custom-tree-node-list">
<span :id="data.id" style="display: flex;flex: 1;width: 0;">
<span>
<svg-icon v-if="data.type === 'db'" icon-class="ds-db" class="ds-icon-db" />
<svg-icon v-if="data.type === 'sql'" icon-class="ds-sql" class="ds-icon-sql" />
<svg-icon v-if="data.type === 'excel'" icon-class="ds-excel" class="ds-icon-excel" />
<svg-icon v-if="data.type === 'custom'" icon-class="ds-custom" class="ds-icon-custom" />
<svg-icon v-if="data.modelInnerType === 'db'" icon-class="ds-db" class="ds-icon-db" />
<svg-icon v-if="data.modelInnerType === 'sql'" icon-class="ds-sql" class="ds-icon-sql" />
<svg-icon v-if="data.modelInnerType === 'excel'" icon-class="ds-excel" class="ds-icon-excel" />
<svg-icon v-if="data.modelInnerType === 'custom'" icon-class="ds-custom" class="ds-icon-custom" />
</span>
<span v-if="data.type === 'db' || data.type === 'sql'">
<span v-if="data.modelInnerType === 'db' || data.modelInnerType === 'sql'">
<span v-if="data.mode === 0" style="margin-left: 6px"><i class="el-icon-s-operation" /></span>
<span v-if="data.mode === 1" style="margin-left: 6px"><i class="el-icon-alarm-clock" /></span>
</span>
......@@ -69,6 +79,8 @@
<script>
import { isKettleRunning, post } from '@/api/dataset/dataset'
import { hasDataPermission } from '@/utils/permission'
import { queryAuthModel } from '@/api/authModel/authModel'
export default {
name: 'DatasetGroupSelectorTree',
......@@ -121,6 +133,13 @@ export default {
},
data() {
return {
searchPids: [], // 查询命中的pid
filterText: '',
searchType: 'all',
searchMap: {
all: this.$t('commons.all'),
folder: this.$t('commons.folder')
},
kettleRunning: false,
sceneMode: false,
search: '',
......@@ -164,16 +183,13 @@ export default {
'table': function() {
this.treeNode(this.groupForm)
},
search(val) {
this.$emit('switchComponent', { name: '' })
this.data = []
this.expandedArray = []
if (this.timer) {
clearTimeout(this.timer)
}
this.timer = setTimeout(() => {
this.getTreeData(val)
}, (val && val !== '') ? 500 : 0)
filterText(val) {
this.searchPids = []
this.$refs.datasetTreeRef.filter(val)
},
searchType(val) {
this.searchPids = []
this.$refs.datasetTreeRef.filter(this.filterText)
}
},
mounted() {
......@@ -208,47 +224,22 @@ export default {
},
treeNode(group) {
post('/dataset/group/treeNode', group).then(res => {
queryAuthModel({ modelType: 'dataset' }).then(res => {
this.data = res.data
this.dsLoading = false
})
},
tableTree() {
this.tableData = []
if (this.currGroup) {
this.dsLoading = true
this.tables = []
post('/dataset/table/list', {
sort: 'type asc,name asc,create_time desc',
sceneId: this.currGroup.id,
mode: this.mode < 0 ? null : this.mode,
typeFilter: this.customType ? this.customType : null
}, false).then(response => {
for (let i = 0; i < response.data.length; i++) {
if (response.data[i].mode === 1 && this.kettleRunning === false) {
this.$set(response.data[i], 'disabled', true)
}
if (hasDataPermission(this.privileges, response.data[i].privileges)) {
this.tables.push(response.data[i])
}
}
this.tableData = JSON.parse(JSON.stringify(this.tables))
this.$nextTick(function() {
this.unionDataChange()
})
this.dsLoading = false
}).catch(res => {
this.dsLoading = false
})
}
},
nodeClick(data, node) {
if (data.type !== 'group') {
if (data.modelInnerType !== 'group') {
this.sceneClick(data, node)
}
if (node.expanded) {
this.expandedArray.push(data.id)
} else {
const index = this.expandedArray.indexOf(data.id)
if (index > -1) {
this.expandedArray.splice(index, 1)
}
}
},
back() {
......@@ -329,118 +320,28 @@ export default {
this.expandedArray.splice(this.expandedArray.indexOf(data.id), 1)
}
},
loadNode(node, resolve) {
if (!this.isTreeSearch) {
if (node.data.id) {
this.dsLoading = true
this.tables = []
post('/dataset/table/listAndGroup', {
sort: 'type asc,name asc,create_time desc',
sceneId: node.data.id,
mode: this.mode < 0 ? null : this.mode,
type: this.type,
typeFilter: this.customType ? this.customType : null
}, false).then(response => {
for (let i = 0; i < response.data.length; i++) {
if (response.data[i].mode === 1 && this.kettleRunning === false) {
this.$set(response.data[i], 'disabled', true)
}
if (hasDataPermission(this.privileges, response.data[i].privileges)) {
this.tables.push(response.data[i])
filterNode(value, data) {
if (!value) return true
if (this.searchType === 'folder') {
if (data.modelInnerType === 'group' && data.label.indexOf(value) !== -1) {
this.searchPids.push(data.id)
return true
}
if (this.searchPids.indexOf(data.pid) !== -1) {
if (data.modelInnerType === 'group') {
this.searchPids.push(data.id)
}
this.tableData = JSON.parse(JSON.stringify(this.tables))
this.$nextTick(function() {
this.unionDataChange()
})
this.dsLoading = false
resolve(this.tableData)
}).catch(res => {
this.dsLoading = false
})
return true
}
} else {
node.data.children ? resolve(node.data.children) : resolve([])
return data.label.indexOf(value) !== -1
}
return false
},
refreshNodeBy(id) {
if (this.isTreeSearch) {
this.data = []
this.expandedArray = []
this.searchTree(this.search)
} else {
if (!id || id === '0') {
this.treeNode(this.groupForm)
} else {
const node = this.$refs.asyncTree.getNode(id) // 通过节点id找到对应树节点对象
node.loaded = false
node.expand() // 主动调用展开节点方法,重新查询该节点下的所有子节点
}
}
},
searchTree(val) {
const queryCondition = {
name: val,
sort: 'type asc,name asc,create_time desc',
mode: this.mode < 0 ? null : this.mode,
type: this.type,
typeFilter: this.customType ? this.customType : null
}
post('/dataset/table/search', queryCondition).then(res => {
this.data = this.buildTree(res.data)
})
},
buildTree(arrs) {
const idMapping = arrs.reduce((acc, el, i) => {
acc[el[this.treeProps.id]] = i
return acc
}, {})
const roots = []
arrs.forEach(el => {
// 判断根节点 ###
if (el[this.treeProps.parentId] === null || el[this.treeProps.parentId] === 0 || el[this.treeProps.parentId] === '0') {
roots.push(el)
return
searchTypeClick(searchTypeInfo) {
this.searchType = searchTypeInfo
}
// 用映射表找到父元素
const parentEl = arrs[idMapping[el[this.treeProps.parentId]]]
// 把当前元素添加到父元素的`children`数组中
parentEl.children = [...(parentEl.children || []), el]
// 设置展开节点 如果没有子节点则不进行展开
if (parentEl.children.length > 0) {
this.expandedArray.push(parentEl[this.treeProps.id])
}
})
return roots
},
// 高亮显示搜索内容
highlights(data) {
if (data && this.search && this.search.length > 0) {
const replaceReg = new RegExp(this.search, 'g')// 匹配关键字正则
const replaceString = '<span style="color: #0a7be0">' + this.search + '</span>' // 高亮替换v-html值
data.forEach(item => {
item.name = item.name.replace(replaceReg, replaceString) // 开始替换
item.label = item.label.replace(replaceReg, replaceString) // 开始替换
})
}
},
getTreeData(val) {
if (val) {
this.isTreeSearch = true
this.searchTree(val)
} else {
this.isTreeSearch = false
this.treeNode(this.groupForm)
}
}
}
}
</script>
......
......@@ -428,8 +428,8 @@ export default {
type: 'success',
showClose: true
})
_this.expandedArray.push(response.data.sceneId)
_this.$refs.datasetTreeRef.setCurrentKey(response.data.id)
_this.expandedArray.push(table.sceneId)
_this.$refs.datasetTreeRef.setCurrentKey(table.id)
_this.treeNode()
this.$store.dispatch('dataset/setTable', new Date().getTime())
})
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论