forked from github/dataease
refactor(数据大屏): 优化外部参数,解决外部参数对所有图表兼容性问题
This commit is contained in:
parent
24982a350a
commit
e9deb711a1
@ -2,6 +2,7 @@ package io.dataease.visualization.dao.ext.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import io.dataease.api.visualization.dto.VisualizationViewTableDTO;
|
||||
import io.dataease.api.visualization.vo.DataVisualizationBaseVO;
|
||||
import io.dataease.api.visualization.vo.DataVisualizationVO;
|
||||
import io.dataease.api.visualization.vo.VisualizationResourceVO;
|
||||
@ -45,4 +46,7 @@ public interface ExtDataVisualizationMapper {
|
||||
|
||||
void copyLinkageField(@Param("copyId") Long copyId);
|
||||
|
||||
List<VisualizationViewTableDTO> getVisualizationViewDetails(@Param("dvId") Long dvId);
|
||||
|
||||
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import io.dataease.api.chart.dto.ChartViewDTO;
|
||||
import io.dataease.api.template.dto.TemplateManageFileDTO;
|
||||
import io.dataease.api.template.dto.VisualizationTemplateExtendDataDTO;
|
||||
import io.dataease.api.visualization.DataVisualizationApi;
|
||||
import io.dataease.api.visualization.dto.VisualizationViewTableDTO;
|
||||
import io.dataease.api.visualization.request.DataVisualizationBaseRequest;
|
||||
import io.dataease.api.visualization.request.VisualizationWorkbranchQueryRequest;
|
||||
import io.dataease.api.visualization.vo.DataVisualizationVO;
|
||||
@ -354,6 +355,11 @@ public class DataVisualizationServer implements DataVisualizationApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VisualizationViewTableDTO> detailList(Long dvId) {
|
||||
return extDataVisualizationMapper.getVisualizationViewDetails(dvId);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void nameCheck(DataVisualizationBaseRequest request) {
|
||||
|
@ -41,7 +41,8 @@
|
||||
`copy_id`)
|
||||
SELECT core_chart_view.`id` + #{copyId} as id,
|
||||
`title`,
|
||||
#{newDvId} as scene_id, `table_id`,
|
||||
#{newDvId} as scene_id,
|
||||
`table_id`,
|
||||
`type`,
|
||||
`render`,
|
||||
`result_count`,
|
||||
@ -73,7 +74,8 @@
|
||||
`refresh_time`,
|
||||
`linkage_active`,
|
||||
`jump_active`,
|
||||
core_chart_view.`id` as copy_from, #{copyId} as copy_id
|
||||
core_chart_view.`id` as copy_from,
|
||||
#{copyId} as copy_id
|
||||
FROM core_chart_view
|
||||
WHERE core_chart_view.scene_id = #{sourceDvId}
|
||||
</insert>
|
||||
@ -160,65 +162,58 @@
|
||||
</select>
|
||||
|
||||
<select id="findRecent" resultType="io.dataease.visualization.dao.ext.po.VisualizationResourcePO">
|
||||
SELECT
|
||||
dvResource.id,
|
||||
dvResource.resource_id,
|
||||
dvResource.name,
|
||||
dvResource.type,
|
||||
dvResource.creator,
|
||||
core_opt_recent.uid AS last_editor,
|
||||
core_opt_recent.time AS last_edit_time,
|
||||
(
|
||||
CASE
|
||||
SELECT dvResource.id,
|
||||
dvResource.resource_id,
|
||||
dvResource.name,
|
||||
dvResource.type,
|
||||
dvResource.creator,
|
||||
core_opt_recent.uid AS last_editor,
|
||||
core_opt_recent.time AS last_edit_time,
|
||||
(
|
||||
CASE
|
||||
|
||||
WHEN core_store.resource_id IS NULL THEN
|
||||
0 ELSE 1
|
||||
END
|
||||
) AS favorite
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
core_dataset_group.id,
|
||||
core_dataset_group.id AS resource_id,
|
||||
core_dataset_group.NAME,
|
||||
'dataset' AS type,
|
||||
core_dataset_group.create_by AS creator
|
||||
FROM
|
||||
core_dataset_group
|
||||
WHERE
|
||||
core_dataset_group.node_type = 'dataset' UNION ALL
|
||||
SELECT
|
||||
core_datasource.id,
|
||||
core_datasource.id AS resource_id,
|
||||
core_datasource.NAME,
|
||||
'datasource' AS type,
|
||||
core_datasource.create_by AS creator
|
||||
FROM
|
||||
core_datasource
|
||||
WHERE
|
||||
core_datasource.type != 'folder' UNION ALL
|
||||
SELECT
|
||||
data_visualization_info.id,
|
||||
data_visualization_info.id AS resource_id,
|
||||
data_visualization_info.NAME,
|
||||
(
|
||||
CASE
|
||||
data_visualization_info.type
|
||||
WHEN 'dataV' THEN
|
||||
'screen' ELSE 'panel'
|
||||
END
|
||||
) AS type,
|
||||
data_visualization_info.create_by AS creator
|
||||
FROM
|
||||
data_visualization_info
|
||||
WHERE
|
||||
data_visualization_info.delete_flag = 0
|
||||
AND node_type = 'leaf'
|
||||
) dvResource
|
||||
LEFT JOIN core_store ON dvResource.id = core_store.resource_id
|
||||
AND core_store.uid = #{uid}
|
||||
INNER JOIN core_opt_recent ON dvResource.resource_id = core_opt_recent.resource_id
|
||||
AND core_opt_recent.uid = #{uid} ${ew.customSqlSegment}
|
||||
WHEN core_store.resource_id IS NULL THEN
|
||||
0
|
||||
ELSE 1
|
||||
END
|
||||
) AS favorite
|
||||
FROM (SELECT core_dataset_group.id,
|
||||
core_dataset_group.id AS resource_id,
|
||||
core_dataset_group.NAME,
|
||||
'dataset' AS type,
|
||||
core_dataset_group.create_by AS creator
|
||||
FROM core_dataset_group
|
||||
WHERE core_dataset_group.node_type = 'dataset'
|
||||
UNION ALL
|
||||
SELECT core_datasource.id,
|
||||
core_datasource.id AS resource_id,
|
||||
core_datasource.NAME,
|
||||
'datasource' AS type,
|
||||
core_datasource.create_by AS creator
|
||||
FROM core_datasource
|
||||
WHERE core_datasource.type != 'folder'
|
||||
UNION ALL
|
||||
SELECT
|
||||
data_visualization_info.id,
|
||||
data_visualization_info.id AS resource_id,
|
||||
data_visualization_info.NAME,
|
||||
(
|
||||
CASE
|
||||
data_visualization_info.type
|
||||
WHEN 'dataV' THEN
|
||||
'screen' ELSE 'panel'
|
||||
END
|
||||
) AS type,
|
||||
data_visualization_info.create_by AS creator
|
||||
FROM
|
||||
data_visualization_info
|
||||
WHERE
|
||||
data_visualization_info.delete_flag = 0
|
||||
AND node_type = 'leaf') dvResource
|
||||
LEFT JOIN core_store ON dvResource.id = core_store.resource_id
|
||||
AND core_store.uid = #{uid}
|
||||
INNER JOIN core_opt_recent ON dvResource.resource_id = core_opt_recent.resource_id
|
||||
AND core_opt_recent.uid = #{uid} ${ew.customSqlSegment}
|
||||
</select>
|
||||
|
||||
<insert id="copyLinkJump">
|
||||
@ -270,7 +265,7 @@
|
||||
visualization_link_jump_info.`checked`,
|
||||
visualization_link_jump_info.`attach_params`,
|
||||
visualization_link_jump_info.`id` AS copy_from,
|
||||
#{copyId} AS copy_id
|
||||
#{copyId} AS copy_id
|
||||
FROM visualization_link_jump_info
|
||||
INNER JOIN (SELECT id AS t_id,
|
||||
copy_from AS s_id
|
||||
@ -294,7 +289,7 @@
|
||||
visualization_link_jump_target_view_info.`target_view_id`,
|
||||
visualization_link_jump_target_view_info.`target_field_id`,
|
||||
visualization_link_jump_target_view_info.`target_id` AS copy_from,
|
||||
#{copyId} AS copy_id
|
||||
#{copyId} AS copy_id
|
||||
FROM visualization_link_jump_target_view_info
|
||||
INNER JOIN (SELECT id AS t_id,
|
||||
copy_from AS s_id
|
||||
@ -370,4 +365,36 @@
|
||||
WHERE copy_id = #{copyId}) pvlf_copy
|
||||
ON visualization_linkage_field.linkage_id = pvlf_copy.s_id
|
||||
</insert>
|
||||
|
||||
<resultMap id="ViewDetailsMap" type="io.dataease.api.visualization.dto.VisualizationViewTableDTO">
|
||||
<result column="id" property="id"/>
|
||||
<result column="title" property="title"/>
|
||||
<result column="scene_id" property="sceneId"/>
|
||||
<result column="table_id" property="tableId"/>
|
||||
<result column="type" property="type"/>
|
||||
<result column="render" property="render"/>
|
||||
<collection property="tableFields" ofType="io.dataease.dto.dataset.DatasetTableFieldDTO">
|
||||
<result column="field_id" jdbcType="VARCHAR" property="id"/>
|
||||
<result column="origin_name" jdbcType="VARCHAR" property="originName"/>
|
||||
<result column="field_name" jdbcType="VARCHAR" property="name"/>
|
||||
<result column="field_type" jdbcType="VARCHAR" property="type"/>
|
||||
<result column="de_type" jdbcType="VARCHAR" property="deType"/>
|
||||
</collection>
|
||||
</resultMap>
|
||||
|
||||
<select id="getVisualizationViewDetails" resultMap="ViewDetailsMap">
|
||||
SELECT core_chart_view.id,
|
||||
core_chart_view.title,
|
||||
core_chart_view.scene_id,
|
||||
core_chart_view.table_id,
|
||||
core_chart_view.`type`,
|
||||
core_chart_view.render,
|
||||
core_chart_view.scene_id as 'visualization_id', core_dataset_table_field.id AS 'field_id', core_dataset_table_field.origin_name,
|
||||
core_dataset_table_field.`name` AS 'field_name', core_dataset_table_field.type AS 'field_type', core_dataset_table_field.de_type
|
||||
FROM core_chart_view
|
||||
LEFT JOIN core_dataset_table_field
|
||||
ON core_chart_view.table_id = core_dataset_table_field.dataset_group_id
|
||||
WHERE core_chart_view.scene_id = #{dvId}
|
||||
AND core_chart_view.id IS NOT NULL
|
||||
</select>
|
||||
</mapper>
|
||||
|
@ -61,14 +61,14 @@
|
||||
</select>
|
||||
|
||||
<select id="queryWithVisualizationId" resultMap="BaseResultMapDTO">
|
||||
SELECT
|
||||
#{visualizationId} as visualization_id,
|
||||
ifnull( visualization_outer_params.checked, 0 ) AS checked
|
||||
FROM
|
||||
visualization_group
|
||||
LEFT JOIN visualization_outer_params ON visualization_group.id = visualization_outer_params.visualization_id
|
||||
WHERE
|
||||
visualization_group.id = #{visualizationId}
|
||||
SELECT
|
||||
#{visualizationId} as visualization_id,
|
||||
ifnull( visualization_outer_params.checked, 0 ) AS checked
|
||||
FROM
|
||||
data_visualization_info
|
||||
LEFT JOIN visualization_outer_params ON data_visualization_info.id = visualization_outer_params.visualization_id
|
||||
WHERE
|
||||
data_visualization_info.id = #{visualizationId}
|
||||
</select>
|
||||
|
||||
<delete id="deleteOuterParamsTargetWithVisualizationId" >
|
||||
|
@ -74,9 +74,9 @@ export const storeStatusApi = (id: string): Promise<IResponse> => {
|
||||
|
||||
export const decompression = data => request.post({ url: '/dataVisualization/decompression', data })
|
||||
|
||||
export const detailList = dvId => {
|
||||
export const viewDetailList = dvId => {
|
||||
return request.get({
|
||||
url: '/dataVisualization/view/detailList/' + dvId,
|
||||
url: '/dataVisualization/viewDetailList/' + dvId,
|
||||
method: 'get',
|
||||
loading: false
|
||||
})
|
||||
|
@ -1,8 +1,8 @@
|
||||
import request from '@/config/axios'
|
||||
|
||||
export function queryWithDvId(dvId) {
|
||||
export function queryWithVisualizationId(dvId) {
|
||||
return request.get({
|
||||
url: '/outerParams/queryWithDvId/' + dvId
|
||||
url: '/outerParams/queryWithVisualizationId/' + dvId
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -434,6 +434,13 @@ const isDataEaseBi = computed(() => appStore.getIsDataEaseBi)
|
||||
|
||||
<div class="right-area" v-if="!batchOptStatus && !linkageSettingStatus">
|
||||
<template v-if="editMode !== 'preview'">
|
||||
<el-tooltip effect="dark" content="外部参数设置" placement="bottom">
|
||||
<component-button
|
||||
tips="外部参数设置"
|
||||
@custom-click="openOuterParamsSet"
|
||||
icon-name="icon_params_setting"
|
||||
/>
|
||||
</el-tooltip>
|
||||
<el-tooltip effect="dark" content="批量操作" placement="bottom">
|
||||
<component-button
|
||||
tips="批量操作"
|
||||
|
@ -1,33 +1,27 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
class="params-class"
|
||||
width="900px"
|
||||
:append-to-body="true"
|
||||
title="外部参数设置"
|
||||
v-model="state.outerParamsSetVisible"
|
||||
@submit.prevent
|
||||
width="70vw"
|
||||
top="10vh"
|
||||
trigger="click"
|
||||
>
|
||||
<el-row style="height: 430px">
|
||||
<el-row>
|
||||
<span style="margin-right: 20px; font-weight: 600">{{
|
||||
t('visualization.outer_param_set')
|
||||
}}</span>
|
||||
<el-checkbox v-model="state.outerParams.checked">{{
|
||||
t('visualization.enable_outer_param_set')
|
||||
}}</el-checkbox>
|
||||
</el-row>
|
||||
<el-row style="height: 550px">
|
||||
<el-row v-loading="state.loading">
|
||||
<el-row class="preview">
|
||||
<el-col :span="8" style="height: 100%; overflow-y: hidden">
|
||||
<el-row class="tree-head">
|
||||
<span style="float: left; margin-left: 30px">{{
|
||||
t('visualization.param_name')
|
||||
}}</span>
|
||||
<span style="float: right; margin-right: 10px">{{
|
||||
t('visualization.enable_param')
|
||||
}}</span>
|
||||
<span class="head-text">参数列表</span>
|
||||
<span class="head-filter">
|
||||
<el-button type="primary" icon="Plus" text @click="addOuterParamsInfo"> </el-button>
|
||||
</span>
|
||||
</el-row>
|
||||
<el-row class="tree-content">
|
||||
<el-tree
|
||||
class="custom-tree"
|
||||
menu
|
||||
ref="outerParamsInfoTree"
|
||||
:data="state.outerParamsInfoArray"
|
||||
node-key="id"
|
||||
@ -35,72 +29,70 @@
|
||||
:props="state.treeProp"
|
||||
@node-click="nodeClick"
|
||||
>
|
||||
<template v-slot="{ node, data }">
|
||||
<template #default="{ node, data }">
|
||||
<span class="custom-tree-node">
|
||||
<span>
|
||||
<span style="margin-left: 6px"
|
||||
><el-input
|
||||
v-model="data.paramName"
|
||||
size="mini"
|
||||
:placeholder="t('visualization.input_param_name')"
|
||||
/></span>
|
||||
</span>
|
||||
<span @click.stop>
|
||||
<div>
|
||||
<div @click.stop>
|
||||
<span class="auth-span">
|
||||
<el-checkbox
|
||||
v-model="data.checked"
|
||||
style="margin-right: 10px"
|
||||
@change="sourceFieldCheckedChange(data)"
|
||||
/>
|
||||
<el-button
|
||||
icon="el-icon-delete"
|
||||
type="text"
|
||||
size="small"
|
||||
@click="removeOuterParamsInfo(node, data)"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</span>
|
||||
<span :id="'paramName-' + data.paramsInfoId">
|
||||
<el-input
|
||||
v-if="curEditDataId === data.paramsInfoId"
|
||||
v-model="data.paramName"
|
||||
size="mini"
|
||||
:placeholder="$t('visualization.input_param_name')"
|
||||
@blur="closeEdit"
|
||||
/>
|
||||
<span class="tree-select-field" v-else-if="data.paramName">
|
||||
{{ data.paramName }}
|
||||
</span>
|
||||
<span class="tree-select-field" v-else> 未配置参数名 </span>
|
||||
</span>
|
||||
<span class="icon-more">
|
||||
<handle-more
|
||||
style="margin-right: 10px"
|
||||
@handle-command="cmd => outerParamsOperation(cmd, node, data)"
|
||||
:menu-list="state.optMenu"
|
||||
icon-name="icon_more_outlined"
|
||||
placement="bottom-start"
|
||||
></handle-more>
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
</el-tree>
|
||||
</el-row>
|
||||
<el-row class="tree-bottom">
|
||||
<el-button
|
||||
size="mini"
|
||||
type="success"
|
||||
icon="el-icon-plus"
|
||||
round
|
||||
@click="addOuterParamsInfo"
|
||||
>{{ t('visualization.add_param') }}
|
||||
</el-button>
|
||||
</el-row>
|
||||
</el-col>
|
||||
<el-col :span="16" class="preview-show">
|
||||
<el-row v-if="state.outerParamsInfo">
|
||||
<el-row class="top_border">
|
||||
<el-row style="margin-top: 10px">
|
||||
<el-col :span="11">
|
||||
<div class="ellip">{{ t('visualization.link_component') }}</div>
|
||||
</el-col>
|
||||
<el-col :span="11">
|
||||
<div class="ellip">{{ t('visualization.link_component_field') }}</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row style="height: 266px; overflow-y: auto">
|
||||
<el-row
|
||||
<el-row v-if="state.curNodeId">
|
||||
<el-row style="margin-top: 5px">
|
||||
<div style="display: flex" class="inner-content">
|
||||
<div style="flex: 1">{{ t('visualization.link_view') }}</div>
|
||||
<div style="width: 36px"></div>
|
||||
<div style="flex: 1">
|
||||
{{ t('visualization.link_view_field') }}
|
||||
</div>
|
||||
<div style="width: 32px"></div>
|
||||
</div>
|
||||
<div style="width: 100%; max-height: 350px; overflow-y: auto">
|
||||
<div
|
||||
style="display: flex; padding: 0 16px 8px"
|
||||
v-for="(targetViewInfo, index) in state.outerParamsInfo.targetViewInfoList"
|
||||
:key="index"
|
||||
>
|
||||
<el-col :span="11">
|
||||
<div style="flex: 1">
|
||||
<div class="select-filed">
|
||||
<el-select
|
||||
v-model="targetViewInfo.targetViewId"
|
||||
filterable
|
||||
style="width: 100%"
|
||||
size="mini"
|
||||
:placeholder="t('fu.search_bar.please_select')"
|
||||
:placeholder="t('visualization.please_select')"
|
||||
@change="viewInfoOnChange(targetViewInfo)"
|
||||
>
|
||||
<el-option
|
||||
@ -110,15 +102,23 @@
|
||||
curItem.id === targetViewInfo.targetViewId
|
||||
)"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:label="item.title"
|
||||
:value="item.id"
|
||||
>
|
||||
<span style="float: left; font-size: 12px"> {{ item.name }}</span>
|
||||
<Icon
|
||||
class-name="view-type-icon"
|
||||
style="margin-right: 4px"
|
||||
:name="item.type"
|
||||
/>
|
||||
<span style="font-size: 12px"> {{ item.title }}</span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="11">
|
||||
</div>
|
||||
<el-icon class="link-icon-join">
|
||||
<Icon style="width: 20px; height: 20px" name="dv-link-target" />
|
||||
</el-icon>
|
||||
<div style="flex: 1">
|
||||
<div class="select-filed">
|
||||
<el-select
|
||||
v-model="targetViewInfo.targetFieldId"
|
||||
@ -126,7 +126,7 @@
|
||||
:disabled="fieldIdDisabledCheck(targetViewInfo)"
|
||||
style="width: 100%"
|
||||
size="mini"
|
||||
:placeholder="t('fu.search_bar.please_select')"
|
||||
:placeholder="t('visualization.please_select')"
|
||||
>
|
||||
<el-option
|
||||
v-for="viewField in getFieldArray(targetViewInfo.targetViewId)"
|
||||
@ -134,70 +134,34 @@
|
||||
:label="viewField.name"
|
||||
:value="viewField.id"
|
||||
>
|
||||
<span style="float: left">
|
||||
<svg-icon
|
||||
v-if="viewField.deType === 0"
|
||||
icon-class="field_text"
|
||||
class="field-icon-text"
|
||||
/>
|
||||
<svg-icon
|
||||
v-if="viewField.deType === 1"
|
||||
icon-class="field_time"
|
||||
class="field-icon-time"
|
||||
/>
|
||||
<svg-icon
|
||||
v-if="viewField.deType === 2 || viewField.deType === 3"
|
||||
icon-class="field_value"
|
||||
class="field-icon-value"
|
||||
/>
|
||||
<svg-icon
|
||||
v-if="viewField.deType === 5"
|
||||
icon-class="field_location"
|
||||
class="field-icon-location"
|
||||
/>
|
||||
</span>
|
||||
<span style="float: left; font-size: 12px">{{ viewField.name }}</span>
|
||||
<Icon
|
||||
style="width: 14px; height: 14px"
|
||||
:name="`field_${fieldType[viewField.deType]}`"
|
||||
:className="`field-icon-${fieldType[viewField.deType]}`"
|
||||
/>
|
||||
<span style="font-size: 12px">{{ viewField.name }}</span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="2">
|
||||
<div>
|
||||
<el-button
|
||||
icon="el-icon-delete"
|
||||
type="text"
|
||||
size="small"
|
||||
style="float: left"
|
||||
@click="deleteOuterParamsField(index)"
|
||||
/>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-row>
|
||||
</div>
|
||||
<el-button class="m-del-icon-btn" text @click="deleteOuterParamsField(index)">
|
||||
<el-icon size="20px">
|
||||
<Icon name="icon_delete-trash_outlined" />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-row class="bottom">
|
||||
<el-button
|
||||
size="mini"
|
||||
type="success"
|
||||
icon="el-icon-plus"
|
||||
round
|
||||
@click="addOuterParamsField"
|
||||
>{{ t('visualization.add_param_link_field') }}
|
||||
<el-row style="width: 100%; padding-left: 16px">
|
||||
<el-button type="primary" icon="Plus" text @click="addOuterParamsField">
|
||||
{{ t('visualization.add_param_link_field') }}
|
||||
</el-button>
|
||||
</el-row>
|
||||
</el-row>
|
||||
<el-row v-if="state.outerParamsInfo.linkType === 'outer'" style="height: 300px">
|
||||
<el-input
|
||||
v-model="state.outerParamsInfo.content"
|
||||
:autosize="{ minRows: 14 }"
|
||||
type="textarea"
|
||||
:placeholder="t('visualization.input_jump_link')"
|
||||
/>
|
||||
</el-row>
|
||||
</el-row>
|
||||
<el-row v-else style="height: 100%" class="custom-position">
|
||||
{{ t('visualization.select_param') }}
|
||||
</el-row>
|
||||
<div v-else class="empty">
|
||||
<empty-background description="请配置参数" img-type="noneWhite" />
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-row>
|
||||
@ -219,18 +183,34 @@ import { ElMessage } from 'element-plus-secondary'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { deepCopy } from '@/utils/utils'
|
||||
import generateID from '@/utils/generateID'
|
||||
import { queryWithDvId, updateOuterParamsSet } from '@/api/visualization/outerParams'
|
||||
import { detailList } from '@/api/visualization/dataVisualization'
|
||||
import { queryWithVisualizationId, updateOuterParamsSet } from '@/api/visualization/outerParams'
|
||||
import { viewDetailList } from '@/api/visualization/dataVisualization'
|
||||
import checkArrayRepeat from '@/utils/check'
|
||||
import HandleMore from '@/components/handle-more/src/HandleMore.vue'
|
||||
import { fieldType } from '@/utils/attr'
|
||||
import EmptyBackground from '@/components/empty-background/src/EmptyBackground.vue'
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const { dvInfo, componentData, canvasStyleData } = storeToRefs(dvMainStore)
|
||||
const outerParamsInfoTree = ref(null)
|
||||
const emits = defineEmits(['outerParamsSetVisibleChange'])
|
||||
const { t } = useI18n()
|
||||
const curEditDataId = ref(null)
|
||||
|
||||
const state = reactive({
|
||||
loading: false,
|
||||
outerParamsSetVisible: false,
|
||||
optMenu: [
|
||||
{
|
||||
label: '重命名',
|
||||
svgName: 'edit',
|
||||
command: 'rename'
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
svgName: 'delete',
|
||||
command: 'delete'
|
||||
}
|
||||
],
|
||||
treeProp: {
|
||||
id: 'paramsInfoId',
|
||||
label: 'paramName',
|
||||
@ -240,9 +220,10 @@ const state = reactive({
|
||||
checked: false,
|
||||
outerParamsInfoArray: []
|
||||
},
|
||||
outerParamsInfoArray: null,
|
||||
outerParamsInfoArray: [],
|
||||
mapOuterParamsInfoArray: {},
|
||||
panelList: [],
|
||||
curNodeId: null,
|
||||
outerParamsInfo: {
|
||||
content: '',
|
||||
linkType: '',
|
||||
@ -280,6 +261,18 @@ const viewSelectedField = computed(() =>
|
||||
state.outerParamsInfo?.targetViewInfoList?.map(targetViewInfo => targetViewInfo.targetViewId)
|
||||
)
|
||||
|
||||
const closeEdit = () => {
|
||||
curEditDataId.value = null
|
||||
}
|
||||
|
||||
const outerParamsOperation = (cmd, node, data) => {
|
||||
if (cmd === 'rename') {
|
||||
curEditDataId.value = data.paramsInfoId
|
||||
} else if (cmd === 'delete') {
|
||||
removeOuterParamsInfo(node, data)
|
||||
}
|
||||
}
|
||||
|
||||
const fieldIdDisabledCheck = targetViewInfo => {
|
||||
return (
|
||||
state.viewIdFieldArrayMap[targetViewInfo.targetViewId] &&
|
||||
@ -292,27 +285,28 @@ const getFieldArray = id => {
|
||||
return state.viewIdFieldArrayMap[id]
|
||||
}
|
||||
|
||||
const init = () => {
|
||||
// 获取当前仪表板外部跳转蚕食信息
|
||||
queryWithDvId(dvInfo['id']).then(rsp => {
|
||||
const initParams = () => {
|
||||
// 获取当前仪表板外部跳转信息
|
||||
queryWithVisualizationId(dvInfo.value.id).then(rsp => {
|
||||
state.outerParams = rsp.data
|
||||
state.outerParamsInfoArray = state.outerParams?.outerParamsInfoArray
|
||||
if (state.outerParamsInfoArray.length > 0) {
|
||||
if (state.outerParamsInfoArray.length >= 1) {
|
||||
state.outerParamsInfoArray.forEach(outerParamsInfo => {
|
||||
state.mapOuterParamsInfoArray[outerParamsInfo.paramsInfoId] = outerParamsInfo
|
||||
})
|
||||
const firstNode = state.outerParamsInfoArray[0]
|
||||
state.curNodeId = null
|
||||
nextTick(() => {
|
||||
outerParamsInfoTree.value.setCurrentKey(firstNode.paramsInfoId)
|
||||
nodeClick(firstNode)
|
||||
// outerParamsInfoTree.value.setCurrentKey(firstNode.paramsInfoId)
|
||||
// nodeClick(firstNode)
|
||||
})
|
||||
}
|
||||
})
|
||||
getPanelViewList(dvInfo['id'])
|
||||
getPanelViewList(dvInfo.value.id)
|
||||
}
|
||||
|
||||
const cancel = () => {
|
||||
emits('outerParamsSetVisibleChange', false)
|
||||
state.outerParamsSetVisible = false
|
||||
}
|
||||
|
||||
const save = () => {
|
||||
@ -335,11 +329,12 @@ const save = () => {
|
||||
|
||||
const nodeClick = data => {
|
||||
state.outerParamsInfo = state.mapOuterParamsInfoArray[data.paramsInfoId]
|
||||
state.curNodeId = data.paramsInfoId
|
||||
}
|
||||
|
||||
// 获取当前视图字段 关联仪表板的视图信息列表
|
||||
const getPanelViewList = dvId => {
|
||||
detailList(dvId).then(rsp => {
|
||||
viewDetailList(dvId).then(rsp => {
|
||||
state.viewIdFieldArrayMap = {}
|
||||
state.currentLinkPanelViewArray = rsp.data
|
||||
if (state.currentLinkPanelViewArray) {
|
||||
@ -416,11 +411,12 @@ const sourceFieldCheckedChange = data => {
|
||||
}
|
||||
|
||||
const addOuterParamsInfo = () => {
|
||||
outerParamsInfoTree.value.checked = true
|
||||
state.outerParams.checked = true
|
||||
const outerParamsInfo = deepCopy(state.defaultOuterParamsInfo)
|
||||
outerParamsInfo['paramsInfoId'] = generateID()
|
||||
state.outerParamsInfoArray.push(outerParamsInfo)
|
||||
state.mapOuterParamsInfoArray[outerParamsInfo.paramsInfoId] = outerParamsInfo
|
||||
curEditDataId.value = outerParamsInfo['paramsInfoId']
|
||||
}
|
||||
|
||||
const removeOuterParamsInfo = (node, data) => {
|
||||
@ -430,12 +426,13 @@ const removeOuterParamsInfo = (node, data) => {
|
||||
children.splice(index, 1)
|
||||
if (data.paramsInfoId === state.outerParamsInfo.paramsInfoId) {
|
||||
delete state.mapOuterParamsInfoArray[data.paramsInfoId]
|
||||
state.outerParamsInfo = null
|
||||
state.curNodeId = null
|
||||
}
|
||||
}
|
||||
|
||||
const optInit = () => {
|
||||
state.outerParamsSetVisible = true
|
||||
initParams()
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
@ -446,23 +443,115 @@ defineExpose({
|
||||
<style scoped lang="less">
|
||||
.root-class {
|
||||
margin: 15px 0px 5px;
|
||||
text-align: center;
|
||||
justify-content: right;
|
||||
}
|
||||
|
||||
.preview {
|
||||
margin-top: 5px;
|
||||
border: 1px solid #e6e6e6;
|
||||
height: 350px !important;
|
||||
border-radius: 4px;
|
||||
height: 470px !important;
|
||||
overflow: hidden;
|
||||
background-size: 100% 100% !important;
|
||||
}
|
||||
|
||||
.tree-head {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
font-size: 12px;
|
||||
color: #3d4d66;
|
||||
.head-text {
|
||||
margin-left: 16px;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
color: #1f2329;
|
||||
}
|
||||
.head-filter {
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
margin-right: 16px;
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
color: #646a73;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ed-row) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.m-del-icon-btn {
|
||||
color: #646a73;
|
||||
margin-top: 4px;
|
||||
margin-left: 4px;
|
||||
|
||||
&:hover {
|
||||
background: rgba(31, 35, 41, 0.1) !important;
|
||||
}
|
||||
&:focus {
|
||||
background: rgba(31, 35, 41, 0.1) !important;
|
||||
}
|
||||
&:active {
|
||||
background: rgba(31, 35, 41, 0.2) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.empty {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.preview-show {
|
||||
border-left: 1px solid #e6e6e6;
|
||||
height: 350px;
|
||||
background-size: 100% 100% !important;
|
||||
}
|
||||
|
||||
.view-type-icon {
|
||||
color: var(--ed-color-primary);
|
||||
width: 22px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.custom-tree {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.custom-tree-node {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 14px;
|
||||
|
||||
.icon-more {
|
||||
margin-left: auto;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
&:hover .icon-more {
|
||||
margin-left: auto;
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
.link-icon-join {
|
||||
font-size: 20px;
|
||||
margin-top: 7px;
|
||||
margin-left: 8px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.inner-content {
|
||||
width: 100%;
|
||||
padding: 16px 16px 8px 16px;
|
||||
font-size: 14px !important;
|
||||
}
|
||||
|
||||
.slot-class {
|
||||
color: white;
|
||||
}
|
||||
@ -490,8 +579,6 @@ defineExpose({
|
||||
|
||||
.select-filed {
|
||||
/*width: 100%;*/
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
overflow: hidden; /*超出部分隐藏*/
|
||||
white-space: nowrap; /*不换行*/
|
||||
text-overflow: ellipsis; /*超出部分文字以...显示*/
|
||||
@ -532,29 +619,12 @@ v-deep(.vue-treeselect__single-value) {
|
||||
line-height: 28px !important;
|
||||
}
|
||||
|
||||
.custom-tree-node {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.auth-span {
|
||||
float: right;
|
||||
width: 40px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.tree-head {
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
border-bottom: 1px solid var(--TableBorderColor, #e6e6e6);
|
||||
background-color: var(--SiderBG, #f7f8fa);
|
||||
font-size: 12px;
|
||||
color: var(--TableColor, #3d4d66);
|
||||
}
|
||||
|
||||
.tree-content {
|
||||
height: calc(100% - 70px);
|
||||
overflow-y: auto;
|
||||
|
@ -754,6 +754,9 @@ export const dvMainStore = defineStore('dataVisualization', {
|
||||
setNowTargetPanelJumpInfo(jumpInfo) {
|
||||
this.nowPanelJumpInfoTargetPanel = jumpInfo.baseJumpInfoVisualizationMap
|
||||
},
|
||||
setNowPanelOuterParamsInfo(outerParamsInfo) {
|
||||
this.nowPanelOuterParamsInfo = outerParamsInfo.outerParamsInfoMap
|
||||
},
|
||||
// 添加联动 下钻 等查询组件
|
||||
addViewTrackFilter(data) {
|
||||
const viewId = data.viewId
|
||||
@ -794,6 +797,72 @@ export const dvMainStore = defineStore('dataVisualization', {
|
||||
useEmitt().emitter.emit('query-data-' + viewId)
|
||||
})
|
||||
},
|
||||
// 添加外部参数的过滤条件
|
||||
addOuterParamsFilter(params) {
|
||||
// params 结构 {key1:value1,key2:value2}
|
||||
const curComponentData = this.componentData
|
||||
if (params) {
|
||||
const trackInfo = this.nowPanelOuterParamsInfo
|
||||
for (let index = 0; index < curComponentData.length; index++) {
|
||||
const element = curComponentData[index]
|
||||
if (element.component !== 'UserView') continue
|
||||
const currentFilters = element.outerParamsFilters || [] // 外部参数信息
|
||||
|
||||
// 外部参数 可能会包含多个参数
|
||||
Object.keys(params).forEach(function (sourceInfo) {
|
||||
// 获取外部参数的值 sourceInfo 是外部参数名称 支持数组传入
|
||||
let paramValue = params[sourceInfo]
|
||||
let paramValueStr = params[sourceInfo]
|
||||
let operator = 'in'
|
||||
if (paramValue && !Array.isArray(paramValue)) {
|
||||
paramValue = [paramValue]
|
||||
operator = 'eq'
|
||||
} else if (paramValue && Array.isArray(paramValue)) {
|
||||
paramValueStr = ''
|
||||
paramValue.forEach((innerValue, index) => {
|
||||
if (index === 0) {
|
||||
paramValueStr = innerValue
|
||||
} else {
|
||||
paramValueStr = paramValueStr + ',' + innerValue
|
||||
}
|
||||
})
|
||||
}
|
||||
// 获取所有目标联动信息
|
||||
const targetInfoList = trackInfo[sourceInfo] || []
|
||||
|
||||
targetInfoList.forEach(targetInfo => {
|
||||
const targetInfoArray = targetInfo.split('#')
|
||||
const targetViewId = targetInfoArray[0] // 目标视图
|
||||
if (element.component === 'UserView' && element.id === targetViewId) {
|
||||
// 如果目标视图 和 当前循环组件id相等 则进行条件增减
|
||||
const targetFieldId = targetInfoArray[1] // 目标视图列ID
|
||||
const condition = {
|
||||
fieldId: targetFieldId,
|
||||
operator: operator,
|
||||
value: paramValue,
|
||||
viewIds: [targetViewId]
|
||||
}
|
||||
let j = currentFilters.length
|
||||
while (j--) {
|
||||
const filter = currentFilters[j]
|
||||
// 兼容性准备 viewIds 只会存放一个值
|
||||
if (targetFieldId === filter.fieldId && filter.viewIds.includes(targetViewId)) {
|
||||
currentFilters.splice(j, 1)
|
||||
}
|
||||
}
|
||||
// 不存在该条件 且 条件有效 直接保存该条件
|
||||
// !filterExist && vValid && currentFilters.push(condition)
|
||||
currentFilters.push(condition)
|
||||
}
|
||||
})
|
||||
if (element.component === 'UserView') {
|
||||
element['outerParamsFilters'] = currentFilters
|
||||
}
|
||||
curComponentData[index] = element
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
trackFilterCursor(element, checkQDList, trackInfo, preActiveComponentIds, viewId) {
|
||||
const currentFilters = element.linkageFilters || [] // 当前联动filter
|
||||
// 联动的图表情况历史条件
|
||||
|
@ -302,6 +302,7 @@ const filter = (firstLoad?: boolean) => {
|
||||
user: wsCache.get('user.uid'),
|
||||
filter,
|
||||
linkageFilters: element.value.linkageFilters,
|
||||
outerParamsFilters: element.value.outerParamsFilters,
|
||||
drill: state.drillClickDimensionList,
|
||||
resultCount: resultCount.value,
|
||||
resultMode: resultMode.value
|
||||
|
@ -6,7 +6,11 @@ import router from '@/router'
|
||||
import { initCanvasData } from '@/utils/canvasUtils'
|
||||
import { queryTargetVisualizationJumpInfo } from '@/api/visualization/linkJump'
|
||||
import { Base64 } from 'js-base64'
|
||||
import { getOuterParamsInfo } from '@/api/visualization/outerParams'
|
||||
import { ElMessage } from 'element-plus-secondary'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const { t } = useI18n()
|
||||
const state = reactive({
|
||||
canvasDataPreview: null,
|
||||
canvasStylePreview: null,
|
||||
@ -45,6 +49,21 @@ const loadCanvasDataAsync = async (dvId, dvType) => {
|
||||
}
|
||||
}
|
||||
|
||||
// 添加外部参数
|
||||
const attachParamsEncode = router.currentRoute.value.query.attachParams
|
||||
let attachParam
|
||||
if (attachParamsEncode) {
|
||||
try {
|
||||
attachParam = JSON.parse(Base64.decode(decodeURIComponent(attachParamsEncode)))
|
||||
await getOuterParamsInfo(dvId).then(rsp => {
|
||||
dvMainStore.setNowPanelOuterParamsInfo(rsp.data)
|
||||
})
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
ElMessage.error(t('visualization.outer_param_decode_error'))
|
||||
}
|
||||
}
|
||||
|
||||
initCanvasData(
|
||||
dvId,
|
||||
dvType,
|
||||
@ -63,6 +82,9 @@ const loadCanvasDataAsync = async (dvId, dvType) => {
|
||||
if (jumpParam) {
|
||||
dvMainStore.addViewTrackFilter(jumpParam)
|
||||
}
|
||||
if (attachParam) {
|
||||
dvMainStore.addOuterParamsFilter(attachParam)
|
||||
}
|
||||
if (props.publicLinkStatus) {
|
||||
// 设置浏览器title为当前仪表板名称
|
||||
document.title = dvInfo.name
|
||||
|
@ -3,6 +3,7 @@ package io.dataease.api.visualization;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.dataease.api.visualization.dto.VisualizationViewTableDTO;
|
||||
import io.dataease.api.visualization.request.DataVisualizationBaseRequest;
|
||||
import io.dataease.api.visualization.request.VisualizationWorkbranchQueryRequest;
|
||||
import io.dataease.api.visualization.vo.DataVisualizationVO;
|
||||
@ -104,4 +105,8 @@ public interface DataVisualizationApi {
|
||||
@Operation(summary = "解析可视化资源模板文件信息")
|
||||
DataVisualizationVO decompressionLocalFile(@RequestPart(value = "file") MultipartFile file);
|
||||
|
||||
|
||||
@GetMapping("/viewDetailList/{dvId}")
|
||||
@Operation(summary = "仪表板视图明细数据")
|
||||
List<VisualizationViewTableDTO> detailList(@PathVariable("dvId") Long dvId);
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import org.springframework.web.bind.annotation.*;
|
||||
public interface VisualizationOuterParamsApi {
|
||||
|
||||
|
||||
@GetMapping("/queryWithDvId/{dvId}")
|
||||
@GetMapping("/queryWithVisualizationId/{dvId}")
|
||||
VisualizationOuterParamsDTO queryWithVisualizationId(@PathVariable("dvId") String dvId);
|
||||
|
||||
@PostMapping("/updateOuterParamsSet")
|
||||
|
@ -0,0 +1,21 @@
|
||||
package io.dataease.api.visualization.dto;
|
||||
|
||||
import io.dataease.api.chart.dto.ChartViewDTO;
|
||||
import io.dataease.dto.dataset.DatasetTableFieldDTO;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : WangJiaHao
|
||||
* @date : 2024/3/14 12:42
|
||||
*/
|
||||
@Data
|
||||
public class VisualizationViewTableDTO extends ChartViewDTO {
|
||||
|
||||
private String visualizationId;
|
||||
|
||||
private String baseVisualizationData;
|
||||
|
||||
private List<DatasetTableFieldDTO> tableFields;
|
||||
}
|
Loading…
Reference in New Issue
Block a user