Merge pull request #2609 from dataease/pr@dev@feat_email_task_view

feat(系统管理): 定时报告增加发送视图数据
This commit is contained in:
fit2cloud-chenyw 2022-07-08 16:55:09 +08:00 committed by GitHub
commit a49b0ed107
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 352 additions and 8 deletions

View File

@ -0,0 +1,16 @@
package io.dataease.commons.model.excel;
import java.util.List;
import lombok.Data;
@Data
public class ExcelSheetModel {
private String sheetName;
private List<String> heads;
private List<List<String>> datas;
}

View File

@ -0,0 +1,59 @@
package io.dataease.commons.utils;
import java.io.File;
import io.dataease.commons.model.excel.ExcelSheetModel;
import java.util.List;
import org.apache.commons.collections.CollectionUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellStyle;
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 {
public static File exportExcel(List<ExcelSheetModel> sheets) throws Exception {
String fastUUID = IdUtil.fastUUID();
File result = new File("/opt/dataease/data/" + fastUUID + ".xls");
HSSFWorkbook wb = new HSSFWorkbook();
sheets.forEach(sheet -> {
List<List<String>> details = sheet.getDatas();
details.add(0, sheet.getHeads());
HSSFSheet curSheet = wb.createSheet(sheet.getSheetName());
CellStyle cellStyle = wb.createCellStyle();
Font font = wb.createFont();
font.setFontHeightInPoints((short) 12);
font.setBold(true);
cellStyle.setFont(font);
cellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
if (CollectionUtils.isNotEmpty(details)) {
for (int i = 0; i < details.size(); i++) {
HSSFRow row = curSheet.createRow(i);
List<String> rowData = details.get(i);
if (rowData != null) {
for (int j = 0; j < rowData.size(); j++) {
HSSFCell cell = row.createCell(j);
cell.setCellValue(rowData.get(j));
if (i == 0) {// 头部
cell.setCellStyle(cellStyle);
// 设置列的宽度
curSheet.setColumnWidth(j, 255 * 20);
}
}
}
}
}
});
wb.write(result);
return result;
}
}

View File

