forked from github/dataease
feat:自定义样式,email
This commit is contained in:
parent
0afbbf3174
commit
5b1ec9b151
@ -372,27 +372,27 @@
|
||||
<skipTests>true</skipTests>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-clean-plugin</artifactId>
|
||||
<configuration>
|
||||
<filesets>
|
||||
<fileset>
|
||||
<directory>src/main/resources/static</directory>
|
||||
<includes>
|
||||
<include>**</include>
|
||||
</includes>
|
||||
<followSymlinks>false</followSymlinks>
|
||||
</fileset>
|
||||
<fileset>
|
||||
<directory>src/main/resources/templates</directory>
|
||||
<includes>
|
||||
<include>**</include>
|
||||
</includes>
|
||||
<followSymlinks>false</followSymlinks>
|
||||
</fileset>
|
||||
</filesets>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- <plugin>-->
|
||||
<!-- <artifactId>maven-clean-plugin</artifactId>-->
|
||||
<!-- <configuration>-->
|
||||
<!-- <filesets>-->
|
||||
<!-- <fileset>-->
|
||||
<!-- <directory>src/main/resources/static</directory>-->
|
||||
<!-- <includes>-->
|
||||
<!-- <include>**</include>-->
|
||||
<!-- </includes>-->
|
||||
<!-- <followSymlinks>false</followSymlinks>-->
|
||||
<!-- </fileset>-->
|
||||
<!-- <fileset>-->
|
||||
<!-- <directory>src/main/resources/templates</directory>-->
|
||||
<!-- <includes>-->
|
||||
<!-- <include>**</include>-->
|
||||
<!-- </includes>-->
|
||||
<!-- <followSymlinks>false</followSymlinks>-->
|
||||
<!-- </fileset>-->
|
||||
<!-- </filesets>-->
|
||||
<!-- </configuration>-->
|
||||
<!-- </plugin>-->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
|
@ -2,6 +2,7 @@ package io.dataease.base.mapper.ext;
|
||||
|
||||
import io.dataease.base.domain.User;
|
||||
import io.dataease.controller.request.UserRequest;
|
||||
import io.dataease.notice.domain.UserDetail;
|
||||
import org.apache.ibatis.annotations.MapKey;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
@ -18,6 +19,8 @@ public interface ExtUserMapper {
|
||||
|
||||
List<User> searchUser(String condition);
|
||||
|
||||
List<UserDetail> queryTypeByIds(List<String> userIds);
|
||||
|
||||
@MapKey("id")
|
||||
Map<String, User> queryNameByIds(List<String> userIds);
|
||||
}
|
||||
|
@ -16,6 +16,18 @@
|
||||
<result column="phone" jdbcType="VARCHAR" property="phone"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="queryTypeByIds" parameterType="java.lang.String" resultType="io.dataease.notice.domain.UserDetail">
|
||||
SELECT
|
||||
email,phone
|
||||
from user
|
||||
WHERE id IN
|
||||
<foreach collection="list" item="id" index="index"
|
||||
open="(" close=")" separator=",">
|
||||
#{id}
|
||||
</foreach>
|
||||
|
||||
</select>
|
||||
|
||||
<select id="getUserList" resultMap="BaseResultMap">
|
||||
select u.id, u.name, u.email, u.phone, u.language, u.status, u.source,
|
||||
u.last_organization_id, u.last_workspace_id, u.language, u.create_time, u.update_time
|
||||
|
@ -31,6 +31,7 @@ public interface ParamConstants {
|
||||
MAIL("smtp"),
|
||||
BASE("base"),
|
||||
LDAP("ldap"),
|
||||
UI("ui"),
|
||||
REGISTRY("registry");
|
||||
|
||||
private String value;
|
||||
|
@ -0,0 +1,69 @@
|
||||
package io.dataease.controller;
|
||||
|
||||
import io.dataease.base.domain.SystemParameter;
|
||||
import io.dataease.commons.constants.ParamConstants;
|
||||
import io.dataease.commons.constants.RoleConstants;
|
||||
import io.dataease.dto.BaseSystemConfigDTO;
|
||||
import io.dataease.dto.SystemParameterDTO;
|
||||
import io.dataease.notice.domain.MailInfo;
|
||||
import io.dataease.service.system.SystemParameterService;
|
||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping(value = "/system")
|
||||
public class SystemParameterController {
|
||||
@Resource
|
||||
private SystemParameterService systemParameterService;
|
||||
|
||||
@PostMapping("/edit/email")
|
||||
@RequiresRoles(value = {RoleConstants.ADMIN})
|
||||
public void editMail(@RequestBody List<SystemParameter> systemParameter) {
|
||||
systemParameterService.editMail(systemParameter);
|
||||
}
|
||||
|
||||
@PostMapping("/testConnection")
|
||||
@RequiresRoles(value = {RoleConstants.ADMIN})
|
||||
public void testConnection(@RequestBody HashMap<String, String> hashMap) {
|
||||
systemParameterService.testConnection(hashMap);
|
||||
}
|
||||
|
||||
@GetMapping("/version")
|
||||
public String getVersion() {
|
||||
return systemParameterService.getVersion();
|
||||
}
|
||||
|
||||
@GetMapping("/mail/info")
|
||||
@RequiresRoles(value = {RoleConstants.ADMIN})
|
||||
public MailInfo mailInfo() {
|
||||
return systemParameterService.mailInfo(ParamConstants.Classify.MAIL.getValue());
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/base/info")
|
||||
@RequiresRoles(value = {RoleConstants.ADMIN})
|
||||
public List<SystemParameterDTO> getBaseInfo () {
|
||||
return systemParameterService.getSystemParameterInfo(ParamConstants.Classify.BASE.getValue());
|
||||
}
|
||||
|
||||
@GetMapping("/ui/info")
|
||||
@RequiresRoles(value = {RoleConstants.ADMIN})
|
||||
public List<SystemParameterDTO> getDisplayInfo () {
|
||||
return systemParameterService.getSystemParameterInfo(ParamConstants.Classify.UI.getValue());
|
||||
}
|
||||
|
||||
@PostMapping(value="/save/ui", consumes = {"multipart/form-data"})
|
||||
@RequiresRoles(value = {RoleConstants.ADMIN})
|
||||
public void saveUIInfo (@RequestPart("request") Map<String,List<SystemParameterDTO>> systemParameterMap,@RequestPart(value = "files") List<MultipartFile> bodyFiles) throws IOException {
|
||||
systemParameterService.saveUIInfo(systemParameterMap,bodyFiles);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package io.dataease.dto;
|
||||
|
||||
import io.dataease.base.domain.SystemParameter;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
public class SystemParameterDTO extends SystemParameter {
|
||||
@ApiModelProperty("文件")
|
||||
private MultipartFile file;
|
||||
@ApiModelProperty("文件名称")
|
||||
private String fileName;
|
||||
|
||||
public MultipartFile getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public void setFile(MultipartFile file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public void setFileName(String fileName) {
|
||||
this.fileName = fileName;
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package io.dataease.notice.controller;
|
||||
|
||||
import io.dataease.notice.domain.MessageDetail;
|
||||
import io.dataease.notice.service.NoticeService;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("notice")
|
||||
public class NoticeController {
|
||||
@Resource
|
||||
private NoticeService noticeService;
|
||||
|
||||
@PostMapping("save/message/task")
|
||||
public void saveMessage(@RequestBody MessageDetail messageDetail) {
|
||||
noticeService.saveMessageTask(messageDetail);
|
||||
}
|
||||
|
||||
@GetMapping("/search/message/type/{type}")
|
||||
public List<MessageDetail> searchMessage(@PathVariable String type) {
|
||||
return noticeService.searchMessageByType(type);
|
||||
}
|
||||
|
||||
@GetMapping("/search/message/{testId}")
|
||||
public List<MessageDetail> searchMessageSchedule(@PathVariable String testId) {
|
||||
return noticeService.searchMessageByTestId(testId);
|
||||
}
|
||||
|
||||
@GetMapping("/delete/message/{identification}")
|
||||
public int deleteMessage(@PathVariable String identification) {
|
||||
return noticeService.delMessage(identification);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,11 @@
|
||||
package io.dataease.notice.controller.request;
|
||||
|
||||
import io.dataease.notice.domain.MessageDetail;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class MessageRequest {
|
||||
private List<MessageDetail> messageDetail;
|
||||
}
|
18
backend/src/main/java/io/dataease/notice/domain/Mail.java
Normal file
18
backend/src/main/java/io/dataease/notice/domain/Mail.java
Normal file
@ -0,0 +1,18 @@
|
||||
package io.dataease.notice.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class Mail {
|
||||
// 发送给谁
|
||||
private String to;
|
||||
|
||||
// 发送主题
|
||||
private String subject;
|
||||
|
||||
// 发送内容
|
||||
private String content;
|
||||
|
||||
// 附件地址
|
||||
private String filePath;
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package io.dataease.notice.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class MailInfo {
|
||||
private String host;
|
||||
private String port;
|
||||
private String account;
|
||||
private String password;
|
||||
private String ssl;
|
||||
private String tls;
|
||||
private String recipient;
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package io.dataease.notice.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class MessageDetail {
|
||||
private List<String> userIds = new ArrayList<>();
|
||||
private String event;
|
||||
private String taskType;
|
||||
private String webhook;
|
||||
private String type;
|
||||
private String identification;
|
||||
private String organizationId;
|
||||
private Boolean isSet;
|
||||
private String testId;
|
||||
private Long createTime;
|
||||
private String template;
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package io.dataease.notice.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class MessageSettingDetail {
|
||||
private List<MessageDetail> jenkinsTask;
|
||||
private List<MessageDetail> testCasePlanTask;
|
||||
private List<MessageDetail> reviewTask;
|
||||
private List<MessageDetail> defectTask;
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package io.dataease.notice.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class UserDetail {
|
||||
private String email;
|
||||
private String phone;
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package io.dataease.notice.message;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class LinkMessage implements Message {
|
||||
|
||||
private String title;
|
||||
private String text;
|
||||
private String picUrl;
|
||||
private String messageUrl;
|
||||
|
||||
public String toJsonString() {
|
||||
Map<String, Object> items = new HashMap<String, Object>();
|
||||
items.put("msgtype", "link");
|
||||
|
||||
Map<String, String> linkContent = new HashMap<String, String>();
|
||||
if (StringUtils.isBlank(title)) {
|
||||
throw new IllegalArgumentException("title should not be blank");
|
||||
}
|
||||
linkContent.put("title", title);
|
||||
|
||||
if (StringUtils.isBlank(messageUrl)) {
|
||||
throw new IllegalArgumentException("messageUrl should not be blank");
|
||||
}
|
||||
linkContent.put("messageUrl", messageUrl);
|
||||
|
||||
if (StringUtils.isBlank(text)) {
|
||||
throw new IllegalArgumentException("text should not be blank");
|
||||
}
|
||||
linkContent.put("text", text);
|
||||
|
||||
if (StringUtils.isNotBlank(picUrl)) {
|
||||
linkContent.put("picUrl", picUrl);
|
||||
}
|
||||
|
||||
items.put("link", linkContent);
|
||||
|
||||
return JSON.toJSONString(items);
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package io.dataease.notice.message;
|
||||
|
||||
public interface Message {
|
||||
String toJsonString();
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package io.dataease.notice.message;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class TextMessage implements Message {
|
||||
private String text;
|
||||
private List<String> mentionedMobileList;
|
||||
private boolean isAtAll;
|
||||
|
||||
public TextMessage(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public boolean isAtAll() {
|
||||
return isAtAll;
|
||||
}
|
||||
|
||||
public void setIsAtAll(boolean isAtAll) {
|
||||
this.isAtAll = isAtAll;
|
||||
}
|
||||
|
||||
public List<String> getMentionedMobileList() {
|
||||
return mentionedMobileList;
|
||||
}
|
||||
|
||||
public void setMentionedMobileList(List<String> mentionedMobileList) {
|
||||
this.mentionedMobileList = mentionedMobileList;
|
||||
}
|
||||
|
||||
public String toJsonString() {
|
||||
Map<String, Object> items = new HashMap<String, Object>();
|
||||
items.put("msgtype", "text");
|
||||
|
||||
Map<String, Object> textContent = new HashMap<String, Object>();
|
||||
if (StringUtils.isBlank(text)) {
|
||||
throw new IllegalArgumentException("text should not be blank");
|
||||
}
|
||||
textContent.put("content", text);
|
||||
if (isAtAll) {
|
||||
if (mentionedMobileList == null) mentionedMobileList = new ArrayList<String>();
|
||||
mentionedMobileList.add("@all");
|
||||
}
|
||||
if (mentionedMobileList != null && !mentionedMobileList.isEmpty()) {
|
||||
textContent.put("mentioned_mobile_list", mentionedMobileList);
|
||||
}
|
||||
items.put("text", textContent);
|
||||
return JSON.toJSONString(items);
|
||||
}
|
||||
}
|
@ -0,0 +1,150 @@
|
||||
package io.dataease.notice.sender;
|
||||
|
||||
import io.dataease.commons.constants.NoticeConstants;
|
||||
import io.dataease.commons.utils.LogUtil;
|
||||
import io.dataease.notice.domain.MessageDetail;
|
||||
import io.dataease.notice.domain.UserDetail;
|
||||
import io.dataease.service.UserService;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.RegExUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public abstract class AbstractNoticeSender implements NoticeSender {
|
||||
@Resource
|
||||
private UserService userService;
|
||||
|
||||
protected String getContext(MessageDetail messageDetail, NoticeModel noticeModel) {
|
||||
// 如果配置了模版就直接使用模版
|
||||
if (StringUtils.isNotBlank(messageDetail.getTemplate())) {
|
||||
return getContent(messageDetail.getTemplate(), noticeModel.getParamMap());
|
||||
}
|
||||
// 处理 userIds 中包含的特殊值
|
||||
List<String> realUserIds = getRealUserIds(messageDetail.getUserIds(), noticeModel.getRelatedUsers(), messageDetail.getEvent());
|
||||
messageDetail.setUserIds(realUserIds);
|
||||
|
||||
// 处理 WeCom Ding context
|
||||
String context = "";
|
||||
switch (messageDetail.getEvent()) {
|
||||
case NoticeConstants.Event.CREATE:
|
||||
case NoticeConstants.Event.UPDATE:
|
||||
case NoticeConstants.Event.DELETE:
|
||||
case NoticeConstants.Event.COMMENT:
|
||||
context = noticeModel.getContext();
|
||||
break;
|
||||
case NoticeConstants.Event.EXECUTE_FAILED:
|
||||
context = noticeModel.getFailedContext();
|
||||
break;
|
||||
case NoticeConstants.Event.EXECUTE_SUCCESSFUL:
|
||||
context = noticeModel.getSuccessContext();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
protected String getHtmlContext(MessageDetail messageDetail, NoticeModel noticeModel) {
|
||||
// 如果配置了模版就直接使用模版
|
||||
if (StringUtils.isNotBlank(messageDetail.getTemplate())) {
|
||||
return getContent(messageDetail.getTemplate(), noticeModel.getParamMap());
|
||||
}
|
||||
// 处理 userIds 中包含的特殊值
|
||||
List<String> realUserIds = getRealUserIds(messageDetail.getUserIds(), noticeModel.getRelatedUsers(), messageDetail.getEvent());
|
||||
messageDetail.setUserIds(realUserIds);
|
||||
|
||||
// 处理 mail context
|
||||
String context = "";
|
||||
try {
|
||||
switch (messageDetail.getEvent()) {
|
||||
case NoticeConstants.Event.CREATE:
|
||||
case NoticeConstants.Event.UPDATE:
|
||||
case NoticeConstants.Event.DELETE:
|
||||
case NoticeConstants.Event.COMMENT:
|
||||
URL resource = this.getClass().getResource("/mail/" + noticeModel.getMailTemplate() + ".html");
|
||||
context = IOUtils.toString(resource, StandardCharsets.UTF_8);
|
||||
break;
|
||||
case NoticeConstants.Event.EXECUTE_FAILED:
|
||||
URL resource1 = this.getClass().getResource("/mail/" + noticeModel.getFailedMailTemplate() + ".html");
|
||||
context = IOUtils.toString(resource1, StandardCharsets.UTF_8);
|
||||
break;
|
||||
case NoticeConstants.Event.EXECUTE_SUCCESSFUL:
|
||||
URL resource2 = this.getClass().getResource("/mail/" + noticeModel.getSuccessMailTemplate() + ".html");
|
||||
context = IOUtils.toString(resource2, StandardCharsets.UTF_8);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LogUtil.error(e);
|
||||
}
|
||||
return getContent(context, noticeModel.getParamMap());
|
||||
}
|
||||
|
||||
protected String getContent(String template, Map<String, Object> context) {
|
||||
if (MapUtils.isNotEmpty(context)) {
|
||||
for (String k : context.keySet()) {
|
||||
if (context.get(k) != null) {
|
||||
template = RegExUtils.replaceAll(template, "\\$\\{" + k + "}", context.get(k).toString());
|
||||
} else {
|
||||
template = RegExUtils.replaceAll(template, "\\$\\{" + k + "}", "未设置");
|
||||
}
|
||||
}
|
||||
}
|
||||
return template;
|
||||
}
|
||||
|
||||
protected List<String> getUserPhones(List<String> userIds) {
|
||||
List<UserDetail> list = userService.queryTypeByIds(userIds);
|
||||
List<String> phoneList = new ArrayList<>();
|
||||
list.forEach(u -> phoneList.add(u.getPhone()));
|
||||
LogUtil.info("收件人地址: " + phoneList);
|
||||
return phoneList.stream().distinct().collect(Collectors.toList());
|
||||
}
|
||||
|
||||
protected List<String> getUserEmails(List<String> userIds) {
|
||||
List<UserDetail> list = userService.queryTypeByIds(userIds);
|
||||
List<String> phoneList = new ArrayList<>();
|
||||
list.forEach(u -> phoneList.add(u.getEmail()));
|
||||
LogUtil.info("收件人地址: " + phoneList);
|
||||
return phoneList.stream().distinct().collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<String> getRealUserIds(List<String> userIds, List<String> relatedUsers, String event) {
|
||||
List<String> toUserIds = new ArrayList<>();
|
||||
for (String userId : userIds) {
|
||||
switch (userId) {
|
||||
case NoticeConstants.RelatedUser.EXECUTOR:
|
||||
if (StringUtils.equals(NoticeConstants.Event.CREATE, event)) {
|
||||
toUserIds.addAll(relatedUsers);
|
||||
}
|
||||
break;
|
||||
case NoticeConstants.RelatedUser.FOUNDER:
|
||||
if (StringUtils.equals(NoticeConstants.Event.UPDATE, event)
|
||||
|| StringUtils.equals(NoticeConstants.Event.DELETE, event)) {
|
||||
toUserIds.addAll(relatedUsers);
|
||||
}
|
||||
break;
|
||||
case NoticeConstants.RelatedUser.MAINTAINER:
|
||||
if (StringUtils.equals(NoticeConstants.Event.COMMENT, event)) {
|
||||
toUserIds.addAll(relatedUsers);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
toUserIds.add(userId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return toUserIds;
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package io.dataease.notice.sender;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
public class NoticeModel {
|
||||
/**
|
||||
* 保存 测试id
|
||||
*/
|
||||
private String testId;
|
||||
/**
|
||||
* 保存状态
|
||||
*/
|
||||
private String status;
|
||||
/**
|
||||
* Event
|
||||
*/
|
||||
private String event;
|
||||
/**
|
||||
* 消息主题
|
||||
*/
|
||||
private String subject;
|
||||
/**
|
||||
* 消息内容
|
||||
*/
|
||||
private String context;
|
||||
private String successContext;
|
||||
private String failedContext;
|
||||
|
||||
/**
|
||||
* html 消息模版
|
||||
*/
|
||||
private String mailTemplate;
|
||||
private String failedMailTemplate;
|
||||
private String successMailTemplate;
|
||||
|
||||
/**
|
||||
* 保存特殊的用户
|
||||
*/
|
||||
private List<String> relatedUsers;
|
||||
|
||||
/**
|
||||
* 模版里的参数信息
|
||||
*/
|
||||
private Map<String, Object> paramMap;
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package io.dataease.notice.sender;
|
||||
|
||||
import io.dataease.notice.domain.MessageDetail;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
|
||||
public interface NoticeSender {
|
||||
@Async
|
||||
void send(MessageDetail messageDetail, NoticeModel noticeModel);
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package io.dataease.notice.sender.impl;
|
||||
|
||||
import com.dingtalk.api.DefaultDingTalkClient;
|
||||
import com.dingtalk.api.DingTalkClient;
|
||||
import com.dingtalk.api.request.OapiRobotSendRequest;
|
||||
import com.taobao.api.ApiException;
|
||||
import io.dataease.commons.utils.LogUtil;
|
||||
import io.dataease.notice.domain.MessageDetail;
|
||||
import io.dataease.notice.sender.AbstractNoticeSender;
|
||||
import io.dataease.notice.sender.NoticeModel;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class DingNoticeSender extends AbstractNoticeSender {
|
||||
|
||||
public void sendNailRobot(MessageDetail messageDetail, String context) {
|
||||
List<String> userIds = messageDetail.getUserIds();
|
||||
if (CollectionUtils.isEmpty(userIds)) {
|
||||
return;
|
||||
}
|
||||
DingTalkClient client = new DefaultDingTalkClient(messageDetail.getWebhook());
|
||||
OapiRobotSendRequest request = new OapiRobotSendRequest();
|
||||
request.setMsgtype("text");
|
||||
OapiRobotSendRequest.Text text = new OapiRobotSendRequest.Text();
|
||||
text.setContent(context);
|
||||
request.setText(text);
|
||||
OapiRobotSendRequest.At at = new OapiRobotSendRequest.At();
|
||||
List<String> phoneList = super.getUserPhones(userIds);
|
||||
LogUtil.info("收件人地址: " + phoneList);
|
||||
at.setAtMobiles(phoneList);
|
||||
request.setAt(at);
|
||||
try {
|
||||
client.execute(request);
|
||||
} catch (ApiException e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(MessageDetail messageDetail, NoticeModel noticeModel) {
|
||||
String context = super.getContext(messageDetail, noticeModel);
|
||||
sendNailRobot(messageDetail, context);
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package io.dataease.notice.sender.impl;
|
||||
|
||||
|
||||
import io.dataease.commons.utils.LogUtil;
|
||||
import io.dataease.notice.domain.MessageDetail;
|
||||
import io.dataease.notice.sender.AbstractNoticeSender;
|
||||
import io.dataease.notice.sender.NoticeModel;
|
||||
import io.dataease.notice.service.MailService;
|
||||
import org.springframework.mail.javamail.JavaMailSenderImpl;
|
||||
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class MailNoticeSender extends AbstractNoticeSender {
|
||||
@Resource
|
||||
private MailService mailService;
|
||||
|
||||
private void sendMail(MessageDetail messageDetail, String context, NoticeModel noticeModel) throws MessagingException {
|
||||
LogUtil.info("发送邮件开始 ");
|
||||
JavaMailSenderImpl javaMailSender = mailService.getMailSender();
|
||||
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
|
||||
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
|
||||
helper.setFrom(javaMailSender.getUsername());
|
||||
LogUtil.info("发件人地址"+javaMailSender.getUsername());
|
||||
LogUtil.info("helper"+helper);
|
||||
helper.setSubject("MeterSphere " + noticeModel.getSubject());
|
||||
List<String> emails = super.getUserEmails(messageDetail.getUserIds());
|
||||
String[] users = emails.toArray(new String[0]);
|
||||
LogUtil.info("收件人地址: " + emails);
|
||||
helper.setText(context, true);
|
||||
helper.setTo(users);
|
||||
javaMailSender.send(mimeMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(MessageDetail messageDetail, NoticeModel noticeModel) {
|
||||
String context = super.getHtmlContext(messageDetail, noticeModel);
|
||||
try {
|
||||
sendMail(messageDetail, context, noticeModel);
|
||||
LogUtil.info("发送邮件结束");
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package io.dataease.notice.sender.impl;
|
||||
|
||||
import io.dataease.notice.sender.AbstractNoticeSender;
|
||||
import io.dataease.commons.utils.LogUtil;
|
||||
import io.dataease.notice.domain.MessageDetail;
|
||||
import io.dataease.notice.message.TextMessage;
|
||||
import io.dataease.notice.sender.NoticeModel;
|
||||
import io.dataease.notice.util.WxChatbotClient;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class WeComNoticeSender extends AbstractNoticeSender {
|
||||
|
||||
|
||||
public void sendWechatRobot(MessageDetail messageDetail, String context) {
|
||||
List<String> userIds = messageDetail.getUserIds();
|
||||
if (CollectionUtils.isEmpty(userIds)) {
|
||||
return;
|
||||
}
|
||||
TextMessage message = new TextMessage(context);
|
||||
List<String> phoneLists = super.getUserPhones(userIds);
|
||||
message.setMentionedMobileList(phoneLists);
|
||||
try {
|
||||
WxChatbotClient.send(messageDetail.getWebhook(), message);
|
||||
} catch (IOException e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(MessageDetail messageDetail, NoticeModel noticeModel) {
|
||||
String context = super.getContext(messageDetail, noticeModel);
|
||||
sendWechatRobot(messageDetail, context);
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
package io.dataease.notice.service;
|
||||
|
||||
import io.dataease.base.domain.SystemParameter;
|
||||
import io.dataease.commons.constants.ParamConstants;
|
||||
import io.dataease.commons.utils.EncryptUtils;
|
||||
import io.dataease.service.system.SystemParameterService;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.springframework.mail.javamail.JavaMailSenderImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
@Service
|
||||
@Transactional(propagation = Propagation.NOT_SUPPORTED)
|
||||
public class MailService {
|
||||
@Resource
|
||||
private SystemParameterService systemParameterService;
|
||||
|
||||
public JavaMailSenderImpl getMailSender() {
|
||||
Properties props = new Properties();
|
||||
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
|
||||
List<SystemParameter> paramList = systemParameterService.getParamList(ParamConstants.Classify.MAIL.getValue());
|
||||
javaMailSender.setDefaultEncoding("UTF-8");
|
||||
javaMailSender.setProtocol("smtp");
|
||||
props.put("mail.smtp.auth", "true");
|
||||
|
||||
for (SystemParameter p : paramList) {
|
||||
switch (p.getParamKey()) {
|
||||
case "smtp.host":
|
||||
javaMailSender.setHost(p.getParamValue());
|
||||
break;
|
||||
case "smtp.port":
|
||||
javaMailSender.setPort(Integer.parseInt(p.getParamValue()));
|
||||
break;
|
||||
case "smtp.account":
|
||||
javaMailSender.setUsername(p.getParamValue());
|
||||
break;
|
||||
case "smtp.password":
|
||||
javaMailSender.setPassword(EncryptUtils.aesDecrypt(p.getParamValue()).toString());
|
||||
break;
|
||||
case "smtp.ssl":
|
||||
if (BooleanUtils.toBoolean(p.getParamValue())) {
|
||||
javaMailSender.setProtocol("smtps");
|
||||
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
|
||||
}
|
||||
break;
|
||||
case "smtp.tls":
|
||||
String result = BooleanUtils.toString(BooleanUtils.toBoolean(p.getParamValue()), "true", "false");
|
||||
props.put("mail.smtp.starttls.enable", result);
|
||||
props.put("mail.smtp.starttls.required", result);
|
||||
break;
|
||||
/* case "smtp.anon":
|
||||
boolean isAnon = BooleanUtils.toBoolean(p.getParamValue());
|
||||
if (isAnon) {
|
||||
props.put("mail.smtp.auth", "false");
|
||||
javaMailSender.setUsername(null);
|
||||
javaMailSender.setPassword(null);
|
||||
}
|
||||
break;*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
props.put("mail.smtp.timeout", "30000");
|
||||
props.put("mail.smtp.connectiontimeout", "5000");
|
||||
javaMailSender.setJavaMailProperties(props);
|
||||
return javaMailSender;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,65 @@
|
||||
package io.dataease.notice.service;
|
||||
|
||||
import com.alibaba.nacos.client.utils.StringUtils;
|
||||
import io.dataease.commons.constants.NoticeConstants;
|
||||
import io.dataease.notice.domain.MessageDetail;
|
||||
import io.dataease.notice.sender.NoticeModel;
|
||||
import io.dataease.notice.sender.NoticeSender;
|
||||
import io.dataease.notice.sender.impl.DingNoticeSender;
|
||||
import io.dataease.notice.sender.impl.MailNoticeSender;
|
||||
import io.dataease.notice.sender.impl.WeComNoticeSender;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class NoticeSendService {
|
||||
@Resource
|
||||
private MailNoticeSender mailNoticeSender;
|
||||
@Resource
|
||||
private WeComNoticeSender weComNoticeSender;
|
||||
@Resource
|
||||
private DingNoticeSender dingNoticeSender;
|
||||
@Resource
|
||||
private NoticeService noticeService;
|
||||
|
||||
private NoticeSender getNoticeSender(MessageDetail messageDetail) {
|
||||
NoticeSender noticeSender = null;
|
||||
switch (messageDetail.getType()) {
|
||||
case NoticeConstants.Type.EMAIL:
|
||||
noticeSender = mailNoticeSender;
|
||||
break;
|
||||
case NoticeConstants.Type.WECHAT_ROBOT:
|
||||
noticeSender = weComNoticeSender;
|
||||
break;
|
||||
case NoticeConstants.Type.NAIL_ROBOT:
|
||||
noticeSender = dingNoticeSender;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return noticeSender;
|
||||
}
|
||||
|
||||
public void send(String taskType, NoticeModel noticeModel) {
|
||||
List<MessageDetail> messageDetails;
|
||||
switch (taskType) {
|
||||
case NoticeConstants.Mode.API:
|
||||
messageDetails = noticeService.searchMessageByType(NoticeConstants.TaskType.JENKINS_TASK);
|
||||
break;
|
||||
case NoticeConstants.Mode.SCHEDULE:
|
||||
messageDetails = noticeService.searchMessageByTestId(noticeModel.getTestId());
|
||||
break;
|
||||
default:
|
||||
messageDetails = noticeService.searchMessageByType(taskType);
|
||||
break;
|
||||
}
|
||||
messageDetails.forEach(messageDetail -> {
|
||||
if (StringUtils.equals(messageDetail.getEvent(), noticeModel.getEvent())) {
|
||||
this.getNoticeSender(messageDetail).send(messageDetail, noticeModel);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,160 @@
|
||||
package io.dataease.notice.service;
|
||||
|
||||
import io.dataease.base.domain.MessageTask;
|
||||
import io.dataease.base.domain.MessageTaskExample;
|
||||
import io.dataease.base.mapper.MessageTaskMapper;
|
||||
import io.dataease.commons.exception.DEException;
|
||||
import io.dataease.commons.user.SessionUser;
|
||||
import io.dataease.commons.utils.SessionUtils;
|
||||
import io.dataease.i18n.Translator;
|
||||
import io.dataease.notice.domain.MessageDetail;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class NoticeService {
|
||||
@Resource
|
||||
private MessageTaskMapper messageTaskMapper;
|
||||
|
||||
public void saveMessageTask(MessageDetail messageDetail) {
|
||||
MessageTaskExample example = new MessageTaskExample();
|
||||
example.createCriteria().andIdentificationEqualTo(messageDetail.getIdentification());
|
||||
List<MessageTask> messageTaskLists = messageTaskMapper.selectByExample(example);
|
||||
if (messageTaskLists.size() > 0) {
|
||||
delMessage(messageDetail.getIdentification());
|
||||
}
|
||||
SessionUser user = SessionUtils.getUser();
|
||||
String orgId = user.getLastOrganizationId();
|
||||
long time = System.currentTimeMillis();
|
||||
String identification = messageDetail.getIdentification();
|
||||
if (StringUtils.isBlank(identification)) {
|
||||
identification = UUID.randomUUID().toString();
|
||||
}
|
||||
for (String userId : messageDetail.getUserIds()) {
|
||||
checkUserIdExist(userId, messageDetail, orgId);
|
||||
MessageTask messageTask = new MessageTask();
|
||||
messageTask.setId(UUID.randomUUID().toString());
|
||||
messageTask.setEvent(messageDetail.getEvent());
|
||||
messageTask.setTaskType(messageDetail.getTaskType());
|
||||
messageTask.setUserId(userId);
|
||||
messageTask.setType(messageDetail.getType());
|
||||
messageTask.setWebhook(messageDetail.getWebhook());
|
||||
messageTask.setIdentification(identification);
|
||||
messageTask.setIsSet(false);
|
||||
messageTask.setOrganizationId(orgId);
|
||||
messageTask.setTestId(messageDetail.getTestId());
|
||||
messageTask.setCreateTime(time);
|
||||
setTemplate(messageDetail, messageTask);
|
||||
messageTaskMapper.insert(messageTask);
|
||||
}
|
||||
}
|
||||
|
||||
private void setTemplate(MessageDetail messageDetail, MessageTask messageTask) {
|
||||
if (StringUtils.isNotBlank(messageDetail.getTemplate())) {
|
||||
messageTask.setTemplate(messageDetail.getTemplate());
|
||||
}
|
||||
}
|
||||
|
||||
private void checkUserIdExist(String userId, MessageDetail list, String orgId) {
|
||||
MessageTaskExample example = new MessageTaskExample();
|
||||
if (StringUtils.isBlank(list.getTestId())) {
|
||||
example.createCriteria()
|
||||
.andUserIdEqualTo(userId)
|
||||
.andEventEqualTo(list.getEvent())
|
||||
.andTypeEqualTo(list.getType())
|
||||
.andTaskTypeEqualTo(list.getTaskType())
|
||||
.andWebhookEqualTo(list.getWebhook())
|
||||
.andOrganizationIdEqualTo(orgId);
|
||||
} else {
|
||||
example.createCriteria()
|
||||
.andUserIdEqualTo(userId)
|
||||
.andEventEqualTo(list.getEvent())
|
||||
.andTypeEqualTo(list.getType())
|
||||
.andTaskTypeEqualTo(list.getTaskType())
|
||||
.andWebhookEqualTo(list.getWebhook())
|
||||
.andTestIdEqualTo(list.getTestId())
|
||||
.andOrganizationIdEqualTo(orgId);
|
||||
}
|
||||
if (messageTaskMapper.countByExample(example) > 0) {
|
||||
DEException.throwException(Translator.get("message_task_already_exists"));
|
||||
}
|
||||
}
|
||||
|
||||
public List<MessageDetail> searchMessageByTestId(String testId) {
|
||||
MessageTaskExample example = new MessageTaskExample();
|
||||
example.createCriteria().andTestIdEqualTo(testId);
|
||||
List<MessageTask> messageTaskLists = messageTaskMapper.selectByExampleWithBLOBs(example);
|
||||
List<MessageDetail> scheduleMessageTask = new ArrayList<>();
|
||||
Map<String, List<MessageTask>> MessageTaskMap = messageTaskLists.stream().collect(Collectors.groupingBy(MessageTask::getIdentification));
|
||||
MessageTaskMap.forEach((k, v) -> {
|
||||
MessageDetail messageDetail = getMessageDetail(v);
|
||||
scheduleMessageTask.add(messageDetail);
|
||||
});
|
||||
scheduleMessageTask.sort(Comparator.comparing(MessageDetail::getCreateTime, Comparator.nullsLast(Long::compareTo)).reversed());
|
||||
return scheduleMessageTask;
|
||||
}
|
||||
|
||||
public List<MessageDetail> searchMessageByType(String type) {
|
||||
SessionUser user = SessionUtils.getUser();
|
||||
String orgId = user.getLastOrganizationId();
|
||||
List<MessageDetail> messageDetails = new ArrayList<>();
|
||||
|
||||
MessageTaskExample example = new MessageTaskExample();
|
||||
example.createCriteria()
|
||||
.andTaskTypeEqualTo(type)
|
||||
.andOrganizationIdEqualTo(orgId);
|
||||
List<MessageTask> messageTaskLists = messageTaskMapper.selectByExampleWithBLOBs(example);
|
||||
|
||||
Map<String, List<MessageTask>> messageTaskMap = messageTaskLists.stream()
|
||||
.collect(Collectors.groupingBy(NoticeService::fetchGroupKey));
|
||||
messageTaskMap.forEach((k, v) -> {
|
||||
MessageDetail messageDetail = getMessageDetail(v);
|
||||
messageDetails.add(messageDetail);
|
||||
});
|
||||
|
||||
return messageDetails.stream()
|
||||
.sorted(Comparator.comparing(MessageDetail::getCreateTime, Comparator.nullsLast(Long::compareTo)).reversed())
|
||||
.collect(Collectors.toList())
|
||||
.stream()
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private MessageDetail getMessageDetail(List<MessageTask> messageTasks) {
|
||||
Set<String> userIds = new HashSet<>();
|
||||
|
||||
MessageDetail messageDetail = new MessageDetail();
|
||||
for (MessageTask m : messageTasks) {
|
||||
userIds.add(m.getUserId());
|
||||
messageDetail.setEvent(m.getEvent());
|
||||
messageDetail.setTaskType(m.getTaskType());
|
||||
messageDetail.setWebhook(m.getWebhook());
|
||||
messageDetail.setIdentification(m.getIdentification());
|
||||
messageDetail.setType(m.getType());
|
||||
messageDetail.setIsSet(m.getIsSet());
|
||||
messageDetail.setCreateTime(m.getCreateTime());
|
||||
messageDetail.setTemplate(m.getTemplate());
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(userIds)) {
|
||||
messageDetail.setUserIds(new ArrayList<>(userIds));
|
||||
}
|
||||
return messageDetail;
|
||||
}
|
||||
|
||||
private static String fetchGroupKey(MessageTask messageTask) {
|
||||
return messageTask.getTaskType() + "#" + messageTask.getIdentification();
|
||||
}
|
||||
|
||||
public int delMessage(String identification) {
|
||||
MessageTaskExample example = new MessageTaskExample();
|
||||
example.createCriteria().andIdentificationEqualTo(identification);
|
||||
return messageTaskMapper.deleteByExample(example);
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package io.dataease.notice.util;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class SendResult {
|
||||
private boolean isSuccess;
|
||||
private Integer errorCode;
|
||||
private String errorMsg;
|
||||
|
||||
public boolean isSuccess() {
|
||||
return isSuccess;
|
||||
}
|
||||
|
||||
public void setIsSuccess(boolean isSuccess) {
|
||||
this.isSuccess = isSuccess;
|
||||
}
|
||||
|
||||
public Integer getErrorCode() {
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
public void setErrorCode(Integer errorCode) {
|
||||
this.errorCode = errorCode;
|
||||
}
|
||||
|
||||
public String getErrorMsg() {
|
||||
return errorMsg;
|
||||
}
|
||||
|
||||
public void setErrorMsg(String errorMsg) {
|
||||
this.errorMsg = errorMsg;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
Map<String, Object> items = new HashMap<String, Object>();
|
||||
items.put("errorCode", errorCode);
|
||||
items.put("errorMsg", errorMsg);
|
||||
items.put("isSuccess", isSuccess);
|
||||
return JSON.toJSONString(items);
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package io.dataease.notice.util;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.dataease.notice.message.Message;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class WxChatbotClient {
|
||||
|
||||
static HttpClient httpclient = HttpClients.createDefault();
|
||||
|
||||
public static SendResult send(String webhook, Message message) throws IOException {
|
||||
|
||||
if (StringUtils.isBlank(webhook)) {
|
||||
return new SendResult();
|
||||
}
|
||||
HttpPost httppost = new HttpPost(webhook);
|
||||
httppost.addHeader("Content-Type", "application/json; charset=utf-8");
|
||||
StringEntity se = new StringEntity(message.toJsonString(), "utf-8");
|
||||
httppost.setEntity(se);
|
||||
|
||||
SendResult sendResult = new SendResult();
|
||||
HttpResponse response = httpclient.execute(httppost);
|
||||
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
|
||||
String result = EntityUtils.toString(response.getEntity());
|
||||
JSONObject obj = JSONObject.parseObject(result);
|
||||
|
||||
Integer errcode = obj.getInteger("errcode");
|
||||
sendResult.setErrorCode(errcode);
|
||||
sendResult.setErrorMsg(obj.getString("errmsg"));
|
||||
sendResult.setIsSuccess(errcode.equals(0));
|
||||
}
|
||||
|
||||
return sendResult;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -48,15 +48,19 @@ public class BaseDisplayService {
|
||||
if (bytes == null) {
|
||||
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(getClass().getClassLoader());
|
||||
switch (imageName) {
|
||||
case "favicon":
|
||||
bytes = IOUtils.toByteArray(resolver.getResources("/static/img/favicon.ico")[0].getInputStream());
|
||||
contentType = MediaType.valueOf("image/vnd.microsoft.icon");
|
||||
break;
|
||||
case "logo":
|
||||
bytes = IOUtils.toByteArray(resolver.getResources("/static/img/logo-light-MeterSphere.*.svg")[0].getInputStream());
|
||||
bytes = IOUtils.toByteArray(resolver.getResources("/static/img/logo-light-MeterSphere*.svg")[0].getInputStream());
|
||||
contentType = MediaType.valueOf("image/svg+xml");
|
||||
break;
|
||||
case "loginImage":
|
||||
bytes = IOUtils.toByteArray(resolver.getResources("/static/img/info.*.png")[0].getInputStream());
|
||||
bytes = IOUtils.toByteArray(resolver.getResources("/static/img/info*.png")[0].getInputStream());
|
||||
break;
|
||||
case "loginLogo":
|
||||
bytes = IOUtils.toByteArray(resolver.getResources("/static/img/logo-dark-MeterSphere.*.svg")[0].getInputStream());
|
||||
bytes = IOUtils.toByteArray(resolver.getResources("/static/img/logo-dark-MeterSphere*.svg")[0].getInputStream());
|
||||
contentType = MediaType.valueOf("image/svg+xml");
|
||||
break;
|
||||
default:
|
||||
|
@ -85,9 +85,13 @@ public class FileService {
|
||||
}
|
||||
|
||||
public FileMetadata saveFile(MultipartFile file) {
|
||||
return saveFile(file,file.getOriginalFilename());
|
||||
}
|
||||
|
||||
public FileMetadata saveFile(MultipartFile file,String originalFilename) {
|
||||
final FileMetadata fileMetadata = new FileMetadata();
|
||||
fileMetadata.setId(UUID.randomUUID().toString());
|
||||
fileMetadata.setName(file.getOriginalFilename());
|
||||
fileMetadata.setName(originalFilename);
|
||||
fileMetadata.setSize(file.getSize());
|
||||
fileMetadata.setCreateTime(System.currentTimeMillis());
|
||||
fileMetadata.setUpdateTime(System.currentTimeMillis());
|
||||
|
@ -23,6 +23,7 @@ import io.dataease.controller.request.organization.QueryOrgMemberRequest;
|
||||
import io.dataease.dto.UserDTO;
|
||||
import io.dataease.dto.UserRoleDTO;
|
||||
import io.dataease.i18n.Translator;
|
||||
import io.dataease.notice.domain.UserDetail;
|
||||
import io.dataease.security.MsUserToken;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
@ -63,6 +64,15 @@ public class UserService {
|
||||
@Resource
|
||||
private WorkspaceService workspaceService;
|
||||
|
||||
public List<UserDetail> queryTypeByIds(List<String> userIds) {
|
||||
return extUserMapper.queryTypeByIds(userIds);
|
||||
}
|
||||
|
||||
public Map<String, User> queryNameByIds(List<String> userIds) {
|
||||
return extUserMapper.queryNameByIds(userIds);
|
||||
}
|
||||
|
||||
|
||||
public UserDTO insert(UserRequest user) {
|
||||
checkUserParam(user);
|
||||
//
|
||||
|
@ -0,0 +1,269 @@
|
||||
package io.dataease.service.system;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.google.gson.JsonObject;
|
||||
import io.dataease.base.domain.FileMetadata;
|
||||
import io.dataease.base.domain.SystemParameter;
|
||||
import io.dataease.base.domain.SystemParameterExample;
|
||||
import io.dataease.base.mapper.FileContentMapper;
|
||||
import io.dataease.base.mapper.FileMetadataMapper;
|
||||
import io.dataease.base.mapper.SystemParameterMapper;
|
||||
import io.dataease.base.mapper.ext.ExtSystemParameterMapper;
|
||||
import io.dataease.commons.constants.ParamConstants;
|
||||
import io.dataease.commons.exception.DEException;
|
||||
import io.dataease.commons.utils.BeanUtils;
|
||||
import io.dataease.commons.utils.EncryptUtils;
|
||||
import io.dataease.commons.utils.LogUtil;
|
||||
import io.dataease.dto.BaseSystemConfigDTO;
|
||||
import io.dataease.dto.SystemParameterDTO;
|
||||
import io.dataease.i18n.Translator;
|
||||
import io.dataease.notice.domain.MailInfo;
|
||||
import io.dataease.service.FileService;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.json.JSONObject;
|
||||
import org.springframework.mail.javamail.JavaMailSenderImpl;
|
||||
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.FileStore;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class SystemParameterService {
|
||||
|
||||
@Resource
|
||||
private SystemParameterMapper systemParameterMapper;
|
||||
@Resource
|
||||
private ExtSystemParameterMapper extSystemParameterMapper;
|
||||
@Resource
|
||||
private FileService fileService;
|
||||
|
||||
|
||||
public String searchEmail() {
|
||||
return extSystemParameterMapper.email();
|
||||
}
|
||||
|
||||
public String getSystemLanguage() {
|
||||
String result = StringUtils.EMPTY;
|
||||
SystemParameterExample example = new SystemParameterExample();
|
||||
example.createCriteria().andParamKeyEqualTo(ParamConstants.I18n.LANGUAGE.getValue());
|
||||
List<SystemParameter> list = systemParameterMapper.selectByExample(example);
|
||||
if (CollectionUtils.isNotEmpty(list)) {
|
||||
String value = list.get(0).getParamValue();
|
||||
if (StringUtils.isNotBlank(value)) {
|
||||
result = value;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void editMail(List<SystemParameter> parameters) {
|
||||
List<SystemParameter> paramList = this.getParamList(ParamConstants.Classify.MAIL.getValue());
|
||||
boolean empty = paramList.size() <= 0;
|
||||
|
||||
parameters.forEach(parameter -> {
|
||||
SystemParameterExample example = new SystemParameterExample();
|
||||
if (parameter.getParamKey().equals(ParamConstants.MAIL.PASSWORD.getValue())) {
|
||||
if (!StringUtils.isBlank(parameter.getParamValue())) {
|
||||
String string = EncryptUtils.aesEncrypt(parameter.getParamValue()).toString();
|
||||
parameter.setParamValue(string);
|
||||
}
|
||||
}
|
||||
example.createCriteria().andParamKeyEqualTo(parameter.getParamKey());
|
||||
if (systemParameterMapper.countByExample(example) > 0) {
|
||||
systemParameterMapper.updateByPrimaryKey(parameter);
|
||||
} else {
|
||||
systemParameterMapper.insert(parameter);
|
||||
}
|
||||
example.clear();
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public List<SystemParameter> getParamList(String type) {
|
||||
SystemParameterExample example = new SystemParameterExample();
|
||||
example.createCriteria().andParamKeyLike(type + "%");
|
||||
return systemParameterMapper.selectByExample(example);
|
||||
}
|
||||
|
||||
public void testConnection(HashMap<String, String> hashMap) {
|
||||
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
|
||||
javaMailSender.setDefaultEncoding("UTF-8");
|
||||
javaMailSender.setHost(hashMap.get(ParamConstants.MAIL.SERVER.getValue()));
|
||||
javaMailSender.setPort(Integer.valueOf(hashMap.get(ParamConstants.MAIL.PORT.getValue())));
|
||||
javaMailSender.setUsername(hashMap.get(ParamConstants.MAIL.ACCOUNT.getValue()));
|
||||
javaMailSender.setPassword(hashMap.get(ParamConstants.MAIL.PASSWORD.getValue()));
|
||||
Properties props = new Properties();
|
||||
String recipients = hashMap.get(ParamConstants.MAIL.RECIPIENTS.getValue());
|
||||
if (BooleanUtils.toBoolean(hashMap.get(ParamConstants.MAIL.SSL.getValue()))) {
|
||||
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
|
||||
}
|
||||
if (BooleanUtils.toBoolean(hashMap.get(ParamConstants.MAIL.TLS.getValue()))) {
|
||||
props.put("mail.smtp.starttls.enable", "true");
|
||||
}
|
||||
props.put("mail.smtp.timeout", "30000");
|
||||
props.put("mail.smtp.connectiontimeout", "5000");
|
||||
javaMailSender.setJavaMailProperties(props);
|
||||
try {
|
||||
javaMailSender.testConnection();
|
||||
} catch (MessagingException e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
DEException.throwException(Translator.get("connection_failed"));
|
||||
}
|
||||
if(!StringUtils.isBlank(recipients)){
|
||||
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
|
||||
MimeMessageHelper helper = null;
|
||||
try {
|
||||
helper = new MimeMessageHelper(mimeMessage, true);
|
||||
helper.setFrom(javaMailSender.getUsername());
|
||||
helper.setSubject("MeterSphere测试邮件 " );
|
||||
helper.setText("这是一封测试邮件,邮件发送成功", true);
|
||||
helper.setTo(recipients);
|
||||
javaMailSender.send(mimeMessage);
|
||||
} catch (MessagingException e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
DEException.throwException(Translator.get("connection_failed"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return System.getenv("MS_VERSION");
|
||||
}
|
||||
|
||||
public MailInfo mailInfo(String type) {
|
||||
List<SystemParameter> paramList = this.getParamList(type);
|
||||
MailInfo mailInfo=new MailInfo ();
|
||||
if (!CollectionUtils.isEmpty(paramList)) {
|
||||
for (SystemParameter param : paramList) {
|
||||
if (StringUtils.equals(param.getParamKey(),ParamConstants.MAIL.SERVER.getValue() )) {
|
||||
mailInfo.setHost(param.getParamValue());
|
||||
} else if (StringUtils.equals(param.getParamKey(), ParamConstants.MAIL.PORT.getValue())) {
|
||||
mailInfo.setPort(param.getParamValue());
|
||||
} else if (StringUtils.equals(param.getParamKey(), ParamConstants.MAIL.ACCOUNT.getValue())) {
|
||||
mailInfo.setAccount(param.getParamValue());
|
||||
} else if (StringUtils.equals(param.getParamKey(), ParamConstants.MAIL.PASSWORD.getValue())) {
|
||||
String password = EncryptUtils.aesDecrypt(param.getParamValue()).toString();
|
||||
mailInfo.setPassword(password);
|
||||
} else if (StringUtils.equals(param.getParamKey(), ParamConstants.MAIL.SSL.getValue())) {
|
||||
mailInfo.setSsl(param.getParamValue());
|
||||
} else if (StringUtils.equals(param.getParamKey(), ParamConstants.MAIL.TLS.getValue())) {
|
||||
mailInfo.setTls(param.getParamValue());
|
||||
} else if (StringUtils.equals(param.getParamKey(), ParamConstants.MAIL.RECIPIENTS.getValue())) {
|
||||
mailInfo.setRecipient(param.getParamValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
return mailInfo;
|
||||
}
|
||||
|
||||
public void saveLdap(List<SystemParameter> parameters) {
|
||||
SystemParameterExample example = new SystemParameterExample();
|
||||
parameters.forEach(param -> {
|
||||
if (param.getParamKey().equals(ParamConstants.LDAP.PASSWORD.getValue())) {
|
||||
String string = EncryptUtils.aesEncrypt(param.getParamValue()).toString();
|
||||
param.setParamValue(string);
|
||||
}
|
||||
example.createCriteria().andParamKeyEqualTo(param.getParamKey());
|
||||
if (systemParameterMapper.countByExample(example) > 0) {
|
||||
systemParameterMapper.updateByPrimaryKey(param);
|
||||
} else {
|
||||
systemParameterMapper.insert(param);
|
||||
}
|
||||
example.clear();
|
||||
});
|
||||
}
|
||||
|
||||
public String getValue(String key) {
|
||||
SystemParameter param = systemParameterMapper.selectByPrimaryKey(key);
|
||||
if (param == null) {
|
||||
return null;
|
||||
}
|
||||
return param.getParamValue();
|
||||
}
|
||||
|
||||
|
||||
public List<SystemParameterDTO> getSystemParameterInfo(String paramConstantsType) {
|
||||
List<SystemParameter> paramList = this.getParamList(paramConstantsType);
|
||||
List<SystemParameterDTO> dtoList = new ArrayList<>();
|
||||
for (SystemParameter systemParameter : paramList) {
|
||||
SystemParameterDTO systemParameterDTO = new SystemParameterDTO();
|
||||
BeanUtils.copyBean(systemParameterDTO, systemParameter);
|
||||
if (systemParameter.getType().equalsIgnoreCase("file")) {
|
||||
FileMetadata fileMetadata = fileService.getFileMetadataById(systemParameter.getParamValue());
|
||||
if (fileMetadata != null) {
|
||||
systemParameterDTO.setFileName(fileMetadata.getName());
|
||||
}
|
||||
}
|
||||
dtoList.add(systemParameterDTO);
|
||||
}
|
||||
dtoList.sort(Comparator.comparingInt(SystemParameter::getSort));
|
||||
return dtoList;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void saveUIInfo(Map<String,List<SystemParameterDTO>> request, List<MultipartFile> bodyFiles) throws IOException {
|
||||
List<SystemParameterDTO> parameters = request.get("systemParams");
|
||||
for (MultipartFile multipartFile : bodyFiles) {
|
||||
if (!multipartFile.isEmpty()) {
|
||||
//防止添加非图片文件
|
||||
try (InputStream input = multipartFile.getInputStream()) {
|
||||
try {
|
||||
// It's an image (only BMP, GIF, JPG and PNG are recognized).
|
||||
ImageIO.read(input).toString();
|
||||
} catch (Exception e) {
|
||||
DEException.throwException("Uploaded images do not meet the image format requirements");
|
||||
return;
|
||||
}
|
||||
}
|
||||
String multipartFileName = multipartFile.getOriginalFilename();
|
||||
String[] split = Objects.requireNonNull(multipartFileName).split(",");
|
||||
parameters.stream().filter(systemParameterDTO -> systemParameterDTO.getParamKey().equalsIgnoreCase(split[1])).forEach(systemParameterDTO -> {
|
||||
systemParameterDTO.setFileName(split[0]);
|
||||
systemParameterDTO.setFile(multipartFile);
|
||||
});
|
||||
}
|
||||
}
|
||||
for (SystemParameterDTO systemParameter : parameters) {
|
||||
MultipartFile file = systemParameter.getFile();
|
||||
if (systemParameter.getType().equalsIgnoreCase("file")) {
|
||||
if (StringUtils.isBlank(systemParameter.getFileName())) {
|
||||
fileService.deleteFileById(systemParameter.getParamValue());
|
||||
}
|
||||
if (file != null) {
|
||||
fileService.deleteFileById(systemParameter.getParamValue());
|
||||
FileMetadata fileMetadata = fileService.saveFile(systemParameter.getFile(),systemParameter.getFileName());
|
||||
systemParameter.setParamValue(fileMetadata.getId());
|
||||
}
|
||||
if (file == null && systemParameter.getFileName() == null) {
|
||||
systemParameter.setParamValue(null);
|
||||
}
|
||||
}
|
||||
systemParameterMapper.deleteByPrimaryKey(systemParameter.getParamKey());
|
||||
systemParameterMapper.insert(systemParameter);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String info="[{\"paramKey\":\"base.url\",\"paramValue\":null,\"type\":\"text\",\"sort\":1,\"file\":null,\"fileName\":null},{\"paramKey\":\"base.title\",\"paramValue\":\"DataEase Title\",\"type\":\"text\",\"sort\":3,\"file\":null,\"fileName\":null},{\"paramKey\":\"base.logo\",\"paramValue\":\"DataEase\",\"type\":\"text\",\"sort\":4,\"file\":null,\"fileName\":\"favicon.icon.png\"}]";
|
||||
List<SystemParameterDTO> temp = JSON.parseArray(info,SystemParameterDTO.class);
|
||||
System.out.println("===>");
|
||||
}
|
||||
}
|
BIN
frontend/src/assets/favicon.ico
Normal file
BIN
frontend/src/assets/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 107 KiB |
@ -32,11 +32,11 @@ export default {
|
||||
// component: () => import('@/business/components/settings/system/TestResourcePool'),
|
||||
// meta: {system: true, title: 'commons.test_resource_pool'}
|
||||
// },
|
||||
// {
|
||||
// path: 'systemparametersetting',
|
||||
// component: () => import('@/business/components/settings/system/SystemParameterSetting'),
|
||||
// meta: {system: true, title: 'commons.system_parameter_setting'}
|
||||
// },
|
||||
{
|
||||
path: 'systemparametersetting',
|
||||
component: () => import('@/business/components/settings/system/SystemParameterSetting'),
|
||||
meta: {system: true, title: 'commons.system_parameter_setting'}
|
||||
},
|
||||
...requireContext.keys().map(key => requireContext(key).system),
|
||||
...requireContext.keys().map(key => requireContext(key).license),
|
||||
{
|
||||
|
@ -1,19 +1,45 @@
|
||||
<template>
|
||||
<div v-loading="result.loading">
|
||||
<el-form :model="formInline" :rules="rules" ref="formInline" class="demo-form-inline"
|
||||
{{systemParams}}
|
||||
<el-form ref="systemParams" class="demo-form-inline"
|
||||
:disabled="show" v-loading="loading" size="small">
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item :label="$t('system_config.base.url')" prop="url">
|
||||
<el-input v-model="formInline.url" :placeholder="$t('system_config.base.url_tip')"/>
|
||||
<i>({{$t('commons.examples')}}:https://rdmetersphere.fit2cloud.com)</i>
|
||||
<el-col v-for="(param,index) in systemParams" :key="index">
|
||||
<!--logo upload-->
|
||||
<el-form-item :label="$t('system_config.base.logo')"
|
||||
v-if="param.paramKey==='base.logo'">
|
||||
<el-upload style="float: left"
|
||||
v-loading="result.loading"
|
||||
class="upload-demo"
|
||||
action=""
|
||||
accept=".jpeg,.jpg,.png,.gif"
|
||||
:on-exceed="handleExceed"
|
||||
:beforeUpload="uploadValidate"
|
||||
:on-error="handleError"
|
||||
:show-file-list="false"
|
||||
:file-list="filesTmp"
|
||||
:http-request="uploadLogo">
|
||||
<el-button style="display: inline-block" size="mini" type="success" plain>
|
||||
{{ $t('commons.upload') }}
|
||||
</el-button>
|
||||
</el-upload>
|
||||
<el-button style="float:left;margin-left: 10px;margin-top: 3px" size="mini" type="danger" plain
|
||||
@click="removeValue('base.logo')">
|
||||
{{ $t('commons.upload') }}
|
||||
</el-button>
|
||||
<el-input :disabled="true" v-model="param.fileName"
|
||||
:placeholder="$t('system_config.base.logo_size')+':135px * 30px'"/>
|
||||
</el-form-item>
|
||||
<!--title-->
|
||||
<el-form-item :label="$t('system_config.base.title')" v-if="param.paramKey==='base.title'">
|
||||
<el-input v-model="param.paramValue" placeholder="eg:DateEase"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<div>
|
||||
<el-button @click="edit" v-if="showEdit" size="small">{{ $t('commons.edit') }}</el-button>
|
||||
<el-button type="success" @click="save('formInline')" v-if="showSave" :disabled="disabledSave" size="small">
|
||||
<el-button type="success" @click="save('systemParams')" v-if="showSave" :disabled="disabledSave" size="small">
|
||||
{{ $t('commons.save') }}
|
||||
</el-button>
|
||||
<el-button @click="cancel" type="info" v-if="showCancel" size="small">{{ $t('commons.cancel') }}</el-button>
|
||||
@ -22,84 +48,123 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ElUploadList from "element-ui/packages/upload/src/upload-list";
|
||||
|
||||
export default {
|
||||
name: "BaseSetting",
|
||||
data() {
|
||||
return {
|
||||
formInline: {},
|
||||
input: '',
|
||||
visible: true,
|
||||
result: {},
|
||||
showEdit: true,
|
||||
showSave: false,
|
||||
showCancel: false,
|
||||
show: true,
|
||||
disabledConnection: false,
|
||||
disabledSave: false,
|
||||
loading: false,
|
||||
rules: {
|
||||
url: [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('system_par'),
|
||||
trigger: ['change', 'blur']
|
||||
},
|
||||
],
|
||||
export default {
|
||||
name: "BaseSetting",
|
||||
data() {
|
||||
return {
|
||||
filesTmp: [],
|
||||
suffixes: new Set(['png', 'jpg', 'gif', 'jpeg']),
|
||||
files: [],
|
||||
systemParams: [],
|
||||
systemParamsOld: [],
|
||||
input: '',
|
||||
visible: true,
|
||||
result: {},
|
||||
showEdit: true,
|
||||
showSave: false,
|
||||
showCancel: false,
|
||||
show: true,
|
||||
disabledConnection: false,
|
||||
disabledSave: false,
|
||||
loading: false,
|
||||
rules: {
|
||||
url: [
|
||||
{
|
||||
required: true,
|
||||
message: 'Not Null',
|
||||
trigger: ['change', 'blur']
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.query()
|
||||
},
|
||||
methods: {
|
||||
query() {
|
||||
this.result = this.$get("/system/base/info", response => {
|
||||
this.formInline = response.data;
|
||||
this.$nextTick(() => {
|
||||
this.$refs.formInline.clearValidate();
|
||||
},
|
||||
created() {
|
||||
this.query()
|
||||
},
|
||||
methods: {
|
||||
query() {
|
||||
this.result = this.$get("/system/base/info", response => {
|
||||
debugger;
|
||||
this.systemParams = response.data;
|
||||
})
|
||||
})
|
||||
},
|
||||
edit() {
|
||||
this.showEdit = false;
|
||||
this.showSave = true;
|
||||
this.showCancel = true;
|
||||
this.show = false;
|
||||
},
|
||||
save(formInline) {
|
||||
this.showEdit = true;
|
||||
this.showCancel = false;
|
||||
this.showSave = false;
|
||||
this.show = true;
|
||||
let param = [
|
||||
{paramKey: "base.url", paramValue: this.formInline.url, type: "text", sort: 1},
|
||||
];
|
||||
},
|
||||
edit() {
|
||||
this.showEdit = false;
|
||||
this.showSave = true;
|
||||
this.showCancel = true;
|
||||
this.show = false;
|
||||
},
|
||||
save() {
|
||||
this.showEdit = true;
|
||||
this.showCancel = false;
|
||||
this.showSave = false;
|
||||
this.show = true;
|
||||
this.systemParams.forEach((param) => {
|
||||
if (param.file !== null) {
|
||||
let file = param.file;
|
||||
let name = file.name + "," + param.paramKey;
|
||||
let newfile = new File([file], name, {type: file.type});
|
||||
this.files.push(newfile);
|
||||
param.file = null;
|
||||
}
|
||||
});
|
||||
|
||||
this.$refs[formInline].validate(valid => {
|
||||
if (valid) {
|
||||
this.result = this.$post("/system/save/base", param, response => {
|
||||
if (response.success) {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
} else {
|
||||
this.$message.error(this.$t('commons.save_failed'));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.result = this.$fileUpload("/system/save/base", null, this.files, {"systemParams": this.systemParams}, response => {
|
||||
if (response.success) {
|
||||
this.query();//刷新数据
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
} else {
|
||||
this.$message.error(this.$t('commons.save_failed'));
|
||||
}
|
||||
});
|
||||
},
|
||||
cancel() {
|
||||
this.showEdit = true;
|
||||
this.showCancel = false;
|
||||
this.showSave = false;
|
||||
this.show = true;
|
||||
this.query();
|
||||
},
|
||||
handleExceed(files, fileList) {
|
||||
this.$warning(this.$t('test_track.case.import.upload_limit_count'));
|
||||
},
|
||||
handleError() {
|
||||
this.$warning(this.$t('test_track.case.import.upload_limit_count'));
|
||||
},
|
||||
uploadValidate(file) {
|
||||
let suffix = file.name.substring(file.name.lastIndexOf('.') + 1);
|
||||
if (!this.suffixes.has(suffix)) {
|
||||
this.$warning(this.$t('test_track.case.import.upload_limit_format'));
|
||||
return false;
|
||||
}
|
||||
})
|
||||
},
|
||||
cancel() {
|
||||
this.showEdit = true;
|
||||
this.showCancel = false;
|
||||
this.showSave = false;
|
||||
this.show = true;
|
||||
this.query();
|
||||
|
||||
if (file.size / 1024 / 1024 > 5) {
|
||||
this.$warning(this.$t('test_track.case.import.upload_limit_size'));
|
||||
return false;
|
||||
}
|
||||
this.errList = [];
|
||||
return true;
|
||||
},
|
||||
uploadLogo(file) {
|
||||
this.systemParams.forEach((param) => {
|
||||
if (param.paramKey === "base.logo") {
|
||||
param.fileName = file.file.name;
|
||||
param.file = file.file;
|
||||
}
|
||||
})
|
||||
},
|
||||
removeValue(paramKey) {
|
||||
this.systemParams.forEach((param) => {
|
||||
if (param.paramKey === paramKey) {
|
||||
param.fileName = null;
|
||||
param.file = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@ -108,4 +173,10 @@ export default {
|
||||
min-height: 300px;
|
||||
}
|
||||
|
||||
.inline-block {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
left: 105px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@ -2,21 +2,15 @@
|
||||
<el-card>
|
||||
<el-tabs class="system-setting" v-model="activeName">
|
||||
|
||||
<el-tab-pane :label="$t('system_config.base_config')" name="base">
|
||||
<base-setting/>
|
||||
<!-- <el-tab-pane :label="$t('system_config.base_config')" name="base">-->
|
||||
<!-- <base-setting/>-->
|
||||
<!-- </el-tab-pane>-->
|
||||
<el-tab-pane :label="$t('display.title')" name="ui">
|
||||
<ui-setting/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('system_parameter_setting.mailbox_service_settings')" name="email">
|
||||
<email-setting/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('system_parameter_setting.ldap_setting')" name="ldap">
|
||||
<ldap-setting/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane v-if="hasLicense()" :label="$t('display.title')" name="display">
|
||||
<ms-display/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane v-if="hasLicense()" :label="$t('auth_source.title')" name="auth">
|
||||
<ms-auth/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-card>
|
||||
</template>
|
||||
@ -24,6 +18,7 @@
|
||||
<script>
|
||||
import EmailSetting from "./EmailSetting";
|
||||
import LdapSetting from "./LdapSetting";
|
||||
import UiSetting from "./UiSetting";
|
||||
import BaseSetting from "./BaseSetting";
|
||||
import {hasLicense} from '@/common/js/utils';
|
||||
|
||||
@ -35,6 +30,7 @@ export default {
|
||||
name: "SystemParameterSetting",
|
||||
components: {
|
||||
BaseSetting,
|
||||
UiSetting,
|
||||
EmailSetting,
|
||||
LdapSetting,
|
||||
"MsDisplay": display.default,
|
||||
@ -42,7 +38,7 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeName: 'base',
|
||||
activeName: 'ui',
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
265
frontend/src/business/components/settings/system/UiSetting.vue
Normal file
265
frontend/src/business/components/settings/system/UiSetting.vue
Normal file
@ -0,0 +1,265 @@
|
||||
<template>
|
||||
<div v-loading="result.loading">
|
||||
<el-form ref="systemParams" class="demo-form-inline"
|
||||
:disabled="show" v-loading="loading" size="small">
|
||||
<el-row>
|
||||
<el-col v-for="(param,index) in systemParams" :key="index">
|
||||
<!--logo upload-->
|
||||
<el-form-item :label="$t('display.logo')"
|
||||
v-if="param.paramKey==='ui.logo'">
|
||||
<el-upload style="float: right;margin-left: 10px"
|
||||
v-loading="result.loading"
|
||||
class="upload-demo"
|
||||
action=""
|
||||
accept=".jpeg,.jpg,.png,.gif"
|
||||
:on-exceed="handleExceed"
|
||||
:beforeUpload="uploadValidate"
|
||||
:on-error="handleError"
|
||||
:show-file-list="false"
|
||||
:file-list="filesTmp"
|
||||
:http-request="uploadLogo">
|
||||
<el-button style="display: inline-block" size="mini" type="success" plain>
|
||||
{{ $t('commons.upload') }}
|
||||
</el-button>
|
||||
</el-upload>
|
||||
<el-button style="float:right;margin-top: 3px" size="mini" type="danger" plain
|
||||
@click="removeValue('ui.logo')">
|
||||
{{ $t('commons.clear') }}
|
||||
</el-button>
|
||||
<el-input :disabled="true" v-model="param.fileName"
|
||||
:placeholder="$t('display.advice_size')+':135px * 30px'"/>
|
||||
</el-form-item>
|
||||
<!--logo upload-->
|
||||
<el-form-item :label="$t('display.loginImage')"
|
||||
v-if="param.paramKey==='ui.loginImage'">
|
||||
<el-upload style="float: right;margin-left: 10px"
|
||||
v-loading="result.loading"
|
||||
class="upload-demo"
|
||||
action=""
|
||||
accept=".jpeg,.jpg,.png,.gif"
|
||||
:on-exceed="handleExceed"
|
||||
:beforeUpload="uploadValidate"
|
||||
:on-error="handleError"
|
||||
:show-file-list="false"
|
||||
:file-list="filesTmp"
|
||||
:http-request="uploadLoginImage">
|
||||
<el-button style="display: inline-block" size="mini" type="success" plain>
|
||||
{{ $t('commons.upload') }}
|
||||
</el-button>
|
||||
</el-upload>
|
||||
<el-button style="float:right;margin-top: 3px" size="mini" type="danger" plain
|
||||
@click="removeValue('ui.loginImage')">
|
||||
{{ $t('commons.clear') }}
|
||||
</el-button>
|
||||
<el-input :disabled="true" v-model="param.fileName"
|
||||
:placeholder="$t('display.advice_size')+':500px * 450px'"/>
|
||||
</el-form-item>
|
||||
<!--favicon upload-->
|
||||
<el-form-item :label="$t('display.loginLogo')"
|
||||
v-if="param.paramKey==='ui.loginLogo'">
|
||||
<el-upload style="float: right;margin-left: 10px"
|
||||
v-loading="result.loading"
|
||||
class="upload-demo"
|
||||
action=""
|
||||
accept=".jpeg,.jpg,.png,.gif"
|
||||
:on-exceed="handleExceed"
|
||||
:beforeUpload="uploadValidate"
|
||||
:on-error="handleError"
|
||||
:show-file-list="false"
|
||||
:file-list="filesTmp"
|
||||
:http-request="uploadLoginLogo">
|
||||
<el-button style="display: inline-block" size="mini" type="success" plain>
|
||||
{{ $t('commons.upload') }}
|
||||
</el-button>
|
||||
</el-upload>
|
||||
<el-button style="float:right;margin-top: 3px" size="mini" type="danger" plain
|
||||
@click="removeValue('ui.loginLogo')">
|
||||
{{ $t('commons.clear') }}
|
||||
</el-button>
|
||||
<el-input :disabled="true" v-model="param.fileName"
|
||||
:placeholder="$t('display.advice_size')+':135px * 30px'"/>
|
||||
</el-form-item>
|
||||
<!--favicon upload-->
|
||||
<el-form-item :label="$t('display.favicon')"
|
||||
v-if="param.paramKey==='ui.favicon'">
|
||||
<el-upload style="float: right;margin-left: 10px"
|
||||
v-loading="result.loading"
|
||||
class="upload-demo"
|
||||
action=""
|
||||
accept=".jpeg,.jpg,.png,.gif"
|
||||
:on-exceed="handleExceed"
|
||||
:beforeUpload="uploadValidate"
|
||||
:on-error="handleError"
|
||||
:show-file-list="false"
|
||||
:file-list="filesTmp"
|
||||
:http-request="uploadFavicon">
|
||||
<el-button style="display: inline-block" size="mini" type="success" plain>
|
||||
{{ $t('commons.upload') }}
|
||||
</el-button>
|
||||
</el-upload>
|
||||
<el-button style="float:right;margin-top: 3px" size="mini" type="danger" plain
|
||||
@click="removeValue('ui.favicon')">
|
||||
{{ $t('commons.clear') }}
|
||||
</el-button>
|
||||
<el-input :disabled="true" v-model="param.fileName"
|
||||
:placeholder="$t('display.advice_size')+':16px * 16px'"/>
|
||||
</el-form-item>
|
||||
<!--ui.loginTitle-->
|
||||
<el-form-item :label="$t('display.loginTitle')" v-if="param.paramKey==='ui.loginTitle'">
|
||||
<el-input v-model="param.paramValue" placeholder="eg:DateEase"/>
|
||||
</el-form-item>
|
||||
<!--ui.title-->
|
||||
<el-form-item :label="$t('display.title')" v-if="param.paramKey==='ui.title'">
|
||||
<el-input v-model="param.paramValue" placeholder="eg:DateEase"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<div>
|
||||
<el-button @click="edit" v-if="showEdit" size="small">{{ $t('commons.edit') }}</el-button>
|
||||
<el-button type="success" @click="save" v-if="showSave" :disabled="disabledSave" size="small">
|
||||
{{ $t('commons.save') }}
|
||||
</el-button>
|
||||
<el-button @click="cancel" type="info" v-if="showCancel" size="small">{{ $t('commons.cancel') }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ElUploadList from "element-ui/packages/upload/src/upload-list";
|
||||
|
||||
export default {
|
||||
name: "UiSetting",
|
||||
data() {
|
||||
return {
|
||||
filesTmp: [],
|
||||
suffixes: new Set(['png', 'jpg', 'gif', 'jpeg']),
|
||||
files: [],
|
||||
systemParams: [],
|
||||
systemParamsOld: [],
|
||||
input: '',
|
||||
visible: true,
|
||||
result: {},
|
||||
showEdit: true,
|
||||
showSave: false,
|
||||
showCancel: false,
|
||||
show: true,
|
||||
disabledConnection: false,
|
||||
disabledSave: false,
|
||||
loading: false,
|
||||
rules: {
|
||||
url: [
|
||||
{
|
||||
required: true,
|
||||
message: 'Not Null',
|
||||
trigger: ['change', 'blur']
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.query()
|
||||
},
|
||||
methods: {
|
||||
query() {
|
||||
this.result = this.$get("/system/ui/info", response => {
|
||||
debugger;
|
||||
this.systemParams = response.data;
|
||||
})
|
||||
},
|
||||
edit() {
|
||||
this.showEdit = false;
|
||||
this.showSave = true;
|
||||
this.showCancel = true;
|
||||
this.show = false;
|
||||
},
|
||||
save() {
|
||||
this.showEdit = true;
|
||||
this.showCancel = false;
|
||||
this.showSave = false;
|
||||
this.show = true;
|
||||
this.systemParams.forEach((systemParam) => {
|
||||
if (systemParam.file !== null) {
|
||||
let file = systemParam.file;
|
||||
let name = file.name + "," + systemParam.paramKey;
|
||||
let newfile = new File([file], name, {type: file.type});
|
||||
this.files.push(newfile);
|
||||
systemParam.file = null;
|
||||
}
|
||||
});
|
||||
|
||||
this.result = this.$fileUpload("/system/save/ui", null, this.files, {"systemParams": this.systemParams}, response => {
|
||||
if (response.success) {
|
||||
this.query();//刷新数据
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
} else {
|
||||
this.$message.error(this.$t('commons.save_failed'));
|
||||
}
|
||||
});
|
||||
},
|
||||
cancel() {
|
||||
this.showEdit = true;
|
||||
this.showCancel = false;
|
||||
this.showSave = false;
|
||||
this.show = true;
|
||||
this.query();
|
||||
},
|
||||
handleExceed(files, fileList) {
|
||||
this.$warning(this.$t('test_track.case.import.upload_limit_count'));
|
||||
},
|
||||
handleError() {
|
||||
this.$warning(this.$t('test_track.case.import.upload_limit_count'));
|
||||
},
|
||||
uploadValidate(file) {
|
||||
let suffix = file.name.substring(file.name.lastIndexOf('.') + 1);
|
||||
if (!this.suffixes.has(suffix)) {
|
||||
this.$warning(this.$t('test_track.case.import.upload_limit_format'));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (file.size / 1024 / 1024 > 5) {
|
||||
this.$warning(this.$t('test_track.case.import.upload_limit_size'));
|
||||
return false;
|
||||
}
|
||||
this.errList = [];
|
||||
return true;
|
||||
},
|
||||
uploadLogo(file) {
|
||||
this.upload(file,'ui.logo')
|
||||
},
|
||||
uploadFavicon(file) {
|
||||
this.upload(file,'ui.favicon')
|
||||
},
|
||||
uploadLoginImage(file) {
|
||||
this.upload(file,'ui.loginImage')
|
||||
},
|
||||
uploadLoginLogo(file) {
|
||||
this.upload(file,'ui.loginLogo')
|
||||
},
|
||||
upload(file,paramKey) {
|
||||
this.systemParams.forEach((systemParam) => {
|
||||
if (systemParam.paramKey === paramKey) {
|
||||
systemParam.fileName = file.file.name;
|
||||
systemParam.file = file.file;
|
||||
}
|
||||
})
|
||||
},
|
||||
removeValue(paramKey) {
|
||||
this.systemParams.forEach((systemParam) => {
|
||||
if (systemParam.paramKey === paramKey) {
|
||||
systemParam.fileName = null;
|
||||
systemParam.file = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.el-form {
|
||||
min-height: 300px;
|
||||
}
|
||||
|
||||
</style>
|
@ -4,7 +4,7 @@
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="shortcut icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<link rel="shortcut icon" href="<%= BASE_URL %>test-favicon.ico">
|
||||
<title>DataEase</title>
|
||||
</head>
|
||||
<body>
|
||||
|
@ -1,5 +1,6 @@
|
||||
export default {
|
||||
commons: {
|
||||
upload:'Upload',
|
||||
cover: 'Cover',
|
||||
not_cover: 'Not Cover',
|
||||
import_mode: 'Import mode',
|
||||
@ -34,7 +35,7 @@ export default {
|
||||
operating: 'Operating',
|
||||
input_limit: 'Within {0} and {1} characters',
|
||||
login: 'Sign In',
|
||||
welcome: 'One-stop open source continuous testing platform',
|
||||
welcome: 'One-stop open source data analysis platform',
|
||||
username: 'Username',
|
||||
password: 'Password',
|
||||
input_username: 'Please enter username',
|
||||
@ -216,12 +217,21 @@ export default {
|
||||
loginImage: 'Picture on the right side of the login page',
|
||||
loginTitle: 'Login page prompt information',
|
||||
pageTitle: 'Page Title',
|
||||
advice_size:"The recommended image size is ",
|
||||
favicon:"Favicon",
|
||||
},
|
||||
system_config: {
|
||||
base_config: 'Base Config',
|
||||
base: {
|
||||
url: 'Website URL',
|
||||
url_tip: 'example:http://localhost:8081'
|
||||
url_tip: 'example:http://localhost:8081',
|
||||
logo: "System LOGO (displayed in the LOGO in the upper left corner of the system homepage)",
|
||||
advice_size:"The recommended image size is ",
|
||||
title:"Title (text displayed on browser tab page)",
|
||||
favicon:"Favicon",
|
||||
system_name:"System name (displayed in the system name in the upper left corner of the system home page)",
|
||||
login_image: "Login page image (the image shown on the login page)",
|
||||
login_name:"System name displayed on login page"
|
||||
}
|
||||
},
|
||||
workspace: {
|
||||
|
@ -1,5 +1,6 @@
|
||||
export default {
|
||||
commons: {
|
||||
upload:'上传',
|
||||
cover: '覆盖',
|
||||
not_cover: '不覆盖',
|
||||
import_mode: '导入模式',
|
||||
@ -35,7 +36,7 @@ export default {
|
||||
operating: '操作',
|
||||
input_limit: '长度在 {0} 到 {1} 个字符',
|
||||
login: '登录',
|
||||
welcome: '一站式开源持续测试平台',
|
||||
welcome: '一站式开源数据分析平台',
|
||||
username: '姓名',
|
||||
password: '密码',
|
||||
input_username: '请输入用户姓名',
|
||||
@ -218,12 +219,21 @@ export default {
|
||||
loginImage: '登陆页面右侧图片',
|
||||
loginTitle: '登陆页面提示信息',
|
||||
pageTitle: '页面 Title',
|
||||
favicon:"Favicon(浏览器Tab页上的小图标)",
|
||||
advice_size:"建议图片大小",
|
||||
},
|
||||
system_config: {
|
||||
base_config: '基本配置',
|
||||
base: {
|
||||
url: '当前站点URL',
|
||||
url_tip: '例如:http://localhost:8081'
|
||||
url_tip: '例如:http://localhost:8081',
|
||||
logo: "系统LOGO(显示在系统主页左上角的LOGO)",
|
||||
advice_size:"建议图片大小",
|
||||
title:"Title(浏览器Tab页上的显示的文字)",
|
||||
favicon:"Favicon(浏览器Tab页上的小图标)",
|
||||
system_name:"系统名称(显示在系统主页左上角的系统名称)",
|
||||
login_image: "登录页图片(登录页中显示的图片)",
|
||||
login_name:"登录页显示的系统名称"
|
||||
}
|
||||
},
|
||||
workspace: {
|
||||
|
@ -1,5 +1,6 @@
|
||||
export default {
|
||||
commons: {
|
||||
upload:'上传',
|
||||
cover: '覆蓋',
|
||||
not_cover: '不覆蓋',
|
||||
import_mode: '導入模式',
|
||||
@ -35,7 +36,7 @@ export default {
|
||||
operating: '操作',
|
||||
input_limit: '長度在 {0} 到 {1} 個字符',
|
||||
login: '登錄',
|
||||
welcome: '壹站式開源持續測試平臺',
|
||||
welcome: '壹站式開源数据分析平臺',
|
||||
username: '姓名',
|
||||
password: '密碼',
|
||||
input_username: '請輸入用戶姓名',
|
||||
@ -217,12 +218,21 @@ export default {
|
||||
loginImage: '登陸頁面右側圖片',
|
||||
loginTitle: '登陸頁面提示信息',
|
||||
pageTitle: '頁面 Title',
|
||||
favicon:"Favicon(瀏覽器Tab頁上的小圖標)",
|
||||
advice_size:"建議圖片大小",
|
||||
},
|
||||
system_config: {
|
||||
base_config: '基本配置',
|
||||
base: {
|
||||
url: '當前站點URL',
|
||||
url_tip: '例如:http://localhost:8081'
|
||||
url_tip: '例如:http://localhost:8081',
|
||||
logo: "系統LOGO(顯示在系統主頁左上角的LOGO)",
|
||||
advice_size:"建議圖片大小",
|
||||
title:"Title(瀏覽器Tab頁上的顯示的文字)",
|
||||
favicon:"Favicon(瀏覽器Tab頁上的小圖標)",
|
||||
system_name:"系統名稱(顯示在系統主頁左上角的系統名稱)",
|
||||
login_image: "登錄頁圖片(登錄頁中顯示的圖片)",
|
||||
login_name:"登錄頁顯示的系統名稱"
|
||||
}
|
||||
},
|
||||
workspace: {
|
||||
|
@ -4,7 +4,7 @@
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="shortcut icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<link rel="shortcut icon" href="<%= BASE_URL %>display/file/favicon">
|
||||
<title>DataEase</title>
|
||||
</head>
|
||||
<body>
|
||||
|
Loading…
Reference in New Issue
Block a user