From ee323058161ea4ab7a556590529b1fbbc8fb92e7 Mon Sep 17 00:00:00 2001 From: fit2cloud-chenyw Date: Wed, 26 Oct 2022 19:24:19 +0800 Subject: [PATCH 01/39] =?UTF-8?q?fix(=E7=99=BB=E5=87=BA):=20oidc=E5=AE=95?= =?UTF-8?q?=E6=9C=BA=E5=90=8E=E6=97=A0=E6=B3=95=E9=80=80=E5=87=BA=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/dataease/auth/server/AuthServer.java | 25 +++++++++++++------ frontend/src/api/user.js | 6 +++-- frontend/src/lang/en.js | 4 +++ frontend/src/lang/tw.js | 4 +++ frontend/src/lang/zh.js | 4 +++ frontend/src/store/modules/user.js | 23 +++++++++++++++++ 6 files changed, 57 insertions(+), 9 deletions(-) diff --git a/backend/src/main/java/io/dataease/auth/server/AuthServer.java b/backend/src/main/java/io/dataease/auth/server/AuthServer.java index ac43dc69ce..e86731d06f 100644 --- a/backend/src/main/java/io/dataease/auth/server/AuthServer.java +++ b/backend/src/main/java/io/dataease/auth/server/AuthServer.java @@ -12,6 +12,7 @@ import io.dataease.auth.service.AuthUserService; import io.dataease.auth.util.JWTUtils; import io.dataease.auth.util.RsaUtil; import io.dataease.commons.constants.SysLogConstants; +import io.dataease.commons.exception.DEException; import io.dataease.commons.utils.*; import io.dataease.controller.sys.request.LdapAddRequest; import io.dataease.exception.DataEaseException; @@ -240,8 +241,13 @@ public class AuthServer implements AuthApi { HttpServletRequest request = ServletUtils.request(); String idToken = request.getHeader("IdToken"); if (StringUtils.isNotBlank(idToken)) { - OidcXpackService oidcXpackService = SpringContextUtil.getBean(OidcXpackService.class); - oidcXpackService.logout(idToken); + try { + OidcXpackService oidcXpackService = SpringContextUtil.getBean(OidcXpackService.class); + oidcXpackService.logout(idToken); + } catch (Exception e) { + LogUtil.error(e.getMessage(), e); + DEException.throwException("oidc_logout_error"); + } } } @@ -253,11 +259,16 @@ public class AuthServer implements AuthApi { String result = null; Integer defaultLoginType = systemParameterService.defaultLoginType(); if (defaultLoginType == 3 && isOpenCas()) { - HttpServletRequest request = ServletUtils.request(); - HttpSession session = request.getSession(); - session.invalidate(); - CasXpackService casXpackService = SpringContextUtil.getBean(CasXpackService.class); - result = casXpackService.logout(); + try { + HttpServletRequest request = ServletUtils.request(); + HttpSession session = request.getSession(); + session.invalidate(); + CasXpackService casXpackService = SpringContextUtil.getBean(CasXpackService.class); + result = casXpackService.logout(); + } catch (Exception e) { + LogUtil.error(e.getMessage(), e); + DEException.throwException("cas_logout_error"); + } } try { Long userId = JWTUtils.tokenInfoByToken(token).getUserId(); diff --git a/frontend/src/api/user.js b/frontend/src/api/user.js index 32d2067307..f7b0df9167 100644 --- a/frontend/src/api/user.js +++ b/frontend/src/api/user.js @@ -18,14 +18,16 @@ export function getInfo(token) { export function logout() { return request({ url: '/api/auth/logout', - method: 'post' + method: 'post', + hideMsg: true }) } export function deLogout() { return request({ url: '/api/auth/deLogout', - method: 'post' + method: 'post', + hideMsg: true }) } diff --git a/frontend/src/lang/en.js b/frontend/src/lang/en.js index 9b9d4d14b0..2b396f403a 100644 --- a/frontend/src/lang/en.js +++ b/frontend/src/lang/en.js @@ -2626,5 +2626,9 @@ export default { apply_logs: 'Apply logs', app_group_delete_tips: 'Are you sure to delete this application category?', app_group_delete_content: 'After deletion, all application templates in this category will also be deleted.' + }, + logout: { + oidc_logout_error: 'OIDC failed to exit, do you continue to exit DataEase?', + cas_logout_error: 'CAS服务异常,请联系管理员!' } } diff --git a/frontend/src/lang/tw.js b/frontend/src/lang/tw.js index ad78066c42..3e41d495c2 100644 --- a/frontend/src/lang/tw.js +++ b/frontend/src/lang/tw.js @@ -2627,5 +2627,9 @@ export default { apply_logs: '應用記錄', app_group_delete_tips: '確定刪除該應用分類嗎?', app_group_delete_content: '刪除後,該分類中所有的應用模闆也將被刪除。' + }, + logout: { + oidc_logout_error: 'OIDC退出失敗,是否繼續退出DataEase?', + cas_logout_error: 'CAS服務異常,請聯系管理員!' } } diff --git a/frontend/src/lang/zh.js b/frontend/src/lang/zh.js index 009725ad24..86e6efae90 100644 --- a/frontend/src/lang/zh.js +++ b/frontend/src/lang/zh.js @@ -2627,5 +2627,9 @@ export default { apply_logs: '应用记录', app_group_delete_tips: '确定删除该应用分类吗?', app_group_delete_content: '删除后,该分类中所有的应用模板也将被删除。' + }, + logout: { + oidc_logout_error: 'OIDC退出失败,是否继续退出DataEase?', + cas_logout_error: 'The CAS service is abnormal, please contact the administrator!' } } diff --git a/frontend/src/store/modules/user.js b/frontend/src/store/modules/user.js index a14a2db029..5d8795d358 100644 --- a/frontend/src/store/modules/user.js +++ b/frontend/src/store/modules/user.js @@ -6,6 +6,7 @@ import { getLanguage } from '@/lang/index' import Cookies from 'js-cookie' import router from '@/router' import i18n from '@/lang' +import { $alert, $confirm } from '@/utils/message' const getDefaultState = () => { return { token: getToken(), @@ -146,6 +147,28 @@ const actions = { resolve(res.data) }).catch(error => { reject(error) + if (error?.response?.data?.message) { + if (error.response.data.message === ('oidc_logout_error')) { + const message = i18n.t('logout.' + error.response.data.message) + $confirm(message, () => { + removeToken() // must remove token first + resetRouter() + commit('RESET_STATE') + window.location.href = '/' + }, { + confirmButtonText: i18n.t('commons.confirm') + }) + } + if (error.response.data.message === ('cas_logout_error')) { + const message = i18n.t('logout.' + error.response.data.message) + $alert(message, () => { + + }, { + confirmButtonText: i18n.t('commons.confirm'), + showClose: false + }) + } + } }) }) }, From 3cc6dd041b921926c5f1e653aae68264e4b40e95 Mon Sep 17 00:00:00 2001 From: wangjiahao <1522128093@qq.com> Date: Wed, 26 Oct 2022 19:34:56 +0800 Subject: [PATCH 02/39] =?UTF-8?q?feat(=E5=BA=94=E7=94=A8=E5=B8=82=E5=9C=BA?= =?UTF-8?q?):=20=E4=B8=89=E6=96=B9=E5=BA=94=E7=94=A8=E5=AF=B9=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/panel/AppLogController.java | 19 +- .../panel/PanelGroupController.java | 14 + .../request/dataset/DataSetGroupRequest.java | 2 + .../panel/PanelAppTemplateApplyRequest.java | 6 + .../dto/appTemplateMarket/AppLogGridDTO.java | 8 + .../java/io/dataease/ext/ExtAppLogMapper.xml | 20 +- .../io/dataease/ext/ExtDataSetGroupMapper.xml | 6 +- .../panel/PanelAppTemplateService.java | 40 +- .../service/panel/PanelGroupService.java | 67 ++- .../service/panel/applog/AppLogService.java | 28 + .../main/resources/db/migration/V42__1.16.sql | 11 + frontend/src/api/appTemplateMarket/log.js | 13 +- frontend/src/api/panel/panel.js | 29 +- .../components/business/DeLayoutContent.vue | 2 +- frontend/src/lang/en.js | 12 +- frontend/src/lang/tw.js | 12 +- frontend/src/lang/zh.js | 12 +- .../panel/appTemplate/AppTemplateContent.vue | 535 ++++++++++++++++++ .../component/AppTemplateApply.vue | 54 ++ .../appTemplate/component/TemplateItem.vue | 130 ++++- .../appTemplate/component/TemplateList.vue | 28 +- .../src/views/panel/appTemplate/index.vue | 504 +---------------- .../component/AppMarketPreview.vue | 124 ++++ .../views/panel/appTemplateMarket/index.vue | 278 ++++----- .../panel/appTemplateMarket/log/index.vue | 167 +++++- .../src/views/panel/list/PanelViewShow.vue | 153 ++--- .../src/views/system/datasource/DsForm.vue | 380 +++++++++++-- 27 files changed, 1835 insertions(+), 819 deletions(-) create mode 100644 frontend/src/views/panel/appTemplate/AppTemplateContent.vue create mode 100644 frontend/src/views/panel/appTemplate/component/AppTemplateApply.vue create mode 100644 frontend/src/views/panel/appTemplateMarket/component/AppMarketPreview.vue diff --git a/backend/src/main/java/io/dataease/controller/panel/AppLogController.java b/backend/src/main/java/io/dataease/controller/panel/AppLogController.java index f388d18a78..45a547acf3 100644 --- a/backend/src/main/java/io/dataease/controller/panel/AppLogController.java +++ b/backend/src/main/java/io/dataease/controller/panel/AppLogController.java @@ -21,24 +21,31 @@ import java.util.List; @RestController @Api(tags = "应用市场:应用日志") @ApiSupport(order = 220) -@RequestMapping("/app/log") +@RequestMapping("app/log") public class AppLogController { @Resource - private AppLogService applogService; + private AppLogService appLogService; @I18n @ApiOperation("查询日志") @PostMapping("/logGrid/{goPage}/{pageSize}") @ApiImplicitParams({ - @ApiImplicitParam(paramType = "path", name = "goPage", value = "页码", required = true, dataType = "Integer"), - @ApiImplicitParam(paramType = "path", name = "pageSize", value = "页容量", required = true, dataType = "Integer"), - @ApiImplicitParam(name = "request", value = "查询条件", required = true) + @ApiImplicitParam(paramType = "path", name = "goPage", value = "页码", required = true, dataType = "Integer"), + @ApiImplicitParam(paramType = "path", name = "pageSize", value = "页容量", required = true, dataType = "Integer"), + @ApiImplicitParam(name = "request", value = "查询条件", required = true) }) public Pager> logGrid(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody KeyGridRequest request) { Page page = PageHelper.startPage(goPage, pageSize, true); - return PageUtils.setPageInfo(page, applogService.query(request)); + return PageUtils.setPageInfo(page, appLogService.query(request)); + } + + + @ApiOperation("删除日志和资源") + @PostMapping("/deleteLog") + public void deleteLogAndResource(@RequestBody AppLogGridDTO request) throws Exception { + appLogService.deleteLogAndResource(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 b9c2cc1dbb..b361b5d725 100644 --- a/backend/src/main/java/io/dataease/controller/panel/PanelGroupController.java +++ b/backend/src/main/java/io/dataease/controller/panel/PanelGroupController.java @@ -203,4 +203,18 @@ public class PanelGroupController { result.setResponseSource("appApply"); return result; } + + @PostMapping("/appEdit") + public void appEdit(@RequestBody PanelAppTemplateApplyRequest request) throws Exception{ + panelGroupService.appEdit(request); + } + + @GetMapping("/findOneWithParent/{panelId}") + public PanelGroupDTO findOneWithParent(@PathVariable String panelId) throws Exception{ + PanelGroupDTO result = findOne(panelId); + result.setParents(authService.parentResource(panelId,"panel")); + result.setRequestId(UUIDUtil.getUUIDAsString()); + result.setResponseSource("appApply"); + return result; + } } diff --git a/backend/src/main/java/io/dataease/controller/request/dataset/DataSetGroupRequest.java b/backend/src/main/java/io/dataease/controller/request/dataset/DataSetGroupRequest.java index 5c87b85646..51f8cd76ba 100644 --- a/backend/src/main/java/io/dataease/controller/request/dataset/DataSetGroupRequest.java +++ b/backend/src/main/java/io/dataease/controller/request/dataset/DataSetGroupRequest.java @@ -18,4 +18,6 @@ public class DataSetGroupRequest extends DatasetGroup { private String userId; @ApiModelProperty("ID集合") private Set ids; + @ApiModelProperty("排除的ID") + private String excludedId; } diff --git a/backend/src/main/java/io/dataease/controller/request/panel/PanelAppTemplateApplyRequest.java b/backend/src/main/java/io/dataease/controller/request/panel/PanelAppTemplateApplyRequest.java index 5446e5a84d..77b95aaabe 100644 --- a/backend/src/main/java/io/dataease/controller/request/panel/PanelAppTemplateApplyRequest.java +++ b/backend/src/main/java/io/dataease/controller/request/panel/PanelAppTemplateApplyRequest.java @@ -13,12 +13,18 @@ import java.util.List; @Data public class PanelAppTemplateApplyRequest { + private String logId; + private String panelId; + private String panelGroupPid; + private String panelName; private String datasetGroupId; + private String datasetGroupPid; + private String datasetGroupName; private String appTemplateId; diff --git a/backend/src/main/java/io/dataease/dto/appTemplateMarket/AppLogGridDTO.java b/backend/src/main/java/io/dataease/dto/appTemplateMarket/AppLogGridDTO.java index c54b894374..6e4e34fd96 100644 --- a/backend/src/main/java/io/dataease/dto/appTemplateMarket/AppLogGridDTO.java +++ b/backend/src/main/java/io/dataease/dto/appTemplateMarket/AppLogGridDTO.java @@ -16,4 +16,12 @@ public class AppLogGridDTO extends PanelAppTemplateLog implements Serializable { private String panelName; + private String panelGroupPid; + + private String datasourceType; + + private String datasetGroupPid; + + private Boolean deleteResource; + } diff --git a/backend/src/main/java/io/dataease/ext/ExtAppLogMapper.xml b/backend/src/main/java/io/dataease/ext/ExtAppLogMapper.xml index ee7b6a93fc..c633110b6e 100644 --- a/backend/src/main/java/io/dataease/ext/ExtAppLogMapper.xml +++ b/backend/src/main/java/io/dataease/ext/ExtAppLogMapper.xml @@ -7,12 +7,30 @@ + + + diff --git a/backend/src/main/java/io/dataease/service/panel/PanelAppTemplateService.java b/backend/src/main/java/io/dataease/service/panel/PanelAppTemplateService.java index 75f9c47bb2..db1c7dbb46 100644 --- a/backend/src/main/java/io/dataease/service/panel/PanelAppTemplateService.java +++ b/backend/src/main/java/io/dataease/service/panel/PanelAppTemplateService.java @@ -5,6 +5,7 @@ import io.dataease.commons.constants.CommonConstants; import io.dataease.commons.constants.PanelConstants; import io.dataease.commons.utils.AuthUtils; import io.dataease.commons.utils.BeanUtils; +import io.dataease.controller.datasource.request.UpdataDsRequest; import io.dataease.controller.request.dataset.DataSetTableRequest; import io.dataease.controller.request.panel.PanelAppTemplateApplyRequest; import io.dataease.controller.request.panel.PanelAppTemplateRequest; @@ -270,15 +271,36 @@ public class PanelAppTemplateService { return chartViewFieldsRealMap; } - public void nameCheck(PanelAppTemplateApplyRequest request) { - panelGroupService.checkPanelName(request.getPanelName(), request.getPanelId(), PanelConstants.OPT_TYPE_INSERT, null, "panel"); - DatasetGroup datasetGroup = new DatasetGroup(); - datasetGroup.setPid(request.getDatasetGroupId()); - datasetGroup.setName(request.getDatasetGroupName()); - dataSetGroupService.checkName(datasetGroup); - request.getDatasourceList().stream().forEach(datasource -> { - datasourceService.checkName(datasource.getName(), datasource.getType(), null); - }); + public void nameCheck(PanelAppTemplateApplyRequest request, String optType) { + if ("add".equals(optType)) { + panelGroupService.checkPanelName(request.getPanelName(), request.getPanelGroupPid(), PanelConstants.OPT_TYPE_INSERT, null, "panel"); + DatasetGroup datasetGroup = new DatasetGroup(); + datasetGroup.setPid(request.getDatasetGroupPid()); + datasetGroup.setName(request.getDatasetGroupName()); + dataSetGroupService.checkName(datasetGroup); + request.getDatasourceList().stream().forEach(datasource -> { + datasourceService.checkName(datasource.getName(), datasource.getType(), null); + }); + } else { + DatasetGroup datasetGroup = new DatasetGroup(); + datasetGroup.setPid(request.getDatasetGroupPid()); + datasetGroup.setName(request.getDatasetGroupName()); + datasetGroup.setId(request.getDatasetGroupId()); + dataSetGroupService.checkName(datasetGroup); + request.getDatasourceList().stream().forEach(datasource -> { + datasourceService.checkName(datasource.getName(), datasource.getType(), datasource.getId()); + }); + } } + + @Transactional(rollbackFor = Exception.class) + public void editDatasource(List updateDatasourceList) throws Exception { + for (int i = 0; i < updateDatasourceList.size(); i++) { + UpdataDsRequest updataDsRequest = new UpdataDsRequest(); + BeanUtils.copyBean(updataDsRequest, updateDatasourceList.get(i)); + datasourceService.updateDatasource(updataDsRequest); + + } + } } 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 73fb1119ba..cb9af63d96 100644 --- a/backend/src/main/java/io/dataease/service/panel/PanelGroupService.java +++ b/backend/src/main/java/io/dataease/service/panel/PanelGroupService.java @@ -127,9 +127,9 @@ public class PanelGroupService { @Resource private PanelAppTemplateLogService appTemplateLogService; @Resource - private ChartGroupService chartGroupService; - @Resource private DataSetGroupService dataSetGroupService; + @Resource + private DatasetGroupMapper datasetGroupMapper; public List tree(PanelGroupRequest panelGroupRequest) { String userId = String.valueOf(AuthUtils.getUser().getUserId()); @@ -232,6 +232,25 @@ public class PanelGroupService { return panelId; } + public void move(PanelGroupRequest request){ + PanelGroupWithBLOBs panelInfo = panelGroupMapper.selectByPrimaryKey(request.getId()); + if (panelInfo.getPid().equalsIgnoreCase(request.getPid())) { + DataEaseException.throwException(Translator.get("i18n_select_diff_folder")); + } + // 移动校验 + if (StringUtils.isNotEmpty(request.getName())) { + checkPanelName(request.getName(), request.getPid(), PanelConstants.OPT_TYPE_INSERT, request.getId(), panelInfo.getNodeType()); + } + PanelGroupWithBLOBs record = new PanelGroupWithBLOBs(); + record.setName(request.getName()); + record.setId(request.getId()); + record.setPid(request.getPid()); + record.setUpdateTime(request.getUpdateTime()); + record.setUpdateBy(request.getUpdateBy()); + panelGroupMapper.updateByPrimaryKeySelective(record); + DeLogUtils.save(SysLogConstants.OPERATE_TYPE.MODIFY, sourceType, request.getId(), panelInfo.getPid(), request.getPid(), sourceType); + } + public void checkPanelName(String name, String pid, String optType, String id, String nodeType) { PanelGroupExample groupExample = new PanelGroupExample(); @@ -811,12 +830,12 @@ public class PanelGroupService { @Transactional(rollbackFor = Exception.class) public String appApply(PanelAppTemplateApplyRequest request) throws Exception{ //仪表板名称校验,数据集分组名称校验,数据源名称校验 - panelAppTemplateService.nameCheck(request); + panelAppTemplateService.nameCheck(request,"add"); String newPanelId = UUIDUtil.getUUIDAsString(); // 新建数据集分组 DatasetGroup newDatasetGroup = new DatasetGroup(); - newDatasetGroup.setPid(request.getDatasetGroupId()); + newDatasetGroup.setPid(request.getDatasetGroupPid()); newDatasetGroup.setName(request.getDatasetGroupName()); newDatasetGroup.setType("group"); DataSetGroupDTO resultDatasetGroup = dataSetGroupService.save(newDatasetGroup); @@ -853,7 +872,7 @@ public class PanelGroupService { panelAppTemplateService.applyViewsField(chartViewFieldsInfo,chartViewsRealMap,datasetsRealMap,datasetFieldsRealMap); - panelAppTemplateService.applyPanel(panelInfo,chartViewsRealMap,newPanelId, request.getPanelName(), request.getPanelId()); + panelAppTemplateService.applyPanel(panelInfo,chartViewsRealMap,newPanelId, request.getPanelName(), request.getPanelGroupPid()); panelAppTemplateService.applyPanelView(panelViewsInfo,chartViewsRealMap,newPanelId); @@ -873,4 +892,42 @@ public class PanelGroupService { appTemplateLogService.newAppApplyLog(templateLog); return newPanelId; } + + @Transactional(rollbackFor = Exception.class) + public void appEdit(PanelAppTemplateApplyRequest request) throws Exception{ + long currentTime = System.currentTimeMillis(); + String userName = AuthUtils.getUser().getUsername(); + //名称校验,数据集分组名称校验,数据源名称校验 + panelAppTemplateService.nameCheck(request,"update"); + //仪表板移动更新名称 + PanelGroup panelHistoryInfo = panelGroupMapper.selectByPrimaryKey(request.getPanelId()); + String panelHistoryPid = panelHistoryInfo.getPid(); + if(panelHistoryPid.equals(request.getPanelGroupPid())){ + // 未移动 + checkPanelName(request.getPanelName(), request.getPanelGroupPid(), PanelConstants.OPT_TYPE_UPDATE, request.getPanelId(), "panel"); + }else{ + checkPanelName(request.getPanelName(), request.getPanelGroupPid(), PanelConstants.OPT_TYPE_INSERT, null, "panel"); + } + panelHistoryInfo.setName(request.getPanelName()); + panelHistoryInfo.setPid(request.getPanelGroupPid()); + panelHistoryInfo.setUpdateBy(userName); + panelHistoryInfo.setUpdateTime(currentTime); + panelGroupMapper.updateByPrimaryKey(panelHistoryInfo); + + //数据集分组移动,变更 + DatasetGroup datasetGroupHistoryInfo = datasetGroupMapper.selectByPrimaryKey(request.getDatasetGroupId()); + DatasetGroup datasetGroup = new DatasetGroup(); + datasetGroup.setName(request.getDatasetGroupName()); + datasetGroup.setId(request.getDatasetGroupId()); + if(datasetGroupHistoryInfo.getPid().equals(request.getDatasetGroupPid())){ + datasetGroup.setPid(request.getDatasetGroupPid()); + } + dataSetGroupService.checkName(datasetGroup); + datasetGroupHistoryInfo.setName(request.getDatasetGroupName()); + datasetGroupHistoryInfo.setPid(request.getDatasetGroupPid()); + datasetGroupMapper.updateByPrimaryKey(datasetGroupHistoryInfo); + + //数据源变更 + panelAppTemplateService.editDatasource(request.getDatasourceList()); + } } diff --git a/backend/src/main/java/io/dataease/service/panel/applog/AppLogService.java b/backend/src/main/java/io/dataease/service/panel/applog/AppLogService.java index 0c174f17a4..2b28d25a78 100644 --- a/backend/src/main/java/io/dataease/service/panel/applog/AppLogService.java +++ b/backend/src/main/java/io/dataease/service/panel/applog/AppLogService.java @@ -7,7 +7,14 @@ import io.dataease.dto.appTemplateMarket.AppLogGridDTO; import io.dataease.ext.ExtAppLogMapper; import io.dataease.ext.query.GridExample; import io.dataease.plugins.common.base.mapper.PanelAppTemplateLogMapper; +import io.dataease.service.dataset.DataSetGroupService; +import io.dataease.service.datasource.DatasourceService; +import io.dataease.service.panel.PanelGroupService; +import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.RequestBody; + import javax.annotation.Resource; import java.util.List; @@ -19,6 +26,12 @@ public class AppLogService { private PanelAppTemplateLogMapper appLogMapper; @Resource private ExtAppLogMapper extAppLogMapper; + @Resource + private PanelGroupService panelGroupService; + @Resource + private DataSetGroupService dataSetGroupService; + @Resource + private DatasourceService datasourceService; public List query(KeyGridRequest request) { @@ -34,4 +47,19 @@ public class AppLogService { } + @Transactional + public void deleteLogAndResource(AppLogGridDTO request) throws Exception { + if (request.getDeleteResource()) { + if (StringUtils.isNotEmpty(request.getPanelId())) { + panelGroupService.deleteCircle(request.getPanelId()); + } + if (StringUtils.isNotEmpty(request.getDatasetGroupId())) { + dataSetGroupService.delete(request.getDatasetGroupId()); + } + if (StringUtils.isNotEmpty(request.getDatasourceId())) { + datasourceService.deleteDatasource(request.getDatasourceId()); + } + } + appLogMapper.deleteByPrimaryKey(request.getId()); + } } diff --git a/backend/src/main/resources/db/migration/V42__1.16.sql b/backend/src/main/resources/db/migration/V42__1.16.sql index 7644233454..d7cc55a7ab 100644 --- a/backend/src/main/resources/db/migration/V42__1.16.sql +++ b/backend/src/main/resources/db/migration/V42__1.16.sql @@ -31,3 +31,14 @@ WHERE (`msg_type_id` = 6); ALTER TABLE `sys_user_assist` ADD COLUMN `larksuite_id` VARCHAR(255) NULL DEFAULT NULL AFTER `lark_id`; + +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-app-template', 'panel/appTemplate/index', 13, 'sys-param', + 'panel/appTemplate/index', 0, 0, 0, NULL, NULL, NULL, NULL, 1620444227389); +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 (203, 0, 0, 1, '应用市场', 'app-template-market', 'panel/appTemplateMarket/index', 6, 'dashboard', + '/appTemplateMarket', 0, 0, 0, NULL, NULL, NULL, NULL, 1620444227389); diff --git a/frontend/src/api/appTemplateMarket/log.js b/frontend/src/api/appTemplateMarket/log.js index 3a14b96f80..a652d53b38 100644 --- a/frontend/src/api/appTemplateMarket/log.js +++ b/frontend/src/api/appTemplateMarket/log.js @@ -11,7 +11,7 @@ export function logGrid(page, size, data) { export function opTypes() { return request({ - url: '/api/log/opTypes', + url: '/app/log/opTypes', method: 'post', loading: true }) @@ -19,10 +19,19 @@ export function opTypes() { export function exportExcel(data) { return request({ - url: '/api/log/export', + url: '/app/log/export', method: 'post', loading: true, responseType: 'blob', data }) } + +export function deleteLogAndResource(data) { + return request({ + url: '/app/log/deleteLog', + method: 'post', + data, + loading: true + }) +} diff --git a/frontend/src/api/panel/panel.js b/frontend/src/api/panel/panel.js index 3a74f445a8..000b261417 100644 --- a/frontend/src/api/panel/panel.js +++ b/frontend/src/api/panel/panel.js @@ -313,7 +313,34 @@ export function appApply(data) { return request({ url: 'panel/group/appApply', method: 'post', - loading: true, + loading: false, data }) } + +export function appEdit(data) { + return request({ + url: 'panel/group/appEdit', + method: 'post', + loading: false, + data + }) +} + +export function editApply(data) { + return request({ + url: 'panel/group/appApply', + method: 'post', + loading: false, + data + }) +} + + +export function findOneWithParent(panelId) { + return request({ + url: 'panel/group/findOneWithParent/'+panelId, + method: 'get', + loading: false + }) +} diff --git a/frontend/src/components/business/DeLayoutContent.vue b/frontend/src/components/business/DeLayoutContent.vue index 372b5c4c94..5c34d3c17a 100644 --- a/frontend/src/components/business/DeLayoutContent.vue +++ b/frontend/src/components/business/DeLayoutContent.vue @@ -42,7 +42,7 @@ export default { return backPath || backName || backTo }, needInnerPadding() { - return ['sys-identification', 'sys-abutment', 'sys-task-email', 'system-dept', 'system-dept-form', 'system-auth', 'sys-appearance', 'system-param', 'system-template', 'sys-task-dataset', 'sys-msg-web-all', 'system-plugin'].includes(this.$route.name) + return ['system-app-template','sys-identification', 'sys-abutment', 'sys-task-email', 'system-dept', 'system-dept-form', 'system-auth', 'sys-appearance', 'system-param', 'system-template', 'sys-task-dataset', 'sys-msg-web-all', 'system-plugin'].includes(this.$route.name) } } } diff --git a/frontend/src/lang/en.js b/frontend/src/lang/en.js index e17d775d0b..2d8b10466a 100644 --- a/frontend/src/lang/en.js +++ b/frontend/src/lang/en.js @@ -2621,6 +2621,16 @@ export default { search_by_keyword: 'Search by keyword', apply_logs: 'Apply logs', app_group_delete_tips: 'Are you sure to delete this application category?', - app_group_delete_content: 'After deletion, all application templates in this category will also be deleted.' + app_group_delete_content: 'After deletion, all application templates in this category will also be deleted.', + panel_position: 'Panel position', + panel_name: 'Panel name', + dataset_group_position: 'Dataset group position', + dataset_group_name: 'Dataset name', + datasource_info: 'Datasource info', + datasource: 'Datasource', + dataset_group: 'Dataset group', + panel: 'Panel', + log_delete_tips: 'Are you sure to delete this application record?', + log_resource_delete_tips: 'Delete related resources (irrecoverable after deletion)' } } diff --git a/frontend/src/lang/tw.js b/frontend/src/lang/tw.js index 49ad2ec52a..8d24054a3e 100644 --- a/frontend/src/lang/tw.js +++ b/frontend/src/lang/tw.js @@ -2622,6 +2622,16 @@ export default { search_by_keyword: '通過關鍵字搜索', apply_logs: '應用記錄', app_group_delete_tips: '確定刪除該應用分類嗎?', - app_group_delete_content: '刪除後,該分類中所有的應用模闆也將被刪除。' + app_group_delete_content: '刪除後,該分類中所有的應用模板也將被刪除。', + panel_position: '儀表板位置', + panel_name: '儀表板名稱', + dataset_group_position: '數據集分組位置', + dataset_group_name: '數據集分組名稱', + datasource_info: '數據源信息', + datasource: '數據源', + dataset_group: '數據集分組', + panel: '儀表板', + log_delete_tips: '確定刪除該條應用記錄嗎?', + log_resource_delete_tips: '刪除相關資源(刪除後不可恢復)' } } diff --git a/frontend/src/lang/zh.js b/frontend/src/lang/zh.js index f3b9652ced..0e2b69f1c0 100644 --- a/frontend/src/lang/zh.js +++ b/frontend/src/lang/zh.js @@ -2622,6 +2622,16 @@ export default { search_by_keyword: '通过关键字搜索', apply_logs: '应用记录', app_group_delete_tips: '确定删除该应用分类吗?', - app_group_delete_content: '删除后,该分类中所有的应用模板也将被删除。' + app_group_delete_content: '删除后,该分类中所有的应用模板也将被删除。', + panel_position: '仪表板位置', + panel_name: '仪表板名称', + dataset_group_position: '数据集分组位置', + dataset_group_name: '数据集分组名称', + datasource_info: '数据源信息', + datasource: '数据源', + dataset_group: '数据集分组', + panel: '仪表板', + log_delete_tips: '确定删除该条应用记录吗?', + log_resource_delete_tips: '删除相关资源(删除后不可恢复)' } } diff --git a/frontend/src/views/panel/appTemplate/AppTemplateContent.vue b/frontend/src/views/panel/appTemplate/AppTemplateContent.vue new file mode 100644 index 0000000000..af5a13a612 --- /dev/null +++ b/frontend/src/views/panel/appTemplate/AppTemplateContent.vue @@ -0,0 +1,535 @@ + + + + + diff --git a/frontend/src/views/panel/appTemplate/component/AppTemplateApply.vue b/frontend/src/views/panel/appTemplate/component/AppTemplateApply.vue new file mode 100644 index 0000000000..2ab5d248a5 --- /dev/null +++ b/frontend/src/views/panel/appTemplate/component/AppTemplateApply.vue @@ -0,0 +1,54 @@ + + + + + diff --git a/frontend/src/views/panel/appTemplate/component/TemplateItem.vue b/frontend/src/views/panel/appTemplate/component/TemplateItem.vue index b86fbee65c..fe456be986 100644 --- a/frontend/src/views/panel/appTemplate/component/TemplateItem.vue +++ b/frontend/src/views/panel/appTemplate/component/TemplateItem.vue @@ -12,7 +12,7 @@ alt="" > -
+
- + - - {{ $t("commons.update") }} + + {{ $t('commons.update') }} - - {{ $t("commons.uninstall") }} + + {{ $t('commons.uninstall') }}
+ +
+ + + + {{ model.name }} + + + + {{ $t('panel.preview') }} + + {{ $t('panel.apply') }} + + + +
- diff --git a/frontend/src/views/panel/appTemplateMarket/component/AppMarketPreview.vue b/frontend/src/views/panel/appTemplateMarket/component/AppMarketPreview.vue new file mode 100644 index 0000000000..1a69620825 --- /dev/null +++ b/frontend/src/views/panel/appTemplateMarket/component/AppMarketPreview.vue @@ -0,0 +1,124 @@ + + + + + diff --git a/frontend/src/views/panel/appTemplateMarket/index.vue b/frontend/src/views/panel/appTemplateMarket/index.vue index d259e822d7..ddee12aeba 100644 --- a/frontend/src/views/panel/appTemplateMarket/index.vue +++ b/frontend/src/views/panel/appTemplateMarket/index.vue @@ -1,12 +1,11 @@ @@ -143,12 +118,17 @@ import MarketPreview from '@/views/panel/appTemplateMarket/component/MarketPrevi import elementResizeDetectorMaker from 'element-resize-detector' import AppTemplateItem from '@/views/panel/appTemplateMarket/component/AppTemplateItem' import AppTemplateLog from '@/views/panel/appTemplateMarket/log' +import AppTemplate from '@/views/panel/appTemplate' +import AppTemplateContent from '@/views/panel/appTemplate/AppTemplateContent' +import AppMarketPreview from '@/views/panel/appTemplateMarket/component/AppMarketPreview' +import AppTemplateApply from '@/views/panel/appTemplate/component/AppTemplateApply' export default { name: 'AppTemplateMarket', - components: { AppTemplateLog, AppTemplateItem, MarketPreview }, + components: { AppTemplateApply, AppMarketPreview, AppTemplateContent, AppTemplate, AppTemplateLog, AppTemplateItem, MarketPreview }, data() { return { + previewItem: null, hasResult: true, templateMiniWidth: 330, templateCurWidth: 310, @@ -194,11 +174,8 @@ export default { } } }, - computed: { - - }, - watch: { - }, + computed: {}, + watch: {}, mounted() { this.initMarketTemplate() this.getGroupTree() @@ -215,6 +192,24 @@ export default { }) }, methods: { + applyNew(item) { + const datasourceInfo = JSON.parse(item.datasourceInfo)[0] + const param = { + datasourceType: datasourceInfo.type, + appTemplateId: item.id, + appTemplateName: item.name, + panelName: item.name, + datasetGroupName: item.name + } + this.$refs.templateApply.init(param) + }, + appApply(){ + this.applyNew(this.previewItem) + }, + previewApp(item){ + this.previewModel = true + this.previewItem = item + }, initMarketTemplate() { searchAppTemplate({ nodeType: 'folder' }).then(rsp => { this.currentAppShowList = rsp.data @@ -280,109 +275,120 @@ export default { diff --git a/frontend/src/views/panel/appTemplateMarket/log/index.vue b/frontend/src/views/panel/appTemplateMarket/log/index.vue index 5b0dbc0b45..a369b675a6 100644 --- a/frontend/src/views/panel/appTemplateMarket/log/index.vue +++ b/frontend/src/views/panel/appTemplateMarket/log/index.vue @@ -10,7 +10,8 @@ type="primary" icon="el-icon-plus" @click="applyNew()" - >{{ $t('commons.create') }} + >{{ $t('commons.create') }} +   {{ $t("user.filter") - }} + >{{ + $t('user.filter') + }} + @@ -45,8 +48,8 @@ class="filter-texts" > {{ paginationConfig.total }} - {{ $t("user.result_one") }} - + {{ $t('user.result_one') }} + {{ ele }} + class="el-icon-close" + @click="clearOneFilter(index)" + />

{{ $t("user.clear_filter") }} + >{{ $t('user.clear_filter') }} +
+ :label="$t('app_template.panel')" + > + + {{ scope.row.applyTime | timestampFormatDate }} + + +
@@ -132,6 +166,36 @@ @search="filterDraw" /> + + + + + + + + + {{$t('app_template.log_resource_delete_tips')}} + + + {{ $t('commons.cancel') }} + {{ $t('commons.confirm') }} + + @@ -144,10 +208,14 @@ import { addOrder, formatOrders } from '@/utils/index' -import { logGrid } from '@/api/appTemplateMarket/log' +import { deleteLogAndResource, logGrid } from '@/api/appTemplateMarket/log' +import { findOneWithParent } from '@/api/panel/panel' +import AppTemplateApply from '@/views/panel/appTemplate/component/AppTemplateApply' +import { deepCopy } from '@/components/canvas/utils/utils' + export default { name: 'AppTemplateLog', - components: { GridTable, filterUser }, + components: { AppTemplateApply, GridTable, filterUser }, mixins: [keyEnter], props: { appTemplateId: { @@ -162,6 +230,11 @@ export default { }, data() { return { + deleteConfirmDialog: false, + deleteItemInfo: { + deleteResource: false + }, + operateWidth: 168, columns: [], paginationConfig: { currentPage: 1, @@ -194,6 +267,53 @@ export default { this.resizeObserver() }, methods: { + closeDel() { + this.deleteItemInfo = { + deleteResource: false + } + this.deleteConfirmDialog = false + }, + confirmDel() { + deleteLogAndResource(this.deleteItemInfo).then(()=>{ + this.closeDel() + this.search() + }) + }, + closeDraw() { + this.search() + }, + editApply(item) { + const param = { + datasourceType: item.datasourceType, + logId: item.id, + panelId: item.panelId, + panelGroupPid: item.panelGroupPid, + datasourceId: item.datasourceId, + datasetGroupPid: item.datasetGroupPid, + datasetGroupId: item.datasetGroupId, + datasetGroupName: item.datasetGroupName, + panelName: item.panelName + } + this.$refs.templateEditApply.init(param) + }, + goToDatasource(row) { + + }, + goPanel(row) { + findOneWithParent(row.panelId).then(rsp => { + this.$router.push({ name: 'panel', params: rsp.data }) + }) + }, + edit() { + + }, + del(item) { + this.deleteItemInfo = { + ...item, + deleteResource: false + } + this.deleteConfirmDialog = true + }, applyNew() { this.$emit('applyNew') }, @@ -302,4 +422,13 @@ export default { .table-container-filter { height: calc(100% - 110px); } + +.link-span { + color: #3370FF; + cursor: pointer; + + &:hover { + text-decoration: underline; + } +} diff --git a/frontend/src/views/panel/list/PanelViewShow.vue b/frontend/src/views/panel/list/PanelViewShow.vue index 106a7dbb4a..25279cdd46 100644 --- a/frontend/src/views/panel/list/PanelViewShow.vue +++ b/frontend/src/views/panel/list/PanelViewShow.vue @@ -17,7 +17,7 @@ style="border-bottom: 1px solid;border-bottom-color:#E6E6E6;" >
- +
- + {{ $t('panel.export_to_img') }} + {{ $t('panel.export_to_app') }} @@ -304,6 +308,7 @@ export default { }, data() { return { + canvasInfoTemp: 'preview-temp-canvas-main', canvasId: 'canvas-main', showMain: true, pdfTemplateSelectedIndex: 0, @@ -405,7 +410,7 @@ export default { saveToTemplate() { this.dataLoading = true setTimeout(() => { - html2canvas(document.getElementById('canvasInfoTemp')).then(canvas => { + html2canvas(document.getElementById(this.canvasInfoTemp)).then(canvas => { this.templateSaveShow = true this.dataLoading = false const snapshot = canvas.toDataURL('image/jpeg', 0.1) // 0.2是图片质量 @@ -430,7 +435,7 @@ export default { _this.dataLoading = true try { _this.findStaticSource(function(staticResource) { - html2canvas(document.getElementById('canvasInfoTemp')).then(canvas => { + html2canvas(document.getElementById(_this.canvasInfoTemp)).then(canvas => { _this.dataLoading = false const snapshot = canvas.toDataURL('image/jpeg', 0.1) // 0.1是图片质量 if (snapshot !== '') { @@ -458,9 +463,9 @@ export default { _this.dataLoading = true try { _this.findStaticSource(function(staticResource) { - html2canvas(document.getElementById('canvasInfoTemp')).then(canvas => { + html2canvas(document.getElementById(_this.canvasInfoTemp)).then(canvas => { _this.dataLoading = false - const snapshot = canvas.toDataURL('image/jpeg', 0.1) // 0.1是图片质量 + const snapshot = canvas.toDataURL('image/jpeg', 1) // 0.1是图片质量 if (snapshot !== '') { const panelInfo = { name: _this.$store.state.panel.panelInfo.name, @@ -528,7 +533,7 @@ export default { setTimeout(() => { this.exporting = true setTimeout(() => { - const canvasID = document.getElementById('canvasInfoTemp') + const canvasID = document.getElementById(this.canvasInfoTemp) const a = document.createElement('a') html2canvas(canvasID).then(canvas => { this.exporting = false @@ -559,7 +564,7 @@ export default { setTimeout(() => { this.exporting = true setTimeout(() => { - html2canvas(document.getElementById('canvasInfoTemp')).then(canvas => { + html2canvas(document.getElementById(this.canvasInfoTemp)).then(canvas => { const snapshot = canvas.toDataURL('image/jpeg', 1) // 是图片质量 this.dataLoading = false this.exporting = false @@ -573,7 +578,7 @@ export default { }, refreshTemplateInfo() { this.templateInfo = {} - html2canvas(document.getElementById('canvasInfoTemp')).then(canvas => { + html2canvas(document.getElementById(this.canvasInfoTemp)).then(canvas => { const snapshot = canvas.toDataURL('image/jpeg', 0.1) // 0.2是图片质量 if (snapshot !== '') { this.templateInfo = { @@ -623,7 +628,9 @@ export default { if (this.showType === 1 && this.shareUserId !== null) { const param = { userId: this.shareUserId } proxyInitPanelData(this.panelInfo.id, param, null) - } else { initPanelData(this.panelInfo.id, false) } + } else { + initPanelData(this.panelInfo.id, false) + } }, changePublishState() { if (this.panelInfo.status === 'publish') { @@ -642,72 +649,76 @@ export default { diff --git a/frontend/src/views/system/datasource/DsForm.vue b/frontend/src/views/system/datasource/DsForm.vue index 96ca0ac5f0..0382ad2bee 100644 --- a/frontend/src/views/system/datasource/DsForm.vue +++ b/frontend/src/views/system/datasource/DsForm.vue @@ -1,9 +1,9 @@ @@ -167,6 +283,10 @@ import PluginCom from '@/views/system/plugin/PluginCom' import { listDatasourceType, listDatasource } from '@/api/system/datasource' import deTextarea from '@/components/deCustomCm/deTextarea.vue' import msgCfm from '@/components/msgCfm' +import { dsGroupTree } from '@/api/dataset/dataset' +import { appApply, appEdit, groupTree } from '@/api/panel/panel' +import { deepCopy } from '@/components/canvas/utils/utils' + export default { name: 'DsForm', components: { @@ -175,8 +295,50 @@ export default { deTextarea }, mixins: [msgCfm], + props: { + referencePosition: { + type: String, + default: 'datasource' + }, + outerParams: { + type: Object, + request: false + } + }, data() { return { + attachRule: { + panelName: [ + { + required: true, + min: 2, + max: 25, + message: i18n.t('datasource.input_limit_2_25', [2, 25]), + trigger: 'blur' + } + ], + datasetGroupName: [ + { + required: true, + min: 2, + max: 25, + message: i18n.t('datasource.input_limit_2_25', [2, 25]), + trigger: 'blur' + } + ], + datasetGroupPid: [{ required: true, message: i18n.t('chart.select_group'), trigger: 'blur' }], + panelGroupPid: [{ required: true, message: i18n.t('chart.select_group'), trigger: 'blur' }] + }, + panelGroupList: [], + datasetGroupList: [], + attachForm: { + appTemplateId: '', + panelGroupPid: null, + panelName: '', + datasetGroupPid: null, + datasetGroupId: null, + datasetGroupName: '' + }, disabled: false, form: { configuration: { @@ -402,8 +564,29 @@ export default { async created() { await this.datasourceTypes() this.queryTreeData() - const { id, showModel, type, name } = this.$route.query + let { id, showModel, type, name } = this.$route.query this.params = this.$route.query + if (this.positionCheck('appMarket')) { + id = this.outerParams.datasourceId + showModel = this.outerParams.showModel + type = this.outerParams.datasourceType + name = this.outerParams.name + this.attachForm.appTemplateId = this.outerParams.appTemplateId + this.attachForm.panelGroupPid = this.outerParams.panelGroupPid + this.attachForm.panelId = this.outerParams.panelId + this.attachForm.panelName = this.outerParams.panelName + this.attachForm.datasetGroupPid = this.outerParams.datasetGroupPid ? this.outerParams.datasetGroupPid : '0' + this.attachForm.datasetGroupId = this.outerParams.datasetGroupId + this.attachForm.datasetGroupName = this.outerParams.datasetGroupName + this.params = { + id: this.outerParams.datasourceId, + showModel: this.outerParams.showModel, + type: this.outerParams.datasourceType, + name: this.outerParams.name + } + this.getPanelGroupTree() + this.getDatasetGroupTree() + } if (id) { await this.getDatasourceDetail(id, showModel) this.edit(this.params) @@ -420,6 +603,36 @@ export default { this.disabled = Boolean(id) && showModel === 'show' && !this.canEdit }, methods: { + normalizer(node) { + // 去掉children=null的属性 + if (node.children === null || node.children === 'null') { + delete node.children + } + }, + getDatasetGroupTree() { + dsGroupTree({ nodeType: 'group', excludedId: this.attachForm.datasetGroupId }).then(res => { + this.datasetGroupList = [{ + id: '0', + name: this.$t('dataset.dataset_group'), + label: this.$t('dataset.dataset_group'), + pid: '0', + privileges: 'grant,manage,use', + type: 'group', + children: res.data + }] + }) + }, + getPanelGroupTree() { + groupTree({ nodeType: 'folder' }).then(res => { + this.panelGroupList = res.data + if (!this.attachForm.panelGroupPid && this.panelGroupList && this.panelGroupList.length > 0) { + this.attachForm.panelGroupPid = this.panelGroupList[0].id + } + }) + }, + positionCheck(referencePosition) { + return this.referencePosition === referencePosition + }, datasourceTypes() { return listDatasourceType().then((res) => { this.dsTypes = res.data || [] @@ -569,7 +782,7 @@ export default { if ( configuration.host === this.form.configuration.host && configuration.dataBase === - this.form.configuration.dataBase && + this.form.configuration.dataBase && configuration.port === this.form.configuration.port ) { repeat = true @@ -584,7 +797,7 @@ export default { if ( configuration.host === this.form.configuration.host && configuration.dataBase === - this.form.configuration.dataBase && + this.form.configuration.dataBase && configuration.port === this.form.configuration.port && configuration.schema === this.form.configuration.schema ) { @@ -621,7 +834,7 @@ export default { configuration.schema === this.form.configuration.schema && configuration.host === this.form.configuration.host && configuration.dataBase === - this.form.configuration.dataBase && + this.form.configuration.dataBase && configuration.port === this.form.configuration.port ) { repeat = true @@ -631,7 +844,7 @@ export default { if ( configuration.host === this.form.configuration.host && configuration.dataBase === - this.form.configuration.dataBase && + this.form.configuration.dataBase && configuration.port === this.form.configuration.port ) { repeat = true @@ -656,11 +869,20 @@ export default { if (!status) { return } + if (this.positionCheck('appMarket')) { + this.$refs.attachParamsForm.validate(valid => { + if (!valid) { + return false + } + } + ) + } this.$refs.dsForm.validate((valid) => { if (!valid) { return false } - const method = this.formType === 'add' ? addDs : editDs + let method = this.formType === 'add' ? addDs : editDs + const form = JSON.parse(JSON.stringify(this.form)) if (form.type === 'api') { if (this.form.apiConfiguration.length < 1) { @@ -674,17 +896,29 @@ export default { } else { form.configuration = JSON.stringify(form.configuration) } + const isAppMarket = this.positionCheck('appMarket') + let appApplyForm + if (isAppMarket) { + if (typeof form.desc === 'object') { + form.desc = '' + } + appApplyForm = { + ...this.attachForm, + datasourceList: [deepCopy(form)] + } + method = this.formType === 'add' ? appApply : appEdit + } if ( this.formType === 'modify' && this.originConfiguration !== form.configuration ) { - if (repeat) { + if (repeat && !isAppMarket) { $confirm( i18n.t('datasource.repeat_datasource_msg') + - '[' + - repeatDsName.join(',') + - '], ' + - i18n.t('datasource.confirm_save'), + '[' + + repeatDsName.join(',') + + '], ' + + i18n.t('datasource.confirm_save'), () => { $confirm(i18n.t('datasource.edit_datasource_msg'), () => { this.method(method, form) @@ -693,27 +927,40 @@ export default { ) } else { $confirm(i18n.t('datasource.edit_datasource_msg'), () => { - this.method(method, form) + isAppMarket ? this.appApplyMethod(method, appApplyForm) : this.method(method, form) }) } return } - if (repeat) { + if (repeat && !isAppMarket) { $confirm( i18n.t('datasource.repeat_datasource_msg') + - '[' + - repeatDsName.join(',') + - '], ' + - i18n.t('datasource.confirm_save'), + '[' + + repeatDsName.join(',') + + '], ' + + i18n.t('datasource.confirm_save'), () => { this.method(method, form) } ) } else { - this.method(method, form) + isAppMarket ? this.appApplyMethod(method, appApplyForm) : this.method(method, form) } }) }, + appApplyMethod(method, form) { + this.formLoading = true + method(form).then((res) => { + this.$success(i18n.t('commons.save_success')) + if (this.formType === 'add') { + this.$router.push({ name: 'panel', params: res.data }) + } else { + this.closeDraw() + } + }).finally(() => { + this.formLoading = false + }) + }, method(method, form) { this.formLoading = true method(form).then((res) => { @@ -767,6 +1014,14 @@ export default { if (!status) { return } + if (this.positionCheck('appMarket')) { + this.$refs.attachParamsForm.validate(valid => { + if (!valid) { + return false + } + } + ) + } this.$refs.dsForm.validate((valid) => { if (valid) { const data = JSON.parse(JSON.stringify(this.form)) @@ -844,6 +1099,10 @@ export default { backToList() { this.$router.push('/datasource/index') }, + + closeDraw() { + this.$emit('closeDraw') + }, logOutTips() { const options = { title: 'role.tips', @@ -967,21 +1226,47 @@ export default { } }) }, - handleClick(tab, event) {} + handleClick(tab, event) { + } } } diff --git a/frontend/src/views/system/user/UserEditer.vue b/frontend/src/views/system/user/UserEditer.vue index 3442409cce..0e35c704c1 100644 --- a/frontend/src/views/system/user/UserEditer.vue +++ b/frontend/src/views/system/user/UserEditer.vue @@ -177,6 +177,7 @@ style="width: 100%" :disabled="formType !== 'add' && form.isAdmin" multiple + filterable :placeholder="$t('user.input_roles')" @remove-tag="deleteTag" @change="changeRole" From f70bc9152a2aee2a29d1eef5b6bc698945c4a84a Mon Sep 17 00:00:00 2001 From: junjun Date: Thu, 27 Oct 2022 15:56:38 +0800 Subject: [PATCH 11/39] =?UTF-8?q?refactor(=E8=A7=86=E5=9B=BE):=20=E8=BE=85?= =?UTF-8?q?=E5=8A=A9=E7=BA=BF=E3=80=81=E9=98=88=E5=80=BC=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E7=95=8C=E9=9D=A2UI=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/views/chart/components/senior/AssistLine.vue | 2 +- frontend/src/views/chart/components/senior/Threshold.vue | 4 ++-- .../views/chart/components/senior/dialog/AssistLineEdit.vue | 2 ++ .../chart/components/senior/dialog/TableThresholdEdit.vue | 1 + 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/frontend/src/views/chart/components/senior/AssistLine.vue b/frontend/src/views/chart/components/senior/AssistLine.vue index b0eef1e46a..0b9c24af06 100644 --- a/frontend/src/views/chart/components/senior/AssistLine.vue +++ b/frontend/src/views/chart/components/senior/AssistLine.vue @@ -51,7 +51,7 @@ :title="$t('chart.assist_line')" :visible="editLineDialog" :show-close="false" - width="70%" + width="1000px" class="dialog-css" > @@ -274,7 +274,7 @@ :title="$t('chart.threshold')" :visible="editTableThresholdDialog" :show-close="false" - width="50%" + width="800px" class="dialog-css" append-to-body > diff --git a/frontend/src/views/chart/components/senior/dialog/AssistLineEdit.vue b/frontend/src/views/chart/components/senior/dialog/AssistLineEdit.vue index 21e133f793..655a2a4a7c 100644 --- a/frontend/src/views/chart/components/senior/dialog/AssistLineEdit.vue +++ b/frontend/src/views/chart/components/senior/dialog/AssistLineEdit.vue @@ -17,6 +17,7 @@ diff --git a/frontend/src/views/chart/components/senior/dialog/TableThresholdEdit.vue b/frontend/src/views/chart/components/senior/dialog/TableThresholdEdit.vue index 073dfdee8b..119bd29ce7 100644 --- a/frontend/src/views/chart/components/senior/dialog/TableThresholdEdit.vue +++ b/frontend/src/views/chart/components/senior/dialog/TableThresholdEdit.vue @@ -100,6 +100,7 @@ v-show="!item.term.includes('null') && !item.term.includes('empty') && item.term !== 'between'" v-model="item.value" class="value-item" + style="margin-left: 10px;" :placeholder="$t('chart.drag_block_label_value')" size="mini" clearable From 1c64abd5d1cae84fd400ddbe6fd388842573b2b3 Mon Sep 17 00:00:00 2001 From: wangjiahao <1522128093@qq.com> Date: Thu, 27 Oct 2022 16:00:45 +0800 Subject: [PATCH 12/39] =?UTF-8?q?refactor(=E4=BB=AA=E8=A1=A8=E6=9D=BF):=20?= =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E7=AB=AF=E8=AE=BE=E8=AE=A1=E6=96=B0=E7=94=BB?= =?UTF-8?q?=E5=B8=83=E9=80=82=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/Editor/ComponentWrapper.vue | 2 +- .../src/components/widget/DeWidget/DeTabs.vue | 19 +++++++++++++------ .../src/views/panel/edit/ComponentWait.vue | 2 +- frontend/src/views/panel/edit/index.vue | 1 + 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/canvas/components/Editor/ComponentWrapper.vue b/frontend/src/components/canvas/components/Editor/ComponentWrapper.vue index cf18c101c3..50407a9c93 100644 --- a/frontend/src/components/canvas/components/Editor/ComponentWrapper.vue +++ b/frontend/src/components/canvas/components/Editor/ComponentWrapper.vue @@ -195,7 +195,7 @@ export default { return style }, componentActiveFlag() { - return (this.curComponent && this.config === this.curComponent && !this.previewVisible && !this.showPosition.includes('email-task')) || this.showPosition.includes('multiplexing') + return !this.mobileLayoutStatus && ((this.curComponent && this.config === this.curComponent && !this.previewVisible && !this.showPosition.includes('email-task')) || this.showPosition.includes('multiplexing')) }, curGap() { return (this.canvasStyleData.panel.gap === 'yes' && this.config.auxiliaryMatrix) ? this.componentGap : 0 diff --git a/frontend/src/components/widget/DeWidget/DeTabs.vue b/frontend/src/components/widget/DeWidget/DeTabs.vue index edb11049dd..b97cd577fd 100644 --- a/frontend/src/components/widget/DeWidget/DeTabs.vue +++ b/frontend/src/components/widget/DeWidget/DeTabs.vue @@ -56,7 +56,7 @@ -
+
item.canvasId === tabCanvasId) + } else { + return getNowCanvasComponentData(tabCanvasId) + } }, setContentThemeStyle() { this.element.options.tabList.forEach(tab => { diff --git a/frontend/src/views/panel/edit/ComponentWait.vue b/frontend/src/views/panel/edit/ComponentWait.vue index cc7ace5ece..3434a4b07a 100644 --- a/frontend/src/views/panel/edit/ComponentWait.vue +++ b/frontend/src/views/panel/edit/ComponentWait.vue @@ -6,7 +6,7 @@ Date: Thu, 27 Oct 2022 16:04:08 +0800 Subject: [PATCH 13/39] =?UTF-8?q?fix:=20cas=E6=9C=8D=E5=8A=A1=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E4=B8=AD=E6=96=87=E6=96=87=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/lang/zh.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/lang/zh.js b/frontend/src/lang/zh.js index 86e6efae90..851565d647 100644 --- a/frontend/src/lang/zh.js +++ b/frontend/src/lang/zh.js @@ -2630,6 +2630,6 @@ export default { }, logout: { oidc_logout_error: 'OIDC退出失败,是否继续退出DataEase?', - cas_logout_error: 'The CAS service is abnormal, please contact the administrator!' + cas_logout_error: 'CAS服务异常,请联系管理员!' } } From 2443b0177deeb062d058e6490a0c4f89dab2ca9c Mon Sep 17 00:00:00 2001 From: fit2cloud-chenyw <67260074+fit2cloud-chenyw@users.noreply.github.com> Date: Thu, 27 Oct 2022 16:04:53 +0800 Subject: [PATCH 14/39] =?UTF-8?q?fix:=20cas=E6=9C=8D=E5=8A=A1=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E8=8B=B1=E6=96=87=E6=96=87=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/lang/en.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/lang/en.js b/frontend/src/lang/en.js index 2b396f403a..d3a53cec82 100644 --- a/frontend/src/lang/en.js +++ b/frontend/src/lang/en.js @@ -2629,6 +2629,6 @@ export default { }, logout: { oidc_logout_error: 'OIDC failed to exit, do you continue to exit DataEase?', - cas_logout_error: 'CAS服务异常,请联系管理员!' + cas_logout_error: 'The CAS service is abnormal, please contact the administrator!' } } From b19914ce6b7efc28da45ff1195da35a5467624e9 Mon Sep 17 00:00:00 2001 From: fit2cloud-chenyw Date: Thu, 27 Oct 2022 16:08:21 +0800 Subject: [PATCH 15/39] =?UTF-8?q?fix(=E7=99=BB=E5=87=BA):=20=E5=AF=B9?= =?UTF-8?q?=E6=8E=A5cas=E5=90=8E=E9=80=80=E5=87=BA=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E8=B7=B3=E8=BD=AC=E5=88=B0cas=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E9=A1=B5=E9=9D=A2issues/2909?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/service/impl/ShiroServiceImpl.java | 2 ++ .../io/dataease/plugins/server/CasServer.java | 9 +++++++++ frontend/src/api/user.js | 7 +++++++ frontend/src/views/login/index.vue | 20 +++++++++++++++---- 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/backend/src/main/java/io/dataease/auth/service/impl/ShiroServiceImpl.java b/backend/src/main/java/io/dataease/auth/service/impl/ShiroServiceImpl.java index b92517f050..0fd46ef9a9 100644 --- a/backend/src/main/java/io/dataease/auth/service/impl/ShiroServiceImpl.java +++ b/backend/src/main/java/io/dataease/auth/service/impl/ShiroServiceImpl.java @@ -86,6 +86,7 @@ public class ShiroServiceImpl implements ShiroService { filterChainDefinitionMap.put("/api/auth/isOpenWecom", ANON); filterChainDefinitionMap.put("/api/auth/isOpenDingtalk", ANON); filterChainDefinitionMap.put("/api/auth/isOpenLark", ANON); + filterChainDefinitionMap.put("/api/auth/isOpenCas", ANON); filterChainDefinitionMap.put("/api/auth/isOpenLarksuite", ANON); filterChainDefinitionMap.put("/api/auth/getPublicKey", ANON); filterChainDefinitionMap.put("/api/pluginCommon/component/*", ANON); @@ -106,6 +107,7 @@ public class ShiroServiceImpl implements ShiroService { filterChainDefinitionMap.put("/plugin/larksuite/bind*", ANON); filterChainDefinitionMap.put("/plugin/larksuite/getQrParam", ANON); filterChainDefinitionMap.put("/cas/reset/**", ANON); + filterChainDefinitionMap.put("/cas/loginPage", ANON); filterChainDefinitionMap.put("/unauth", ANON); filterChainDefinitionMap.put("/display/**", ANON); diff --git a/backend/src/main/java/io/dataease/plugins/server/CasServer.java b/backend/src/main/java/io/dataease/plugins/server/CasServer.java index c54639c1b3..9a68ebec93 100644 --- a/backend/src/main/java/io/dataease/plugins/server/CasServer.java +++ b/backend/src/main/java/io/dataease/plugins/server/CasServer.java @@ -115,4 +115,13 @@ public class CasServer { return error; } } + + @GetMapping("/loginPage") + @ResponseBody + public String loginPage() { + String casServerUrlPrefix = systemParameterService.getValue("cas.login"); + String callBack = systemParameterService.getValue("cas.callBack"); + String result = casServerUrlPrefix + "?service=" + callBack; + return result; + } } diff --git a/frontend/src/api/user.js b/frontend/src/api/user.js index 32d2067307..14faf86234 100644 --- a/frontend/src/api/user.js +++ b/frontend/src/api/user.js @@ -100,6 +100,13 @@ export function casStatus() { }) } +export function casLoginPage() { + return request({ + url: '/cas/loginPage', + method: 'get' + }) +} + export function wecomStatus() { return request({ url: '/api/auth/isOpenWecom', diff --git a/frontend/src/views/login/index.vue b/frontend/src/views/login/index.vue index e5881db818..6765a686eb 100644 --- a/frontend/src/views/login/index.vue +++ b/frontend/src/views/login/index.vue @@ -130,17 +130,17 @@ > @@ -210,7 +210,7 @@ diff --git a/frontend/src/components/canvas/custom-component/DeRichTextView.vue b/frontend/src/components/canvas/custom-component/DeRichTextView.vue index c91825be1e..61de151790 100644 --- a/frontend/src/components/canvas/custom-component/DeRichTextView.vue +++ b/frontend/src/components/canvas/custom-component/DeRichTextView.vue @@ -1,8 +1,5 @@ @@ -167,7 +170,8 @@ export default { borderRadius: '0px', mapCenter: null, linkageActiveParam: null, - buttonTextColor: null + buttonTextColor: null, + loading: true } }, @@ -222,6 +226,7 @@ export default { } }, preDraw() { + this.loading = true // 基于准备好的dom,初始化echarts实例 // 渲染echart等待dom加载完毕,渲染之前先尝试销毁具有相同id的echart 放置多次切换仪表板有重复id情况 const that = this @@ -253,6 +258,10 @@ export default { that.$refs.viewTrack.trackButtonClick() } }) + this.myChart.off('finished') + this.myChart.on('finished', () => { + this.loading = false + }) }) }, loadThemeStyle() { From 8fe512cdf38e48add3b7d1174c456b066c987ad3 Mon Sep 17 00:00:00 2001 From: dataeaseShu <106045316+dataeaseShu@users.noreply.github.com> Date: Fri, 28 Oct 2022 16:58:25 +0800 Subject: [PATCH 35/39] =?UTF-8?q?fix:=20=E8=A7=92=E8=89=B2=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E7=94=A8=E6=88=B7=E5=A4=9A=E9=80=89=E6=89=93=E5=8B=BE?= =?UTF-8?q?=20=E6=95=B0=E6=8D=AE=E9=9B=86=E5=90=8D=E7=A7=B0=E9=87=8D?= =?UTF-8?q?=E5=A4=8D=E5=9B=BD=E9=99=85=E5=8C=96=20=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=BA=90=E5=8A=A0=E8=BD=BD=E6=95=B0=E6=8D=AEloading?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/styles/index.scss | 25 ++++++++++++++++++ frontend/src/views/dataset/add/AddApi.vue | 18 +------------ frontend/src/views/dataset/add/AddDB.vue | 19 +------------- frontend/src/views/dataset/form.vue | 2 +- .../system/datasource/DsConfiguration.vue | 26 ++++++++++++++++++- .../src/views/system/datasource/DsForm.vue | 3 +++ 6 files changed, 56 insertions(+), 37 deletions(-) diff --git a/frontend/src/styles/index.scss b/frontend/src/styles/index.scss index 0c6f4b2b69..3b1b8cfb1d 100644 --- a/frontend/src/styles/index.scss +++ b/frontend/src/styles/index.scss @@ -1632,4 +1632,29 @@ div:focus { white-space: nowrap; height: 24px; } +} + +.db-multiple-select-pop { + .selected::after { + content: ''; + width: 6px; + height: 12px; + position: absolute; + right: 12px; + top: 9px; + border: 2px solid #3370ff; + border-top-color: rgba(0, 0, 0, 0); + border-left-color: rgba(0, 0, 0, 0); + -webkit-transform: rotate(45deg); + transform: rotate(45deg); + } +} + +.role-add-name { + .el-select-dropdown__item.selected::after { + content: ''; + position: absolute; + right: 12px; + top: 9px; + } } \ No newline at end of file diff --git a/frontend/src/views/dataset/add/AddApi.vue b/frontend/src/views/dataset/add/AddApi.vue index a142f9a921..2e009ccca8 100644 --- a/frontend/src/views/dataset/add/AddApi.vue +++ b/frontend/src/views/dataset/add/AddApi.vue @@ -32,6 +32,7 @@ - diff --git a/frontend/src/views/dataset/add/AddDB.vue b/frontend/src/views/dataset/add/AddDB.vue index ba39fb8381..791f839d8c 100644 --- a/frontend/src/views/dataset/add/AddDB.vue +++ b/frontend/src/views/dataset/add/AddDB.vue @@ -33,7 +33,7 @@ v-model="dataSource" class="ds-list" filterable - popper-class="db-select-pop" + popper-class="db-multiple-select-pop" :placeholder="$t('dataset.pls_slc_data_source')" size="small" > @@ -640,20 +640,3 @@ export default { } } - diff --git a/frontend/src/views/dataset/form.vue b/frontend/src/views/dataset/form.vue index fa397647c1..6612092422 100644 --- a/frontend/src/views/dataset/form.vue +++ b/frontend/src/views/dataset/form.vue @@ -21,7 +21,7 @@ style="left: 55px" class="el-form-item__error" > - {{ $t('deDataset.already_Exists') }} + {{ $t('deDataset.already_exists') }}