forked from github/dataease
Merge pull request #6658 from dataease/pr@dev@refactor_template-market
refactor: 模版市场优化
This commit is contained in:
commit
b9e38d3717
@ -6,10 +6,12 @@ import io.dataease.api.chart.dto.ChartViewDTO;
|
||||
import io.dataease.api.chart.dto.ViewDetailField;
|
||||
import io.dataease.api.chart.request.ChartExcelRequest;
|
||||
import io.dataease.chart.manage.ChartDataManage;
|
||||
import io.dataease.constant.CommonConstants;
|
||||
import io.dataease.engine.constant.DeTypeConstants;
|
||||
import io.dataease.exception.DEException;
|
||||
import io.dataease.result.ResultCode;
|
||||
import io.dataease.utils.LogUtil;
|
||||
import io.dataease.visualization.manage.VisualizationTemplateExtendDataManage;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
@ -41,10 +43,18 @@ public class ChartDataServer implements ChartDataApi {
|
||||
@Resource
|
||||
private ChartDataManage chartDataManage;
|
||||
|
||||
@Resource
|
||||
private VisualizationTemplateExtendDataManage extendDataManage;
|
||||
|
||||
@Override
|
||||
public ChartViewDTO getData(ChartViewDTO chartViewDTO) throws Exception {
|
||||
try {
|
||||
return chartDataManage.calcData(chartViewDTO);
|
||||
// 从模版数据获取
|
||||
if(CommonConstants.VIEW_DATA_FROM.TEMPLATE.equalsIgnoreCase(chartViewDTO.getDataFrom())){
|
||||
return extendDataManage.getChartDataInfo(chartViewDTO.getId(),chartViewDTO);
|
||||
}else{
|
||||
return chartDataManage.calcData(chartViewDTO);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
DEException.throwException(ResultCode.DATA_IS_WRONG.code(), e.getMessage());
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ public class MenuManage {
|
||||
return convertTree(treeNodes);
|
||||
}
|
||||
|
||||
@Cacheable(cacheNames = CORE_MENU_CACHE, key = "'-dataease-'")
|
||||
// @Cacheable(cacheNames = CORE_MENU_CACHE, key = "'-dataease-'")
|
||||
public List<CoreMenu> coreMenus() {
|
||||
QueryWrapper<CoreMenu> wrapper = new QueryWrapper<>();
|
||||
wrapper.orderByAsc("menu_sort");
|
||||
|
@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
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.request.DataVisualizationBaseRequest;
|
||||
import io.dataease.api.visualization.request.VisualizationWorkbranchQueryRequest;
|
||||
@ -20,6 +21,8 @@ import io.dataease.license.config.XpackInteract;
|
||||
import io.dataease.model.BusiNodeRequest;
|
||||
import io.dataease.model.BusiNodeVO;
|
||||
import io.dataease.template.dao.auto.entity.VisualizationTemplate;
|
||||
import io.dataease.template.dao.auto.entity.VisualizationTemplateExtendData;
|
||||
import io.dataease.template.dao.auto.mapper.VisualizationTemplateExtendDataMapper;
|
||||
import io.dataease.template.dao.auto.mapper.VisualizationTemplateMapper;
|
||||
import io.dataease.template.manage.TemplateMarketManage;
|
||||
import io.dataease.utils.AuthUtils;
|
||||
@ -73,6 +76,9 @@ public class DataVisualizationServer implements DataVisualizationApi {
|
||||
@Resource
|
||||
private StaticResourceServer staticResourceServer;
|
||||
|
||||
@Resource
|
||||
private VisualizationTemplateExtendDataMapper templateExtendDataMapper;
|
||||
|
||||
|
||||
@Override
|
||||
@XpackInteract(value = "dataVisualizationServer", original = true)
|
||||
@ -256,7 +262,7 @@ public class DataVisualizationServer implements DataVisualizationApi {
|
||||
Map<String, String> dynamicDataMap = JsonUtil.parseObject(dynamicData, Map.class);
|
||||
List<ChartViewDTO> chartViews = new ArrayList<>();
|
||||
Map<Long,ChartViewDTO> canvasViewInfo = new HashMap<>();
|
||||
// List<PanelGroupExtendDataDTO> viewsData = new ArrayList<>();
|
||||
Map<Long,VisualizationTemplateExtendDataDTO> extendDataInfo = new HashMap<>();
|
||||
for (Map.Entry<String, String> entry : dynamicDataMap.entrySet()) {
|
||||
String originViewId = entry.getKey();
|
||||
String originViewData = entry.getValue();
|
||||
@ -265,17 +271,21 @@ public class DataVisualizationServer implements DataVisualizationApi {
|
||||
chartView.setId(newViewId);
|
||||
chartView.setSceneId(newDvId);
|
||||
chartView.setDataFrom(CommonConstants.VIEW_DATA_FROM.TEMPLATE);
|
||||
// 数据处理 1.替换viewId 2.加入panelView 数据(数据来源为template) 3.加入模板view data数据
|
||||
// viewsData.add(new PanelGroupExtendDataDTO(newPanelId, newViewId, originViewData));
|
||||
// 数据处理 1.替换viewId 2.加入模板view data数据
|
||||
VisualizationTemplateExtendDataDTO extendDataDTO = new VisualizationTemplateExtendDataDTO(newViewId, newDvId,originViewData);
|
||||
extendDataInfo.put(newViewId, extendDataDTO);
|
||||
templateData = templateData.replaceAll(originViewId, newViewId.toString());
|
||||
chartViewManege.save(chartView);
|
||||
canvasViewInfo.put(chartView.getId(),chartView);
|
||||
//插入模版数据 此处预先插入减少数据交互量
|
||||
VisualizationTemplateExtendData extendData = new VisualizationTemplateExtendData();
|
||||
templateExtendDataMapper.insert(BeanUtils.copyBean(extendData,extendDataDTO));
|
||||
}
|
||||
request.setComponentData(templateData);
|
||||
request.setCanvasStyleData(templateStyle);
|
||||
//Store static resource into the server
|
||||
staticResourceServer.saveFilesToServe(staticResource);
|
||||
return new DataVisualizationVO(newDvId,name,dvType,templateStyle,templateData,canvasViewInfo);
|
||||
return new DataVisualizationVO(newDvId,name,dvType,templateStyle,templateData,canvasViewInfo,null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -67,3 +67,5 @@ export const storeApi = (data): Promise<IResponse> => {
|
||||
export const storeStatusApi = (id: string): Promise<IResponse> => {
|
||||
return request.get({ url: `/store/favorited/${id}` })
|
||||
}
|
||||
|
||||
export const decompression = data => request.post({ url: '/dataVisualization/decompression', data })
|
||||
|
239
core/core-frontend/src/views/common/DeResourceCreateOpt.vue
Normal file
239
core/core-frontend/src/views/common/DeResourceCreateOpt.vue
Normal file
@ -0,0 +1,239 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
class="create-dialog"
|
||||
title="从模版新建"
|
||||
v-model="state.dialogShow"
|
||||
width="600"
|
||||
:before-close="close"
|
||||
@submit.prevent
|
||||
>
|
||||
<el-row v-loading="state.loading">
|
||||
<el-row>
|
||||
<el-col :span="18" style="height: 40px">
|
||||
<el-radio v-model="state.inputType" label="new_outer_template"
|
||||
>{{ t('visualization.import_template') }}
|
||||
</el-radio>
|
||||
<el-radio v-model="state.inputType" label="new_inner_template" @click="getTree"
|
||||
>{{ t('visualization.copy_template') }}
|
||||
</el-radio>
|
||||
</el-col>
|
||||
<el-col v-if="state.inputType === 'new_outer_template'" :span="6">
|
||||
<el-button class="el-icon-upload" size="small" type="primary" @click="goFile"
|
||||
>{{ t('visualization.upload_template') }}
|
||||
</el-button>
|
||||
<input
|
||||
id="input"
|
||||
ref="files"
|
||||
type="file"
|
||||
accept=".DET"
|
||||
hidden
|
||||
@change="handleFileChange"
|
||||
/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row style="margin-top: 5px">
|
||||
<el-col :span="4">{{ state.titleSuf }}{{ t('commons.name') }}</el-col>
|
||||
<el-col :span="20">
|
||||
<el-input v-model="state.dvCreateInfo.name" clearable size="mini" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row v-if="state.inputType === 'new_inner_template'" class="preview">
|
||||
<el-col :span="8" style="height: 100%; overflow-y: auto">
|
||||
<template-all-list
|
||||
:template-list="state.templateList"
|
||||
@showCurrentTemplateInfo="showCurrentTemplateInfo"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :span="16" :style="classBackground" class="preview-show" />
|
||||
</el-row>
|
||||
<el-row
|
||||
v-if="state.inputType === 'new_outer_template'"
|
||||
class="preview"
|
||||
:style="classBackground"
|
||||
/>
|
||||
<el-row class="root-class">
|
||||
<el-button size="mini" @click="cancel()">{{ t('commons.cancel') }} </el-button>
|
||||
<el-button type="primary" size="mini" :disabled="!saveStatus" @click="save()"
|
||||
>{{ t('commons.confirm') }}
|
||||
</el-button>
|
||||
</el-row>
|
||||
</el-row>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { showTemplateList } from '@/api/template'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { computed, reactive, ref } from 'vue'
|
||||
import { imgUrlTrans } from '@/utils/imgUtils'
|
||||
import { watch } from 'vue/dist/vue'
|
||||
import { ElMessage } from 'element-plus-secondary'
|
||||
import { decompression } from '@/api/visualization/dataVisualization'
|
||||
const { t } = useI18n()
|
||||
const emits = defineEmits(['closeEditPanelDialog'])
|
||||
const files = ref(null)
|
||||
const props = defineProps({
|
||||
editPanelOut: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
const state = reactive({
|
||||
dialogShow: false,
|
||||
loading: false,
|
||||
inputType: 'new_outer_template',
|
||||
fieldName: 'name',
|
||||
tableRadio: null,
|
||||
keyWordSearch: '',
|
||||
columnLabel: t('visualization.belong_to_category'),
|
||||
templateList: [],
|
||||
importTemplateInfo: {
|
||||
snapshot: ''
|
||||
},
|
||||
dvCreateInfo: {
|
||||
name:null,
|
||||
canvasStyleData: null,
|
||||
componentData: null,
|
||||
templateId: null,
|
||||
dynamicData: null,
|
||||
staticResource: null
|
||||
},
|
||||
templateSelected: false
|
||||
})
|
||||
|
||||
const saveStatus = computed(() => {
|
||||
return state.dvCreateInfo.name && state.templateSelected
|
||||
})
|
||||
|
||||
const classBackground = computed(() => {
|
||||
if (state.importTemplateInfo.snapshot) {
|
||||
return {
|
||||
background: `url(${imgUrlTrans(state.importTemplateInfo.snapshot)}) no-repeat`
|
||||
}
|
||||
} else {
|
||||
return {}
|
||||
}
|
||||
})
|
||||
|
||||
watch(
|
||||
() => state.inputType,
|
||||
val => {
|
||||
state.templateSelected = false
|
||||
state.dvCreateInfo.name = null
|
||||
state.dvCreateInfo.canvasStyleData = null
|
||||
state.dvCreateInfo.componentData = null
|
||||
state.importTemplateInfo.snapshot = null
|
||||
state.dvCreateInfo.templateId = null
|
||||
}
|
||||
)
|
||||
|
||||
const showCurrentTemplateInfo = data => {
|
||||
state.dvCreateInfo.templateId = data.id
|
||||
if (data.nodeType === 'folder') {
|
||||
state.dvCreateInfo.name = null
|
||||
state.importTemplateInfo.snapshot = null
|
||||
state.templateSelected = false
|
||||
} else {
|
||||
state.dvCreateInfo.name = data.name
|
||||
state.importTemplateInfo.snapshot = data.snapshot
|
||||
state.templateSelected = true
|
||||
}
|
||||
}
|
||||
|
||||
const getTree = () => {
|
||||
const request = {
|
||||
level: '-1',
|
||||
withChildren: true
|
||||
}
|
||||
state.loading = true
|
||||
showTemplateList(request).then(res => {
|
||||
state.templateList = res.data
|
||||
state.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
const cancel = () => {
|
||||
emits('closeEditPanelDialog')
|
||||
}
|
||||
|
||||
const save = () => {
|
||||
if (!state.dvCreateInfo.name) {
|
||||
ElMessage.warning(t('common.save_success'))
|
||||
return false
|
||||
}
|
||||
|
||||
if (state.dvCreateInfo.name.length > 50) {
|
||||
ElMessage.warning(t('common.char_can_not_more_50'))
|
||||
return false
|
||||
}
|
||||
|
||||
if (
|
||||
!state.dvCreateInfo.templateId &&
|
||||
state.inputType === 'new_inner_template'
|
||||
) {
|
||||
ElMessage.warning('chart.template_can_not_empty')
|
||||
return false
|
||||
}
|
||||
state.dvCreateInfo['newFrom'] = state.inputType
|
||||
state.loading = true
|
||||
decompression(state.dvCreateInfo)
|
||||
.then(response => {
|
||||
state.loading = false
|
||||
emits('closeEditPanelDialog', response.data)
|
||||
})
|
||||
.catch(() => {
|
||||
state.loading = false
|
||||
})
|
||||
}
|
||||
const handleFileChange = e => {
|
||||
const file = e.target.files[0]
|
||||
const reader = new FileReader()
|
||||
reader.onload = res => {
|
||||
state.templateSelected = true
|
||||
const result = res.target.result
|
||||
state.importTemplateInfo = JSON.parse(result)
|
||||
state.dvCreateInfo.name = state.importTemplateInfo['name'].name
|
||||
state.dvCreateInfo.canvasStyleData = state.importTemplateInfo['canvasStyleData']
|
||||
state.dvCreateInfo.componentData = state.importTemplateInfo['componentData']
|
||||
state.dvCreateInfo.dynamicData = state.importTemplateInfo['dynamicData']
|
||||
state.dvCreateInfo.staticResource = state.importTemplateInfo['staticResource']
|
||||
}
|
||||
reader.readAsText(file)
|
||||
}
|
||||
const goFile = () => {
|
||||
files.value.files.click()
|
||||
}
|
||||
|
||||
const close = () ={
|
||||
// do close
|
||||
}
|
||||
const optInit = () =>{
|
||||
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
optInit
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.root-class {
|
||||
margin: 15px 0px 5px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.preview {
|
||||
margin-top: 5px;
|
||||
border: 1px solid #e6e6e6;
|
||||
height: 250px !important;
|
||||
overflow: hidden;
|
||||
background-size: 100% 100% !important;
|
||||
}
|
||||
|
||||
.preview-show {
|
||||
border-left: 1px solid #e6e6e6;
|
||||
height: 250px;
|
||||
background-size: 100% 100% !important;
|
||||
}
|
||||
</style>
|
@ -102,6 +102,11 @@ state.resourceTypeList = [
|
||||
svgName: curCanvasType.value === 'dashboard' ? 'dv-dashboard-spine' : 'dv-screen-spine',
|
||||
command: 'newLeaf'
|
||||
},
|
||||
{
|
||||
label: '从模版新建',
|
||||
svgName: curCanvasType.value === 'dashboard' ? 'dv-dashboard-spine' : 'dv-screen-spine',
|
||||
command: 'newFromTemplate'
|
||||
},
|
||||
{
|
||||
label: '新建文件夹',
|
||||
divided: true,
|
||||
@ -236,6 +241,9 @@ const addOperation = (
|
||||
} else {
|
||||
window.open(baseUrl, '_blank')
|
||||
}
|
||||
} else if(cmd === 'newFromTemplate') {
|
||||
// newFromTemplate
|
||||
|
||||
} else {
|
||||
resourceGroupOpt.value.optInit(nodeType, data || {}, cmd, parentSelect)
|
||||
}
|
||||
|
95
core/core-frontend/src/views/common/DeTemplateList.vue
Normal file
95
core/core-frontend/src/views/common/DeTemplateList.vue
Normal file
@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<el-col>
|
||||
<el-row style="margin-top: 5px">
|
||||
<el-row>
|
||||
<el-input
|
||||
v-model="state.templateFilterText"
|
||||
:placeholder="t('visualization.filter_keywords')"
|
||||
size="mini"
|
||||
clearable
|
||||
prefix-icon="el-icon-search"
|
||||
/>
|
||||
</el-row>
|
||||
<el-row style="margin-top: 5px">
|
||||
<el-tree
|
||||
ref="templateTree"
|
||||
:default-expanded-keys="state.defaultExpandedKeys"
|
||||
:data="templateList"
|
||||
node-key="id"
|
||||
:expand-on-click-node="true"
|
||||
:filter-node-method="filterNode"
|
||||
:highlight-current="true"
|
||||
@node-click="nodeClick"
|
||||
>
|
||||
<template #default="{ data }">
|
||||
<span class="custom-tree-node">
|
||||
<span style="display: flex; flex: 1 1 0%; width: 0px">
|
||||
<span v-if="data.nodeType === 'template'">
|
||||
<svg-icon icon-class="panel" class="ds-icon-scene" />
|
||||
</span>
|
||||
<span v-if="data.nodeType === 'folder'">
|
||||
<i class="el-icon-folder" />
|
||||
</span>
|
||||
<span
|
||||
:title="data.name"
|
||||
style="
|
||||
margin-left: 6px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
"
|
||||
>{{ data.name }}</span
|
||||
>
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
</el-tree>
|
||||
</el-row>
|
||||
</el-row>
|
||||
</el-col>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { findOne } from '@/api/template'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { reactive } from 'vue'
|
||||
const { t } = useI18n()
|
||||
const emits = defineEmits(['showCurrentTemplateInfo'])
|
||||
|
||||
const props = defineProps({
|
||||
templateList: {
|
||||
type: Array,
|
||||
default: function () {
|
||||
return []
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const state = reactive({
|
||||
templateFilterText: '',
|
||||
defaultExpandedKeys: [],
|
||||
currentTemplateShowList: []
|
||||
})
|
||||
|
||||
const filterNode = (value, data) => {
|
||||
if (!value) return true
|
||||
return data.label.indexOf(value) !== -1
|
||||
}
|
||||
|
||||
const nodeClick = (data, node) => {
|
||||
findOne(data.id).then(res => {
|
||||
emits('showCurrentTemplateInfo', res.data)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.custom-tree-node {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 14px;
|
||||
padding-right: 8px;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,26 @@
|
||||
package io.dataease.api.template.dto;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import io.dataease.api.template.vo.VisualizationTemplateExtendDataVO;
|
||||
import io.dataease.utils.IDUtils;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author : WangJiaHao
|
||||
* @date : 2023/11/13 10:25
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class VisualizationTemplateExtendDataDTO extends VisualizationTemplateExtendDataVO {
|
||||
|
||||
|
||||
public VisualizationTemplateExtendDataDTO(Long dvId, Long viewId, String viewDetails) {
|
||||
super();
|
||||
super.setId(IDUtils.snowID());
|
||||
super.setDvId(dvId);
|
||||
super.setViewId(viewId);
|
||||
super.setViewDetails(viewDetails);
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package io.dataease.api.template.vo;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author : WangJiaHao
|
||||
* @date : 2023/11/13 10:25
|
||||
*/
|
||||
@Data
|
||||
public class VisualizationTemplateExtendDataVO {
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long id;
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long dvId;
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long viewId;
|
||||
|
||||
private String viewDetails;
|
||||
|
||||
private String copyFrom;
|
||||
|
||||
private String copyId;
|
||||
|
||||
}
|
@ -3,6 +3,7 @@ package io.dataease.api.visualization.vo;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import io.dataease.api.chart.dto.ChartViewDTO;
|
||||
import io.dataease.api.template.dto.VisualizationTemplateExtendDataDTO;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@ -13,7 +14,7 @@ import java.util.Map;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class DataVisualizationVO implements Serializable {
|
||||
public class DataVisualizationVO implements Serializable {
|
||||
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long id;
|
||||
@ -121,14 +122,20 @@ public class DataVisualizationVO implements Serializable {
|
||||
/**
|
||||
* 视图基本信息
|
||||
*/
|
||||
private Map<Long,ChartViewDTO> canvasViewInfo = new HashMap<>();
|
||||
private Map<Long, ChartViewDTO> canvasViewInfo = new HashMap<>();
|
||||
|
||||
public DataVisualizationVO(Long id, String name, String type, String canvasStyleData, String componentData, Map<Long,ChartViewDTO> canvasViewInfo) {
|
||||
/**
|
||||
* 视图模版数据
|
||||
*/
|
||||
private Map<Long, VisualizationTemplateExtendDataDTO> extendDataInfo = new HashMap<>();
|
||||
|
||||
public DataVisualizationVO(Long id, String name, String type, String canvasStyleData, String componentData, Map<Long, ChartViewDTO> canvasViewInfo, Map<Long, VisualizationTemplateExtendDataDTO> extendDataInfo) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.canvasStyleData = canvasStyleData;
|
||||
this.componentData = componentData;
|
||||
this.canvasViewInfo = canvasViewInfo;
|
||||
this.extendDataInfo = extendDataInfo;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user