@ -28,7 +28,7 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
@Service("emailTaskHandler")
public class EmailTaskHandler extends TaskHandler implements Job {
private static final Integer RUNING = 0;
@ -50,8 +50,8 @@ public class EmailTaskHandler extends TaskHandler implements Job {
return jobDataMap;
}
public EmailTaskHandler proxy() {
return CommonBeanFactory.getBean(EmailTaskHandler.class);
public EmailTaskHandler proxy(String handlerName) {
return (EmailTaskHandler) CommonBeanFactory.getBean(handlerName);
}
@Override
@ -86,7 +86,7 @@ public class EmailTaskHandler extends TaskHandler implements Job {
XpackEmailTemplateDTO emailTemplate = (XpackEmailTemplateDTO) jobDataMap.get("emailTemplate");
SysUserEntity creator = (SysUserEntity) jobDataMap.get("creator");
LogUtil.info("start execute send panel report task...");
proxy().sendReport(taskInstance, emailTemplate, creator);
proxy(taskEntity.getTaskType()).sendReport(taskInstance, emailTemplate, creator);
}
@ -109,14 +109,14 @@ public class EmailTaskHandler extends TaskHandler implements Job {
return taskInstance;
}
private void success(GlobalTaskInstance taskInstance) {
protected void success(GlobalTaskInstance taskInstance) {
taskInstance.setStatus(SUCCESS);
taskInstance.setFinishTime(System.currentTimeMillis());
EmailXpackService emailXpackService = SpringContextUtil.getBean(EmailXpackService.class);
emailXpackService.saveInstance(taskInstance);
}
private void error(GlobalTaskInstance taskInstance, Throwable t) {
protected void error(GlobalTaskInstance taskInstance, Throwable t) {
taskInstance.setStatus(ERROR);
taskInstance.setInfo(t.getMessage());
EmailXpackService emailXpackService = SpringContextUtil.getBean(EmailXpackService.class);

View File

@ -0,0 +1,63 @@
package io.dataease.job.sechedule.strategy.impl;
import io.dataease.auth.entity.SysUserEntity;
import io.dataease.commons.utils.CronUtils;
import io.dataease.commons.utils.LogUtil;
import io.dataease.dto.PermissionProxy;
import io.dataease.plugins.common.entity.GlobalTaskInstance;
import io.dataease.plugins.config.SpringContextUtil;
import io.dataease.plugins.xpack.email.dto.request.XpackEmailTaskRequest;
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.lang3.ObjectUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@Service("emailTaskViewHandler")
public class EmailTaskViewHandler extends EmailTaskHandler {
@Resource
private ViewExportExcel viewExportExcel;
@Async("priorityExecutor")
public void sendReport(GlobalTaskInstance taskInstance, XpackEmailTemplateDTO emailTemplateDTO,
SysUserEntity user) {
EmailXpackService emailXpackService = SpringContextUtil.getBean(EmailXpackService.class);
try {
XpackEmailTaskRequest taskForm = emailXpackService.taskForm(taskInstance.getTaskId());
if (ObjectUtils.isEmpty(taskForm) || CronUtils.taskExpire(taskForm.getEndTime())) {
return;
}
String panelId = emailTemplateDTO.getPanelId();
// 下面继续执行发送邮件的
byte[] content = emailTemplateDTO.getContent();
EmailService emailService = SpringContextUtil.getBean(EmailService.class);
String contentStr = "";
if (ObjectUtils.isNotEmpty(content)) {
contentStr = new String(content, "UTF-8");
}
String viewIds = emailTemplateDTO.getPixel();
List<String> viewIdList = Arrays.asList(viewIds.split(",")).stream().map(s -> (s.trim()))
.collect(Collectors.toList());
PermissionProxy proxy = new PermissionProxy();
proxy.setUserId(user.getUserId());
List<File> 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);
}
}
}

View File

@ -0,0 +1,139 @@
package io.dataease.service.chart;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import com.google.gson.Gson;
import io.dataease.auth.annotation.DePermissionProxy;
import io.dataease.commons.exception.DEException;
import io.dataease.commons.model.excel.ExcelSheetModel;
import io.dataease.commons.utils.ExcelUtils;
import io.dataease.commons.utils.LogUtil;
import io.dataease.controller.request.chart.ChartExtRequest;
import io.dataease.dto.PermissionProxy;
import io.dataease.dto.chart.ChartViewDTO;
import io.dataease.dto.panel.PanelGroupDTO;
import io.dataease.plugins.common.dto.chart.ChartViewFieldDTO;
import io.dataease.plugins.common.request.chart.ChartExtFilterRequest;
import io.dataease.plugins.config.SpringContextUtil;
import io.dataease.service.panel.PanelGroupService;
import java.io.File;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import com.google.gson.reflect.TypeToken;
@Service
public class ViewExportExcel {
private final static Gson gson = new Gson();
private Type tokenType = new TypeToken<List<Map<String, Object>>>() {
}.getType();
@DePermissionProxy(paramIndex = 2)
public List<File> export(String panelId, List<String> viewIds, PermissionProxy proxy) throws Exception {
PanelGroupService panelGroupService = SpringContextUtil.getBean(PanelGroupService.class);
PanelGroupDTO panelDto = panelGroupService.findOne(panelId);
String componentsJson = panelDto.getPanelData();
List<Map<String, Object>> components = gson.fromJson(componentsJson, tokenType);
ChartExtRequest chartExtRequest = buildViewRequest(componentsFilter(components, "custom", null, null));
List<File> results = new ArrayList<>();
List<ExcelSheetModel> sheets = viewIds.stream().map(viewId -> viewFiles(viewId, chartExtRequest))
.collect(Collectors.toList());
File excelFile = ExcelUtils.exportExcel(sheets);
results.add(excelFile);
return results;
}
private List<Map<String, Object>> componentsFilter(List<Map<String, Object>> 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 cServiceName = Optional.ofNullable(component.get("serviceName")).orElse("").toString();
boolean typeMatch = true;
boolean componentTypeMatch = true;
boolean serviceNameMatch = true;
if (StringUtils.isNotBlank(type)) {
typeMatch = StringUtils.equals(type, ctype);
}
if (StringUtils.isNotBlank(componentType)) {
componentTypeMatch = StringUtils.equals(componentType, cComponentType);
}
if (StringUtils.isNotBlank(serviceName)) {
serviceNameMatch = StringUtils.equals(serviceName, cServiceName);
}
return typeMatch && componentTypeMatch && serviceNameMatch;
}).collect(Collectors.toList());
}
private ChartExtRequest buildViewRequest(List<Map<String, Object>> filters) {
ChartExtRequest chartExtRequest = new ChartExtRequest();
filters = Optional.ofNullable(filters).orElse(new ArrayList<>());
List<ChartExtFilterRequest> panelFilters = filters.stream().map(item -> {
ChartExtFilterRequest curentFilter = new ChartExtFilterRequest();
return curentFilter;
}).collect(Collectors.toList());
chartExtRequest.setQueryFrom("panel");
chartExtRequest.setFilter(panelFilters);
return chartExtRequest;
}
private ExcelSheetModel viewFiles(String viewId, ChartExtRequest request) {
ExcelSheetModel result = new ExcelSheetModel();
ChartViewDTO chartViewDTO = null;
try {
ChartViewService chartViewService = SpringContextUtil.getBean(ChartViewService.class);
chartViewDTO = chartViewService.getData(viewId, request);
} catch (Exception e) {
LogUtil.error(e.getMessage());
DEException.throwException(e);
}
String title = Optional.ofNullable(chartViewDTO.getTitle()).orElse(chartViewDTO.getName());
Map<String, Object> chart = chartViewDTO.getData();
Object objectFields = chart.get("fields");
List<ChartViewFieldDTO> fields = (List<ChartViewFieldDTO>) objectFields;
List<String> heads = new ArrayList<>();
List<String> headKeys = new ArrayList<>();
fields.forEach(field -> {
if (ObjectUtils.isNotEmpty(field.getName()) && ObjectUtils.isNotEmpty(field.getDataeaseName())) {
heads.add(field.getName());
headKeys.add(field.getDataeaseName());
}
});
Object objectTableRow = chart.get("tableRow");
List<Map<String, Object>> tableRow = (List<Map<String, Object>>) objectTableRow;
List<List<String>> details = tableRow.stream().map(row -> headKeys.stream().map(key -> {
Object val = row.get(key);
if (ObjectUtils.isEmpty(val))
return StringUtils.EMPTY;
return val.toString();
}).collect(Collectors.toList())).collect(Collectors.toList());
result.setHeads(heads);
result.setDatas(details);
result.setSheetName(title);
return result;
}
}

View File

@ -16,14 +16,19 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.annotation.Resource;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;
import javax.mail.util.ByteArrayDataSource;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Properties;
@ -58,6 +63,7 @@ public class EmailService {
if (StringUtils.isBlank(to))
return;
MailInfo mailInfo = proxy().mailInfo();
checkMailInfo(mailInfo);
JavaMailSenderImpl driver = driver(mailInfo);
MimeMessage mimeMessage = driver.createMimeMessage();
@ -75,10 +81,45 @@ public class EmailService {
}
}
public void sendWithFiles(String to, String title, String content, List<File> files) {
if (StringUtils.isBlank(to))
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 + "<br/><img style='width: 60%;' src='cid:" + uuid + "' />",
"text/html; charset=gb2312");
MimeMultipart multipart = new MimeMultipart();
multipart.addBodyPart(text);
multipart.setSubType("related");
for (int i = 0; i < files.size(); i++) {
File file = files.get(i);
MimeBodyPart attach = new MimeBodyPart();
FileDataSource fileDataSource = new FileDataSource(file);
attach.setDataHandler(new DataHandler(fileDataSource));
attach.setFileName(MimeUtility.encodeText(file.getName()));
multipart.addBodyPart(attach);
}
mimeMessage.setFrom(driver.getUsername());
mimeMessage.setSubject(title);
mimeMessage.setRecipients(Message.RecipientType.TO, to);
mimeMessage.setContent(multipart);
driver.send(mimeMessage);
} catch (Exception e) {
LogUtil.error(e.getMessage(), e);
DEException.throwException(e);
}
}
public void sendWithImage(String to, String title, String content, byte[] bytes) {
if (StringUtils.isBlank(to))
return;
MailInfo mailInfo = proxy().mailInfo();
checkMailInfo(mailInfo);
JavaMailSenderImpl driver = driver(mailInfo);
MimeMessage mimeMessage = driver.createMimeMessage();
@ -156,9 +197,18 @@ public class EmailService {
}
}
}
return mailInfo;
}
public void checkMailInfo(MailInfo info) {
Assert.notNull(info, Translator.get("I18N_EMAIL_CONFIG_ERROR"));
Assert.notNull(info.getHost(), Translator.get("I18N_EMAIL_HOST_ERROR"));
Assert.notNull(info.getPort(), Translator.get("I18N_EMAIL_PORT_ERROR"));
Assert.notNull(info.getAccount(), Translator.get("I18N_EMAIL_ACCOUNT_ERROR"));
}
public List<SystemParameter> getParamList(String type) {
SystemParameterExample example = new SystemParameterExample();
example.createCriteria().andParamKeyLike(type + "%");

View File

@ -188,4 +188,10 @@ I18N_NO_PERMISSION=You do not have permission to
I18N_PLEASE_CONCAT_ADMIN=Please contact the administrator for authorization
I18N_SQL_variable_limit=SQL variables can only be used in where conditions
I18N_SQL_variable_limit=SQL variables can only be used in where conditions
I18N_EMAIL_CONFIG_ERROR=Email config error
I18N_EMAIL_HOST_ERROR=Email host can not be empty
I18N_EMAIL_PORT_ERROR=Email port can not be empty
I18N_EMAIL_ACCOUNT_ERROR=Email account can not be empty

View File

@ -192,3 +192,8 @@ I18N_NO_PERMISSION=当前用户没有权限
I18N_PLEASE_CONCAT_ADMIN=请联系管理员开通
I18N_SQL_variable_limit=SQL 变量只能在 WHERE 条件中使用
I18N_EMAIL_CONFIG_ERROR=邮件配置错误
I18N_EMAIL_HOST_ERROR=邮件主机不能为空
I18N_EMAIL_PORT_ERROR=邮件端口不能为空
I18N_EMAIL_ACCOUNT_ERROR=邮件账号不能为空

View File

@ -186,4 +186,10 @@ I18N_NO_PERMISSION=當前用戶沒有權限
I18N_PLEASE_CONCAT_ADMIN=請聯系管理員開通
I18N_SQL_variable_limit=SQL變數只能在WHERE條件中使用
I18N_SQL_variable_limit=SQL變數只能在WHERE條件中使用
I18N_EMAIL_CONFIG_ERROR=郵件配置錯誤
I18N_EMAIL_HOST_ERROR=郵件主機不能為空
I18N_EMAIL_PORT_ERROR=郵件端口不能為空
I18N_EMAIL_ACCOUNT_ERROR=郵件賬號不能為空