From a7da54227b49211e51377cf3919a9293fb9a9c34 Mon Sep 17 00:00:00 2001 From: fit2cloud-chenyw Date: Mon, 11 Jul 2022 16:39:36 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E5=AE=9A=E6=97=B6?= =?UTF-8?q?=E6=8A=A5=E5=91=8A=E5=8F=91=E9=80=81=E8=A7=86=E5=9B=BE=E9=99=84?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/dataease/commons/utils/ExcelUtils.java | 25 ++++++++-- .../controller/chart/ChartViewController.java | 7 +++ .../io/dataease/dto/chart/ViewOption.java | 13 +++++ .../io/dataease/ext/ExtChartViewMapper.java | 3 ++ .../io/dataease/ext/ExtChartViewMapper.xml | 4 ++ .../strategy/impl/EmailTaskHandler.java | 11 ++++- .../strategy/impl/EmailTaskViewHandler.java | 17 +++++-- .../service/chart/ChartViewService.java | 4 ++ .../service/chart/ViewExportExcel.java | 10 ++-- .../dataease/service/system/EmailService.java | 8 ++-- frontend/src/api/chart/chart.js | 9 +++- .../src/components/DeViewSelect/index.vue | 48 +++++++++++-------- .../canvas/components/Editor/EditBarView.vue | 9 +--- frontend/src/store/modules/task.js | 28 ++++++++--- 14 files changed, 143 insertions(+), 53 deletions(-) create mode 100644 backend/src/main/java/io/dataease/dto/chart/ViewOption.java diff --git a/backend/src/main/java/io/dataease/commons/utils/ExcelUtils.java b/backend/src/main/java/io/dataease/commons/utils/ExcelUtils.java index b6a911baf3..7d66068be9 100644 --- a/backend/src/main/java/io/dataease/commons/utils/ExcelUtils.java +++ b/backend/src/main/java/io/dataease/commons/utils/ExcelUtils.java @@ -1,10 +1,14 @@ package io.dataease.commons.utils; import java.io.File; + import io.dataease.commons.model.excel.ExcelSheetModel; + import java.util.List; +import java.util.concurrent.atomic.AtomicReference; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; @@ -14,18 +18,25 @@ import org.apache.poi.ss.usermodel.FillPatternType; import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.IndexedColors; -import cn.hutool.core.util.IdUtil; public class ExcelUtils { + private static final String suffix = ".xls"; - public static File exportExcel(List sheets) throws Exception { - String fastUUID = IdUtil.fastUUID(); - File result = new File("/opt/dataease/data/" + fastUUID + ".xls"); + public static File exportExcel(List sheets, String fileName) throws Exception { + AtomicReference realFileName = new AtomicReference<>(fileName); HSSFWorkbook wb = new HSSFWorkbook(); + sheets.forEach(sheet -> { + List> details = sheet.getDatas(); details.add(0, sheet.getHeads()); - HSSFSheet curSheet = wb.createSheet(sheet.getSheetName()); + String sheetName = sheet.getSheetName(); + HSSFSheet curSheet = wb.createSheet(sheetName); + if (StringUtils.isBlank(fileName)) { + String cName = sheetName + suffix; + realFileName.set(cName); + } + CellStyle cellStyle = wb.createCellStyle(); Font font = wb.createFont(); font.setFontHeightInPoints((short) 12); @@ -52,6 +63,10 @@ public class ExcelUtils { } } }); + if (!StringUtils.endsWith(fileName, suffix)) { + realFileName.set(realFileName.get() + suffix); + } + File result = new File("/opt/dataease/data/" + realFileName.get()); wb.write(result); return result; } diff --git a/backend/src/main/java/io/dataease/controller/chart/ChartViewController.java b/backend/src/main/java/io/dataease/controller/chart/ChartViewController.java index c8b9d03057..3582444176 100644 --- a/backend/src/main/java/io/dataease/controller/chart/ChartViewController.java +++ b/backend/src/main/java/io/dataease/controller/chart/ChartViewController.java @@ -8,6 +8,7 @@ import io.dataease.commons.constants.ResourceAuthLevel; import io.dataease.controller.request.chart.*; import io.dataease.controller.response.ChartDetail; import io.dataease.dto.chart.ChartViewDTO; +import io.dataease.dto.chart.ViewOption; import io.dataease.plugins.common.base.domain.ChartViewWithBLOBs; import io.dataease.service.chart.ChartViewCacheService; import io.dataease.service.chart.ChartViewService; @@ -178,4 +179,10 @@ public class ChartViewController { chartViewService.viewPropsSave(chartViewWithBLOBs); } + @ApiOperation("查询仪表板下视图选项") + @PostMapping("/viewOptions/{panelId}") + public List viewOptions(@PathVariable("panelId") String panelId) { + return chartViewService.viewOptions(panelId); + } + } diff --git a/backend/src/main/java/io/dataease/dto/chart/ViewOption.java b/backend/src/main/java/io/dataease/dto/chart/ViewOption.java new file mode 100644 index 0000000000..116b119dfd --- /dev/null +++ b/backend/src/main/java/io/dataease/dto/chart/ViewOption.java @@ -0,0 +1,13 @@ +package io.dataease.dto.chart; + +import lombok.Data; + +import java.io.Serializable; + +@Data +public class ViewOption implements Serializable { + + private String id; + + private String name; +} diff --git a/backend/src/main/java/io/dataease/ext/ExtChartViewMapper.java b/backend/src/main/java/io/dataease/ext/ExtChartViewMapper.java index cb7467f896..4f42e6bf1d 100644 --- a/backend/src/main/java/io/dataease/ext/ExtChartViewMapper.java +++ b/backend/src/main/java/io/dataease/ext/ExtChartViewMapper.java @@ -2,6 +2,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 org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; @@ -50,4 +51,6 @@ public interface ExtChartViewMapper { void deleteNoUseView(@Param("viewIds") List viewIds,@Param("panelId") String panelId ); void initPanelChartViewCache(@Param("panelId") String panelId); + + List chartOptions(@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 68b45e2614..c4e3e49212 100644 --- a/backend/src/main/java/io/dataease/ext/ExtChartViewMapper.xml +++ b/backend/src/main/java/io/dataease/ext/ExtChartViewMapper.xml @@ -588,4 +588,8 @@ + + diff --git a/backend/src/main/java/io/dataease/job/sechedule/strategy/impl/EmailTaskHandler.java b/backend/src/main/java/io/dataease/job/sechedule/strategy/impl/EmailTaskHandler.java index 1ad73bee3d..e24464bf55 100644 --- a/backend/src/main/java/io/dataease/job/sechedule/strategy/impl/EmailTaskHandler.java +++ b/backend/src/main/java/io/dataease/job/sechedule/strategy/impl/EmailTaskHandler.java @@ -27,6 +27,7 @@ import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import javax.annotation.Resource; +import java.util.Optional; @Service("emailTaskHandler") public class EmailTaskHandler extends TaskHandler implements Job { @@ -116,6 +117,13 @@ public class EmailTaskHandler extends TaskHandler implements Job { emailXpackService.saveInstance(taskInstance); } + protected void removeInstance(GlobalTaskInstance taskInstance) { + EmailXpackService emailXpackService = SpringContextUtil.getBean(EmailXpackService.class); + Optional.ofNullable(taskInstance).ifPresent(instance -> + Optional.ofNullable(taskInstance.getInstanceId()).ifPresent(instanceId -> + emailXpackService.delInstance(instanceId))); + } + protected void error(GlobalTaskInstance taskInstance, Throwable t) { taskInstance.setStatus(ERROR); taskInstance.setInfo(t.getMessage()); @@ -125,11 +133,12 @@ public class EmailTaskHandler extends TaskHandler implements Job { @Async("priorityExecutor") public void sendReport(GlobalTaskInstance taskInstance, XpackEmailTemplateDTO emailTemplateDTO, - SysUserEntity user) { + SysUserEntity user) { EmailXpackService emailXpackService = SpringContextUtil.getBean(EmailXpackService.class); try { XpackEmailTaskRequest taskForm = emailXpackService.taskForm(taskInstance.getTaskId()); if (ObjectUtils.isEmpty(taskForm) || CronUtils.taskExpire(taskForm.getEndTime())) { + removeInstance(taskInstance); return; } String panelId = emailTemplateDTO.getPanelId(); diff --git a/backend/src/main/java/io/dataease/job/sechedule/strategy/impl/EmailTaskViewHandler.java b/backend/src/main/java/io/dataease/job/sechedule/strategy/impl/EmailTaskViewHandler.java index 902399c751..34881d2881 100644 --- a/backend/src/main/java/io/dataease/job/sechedule/strategy/impl/EmailTaskViewHandler.java +++ b/backend/src/main/java/io/dataease/job/sechedule/strategy/impl/EmailTaskViewHandler.java @@ -11,6 +11,7 @@ import io.dataease.plugins.xpack.email.dto.response.XpackEmailTemplateDTO; import io.dataease.plugins.xpack.email.service.EmailXpackService; import io.dataease.service.chart.ViewExportExcel; import io.dataease.service.system.EmailService; +import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.ObjectUtils; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; @@ -31,9 +32,11 @@ public class EmailTaskViewHandler extends EmailTaskHandler { public void sendReport(GlobalTaskInstance taskInstance, XpackEmailTemplateDTO emailTemplateDTO, SysUserEntity user) { EmailXpackService emailXpackService = SpringContextUtil.getBean(EmailXpackService.class); + List files = null; try { XpackEmailTaskRequest taskForm = emailXpackService.taskForm(taskInstance.getTaskId()); if (ObjectUtils.isEmpty(taskForm) || CronUtils.taskExpire(taskForm.getEndTime())) { + removeInstance(taskInstance); return; } String panelId = emailTemplateDTO.getPanelId(); @@ -51,13 +54,21 @@ public class EmailTaskViewHandler extends EmailTaskHandler { .collect(Collectors.toList()); PermissionProxy proxy = new PermissionProxy(); proxy.setUserId(user.getUserId()); - List files = viewExportExcel.export(panelId, viewIdList, proxy); - emailService.sendWithFiles(emailTemplateDTO.getRecipients(), emailTemplateDTO.getTitle(), contentStr, - files); + files = viewExportExcel.export(panelId, viewIdList, proxy); + emailService.sendWithFiles(emailTemplateDTO.getRecipients(), emailTemplateDTO.getTitle(), contentStr, files); success(taskInstance); } catch (Exception e) { error(taskInstance, e); LogUtil.error(e.getMessage(), e); + } finally { + if (CollectionUtils.isNotEmpty(files)) { + for (int i = 0; i < files.size(); i++) { + File file = files.get(i); + if (file.exists()) { + file.delete(); + } + } + } } } } diff --git a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java index 0b654d416b..a5fa30b79d 100644 --- a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java +++ b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java @@ -1548,4 +1548,8 @@ public class ChartViewService { } return res; } + + public List viewOptions(String panelId) { + return extChartViewMapper.chartOptions(panelId); + } } diff --git a/backend/src/main/java/io/dataease/service/chart/ViewExportExcel.java b/backend/src/main/java/io/dataease/service/chart/ViewExportExcel.java index 15dcf608fc..3c8788bafe 100644 --- a/backend/src/main/java/io/dataease/service/chart/ViewExportExcel.java +++ b/backend/src/main/java/io/dataease/service/chart/ViewExportExcel.java @@ -46,10 +46,8 @@ public class ViewExportExcel { List> components = gson.fromJson(componentsJson, tokenType); ChartExtRequest chartExtRequest = buildViewRequest(componentsFilter(components, "custom", null, null)); List results = new ArrayList<>(); - List sheets = viewIds.stream().map(viewId -> viewFiles(viewId, chartExtRequest)) - .collect(Collectors.toList()); - - File excelFile = ExcelUtils.exportExcel(sheets); + List sheets = viewIds.stream().map(viewId -> viewFiles(viewId, chartExtRequest)).collect(Collectors.toList()); + File excelFile = ExcelUtils.exportExcel(sheets, panelDto.getName()); results.add(excelFile); return results; } @@ -57,8 +55,8 @@ public class ViewExportExcel { private List> componentsFilter(List> components, String type, String componentType, String serviceName) { return components.stream().filter(component -> { - String ctype = component.get("type").toString(); - String cComponentType = component.get("component").toString(); + String ctype = Optional.ofNullable(component.get("type")).orElse("").toString(); + String cComponentType = Optional.ofNullable(component.get("component")).orElse("").toString(); String cServiceName = Optional.ofNullable(component.get("serviceName")).orElse("").toString(); boolean typeMatch = true; diff --git a/backend/src/main/java/io/dataease/service/system/EmailService.java b/backend/src/main/java/io/dataease/service/system/EmailService.java index 845d2c94b8..ade9939eb8 100644 --- a/backend/src/main/java/io/dataease/service/system/EmailService.java +++ b/backend/src/main/java/io/dataease/service/system/EmailService.java @@ -84,16 +84,18 @@ public class EmailService { public void sendWithFiles(String to, String title, String content, List files) { if (StringUtils.isBlank(to)) return; + if (CollectionUtils.isEmpty(files)) { + send(to, title, content); + return; + } MailInfo mailInfo = proxy().mailInfo(); checkMailInfo(mailInfo); JavaMailSenderImpl driver = driver(mailInfo); MimeMessage mimeMessage = driver.createMimeMessage(); - String uuid = UUID.randomUUID().toString(); MimeBodyPart text = new MimeBodyPart(); try { - text.setContent(content + "
", - "text/html; charset=gb2312"); MimeMultipart multipart = new MimeMultipart(); + text.setText(content, "gb2312"); multipart.addBodyPart(text); multipart.setSubType("related"); for (int i = 0; i < files.size(); i++) { diff --git a/frontend/src/api/chart/chart.js b/frontend/src/api/chart/chart.js index 14149acae7..b70f9c4b1b 100644 --- a/frontend/src/api/chart/chart.js +++ b/frontend/src/api/chart/chart.js @@ -1,6 +1,4 @@ import request from '@/utils/request' -import store from '@/store' -import { queryPanelComponents } from '@/api/panel/panel' export function post(url, data, loading = false) { return request({ @@ -134,3 +132,10 @@ export function viewPropsSave(panelId, data) { data }) } + +export const viewOptions = panelId => { + return request({ + url: '/chart/view/viewOptions/' + panelId, + method: 'post' + }) +} diff --git a/frontend/src/components/DeViewSelect/index.vue b/frontend/src/components/DeViewSelect/index.vue index e71ae411a1..40160056f6 100644 --- a/frontend/src/components/DeViewSelect/index.vue +++ b/frontend/src/components/DeViewSelect/index.vue @@ -4,7 +4,6 @@ ref="select" v-model="innerValues" v-popover:popover - :title="labels" popper-class="view-select-option" style="width: 100%;" multiple @@ -14,10 +13,10 @@ @focus="_popoverShowFun" > @@ -43,6 +42,7 @@ import { on, off } from './dom' import Preview from '@/components/canvas/components/Editor/Preview' import { findOne } from '@/api/panel/panel' +import { viewOptions } from '@/api/chart/chart' import { panelDataPrepare } from '@/components/canvas/utils/utils' export default { name: 'DeViewSelect', @@ -60,7 +60,6 @@ export default { }, data() { return { - labels: [], visible: false, placement: 'bottom', transition: 'el-zoom-in-top', @@ -69,7 +68,8 @@ export default { innerValues: [], panelHeight: 450, showPosition: 'email-task', - viewLoaded: false + viewLoaded: false, + selectOptions: [] } }, computed: { @@ -92,25 +92,19 @@ export default { }, panelId(val, old) { if (val !== old) { + this.innerValues = [] this.loadView() } }, selectedViews: { handler(val) { if (!val || !JSON.stringify(val)) { - this.labels = [] this.innerValues = [] return } - const views = JSON.parse(JSON.stringify(val)) - const viewIds = [] - const names = [] - views.forEach(item => { - viewIds.push(item.viewId) - names.push(item.title) - }) + const viewIds = JSON.parse(JSON.stringify(val)) + this.innerValues = JSON.parse(JSON.stringify(viewIds)) - this.labels = JSON.parse(JSON.stringify(names)) }, deep: true } @@ -122,6 +116,7 @@ export default { }) }, beforeDestroy() { + this._selectClearFun() off(document, 'mouseup', this._popoverHideFun) }, created() { @@ -129,6 +124,8 @@ export default { }, methods: { loadView() { + this._selectClearFun() + this.innerValues = this.value this.viewLoaded = false this.panelId && findOne(this.panelId).then(response => { this.panelInfo = { @@ -143,9 +140,17 @@ export default { this.viewLoaded = true this.componentData = rsp.componentData this.canvasStyleData = rsp.componentStyle + this.loadOptions() }) }) }, + + loadOptions() { + this.panelId && viewOptions(this.panelId).then(res => { + this.selectOptions = res.data + this.init() + }) + }, _updateH() { this.$nextTick(() => { this.width = this.$refs.select.$el.getBoundingClientRect().width @@ -193,10 +198,13 @@ export default { }) }, _selectClearFun() { - const views = JSON.parse(JSON.stringify(this.selectedViews)) - views.forEach(item => { - this.$store.dispatch('task/delView', { 'panelId': this.panelId, 'viewId': item.viewId }) - }) + this.$store.dispatch('task/delPanelViews', this.panelId) + }, + init() { + if (this.value && this.value.length) { + const viewIds = JSON.parse(JSON.stringify(this.value)) + this.$store.dispatch('task/initPanelView', { 'panelId': this.panelId, 'viewIds': viewIds }) + } } } diff --git a/frontend/src/components/canvas/components/Editor/EditBarView.vue b/frontend/src/components/canvas/components/Editor/EditBarView.vue index 9422f4832f..6dd7546a8b 100644 --- a/frontend/src/components/canvas/components/Editor/EditBarView.vue +++ b/frontend/src/components/canvas/components/Editor/EditBarView.vue @@ -47,10 +47,6 @@ export default { panelId: { type: String, default: null - }, - chartTitle: { - type: String, - default: null } }, data() { @@ -85,7 +81,7 @@ export default { taskChecked() { const panelId = this.panelId - return !!this.panelViews && !!this.panelViews[panelId] && !!this.panelViews[panelId].some(view => view.viewId === this.viewId) + return !!this.panelViews && !!this.panelViews[panelId] && !!this.panelViews[panelId].some(viewId => viewId === this.viewId) } }, watch: { @@ -100,7 +96,6 @@ export default { } if (this.showPosition === 'email-task') { this.isTaskChecked = !!this.taskChecked - // this.emailTaskCheck(this.isTaskChecked) } }, beforeDestroy() { @@ -134,7 +129,7 @@ export default { }, emailTaskCheck(val) { if (val) { - this.$store.dispatch('task/addView', { 'panelId': this.panelId, 'viewId': this.viewId, 'title': this.chartTitle }) + this.$store.dispatch('task/addView', { 'panelId': this.panelId, 'viewId': this.viewId }) } else { this.$store.dispatch('task/delView', { 'panelId': this.panelId, 'viewId': this.viewId }) } diff --git a/frontend/src/store/modules/task.js b/frontend/src/store/modules/task.js index ec22d7276c..1ea6773dbb 100644 --- a/frontend/src/store/modules/task.js +++ b/frontend/src/store/modules/task.js @@ -5,16 +5,16 @@ const state = { const mutations = { - ADD_VIEW: (state, { panelId, viewId, title }) => { + ADD_VIEW: (state, { panelId, viewId }) => { if (!state.panelViews[panelId]) { Vue.set(state.panelViews, panelId, []) } - const views = state.panelViews[panelId] - if (views.some(item => item.viewId === viewId)) { + const viewIds = state.panelViews[panelId] + if (viewIds.some(item => item === viewId)) { return } - views.push({ viewId, title }) - state.panelViews[panelId] = views + viewIds.push(viewId) + state.panelViews[panelId] = viewIds }, DEL_VIEW: (state, { panelId, viewId }) => { @@ -23,20 +23,36 @@ const mutations = { let len = views.length while (len--) { const item = views[len] - if (viewId === item.viewId) { + if (viewId === item) { views.splice(len, 1) } } state.panelViews[panelId] = views + }, + + DEL_PANEL_VIEW: (state, panelId) => { + const views = state.panelViews[panelId] + if (!views || !views.length) return + Vue.set(state.panelViews, panelId, []) + }, + + INIT_PANEL_VIEWS: (state, { panelId, viewIds }) => { + state.panelViews[panelId] = viewIds || [] } } const actions = { + initPanelView({ commit }, data) { + commit('INIT_PANEL_VIEWS', data) + }, addView({ commit }, data) { commit('ADD_VIEW', data) }, delView({ commit }, data) { commit('DEL_VIEW', data) + }, + delPanelViews({ commit }, data) { + commit('DEL_PANEL_VIEW', data) } }