diff --git a/core/core-backend/pom.xml b/core/core-backend/pom.xml index 202a279ec8..30230151fe 100644 --- a/core/core-backend/pom.xml +++ b/core/core-backend/pom.xml @@ -92,6 +92,10 @@ + + com.h2database + h2 + diff --git a/core/core-backend/src/main/java/io/dataease/commons/constants/DataVisualizationConstants.java b/core/core-backend/src/main/java/io/dataease/commons/constants/DataVisualizationConstants.java index 25acbfd475..19cc6e310c 100644 --- a/core/core-backend/src/main/java/io/dataease/commons/constants/DataVisualizationConstants.java +++ b/core/core-backend/src/main/java/io/dataease/commons/constants/DataVisualizationConstants.java @@ -51,5 +51,13 @@ public class DataVisualizationConstants { public static final String COPY = "copy"; } + public static final class TEMPLATE_SOURCE { + //模板市场 + public static final String MARKET = "market"; + //模板管理 + public static final String MANAGE = "manage"; + //公共 + public static final String PUBLIC = "public"; + } } diff --git a/core/core-backend/src/main/java/io/dataease/template/manage/TemplateCenterManage.java b/core/core-backend/src/main/java/io/dataease/template/manage/TemplateCenterManage.java index 451e4c08d6..31b9bc83b9 100644 --- a/core/core-backend/src/main/java/io/dataease/template/manage/TemplateCenterManage.java +++ b/core/core-backend/src/main/java/io/dataease/template/manage/TemplateCenterManage.java @@ -1,5 +1,6 @@ package io.dataease.template.manage; +import com.mysql.cj.log.Log; import io.dataease.api.template.dto.TemplateManageDTO; import io.dataease.api.template.dto.TemplateManageFileDTO; import io.dataease.api.template.dto.TemplateMarketDTO; @@ -8,6 +9,7 @@ import io.dataease.api.template.response.*; import io.dataease.api.template.vo.MarketApplicationSpecVO; import io.dataease.api.template.vo.MarketMetaDataVO; import io.dataease.api.template.vo.TemplateCategoryVO; +import io.dataease.constant.CommonConstants; import io.dataease.exception.DEException; import io.dataease.operation.manage.CoreOptRecentManage; import io.dataease.system.manage.SysParameterManage; @@ -71,9 +73,14 @@ public class TemplateCenterManage { } private MarketTemplateV2BaseResponse templateQuery(Map templateParams) { - String result = marketGet(templateParams.get("template.url") + POSTS_API_V2, null); - MarketTemplateV2BaseResponse postsResult = JsonUtil.parseObject(result, MarketTemplateV2BaseResponse.class); - return postsResult; + try { + String result = marketGet(templateParams.get("template.url") + POSTS_API_V2, null); + MarketTemplateV2BaseResponse postsResult = JsonUtil.parseObject(result, MarketTemplateV2BaseResponse.class); + return postsResult; + } catch (Exception e) { + LogUtil.error(e); + return null; + } } public MarketBaseResponse searchTemplate() { @@ -81,7 +88,7 @@ public class TemplateCenterManage { Map templateParams = sysParameterManage.groupVal("template."); return baseResponseV2Trans(templateQuery(templateParams), searchTemplateFromManage(), templateParams.get("template.url")); } catch (Exception e) { - DEException.throwException(e); + LogUtil.error(e); } return null; } @@ -124,7 +131,7 @@ public class TemplateCenterManage { Map templateParams = sysParameterManage.groupVal("template."); return basePreviewResponseV2Trans(templateQuery(templateParams), searchTemplateFromManage(), templateParams.get("template.url")); } catch (Exception e) { - DEException.throwException(e); + LogUtil.error(e); } return null; } @@ -133,12 +140,14 @@ public class TemplateCenterManage { Map useTime = coreOptRecentManage.findTemplateRecentUseTime(); Map categoriesMap = getCategoriesBaseV2(); List contents = new ArrayList<>(); - v2BaseResponse.getItems().stream().forEach(marketTemplateV2ItemResult -> { - MarketApplicationSpecVO spec = marketTemplateV2ItemResult.getApplication().getSpec(); - if ("Y".equalsIgnoreCase(spec.getSuggest())) { - contents.add(new TemplateMarketDTO(spec.getReadmeName(), spec.getDisplayName(), spec.getScreenshots().get(0).getUrl(), spec.getLinks().get(0).getUrl(), categoriesMap.get(spec.getLabel()), spec.getTemplateType(), useTime.get(spec.getReadmeName()), "Y")); - } - }); + if (v2BaseResponse != null) { + v2BaseResponse.getItems().stream().forEach(marketTemplateV2ItemResult -> { + MarketApplicationSpecVO spec = marketTemplateV2ItemResult.getApplication().getSpec(); + if ("Y".equalsIgnoreCase(spec.getSuggest())) { + contents.add(new TemplateMarketDTO(spec.getReadmeName(), spec.getDisplayName(), spec.getScreenshots().get(0).getUrl(), spec.getLinks().get(0).getUrl(), categoriesMap.get(spec.getLabel()), spec.getTemplateType(), useTime.get(spec.getReadmeName()), "Y")); + } + }); + } // 最近使用排序 Collections.sort(contents); return new MarketBaseResponse(url, contents); @@ -147,10 +156,16 @@ public class TemplateCenterManage { private MarketBaseResponse baseResponseV2Trans(MarketTemplateV2BaseResponse v2BaseResponse, List contents, String url) { Map useTime = coreOptRecentManage.findTemplateRecentUseTime(); Map categoriesMap = getCategoriesBaseV2(); - v2BaseResponse.getItems().stream().forEach(marketTemplateV2ItemResult -> { - MarketApplicationSpecVO spec = marketTemplateV2ItemResult.getApplication().getSpec(); - contents.add(new TemplateMarketDTO(spec.getReadmeName(), spec.getDisplayName(), spec.getScreenshots().get(0).getUrl(), spec.getLinks().get(0).getUrl(), categoriesMap.get(spec.getLabel()), spec.getTemplateType(), useTime.get(spec.getReadmeName()), spec.getSuggest())); + contents.stream().forEach(templateMarketDTO -> { + Long recentUseTime = useTime.get(templateMarketDTO.getId()); + templateMarketDTO.setRecentUseTime(recentUseTime == null ? 0 : recentUseTime); }); + if (v2BaseResponse != null) { + v2BaseResponse.getItems().stream().forEach(marketTemplateV2ItemResult -> { + MarketApplicationSpecVO spec = marketTemplateV2ItemResult.getApplication().getSpec(); + contents.add(new TemplateMarketDTO(spec.getReadmeName(), spec.getDisplayName(), spec.getScreenshots().get(0).getUrl(), spec.getLinks().get(0).getUrl(), categoriesMap.get(spec.getLabel()), spec.getTemplateType(), useTime.get(spec.getReadmeName()), spec.getSuggest())); + }); + } // 最近使用排序 Collections.sort(contents); return new MarketBaseResponse(url, contents); @@ -167,12 +182,14 @@ public class TemplateCenterManage { categoriesMap.forEach((key, value) -> { if (!"全部".equalsIgnoreCase(value)) { List contents = new ArrayList<>(); - v2BaseResponse.getItems().stream().forEach(marketTemplateV2ItemResult -> { - MarketApplicationSpecVO spec = marketTemplateV2ItemResult.getApplication().getSpec(); - if (key.equalsIgnoreCase(spec.getLabel())) { - contents.add(new TemplateMarketDTO(spec.getReadmeName(), spec.getDisplayName(), spec.getScreenshots().get(0).getUrl(), spec.getLinks().get(0).getUrl(), categoriesMap.get(spec.getLabel()), spec.getTemplateType(), useTime.get(spec.getReadmeName()), spec.getSuggest())); - } - }); + if (v2BaseResponse != null) { + v2BaseResponse.getItems().stream().forEach(marketTemplateV2ItemResult -> { + MarketApplicationSpecVO spec = marketTemplateV2ItemResult.getApplication().getSpec(); + if (key.equalsIgnoreCase(spec.getLabel())) { + contents.add(new TemplateMarketDTO(spec.getReadmeName(), spec.getDisplayName(), spec.getScreenshots().get(0).getUrl(), spec.getLinks().get(0).getUrl(), categoriesMap.get(spec.getLabel()), spec.getTemplateType(), useTime.get(spec.getReadmeName()), spec.getSuggest())); + } + }); + } manageContents.stream().forEach(templateMarketDTO -> { if (value.equalsIgnoreCase(templateMarketDTO.getMainCategory())) { contents.add(templateMarketDTO); @@ -194,8 +211,7 @@ public class TemplateCenterManage { public List getCategoriesObject() { List result = getCategoriesV2(); - result.add(0, new MarketMetaDataVO("suggest", "推荐")); - result.add(0, new MarketMetaDataVO("recent", "最近使用")); + result.add(0, new MarketMetaDataVO("recent", "最近使用", "public")); return result; } @@ -209,13 +225,14 @@ public class TemplateCenterManage { List allCategories = new ArrayList<>(); List manageCategories = templateManageMapper.findBaseTemplateList("folder"); List manageCategoriesTrans = manageCategories.stream() - .map(templateCategory -> new MarketMetaDataVO(templateCategory.getId(), templateCategory.getName())) + .map(templateCategory -> new MarketMetaDataVO(templateCategory.getId(), templateCategory.getName(), CommonConstants.TEMPLATE_SOURCE.MANAGE)) .collect(Collectors.toList()); try { Map templateParams = sysParameterManage.groupVal("template."); String resultStr = marketGet(templateParams.get("template.url") + TEMPLATE_META_DATA_URL, null); MarketMetaDataBaseResponse metaData = JsonUtil.parseObject(resultStr, MarketMetaDataBaseResponse.class); allCategories.addAll(metaData.getLabels()); + allCategories.add(0, new MarketMetaDataVO("suggest", "推荐")); } catch (Exception e) { LogUtil.error("模板市场分类获取错误", e); } diff --git a/core/core-backend/src/main/java/io/dataease/visualization/server/DataVisualizationServer.java b/core/core-backend/src/main/java/io/dataease/visualization/server/DataVisualizationServer.java index 188a83c7d4..ba43f7c297 100644 --- a/core/core-backend/src/main/java/io/dataease/visualization/server/DataVisualizationServer.java +++ b/core/core-backend/src/main/java/io/dataease/visualization/server/DataVisualizationServer.java @@ -242,6 +242,8 @@ public class DataVisualizationServer implements DataVisualizationApi { dynamicData = visualizationTemplate.getDynamicData(); name = visualizationTemplate.getName(); dvType = visualizationTemplate.getDvType(); + // 模板市场记录 + coreOptRecentManage.saveOpt(request.getTemplateId(), OptConstants.OPT_RESOURCE_TYPE.TEMPLATE,OptConstants.OPT_TYPE.NEW); } else if (DataVisualizationConstants.NEW_PANEL_FROM.NEW_OUTER_TEMPLATE.equals(newFrom)) { templateStyle = request.getCanvasStyleData(); templateData = request.getComponentData(); diff --git a/core/core-frontend/src/views/common/DeResourceTree.vue b/core/core-frontend/src/views/common/DeResourceTree.vue index 2c42687aad..c77beb8d63 100644 --- a/core/core-frontend/src/views/common/DeResourceTree.vue +++ b/core/core-frontend/src/views/common/DeResourceTree.vue @@ -450,17 +450,17 @@ defineExpose({ @finish="resourceOptFinish" ref="resourceGroupOpt" /> - - - + - + + + diff --git a/core/core-frontend/src/views/template-market/component/MarketPreviewV2.vue b/core/core-frontend/src/views/template-market/component/MarketPreviewV2.vue index 9ad45f6d98..4a936cd2f9 100644 --- a/core/core-frontend/src/views/template-market/component/MarketPreviewV2.vue +++ b/core/core-frontend/src/views/template-market/component/MarketPreviewV2.vue @@ -98,7 +98,6 @@ {{ t('visualization.apply_this_template') }} diff --git a/core/core-frontend/src/views/template-market/component/TemplateMarketV2Item.vue b/core/core-frontend/src/views/template-market/component/TemplateMarketV2Item.vue index bfac0cc847..e0d32eeff3 100644 --- a/core/core-frontend/src/views/template-market/component/TemplateMarketV2Item.vue +++ b/core/core-frontend/src/views/template-market/component/TemplateMarketV2Item.vue @@ -2,7 +2,10 @@
- + {{ template.title }} @@ -33,6 +36,9 @@ const props = defineProps({ return {} } }, + curPosition: { + type: String + }, baseUrl: { type: String }, @@ -130,4 +136,7 @@ const templateInnerPreview = e => { color: deepskyblue; cursor: pointer; } +.create-area { + bottom: -38px !important; +} diff --git a/core/core-frontend/src/views/template-market/index.vue b/core/core-frontend/src/views/template-market/index.vue index 48e14c0c4e..b106702baa 100644 --- a/core/core-frontend/src/views/template-market/index.vue +++ b/core/core-frontend/src/views/template-market/index.vue @@ -3,14 +3,47 @@ class="template-outer-body" :class="{ 'template-outer-body-padding': outPaddingState }" v-loading="state.loading" + v-show="state.initReady" > - + + + + {{ state.curTemplate.title }} + + 上一个 + 下一个 + {{ t('visualization.apply_this_template') }} + + + + + + + + + + + {{ title }} @@ -30,7 +63,7 @@ /> - + @@ -54,7 +86,7 @@ @@ -122,24 +155,59 @@ import { useCache } from '@/hooks/web/useCache' import TemplateMarketV2Item from '@/views/template-market/component/TemplateMarketV2Item.vue' import MarketPreviewV2 from '@/views/template-market/component/MarketPreviewV2.vue' import { propTypes } from '@/utils/propTypes' +import { imgUrlTrans } from '@/utils/imgUtils' const { t } = useI18n() const { wsCache } = useCache() const route = useRoute() -const previewModel = ref(false) -const title = ref('模版市场') +// full 正常展示 marketPreview 模板中心预览 createPreview 创建界面预览 +const previewModel = ref('full') +const emits = defineEmits(['close']) + +const close = () => { + emits('close') +} + +const title = computed(() => (state.curPosition === 'branch' ? '模板中心' : '使用模版新建')) + +const categoriesComputed = computed(() => { + if (state.templateSourceType === 'all') { + return state.marketTabs + } else { + return state.marketTabs.filter( + category => category.source === 'public' || category.source === state.templateSourceType + ) + } +}) + +const curTemplateImg = computed(() => { + if ( + state.curTemplate.thumbnail.indexOf('http') > -1 || + state.curTemplate.thumbnail.indexOf('static-resource') > -1 + ) { + return imgUrlTrans(state.curTemplate.thumbnail) + } else { + return imgUrlTrans(state.baseUrl + state.curTemplate.thumbnail) + } +}) const outPaddingState = computed(() => { - return state.curPosition === 'branch' && !previewModel.value + return state.curPosition === 'branch' && previewModel.value !== 'marketPreview' }) const optInit = params => { + state.initReady = false state.curPosition = params.curPosition state.templateType = params.templateType + previewModel.value = 'full' state.pid = params.pid + nextTick(() => { + state.initReady = true + }) } const state = reactive({ + initReady: true, curPosition: 'branch', pid: null, treeProps: { @@ -183,7 +251,7 @@ const state = reactive({ templateSpan: '25%', previewVisible: false, templatePreviewId: '', - marketTabs: null, + marketTabs: [], marketActiveTab: null, searchText: null, dvCreateForm: { @@ -203,6 +271,9 @@ const state = reactive({ folderSelectShow: false, baseUrl: 'https://dataease.io/templates', currentMarketTemplateShowList: [], + curTemplateShowFilter: [], + curTemplateIndex: 0, + curTemplate: null, networkStatus: true, rule: { name: [ @@ -252,7 +323,7 @@ const nodeClick = data => { initTemplateShow() } const closePreview = () => { - previewModel.value = false + previewModel.value = 'full' } const initMarketTemplate = async () => { @@ -294,6 +365,20 @@ const normalizer = node => { } } +const preOne = () => { + if (state.curTemplateIndex > 0) { + state.curTemplateIndex-- + state.curTemplate = state.curTemplateShowFilter[state.curTemplateIndex] + } +} + +const nextOne = () => { + if (state.curTemplateIndex < state.curTemplateShowFilter.length - 1) { + state.curTemplateIndex++ + state.curTemplate = state.curTemplateShowFilter[state.curTemplateIndex] + } +} + const templateApply = template => { state.curApplyTemplate = template state.dvCreateForm.name = template.title @@ -305,7 +390,6 @@ const templateApply = template => { state.dvCreateForm.newFrom = 'new_inner_template' state.dvCreateForm.templateId = template.id } - apply() } @@ -317,6 +401,7 @@ const apply = () => { state.loading = true decompression(state.dvCreateForm) .then(response => { + state.curApplyTemplate.recentUseTime = Date.now() state.loading = false const templateData = response.data // do create @@ -383,14 +468,19 @@ const templateShow = templateItem => { } const templatePreview = previewId => { - state.templatePreviewId = previewId - previewModel.value = true + if (state.curPosition === 'branch') { + // 模版中心模式 + state.templatePreviewId = previewId + previewModel.value = 'marketPreview' + } else { + state.curTemplateShowFilter = state.currentMarketTemplateShowList.filter(ele => ele.showFlag) + state.curTemplateIndex = state.curTemplateShowFilter.findIndex(temp => temp.id === previewId) + state.curTemplate = state.curTemplateShowFilter[state.curTemplateIndex] + previewModel.value = 'createPreview' + } } onMounted(() => { - if (route.params.add === '1') { - title.value = '使用模版新建' - } previewInit() initMarketTemplate() const erd = elementResizeDetectorMaker() @@ -522,7 +612,30 @@ defineExpose({ } .custom-divider-line { - height: 30px; + height: 16px; + margin-top: 6px; +} + +.custom-market-icon { + font-size: 20px; + margin-top: 4px; + cursor: pointer; +} + +.custom-back-icon { + font-size: 20px; + cursor: pointer; + margin-right: 8px; +} + +.img-main-create { + display: inherit; + justify-content: center; + width: 100%; + background: #0f1114; + overflow-x: auto; + overflow-y: hidden; + height: 100%; } diff --git a/core/core-frontend/src/views/workbranch/index.vue b/core/core-frontend/src/views/workbranch/index.vue index b886327fd9..cb447cb1cf 100644 --- a/core/core-frontend/src/views/workbranch/index.vue +++ b/core/core-frontend/src/views/workbranch/index.vue @@ -13,6 +13,7 @@ import TemplateBranchItem from '@/views/workbranch/TemplateBranchItem.vue' import { ElMessage } from 'element-plus-secondary' import { decompression } from '@/api/visualization/dataVisualization' import { useCache } from '@/hooks/web/useCache' +import DeResourceCreateOptV2 from '@/views/common/DeResourceCreateOptV2.vue' const userStore = useUserStoreWithOut() const interactiveStore = interactiveStoreWithOut() const permissionStore = usePermissionStoreWithOut() @@ -23,6 +24,7 @@ const busiCountCardList = ref([]) const { wsCache } = useCache() const { push } = useRouter() const router = useRouter() +const resourceCreateOpt = ref(null) const quickCreationList = shallowRef([ { @@ -225,12 +227,11 @@ const toTemplateMarket = () => { } const toTemplateMarketAdd = () => { - push({ - name: 'template-market', - params: { - add: '1' - } - }) + const params = { + curPosition: 'branchCreate', + templateType: 'all' + } + resourceCreateOpt.value.optInit(params) } fillCardInfo() @@ -351,6 +352,7 @@ initMarketTemplate()
+ diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/template/vo/MarketMetaDataVO.java b/sdk/api/api-base/src/main/java/io/dataease/api/template/vo/MarketMetaDataVO.java index 1f0bc3f2f0..2f3471c5f6 100644 --- a/sdk/api/api-base/src/main/java/io/dataease/api/template/vo/MarketMetaDataVO.java +++ b/sdk/api/api-base/src/main/java/io/dataease/api/template/vo/MarketMetaDataVO.java @@ -1,5 +1,6 @@ package io.dataease.api.template.vo; +import io.dataease.constant.CommonConstants; import lombok.Data; import lombok.NoArgsConstructor; @@ -15,9 +16,19 @@ public class MarketMetaDataVO { private String value; private String label; + // market 模板中心 manage 模版管理 public 公共 + private String source = CommonConstants.TEMPLATE_SOURCE.MARKET; + public MarketMetaDataVO(String value, String label) { this.label = label; this.value = value; this.slug = value; } + + public MarketMetaDataVO(String value, String label,String source) { + this.label = label; + this.value = value; + this.slug = value; + this.source = source; + } } diff --git a/sdk/common/src/main/java/io/dataease/constant/CommonConstants.java b/sdk/common/src/main/java/io/dataease/constant/CommonConstants.java index 652fa25c28..419a92ef37 100644 --- a/sdk/common/src/main/java/io/dataease/constant/CommonConstants.java +++ b/sdk/common/src/main/java/io/dataease/constant/CommonConstants.java @@ -79,4 +79,13 @@ public class CommonConstants { public static final String CHART = "dataset"; } + + public static final class TEMPLATE_SOURCE { + //模板市场 + public static final String MARKET = "market"; + //模板管理 + public static final String MANAGE = "manage"; + //公共 + public static final String PUBLIC = "public"; + } }