From 522d33b2db05f5489ee68781b7e6540c9e02705f Mon Sep 17 00:00:00 2001 From: wangjiahao <1522128093@qq.com> Date: Thu, 8 Sep 2022 18:29:34 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BB=AA=E8=A1=A8=E6=9D=BF=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=BA=94=E7=94=A8=E5=AF=BC=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../panel/PanelAppTemplateController.java | 66 ++ .../panel/PanelGroupController.java | 5 + .../panel/PanelAppTemplateRequest.java | 14 + .../dto/panel/PanelAppTemplateDTO.java | 12 + .../dataease/dto/panel/PanelExport2App.java | 61 ++ .../dataease/dto/panel/PanelGroupAppInfo.java | 25 + .../dataease/ext/ExtChartViewFieldMapper.java | 14 + .../dataease/ext/ExtChartViewFieldMapper.xml | 16 + .../io/dataease/ext/ExtChartViewMapper.java | 4 + .../io/dataease/ext/ExtChartViewMapper.xml | 10 + .../ext/ExtDataSetTableFieldMapper.java | 11 + .../ext/ExtDataSetTableFieldMapper.xml | 29 + .../dataease/ext/ExtDataSetTableMapper.java | 2 + .../io/dataease/ext/ExtDataSetTableMapper.xml | 20 + .../io/dataease/ext/ExtDataSetTaskMapper.java | 3 + .../io/dataease/ext/ExtDataSetTaskMapper.xml | 21 + .../io/dataease/ext/ExtDataSourceMapper.java | 4 + .../io/dataease/ext/ExtDataSourceMapper.xml | 15 + .../common/base/domain/PanelAppTemplate.java | 29 + .../base/domain/PanelAppTemplateExample.java | 870 ++++++++++++++++++ .../domain/PanelAppTemplateWithBLOBs.java | 29 + .../base/mapper/PanelAppTemplateMapper.java | 37 + .../base/mapper/PanelAppTemplateMapper.xml | 470 ++++++++++ .../service/dataset/DataSetGroupService.java | 2 +- .../panel/PanelAppTemplateService.java | 80 ++ .../service/panel/PanelGroupService.java | 141 ++- .../service/panel/PanelViewService.java | 5 + .../main/resources/db/migration/V40__1.15.sql | 26 + .../src/main/resources/generatorConfig.xml | 4 +- frontend/src/api/panel/panel.js | 8 + frontend/src/api/system/templateApp.js | 48 + frontend/src/lang/en.js | 2 + frontend/src/lang/tw.js | 2 + frontend/src/lang/zh.js | 2 + frontend/src/styles/deicon/demo_index.html | 33 +- frontend/src/styles/deicon/iconfont.css | 10 +- frontend/src/styles/deicon/iconfont.js | 2 +- frontend/src/styles/deicon/iconfont.json | 7 + frontend/src/styles/deicon/iconfont.ttf | Bin 32308 -> 32484 bytes frontend/src/styles/deicon/iconfont.woff | Bin 19668 -> 19788 bytes frontend/src/styles/deicon/iconfont.woff2 | Bin 16676 -> 16784 bytes .../src/views/panel/list/PanelViewShow.vue | 45 +- frontend/src/views/panel/template/index.vue | 2 +- .../templateApp/component/TemplateImport.vue | 222 +++++ .../templateApp/component/TemplateItem.vue | 145 +++ .../templateApp/component/TemplateList.vue | 235 +++++ .../src/views/panel/templateApp/index.vue | 405 ++++++++ frontend/src/views/wizard/wizardCard.vue | 2 - .../src/views/wizard/wizardCardEnterprise.vue | 2 - 49 files changed, 3136 insertions(+), 61 deletions(-) create mode 100644 backend/src/main/java/io/dataease/controller/panel/PanelAppTemplateController.java create mode 100644 backend/src/main/java/io/dataease/controller/request/panel/PanelAppTemplateRequest.java create mode 100644 backend/src/main/java/io/dataease/dto/panel/PanelAppTemplateDTO.java create mode 100644 backend/src/main/java/io/dataease/dto/panel/PanelExport2App.java create mode 100644 backend/src/main/java/io/dataease/dto/panel/PanelGroupAppInfo.java create mode 100644 backend/src/main/java/io/dataease/ext/ExtChartViewFieldMapper.java create mode 100644 backend/src/main/java/io/dataease/ext/ExtChartViewFieldMapper.xml create mode 100644 backend/src/main/java/io/dataease/ext/ExtDataSetTableFieldMapper.java create mode 100644 backend/src/main/java/io/dataease/ext/ExtDataSetTableFieldMapper.xml create mode 100644 backend/src/main/java/io/dataease/plugins/common/base/domain/PanelAppTemplate.java create mode 100644 backend/src/main/java/io/dataease/plugins/common/base/domain/PanelAppTemplateExample.java create mode 100644 backend/src/main/java/io/dataease/plugins/common/base/domain/PanelAppTemplateWithBLOBs.java create mode 100644 backend/src/main/java/io/dataease/plugins/common/base/mapper/PanelAppTemplateMapper.java create mode 100644 backend/src/main/java/io/dataease/plugins/common/base/mapper/PanelAppTemplateMapper.xml create mode 100644 backend/src/main/java/io/dataease/service/panel/PanelAppTemplateService.java create mode 100644 frontend/src/api/system/templateApp.js create mode 100644 frontend/src/views/panel/templateApp/component/TemplateImport.vue create mode 100644 frontend/src/views/panel/templateApp/component/TemplateItem.vue create mode 100644 frontend/src/views/panel/templateApp/component/TemplateList.vue create mode 100644 frontend/src/views/panel/templateApp/index.vue diff --git a/backend/src/main/java/io/dataease/controller/panel/PanelAppTemplateController.java b/backend/src/main/java/io/dataease/controller/panel/PanelAppTemplateController.java new file mode 100644 index 0000000000..a7e709a12b --- /dev/null +++ b/backend/src/main/java/io/dataease/controller/panel/PanelAppTemplateController.java @@ -0,0 +1,66 @@ +package io.dataease.controller.panel; + +import com.github.xiaoymin.knife4j.annotations.ApiSupport; +import io.dataease.controller.handler.annotation.I18n; +import io.dataease.controller.request.panel.PanelAppTemplateRequest; +import io.dataease.plugins.common.base.domain.PanelAppTemplate; +import io.dataease.plugins.common.base.domain.PanelAppTemplateWithBLOBs; +import io.dataease.service.panel.PanelAppTemplateService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + +/** + * Author: wangjiahao + * Date: 2022/9/8 + * Description: + */ +@Api(tags = "仪表板:应该关系") +@ApiSupport(order = 170) +@RestController +@RequestMapping("templateApp") +public class PanelAppTemplateController { + + + + @Resource + private PanelAppTemplateService panelAppTemplateService; + + @ApiOperation("查询") + @PostMapping("/find") + @I18n + public List templateAppList(@RequestBody PanelAppTemplateRequest request) { + return panelAppTemplateService.list(request); + } + + @ApiOperation("保存") + @PostMapping("/save") + @I18n + public void save(@RequestBody PanelAppTemplateRequest request) { + panelAppTemplateService.save(request); + } + + @ApiOperation("更新") + @PostMapping("/update") + @I18n + public void update(@RequestBody PanelAppTemplateRequest request) { + panelAppTemplateService.update(request); + } + + @ApiOperation("更新") + @DeleteMapping("/delete/{templateAppId}") + @I18n + public void delete(@PathVariable String templateAppId) { + panelAppTemplateService.delete(templateAppId); + } + + @ApiOperation("名称校验") + @PostMapping("/nameCheck") + @I18n + public String nameCheck(@RequestBody PanelAppTemplateRequest request) { + return panelAppTemplateService.nameCheck(request); + } +} diff --git a/backend/src/main/java/io/dataease/controller/panel/PanelGroupController.java b/backend/src/main/java/io/dataease/controller/panel/PanelGroupController.java index cb7d2e7ed7..118308fb86 100644 --- a/backend/src/main/java/io/dataease/controller/panel/PanelGroupController.java +++ b/backend/src/main/java/io/dataease/controller/panel/PanelGroupController.java @@ -15,6 +15,7 @@ import io.dataease.controller.request.panel.PanelGroupRequest; import io.dataease.controller.request.panel.PanelViewDetailsRequest; import io.dataease.dto.PermissionProxy; import io.dataease.dto.authModel.VAuthModelDTO; +import io.dataease.dto.panel.PanelExport2App; import io.dataease.dto.panel.PanelGroupDTO; import io.dataease.service.panel.PanelGroupService; import io.swagger.annotations.Api; @@ -191,4 +192,8 @@ public class PanelGroupController { public Object findPanelElementInfo(@PathVariable String viewId){ return panelGroupService.findPanelElementInfo(viewId); } + @GetMapping("/export2AppCheck/{panelId}") + public PanelExport2App export2AppCheck(@PathVariable String panelId){ + return panelGroupService.panelExport2AppCheck(panelId); + } } diff --git a/backend/src/main/java/io/dataease/controller/request/panel/PanelAppTemplateRequest.java b/backend/src/main/java/io/dataease/controller/request/panel/PanelAppTemplateRequest.java new file mode 100644 index 0000000000..f4ef20c766 --- /dev/null +++ b/backend/src/main/java/io/dataease/controller/request/panel/PanelAppTemplateRequest.java @@ -0,0 +1,14 @@ +package io.dataease.controller.request.panel; + +import io.dataease.plugins.common.base.domain.PanelAppTemplateWithBLOBs; +import lombok.Data; + +/** + * Author: wangjiahao + * Date: 2022/9/8 + * Description: + */ +@Data +public class PanelAppTemplateRequest extends PanelAppTemplateWithBLOBs { + private String optType; +} diff --git a/backend/src/main/java/io/dataease/dto/panel/PanelAppTemplateDTO.java b/backend/src/main/java/io/dataease/dto/panel/PanelAppTemplateDTO.java new file mode 100644 index 0000000000..a5dfdf2ef1 --- /dev/null +++ b/backend/src/main/java/io/dataease/dto/panel/PanelAppTemplateDTO.java @@ -0,0 +1,12 @@ +package io.dataease.dto.panel; + +import io.dataease.plugins.common.base.domain.PanelAppTemplateWithBLOBs; + +/** + * Author: wangjiahao + * Date: 2022/9/8 + * Description: + */ +public class PanelAppTemplateDTO extends PanelAppTemplateWithBLOBs { + +} diff --git a/backend/src/main/java/io/dataease/dto/panel/PanelExport2App.java b/backend/src/main/java/io/dataease/dto/panel/PanelExport2App.java new file mode 100644 index 0000000000..68f3a94270 --- /dev/null +++ b/backend/src/main/java/io/dataease/dto/panel/PanelExport2App.java @@ -0,0 +1,61 @@ +package io.dataease.dto.panel; + +import com.alibaba.fastjson.JSON; +import io.dataease.dto.DatasourceDTO; +import io.dataease.dto.dataset.DataSetTaskDTO; +import io.dataease.plugins.common.base.domain.ChartViewField; +import io.dataease.plugins.common.base.domain.ChartViewWithBLOBs; +import io.dataease.plugins.common.base.domain.DatasetTable; +import io.dataease.plugins.common.base.domain.DatasetTableField; +import lombok.Data; +import org.apache.commons.lang3.ArrayUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * Author: wangjiahao + * Date: 2022/9/8 + * Description: + */ +@Data +public class PanelExport2App { + + private Boolean checkStatus = false; + + private String checkMes; + + private String panelInfo; + + private String chartViewsInfo; + + private String chartViewFieldsInfo; + + private String datasetTablesInfo; + + private String datasetTableFieldsInfo; + + private String dataSetTasksInfo; + + private String datasourceDTOS; + + public PanelExport2App() { + + } + + public PanelExport2App(String checkMes) { + this.checkMes = checkMes; + } + + public PanelExport2App(List chartViewsInfo, List chartViewFieldsInfo, List datasetTablesInfo, List datasetTableFieldsInfo, List dataSetTasksInfo, List datasourceDTOS) { + List empty = new ArrayList(); + this.checkStatus = true; + this.checkMes = "success"; + this.chartViewsInfo = JSON.toJSONString(chartViewsInfo!=null?chartViewsInfo:empty); + this.chartViewFieldsInfo = JSON.toJSONString(chartViewFieldsInfo!=null?chartViewFieldsInfo:empty); + this.datasetTablesInfo = JSON.toJSONString(datasetTablesInfo!=null?datasetTablesInfo:empty); + this.datasetTableFieldsInfo = JSON.toJSONString(datasetTableFieldsInfo!=null?datasetTableFieldsInfo:empty); + this.dataSetTasksInfo = JSON.toJSONString(dataSetTasksInfo!=null?dataSetTasksInfo:empty); + this.datasourceDTOS = JSON.toJSONString(datasourceDTOS!=null?datasourceDTOS:empty); + } +} diff --git a/backend/src/main/java/io/dataease/dto/panel/PanelGroupAppInfo.java b/backend/src/main/java/io/dataease/dto/panel/PanelGroupAppInfo.java new file mode 100644 index 0000000000..2dd7ff5815 --- /dev/null +++ b/backend/src/main/java/io/dataease/dto/panel/PanelGroupAppInfo.java @@ -0,0 +1,25 @@ +package io.dataease.dto.panel; + +import lombok.Data; + +/** + * Author: wangjiahao + * Date: 2022/9/8 + * Description: + */ +@Data +public class PanelGroupAppInfo{ + + private String id; + + private String name; + + private String snapshot; + + private String panelStyle; + + private String panelData; + + private String staticResource; + +} diff --git a/backend/src/main/java/io/dataease/ext/ExtChartViewFieldMapper.java b/backend/src/main/java/io/dataease/ext/ExtChartViewFieldMapper.java new file mode 100644 index 0000000000..1a9ee5c311 --- /dev/null +++ b/backend/src/main/java/io/dataease/ext/ExtChartViewFieldMapper.java @@ -0,0 +1,14 @@ +package io.dataease.ext; + + +import io.dataease.plugins.common.base.domain.ChartViewField; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +@Mapper +public interface ExtChartViewFieldMapper { + List findByPanelId(@Param("panelId") String panelId); + +} diff --git a/backend/src/main/java/io/dataease/ext/ExtChartViewFieldMapper.xml b/backend/src/main/java/io/dataease/ext/ExtChartViewFieldMapper.xml new file mode 100644 index 0000000000..00bd07cc73 --- /dev/null +++ b/backend/src/main/java/io/dataease/ext/ExtChartViewFieldMapper.xml @@ -0,0 +1,16 @@ + + + + + + + + diff --git a/backend/src/main/java/io/dataease/ext/ExtChartViewMapper.java b/backend/src/main/java/io/dataease/ext/ExtChartViewMapper.java index 8856ff7922..020d0df040 100644 --- a/backend/src/main/java/io/dataease/ext/ExtChartViewMapper.java +++ b/backend/src/main/java/io/dataease/ext/ExtChartViewMapper.java @@ -3,6 +3,7 @@ package io.dataease.ext; import io.dataease.controller.request.chart.ChartViewRequest; import io.dataease.dto.chart.ChartViewDTO; import io.dataease.dto.chart.ViewOption; +import io.dataease.plugins.common.base.domain.ChartViewWithBLOBs; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; @@ -55,4 +56,7 @@ public interface ExtChartViewMapper { void initPanelChartViewCache(@Param("panelId") String panelId); List chartOptions(@Param("panelId") String panelId); + + List findByPanelId(@Param("panelId") String panelId); + } diff --git a/backend/src/main/java/io/dataease/ext/ExtChartViewMapper.xml b/backend/src/main/java/io/dataease/ext/ExtChartViewMapper.xml index fbe2da6cb3..2a12627b5e 100644 --- a/backend/src/main/java/io/dataease/ext/ExtChartViewMapper.xml +++ b/backend/src/main/java/io/dataease/ext/ExtChartViewMapper.xml @@ -8,6 +8,16 @@ + + + select + dataset_table_field.* + from dataset_table_field + where table_id in ( + SELECT + table_id + FROM + chart_view + WHERE + id IN ( + SELECT + chart_view_id + FROM + panel_view + WHERE + panel_id = #{panelId} + ) + ) + + diff --git a/backend/src/main/java/io/dataease/ext/ExtDataSetTableMapper.java b/backend/src/main/java/io/dataease/ext/ExtDataSetTableMapper.java index 902c39cc91..996038710b 100644 --- a/backend/src/main/java/io/dataease/ext/ExtDataSetTableMapper.java +++ b/backend/src/main/java/io/dataease/ext/ExtDataSetTableMapper.java @@ -2,6 +2,7 @@ package io.dataease.ext; import io.dataease.controller.request.dataset.DataSetTableRequest; import io.dataease.dto.dataset.DataSetTableDTO; +import io.dataease.plugins.common.base.domain.DatasetTable; import org.apache.ibatis.annotations.Param; import java.util.List; @@ -12,5 +13,6 @@ public interface ExtDataSetTableMapper { DataSetTableDTO searchOne(DataSetTableRequest request); List searchDataSetTableWithPanelId(@Param("panelId") String panelId, @Param("userId") String userId); + List findByPanelId(@Param("panelId") String panelId); } diff --git a/backend/src/main/java/io/dataease/ext/ExtDataSetTableMapper.xml b/backend/src/main/java/io/dataease/ext/ExtDataSetTableMapper.xml index 2d17d26d03..657c805fdc 100644 --- a/backend/src/main/java/io/dataease/ext/ExtDataSetTableMapper.xml +++ b/backend/src/main/java/io/dataease/ext/ExtDataSetTableMapper.xml @@ -124,4 +124,24 @@ ) + diff --git a/backend/src/main/java/io/dataease/ext/ExtDataSetTaskMapper.java b/backend/src/main/java/io/dataease/ext/ExtDataSetTaskMapper.java index 2e860bb85f..c0c320d041 100644 --- a/backend/src/main/java/io/dataease/ext/ExtDataSetTaskMapper.java +++ b/backend/src/main/java/io/dataease/ext/ExtDataSetTaskMapper.java @@ -4,6 +4,7 @@ import io.dataease.ext.query.GridExample; import io.dataease.dto.dataset.DataSetTaskDTO; import io.dataease.dto.dataset.DataSetTaskLogDTO; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; import java.util.List; @@ -22,4 +23,6 @@ public interface ExtDataSetTaskMapper { List userTaskList(GridExample example); List taskWithTriggers(GridExample example); + + List findByPanelId(@Param("panelId") String panelId); } diff --git a/backend/src/main/java/io/dataease/ext/ExtDataSetTaskMapper.xml b/backend/src/main/java/io/dataease/ext/ExtDataSetTaskMapper.xml index 20295774f3..b073d3c111 100644 --- a/backend/src/main/java/io/dataease/ext/ExtDataSetTaskMapper.xml +++ b/backend/src/main/java/io/dataease/ext/ExtDataSetTaskMapper.xml @@ -94,6 +94,27 @@ + + diff --git a/backend/src/main/java/io/dataease/ext/ExtDataSourceMapper.java b/backend/src/main/java/io/dataease/ext/ExtDataSourceMapper.java index 6c519999f9..21ddb7de91 100644 --- a/backend/src/main/java/io/dataease/ext/ExtDataSourceMapper.java +++ b/backend/src/main/java/io/dataease/ext/ExtDataSourceMapper.java @@ -3,6 +3,7 @@ package io.dataease.ext; import io.dataease.ext.query.GridExample; import io.dataease.controller.request.DatasourceUnionRequest; import io.dataease.dto.DatasourceDTO; +import org.apache.ibatis.annotations.Param; import java.util.List; @@ -12,6 +13,9 @@ public interface ExtDataSourceMapper { List queryUnion(DatasourceUnionRequest request); + List findByPanelId(@Param("panelId") String panelId); + + } diff --git a/backend/src/main/java/io/dataease/ext/ExtDataSourceMapper.xml b/backend/src/main/java/io/dataease/ext/ExtDataSourceMapper.xml index 4202bff325..95b8f716f5 100644 --- a/backend/src/main/java/io/dataease/ext/ExtDataSourceMapper.xml +++ b/backend/src/main/java/io/dataease/ext/ExtDataSourceMapper.xml @@ -118,5 +118,20 @@ + + diff --git a/backend/src/main/java/io/dataease/plugins/common/base/domain/PanelAppTemplate.java b/backend/src/main/java/io/dataease/plugins/common/base/domain/PanelAppTemplate.java new file mode 100644 index 0000000000..fe5f1d7d03 --- /dev/null +++ b/backend/src/main/java/io/dataease/plugins/common/base/domain/PanelAppTemplate.java @@ -0,0 +1,29 @@ +package io.dataease.plugins.common.base.domain; + +import java.io.Serializable; +import lombok.Data; + +@Data +public class PanelAppTemplate implements Serializable { + private String id; + + private String name; + + private String nodeType; + + private Integer level; + + private String pid; + + private String version; + + private Long updateTime; + + private String updateUser; + + private Long createTime; + + private String createUser; + + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/backend/src/main/java/io/dataease/plugins/common/base/domain/PanelAppTemplateExample.java b/backend/src/main/java/io/dataease/plugins/common/base/domain/PanelAppTemplateExample.java new file mode 100644 index 0000000000..aab50aeaca --- /dev/null +++ b/backend/src/main/java/io/dataease/plugins/common/base/domain/PanelAppTemplateExample.java @@ -0,0 +1,870 @@ +package io.dataease.plugins.common.base.domain; + +import java.util.ArrayList; +import java.util.List; + +public class PanelAppTemplateExample { + protected String orderByClause; + + protected boolean distinct; + + protected List oredCriteria; + + public PanelAppTemplateExample() { + oredCriteria = new ArrayList(); + } + + public void setOrderByClause(String orderByClause) { + this.orderByClause = orderByClause; + } + + public String getOrderByClause() { + return orderByClause; + } + + public void setDistinct(boolean distinct) { + this.distinct = distinct; + } + + public boolean isDistinct() { + return distinct; + } + + public List getOredCriteria() { + return oredCriteria; + } + + public void or(Criteria criteria) { + oredCriteria.add(criteria); + } + + public Criteria or() { + Criteria criteria = createCriteriaInternal(); + oredCriteria.add(criteria); + return criteria; + } + + public Criteria createCriteria() { + Criteria criteria = createCriteriaInternal(); + if (oredCriteria.size() == 0) { + oredCriteria.add(criteria); + } + return criteria; + } + + protected Criteria createCriteriaInternal() { + Criteria criteria = new Criteria(); + return criteria; + } + + public void clear() { + oredCriteria.clear(); + orderByClause = null; + distinct = false; + } + + protected abstract static class GeneratedCriteria { + protected List criteria; + + protected GeneratedCriteria() { + super(); + criteria = new ArrayList(); + } + + public boolean isValid() { + return criteria.size() > 0; + } + + public List getAllCriteria() { + return criteria; + } + + public List getCriteria() { + return criteria; + } + + protected void addCriterion(String condition) { + if (condition == null) { + throw new RuntimeException("Value for condition cannot be null"); + } + criteria.add(new Criterion(condition)); + } + + protected void addCriterion(String condition, Object value, String property) { + if (value == null) { + throw new RuntimeException("Value for " + property + " cannot be null"); + } + criteria.add(new Criterion(condition, value)); + } + + protected void addCriterion(String condition, Object value1, Object value2, String property) { + if (value1 == null || value2 == null) { + throw new RuntimeException("Between values for " + property + " cannot be null"); + } + criteria.add(new Criterion(condition, value1, value2)); + } + + public Criteria andIdIsNull() { + addCriterion("id is null"); + return (Criteria) this; + } + + public Criteria andIdIsNotNull() { + addCriterion("id is not null"); + return (Criteria) this; + } + + public Criteria andIdEqualTo(String value) { + addCriterion("id =", value, "id"); + return (Criteria) this; + } + + public Criteria andIdNotEqualTo(String value) { + addCriterion("id <>", value, "id"); + return (Criteria) this; + } + + public Criteria andIdGreaterThan(String value) { + addCriterion("id >", value, "id"); + return (Criteria) this; + } + + public Criteria andIdGreaterThanOrEqualTo(String value) { + addCriterion("id >=", value, "id"); + return (Criteria) this; + } + + public Criteria andIdLessThan(String value) { + addCriterion("id <", value, "id"); + return (Criteria) this; + } + + public Criteria andIdLessThanOrEqualTo(String value) { + addCriterion("id <=", value, "id"); + return (Criteria) this; + } + + public Criteria andIdLike(String value) { + addCriterion("id like", value, "id"); + return (Criteria) this; + } + + public Criteria andIdNotLike(String value) { + addCriterion("id not like", value, "id"); + return (Criteria) this; + } + + public Criteria andIdIn(List values) { + addCriterion("id in", values, "id"); + return (Criteria) this; + } + + public Criteria andIdNotIn(List values) { + addCriterion("id not in", values, "id"); + return (Criteria) this; + } + + public Criteria andIdBetween(String value1, String value2) { + addCriterion("id between", value1, value2, "id"); + return (Criteria) this; + } + + public Criteria andIdNotBetween(String value1, String value2) { + addCriterion("id not between", value1, value2, "id"); + return (Criteria) this; + } + + public Criteria andNameIsNull() { + addCriterion("`name` is null"); + return (Criteria) this; + } + + public Criteria andNameIsNotNull() { + addCriterion("`name` is not null"); + return (Criteria) this; + } + + public Criteria andNameEqualTo(String value) { + addCriterion("`name` =", value, "name"); + return (Criteria) this; + } + + public Criteria andNameNotEqualTo(String value) { + addCriterion("`name` <>", value, "name"); + return (Criteria) this; + } + + public Criteria andNameGreaterThan(String value) { + addCriterion("`name` >", value, "name"); + return (Criteria) this; + } + + public Criteria andNameGreaterThanOrEqualTo(String value) { + addCriterion("`name` >=", value, "name"); + return (Criteria) this; + } + + public Criteria andNameLessThan(String value) { + addCriterion("`name` <", value, "name"); + return (Criteria) this; + } + + public Criteria andNameLessThanOrEqualTo(String value) { + addCriterion("`name` <=", value, "name"); + return (Criteria) this; + } + + public Criteria andNameLike(String value) { + addCriterion("`name` like", value, "name"); + return (Criteria) this; + } + + public Criteria andNameNotLike(String value) { + addCriterion("`name` not like", value, "name"); + return (Criteria) this; + } + + public Criteria andNameIn(List values) { + addCriterion("`name` in", values, "name"); + return (Criteria) this; + } + + public Criteria andNameNotIn(List values) { + addCriterion("`name` not in", values, "name"); + return (Criteria) this; + } + + public Criteria andNameBetween(String value1, String value2) { + addCriterion("`name` between", value1, value2, "name"); + return (Criteria) this; + } + + public Criteria andNameNotBetween(String value1, String value2) { + addCriterion("`name` not between", value1, value2, "name"); + return (Criteria) this; + } + + public Criteria andNodeTypeIsNull() { + addCriterion("node_type is null"); + return (Criteria) this; + } + + public Criteria andNodeTypeIsNotNull() { + addCriterion("node_type is not null"); + return (Criteria) this; + } + + public Criteria andNodeTypeEqualTo(String value) { + addCriterion("node_type =", value, "nodeType"); + return (Criteria) this; + } + + public Criteria andNodeTypeNotEqualTo(String value) { + addCriterion("node_type <>", value, "nodeType"); + return (Criteria) this; + } + + public Criteria andNodeTypeGreaterThan(String value) { + addCriterion("node_type >", value, "nodeType"); + return (Criteria) this; + } + + public Criteria andNodeTypeGreaterThanOrEqualTo(String value) { + addCriterion("node_type >=", value, "nodeType"); + return (Criteria) this; + } + + public Criteria andNodeTypeLessThan(String value) { + addCriterion("node_type <", value, "nodeType"); + return (Criteria) this; + } + + public Criteria andNodeTypeLessThanOrEqualTo(String value) { + addCriterion("node_type <=", value, "nodeType"); + return (Criteria) this; + } + + public Criteria andNodeTypeLike(String value) { + addCriterion("node_type like", value, "nodeType"); + return (Criteria) this; + } + + public Criteria andNodeTypeNotLike(String value) { + addCriterion("node_type not like", value, "nodeType"); + return (Criteria) this; + } + + public Criteria andNodeTypeIn(List values) { + addCriterion("node_type in", values, "nodeType"); + return (Criteria) this; + } + + public Criteria andNodeTypeNotIn(List values) { + addCriterion("node_type not in", values, "nodeType"); + return (Criteria) this; + } + + public Criteria andNodeTypeBetween(String value1, String value2) { + addCriterion("node_type between", value1, value2, "nodeType"); + return (Criteria) this; + } + + public Criteria andNodeTypeNotBetween(String value1, String value2) { + addCriterion("node_type not between", value1, value2, "nodeType"); + return (Criteria) this; + } + + public Criteria andLevelIsNull() { + addCriterion("`level` is null"); + return (Criteria) this; + } + + public Criteria andLevelIsNotNull() { + addCriterion("`level` is not null"); + return (Criteria) this; + } + + public Criteria andLevelEqualTo(Integer value) { + addCriterion("`level` =", value, "level"); + return (Criteria) this; + } + + public Criteria andLevelNotEqualTo(Integer value) { + addCriterion("`level` <>", value, "level"); + return (Criteria) this; + } + + public Criteria andLevelGreaterThan(Integer value) { + addCriterion("`level` >", value, "level"); + return (Criteria) this; + } + + public Criteria andLevelGreaterThanOrEqualTo(Integer value) { + addCriterion("`level` >=", value, "level"); + return (Criteria) this; + } + + public Criteria andLevelLessThan(Integer value) { + addCriterion("`level` <", value, "level"); + return (Criteria) this; + } + + public Criteria andLevelLessThanOrEqualTo(Integer value) { + addCriterion("`level` <=", value, "level"); + return (Criteria) this; + } + + public Criteria andLevelIn(List values) { + addCriterion("`level` in", values, "level"); + return (Criteria) this; + } + + public Criteria andLevelNotIn(List values) { + addCriterion("`level` not in", values, "level"); + return (Criteria) this; + } + + public Criteria andLevelBetween(Integer value1, Integer value2) { + addCriterion("`level` between", value1, value2, "level"); + return (Criteria) this; + } + + public Criteria andLevelNotBetween(Integer value1, Integer value2) { + addCriterion("`level` not between", value1, value2, "level"); + return (Criteria) this; + } + + public Criteria andPidIsNull() { + addCriterion("pid is null"); + return (Criteria) this; + } + + public Criteria andPidIsNotNull() { + addCriterion("pid is not null"); + return (Criteria) this; + } + + public Criteria andPidEqualTo(String value) { + addCriterion("pid =", value, "pid"); + return (Criteria) this; + } + + public Criteria andPidNotEqualTo(String value) { + addCriterion("pid <>", value, "pid"); + return (Criteria) this; + } + + public Criteria andPidGreaterThan(String value) { + addCriterion("pid >", value, "pid"); + return (Criteria) this; + } + + public Criteria andPidGreaterThanOrEqualTo(String value) { + addCriterion("pid >=", value, "pid"); + return (Criteria) this; + } + + public Criteria andPidLessThan(String value) { + addCriterion("pid <", value, "pid"); + return (Criteria) this; + } + + public Criteria andPidLessThanOrEqualTo(String value) { + addCriterion("pid <=", value, "pid"); + return (Criteria) this; + } + + public Criteria andPidLike(String value) { + addCriterion("pid like", value, "pid"); + return (Criteria) this; + } + + public Criteria andPidNotLike(String value) { + addCriterion("pid not like", value, "pid"); + return (Criteria) this; + } + + public Criteria andPidIn(List values) { + addCriterion("pid in", values, "pid"); + return (Criteria) this; + } + + public Criteria andPidNotIn(List values) { + addCriterion("pid not in", values, "pid"); + return (Criteria) this; + } + + public Criteria andPidBetween(String value1, String value2) { + addCriterion("pid between", value1, value2, "pid"); + return (Criteria) this; + } + + public Criteria andPidNotBetween(String value1, String value2) { + addCriterion("pid not between", value1, value2, "pid"); + return (Criteria) this; + } + + public Criteria andVersionIsNull() { + addCriterion("version is null"); + return (Criteria) this; + } + + public Criteria andVersionIsNotNull() { + addCriterion("version is not null"); + return (Criteria) this; + } + + public Criteria andVersionEqualTo(String value) { + addCriterion("version =", value, "version"); + return (Criteria) this; + } + + public Criteria andVersionNotEqualTo(String value) { + addCriterion("version <>", value, "version"); + return (Criteria) this; + } + + public Criteria andVersionGreaterThan(String value) { + addCriterion("version >", value, "version"); + return (Criteria) this; + } + + public Criteria andVersionGreaterThanOrEqualTo(String value) { + addCriterion("version >=", value, "version"); + return (Criteria) this; + } + + public Criteria andVersionLessThan(String value) { + addCriterion("version <", value, "version"); + return (Criteria) this; + } + + public Criteria andVersionLessThanOrEqualTo(String value) { + addCriterion("version <=", value, "version"); + return (Criteria) this; + } + + public Criteria andVersionLike(String value) { + addCriterion("version like", value, "version"); + return (Criteria) this; + } + + public Criteria andVersionNotLike(String value) { + addCriterion("version not like", value, "version"); + return (Criteria) this; + } + + public Criteria andVersionIn(List values) { + addCriterion("version in", values, "version"); + return (Criteria) this; + } + + public Criteria andVersionNotIn(List values) { + addCriterion("version not in", values, "version"); + return (Criteria) this; + } + + public Criteria andVersionBetween(String value1, String value2) { + addCriterion("version between", value1, value2, "version"); + return (Criteria) this; + } + + public Criteria andVersionNotBetween(String value1, String value2) { + addCriterion("version not between", value1, value2, "version"); + return (Criteria) this; + } + + public Criteria andUpdateTimeIsNull() { + addCriterion("update_time is null"); + return (Criteria) this; + } + + public Criteria andUpdateTimeIsNotNull() { + addCriterion("update_time is not null"); + return (Criteria) this; + } + + public Criteria andUpdateTimeEqualTo(Long value) { + addCriterion("update_time =", value, "updateTime"); + return (Criteria) this; + } + + public Criteria andUpdateTimeNotEqualTo(Long value) { + addCriterion("update_time <>", value, "updateTime"); + return (Criteria) this; + } + + public Criteria andUpdateTimeGreaterThan(Long value) { + addCriterion("update_time >", value, "updateTime"); + return (Criteria) this; + } + + public Criteria andUpdateTimeGreaterThanOrEqualTo(Long value) { + addCriterion("update_time >=", value, "updateTime"); + return (Criteria) this; + } + + public Criteria andUpdateTimeLessThan(Long value) { + addCriterion("update_time <", value, "updateTime"); + return (Criteria) this; + } + + public Criteria andUpdateTimeLessThanOrEqualTo(Long value) { + addCriterion("update_time <=", value, "updateTime"); + return (Criteria) this; + } + + public Criteria andUpdateTimeIn(List values) { + addCriterion("update_time in", values, "updateTime"); + return (Criteria) this; + } + + public Criteria andUpdateTimeNotIn(List values) { + addCriterion("update_time not in", values, "updateTime"); + return (Criteria) this; + } + + public Criteria andUpdateTimeBetween(Long value1, Long value2) { + addCriterion("update_time between", value1, value2, "updateTime"); + return (Criteria) this; + } + + public Criteria andUpdateTimeNotBetween(Long value1, Long value2) { + addCriterion("update_time not between", value1, value2, "updateTime"); + return (Criteria) this; + } + + public Criteria andUpdateUserIsNull() { + addCriterion("update_user is null"); + return (Criteria) this; + } + + public Criteria andUpdateUserIsNotNull() { + addCriterion("update_user is not null"); + return (Criteria) this; + } + + public Criteria andUpdateUserEqualTo(String value) { + addCriterion("update_user =", value, "updateUser"); + return (Criteria) this; + } + + public Criteria andUpdateUserNotEqualTo(String value) { + addCriterion("update_user <>", value, "updateUser"); + return (Criteria) this; + } + + public Criteria andUpdateUserGreaterThan(String value) { + addCriterion("update_user >", value, "updateUser"); + return (Criteria) this; + } + + public Criteria andUpdateUserGreaterThanOrEqualTo(String value) { + addCriterion("update_user >=", value, "updateUser"); + return (Criteria) this; + } + + public Criteria andUpdateUserLessThan(String value) { + addCriterion("update_user <", value, "updateUser"); + return (Criteria) this; + } + + public Criteria andUpdateUserLessThanOrEqualTo(String value) { + addCriterion("update_user <=", value, "updateUser"); + return (Criteria) this; + } + + public Criteria andUpdateUserLike(String value) { + addCriterion("update_user like", value, "updateUser"); + return (Criteria) this; + } + + public Criteria andUpdateUserNotLike(String value) { + addCriterion("update_user not like", value, "updateUser"); + return (Criteria) this; + } + + public Criteria andUpdateUserIn(List values) { + addCriterion("update_user in", values, "updateUser"); + return (Criteria) this; + } + + public Criteria andUpdateUserNotIn(List values) { + addCriterion("update_user not in", values, "updateUser"); + return (Criteria) this; + } + + public Criteria andUpdateUserBetween(String value1, String value2) { + addCriterion("update_user between", value1, value2, "updateUser"); + return (Criteria) this; + } + + public Criteria andUpdateUserNotBetween(String value1, String value2) { + addCriterion("update_user not between", value1, value2, "updateUser"); + return (Criteria) this; + } + + public Criteria andCreateTimeIsNull() { + addCriterion("create_time is null"); + return (Criteria) this; + } + + public Criteria andCreateTimeIsNotNull() { + addCriterion("create_time is not null"); + return (Criteria) this; + } + + public Criteria andCreateTimeEqualTo(Long value) { + addCriterion("create_time =", value, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeNotEqualTo(Long value) { + addCriterion("create_time <>", value, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeGreaterThan(Long value) { + addCriterion("create_time >", value, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeGreaterThanOrEqualTo(Long value) { + addCriterion("create_time >=", value, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeLessThan(Long value) { + addCriterion("create_time <", value, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeLessThanOrEqualTo(Long value) { + addCriterion("create_time <=", value, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeIn(List values) { + addCriterion("create_time in", values, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeNotIn(List values) { + addCriterion("create_time not in", values, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeBetween(Long value1, Long value2) { + addCriterion("create_time between", value1, value2, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateTimeNotBetween(Long value1, Long value2) { + addCriterion("create_time not between", value1, value2, "createTime"); + return (Criteria) this; + } + + public Criteria andCreateUserIsNull() { + addCriterion("create_user is null"); + return (Criteria) this; + } + + public Criteria andCreateUserIsNotNull() { + addCriterion("create_user is not null"); + return (Criteria) this; + } + + public Criteria andCreateUserEqualTo(String value) { + addCriterion("create_user =", value, "createUser"); + return (Criteria) this; + } + + public Criteria andCreateUserNotEqualTo(String value) { + addCriterion("create_user <>", value, "createUser"); + return (Criteria) this; + } + + public Criteria andCreateUserGreaterThan(String value) { + addCriterion("create_user >", value, "createUser"); + return (Criteria) this; + } + + public Criteria andCreateUserGreaterThanOrEqualTo(String value) { + addCriterion("create_user >=", value, "createUser"); + return (Criteria) this; + } + + public Criteria andCreateUserLessThan(String value) { + addCriterion("create_user <", value, "createUser"); + return (Criteria) this; + } + + public Criteria andCreateUserLessThanOrEqualTo(String value) { + addCriterion("create_user <=", value, "createUser"); + return (Criteria) this; + } + + public Criteria andCreateUserLike(String value) { + addCriterion("create_user like", value, "createUser"); + return (Criteria) this; + } + + public Criteria andCreateUserNotLike(String value) { + addCriterion("create_user not like", value, "createUser"); + return (Criteria) this; + } + + public Criteria andCreateUserIn(List values) { + addCriterion("create_user in", values, "createUser"); + return (Criteria) this; + } + + public Criteria andCreateUserNotIn(List values) { + addCriterion("create_user not in", values, "createUser"); + return (Criteria) this; + } + + public Criteria andCreateUserBetween(String value1, String value2) { + addCriterion("create_user between", value1, value2, "createUser"); + return (Criteria) this; + } + + public Criteria andCreateUserNotBetween(String value1, String value2) { + addCriterion("create_user not between", value1, value2, "createUser"); + return (Criteria) this; + } + } + + public static class Criteria extends GeneratedCriteria { + + protected Criteria() { + super(); + } + } + + public static class Criterion { + private String condition; + + private Object value; + + private Object secondValue; + + private boolean noValue; + + private boolean singleValue; + + private boolean betweenValue; + + private boolean listValue; + + private String typeHandler; + + public String getCondition() { + return condition; + } + + public Object getValue() { + return value; + } + + public Object getSecondValue() { + return secondValue; + } + + public boolean isNoValue() { + return noValue; + } + + public boolean isSingleValue() { + return singleValue; + } + + public boolean isBetweenValue() { + return betweenValue; + } + + public boolean isListValue() { + return listValue; + } + + public String getTypeHandler() { + return typeHandler; + } + + protected Criterion(String condition) { + super(); + this.condition = condition; + this.typeHandler = null; + this.noValue = true; + } + + protected Criterion(String condition, Object value, String typeHandler) { + super(); + this.condition = condition; + this.value = value; + this.typeHandler = typeHandler; + if (value instanceof List) { + this.listValue = true; + } else { + this.singleValue = true; + } + } + + protected Criterion(String condition, Object value) { + this(condition, value, null); + } + + protected Criterion(String condition, Object value, Object secondValue, String typeHandler) { + super(); + this.condition = condition; + this.value = value; + this.secondValue = secondValue; + this.typeHandler = typeHandler; + this.betweenValue = true; + } + + protected Criterion(String condition, Object value, Object secondValue) { + this(condition, value, secondValue, null); + } + } +} \ No newline at end of file diff --git a/backend/src/main/java/io/dataease/plugins/common/base/domain/PanelAppTemplateWithBLOBs.java b/backend/src/main/java/io/dataease/plugins/common/base/domain/PanelAppTemplateWithBLOBs.java new file mode 100644 index 0000000000..216c7592db --- /dev/null +++ b/backend/src/main/java/io/dataease/plugins/common/base/domain/PanelAppTemplateWithBLOBs.java @@ -0,0 +1,29 @@ +package io.dataease.plugins.common.base.domain; + +import java.io.Serializable; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PanelAppTemplateWithBLOBs extends PanelAppTemplate implements Serializable { + private String applicationInfo; + + private String panelInfo; + + private String viewsInfo; + + private String datasetInfo; + + private String datasetFieldsInfo; + + private String datasetTasksInfo; + + private String datasourceInfo; + + private String snapshot; + + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/backend/src/main/java/io/dataease/plugins/common/base/mapper/PanelAppTemplateMapper.java b/backend/src/main/java/io/dataease/plugins/common/base/mapper/PanelAppTemplateMapper.java new file mode 100644 index 0000000000..bc4dff558c --- /dev/null +++ b/backend/src/main/java/io/dataease/plugins/common/base/mapper/PanelAppTemplateMapper.java @@ -0,0 +1,37 @@ +package io.dataease.plugins.common.base.mapper; + +import io.dataease.plugins.common.base.domain.PanelAppTemplate; +import io.dataease.plugins.common.base.domain.PanelAppTemplateExample; +import io.dataease.plugins.common.base.domain.PanelAppTemplateWithBLOBs; +import java.util.List; +import org.apache.ibatis.annotations.Param; + +public interface PanelAppTemplateMapper { + long countByExample(PanelAppTemplateExample example); + + int deleteByExample(PanelAppTemplateExample example); + + int deleteByPrimaryKey(String id); + + int insert(PanelAppTemplateWithBLOBs record); + + int insertSelective(PanelAppTemplateWithBLOBs record); + + List selectByExampleWithBLOBs(PanelAppTemplateExample example); + + List selectByExample(PanelAppTemplateExample example); + + PanelAppTemplateWithBLOBs selectByPrimaryKey(String id); + + int updateByExampleSelective(@Param("record") PanelAppTemplateWithBLOBs record, @Param("example") PanelAppTemplateExample example); + + int updateByExampleWithBLOBs(@Param("record") PanelAppTemplateWithBLOBs record, @Param("example") PanelAppTemplateExample example); + + int updateByExample(@Param("record") PanelAppTemplate record, @Param("example") PanelAppTemplateExample example); + + int updateByPrimaryKeySelective(PanelAppTemplateWithBLOBs record); + + int updateByPrimaryKeyWithBLOBs(PanelAppTemplateWithBLOBs record); + + int updateByPrimaryKey(PanelAppTemplate record); +} \ No newline at end of file diff --git a/backend/src/main/java/io/dataease/plugins/common/base/mapper/PanelAppTemplateMapper.xml b/backend/src/main/java/io/dataease/plugins/common/base/mapper/PanelAppTemplateMapper.xml new file mode 100644 index 0000000000..5d6f1fe4e3 --- /dev/null +++ b/backend/src/main/java/io/dataease/plugins/common/base/mapper/PanelAppTemplateMapper.xml @@ -0,0 +1,470 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + and ${criterion.condition} + + + and ${criterion.condition} #{criterion.value} + + + and ${criterion.condition} #{criterion.value} and #{criterion.secondValue} + + + and ${criterion.condition} + + #{listItem} + + + + + + + + + + + + + + + + + + and ${criterion.condition} + + + and ${criterion.condition} #{criterion.value} + + + and ${criterion.condition} #{criterion.value} and #{criterion.secondValue} + + + and ${criterion.condition} + + #{listItem} + + + + + + + + + + + id, `name`, node_type, `level`, pid, version, update_time, update_user, create_time, + create_user + + + application_info, panel_info, views_info, dataset_info, dataset_fields_info, dataset_tasks_info, + datasource_info, snapshot + + + + + + delete from panel_app_template + where id = #{id,jdbcType=VARCHAR} + + + delete from panel_app_template + + + + + + insert into panel_app_template (id, `name`, node_type, + `level`, pid, version, + update_time, update_user, create_time, + create_user, application_info, panel_info, + views_info, dataset_info, dataset_fields_info, + dataset_tasks_info, datasource_info, + snapshot) + values (#{id,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{nodeType,jdbcType=VARCHAR}, + #{level,jdbcType=INTEGER}, #{pid,jdbcType=VARCHAR}, #{version,jdbcType=VARCHAR}, + #{updateTime,jdbcType=BIGINT}, #{updateUser,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, + #{createUser,jdbcType=VARCHAR}, #{applicationInfo,jdbcType=LONGVARCHAR}, #{panelInfo,jdbcType=LONGVARCHAR}, + #{viewsInfo,jdbcType=LONGVARCHAR}, #{datasetInfo,jdbcType=LONGVARCHAR}, #{datasetFieldsInfo,jdbcType=LONGVARCHAR}, + #{datasetTasksInfo,jdbcType=LONGVARCHAR}, #{datasourceInfo,jdbcType=LONGVARCHAR}, + #{snapshot,jdbcType=LONGVARCHAR}) + + + insert into panel_app_template + + + id, + + + `name`, + + + node_type, + + + `level`, + + + pid, + + + version, + + + update_time, + + + update_user, + + + create_time, + + + create_user, + + + application_info, + + + panel_info, + + + views_info, + + + dataset_info, + + + dataset_fields_info, + + + dataset_tasks_info, + + + datasource_info, + + + snapshot, + + + + + #{id,jdbcType=VARCHAR}, + + + #{name,jdbcType=VARCHAR}, + + + #{nodeType,jdbcType=VARCHAR}, + + + #{level,jdbcType=INTEGER}, + + + #{pid,jdbcType=VARCHAR}, + + + #{version,jdbcType=VARCHAR}, + + + #{updateTime,jdbcType=BIGINT}, + + + #{updateUser,jdbcType=VARCHAR}, + + + #{createTime,jdbcType=BIGINT}, + + + #{createUser,jdbcType=VARCHAR}, + + + #{applicationInfo,jdbcType=LONGVARCHAR}, + + + #{panelInfo,jdbcType=LONGVARCHAR}, + + + #{viewsInfo,jdbcType=LONGVARCHAR}, + + + #{datasetInfo,jdbcType=LONGVARCHAR}, + + + #{datasetFieldsInfo,jdbcType=LONGVARCHAR}, + + + #{datasetTasksInfo,jdbcType=LONGVARCHAR}, + + + #{datasourceInfo,jdbcType=LONGVARCHAR}, + + + #{snapshot,jdbcType=LONGVARCHAR}, + + + + + + update panel_app_template + + + id = #{record.id,jdbcType=VARCHAR}, + + + `name` = #{record.name,jdbcType=VARCHAR}, + + + node_type = #{record.nodeType,jdbcType=VARCHAR}, + + + `level` = #{record.level,jdbcType=INTEGER}, + + + pid = #{record.pid,jdbcType=VARCHAR}, + + + version = #{record.version,jdbcType=VARCHAR}, + + + update_time = #{record.updateTime,jdbcType=BIGINT}, + + + update_user = #{record.updateUser,jdbcType=VARCHAR}, + + + create_time = #{record.createTime,jdbcType=BIGINT}, + + + create_user = #{record.createUser,jdbcType=VARCHAR}, + + + application_info = #{record.applicationInfo,jdbcType=LONGVARCHAR}, + + + panel_info = #{record.panelInfo,jdbcType=LONGVARCHAR}, + + + views_info = #{record.viewsInfo,jdbcType=LONGVARCHAR}, + + + dataset_info = #{record.datasetInfo,jdbcType=LONGVARCHAR}, + + + dataset_fields_info = #{record.datasetFieldsInfo,jdbcType=LONGVARCHAR}, + + + dataset_tasks_info = #{record.datasetTasksInfo,jdbcType=LONGVARCHAR}, + + + datasource_info = #{record.datasourceInfo,jdbcType=LONGVARCHAR}, + + + snapshot = #{record.snapshot,jdbcType=LONGVARCHAR}, + + + + + + + + update panel_app_template + set id = #{record.id,jdbcType=VARCHAR}, + `name` = #{record.name,jdbcType=VARCHAR}, + node_type = #{record.nodeType,jdbcType=VARCHAR}, + `level` = #{record.level,jdbcType=INTEGER}, + pid = #{record.pid,jdbcType=VARCHAR}, + version = #{record.version,jdbcType=VARCHAR}, + update_time = #{record.updateTime,jdbcType=BIGINT}, + update_user = #{record.updateUser,jdbcType=VARCHAR}, + create_time = #{record.createTime,jdbcType=BIGINT}, + create_user = #{record.createUser,jdbcType=VARCHAR}, + application_info = #{record.applicationInfo,jdbcType=LONGVARCHAR}, + panel_info = #{record.panelInfo,jdbcType=LONGVARCHAR}, + views_info = #{record.viewsInfo,jdbcType=LONGVARCHAR}, + dataset_info = #{record.datasetInfo,jdbcType=LONGVARCHAR}, + dataset_fields_info = #{record.datasetFieldsInfo,jdbcType=LONGVARCHAR}, + dataset_tasks_info = #{record.datasetTasksInfo,jdbcType=LONGVARCHAR}, + datasource_info = #{record.datasourceInfo,jdbcType=LONGVARCHAR}, + snapshot = #{record.snapshot,jdbcType=LONGVARCHAR} + + + + + + update panel_app_template + set id = #{record.id,jdbcType=VARCHAR}, + `name` = #{record.name,jdbcType=VARCHAR}, + node_type = #{record.nodeType,jdbcType=VARCHAR}, + `level` = #{record.level,jdbcType=INTEGER}, + pid = #{record.pid,jdbcType=VARCHAR}, + version = #{record.version,jdbcType=VARCHAR}, + update_time = #{record.updateTime,jdbcType=BIGINT}, + update_user = #{record.updateUser,jdbcType=VARCHAR}, + create_time = #{record.createTime,jdbcType=BIGINT}, + create_user = #{record.createUser,jdbcType=VARCHAR} + + + + + + update panel_app_template + + + `name` = #{name,jdbcType=VARCHAR}, + + + node_type = #{nodeType,jdbcType=VARCHAR}, + + + `level` = #{level,jdbcType=INTEGER}, + + + pid = #{pid,jdbcType=VARCHAR}, + + + version = #{version,jdbcType=VARCHAR}, + + + update_time = #{updateTime,jdbcType=BIGINT}, + + + update_user = #{updateUser,jdbcType=VARCHAR}, + + + create_time = #{createTime,jdbcType=BIGINT}, + + + create_user = #{createUser,jdbcType=VARCHAR}, + + + application_info = #{applicationInfo,jdbcType=LONGVARCHAR}, + + + panel_info = #{panelInfo,jdbcType=LONGVARCHAR}, + + + views_info = #{viewsInfo,jdbcType=LONGVARCHAR}, + + + dataset_info = #{datasetInfo,jdbcType=LONGVARCHAR}, + + + dataset_fields_info = #{datasetFieldsInfo,jdbcType=LONGVARCHAR}, + + + dataset_tasks_info = #{datasetTasksInfo,jdbcType=LONGVARCHAR}, + + + datasource_info = #{datasourceInfo,jdbcType=LONGVARCHAR}, + + + snapshot = #{snapshot,jdbcType=LONGVARCHAR}, + + + where id = #{id,jdbcType=VARCHAR} + + + update panel_app_template + set `name` = #{name,jdbcType=VARCHAR}, + node_type = #{nodeType,jdbcType=VARCHAR}, + `level` = #{level,jdbcType=INTEGER}, + pid = #{pid,jdbcType=VARCHAR}, + version = #{version,jdbcType=VARCHAR}, + update_time = #{updateTime,jdbcType=BIGINT}, + update_user = #{updateUser,jdbcType=VARCHAR}, + create_time = #{createTime,jdbcType=BIGINT}, + create_user = #{createUser,jdbcType=VARCHAR}, + application_info = #{applicationInfo,jdbcType=LONGVARCHAR}, + panel_info = #{panelInfo,jdbcType=LONGVARCHAR}, + views_info = #{viewsInfo,jdbcType=LONGVARCHAR}, + dataset_info = #{datasetInfo,jdbcType=LONGVARCHAR}, + dataset_fields_info = #{datasetFieldsInfo,jdbcType=LONGVARCHAR}, + dataset_tasks_info = #{datasetTasksInfo,jdbcType=LONGVARCHAR}, + datasource_info = #{datasourceInfo,jdbcType=LONGVARCHAR}, + snapshot = #{snapshot,jdbcType=LONGVARCHAR} + where id = #{id,jdbcType=VARCHAR} + + + update panel_app_template + set `name` = #{name,jdbcType=VARCHAR}, + node_type = #{nodeType,jdbcType=VARCHAR}, + `level` = #{level,jdbcType=INTEGER}, + pid = #{pid,jdbcType=VARCHAR}, + version = #{version,jdbcType=VARCHAR}, + update_time = #{updateTime,jdbcType=BIGINT}, + update_user = #{updateUser,jdbcType=VARCHAR}, + create_time = #{createTime,jdbcType=BIGINT}, + create_user = #{createUser,jdbcType=VARCHAR} + where id = #{id,jdbcType=VARCHAR} + + \ No newline at end of file diff --git a/backend/src/main/java/io/dataease/service/dataset/DataSetGroupService.java b/backend/src/main/java/io/dataease/service/dataset/DataSetGroupService.java index 28ff78c646..fe058b6184 100644 --- a/backend/src/main/java/io/dataease/service/dataset/DataSetGroupService.java +++ b/backend/src/main/java/io/dataease/service/dataset/DataSetGroupService.java @@ -46,7 +46,7 @@ public class DataSetGroupService { @Resource private SysAuthService sysAuthService; - @DeCleaner(value = DePermissionType.DATASET, key = "pid") +// @DeCleaner(value = DePermissionType.DATASET, key = "pid") public DataSetGroupDTO save(DatasetGroup datasetGroup) throws Exception { checkName(datasetGroup); if (StringUtils.isEmpty(datasetGroup.getId())) { diff --git a/backend/src/main/java/io/dataease/service/panel/PanelAppTemplateService.java b/backend/src/main/java/io/dataease/service/panel/PanelAppTemplateService.java new file mode 100644 index 0000000000..1b70204257 --- /dev/null +++ b/backend/src/main/java/io/dataease/service/panel/PanelAppTemplateService.java @@ -0,0 +1,80 @@ +package io.dataease.service.panel; + +import io.dataease.commons.constants.CommonConstants; +import io.dataease.commons.utils.AuthUtils; +import io.dataease.commons.utils.BeanUtils; +import io.dataease.controller.request.panel.PanelAppTemplateRequest; +import io.dataease.controller.request.panel.PanelTemplateRequest; +import io.dataease.dto.panel.PanelAppTemplateDTO; +import io.dataease.plugins.common.base.domain.*; +import io.dataease.plugins.common.base.mapper.PanelAppTemplateMapper; +import org.pentaho.di.core.util.UUIDUtil; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import javax.annotation.Resource; +import java.util.List; + +/** + * Author: wangjiahao + * Date: 2022/9/8 + * Description: + */ +@Service +public class PanelAppTemplateService { + + @Resource + private PanelAppTemplateMapper panelAppTemplateMapper; + + public List list(PanelAppTemplateRequest request){ + PanelAppTemplateExample example = new PanelAppTemplateExample(); + example.createCriteria().andPidEqualTo(request.getPid()); + return panelAppTemplateMapper.selectByExampleWithBLOBs(example); + } + + public void save(PanelAppTemplateRequest request){ + request.setId(UUIDUtil.getUUIDAsString()); + request.setCreateUser(AuthUtils.getUser().getUsername()); + request.setCreateTime(System.currentTimeMillis()); + PanelAppTemplateWithBLOBs requestTemplate = new PanelAppTemplateWithBLOBs(); + BeanUtils.copyBean(requestTemplate,request); + panelAppTemplateMapper.insertSelective(requestTemplate); + } + + + public void update(PanelAppTemplateRequest request){ + request.setUpdateUser(AuthUtils.getUser().getUsername()); + request.setUpdateTime(System.currentTimeMillis()); + PanelAppTemplateWithBLOBs requestTemplate = new PanelAppTemplateWithBLOBs(); + BeanUtils.copyBean(requestTemplate,request); + panelAppTemplateMapper.updateByPrimaryKeySelective(requestTemplate); + } + + public void delete(String templateAppId){ + panelAppTemplateMapper.deleteByPrimaryKey(templateAppId); + } + + public String nameCheck(PanelAppTemplateRequest request) { + return nameCheck(request.getOptType(), request.getName(), request.getPid(), request.getId()); + + } + + //名称检查 + public String nameCheck(String optType, String name, String pid, String id) { + PanelAppTemplateExample example = new PanelAppTemplateExample(); + if (CommonConstants.OPT_TYPE.INSERT.equals(optType)) { + example.createCriteria().andPidEqualTo(pid).andNameEqualTo(name); + + } else if (CommonConstants.OPT_TYPE.UPDATE.equals(optType)) { + example.createCriteria().andPidEqualTo(pid).andNameEqualTo(name).andIdNotEqualTo(id); + } + List panelTemplates = panelAppTemplateMapper.selectByExample(example); + if (CollectionUtils.isEmpty(panelTemplates)) { + return CommonConstants.CHECK_RESULT.NONE; + } else { + return CommonConstants.CHECK_RESULT.EXIST_ALL; + } + } + + +} diff --git a/backend/src/main/java/io/dataease/service/panel/PanelGroupService.java b/backend/src/main/java/io/dataease/service/panel/PanelGroupService.java index 8791b91744..feeb5792fe 100644 --- a/backend/src/main/java/io/dataease/service/panel/PanelGroupService.java +++ b/backend/src/main/java/io/dataease/service/panel/PanelGroupService.java @@ -11,11 +11,15 @@ import io.dataease.controller.request.dataset.DataSetTableRequest; import io.dataease.controller.request.panel.*; +import io.dataease.dto.DatasourceDTO; import io.dataease.dto.PanelGroupExtendDataDTO; import io.dataease.dto.SysLogDTO; import io.dataease.dto.authModel.VAuthModelDTO; import io.dataease.dto.chart.ChartViewDTO; import io.dataease.dto.dataset.DataSetTableDTO; +import io.dataease.dto.dataset.DataSetTaskDTO; +import io.dataease.dto.panel.PanelExport2App; +import io.dataease.dto.panel.PanelGroupAppInfo; import io.dataease.dto.panel.PanelGroupDTO; import io.dataease.dto.panel.PanelTemplateFileDTO; import io.dataease.dto.panel.po.PanelViewInsertDTO; @@ -106,6 +110,14 @@ public class PanelGroupService { private ExtPanelGroupExtendDataMapper extPanelGroupExtendDataMapper; @Resource private StaticResourceService staticResourceService; + @Resource + private ExtChartViewFieldMapper extChartViewFieldMapper; + @Resource + private ExtDataSetTableFieldMapper extDataSetTableFieldMapper; + @Resource + private ExtDataSetTaskMapper extDataSetTaskMapper; + @Resource + private ExtDataSourceMapper extDataSourceMapper; public List tree(PanelGroupRequest panelGroupRequest) { String userId = String.valueOf(AuthUtils.getUser().getUserId()); @@ -402,9 +414,9 @@ public class PanelGroupService { dynamicData = request.getDynamicData(); staticResource = request.getStaticResource(); mobileLayout = panelViewService.havaMobileLayout(templateData); - } else if (PanelConstants.NEW_PANEL_FROM.NEW_MARKET_TEMPLATE.equals(newFrom)){ - PanelTemplateFileDTO templateFileInfo = getTemplateFromMarket(request.getTemplateUrl()); - if(templateFileInfo == null){ + } else if (PanelConstants.NEW_PANEL_FROM.NEW_MARKET_TEMPLATE.equals(newFrom)) { + PanelTemplateFileDTO templateFileInfo = getTemplateFromMarket(request.getTemplateUrl()); + if (templateFileInfo == null) { DataEaseException.throwException("Can't find the template's info from market,please check"); } templateStyle = templateFileInfo.getPanelStyle(); @@ -414,7 +426,7 @@ public class PanelGroupService { mobileLayout = panelViewService.havaMobileLayout(templateData); } Map dynamicDataMap = gson.fromJson(dynamicData, Map.class); - if(dynamicDataMap == null){ + if (dynamicDataMap == null) { DataEaseException.throwException("Please use the template after v1.9"); } @@ -588,15 +600,15 @@ public class PanelGroupService { cell.setCellStyle(cellStyle); //设置列的宽度 detailsSheet.setColumnWidth(j, 255 * 20); - }else{ + } else { // with DataType - if((excelTypes[j]== DeTypeConstants.DE_INT || excelTypes[j]== DeTypeConstants.DE_FLOAT)&& StringUtils.isNotEmpty(rowData[j])){ - try{ + if ((excelTypes[j] == DeTypeConstants.DE_INT || excelTypes[j] == DeTypeConstants.DE_FLOAT) && StringUtils.isNotEmpty(rowData[j])) { + try { cell.setCellValue(Double.valueOf(rowData[j])); - }catch (Exception e){ + } catch (Exception e) { LogUtil.warn("export excel data transform error"); } - }else{ + } else { cell.setCellValue(rowData[j]); } } @@ -631,7 +643,7 @@ public class PanelGroupService { String viewId = request.getViewId(); ChartViewWithBLOBs chartViewWithBLOBs = chartViewService.get(viewId); String pid = chartViewWithBLOBs.getSceneId(); - DeLogUtils.save(SysLogConstants.OPERATE_TYPE.EXPORT, SysLogConstants.SOURCE_TYPE.VIEW, viewId,pid, null, null); + DeLogUtils.save(SysLogConstants.OPERATE_TYPE.EXPORT, SysLogConstants.SOURCE_TYPE.VIEW, viewId, pid, null, null); } } @@ -645,54 +657,55 @@ public class PanelGroupService { } - public PanelTemplateFileDTO getTemplateFromMarket(String templateUrl){ - if(StringUtils.isNotEmpty(templateUrl)){ + public PanelTemplateFileDTO getTemplateFromMarket(String templateUrl) { + if (StringUtils.isNotEmpty(templateUrl)) { Gson gson = new Gson(); - String templateInfo = HttpClientUtil.get(templateUrl,null); + String templateInfo = HttpClientUtil.get(templateUrl, null); return gson.fromJson(templateInfo, PanelTemplateFileDTO.class); - }else{ + } else { return null; } } /** * @Description: Automatically save panel data to cache when editing - * */ - public void autoCache(PanelGroupRequest request){ - String cacheName = JdbcConstants.PANEL_CACHE_KEY+request.getId(); - String cacheId = AuthUtils.getUser().getUserId()+"&"+request.getId(); + */ + public void autoCache(PanelGroupRequest request) { + String cacheName = JdbcConstants.PANEL_CACHE_KEY + request.getId(); + String cacheId = AuthUtils.getUser().getUserId() + "&" + request.getId(); CacheUtils.put(cacheName, cacheId, request, null, null); } /** * @Description: Remove panel cache for specific user - * */ - public void removePanelCache(String panelId){ - String cacheName = JdbcConstants.PANEL_CACHE_KEY+panelId; - String cacheId = AuthUtils.getUser().getUserId()+"&"+panelId; - CacheUtils.remove(cacheName,cacheId); + */ + public void removePanelCache(String panelId) { + String cacheName = JdbcConstants.PANEL_CACHE_KEY + panelId; + String cacheId = AuthUtils.getUser().getUserId() + "&" + panelId; + CacheUtils.remove(cacheName, cacheId); } - public void removePanelAllCache(String panelId){ - String cacheName = JdbcConstants.PANEL_CACHE_KEY+panelId; + public void removePanelAllCache(String panelId) { + String cacheName = JdbcConstants.PANEL_CACHE_KEY + panelId; CacheUtils.removeAll(cacheName); } - public PanelGroupDTO findUserPanelCache(String panelId){ - String cacheName = JdbcConstants.PANEL_CACHE_KEY+panelId; - String cacheId = AuthUtils.getUser().getUserId()+"&"+panelId; - Object cache = CacheUtils.get(cacheName,cacheId); - if(cache==null){ + public PanelGroupDTO findUserPanelCache(String panelId) { + String cacheName = JdbcConstants.PANEL_CACHE_KEY + panelId; + String cacheId = AuthUtils.getUser().getUserId() + "&" + panelId; + Object cache = CacheUtils.get(cacheName, cacheId); + if (cache == null) { return null; - }else{ - return (PanelGroupRequest)cache; + } else { + return (PanelGroupRequest) cache; } } - public Boolean checkUserCache(String panelId){ - String cacheName = JdbcConstants.PANEL_CACHE_KEY+panelId; - String cacheId = AuthUtils.getUser().getUserId()+"&"+panelId; - Object cache = CacheUtils.get(cacheName,cacheId); - return cache!=null; + + public Boolean checkUserCache(String panelId) { + String cacheName = JdbcConstants.PANEL_CACHE_KEY + panelId; + String cacheId = AuthUtils.getUser().getUserId() + "&" + panelId; + Object cache = CacheUtils.get(cacheName, cacheId); + return cache != null; } public void viewLog(PanelViewLogRequest request) { @@ -706,15 +719,15 @@ public class PanelGroupService { DeLogUtils.save(operateType, sourceType, panelId, panel.getPid(), null, null); } - public Object findPanelElementInfo(String viewId){ + public Object findPanelElementInfo(String viewId) { PanelView panelView = panelViewService.findByViewId(viewId); - if(panelView!=null){ + if (panelView != null) { PanelGroupWithBLOBs panelGroupWithBLOBs = panelGroupMapper.selectByPrimaryKey(panelView.getPanelId()); - if(panelGroupWithBLOBs != null){ - JSONArray panelData = JSONObject.parseArray(panelGroupWithBLOBs.getPanelData()); - for(int i = 0;i chartViewsInfo = panelViewService.findByPanelId(panelId); + //TODO 2.获取视图扩展字段信息 + List chartViewFieldsInfo = extChartViewFieldMapper.findByPanelId(panelId); + //TODO 3.获取所有数据集信息 + List datasetTablesInfo = extDataSetTableMapper.findByPanelId(panelId); + //TODO 4.获取所有数据集字段信息 + List datasetTableFieldsInfo = extDataSetTableFieldMapper.findByPanelId(panelId); + //TODO 5.获取所有任务信息 + List dataSetTasksInfo = extDataSetTaskMapper.findByPanelId(panelId); + //TODO 6.获取所有数据源信息 + List datasourceDTOS = extDataSourceMapper.findByPanelId(panelId); + + //校验标准 1.存在视图且所有视图的数据来源必须是dataset 2.存在数据集且没有excel数据集 3.存在数据源且是单数据源 + //1.view check + if (CollectionUtils.isEmpty(chartViewsInfo)) { + return new PanelExport2App("this panel don't have views"); + } else if (chartViewsInfo.stream().filter(chartView -> chartView.getDataFrom().equals("template")).collect(Collectors.toList()).size() > 0) { + return new PanelExport2App("this panel have view from template"); + } + + // dataset check + if (CollectionUtils.isEmpty(datasetTablesInfo)) { + return new PanelExport2App("this panel don't have dataset"); + } else if (datasetTablesInfo.stream().filter(datasetTable -> datasetTable.getType().equals("excel")).collect(Collectors.toList()).size() > 0) { + return new PanelExport2App("this panel have dataset witch type is excel"); + } + + //datasource check + if (CollectionUtils.isEmpty(datasourceDTOS)) { + return new PanelExport2App("this panel don't have datasource"); + } else if (datasourceDTOS.size() > 1) { + return new PanelExport2App("this panel should hava only one dataset"); + } + return new PanelExport2App(chartViewsInfo, chartViewFieldsInfo, datasetTablesInfo, datasetTableFieldsInfo, dataSetTasksInfo, datasourceDTOS); + } + + public void appApply(PanelExport2App appApplyInfo){ + + } } diff --git a/backend/src/main/java/io/dataease/service/panel/PanelViewService.java b/backend/src/main/java/io/dataease/service/panel/PanelViewService.java index 6dabb1229b..3a788e4605 100644 --- a/backend/src/main/java/io/dataease/service/panel/PanelViewService.java +++ b/backend/src/main/java/io/dataease/service/panel/PanelViewService.java @@ -11,6 +11,7 @@ import io.dataease.dto.panel.PanelViewDto; import io.dataease.dto.panel.PanelViewTableDTO; import io.dataease.dto.panel.po.PanelViewInsertDTO; import io.dataease.dto.panel.po.PanelViewPo; +import io.dataease.plugins.common.base.domain.ChartViewWithBLOBs; import io.dataease.plugins.common.base.domain.PanelGroupWithBLOBs; import io.dataease.plugins.common.base.domain.PanelView; import io.dataease.plugins.common.base.domain.PanelViewExample; @@ -168,4 +169,8 @@ public class PanelViewService { return null; } } + + public List findByPanelId(String panelId) { + return extChartViewMapper.findByPanelId(panelId); + } } diff --git a/backend/src/main/resources/db/migration/V40__1.15.sql b/backend/src/main/resources/db/migration/V40__1.15.sql index e6b292b6ce..484c3cc94d 100644 --- a/backend/src/main/resources/db/migration/V40__1.15.sql +++ b/backend/src/main/resources/db/migration/V40__1.15.sql @@ -8,3 +8,29 @@ CREATE TABLE `sys_external_token` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci; UPDATE `sys_menu` set `component` = 'system/datasource/DsForm' where `component` = 'system/datasource/form'; + + +INSERT INTO `sys_menu` (`menu_id`, `pid`, `sub_count`, `type`, `title`, `name`, `component`, `menu_sort`, `icon`, `path`, `i_frame`, `cache`, `hidden`, `permission`, `create_by`, `update_by`, `create_time`, `update_time`) VALUES (41, 1, 1, 1, '应用管理', 'system-template-app', 'panel/templateApp/index', 13, 'display-setting', 'panel/templateApp/index', 0, 0, 0, 'template:read', NULL, NULL, NULL, 1620444227389); + +DROP TABLE IF EXISTS `panel_app_template`; +CREATE TABLE `panel_app_template` ( + `id` varchar(50) NOT NULL, + `name` varchar(255) DEFAULT NULL COMMENT '名称', + `node_type` varchar(255) DEFAULT NULL COMMENT '节点类型', + `level` int(8) DEFAULT NULL, + `pid` varchar(255) DEFAULT NULL COMMENT '父级ID', + `version` varchar(255) DEFAULT NULL COMMENT '版本', + `application_info` longtext COMMENT '应用信息', + `panel_info` longtext COMMENT '仪表板信息', + `views_info` longtext COMMENT '视图信息', + `dataset_info` longtext COMMENT '数据集信息', + `dataset_fields_info` longtext COMMENT '数据集字段信息', + `dataset_tasks_info` longtext COMMENT '数据集任务信息', + `datasource_info` longtext COMMENT '数据源信息', + `snapshot` longtext, + `update_time` bigint(13) DEFAULT NULL, + `update_user` varchar(255) DEFAULT NULL, + `create_time` bigint(13) DEFAULT NULL, + `create_user` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/backend/src/main/resources/generatorConfig.xml b/backend/src/main/resources/generatorConfig.xml index 3a22039abe..0c95002c42 100644 --- a/backend/src/main/resources/generatorConfig.xml +++ b/backend/src/main/resources/generatorConfig.xml @@ -63,8 +63,8 @@ - -
+
+ diff --git a/frontend/src/api/panel/panel.js b/frontend/src/api/panel/panel.js index fa269dbc94..0b5a510ba1 100644 --- a/frontend/src/api/panel/panel.js +++ b/frontend/src/api/panel/panel.js @@ -299,3 +299,11 @@ export function findPanelElementInfo(viewId) { loading: false }) } + +export function export2AppCheck(panelId){ + return request({ + url: 'panel/group/export2AppCheck/'+panelId, + method: 'get', + loading: false + }) +} diff --git a/frontend/src/api/system/templateApp.js b/frontend/src/api/system/templateApp.js new file mode 100644 index 0000000000..58b05a720f --- /dev/null +++ b/frontend/src/api/system/templateApp.js @@ -0,0 +1,48 @@ +import request from '@/utils/request' + +export function save(data) { + return request({ + url: '/templateApp/save', + data: data, + method: 'post', + loading: true + }) +} +export function templateDelete(id) { + return request({ + url: '/templateApp/delete/' + id, + method: 'delete' + }) +} + +export function showtemplateAppList(data) { + return request({ + url: '/templateApp/templateAppList', + data: data, + method: 'post' + }) +} + +export function findOne(id) { + return request({ + url: '/templateApp/findOne/' + id, + method: 'get' + }) +} + +export function find(data) { + return request({ + url: '/templateApp/find', + data: data, + loading: true, + method: 'post' + }) +} + +export function nameCheck(data) { + return request({ + url: '/templateApp/nameCheck', + data: data, + method: 'post' + }) +} diff --git a/frontend/src/lang/en.js b/frontend/src/lang/en.js index dfa08ce487..58e78076af 100644 --- a/frontend/src/lang/en.js +++ b/frontend/src/lang/en.js @@ -1837,6 +1837,7 @@ export default { sys_template: 'System Template', user_template: 'User Template', add_category: 'Add Category', + add_app_category: 'Add App Category', filter_keywords: 'Enter keywords to filter', dashboard_theme: 'Dashboard Theme', table: 'Table', @@ -1856,6 +1857,7 @@ export default { export_to_panel: 'Export to template', export_to_pdf: 'Export to PDF', export_to_img: 'Export to Image', + export_to_app: 'Export to App', preview: 'Preview', fullscreen_preview: 'Fullscreen Preview', new_tab_preview: 'New Tab Preview', diff --git a/frontend/src/lang/tw.js b/frontend/src/lang/tw.js index 12065f458b..c086f2c762 100644 --- a/frontend/src/lang/tw.js +++ b/frontend/src/lang/tw.js @@ -1837,6 +1837,7 @@ export default { sys_template: '繫統模闆', user_template: '用戶模闆', add_category: '添加分類', + add_app_category: '添加应用分類', filter_keywords: '輸入關鍵字進行過濾', dashboard_theme: '儀錶闆主題', table: '錶格', @@ -1856,6 +1857,7 @@ export default { export_to_panel: '導出爲模闆', export_to_pdf: '導出爲PDF', export_to_img: '導出爲圖片', + export_to_app: '導出爲应用', preview: '預覽', fullscreen_preview: '全屏預覽', new_tab_preview: '新Tab頁預覽', diff --git a/frontend/src/lang/zh.js b/frontend/src/lang/zh.js index 0a09f968bf..f54236e6cc 100644 --- a/frontend/src/lang/zh.js +++ b/frontend/src/lang/zh.js @@ -1837,6 +1837,7 @@ export default { sys_template: '系统模板', user_template: '用户模板', add_category: '添加分类', + add_app_category: '添加应用分类', filter_keywords: '输入关键字进行过滤', dashboard_theme: '仪表板主题', table: '表格', @@ -1856,6 +1857,7 @@ export default { export_to_panel: '导出为模板', export_to_pdf: '导出为PDF', export_to_img: '导出为图片', + export_to_app: '导出为应用', preview: '预览', fullscreen_preview: '全屏预览', new_tab_preview: '新Tab页预览', diff --git a/frontend/src/styles/deicon/demo_index.html b/frontend/src/styles/deicon/demo_index.html index a779f9a1a8..767b048576 100644 --- a/frontend/src/styles/deicon/demo_index.html +++ b/frontend/src/styles/deicon/demo_index.html @@ -3,8 +3,8 @@ iconfont Demo - - + + @@ -54,6 +54,12 @@
    +
  • + +
    application
    +
    &#xe89e;
    +
  • +
  • data-source-24
    @@ -780,9 +786,9 @@
    @font-face {
       font-family: 'iconfont';
    -  src: url('iconfont.woff2?t=1660024163434') format('woff2'),
    -       url('iconfont.woff?t=1660024163434') format('woff'),
    -       url('iconfont.ttf?t=1660024163434') format('truetype');
    +  src: url('iconfont.woff2?t=1662616551987') format('woff2'),
    +       url('iconfont.woff?t=1662616551987') format('woff'),
    +       url('iconfont.ttf?t=1662616551987') format('truetype');
     }
     

    第二步:定义使用 iconfont 的样式

    @@ -808,6 +814,15 @@
      +
    • + +
      + application +
      +
      .icon-application +
      +
    • +
    • @@ -1897,6 +1912,14 @@
        +
      • + +
        application
        +
        #icon-application
        +
      • +
      • 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 AUjP6A delta 19233 zcmV)4K+3<&ngP_A0Tg#nMn(Vu00000Ow<4i00000el(F3OMkKe00};OJGX#mYaBp*T002oG000BE000Iwz2vmS zlL!HXf4OgzR}{wKpT`TE0kba#n|rd$h-An$)6Jf3>SqUFuekdex@^4e6i`>9CIJgih&< z&T3TWbU~MOMPrgmx~?0#rQ5~2VneaH*j7AH94lQcT`H+uC^we-$|L3T<45n@0Z|#h z_5KXm6BbsKBe@iso zBB7|kBCBYIMQYJZtNhMc7D-04Ei#SfSfm@xwa7V|XOVa`-y-{HfyF663oXtAYP2{R zXpxck78^OgCd(aAv&9KQON^ZBQX}WO%*gLwZsfdISe!Yu(&F@?RYtDIY9rTUjm6nS zYmHo+br$Cptv7O=Hdvftw9(=;f1^!CuHR-O*KdnuW!F~APM~c@=3={%x!7T3E_PaW z3+*y8BfBjs2HIoUS+v)pil7!F_oUUx%(h$97}Q}=ZBVC0-9cRz6$o`()FRYllliYf(wjs6|ah=Zu`k1taHr*~tCBVp&0T)uIZcG0SeRYer`9 zFC()oBePsGa-XkTRB&{|@;?OKG;-hmHFB?R8JV@)7B!z@okjJh*kI8IC^lPk1d44I zy@BEZi!MQN%%WdVx@gfke<)qD=pmG3(M>29Ecy!NMvD$ZxzD24P#(7EI+RB&`VZyv z7M+OkBNjc0@uSAR{{WQ_4gCNBc$}?$2Vfl4nee>#rtj?R&bHYu?XGrLy==9*+&kEo zB^zwZ-NxVo28U*_Omhe!Bp6aCp(T*m$t4$vNxc)0P|KxdCn!x0Tz?9pJ9#IFyt`N%R{&GhhaC zj%chm7x0P63$jGz2RDJI8V1%!G{XoQhIWQU zMtp&$wt>nw2ilqfKIX>l%w6#{^m*Xd*RZ!O91Mor=Ae`vklJ^4z>a3q?>Czx9;1Je z9ki(5@L1c8kO9vp&#*Z7@i6A&JV(Z1%-gtbZUM)ot0R@oe-z3C$Q~av;FClI5zNhk zSqe#15FMd1D#2J0$cJFKawY=L#fvwse{TJzquF#id-Sxk;u?*^?_&q{??3RdX&1W9 z`n?kNsmP^fdsE!@RM??rvc^VTu-x@i29N}iBvBcXF1@n;#Fix zMavbB1bMw4QoLpHT9r?(`%I!I>5C@B=AJGkj~aRwfAps490^mupZYxh37OA1xd_(; zJ7bvRNFqn~f{*TtR01W81ltyDQ>15lQpA)*UmXhM22rWdfig)KqW*IPx>5VJyLR*q z4D{{Tb*=SH)K1?^H;TFmRksM5}6zo#iL+3 z37J38f46hjUv};6>nB?$pN2v<{dg0UmYKY=zZx-MJ$>XBJMmqD8}iW-@SB5bYxNj; z3E+bdMxmR#gyUxPlR*duAIv267s_mJ*T#tCbAcG_^A?oM^uxXU3x)g|fB{vzBk3B1w}>6E=b!)$d)0>+x0Q=Mm&${ZtSl*$~aSyNgRjTxv; z6z3M(AY4j#E3|A~zomsYA%F2R(W zf7K;$&Oq$2{vCCRVx4G6)~B3Kbe?2@2OY4!jyfeNE_y^e7#wkF1?ohd%msm;coUmTTfT#*Y*Lx&HK{rYXUtGceD%*7qO4e?f@5+BdE8TF;1Qhj}C zXLC<8Jf|Upbzq~lwnJCYcNBf!cI#)pRstDR(iUau!FXG&sj0WAiH_aWDe^JWf5PQq zAPsw6Lj&pBEhhW`rv1}_bT`l?pHHwY01qr`e4MRPUeI2zjQ&(}GvDj7Acs7J^Mn*Z zMDMqT=~_k;itLnbzv`N|3jwEfiY`E8-pah@0rLZEYWhXv6OnYte}j*CLg~mv z$OHDsDB>!|@aX8s2t1feM=U>U%IlFdYGHjFMUM{T{LH-(T|$bS)aJeA8W%;g$v>uPE&%pnfE3v#)u zsIee7V*Ail4Kovs+CDsPe|xRtcH$|n8lJPmr>bRHRX;v{?r=5-|3aQ3>lj9#1AV0k z9EcRy1hCfusk;C@Wjb&>hTTCjC0I}{WCFOMyCs_`W+gF;rgyY-o$PlY;d#~cYtok$ ziRg}BuH%hBK>FyP9X>+&G)e=|0yd8UP6StNru zi%9ipfBuN<4;cLVUpRDLR=y-5&2K6vk>K#Jc+um&S8(0`q#-RjqItitL**^cmu#T< zjKSdc)E~&Zhzn?yURYT+fOMg=Fj+66el#;svLWXnEJl0hqrG<1j$KW+@5@GrArX9^ zC&c#sV*udeqImoof7$7jQ9CpNk{@SjLY^PcEc@}1knu8&-v8LlXs)^kUL(&C58L<6 z6qW-VM>a7?DMKW*A(Ww5Hed=se5VJ1sA@-&AZD=x{gbL%!=ffwt5g+zT-2;Dp%N-t zU$yqhh7jO+2_5lu`q2@I=S|)tS%*Y{=+^HfQ?!0d2=a)ge}oKTeeWw@`LZ<*$u!eE9+5@fB&38OD0OdPw6NNfDqaeFnjR~ zVl+{<;W%3IO;P+gR7D$vuISm;1J7fMQml%1+#rowwlO`SThZ_ps9J^$5l#=qZ@%IB}$|s6o_EJv6 zkEWe5K$6vLsl<$Isp)KZ;@=&Bd>xK|7ga}{!y#Cr?MH724hT?1YrGnR-mqgVu^Lm& zc^uw2IJeo}Z8N>9hVDCec+Jb%^ySnK$wQVO|h5QQ*-b#T!v}zNSPxh}1*u8A+{URs~^9;34P+ zU>cEf@vnjPv+2sI=ZHeeT!G`v@&IN8y{8{GMHUFRJgie7>JdE9Bp0W;G2mO65esm&GR~JAh{4H@K z%3$zMU_XXn4oX}P3<3=XR@j->xzM|Cie|@?S zeJ7H=anLJ;Zp@?(7(#UORSoW*qhHZ@wkJjgiT)A%S4_eZIwVBy^MrQp-h&sv^Ji|=gM@#a}*W>ECEQ8V=!Av)VLfN5icEQCT2^` z+|f{)7hJHj?c(sSy-sU~)9ZDjdz@Zt0d-9Nhmp2$ zxUJY0iL@=X?hR)$VcZZ-e37f2*>o=$bi~&4CBK zMEh(tcMW&JgGQ-OQj|4oWKUSxqpEw9$ncy?Z@F}i2kP%!y=AxyI)WA}5lEthJ@Ovl zQ1&Qiw564{CBtTe4R$KgZgX*Lu2RUx?Qu*uIDik-$wqzDZh_Uzd@tFpv);y<5cVKi zohLF3m3IwqS>1`Ce>tpKXtCV_1kI%_^4fIWA@ZN(TF%XNaJ_<<0K_6u;5SW zL;?<`on%wR`~WEz^Zqz7VP)V#J5K7@7sqI-xM6-aJAcD2+rpjw>YSZ7F1>!);q7yj z*>fCow;x(^{gT5w<~ppoa}JE=^P>lDJg_F0TXO(kOS6s9e{5qk_rDxkcGHfzYHzP& z-i{lV9a?;7+ib^z`Rbf)T?J(+f`zcJ)^FlN%==BE3x3@Hnx^a?S&-+054e>=CIb-9vbb^{aup~5bKx1Zrk^B?yvaO+ zC@*xOKS*BbPEm7Q6TWKu^ zG#MFChhqIs)~qQ_P-XGkBIbjdK>jIcjCjnTaRD!Dyz~)S3rWIDPM2hz3PvJ9)FN2l zLcL?lf3uk}_gjr!(H2}%($lPhGuHVkMgM<0cGz{!u|t3VKN>qSALx=h1w*6dI}AE@ z)^BAXERaXmD!=|;j~%7Y{zy&`gR7^KHp+Ry2vAABP|hky^3(C^M?#<+D3!g%0?8us zDKV%`e#;>XL;>!q`GmGw*WOw~%^KNIy|F`*nEBPFsx*RBbCvpJODEri>6pZFsfAEH(lWs6|zy6}j=X1TN zfBVs6EZmD+G@J#oNa5VU_+=4k-`J)Sud)O*aOOqhv77GLn!=$pOKXf0>7mTbz;Iiu>3okz;-Rd{^NEg*IUOAdBN$8ugNC2)Yr>gWXAGWSe>=UY zfb5b4Dbf`1yiQ4@%J)JUf*K=RMA_w<&|y~$^z_Yk8IF41M|?)7h#YP)>j@~TBfv+1 ztyQ<*stEOlXCe^Pl&!S!-=Nja>9{(W426=x+PTBW$SHR2(7-L@t~iUwDOZ^sp-MQ_ zB$zO!Hn4#~?+WC~U6coA>^LJGe;CvP#GaA5lJww$krOPQ5uz+(98=gs6TzO?UMa>4 zvARMOKOYT+>*M*!A0|xvyqQRtm13|SANQC0%Kn@Drs=1=nIjOmDKOL)Snu%HIo3hw zf4Bk;)4b6fY&X|A{4V5D*F$LY=}crao{v`wP=nJ|sKY10w~v)xpeBAhe@%2_pwwUX zt18rB4nkpVLr_>e;8;&9|5~6L+CFH9u7lL2mg#H`wr(rr4KfT+pr6Xx%XHaR7ajZ= z^hDOQWe3&L=Ve)woxxOb?uI?@Qe?M|Zj)u}fS#DYc+aX! zO4x}*4mVn0eNI>3d+GYYf3EPr+Jz$ngG~m(hT_ch_pBUR(b=N`gw?U4TURLon%gjt zLk`pz=53Y~wAt}FWl{iM z{dPlP?wR=&sEfEy}GGx{)yiVEUCty>KafI8^$JMUOM3dltff0wQP+UqFfbvw}a z-N?#zY~69$`ith)j|^XZ?YlB)k98Ei9ahY98j5QFY|xF6GIO4 zoGV~G^f_KOL+R$yZTl}>u*fBxupY7=;#9^vOpqZar*fP@AyH`#P)0`eeM|S*@O8)I z>}UN))&7%h<4~p0e^4wo;FIZM5$7Mbh90+OKaO^s?ZEqs4V40gA~o zOx7^749FfHFEp1DdnRpv z9V(h=$+{EwubX2V#Y|=PI`mH`PE@w^fCo>k>#lrp&K&D^e{<%XfZzQgWPq`54*vC= zb@!iGS2ggzW{T@hpj^+o%4~4;pnso(hUZjXIkE0U$XazGbpM<=&6 zOV2Vc9k~31|NPG%ynJBt2TPY?yl>wt%a$$u-IMFu8Layhd5!FavF_&<(31m{FBMB! zK+4&6pik(LC?E~GcI{Ox+IS+6r*N{z$A{?mT~Bb|&PACQxhh2R071cGSB&M=u&1 zyYRNUe>R@)>da=|zNWKO>TKyc(6yqYV?`I*7`m{pdrc_LPky0(XmEJZmDwbf9g0kr z^(hi%yJ0T3klRVmnW>zB5#&{&Cd`vfH02pG%}DnCplM=gI!%=jJtNIOP|oVDPLH;Y ziXFFU9_LoY>5Tu|zoDKthd%o(nsv^!htbVce}HLS>r^gLw7<~kzi8leUNVHDchRW3 zSd0~7r+L4q##x`lE*e?+1B=~FBX?Khs$=s>@^!Lu`h2g4TmEJ_Iyo17p!^h*TIRD- z-p@o3faYu=XUZ(6sB9v|PMof{eiuw6g2(`zlX~L~TyIS<{}Aff zf7Z9N4=5t!ZeCdR_5;yGRwRPf?)7v;{GwloGjSa3B|7gl;xupC3!%hv z0cjMeC(Du%B}W-|ysgUU932LV(~RQCHk4DltvcMzmvVU@y1fdYEb|pq%nZ5^*bC}Wuip<38UU6yHo{7je4DzC6QNV$vl?G`!{LO%)gjT zaiy-wa7e(V>{iqAkdbnFaJ1bpeMTXsA>G^NQA3`Tr-9;6G&ME#PBKOIa~qhJ7mSDq zoEpwVcsLWy7ATP(XIUTH2wd_C{#HKU!4 z3NJcmm3pu6n+Oxf_7AqU0aRVLk?e2G-VVTZ@77Isqe}N{-(P&8J!oHLr3IhP2FVl!P7V)lZS;h`glqIaq@04|3 zlDjtz%CIbC2ay);nIk)R#bNMRmDjwdtwUC2BCA-=b*)%=G^8%Ns5uzSgu_d>ZA%w< zy!+C9KfFTD%nw1(;%(br43uKRo^R~BWG4;=JhKM6&A8tm_a|h8f4i=^P!=%}oq_m@ z75xD}UZwSAL>W7!t|dB_T+S<%Ia|AB*(uMtY?+2tw|;ziY|{0uP78N zM?+@wMT^u>dfWCT;c&Wm{*^!4zi&5=g&|;ZFl_xK5Zt-zl2iNQWnVB94AiYy5%=pd zMve=w=^{ddCmsm&f3I9wJp-GIzXB8rR|W!KVItM6!lXGsIZ|nksQ{(_SBiL&HEC|B=~~zoP6U{v$QVPY0)2GV*BHThVI?f7tqage)W*0N#gyGVBAc z{VZq?Tq8ST29Pd#Pb+RPv_=;mMQp%r*EmI~#yk>7<+WgaDu}(o6i&QwOjMthpVsBd zZ|DKqq58nFK;0o(w|*RLZl2ZL9MwIZsK-M#q=J)Q2&Pg&GB23wR%DDNb@FpG3z;W7 zu~}DVVy9eLe@gSrYTiNfL_Hj*PfbqU%Jbw(PJ@0>t(1A(N^UdvPVNNv8SeAk7rAe6 zFH;SPnn)Yalh+oq+M-~oST3~#u#U0Ah%6;^82SQ)1)E5C>wIUWM7BOznaOf(29k|q zxvR4)%LMY%nyn<0O|eZ2IqT5rk!1`f6lGIeKz8{_f6?qpWxHxrhmAgLsee9o`UK#W zJQa`bSd-7M$tQc0$=>(Jciw-O~L?X&^Ms&HM8>U}!|KQxoH=Ryl{mA8LZg$1;@kB9ZUEWlh)e?#qu`CL* z9!2-NRj*Y>I3My$yjNQcDAPc<`;sy59H*BTf7@pfB*@loG=DyNu*FOZBvwhD9{y_sxksJ#-86oHYoy|V6UhF zoX?p7Kxb@OF!_3J0NdCtRXY?T_a(1gF??dUq2A>-9b=a*duJ)%&GU1HiZ?A>{?6S! ze|;kHXdcDqN~MwqX~GrPCR4w3dj+|$_M!_4sIayWjkv>3wIP!qTb#)(-mr6QQPx3> zuFhy<6dv3TIT{*VKGkpHJiWYn@S*=3~yCbo} z1$kOSUKYHDY7j?u(bx{C0IYnrL3N(*f1`y*Yv;+IB3~oRxi~$^6lN}cBX7*uJyiSx zU{<7T1|_#lYEk79%ARxq)A4ib^>nF}#;eoCxy_54D<5lF)B+FkqwiU9UB^3#TWM@h z?hy>BAo0SUmN|)_3-g5rJl2rUH&_p#%|KnkQ+XH+lt*z{byZHecxS1<;bF+pe;|0I zhdo|ZBnG38DSRFWp4#LZxGrvX6=K?lI27*9aF^|F*#e`)OivS<*<+uW2I`r#RE~K~ z(~C!`Im7)vc(bNCImgFr{F@nZm8Ypb32C7bS#xs4wvV5qlsCCY*h$p?U7t|m&3(eh zEmkXHwa#$wvHMb~_6`4fauh;*f8-dLle@|2=Tt228M;?at}#1WZYljkD=a2EJR6Ep4hYYm5pttH6~}QlxfXW1p&K$<9Te zJ^9&pFJJy{+p=~#ea-`0H}~`ltEfWgDzUG3^VTcuz}|jwH4R)%1GinFe|vT3cO{=w z!oOHFT>!NzzG||5$a?_tUIBUgM7uztzsC+dunh`C-$bUO>x%V?E`3*W`XsJOPre3l zDZn)XE?>-@&y7%R|I}%9>AWqLFsqnnS}XzBCPNs0sZoqDBrr@>q-P^QDW5Hy2_a=l z*#tH-4XYO|XolZ{MXQ(3f1ABV?PwNe71v&P(eCvZ7E7h#h3j|E9!PHRgfR)a_J$WW zDeC7!C{$iwDy`o`jc4rngvFG9o*5nGa zit9K2VB`AYtUx`!H01f2Ah>*WEwb==Psn<`S`ZjFmlH=WDAymce`UE7zc%4qKry#lXdt6QWAz&Qu(VO(b!_|~Nr|zvL)Lky!)2iF)Tr`{P5ePphl( zbSjs0k0gpNpC5{^+MIo+3Y%vq{uS`WCQwpQF2-fJOM!mk()7Yed4QBlaV+UX63d+= zg*vn8X}kpEMHdx4bfCDfgJHyCVVXl`ClxxTtIg)5&8k+)e*i2r$Td(s9})>=5v7!F z&sT||NrpOExUI@BiE&IZ0JO#qP1)^ZNW#t%$LOlASV;65b1vM{kzbXQydLUmdEfO2 zy$e}i=!|8f(QFLuN$y)1i`Lh9qtV1b#Pq7Zq!wsQ?pvTcv8HGtQ_C-JL>^dq9*4(Y zzqlzH^~Dq3fBbok9!XS!Apr?|STW3X{qcGv8g31EO%#vK8uoipQ)4FAeNA^mz275y zVH!QCad{rdSr2d<4%y}I&CSiGe+CoP!UPeCp`fe^c4b;3ZbT!E zOP~pwSC{NId9{#3*0APSxDSobzIh-X5sBb53;~6r-PiQw&TH}nhG(T4BT;8Op}TVD zH6kF4c%-^LF!@3to4j;Ea(3JijU?*&*9Ak$ynV2A9I*FZ1^826l{?!~XZuvXgG!$1 z$-Gg0e@ULI-4|1co!0wP-n;>}krJqgxBAlXiE;KD8iE%OO}j0y5jQ?Q#nBM_;J7t0 zjy8>>2ZtsnhVb|}bykLk2u;djHjQ&0w!T~N@pH(TU`eG!xoDvm3#aw%5*PpT9vT ze}?ei0Oo`NZqLv$ga-L%GDpyO;jBvpc|2~tVm5~;wrY%8AB<-kV`xh(YyA#A>J5es z>q2iZ=*6E1w}h~-?rkl0{e;MFkh_ylz(%G_o zeNYgyX&V`MohY3Z&Il~0OK5aI75H5?fA6rQs*?3_m&^LNtSIvMkF7t@h$%FDW&|2` zp{Bk&?&xcn$Gbc({s~EXf;r})jyvwSbVCEQ4 zkyj`qNTp#+A1o;$I|c?(0mN1;705RP(q~<6UEW6op2s{!&!Ok2Qy|t#!(&)0e{By9 zMiP(wypa6)&yx^l@L00`hA0C?IwOSXf1i|!5GD~j zjNVbid0>nf=VMY4g13~(reVDNT|P)r>?%;DW~%kTF0ocs#{{}<0w&cbgVen!XAfOJ zD&$kARiLxB3_5$JQgogYyi`|&il_(ai8PfE`t3sx$)75eB&v&375qRbbVZ_*NUz?~ z+f(#pTcTO$Rgx@KuY607f31?LGiBitlL%J}Wvb&6`jNZNuaI`3IbvNKX%^av;*X<0 zp)*4n2gfek5uRFeNnTQe|;SlpQ|VkB;f#dZQ9ar6LuhKCDmsv}DARWIa^x zwx+_#WEdfLeMqkle|xR})V)B4BEb{G^UCn6Z%gcj7uC1b*Eu~p20{SOo3(ouJPC8R znee&;u0syB-rP$&2u7VI@28qG%4M{J3%lC?_WN|QE-B`UgD%}0@kSzEJtVuF^}HeL zf(&rMp}3`el9-hgNo*9AbGfYVVNuv4ItVk-9Zp3TWm(i^f0tqFRvE-MsMaf$<%YNL@5Ffk#nzfZm z{ZH9$wa3cE1m9w3$ezUZAdW7tP8{s9YsH|+l`6cZravbyJ;V)?MBP3$F0X}?LJs- zHh$Yb*lg6xn$2j2Pm|}#QlNksZAQs+N?n`w0RVLXe<__oRXRK?OF9lZ*6@?^A%T&#N*BHXnV&jzc*v8KkYAj;kR!oP4|wrrdI2jHvAhFR(?m@k>+@O zh(>ltV)f>!KW_ZB!$E#||~B?r`{`Xbd3CH<>b5yY5@{UQrE)h0CwL;SwPd zR>gPmhQpLUgz@`%cfha?<&Myl2eYaVa;xw}e|=o7U;jbg2K{PdH}q$SdNXON$7f%v z0+^i6Fhx3{4cVQ9SwZFMIdoM+(pH&-xx$Le=ZpD#l{c`aqEoz!N6)DaO|hQTq7H}i z@77W4HpDqqN5pA;Lg7X9p)N?CQ6oNen-zTRPsa-7@(fAeNT#E6<^lY z0kkn2nvp7NYjun4ii$Kd72f7>9PBuJe|RjB=s4)84>%5{!sh%nYct^a;*2N>dIv*3 zBlZ=5hVXnHmP4EBi>U4D9KXAV>hSfr0#>~pd&lY6*?w1#+Yd=x{?9tM83 ziyou-ao2Qg%+%ik!i<(^LL5g|ntY0TmlYzYleGu^WBtLJieyVmP0% z;z%TC-2qC?q{tIRRG76Oj`psy?nK`L-dpsEU2^3bTp)s|Itf2P2%0oqdY9hdZ3tKb zIu+@Nz(X=%j26?COR1_5dhYYrf6P08Hm|TAL{E3F=oGQoAp;402l&@ckbE~*5+hTh%O1%^+8SIm$BS1)x%xh=OSoXUI(17_kq8sQNr2iR8@d*z}6Qe;IxuHS=Dl zPee~yuToupJkBmb0A)HvsarGzUi8ypUJ+de=7%L-RCJI0*TULDVeLiKD5UyRss8yr zi9`>sOi{gDj3AF|hTHn|Q`AijsDNGDuq#8XjtUpfK$YUKfIYe-^Q%S78!q0B-kD#! zi&n8~ZQhzl_Ra50qEyfPf1VVY@;H%w`NK1QPG|Lg)=}~svWIJ^ec6TnxlLQH8mO;n z1G;Oc|CqaP$ylx!4#|=vhr-3&*b+4B>=3f2=CYoB>(o^q+Re<(*niX>kEs|tY$o_`(a-bN3?t0l+3MZ7YxVqM|LYjv7v1bUAwRUNcDcrCj4skPBqoSsj?nYszabxFTqnT<-GYi zfu6eoKO%`qdSNbQ^Co5VZ5hia@6>>X)_x+wgz(r1d+~E>fB3E+&hRQ=)RLh!N>DxN z)_Bc>5#~in{;AW04efnjRnYiZ0q$@uCDT2gnwq)+*6Q^DlWybQ&wUucbDp*W{(#!e zX3CVKFJ`g@n+UVDy;JOSNA&t1BQSjcny7A!O|_X+y6QI>l*vFA#$*ApoNZ@^XY{Hd z)vKuipnz!ue|*SHKPzG1A!JLRUQwKRd+ZE|haQ|z)V5Zychkm=0R`ZOENtAk$?I)x z^PY}SWdULYS*=E?$`37fxxrgS6k+ddtu$O4Vs zuCUm571!o+YcHloksWc*qsG8))x&!ds@nZ%x8G3fe^ig;bSfSJysBCc6y)w&g8ZZ1 zf=78%3f`kU?$NIfIR{0-`9oJo7+N+Yg!ETcK^YRAqDsc;9ka9JU9UjrSUi8V?m>gq zhJk?wsx1S9!J;WLP7u&N-P{Pf!$--GBK>+n3{#bycHm>^g#_1_BlzzM#zUBP$KA;)9#RWMiT2DenxI@Xu43ODar#|oG#?m zPVkb7J+Qjn4-hpd%R!YqU@vx6;!nU{aXGgyL6Q`P}5} zf9|3BWR+gOp1%n23q2#51u!Z{_5TvEd&;?TDNEWJ(j#I3dFd@a*hy5xYJZj~P-6E> z>9yPf8q&N@!O?=k-F(o9O0xW_5YM`u!Yf(`N!PuBkKZI}X!09Q;buX&NpzA9r+Aa_ zZkOqdUHga;#74l6-{lTC9PY{$4N-iPe|4v|VlyvE{r!^2Zz3AMi5F$?NZ`wjp%c&~27gfn1YNz$9RcO8tWmqI%TB zWqg;fEKTE_%+`n>Zveu+~6 zmle7=6g zgAk{ZdV5;aB8UQqTFR>@{6vh>mKWQwdq^8yyr= zCa4BIrH)g@8qJrY6ym+}=Djd)-u%Yc3$aG4e*Uf2_FLy=1{)v%H^ds}rw5;$|F!w_ zi8eMy=c89E-@o-%oK6p>zXk!Z7r;@wtMXOy3dv97Y}g6*H!Y;9og|;1f1LjWUS0Xv z6Von|J9yo7*Isws!CDzM?|-@sXf{d|6ScQU?zSRSh-R%IcTZk|K1tnV$?o0OEqkn6 zs97!NB!3TCe!3j0&W>ihCQp$$oC+%}Zp$bbe~Qay*ePHaJqToHekhB|COJ@SX*AD&afPXAlfP8sE}dYc zMZLTCD(I;ftz79a{&P{&g6F?@zS-DfH7I+_Mb+(dA}JPE(9ZnHisRilUe9) zrW26@I*4+t!_dAI)r7Fw#>5PF3;LhAXXgE>Bx{;1DVm0Upi_lxe;xe0sxGIq>H_0p z>XoZ5$U3jI6`$)fQbk6qWXSh-4Fs*r*)~vmQ)=Z64)UOP` zMH{N~_zCh+vI=U7vu~SF;j%4W};};a!qq!T3X~W?~y}kwwJ*)a+>ZtXUC!h0J zFFIXO)E4VSgVs}$rkvCqQGcB~oKA<`b^d5=&Tque!%A!CdbkC^A#UfcWVdCewf@i4 z=LfzJ8rW5=YLM76oAR`;rkF?FaU|GLw(NGzE3Ve9wbdlTX zdfE<^3_Fy7!+>&IWJfb~)SmC!Wk5`iCJ))AtX8zu2wg*CtjlCt8RM;O9U?E=EmZep z6!`0ZOoMfXe|C{zGsZSsoS5k$GgXadE=e*{8Erqm9Ugp)*_FnIT&@8hqvp89)QS*Q z53;KIQ>dzQ^eb;Lm z$P(JRRS%Qjk}(*UI5)^G<<>HNlyiJP1r@!NGAGcpe>4@OFgiUjzz#^*{aGLpmCg^ZZNLLu605z-x-&;hi#X{e=k`7WSo5eGN=VQ=$eLqjxt0b_Mt~FeX2KC(65s z^NZHMe}z4sFxmy~`vjzD!hHcD-1J#fh**EXDS8XG@(CV-4PJ5bcsSL!u&<#3jMOh8 z?PV&u0mB}7?6+f;zDzD*zaqInPVEkW> z)(@Qe%tZrt;m6S)WDN1 zM{QZt>tq5?RbgwMn+w=uD`3aB(5e%rmv%DaJzF|-mh|Xs>C)ML^py2mm*4L~9%{~T ze_NlY;=j0m@#1((OPm_`qt??bdH_tf#k&ImH=1+>0{YBwI~Pg?sFHqQ3a21}tMW2L zp((o@YFMxPU5jbVVwWFv2iyz6?OxyxR32eLEOJ`kko=U~!oJ7o1e&djeR%@bGoW)= z?d7f#nt9BbPO{4(W&5rTJAq&~MoC7;e{noOXe9nt@?;Wz)TpfQMD?AW)~lW9!7Xb> zdiyfr(BROgH*Xvs*`sOkx&=KS7+!kI`ug;y+wQty)Yo2Yy#m$KoQVX@ZcTK;Z&ORl z((@+9)-PJJRFXQn9@#v$ZvFh;LHsHjI&k#em-Q)&t~+{rsV&FRyOvC6>KDM1e-r`g zZQ?HCUPDDRhPI+v(4HDgbQT*%sOVmE&Bbxds!xMEsm2Zr4a%V7XzVT0d;u+vvJge0Okf6>jzscLAp zEF_#F)*7VBV@Pv)<*3(%7rMNa1Nb&9h1~US`fUZlx)zDD=(o#WK8i5k zpyA4OYBrM#*#XQ#D35r}w^%n2l3fmgAO&Vu;WbE=SV#oH zscQ{hsJeK2D?$z(_d+kQUk7H~qx+Dq6*V2TBA#fnAc@VXMyH~h2zlM-yS=h3#zJA$ zkOhrbP-|UFTEUn<aC|Lz7$`y}iRYggvf6P7rv+8!gQqUT{e+e-mh7*xW)|#?UCB zq#m#i>OQXv-IUzS^CrrRL;;{KbhgV1MzWko$gfrYh>7NP$k06`r-i~_u^Mq;8S_qT zV&oti@OmN!Vk3w}%wq>uq5!Woh4{jfJ1zi(sdoTj5aNB<fH-SW58 zkDlp9#k}A2r|A8(0qhDB^;AamnNkKALZE_tE}WO*?5=wtR~lOr+j7Lgi@Yyf-&QAh7pw|7oe6jyZUq@mhksojPb34;&s%~?kcR$r35w2r$;6d(uz+oGK2Raiy zrRe4}Pj@1g@_JgE2HTRQiUa2sefWQHD07%l}1?o|7A4( zG@FAV+k{Fi$*vLoJqBdr{p{1WfA@sg2dp}6GvwK>D{E<~YiWURcKz_bj;`%Z9^ucy z8f^qRVwhXc=Q z-;{?OZRk;-QGdG^_o&tpdd7yXR(lqALr_mcJQs`Qtn+=5NMj^|4tb-|Y&6Cc-^0p@9$#svO3P+cjm1nZgVu79nkTCS%V*1V9V+SsSRB3CLi zor0{`W#40}vKM|zma=Pai44tV&bWt0s&1;SklOIL=J9BcI}Jl4>vo1Bv-cj}JA3xt z*^Nu4%76NpVJJ#{~a@Fz-bqnYlJ+WknzUOx}{CC z_YMv1y?SqlN|2c`pB$R0@P1Gbs+(~ z%+LIqS>8y|FSAMTmaFl#bo5MaW_x!({4mt~5c;IG0w}FdSS#sktt>&5NM2;HK+mLTD2SB?0s-j`3Y?=S+thcC;N@2D%(BO}pbRu!{;s zJ}p>(cdDq}83+cP8?->k@4P~FR)YAKPW7=^<10X+^&OyGiS(Z+sViC>?8R zicLOCO)_ipSw%-cFZD93@&J&ynn$OyvzrtRgA?nQq*CZT*1q4~V7+)7I?)uXjDNpHcJ~&Z<23Zk~fa)^kJL25vK(Nz)TXk(SLf(>2aY;8zc=izW3&vKm6h356-`RJl1Y5y62Kh z$RvKo9d8+f&N|f1W2*jPq^Xr&m5zamzfA3RrsSDxSLuM>B$?5~vc!($ z#TO@!EXyUMrAv04Ip+q05KUYU(_G@xu!#M>WHtpnPSHsCMTvfU#{d60`+rxo$zQ2Y z3rcU+`a5bvzAwQKW&elk;G&)j*72jcl{zA|vLFo3{)@uiPo^#8m6V_CK`w*k2v3``(V0APO&P5=M^c${Nk zWME)!_}{<~!)pBh?*Bh5TNxREA}F8~0I*mGo_L&NVPIfjLBan&uwaOj1xGM{NLLei z000000002G0WblK0uTbM0{86QM24Dt|2G$282WAJ{2qXx0 z2%ZT72`~wk3Oove3djp43vdh$46F?94VDf}4)PCL53~>l5NHs>5ke8r5=0XE6NnU8 z6p$3i6)YBH7X%kz7s?nk7_b?CG8xbs@EbrItQ-s+P#mBf@*Q9w4j*bC#vmXdj3E9Y z#3DW-^dmGQ$RrdbG9-#6dL|wwWG28S=qD&AUMHd_#3$$|3Md#TR4B$M{3%W;>?(LG z7Atft0xW7SS}xQtSTHCszA;2Gh%xLkUNX=#STojmoMT{QU|=X^%wiA|V*mjrAm#!> z28RD&J_7(D4+0IdOGrxr0dtd=NgjX2l74-0r0lrNB9^w@dyM z+xQ$`;7fdkukj7;;9Go$@9_if;z#_1pYaQR#c%i>f8bC2g}*VyKM)8JAqF8qiVPAn z%#ovjf<}o2D%3ErxYyZ_g%P#3RYXBeIYnl$&a_I`nLHld(Tb*b8|yf<#%MLIWSW_w zjI;_0u?p$XiBnq!IVEPQt;v6-qPQ33x~7o`ZdIb7YuAr&jGB-{=7y?+Cg!FvQFa#5 z+M=99b!Kb#j-|*;5nr%Ul5kb^1#2NvC6m>e^=fO?1u0Vpkua3%O49wXy~d%8F4R$G z4*99=a$~C~))!1xoih#Ers#_H8);!>G_T1RsnXqgVMTS?VTwIzL@s|Le+pN2G?@(ZQ@pbzJ?v^3*R*%3c8zSkM4ZT2@Cd8++3`(%HIi*LoYldU{DS6kPJ zu0iqLh&+1Cz!tMlVDpNX7{l>Ci8IP=?S{akqt=9pq>f(`Qwn7!PLOh(MT zYqpWWWO!fpd9DgxA0+JPS{ZmwiiKBa#DDjICsLJegS|vE$sEalb`a`3-pP4tshZZM zh}dDH1{<}vmW6*6M~SWqVW$6eoetby(^{@+%mbdPAmRa{syDOTFn+JC9@Y#go;nmg z<{*@P$GpSCU38yeNKBPVYnpiN6m$(OjbF;h*ot~gPQ~r5h}`5Zt>WXWwz@l$al_o& zQK**IyIpBMn7Wl*$T2786K>H=oWB`Q*Th^jze~Rn-H;ZZo_<@E>?(G?w6fIc{0pJo I4yphE0Oa`To&W#< diff --git a/frontend/src/styles/deicon/iconfont.woff2 b/frontend/src/styles/deicon/iconfont.woff2 index 4a60d8cda6f8c258c2b8fd76328793053fe7f02d..e40e790d9cc6be67492049bb9e38c9e07f03918a 100644 GIT binary patch literal 16784 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

        $)?T?tW)Q6`&b#fS7|ie%M-i~o z=7V2?&1Qv2z57wfpU=vU%Gs%h zo$Y|X=$!pP_xbKM(Ua8ws;Sp^Z;f7S1>I_I&6$);a)t-!M#mwiAxEQ*HsUzS=SKWv zJ8+X$mrGFsk|6Su%PuBOYQ7&A(Mgc8(I$Erb_yR5ED1Y7q*x)u6BZ~dK=dB|q}6t@ zVw^*zrKKUw0wuQS0YaT(STD8O4hCQjt^xq*kh1KB3J;IO90MjUMYE?pOZw9^Ye%P0 zh^&cQ`cV790$8DlABl(+g`m9>hgCE(t#Jw5)nPIjB(+U(l2`+56|ctvx( zgpSTQ{p8QZk>349#oA&}oqrXVaw(l|8;a3O9G&uUk3rT9jd)@4g{cck7aW>L!fG3k zzxe`x711+Khc6NJCeX8r(N=0RI-qGk?r5JPcZKiNkaqS@WLbRy`fZ1~g7L;CmXvTa z#K=(W2a}{5zw1H<^*mHxWWs%%T4+MrkFJj0j<&q`OvZ>kvYV}O73`5}M1Y@CBUa-F z&qJ(>$u%E8p=DWPk0|IH|E%$t?@hhlc)~aF5c|Vvi1Dv=;8e$-3D4BSZjY(*)h9_Y z@;Y@05N^^nZASE(!u@Z~kjpsk4P_~hAII?+cAdoinv5oNU0-M3C3N1!L~cSF-b^;uSgkqGByc`MSe^T`C4DfX!X^~6v@Qg-COO zqe&=lP`x|HSau(yF^~38p^#vbpv1jJGC)`G;2F8SQgOUV_@vzk%pec7J6D z%K$P|zd$CQ3ix`AR$*%TQ8y^W*jXl)sv8F=!Bh?aqUTkof3gaJ|2Sb%Y=4d|F!Zp> z>QoxV3YY<=1_1t3_Pw30#UA!p_VE~9{WB#M-9}&_gfzF$t{XaLO?^kS{Pdi@0 zvED6lve_dgUOEk&57$A@{)Kb#d^HOI7y?Ck*zpeq-0&{oKj}Aj9-=fNBZ(nH$R`qj z1MGV(KM0d9HxX;ugjb5pw?fY{Yw3F!!^jP3liO`V zr_aU!J$-tPojjF1%Sm6FsSp8oS9o0gmlyyA2oc1PKnnU_Y0y6*L4n_)1z3_5RnraA zvK`m+gD{GdG|P*!s++d!hjE&hb=!~gx}W#+{rw@rgfcFqqH4NfTDIeQ{{Msh?g+vt zPSPwd%BpVKt{=u}Ue;|t&g*{O@0a378AvIT10~_>0ThZ@cGwk+==At73Wsc_SEoOP zaruwS3TM5k3NJH-QBNSVx|?C&Sz78MdR>ZXB*vk3Q3{?y_dUamuiw0Sd+NW| zQ&h~i>V=;{-KYt#_izy*3-P{j13^qM?4B|79-Wp4oFOpz{ZRW`$&9R}bD$U`69$P~ z?Jl`I$Z0HfLW0$tyw?#VlHt!Jk$SVU5$HvL} zNM&5;4wZ-A&JsoXWbK@!eWR8h@LBAlxcE$jFOQte-DGpRH3B4IWbKqd4x<5|Zi6ie z*hxY@JMgU>dKimjDk)uiM8cjx8uD%5&^X{S+EKAk6xz9mvR3wDWj8m0bhN$*6xhSI z2?haW0h<2Y(_*q6p}#!Y(*TBtH=0@d^Siq(C^5r={=8w6N$rMS~YBBz$IE~90uG$SId`_8zC6_aYB zq1EVtuD-mp=0_GwU6pA~XNi^^c57sl7O;sbFdG3^$dQF0G|};`@FY{k1pIVw_y_<1 D(PxVX literal 16676 zcmV)0K+eB+Pew8T0RR9106`=G3jhEB0Dd$806^0K0RR9100000000000000000000 z0000SR0d!Gl0FK7&n$tb2>~_&Bm;v~3xR9^1Rw>3X9tWl8)IlSva`nk=K&EuuKcJd zN)xL@QPL)s+5i7BxgkUF4bau`YG^LADtp)kYy|chR&QS&?y?Oa=cvc zRR0yHoK+7=iY5rOR%Uh|fVhZPV^9cLml9O8-&^gxUI+k6K+iI<04UjwkU=MM)}Q`7 z@Qkbecm*7cJrJ*pRq+y-7^htY86k+a;m2%<)mUXP5s^a{HgR8P^~(m>lxvEHOR3D= z{h!-;!pKI9kvz6EX^7mcK?HUYfdv$#SSa==f*lJgSZYMT7E4sH)x?$vYE)7*v81SJ zO-yp8H1*DsboDNmnDz-tKBZoAxzcjQ{odL8QoQN*NMk!G<8BFXVBrEL7ui3f_D^&A z7ib>>8XmOyKnY8YA=$-1{ZG0CP90ZD6*xkbcf~0ekL9iZY9gu&d zU+MS2(6T{L!r*|?l#klHR6+&*ZAs&W*~{+18>V)f-Db5s~tY@QPGu^UpoV zHV+4UH5T+pC0D`jyF&mO<_r)V_H$f^w6(Bxy&_@dbpxvNhPAX}k%XHx1qOnWOxzm` zr|^-8Xn*GsewrVA_=F0aLL`PLZ`I!N;Y-C|%j!%&5AkDkx(i|d5l99x=*lb;p9mMC z4R+8RY#|2pA{O)@4s;>} zt`G(thzGT30osuOD$o)PAQ7A)2}~myR3QRBAjQp5r~vCo19xZzo})ErLpr!e253ba zu#8Nwk1WuHY>%dJ05YL1$bxoY1MNXJbO1S!3(AlOav>kQKmiy=N05h3ARnEt)h^?R> z4d5C#fokjqHP{P2VjuW~Tft}C1`csM7{#4n1`mT*I0~NPC2)@SK{q}E^JoHZ@CoR` zm!Jh-fqHxm8t^R`!H-}Se*^*k4i@kau!etvKKvU@@*4}b`AxQ5K?goMCS0;z|k z6!HY%C4X*O-Wj!(Ma@Q0B(lg!?H}M;V9-)H%p1bt=-jiv+>(%_@&cZb_xY8RHxIbv>CB z)M=KM%%LP|PM+o&9ZAukJ)+r2cM?-cm9TpjNK>S*v_?tNT%$bHE|oSpse-N-Wp&Dz z2c{)3Q1T|o#)~-ZyVSWQur85yi_F8kJcf>f4TWB1lx=yFv8Dl|((3PLETxddxUkBD zXJ@5at7HT>UM`gwvNcUmukUqk(6JnA4z!a;^O_-5Fs?a8Cg;h?@d}1LV6iXPXq3V@ zRygK%S+(%c1!`VK$A{L~SPGndwMHVz*~N5A<5w5Y)GGt2`x? zBs0?tMHDH}C$BEJ$=*zhU@&k4yz|i4bzXNmQiuba9iz^H9eYRAjk7}Qc)nLvAq`YC zRQC;REp%6?u(j=I-oo)z#vqK1VWaQwKX{Qn`uckNDq|YeyBAJo8?)G4^tNkgIc3YB zO1U?fs^EpU5RjGD5DGo2(6vu<83t>6Ry=ElOm^|wa>jK%uoOo7ret)GMdhH@!*ruE zkhMpB>jbIuP`_k|JkXY*!9Mh>?>SSee&sJ9{TqLEO$y!Xf5-m$n}74|#@JBS>f09L zpLZLNqoAjm9_?*$hIn0Smt4~X{&+P-Zs^BeB9?x>qoXnjU3-VBXzLSe-O7D*gMqDg z?wE8a;yKgxw`3r980OQvUjyrGHH z(~cd{Q>k}3I+Hhf2D|Piq#i@hhh}1M?toTO=82Y`%AQQTQKEFsDyMx-Iw%ea?AfjumNkiL)EoHk@#ugA63{U1B` zx~|JcTHBn6TUp`WbXysu%Muw>i(tzkpYpA&prb=4T`QHjK+7lEu1G99ptdLv3P(e4 z<-m+RvH8x!3$?&Pj;Pq+s5v=#=`iEl74!uJW#ejbWtuP)o_xmi)~U&9T_HPUkxo>D z!6{Q_|I#%wE?NE#4S`~`9B)WqU*aFLvbV2wdpQ(Ow(X^bGu>yWo$&(el1?894rOun4^H&6l<~)`bThd+!d*K09oS{SOHg z!oA_gREdNC^n}{#096M&7|Nze`)&K}Z`?IBOzzvS*lHc4OqMaXUT0VV`8j6*Q+W>N zl~dxYY)B4AjTmAHuQI)~GjS1@X&GjNAM$H8bR(RnWPBfBoHAqQj2(y4Y7s(7k6jkd z^u-*1?wEIcKDc<)J#xV^x&-^(LD{jk7b8M#`>$iD(96F7#b5v0=!T~Zg1ved}jglb}->unae{}=Abshn}VGAh%II#EB ze)nK;_~V_6gPaGab(R$g2yWArI<<)WPl#kl_5tR3R?lX#nN6v_(N}8?cY^Y3UkuPpAg#pi~?*C$$gd^wX0*8g0l7io3yyy(LDN1|?9(-a_{_=k=N#JszJkTAr6 zRfV|34YQLg9rMBZ>1)WHx^#*FK;u7#2n0O zwcU9ATBtleBHk=7dUBIPIdlPirJ=3cjzRbL>9kAD=IXJidB<<`%ZjWq+YbwS0Fh4mbMd~` zXdPE$#fLe&h9r@So1`~mxT#Yn&#HA2_9g07U|+iWqch#-*>o>d>I;2gkp{mQM;1J#H2XIg$8<-Lz> zE%(Cjzw+7sztam}9-Mywe9*mj(;E2OwT(^!E>Fg0LmFl0>*U$B%ay`BH|$XBJ}spZ zzg;^rrD`&azKcoF!N?SXk}i|L5#JDYFLX&YQRm`-U?wc> zYgjI)=7jqAH-O=~{YohCk`+fk3yQ)WX2MF@8AEOC9D6lFYP+FJlzce;WQoA$B*Nw9 zNQ2=D?4m>RIC3Mzph+3`xE+(qHPbzvZ+%a-zB43&7ppww)O>R-DAaFUt{Fi`6frN= zkdkmy1Kns7zj-Q7?^+SKB!Gj1aq3qIloC6KI6Wk1ca$x<<`7e#@WTnCJOwtqi8V0J z$O#Hi2J#u_8kSws50v81{r)(HxbwG6nK|>~`-5;^UP&H%N$|Xp8~%9WLgUtW5=8a) z2=6${bQZoiG5B@Lmu0^=X`~%otN#5{To_A|>D171Chu-9v1p9xDTY7GC3SgaMpAAP zyQq{%0&%~taia2(iB}rcXXH(!m&r9HCQj9iS+i%5=}VbHr_VmpSUownIKB3x4>bft zsv^u^PVd)pv}y#r*31*;BLR*P%vwbjid4+mluOK+@<-y<-N#dB53iE#*d0e2 zT+ah%gpAToVUtVWW#%UhUmK{648$XI>$hcl7XNm|DJV}Zr%q8yiA}$5m+GH1?o@Q| zaCbC(wE3WU^+yl%uXI0$^1mKku2(@kXtQ2x)Nh1CXj0KyQ}n}=%tm+j>DJGXzWj&! zjfEZI5UO^U_^Quw>Ny6nH(kGW%VSjpac{skyzMLwg(EAp$@ERkXMNcZJ z2)@n>Az!2|C%Re`%|e_VfYFD`!&R}-sPo{qv6C$4GoT$qh1{<~q+jUE{|YWMv)ctj zQ#eb$xEv)OXK@&vvEfB1#yL5}1!OL)%0Jue)EdwMkL|>iBW$I(mJ6HI+A~~?jb}8O z@D?>?@}kjeTP9!kCHQfvQh4V$FrIc1l*U_O#q9 z4D{ENEF0CO08<&SuzRP9XnU&jv2r}{<)v^CV$U5RN++ktJ%T9wDaGe#zzy#&R2CHN zOs1^amzdLKOh6P&dLN4mk#x+2L|WL!f)K)-TRx8;L@J4i{$3@+g{N6ASi2k$%94L! z6Cl}m!tW!YkSUQ88_+`=7oNZ+L8_tfL1QIFqpv+*Gbjc>teT!vTMj1^G=AO$&~XN( zy|(@j4=q6-Z0Fnm1>N_~rwp~lf2~|x(`rWuc=ID5_?7;JSm1#XXjkF#V_^G(Hv?xK z`v;&pt8UC<)zYIyH#IqKv+CjD(lv0?!?607opIs~>xr<8KdgS_P`VM)cGp5fe&mmf zCl%x9#^kiO#gpq#?s#IXX-IlUerlVp(2s%fNkObE)&lVU2^I8+W7_l^5J=@QExku* zj~e^4Nl8bVBJr2gA_d0tdGU>zMCRVU0W6a}s#!~>U7o7ytnM4VOw9yQ1dl;<jqOh;*D;(VGphbm0M*ZfA|QxvX8x~&mkR}mLC$ioNO$i;S}n{>r{x-=gl!U z!Y(rEh?z!IAaSFhbi!+mG=x+lorh3@4)-+elC@A~$xQ!o9=w`0RM)6LY!A3`JbiGu#N z+;z&g?*=yh+xq1{hweSsy!gjEPrBwETi-GE!XIpXre(mVdYDF&u$c<3qV<#{PG&pu z+zcb9<-iyZI$1bXDToDvF8JsSC85C7aqS+2jfcJ0&wt4EmIwAQSZO_h$@1uX|?^y z(ULXh=!$W;on_Ri%|HJ+JmZ-^3M^arK?V(pn_rB4=5srU;ixT0vgg3srV$Rhr)$5K z-~M*g1k{G}dNl&BP9!pZiBf7|f5EKmv>}Z>Nb{;03_{h3Tv8M~1Z%4*vE-BCu{OSJ zOQ)aU3qRq%sL3oImKG6kC%I-3Sf+5+T91yV9;Cc`B29`k>ve7(PyjZu-B4+0ThkRRkkt^halScEMA_^rZeAq zMZ37_{&>x-S2#uV6D4MJjf~d7r$uW1nMtyo3>!r&6E*8BXut=M?^&S!@Vm2FB~O;t zorNoe5{4XR32lRJjA((uAopojrL15HG`BOWJ7HjVLSaMq3Wjh;j%LRY2QzmMSV4gm zoC6QSI>-kjzkc7jAM-r-vuHNWH6) z%NmN$%F8~siwajvhX)Q0HLncV!B+F2XWEMH7W*i`^V(<_BCQX0u??H8kutDgS+ zT{Z=j;4~3FY5JYZo82-0 zI!jN%pMRCn0fdN*LX;`(CD_WHp@JWYg-oe8G4}|yXYE_k_okaKEPG%^oO6z+fE+&* z-cI5IIMK7+^rrLn+)p|#(5%)oc8hAh10@P84fu#463K2_7?-({$VV?aPZq#oq_o(t zC`A)CiJ#xf!GY;H&yn8G4ZPqiX8aDir$JXd#p$8*gIrMy9Q;W@q~{P#FFrt}By28b z48;S!$EENA*;mD!217Cg!DRAK3Q^wgF}U5LR5=>r)@g6>fw+L1L8N`$gBM6bH1pX6 zztHUO?S)r7fM<*uzPW+ei&QZRW0aHqGFX)ciR*%{+N%P(FhC(&$9X85z+O+++){+hiw_ER`K<;9}Dx(4P3atJLKOJ4m4HN7>AJz=BtuDb^jh298j1;K{M&n z9q4lWY}Dzm$PNqNp^CsSAZ2hGm~stWiZ*k58Ff+Tkn9uzv zfmO(eZDixN2Te9_#2^~tHb)*UffAj#Iyibwj)PkBdigT+v8%t48$0k(0#03t4VWF^ zAi2eIlx*Lpcbc-e!hT4vUnX6;cZ~!5D@tX}e*}+@-6o>c{PUgmNqVy=o!;!3&IFzp zZqrB{-UM$P>8!G*n6)^%;grapgt;rK2HEh(J8|&S9sRID2jqCU@rqzX$|1C^3CoW;*kZjR=xBsXuQ_WV@BDy zAMc{r-vvs!9#o3}K9J2_g69PF>5`O07r4aC3uNHT^nz79F}@Ly7?`?Vrw1y@O;ORG z0>f_>4NlUT0+oO>(tZ|z!F)5W3!Dmd5Atwtix3q1C`%E{W|JnKx_q9N0ZbC|iF=OQN&p3TpPCyvX+m@uBSBTM0q@Fx&8ezvb?{K>$r@dIyyT#xDa<9yZ7}g$*R6SI08_VE>?>~YH|84p-QPm zXY*Tkj)h8Hd1!HPaB*n)e;swS(b@dJJ8Qp-D?A6gsfhU~Zm`8*2r_bGV0=MLw0rhU zP)$gRD;_ri3GrX!<0KtH2Y<2?=xj zxr9Uw;_y1GXE{|v(U{Z}wHI@2CM^Q~o#xoC;FC((a)^X6fU^Ko9XPj`;K{~|IbDbE z;D+p+AC9i}?8ckm2e1k6SX`m;3}o`}OmOjBu^2C!w~+ppBhC3uTeYh=I|6q|lm!^K zABX1$iMXk0*f0Lv`%MkTrWajjezP2VjQ-PJ8?_2QO)*da{j{geG3FK>@)R(jv_=d_ zF(#o+`%@gCc^<86iJ)YQ)dQ%lsv2Yt-n^+rhU53pq1adrq5-<4=}H;v17e^UDF)<2 zm7R8*Ix2N4wF>Cf`q8`U09A(4d=yf@6d-bo zazP}GoDB_2qpAgbF#_BjvwHb{^N^eCw&up1CSZTPe59*DaO=RE%#7E8mMN)4M=$+~ z-77hWEm}7hV(zNUNfO--+oKtpFsFXgxijiqF7{m1&dv{1%*2r99hLHN_R_g7)y~fD z1?9_X_=FlG#zuJJVnYK=15G@xc+GI6fdjZM&{*&_t(PZN)m zx6!vALllJY$QC4L78&ja)FAksDC|OK5#Sc3<|D%>EtQ_NZDPvS!X_ z7ESv>&iC2enfuQA+UcUR&1}{~hHB5Y^#NzEWVhL7Oq@A00p9DJvONFMIdW6d#8RUdo?RCg45tZUxIXz6FeE*(XHQ8MkqVK z?1Y8f5!wM}81RK#X`u%naxA%)LxVC!`eL7@({Ln2i|sFn++Cw%T+^hxMW?!v)m_-g z=cc3_+Rr+c;faEEW7uc-hR=;rpV1q!t29g{tA(Xx@|iLg2qro(9f+X;E7yrac)hMX zJ=e95mrJCuke@(e%Nxr59;D|1F%wT_j(*%AKhBp zg1`y78<-Rp_^-)lg`-U7xT4rGtI(#!cY&5CR*KaTtLn%m5(JZ0c2$_f%dfP@x@zur7~OyzTgQ zgjDN#bZG@f5vN~iUf%}4S{_X#$fJoDGyvv)W3;M^F2Rz|Bph8xD&%_x~; zXR+gBh%TL1miO!;2>|P5*xb8;+@-XVG8M#Q8$#0b*i&m`&)g-l_X zlp#x7qL&dD2~&<}z9K$Kh)7)GPMX66d~>aUskYR`kuyc$+-4J|I6qjLi4OTC-h1i$ zzi2DU2ey`V`)&9O&C$lH?IB*$cR){4eKwL+ ztCP>B4KmNBFyD6b8r=(m4GQS;RPM}{DXT&WoX;M!V0+(k_!KVh!l4nV=Qb?99s#~7 z>N(rsS=)KL7ZUayd(-Y;?B;E6FB6d~>3}|`-YKHpx zs2Twmsvd(aSIswamnVfMt?(=h=(eCh-PM1ZHgq*u*KgQh0*HkS7j0E$mn<%c@X58l z&d9Y`;WX@0aSOi{stnBZ3Q>@3lAfk|MDmr4@85Nh4}rL31MSJ9>!W1*VY9hY zcDg~67FNS zL0PS+Y>+oabrY56%Ce&feDlPofoUa7wOVLu4??J6RL}Ee{CNRDaPI(OK7?mv>^gUD z*K7>8#VJRb<5aN|=NcKW!C7G1wm$sZu&{8lV$RMw_#yL7HIR?%CCbrc-uNT)m_qATKYVK=Mhb&I!nq6nttp*JI)^nMZ@y*JSLn9Sbzk zg>GDMnxA0XThvrV6m_P7xcH-oU7ybH%1B%W{*3r!%?7I_T2A}un@Kf>e0(P>#vUNr z47XI5<{k8GJ4s8J9qC84Dx@$V%QlOhj@t0#@p5zmI$xOOS(2l6R0x{8IO@-vGkwbB zw7J9!tg;s+DLnETswK8RooxW=nbF1Sw=zxX_2mLm+nK>VM>1fTb;90z+KfBO#KVz~_W#{) z+S~N!?fq8!e+WmESo1j`cyWBYb+c9Amz{anL=OVjecnRqaY}sn)?wn=(}k3-t7r2s zDE-c#?)44-efvO;o05pXnzq2mK8jdi3Fc@_=?(KE38BmT*kLHP2VzaEC!R*UIV^@8 zxY0P&Wt59h*zC&Fz#d&wob8n1*uCk(`RiNZp68k~)RWJB5y>ZHovZx8X7_p*vyzLN zeLS^lXYRkj1^aPbk85aw5eZqT74OUaI#K-r$3l1ae6@1&_gYk^--_$Hv=v!_vRZ0{ zmeUSV`4$BZyEeP!xaU_EIb}O$c5ljX%yt4r$)%;Mtd3x@)n(RWvY3CX?}e1%RvU7{ zLh>4*?XVei%n2J7SydJnW>Gy7+Kul=Lg_=*YW$XL_ZW{@Tq8MZ~a6c)NfH8v=1@@)!YWAYb=B$J^NQL9UzRaRG2JSnY%l4b1mn~sZ)&ZqZv zo2^RaV9IZ4i;7B0w2P<;+tn%bhLA4J6IxRAY?4{lqfllR!t}<*bRmSLpp}=BO-WYG zdERO{Z8^9gQ6VZG-?<8zSRy2>=ko)+0Iw4GZPEWMxDzbMt-*H$_LY0p9;Oabe^%~5 zcsk3P@iRll;4-L%e;M6u-rtDb0hwJl!!;6kk_LCInWZ5j>`GwzSF93=RE0v7(W)&*jfA_8DQE7JPnd)5DtX^ZX0|c0Xlxgu3j@h} zenhYaf&puD?sBB=_ebJRBif#3izK}6jGNP8;31Spyp)Y*FCM)czOcXU}?Z6So{gK z?sZip3D-bqz>z9v5HRcEkkr(ae)UpX8n7{;N|KfCXh)#*ggoae&Y?RbH8;lwxG`>}nwn4SS;!kK*(Iro<1J20 z6&0n4#i^ih)r&X#$gh0}e!4HvQJm!%9VN)psu&%;LQwcMUsRN1me}cl3qhDDq)j-> ze!wfVl^}(m%~uGNf^h!Ih?TA`k-!D|8wp?wAH$L{IY4) zV`|yHNOXa?z$4gIG9T6JqlyPB zLD_25MYd9uwLQvoXedtkNXb3% zQY86Un*5;J@9D6KYJ$1Ms}CM%Y4bEKu#QdVE2G@xE-q0nvBzCvDkj$wxG57N_)?y_ z1&;rJuX(XwnzuUDD_vYvmg$%7?Vah9{kS1w=`4j`S=e2>6_u17lvfy;S7r59bN&f`scOWbyae0lJ>D~ec6sldq@i&w~J z4d=Ux&p5<`dJs>Ek9)@1%ZmLYI%e~klakw(j@$&$;OvOxWg42g;!tscHjz*TS!XTH zShryMf>N3NI%&UL2_DQfC>moNK!SnySmgBu)&W<^kk4?X!A))@dq2&0Wc(4ysDL6Opb9XxNADn2Laq_IM=I6JoHSI| z2|bxWg(1yxyeHI5ox(A6rP5r~+Y5oKVD&d6S2 zT&WyYxi-6jC7qW2;TslUfAfJ2Sl8azTDL^w43K(6jcK!34^vrLTBKe!HyftjbSJp< z!3{RiPQH#@CZ~y=XIp4*`#m2gZ?=d{_Bc#!qD51Ok)j`36BVeOt0lx9%bqGp1WzB4 zznii05&!of_Jm&Gf8Q!j&72jd-hg1l%3Ov%x#?Bh*-5m_T#Ov& zYjz!1iI!vh&=C4Pn&JrvN5Lhw+#3<=)ODNi1@h5i1W2mCG~%xL*8k?tR590njW7J` zXUtqIZk0t7VroBT5(m)U=+C^57G3}4_1W;&@@#sId(6O^+bB1N2_^N{3_SQQOrJJ9 z1qQPd_N%{+G6UF=|C2w)Y_?zaPi!BngVh(iUJd)rF{WQoo?cm9?AF+2|5`(2Q?$<0 z0|d0Px>&6N^yI0FHj!W2y`ro)^EBs(Zfzpw1h@S;tUwAP{3`wYfS>MA986!D`%F(> zUT*rS%>8lMkMs)LO8h+Pcxx?wj`DRYJtBbX?_Vay4IoR7IUUf;loywBsxpAABIzuO z=}Tor!3EYN@!3bRP82|oa5eBTy)%3h0#)#2l`PVCjPs}6XF+Rf4+?89I`hPu_))~7 z8mUt15S4i0NXS1qaDMI)A|_QDfvv|{6xnHAE3lmyC)^H#6`Zk#klJG~Shi~xByXkB z$}kzH4lOJtAw56rAjX4KEj95-$SNzqYZu@0%>rxJH0n};*{VOD>xa|x$(oU0@82EC z{b$P`kJrvr=93FXe!I{4-D*_qL}|_~v0u`%+VJ=(`M;nYshg8GdVgQk9N8S$c1zp= z9yO=3`riJijiW>Z&B{*0`pNa3gS8x(QaQKR4z6E6x8AUtw($iE1`bqtLE8ah(|dahfV}Z=E0XNqL_GlP`3Vneoju>dSzr}@bXfwYbbC1tK^LF;^39Y?*6?N z^wety9LNrf+Yd}(_HNfBU3|wis|Q&T>=BJ-kUf|m`w_O74WJs5n0S~Z;)qCxiDJwj zHe-E@+r3C$*AMocppUghZ#p+VV!Zrkaan6!!&1%Vp%LTNMiv~bD`&HekW#)10$G4XK-m9PHt1}u_U?~k+mnaAI=9IcH>R9_N= z3$~~Z2l)|#8!9kkZ}}reW~m3Y{|+8VKcv7k2|$)M`hI~?D7;&-Boq-x7b{XUUMVn< zOfuK~zR^2XBu*{Xrc`l}WP22eLwPf9a<>^7=!4~OAL>7pC1TkHioo5M15x+t=vdth zomtZh0_@S{J7cg}I7ZAsD=rHg<1bWiz1D#kMiwpx>+f|2OS&%^L5HimhSN{j2Ab$X zx29+Ay8e~EKOVah@-I2u4z0w-%Y^E!*M7LfeXRu>OA}}Mly(*!Z7B^Y3Jxv`DQ!6l?x`E-jdOE-1WyZd!cQk(EU!*c z`O;rnqI&IF+ppi)!R*&PZ9cDo>1oq`v0zW|bQ!+2e`d_ZCC5MeP`1BPkI%+aaO@zs zT9*Cz#&Y~!T&8BZ)G|&`lpCmyo<31@^+50at?-jm|B+C{MrU_T$f0$cTAu7~Sk#2Z zt75TXSIg6wfd^N+Rqk7Dp6iJy(o#W>CaAz|T|;7vDQ5d(L1;&@>P2HkcZg4_mse_u zp&BU>%scqos(_5j^iqLZ3j@ordv_i?L~lkoXKsBFH-7Rb0@}ikkiC01x0wDES5GhI zZX=suXMrB~ufRC&qP6)sf|)*qows|pf%WG7tLy0P8EyB_nkU)^!(P9euSWovaGRrj8{h4n@OgPr#E8T*OY%Te$}3vat<5p8H~FUu`VZ^ z5Ye8Kas_fzS5vlY1OZ6VdOgrf&4G4s;pq>GpKc7@Q?33s{%eQU1pr$rJ_I?HWBU%p zN3SwBlTSNB5s+g|GBdA3^HEO=%sC~0^#PksYgS>_s%YuJIHfDm6@N(2z+WI|K`uyq3Cwt+i8T|a*C^L2Pd81hwJ5p)bV_X5*0Pt4ugYJ2)wuN|e??Bf z-#%XVRwqRPou%F^nV<(fmQ-`fTk8${6u-$vn+p>YZ{JQz)Se&rYJI$eQ~r7pxY(g5 z#~e%9hc}!GbVk22x9WzInBM6lwA&@u`>AN_H zi3-58B*hy{SxeX;YI?Up;Xr@D&r3qP^XS^OK~4l`M5U63AhR=woBQJsiqk|D3Eu`v zLwpfhLJvGYx3P(J=07si+egME6A!up-`V7XAE0r{JWMeEI98y6=ywv*6u@(o`Tr}R zaTr(&AR}Ug0$?NL295W)OCnw+epP>x;0!ntF zco2$CQ05N}%f<{A-sP&f?DF>F1@#%`*F;_bAmvxQTud+!WMr{rgQXZ&@Mhhj+%83( z*8CLj^~b}4-|_dpa0fxBPH*2{x2gqi!~@a06jn`5so-yha`KctJ(-zkby|FbLlx!I zwta$Mup1g4jxubc*7rhmx+1r^%QtTQOTmka!ROD_t^IvqnnWRe1jicWpYADlA-(3Z z|9I1siZtK2(pDDzUyQBMR=FLeg^*;V7?PY6Qb0^K+5aE1iX25k_$L<0sO1W8gw+Y$ zu|wwO5Co9Pi|NRLP@%n02!xaW>g>tMQ@bi%17jr#f+?FUMrKGR0;h_|k z?YGFa$l_$!X3AwlJ34;t=r(Raiuv` zt0&u&#aL0p8DTU=*kK8!RWH8=iG%cGzY^>%%_wd)uGhvuU_Xj1^gBcIZu`BrIAh$_ z2En1s*)v259f7L?&6@GK9B$iwpWd>aD{u@y!cSIa=4MQU$udYf_3Dj`wo89SerINj zAz`tWG+Wa6T0qDpNgw3D0G=!dBB93GlS}B%#h?KiMO#DFW5hU`x8-vb>|i6tqJ^h| zV~7B2hQ`;uITYi7>f~0HZ1y`xAUH8Wlv8Zv%)QfmDq;akyY1Z}917a^y$wl%h0LIn zGd3hEA{lFLhJp|xjfyuT+#>jl&ngRdDu(FeKHd_mN!i0|ncui&C1i%eU>wLvWQVoQ zX>;rQ@t{gJ<=cju{Iox^l|tnohg_2V%L=@*1Q^IdsKSdyTR7IAr+>7zjOEG46dSK!A<+pomY3WQk_~2f%M%FL zWA}w$RE*_>O1<@I=r5n2;ZvcT%YZoiY`t`ql`a{Ndd}a|oWD5V{lh6|6TY*yX$#9d z#DJ8mRew>^^+HZoxFovNBL)gwpv5o1Y4~}3oBSA`2Al2_8g@^53>U&{wRjv7=AV-b zvrk$(fdJ7({!s6w-VHI6HvUx8XzU%1+1T(q%(rFFNM_h$Lo}n)sPm|kQAZtjnvmn; z0dXya8N2J%XaP|Wb=9?xAv3z)=R_I{3qH|8iv#EQKEaCc(*&{&LO5-SvH=92u`gO} z4>Q&!Oj=$Z+A36Xo9!daIhOfGtL>r##>hGVkS-~cFI0GXCg&M4c_mrB_)O_{bIhJj zAQPC=H}+%wkCwm&MfglWY{(Yc7kO-B420J7&4>E8nlwsuL$l zeSPlv?(^MCqx<$UMoYtOs&Qf-wo>3kEq2s8j%>CI{@L<-Iv(t$kJ~4{w4bNrN&D#i zBLYDf2J1mT4Ne{h2v;&0nO6u0vh4V?nKp4y=hNwLR=hn$uJ|LI2F~=8X^w$oJh=-4 z+e>&4dE8!h?_VDuwmn?-aN|S%S-;L%&+%7atmYN#J^bNE&~f-{y?6`-KemUGy9d4r zU4SQ%M-VsW;Xn_{d;(2dN$s) z_23PFe`Iq7zo7TgqwtS~!#&`EpLBS{5T*0`vkT-8P-VNXcEZ_VTYQH@hxQQnPzkr> zF*m8JJ6=EYeQA`>U`eUA6x0^pz@=Tyq}hjI^b#lMLfkWuGfyR4UVeG@a>`}L){*c^ z-EF-Rek)qy55q0(yAC4cQDFxhJ4Y zDYPCvt!-9wj|&_c_*?T4Uz>fUJMBLS2>XijX80}9TKzlLHMjWahnZ(v1;H~tIhMSi^(a3)}~Dz+i<^+%FUKXq1&MO z^s(T%eMaU|C_=@CdexRM;*{+-wJdTP80|gnooDC%g>QO7oI`H@hsL4}-I-jq8R70M z|J!QH_LUI|%x>@8u`~DkB>S3`Qkfr2cj?;7z0`RO=^JQm{S8!~bLY2q>r87vQo#O! z#@`j-dW!m2xfvJSu86`{nJUl@KQNN32B6x0b?bP}`u#s;QSSUj|4TuxtF$iVkxyfU z7Vw|Z`C+7MAn?z{J-s@R2m|#LYTuiGs7PJ}t35&E4?oYT{YyjsM=LzeJ7g~PK|I)$ z3+DkV@K9{~6He}WylM#`5mSAO$6Sb=?dun>UZ3*|8FL>VWgXtA`qpQe z+n>{0hcQZzF#<*55CC|P-xK7+v)oyj$ppIx<7hWQIw`=N&Zd~n5k~Tbm(5JVb=J!C9%kC1(`4fNu6d=TqKnfY?e}W8oQ~DuoCW%D9k98|!?CDVN&%Fi!KbZu@aw z_w#Rsi ziMNu+Rd=*@oDt|Sy<{KdR>TVB*x*yMJadz-Omg&zJ2%R{YCq7Pf;;H zOwaua>c*MWypxLvSxWor4Foa4@bsji_vp0T>kNU(@0PVcmCVRmItPkDGGUj{?cS2h zK}qANqX^x8eX?$;?o@5thK0+mO3`7_O16vu0pT+8|wdo41O4u2xGmxJ)jK$73RVed=WHCY#g4(nk_T)=mjzKN|4GrrV5woh0PT z7x63yo;O7@jg;nXB4JM;HTiR2RXgA^+Uc-JANrMta1h2B7;wO`4hGy) zGuf6fUZ3x1;K8uQcCw}c<#D?LuO^txgTG3F&bQ?4)@hIR3^@=t335>KO&Mtii6_GX zPQ`(UgSqgqZRbne8cviYTqu~Nu^*AIxCyPs7t-vQy}sUaX(b&+>7o82uZ12f^yPR< zJG)ugmO#n~0rLP1{~Y#1mt3sKdm>_wNa_fb)i}Dpl?RtsBbwpLn zi;}=iBK76n&*5ZGv%#~MJcBOUDT}i-UW-C|yo5-BJBK{6oJ_V8({1)9=S3n7ixHHb zj0QcOo^>)7d<4m2zvn&DL>vmft~UZK_*ikPO(Lh3@uZBF?N~D+(ste&7qMb;JkhXf zY)?O)ytVpQ7E9f6rWIXwT5#B{kS)=`CYiu=1YDt~M*^Wy#y7`dreh}Hqn+Ua{wb1K diff --git a/frontend/src/views/panel/list/PanelViewShow.vue b/frontend/src/views/panel/list/PanelViewShow.vue index 443a22e0fd..dde235c31a 100644 --- a/frontend/src/views/panel/list/PanelViewShow.vue +++ b/frontend/src/views/panel/list/PanelViewShow.vue @@ -60,6 +60,7 @@ {{ $t('panel.export_to_panel') }} {{ $t('panel.export_to_pdf') }} {{ $t('panel.export_to_img') }} + {{ $t('panel.export_to_app') }} @@ -164,7 +165,7 @@ import { starStatus, saveEnshrine, deleteEnshrine } from '@/api/panel/enshrine' import bus from '@/utils/bus' import { queryAll } from '@/api/panel/pdfTemplate' import ShareHead from '@/views/panel/GrantAuth/ShareHead' -import { initPanelData, updatePanelStatus } from '@/api/panel/panel' +import {export2AppCheck, initPanelData, updatePanelStatus} from '@/api/panel/panel' import { proxyInitPanelData } from '@/api/panel/shareProxy' import { dataURLToBlob } from '@/components/canvas/utils/utils' import { findResourceAsBase64 } from '@/api/staticResource/staticResource' @@ -326,6 +327,48 @@ export default { _this.dataLoading = false } }, + saveAppFile(appAttachInfo) { + const _this = this + _this.dataLoading = true + try { + _this.findStaticSource(function(staticResource) { + html2canvas(document.getElementById('canvasInfoTemp')).then(canvas => { + _this.dataLoading = false + const snapshot = canvas.toDataURL('image/jpeg', 0.1) // 0.1是图片质量 + if (snapshot !== '') { + const panelInfo = { + name: _this.$store.state.panel.panelInfo.name, + id: _this.$store.state.panel.panelInfo.id, + snapshot: snapshot, + panelStyle: JSON.stringify(_this.canvasStyleData), + panelData: JSON.stringify(_this.componentData), + staticResource: JSON.stringify(staticResource || {}) + } + appAttachInfo['panelInfo'] = JSON.stringify(panelInfo) + const blob = new Blob([JSON.stringify(appAttachInfo)], { type: '' }) + FileSaver.saveAs(blob, _this.$store.state.panel.panelInfo.name + '-APP.DEAPP') + } + }) + }) + } catch (e) { + console.error(e) + _this.dataLoading = false + } + }, + downLoadToApp(){ + this.dataLoading = true + export2AppCheck(this.$store.state.panel.panelInfo.id).then(rsp=>{ + if(rsp.data.checkStatus){ + this.saveAppFile(rsp.data) + }else{ + this.dataLoading = false + this.$message({ + message: rsp.data.checkMes, + type: 'error' + }) + } + }) + }, // 解析静态文件 findStaticSource(callBack) { const staticResource = [] diff --git a/frontend/src/views/panel/template/index.vue b/frontend/src/views/panel/template/index.vue index 18b5a0d33a..a9874ec1aa 100644 --- a/frontend/src/views/panel/template/index.vue +++ b/frontend/src/views/panel/template/index.vue @@ -414,4 +414,4 @@ export default { } } } - \ No newline at end of file + diff --git a/frontend/src/views/panel/templateApp/component/TemplateImport.vue b/frontend/src/views/panel/templateApp/component/TemplateImport.vue new file mode 100644 index 0000000000..1ffc4e202d --- /dev/null +++ b/frontend/src/views/panel/templateApp/component/TemplateImport.vue @@ -0,0 +1,222 @@ + + + + + + + diff --git a/frontend/src/views/panel/templateApp/component/TemplateItem.vue b/frontend/src/views/panel/templateApp/component/TemplateItem.vue new file mode 100644 index 0000000000..e3e75b1dc0 --- /dev/null +++ b/frontend/src/views/panel/templateApp/component/TemplateItem.vue @@ -0,0 +1,145 @@ + + + + + diff --git a/frontend/src/views/panel/templateApp/component/TemplateList.vue b/frontend/src/views/panel/templateApp/component/TemplateList.vue new file mode 100644 index 0000000000..9ae47a0cef --- /dev/null +++ b/frontend/src/views/panel/templateApp/component/TemplateList.vue @@ -0,0 +1,235 @@ + + + + + diff --git a/frontend/src/views/panel/templateApp/index.vue b/frontend/src/views/panel/templateApp/index.vue new file mode 100644 index 0000000000..124a4dcd12 --- /dev/null +++ b/frontend/src/views/panel/templateApp/index.vue @@ -0,0 +1,405 @@ + + + + + diff --git a/frontend/src/views/wizard/wizardCard.vue b/frontend/src/views/wizard/wizardCard.vue index 574dfd15a8..ad7e2914fb 100644 --- a/frontend/src/views/wizard/wizardCard.vue +++ b/frontend/src/views/wizard/wizardCard.vue @@ -8,10 +8,8 @@ - {{$t('wizard.click_show') }} - diff --git a/frontend/src/views/wizard/wizardCardEnterprise.vue b/frontend/src/views/wizard/wizardCardEnterprise.vue index a95f0bd10e..f536f0948c 100644 --- a/frontend/src/views/wizard/wizardCardEnterprise.vue +++ b/frontend/src/views/wizard/wizardCardEnterprise.vue @@ -8,10 +8,8 @@ - {{$t('wizard.apply') }} -