feat: 仪表板支持接收外部参数

This commit is contained in:
wangjiahao 2022-03-26 21:17:22 +08:00
parent dd306a3004
commit ab886fe1b4
20 changed files with 283 additions and 32 deletions

View File

@ -1,9 +1,11 @@
package io.dataease.base.mapper.ext;
import io.dataease.dto.panel.outerParams.PanelOuterParamsDTO;
import io.dataease.dto.panel.outerParams.PanelOuterParamsInfoDTO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface ExtPanelOuterParamsMapper {
PanelOuterParamsDTO queryWithPanelId(@Param("panelId") String panelId);
@ -14,4 +16,6 @@ public interface ExtPanelOuterParamsMapper {
void deleteOuterParamsWithPanelId(@Param("panelId") String panelId);
List<PanelOuterParamsInfoDTO> getPanelOuterParamsInfo(@Param("panelId") String panelId);
}

View File

@ -17,6 +17,13 @@
</collection>
</resultMap>
<resultMap id="AllOuterParamsMap" type="io.dataease.dto.panel.outerParams.PanelOuterParamsInfoDTO">
<result column="sourceInfo" jdbcType="VARCHAR" property="sourceInfo"/>
<collection property="targetInfoList" ofType="String">
<result column="targetInfo" jdbcType="VARCHAR"/>
</collection>
</resultMap>
<select id="getOuterParamsInfo" resultMap="OuterParamsInfoMap">
SELECT
pop.panel_id,
@ -76,6 +83,17 @@
pop.panel_id = #{panelId}
</delete>
<select id="getPanelOuterParamsInfo" resultMap="AllOuterParamsMap">
SELECT DISTINCT
param_name AS sourceInfo,
CONCAT( poptvi.target_view_id, '#', poptvi.target_field_id ) AS targetInfo
FROM
panel_outer_params pop
LEFT JOIN panel_outer_params_info popi ON pop.params_id = popi.params_id
LEFT JOIN panel_outer_params_target_view_info poptvi ON popi.params_info_id = poptvi.params_info_id
WHERE
pop.panel_id = #{panelId}
</select>
</mapper>

View File

@ -7,12 +7,15 @@ import io.dataease.commons.utils.CodingUtil;
import io.dataease.commons.utils.LogUtil;
import io.dataease.commons.utils.ServletUtils;
import io.dataease.service.panel.PanelLinkService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@ -59,6 +62,12 @@ public class IndexController {
}
HttpServletResponse response = ServletUtils.response();
try {
// TODO 增加仪表板外部参数
HttpServletRequest request = ServletUtils.request();
String attachParams = request.getParameter("attachParams");
if(StringUtils.isNotEmpty(attachParams)){
url = url+"&attachParams="+attachParams;
}
response.sendRedirect(url);
} catch (IOException e) {
LogUtil.error(e.getMessage());

View File

@ -1,6 +1,7 @@
package io.dataease.controller.panel;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.dataease.dto.panel.outerParams.PanelOuterParamsBaseResponse;
import io.dataease.dto.panel.outerParams.PanelOuterParamsDTO;
import io.dataease.service.panel.PanelOuterParamsService;
import io.swagger.annotations.Api;
@ -34,4 +35,10 @@ public class PanelOuterParamsController {
public void updateOuterParamsSet(@RequestBody PanelOuterParamsDTO OuterParamsDTO) {
panelOuterParamsService.updateOuterParamsSet(OuterParamsDTO);
}
@ApiOperation("仪表板外部参数映射关系")
@GetMapping("/getOuterParamsInfo/{panelId}")
public PanelOuterParamsBaseResponse getOuterParamsInfo(@PathVariable("panelId") String panelId){
return panelOuterParamsService.getOuterParamsInfo(panelId);
}
}

View File

@ -18,10 +18,12 @@ public class ChartExtRequest {
@ApiModelProperty("视图额外过滤条件集合")
private List<ChartExtFilterRequest> filter;
// 联动过滤条件
@ApiModelProperty("联动过滤条件集合")
private List<ChartExtFilterRequest> linkageFilters;
@ApiModelProperty("外部参数过滤条件集合")
private List<ChartExtFilterRequest> outerParamsFilters;
@ApiModelProperty("下钻维度集合")
private List<ChartDrillRequest> drill;

View File

@ -0,0 +1,25 @@
package io.dataease.dto.panel.outerParams;
import lombok.Data;
import java.util.List;
import java.util.Map;
/**
* Author: wangjiahao
* Date: 2022/3/25
* Description:
*/
@Data
public class PanelOuterParamsBaseResponse {
// 获取仪表板外部参数映射信息
private Map<String, List<String>> outerParamsInfoMap;
public PanelOuterParamsBaseResponse(Map<String, List<String>> outerParamsInfoMap) {
this.outerParamsInfoMap = outerParamsInfoMap;
}
public PanelOuterParamsBaseResponse() {
}
}

View File

@ -18,4 +18,10 @@ public class PanelOuterParamsInfoDTO extends PanelOuterParamsInfo {
private String panelId;
private List<PanelOuterParamsTargetViewInfo> targetViewInfoList=new ArrayList<>();
//仪表板外部参数信息 panelId#paramName
private String sourceInfo;
//目标联动参数 targetViewId#targetFieldId
private List<String> targetInfoList;
}

View File

@ -426,9 +426,20 @@ public class ChartViewService {
}
}
//联动过滤条件联动条件全部加上
if (ObjectUtils.isNotEmpty(requestList.getLinkageFilters())) {
for (ChartExtFilterRequest request : requestList.getLinkageFilters()) {
List<ChartExtFilterRequest> filters = new ArrayList<>();
// 联动条件
if(ObjectUtils.isNotEmpty(requestList.getLinkageFilters())){
filters.addAll(requestList.getLinkageFilters());
}
// 外部参数条件
if(ObjectUtils.isNotEmpty(requestList.getOuterParamsFilters())){
filters.addAll(requestList.getOuterParamsFilters());
}
//联动过滤条件和外部参数过滤条件全部加上
if (ObjectUtils.isNotEmpty(filters)) {
for (ChartExtFilterRequest request : filters) {
DatasetTableField datasetTableField = dataSetTableFieldsService.get(request.getFieldId());
if (!desensitizationList.contains(datasetTableField.getDataeaseName()) && dataeaseNames.contains(datasetTableField.getDataeaseName())) {
request.setDatasetTableField(datasetTableField);

View File

@ -5,15 +5,19 @@ import io.dataease.base.mapper.PanelOuterParamsMapper;
import io.dataease.base.mapper.PanelOuterParamsTargetViewInfoMapper;
import io.dataease.base.mapper.ext.ExtPanelOuterParamsMapper;
import io.dataease.dto.panel.linkJump.PanelLinkJumpDTO;
import io.dataease.dto.panel.outerParams.PanelOuterParamsBaseResponse;
import io.dataease.dto.panel.outerParams.PanelOuterParamsDTO;
import io.dataease.dto.panel.outerParams.PanelOuterParamsInfoDTO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* Author: wangjiahao
@ -67,4 +71,9 @@ public class PanelOuterParamsService {
});
}
public PanelOuterParamsBaseResponse getOuterParamsInfo(String panelId){
List<PanelOuterParamsInfoDTO> result = extPanelOuterParamsMapper.getPanelOuterParamsInfo(panelId);
return new PanelOuterParamsBaseResponse(Optional.ofNullable(result).orElse(new ArrayList<>()).stream().collect(Collectors.toMap(PanelOuterParamsInfoDTO::getSourceInfo, PanelOuterParamsInfoDTO::getTargetInfoList)));
}
}

View File

@ -32,6 +32,7 @@
const link = getQueryVariable('link')
const user = getQueryVariable('user')
const terminal = getQueryVariable('terminal')
const attachParams = getQueryVariable('attachParams')
let url = "/#/delink?link=" + encodeURIComponent(link)
if (terminal) {
url += '&terminal=' + terminal
@ -39,6 +40,9 @@
if (user) {
url += '&user=' + user
}
if (attachParams) {
url += '&attachParams=' + attachParams
}
window.location.href = url
</script>

View File

@ -7,8 +7,6 @@ export function queryWithPanelId(panelId) {
})
}
export function updateOuterParamsSet(requestInfo) {
return request({
url: '/outerParams/updateOuterParamsSet',
@ -17,3 +15,11 @@ export function updateOuterParamsSet(requestInfo) {
loading: true
})
}
export function getOuterParamsInfo(panelId) {
return request({
url: '/outerParams/getOuterParamsInfo/' + panelId,
method: 'get',
loading: true
})
}

View File

@ -9,6 +9,7 @@ import { uuid } from 'vue-uuid'
import { initPanelData } from '@/api/panel/panel'
import { queryTargetPanelJumpInfo } from '@/api/panel/linkJump'
import { proxyInitPanelData } from '@/api/panel/shareProxy'
import { getOuterParamsInfo } from '@/api/panel/outerParams'
export default {
components: { Preview },
@ -75,9 +76,33 @@ export default {
},
initCallBack() {
this.dataLoading = false
this.dataLoading = true
let loadingCount = 0
//
const tempParam = localStorage.getItem('jumpInfoParam')
//
const attachParamsEncode = this.$route.query.attachParams
tempParam && loadingCount++
attachParamsEncode && loadingCount++
if (attachParamsEncode) {
try {
const Base64 = require('js-base64').Base64
const attachParam = JSON.parse(Base64.decode(attachParamsEncode))
getOuterParamsInfo(this.panelId).then(rsp => {
if (--loadingCount === 0) {
this.dataLoading = false
}
this.$store.commit('setNowPanelOuterParamsInfo', rsp.data)
this.$store.commit('addOuterParamsFilter', attachParam)
})
} catch (e) {
if (--loadingCount === 0) {
this.dataLoading = false
}
console.log('outerParams Deocode error', e)
}
}
if (tempParam) {
localStorage.removeItem('jumpInfoParam')
const jumpParam = JSON.parse(tempParam)
@ -87,13 +112,24 @@ export default {
sourceFieldId: jumpParam.sourceFieldId,
targetPanelId: this.panelId
}
this.dataLoading = true
//
queryTargetPanelJumpInfo(jumpRequestParam).then(rsp => {
this.dataLoading = false
this.$store.commit('setNowTargetPanelJumpInfo', rsp.data)
this.$store.commit('addViewTrackFilter', jumpParam)
})
try {
//
queryTargetPanelJumpInfo(jumpRequestParam).then(rsp => {
if (--loadingCount === 0) {
this.dataLoading = false
}
this.$store.commit('setNowTargetPanelJumpInfo', rsp.data)
this.$store.commit('addViewTrackFilter', jumpParam)
})
} catch (e) {
if (--loadingCount === 0) {
this.dataLoading = false
}
console.log('queryTargetPanelJumpInfo error', e)
}
}
if (loadingCount === 0) {
this.dataLoading = false
}
},
resetID(data) {

View File

@ -213,6 +213,7 @@ export default {
const filter = {}
filter.filter = this.isFirstLoad ? this.filters : this.cfilters
filter.linkageFilters = this.element.linkageFilters
filter.outerParamsFilters = this.element.outerParamsFilters
filter.drill = this.drillClickDimensionList
filter.resultCount = this.resultCount
filter.resultMode = this.resultMode

View File

@ -1382,6 +1382,7 @@ export default {
sure_bt: 'Confirm'
},
panel: {
repeat_params: 'Repeat Params Exist',
enable_outer_param_set: 'Enable Outer Param Set',
select_param: 'Please Select Param...',
add_param_link_field: "Add Params' Linked Field",

View File

@ -1383,6 +1383,7 @@ export default {
sure_bt: '確定'
},
panel: {
repeat_params: '存在名称重复的参数',
enable_outer_param_set: '启用外部参数设置',
select_param: '请选择参数...',
add_param_link_field: '添加参数联动字段',

View File

@ -1391,6 +1391,7 @@ export default {
sure_bt: '确定'
},
panel: {
repeat_params: '存在名称重复的参数',
enable_outer_param_set: '启用外部参数设置',
select_param: '请选择参数...',
add_param_link_field: '添加参数联动字段',

View File

@ -79,6 +79,8 @@ const data = {
nowPanelJumpInfo: {},
// 当前仪表板的跳转信息(只包括仪表板)
nowPanelJumpInfoTargetPanel: {},
// 当前仪表板的外部参数信息
nowPanelOuterParamsInfo: {},
// 拖拽的组件信息
dragComponentInfo: null,
// 仪表板组件间隙大小 px
@ -293,6 +295,50 @@ const data = {
state.componentData[index] = element
}
},
// 添加外部参数的过滤条件
addOuterParamsFilter(state, params) {
// params 结构 {key1:value1,key2:value2}
if (params) {
const trackInfo = state.nowPanelOuterParamsInfo
for (let index = 0; index < state.componentData.length; index++) {
const element = state.componentData[index]
if (!element.type || element.type !== 'view') continue
const currentFilters = element.outerParamsFilters || [] // 外部参数信息
// 外部参数 可能会包含多个参数
Object.keys(params).forEach(function(sourceInfo) {
// 获取外部参数的值 sourceInfo 是外部参数名称
const paramValue = params[sourceInfo]
// 获取所有目标联动信息
const targetInfoList = trackInfo[sourceInfo] || []
targetInfoList.forEach(targetInfo => {
const targetInfoArray = targetInfo.split('#')
const targetViewId = targetInfoArray[0] // 目标视图
if (element.propValue.viewId === targetViewId) { // 如果目标视图 和 当前循环组件id相等 则进行条件增减
const targetFieldId = targetInfoArray[1] // 目标视图列ID
const condition = new Condition('', targetFieldId, 'eq', [paramValue], [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)
}
})
element.outerParamsFilters = currentFilters
state.componentData[index] = element
})
}
}
},
setComponentWithId(state, component) {
for (let index = 0; index < state.componentData.length; index++) {
const element = state.componentData[index]
@ -338,6 +384,9 @@ const data = {
setNowTargetPanelJumpInfo(state, jumpInfo) {
state.nowPanelJumpInfoTargetPanel = jumpInfo.baseJumpInfoPanelMap
},
setNowPanelOuterParamsInfo(state, outerParamsInfo) {
state.nowPanelOuterParamsInfo = outerParamsInfo.outerParamsInfoMap
},
clearPanelLinkageInfo(state) {
state.componentData.forEach(item => {
if (item.linkageFilters && item.linkageFilters.length > 0) {

View File

@ -0,0 +1,11 @@
export function checkRepeat(arrayData, key) {
for (let i = 0; i < arrayData.length; i++) {
for (let j = i + 1; j < arrayData.length; j++) {
if (arrayData[i][key] === arrayData[j][key]) {
return true
}
}
}
return false
}

View File

@ -11,6 +11,7 @@ import Preview from '@/components/canvas/components/Editor/Preview'
import { getPanelAllLinkageInfo } from '@/api/panel/linkage'
import { queryPanelJumpInfo, queryTargetPanelJumpInfo } from '@/api/panel/linkJump'
import { panelInit } from '@/components/canvas/utils/utils'
import { getOuterParamsInfo } from '@/api/panel/outerParams'
export default {
name: 'LinkView',
@ -37,6 +38,8 @@ export default {
methods: {
setPanelInfo() {
loadResource(this.resourceId).then(res => {
this.show = false
let loadingCount = 0
this.$store.dispatch('panel/setPanelInfo', {
id: res.data.id,
name: res.data.name,
@ -54,25 +57,59 @@ export default {
queryPanelJumpInfo(this.resourceId).then(rsp => {
this.$store.commit('setNowPanelJumpInfo', rsp.data)
})
//
const tempParam = localStorage.getItem('jumpInfoParam')
if (tempParam) {
localStorage.removeItem('jumpInfoParam')
const jumpParam = JSON.parse(tempParam)
const jumpRequestParam = {
sourcePanelId: jumpParam.sourcePanelId,
sourceViewId: jumpParam.sourceViewId,
sourceFieldId: jumpParam.sourceFieldId,
targetPanelId: this.resourceId
//
const attachParamsEncode = this.$route.query.attachParams
tempParam && loadingCount++
attachParamsEncode && loadingCount++
if (attachParamsEncode) {
try {
const Base64 = require('js-base64').Base64
const attachParam = JSON.parse(Base64.decode(attachParamsEncode))
getOuterParamsInfo(this.resourceId).then(rsp => {
if (--loadingCount === 0) {
this.show = true
}
this.$store.commit('setNowPanelOuterParamsInfo', rsp.data)
this.$store.commit('addOuterParamsFilter', attachParam)
})
} catch (e) {
if (--loadingCount === 0) {
this.show = true
}
console.log('outerParams Decode error', e)
}
this.show = false
//
queryTargetPanelJumpInfo(jumpRequestParam).then(rsp => {
this.show = true
this.$store.commit('setNowTargetPanelJumpInfo', rsp.data)
this.$store.commit('addViewTrackFilter', jumpParam)
})
} else {
}
if (tempParam) {
try {
localStorage.removeItem('jumpInfoParam')
const jumpParam = JSON.parse(tempParam)
const jumpRequestParam = {
sourcePanelId: jumpParam.sourcePanelId,
sourceViewId: jumpParam.sourceViewId,
sourceFieldId: jumpParam.sourceFieldId,
targetPanelId: this.resourceId
}
//
queryTargetPanelJumpInfo(jumpRequestParam).then(rsp => {
this.show = true
this.$store.commit('setNowTargetPanelJumpInfo', rsp.data)
this.$store.commit('addViewTrackFilter', jumpParam)
})
} catch (e) {
if (--loadingCount === 0) {
this.show = true
}
console.log('tempParam error', e)
}
}
if (loadingCount === 0) {
this.show = true
}
})

View File

@ -173,6 +173,7 @@ import { mapState } from 'vuex'
import { queryWithPanelId, updateOuterParamsSet } from '@/api/panel/outerParams'
import { uuid } from 'vue-uuid'
import { deepCopy } from '@/components/canvas/utils/utils'
import { checkRepeat } from '@/utils/check'
export default {
name: 'OuterParamsSet',
@ -258,9 +259,17 @@ export default {
this.$emit('outerParamsSetVisibleChange', false)
},
save() {
if (checkRepeat(this.outerParams.outerParamsInfoArray, 'name')) {
this.$message({
message: this.$t('panel.repeat_params'),
type: 'warn',
showClose: true
})
return
}
updateOuterParamsSet(this.outerParams).then(rsp => {
this.$message({
message: '保存成功',
message: this.$t('commons.save_success'),
type: 'success',
showClose: true
})
@ -329,6 +338,10 @@ export default {
const children = parent.data.children || parent.data
const index = children.findIndex(d => d.paramsInfoId === data.paramsInfoId)
children.splice(index, 1)
if (data.paramsInfoId === this.outerParamsInfo.paramsInfoId) {
delete this.mapOuterParamsInfoArray[data.paramsInfoId]
this.outerParamsInfo = null
}
}
}
}