提交 5b1ec9b1 authored 作者: wangjiahao's avatar wangjiahao

feat:自定义样式,email

上级 0afbbf31
...@@ -372,27 +372,27 @@ ...@@ -372,27 +372,27 @@
<skipTests>true</skipTests> <skipTests>true</skipTests>
</configuration> </configuration>
</plugin> </plugin>
<plugin> <!-- <plugin>-->
<artifactId>maven-clean-plugin</artifactId> <!-- <artifactId>maven-clean-plugin</artifactId>-->
<configuration> <!-- <configuration>-->
<filesets> <!-- <filesets>-->
<fileset> <!-- <fileset>-->
<directory>src/main/resources/static</directory> <!-- <directory>src/main/resources/static</directory>-->
<includes> <!-- <includes>-->
<include>**</include> <!-- <include>**</include>-->
</includes> <!-- </includes>-->
<followSymlinks>false</followSymlinks> <!-- <followSymlinks>false</followSymlinks>-->
</fileset> <!-- </fileset>-->
<fileset> <!-- <fileset>-->
<directory>src/main/resources/templates</directory> <!-- <directory>src/main/resources/templates</directory>-->
<includes> <!-- <includes>-->
<include>**</include> <!-- <include>**</include>-->
</includes> <!-- </includes>-->
<followSymlinks>false</followSymlinks> <!-- <followSymlinks>false</followSymlinks>-->
</fileset> <!-- </fileset>-->
</filesets> <!-- </filesets>-->
</configuration> <!-- </configuration>-->
</plugin> <!-- </plugin>-->
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
......
...@@ -2,6 +2,7 @@ package io.dataease.base.mapper.ext; ...@@ -2,6 +2,7 @@ package io.dataease.base.mapper.ext;
import io.dataease.base.domain.User; import io.dataease.base.domain.User;
import io.dataease.controller.request.UserRequest; import io.dataease.controller.request.UserRequest;
import io.dataease.notice.domain.UserDetail;
import org.apache.ibatis.annotations.MapKey; import org.apache.ibatis.annotations.MapKey;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
...@@ -18,6 +19,8 @@ public interface ExtUserMapper { ...@@ -18,6 +19,8 @@ public interface ExtUserMapper {
List<User> searchUser(String condition); List<User> searchUser(String condition);
List<UserDetail> queryTypeByIds(List<String> userIds);
@MapKey("id") @MapKey("id")
Map<String, User> queryNameByIds(List<String> userIds); Map<String, User> queryNameByIds(List<String> userIds);
} }
...@@ -16,6 +16,18 @@ ...@@ -16,6 +16,18 @@
<result column="phone" jdbcType="VARCHAR" property="phone"/> <result column="phone" jdbcType="VARCHAR" property="phone"/>
</resultMap> </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 id="getUserList" resultMap="BaseResultMap">
select u.id, u.name, u.email, u.phone, u.language, u.status, u.source, 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 u.last_organization_id, u.last_workspace_id, u.language, u.create_time, u.update_time
......
...@@ -31,6 +31,7 @@ public interface ParamConstants { ...@@ -31,6 +31,7 @@ public interface ParamConstants {
MAIL("smtp"), MAIL("smtp"),
BASE("base"), BASE("base"),
LDAP("ldap"), LDAP("ldap"),
UI("ui"),
REGISTRY("registry"); REGISTRY("registry");
private String value; private String value;
......
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);
}
}
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;
}
}
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);
}
}
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;
}
package io.dataease.notice.domain;
import lombok.Data;
@Data
public class Mail {
// 发送给谁
private String to;
// 发送主题
private String subject;
// 发送内容
private String content;
// 附件地址
private String filePath;
}
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;
}
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;
}
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;
}
package io.dataease.notice.domain;
import lombok.Data;
@Data
public class UserDetail {
private String email;
private String phone;
}
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);
}
}
package io.dataease.notice.message;
public interface Message {
String toJsonString();
}
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);
}
}
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;
}
}
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;
}
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);
}
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);
}
}
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);
}
}
}
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);
}
}
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;
}
}
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);
}
});
}
}
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);
}
}
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);
}
}
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 { ...@@ -48,15 +48,19 @@ public class BaseDisplayService {
if (bytes == null) { if (bytes == null) {
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(getClass().getClassLoader()); PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(getClass().getClassLoader());
switch (imageName) { 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": 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"); contentType = MediaType.valueOf("image/svg+xml");
break; break;
case "loginImage": 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; break;
case "loginLogo": 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"); contentType = MediaType.valueOf("image/svg+xml");
break; break;
default: default:
......
...@@ -85,9 +85,13 @@ public class FileService { ...@@ -85,9 +85,13 @@ public class FileService {
} }
public FileMetadata saveFile(MultipartFile file) { public FileMetadata saveFile(MultipartFile file) {
return saveFile(file,file.getOriginalFilename());
}
public FileMetadata saveFile(MultipartFile file,String originalFilename) {
final FileMetadata fileMetadata = new FileMetadata(); final FileMetadata fileMetadata = new FileMetadata();
fileMetadata.setId(UUID.randomUUID().toString()); fileMetadata.setId(UUID.randomUUID().toString());
fileMetadata.setName(file.getOriginalFilename()); fileMetadata.setName(originalFilename);
fileMetadata.setSize(file.getSize()); fileMetadata.setSize(file.getSize());
fileMetadata.setCreateTime(System.currentTimeMillis()); fileMetadata.setCreateTime(System.currentTimeMillis());
fileMetadata.setUpdateTime(System.currentTimeMillis()); fileMetadata.setUpdateTime(System.currentTimeMillis());
......
...@@ -23,6 +23,7 @@ import io.dataease.controller.request.organization.QueryOrgMemberRequest; ...@@ -23,6 +23,7 @@ import io.dataease.controller.request.organization.QueryOrgMemberRequest;
import io.dataease.dto.UserDTO; import io.dataease.dto.UserDTO;
import io.dataease.dto.UserRoleDTO; import io.dataease.dto.UserRoleDTO;
import io.dataease.i18n.Translator; import io.dataease.i18n.Translator;
import io.dataease.notice.domain.UserDetail;
import io.dataease.security.MsUserToken; import io.dataease.security.MsUserToken;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils; import org.apache.shiro.SecurityUtils;
...@@ -63,6 +64,15 @@ public class UserService { ...@@ -63,6 +64,15 @@ public class UserService {
@Resource @Resource
private WorkspaceService workspaceService; 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) { public UserDTO insert(UserRequest user) {
checkUserParam(user); checkUserParam(user);
// //
......
...@@ -32,11 +32,11 @@ export default { ...@@ -32,11 +32,11 @@ export default {
// component: () => import('@/business/components/settings/system/TestResourcePool'), // component: () => import('@/business/components/settings/system/TestResourcePool'),
// meta: {system: true, title: 'commons.test_resource_pool'} // meta: {system: true, title: 'commons.test_resource_pool'}
// }, // },
// { {
// path: 'systemparametersetting', path: 'systemparametersetting',
// component: () => import('@/business/components/settings/system/SystemParameterSetting'), component: () => import('@/business/components/settings/system/SystemParameterSetting'),
// meta: {system: true, title: 'commons.system_parameter_setting'} meta: {system: true, title: 'commons.system_parameter_setting'}
// }, },
...requireContext.keys().map(key => requireContext(key).system), ...requireContext.keys().map(key => requireContext(key).system),
...requireContext.keys().map(key => requireContext(key).license), ...requireContext.keys().map(key => requireContext(key).license),
{ {
......
<template> <template>
<div v-loading="result.loading"> <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"> :disabled="show" v-loading="loading" size="small">
<el-row> <el-row>
<el-col> <el-col v-for="(param,index) in systemParams" :key="index">
<el-form-item :label="$t('system_config.base.url')" prop="url"> <!--logo upload-->
<el-input v-model="formInline.url" :placeholder="$t('system_config.base.url_tip')"/> <el-form-item :label="$t('system_config.base.logo')"
<i>({{$t('commons.examples')}}:https://rdmetersphere.fit2cloud.com)</i> 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-form-item>
</el-col> </el-col>
</el-row> </el-row>
</el-form> </el-form>
<div> <div>
<el-button @click="edit" v-if="showEdit" size="small">{{ $t('commons.edit') }}</el-button> <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') }} {{ $t('commons.save') }}
</el-button> </el-button>
<el-button @click="cancel" type="info" v-if="showCancel" size="small">{{ $t('commons.cancel') }}</el-button> <el-button @click="cancel" type="info" v-if="showCancel" size="small">{{ $t('commons.cancel') }}</el-button>
...@@ -22,84 +48,123 @@ ...@@ -22,84 +48,123 @@
</template> </template>
<script> <script>
import ElUploadList from "element-ui/packages/upload/src/upload-list";
export default { export default {
name: "BaseSetting", name: "BaseSetting",
data() { data() {
return { return {
formInline: {}, filesTmp: [],
input: '', suffixes: new Set(['png', 'jpg', 'gif', 'jpeg']),
visible: true, files: [],
result: {}, systemParams: [],
showEdit: true, systemParamsOld: [],
showSave: false, input: '',
showCancel: false, visible: true,
show: true, result: {},
disabledConnection: false, showEdit: true,
disabledSave: false, showSave: false,
loading: false, showCancel: false,
rules: { show: true,
url: [ disabledConnection: false,
{ disabledSave: false,
required: true, loading: false,
message: this.$t('system_par'), rules: {
trigger: ['change', 'blur'] 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();
})
})
}, },
edit() { created() {
this.showEdit = false; this.query()
this.showSave = true;
this.showCancel = true;
this.show = false;
}, },
save(formInline) { methods: {
this.showEdit = true; query() {
this.showCancel = false; this.result = this.$get("/system/base/info", response => {
this.showSave = false; debugger;
this.show = true; this.systemParams = response.data;
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 => { this.result = this.$fileUpload("/system/save/base", null, this.files, {"systemParams": this.systemParams}, response => {
if (valid) { if (response.success) {
this.result = this.$post("/system/save/base", param, response => { this.query();//刷新数据
if (response.success) { this.$success(this.$t('commons.save_success'));
this.$success(this.$t('commons.save_success')); } else {
} else { this.$message.error(this.$t('commons.save_failed'));
this.$message.error(this.$t('commons.save_failed')); }
} });
}); },
} else { 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; return false;
} }
})
}, if (file.size / 1024 / 1024 > 5) {
cancel() { this.$warning(this.$t('test_track.case.import.upload_limit_size'));
this.showEdit = true; return false;
this.showCancel = false; }
this.showSave = false; this.errList = [];
this.show = true; return true;
this.query(); },
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> </script>
<style scoped> <style scoped>
...@@ -108,4 +173,10 @@ export default { ...@@ -108,4 +173,10 @@ export default {
min-height: 300px; min-height: 300px;
} }
.inline-block {
display: inline-block;
position: absolute;
left: 105px;
}
</style> </style>
...@@ -2,21 +2,15 @@ ...@@ -2,21 +2,15 @@
<el-card> <el-card>
<el-tabs class="system-setting" v-model="activeName"> <el-tabs class="system-setting" v-model="activeName">
<el-tab-pane :label="$t('system_config.base_config')" name="base"> <!-- <el-tab-pane :label="$t('system_config.base_config')" name="base">-->
<base-setting/> <!-- <base-setting/>-->
<!-- </el-tab-pane>-->
<el-tab-pane :label="$t('display.title')" name="ui">
<ui-setting/>
</el-tab-pane> </el-tab-pane>
<el-tab-pane :label="$t('system_parameter_setting.mailbox_service_settings')" name="email"> <el-tab-pane :label="$t('system_parameter_setting.mailbox_service_settings')" name="email">
<email-setting/> <email-setting/>
</el-tab-pane> </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-tabs>
</el-card> </el-card>
</template> </template>
...@@ -24,6 +18,7 @@ ...@@ -24,6 +18,7 @@
<script> <script>
import EmailSetting from "./EmailSetting"; import EmailSetting from "./EmailSetting";
import LdapSetting from "./LdapSetting"; import LdapSetting from "./LdapSetting";
import UiSetting from "./UiSetting";
import BaseSetting from "./BaseSetting"; import BaseSetting from "./BaseSetting";
import {hasLicense} from '@/common/js/utils'; import {hasLicense} from '@/common/js/utils';
...@@ -35,6 +30,7 @@ export default { ...@@ -35,6 +30,7 @@ export default {
name: "SystemParameterSetting", name: "SystemParameterSetting",
components: { components: {
BaseSetting, BaseSetting,
UiSetting,
EmailSetting, EmailSetting,
LdapSetting, LdapSetting,
"MsDisplay": display.default, "MsDisplay": display.default,
...@@ -42,7 +38,7 @@ export default { ...@@ -42,7 +38,7 @@ export default {
}, },
data() { data() {
return { return {
activeName: 'base', activeName: 'ui',
} }
}, },
methods: { methods: {
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0"> <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> <title>DataEase</title>
</head> </head>
<body> <body>
......
export default { export default {
commons: { commons: {
upload:'Upload',
cover: 'Cover', cover: 'Cover',
not_cover: 'Not Cover', not_cover: 'Not Cover',
import_mode: 'Import mode', import_mode: 'Import mode',
...@@ -34,7 +35,7 @@ export default { ...@@ -34,7 +35,7 @@ export default {
operating: 'Operating', operating: 'Operating',
input_limit: 'Within {0} and {1} characters', input_limit: 'Within {0} and {1} characters',
login: 'Sign In', login: 'Sign In',
welcome: 'One-stop open source continuous testing platform', welcome: 'One-stop open source data analysis platform',
username: 'Username', username: 'Username',
password: 'Password', password: 'Password',
input_username: 'Please enter username', input_username: 'Please enter username',
...@@ -216,12 +217,21 @@ export default { ...@@ -216,12 +217,21 @@ export default {
loginImage: 'Picture on the right side of the login page', loginImage: 'Picture on the right side of the login page',
loginTitle: 'Login page prompt information', loginTitle: 'Login page prompt information',
pageTitle: 'Page Title', pageTitle: 'Page Title',
advice_size:"The recommended image size is ",
favicon:"Favicon",
}, },
system_config: { system_config: {
base_config: 'Base Config', base_config: 'Base Config',
base: { base: {
url: 'Website URL', 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: { workspace: {
......
export default { export default {
commons: { commons: {
upload:'上传',
cover: '覆盖', cover: '覆盖',
not_cover: '不覆盖', not_cover: '不覆盖',
import_mode: '导入模式', import_mode: '导入模式',
...@@ -35,7 +36,7 @@ export default { ...@@ -35,7 +36,7 @@ export default {
operating: '操作', operating: '操作',
input_limit: '长度在 {0} 到 {1} 个字符', input_limit: '长度在 {0} 到 {1} 个字符',
login: '登录', login: '登录',
welcome: '一站式开源持续测试平台', welcome: '一站式开源数据分析平台',
username: '姓名', username: '姓名',
password: '密码', password: '密码',
input_username: '请输入用户姓名', input_username: '请输入用户姓名',
...@@ -218,12 +219,21 @@ export default { ...@@ -218,12 +219,21 @@ export default {
loginImage: '登陆页面右侧图片', loginImage: '登陆页面右侧图片',
loginTitle: '登陆页面提示信息', loginTitle: '登陆页面提示信息',
pageTitle: '页面 Title', pageTitle: '页面 Title',
favicon:"Favicon(浏览器Tab页上的小图标)",
advice_size:"建议图片大小",
}, },
system_config: { system_config: {
base_config: '基本配置', base_config: '基本配置',
base: { base: {
url: '当前站点URL', 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: { workspace: {
......
export default { export default {
commons: { commons: {
upload:'上传',
cover: '覆蓋', cover: '覆蓋',
not_cover: '不覆蓋', not_cover: '不覆蓋',
import_mode: '導入模式', import_mode: '導入模式',
...@@ -35,7 +36,7 @@ export default { ...@@ -35,7 +36,7 @@ export default {
operating: '操作', operating: '操作',
input_limit: '長度在 {0} 到 {1} 個字符', input_limit: '長度在 {0} 到 {1} 個字符',
login: '登錄', login: '登錄',
welcome: '壹站式開源持續測試平臺', welcome: '壹站式開源数据分析平臺',
username: '姓名', username: '姓名',
password: '密碼', password: '密碼',
input_username: '請輸入用戶姓名', input_username: '請輸入用戶姓名',
...@@ -217,12 +218,21 @@ export default { ...@@ -217,12 +218,21 @@ export default {
loginImage: '登陸頁面右側圖片', loginImage: '登陸頁面右側圖片',
loginTitle: '登陸頁面提示信息', loginTitle: '登陸頁面提示信息',
pageTitle: '頁面 Title', pageTitle: '頁面 Title',
favicon:"Favicon(瀏覽器Tab頁上的小圖標)",
advice_size:"建議圖片大小",
}, },
system_config: { system_config: {
base_config: '基本配置', base_config: '基本配置',
base: { base: {
url: '當前站點URL', 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: { workspace: {
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0"> <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> <title>DataEase</title>
</head> </head>
<body> <body>
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论