Parcourir la source

添加通知配置相关页面和接口

reghao il y a 2 ans
Parent
commit
cc5f60b986
31 fichiers modifiés avec 564 ajouts et 95 suppressions
  1. 1 0
      manager/src/main/java/cn/reghao/devops/manager/app/controller/page/config/RepoAuthPageController.java
  2. 1 1
      manager/src/main/java/cn/reghao/devops/manager/app/service/bd/impl/BuildDeployNotifyImpl.java
  3. 2 2
      manager/src/main/java/cn/reghao/devops/manager/app/service/bd/webhook/WebhookService.java
  4. 2 2
      manager/src/main/java/cn/reghao/devops/manager/machine/service/ClusterService.java
  5. 0 22
      manager/src/main/java/cn/reghao/devops/manager/notification/NotifyReceiver.java
  6. 51 0
      manager/src/main/java/cn/reghao/devops/manager/notification/controller/EmailAccountController.java
  7. 69 0
      manager/src/main/java/cn/reghao/devops/manager/notification/controller/NotifyReceiverController.java
  8. 11 0
      manager/src/main/java/cn/reghao/devops/manager/notification/db/repository/EmailAccountRepository.java
  9. 13 0
      manager/src/main/java/cn/reghao/devops/manager/notification/db/repository/NotifyReceiverRepository.java
  10. 1 1
      manager/src/main/java/cn/reghao/devops/manager/notification/model/BuildNotifyMsg.java
  11. 1 1
      manager/src/main/java/cn/reghao/devops/manager/notification/model/DeployNotifyMsg.java
  12. 9 0
      manager/src/main/java/cn/reghao/devops/manager/notification/model/NotifyType.java
  13. 26 0
      manager/src/main/java/cn/reghao/devops/manager/notification/model/po/EmailAccount.java
  14. 28 0
      manager/src/main/java/cn/reghao/devops/manager/notification/model/po/NotifyReceiver.java
  15. 0 19
      manager/src/main/java/cn/reghao/devops/manager/notification/notifier/email/EmailAccount.java
  16. 9 12
      manager/src/main/java/cn/reghao/devops/manager/notification/service/NotifyService.java
  17. 1 1
      manager/src/main/java/cn/reghao/devops/manager/notification/service/notifier/Notify.java
  18. 1 1
      manager/src/main/java/cn/reghao/devops/manager/notification/service/notifier/NotifyMsg.java
  19. 1 1
      manager/src/main/java/cn/reghao/devops/manager/notification/service/notifier/ding/DingMsg.java
  20. 2 2
      manager/src/main/java/cn/reghao/devops/manager/notification/service/notifier/ding/DingNotify.java
  21. 1 1
      manager/src/main/java/cn/reghao/devops/manager/notification/service/notifier/email/EmailMsg.java
  22. 3 4
      manager/src/main/java/cn/reghao/devops/manager/notification/service/notifier/email/EmailNotify.java
  23. 3 12
      manager/src/main/resources/application-dev.yml
  24. 1 10
      manager/src/main/resources/application-test.yml
  25. 63 0
      manager/src/main/resources/templates/sys/notify/email.html
  26. 50 0
      manager/src/main/resources/templates/sys/notify/emailadd.html
  27. 50 0
      manager/src/main/resources/templates/sys/notify/emailedit.html
  28. 61 0
      manager/src/main/resources/templates/sys/notify/receiver.html
  29. 38 0
      manager/src/main/resources/templates/sys/notify/receiveradd.html
  30. 35 0
      manager/src/main/resources/templates/sys/notify/receiveredit.html
  31. 30 3
      manager/src/test/java/AppConfigTest.java

+ 1 - 0
manager/src/main/java/cn/reghao/devops/manager/app/controller/page/config/RepoAuthPageController.java

@@ -80,6 +80,7 @@ public class RepoAuthPageController {
 
     @GetMapping("/repoauth/detail/{id}")
     public String repoAuthDetailPage(@PathVariable("id") RepoAuthConfig repoAuth, Model model) {
+        repoAuth.setPassword("******");
         model.addAttribute("repoAuth", repoAuth);
         return "/app/config/repoauth/detail";
     }

+ 1 - 1
manager/src/main/java/cn/reghao/devops/manager/app/service/bd/impl/BuildDeployNotifyImpl.java

@@ -7,7 +7,7 @@ import cn.reghao.devops.manager.app.model.po.log.DeployLog;
 import cn.reghao.devops.manager.app.service.bd.BuildDeployNotify;
 import cn.reghao.devops.manager.notification.model.BuildNotifyMsg;
 import cn.reghao.devops.manager.notification.model.DeployNotifyMsg;
-import cn.reghao.devops.manager.notification.NotifyService;
+import cn.reghao.devops.manager.notification.service.NotifyService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 

+ 2 - 2
manager/src/main/java/cn/reghao/devops/manager/app/service/bd/webhook/WebhookService.java

@@ -4,8 +4,8 @@ import cn.reghao.devops.manager.app.db.query.AppConfigQuery;
 import cn.reghao.devops.manager.app.model.po.config.AppConfig;
 import cn.reghao.devops.manager.app.service.bd.BuildApp;
 import cn.reghao.devops.manager.app.service.bd.webhook.event.*;
-import cn.reghao.devops.manager.notification.NotifyService;
-import cn.reghao.devops.manager.notification.notifier.ding.DingMsg;
+import cn.reghao.devops.manager.notification.service.NotifyService;
+import cn.reghao.devops.manager.notification.service.notifier.ding.DingMsg;
 import cn.reghao.jutil.web.ServletUtil;
 import cn.reghao.jutil.jdk.serializer.JsonConverter;
 import com.google.gson.JsonObject;

+ 2 - 2
manager/src/main/java/cn/reghao/devops/manager/machine/service/ClusterService.java

@@ -1,8 +1,8 @@
 package cn.reghao.devops.manager.machine.service;
 
 import cn.reghao.devops.manager.machine.model.dto.KeepalivedState;
-import cn.reghao.devops.manager.notification.NotifyService;
-import cn.reghao.devops.manager.notification.notifier.ding.DingMsg;
+import cn.reghao.devops.manager.notification.service.NotifyService;
+import cn.reghao.devops.manager.notification.service.notifier.ding.DingMsg;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 

+ 0 - 22
manager/src/main/java/cn/reghao/devops/manager/notification/NotifyReceiver.java

@@ -1,22 +0,0 @@
-package cn.reghao.devops.manager.notification;
-
-import lombok.Data;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.stereotype.Component;
-
-/**
- * @author reghao
- * @date 2021-03-18 21:01:46
- */
-@Data
-@Component
-@ConfigurationProperties(prefix = "receiver")
-public class NotifyReceiver {
-    @Value("${receiver.name}")
-    private String name;
-    @Value("${receiver.type}")
-    private String type;
-    @Value("${receiver.url}")
-    private String url;
-}

+ 51 - 0
manager/src/main/java/cn/reghao/devops/manager/notification/controller/EmailAccountController.java

@@ -0,0 +1,51 @@
+package cn.reghao.devops.manager.notification.controller;
+
+import cn.reghao.devops.manager.notification.db.repository.EmailAccountRepository;
+import cn.reghao.devops.manager.notification.model.po.EmailAccount;
+import cn.reghao.devops.manager.util.db.PageSort;
+import io.swagger.annotations.Api;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+/**
+ * @author reghao
+ * @date 2024-01-26 20:52:54
+ */
+@Api(tags = "邮件账户接收页面")
+@Controller
+@RequestMapping("/sys/notify/email")
+public class EmailAccountController {
+    private final EmailAccountRepository emailAccountRepository;
+
+    public EmailAccountController(EmailAccountRepository emailAccountRepository) {
+        this.emailAccountRepository = emailAccountRepository;
+    }
+
+    @GetMapping("")
+    public String emailIndex(Model model) throws Exception {
+        PageRequest pageRequest = PageSort.pageRequest();
+        Page<EmailAccount> page = emailAccountRepository.findAll(pageRequest);
+        page.getContent().forEach(emailAccount -> {
+            emailAccount.setPassword("******");
+        });
+
+        model.addAttribute("page", page);
+        model.addAttribute("list", page.getContent());
+        return "/sys/notify/email";
+    }
+
+    @GetMapping("/add")
+    public String emailAdd(Model model) throws Exception {
+        return "/sys/notify/emailadd";
+    }
+
+    @GetMapping("/edit")
+    public String emailEdit(Model model) throws Exception {
+        model.addAttribute("emailAccount", null);
+        return "/sys/notify/emailedit";
+    }
+}

+ 69 - 0
manager/src/main/java/cn/reghao/devops/manager/notification/controller/NotifyReceiverController.java

@@ -0,0 +1,69 @@
+package cn.reghao.devops.manager.notification.controller;
+
+import cn.reghao.devops.manager.notification.db.repository.NotifyReceiverRepository;
+import cn.reghao.devops.manager.notification.model.po.NotifyReceiver;
+import cn.reghao.devops.manager.util.db.PageSort;
+import cn.reghao.jutil.jdk.result.WebResult;
+import io.swagger.annotations.Api;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @author reghao
+ * @date 2024-01-26 20:32:24
+ */
+@Api(tags = "通知接收页面")
+@Controller
+@RequestMapping("/sys/notify/receiver")
+public class NotifyReceiverController {
+    private final NotifyReceiverRepository notifyReceiverRepository;
+
+    public NotifyReceiverController(NotifyReceiverRepository notifyReceiverRepository) {
+        this.notifyReceiverRepository = notifyReceiverRepository;
+    }
+
+    @GetMapping("")
+    public String receiverIndex(Model model) throws Exception {
+        PageRequest pageRequest = PageSort.pageRequest();
+        Page<NotifyReceiver> page = notifyReceiverRepository.findAll(pageRequest);
+        model.addAttribute("page", page);
+        model.addAttribute("list", page.getContent());
+        return "/sys/notify/receiver";
+    }
+
+    @GetMapping("/add")
+    public String receiverAdd(Model model) throws Exception {
+        return "/sys/notify/receiveradd";
+    }
+
+    @GetMapping("/edit/{name}")
+    public String receiverEdit(@PathVariable("name") String name, Model model) throws Exception {
+        NotifyReceiver notifyReceiver = notifyReceiverRepository.findByName(name);
+        model.addAttribute("notifyReceiver", notifyReceiver);
+        return "/sys/notify/receiveredit";
+    }
+
+    @PostMapping(value = "/save", produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    public String saveReceiver(@Validated NotifyReceiver notifyReceiver) {
+        String type = notifyReceiver.getType();
+        NotifyReceiver notifyReceiver1 = notifyReceiverRepository.findByType(type);
+        return WebResult.success();
+    }
+
+    @DeleteMapping(value = "/delete/{name}", produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    public String deleteReceiver(@PathVariable("name") String name) throws Exception {
+        NotifyReceiver notifyReceiver = notifyReceiverRepository.findByName(name);
+        if (notifyReceiver != null) {
+            notifyReceiverRepository.delete(notifyReceiver);
+        }
+
+        return WebResult.success();
+    }
+}

+ 11 - 0
manager/src/main/java/cn/reghao/devops/manager/notification/db/repository/EmailAccountRepository.java

@@ -0,0 +1,11 @@
+package cn.reghao.devops.manager.notification.db.repository;
+
+import cn.reghao.devops.manager.notification.model.po.EmailAccount;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+/**
+ * @author reghao
+ * @date 2024-01-26 20:02:50
+ */
+public interface EmailAccountRepository extends JpaRepository<EmailAccount, Integer> {
+}

+ 13 - 0
manager/src/main/java/cn/reghao/devops/manager/notification/db/repository/NotifyReceiverRepository.java

@@ -0,0 +1,13 @@
+package cn.reghao.devops.manager.notification.db.repository;
+
+import cn.reghao.devops.manager.notification.model.po.NotifyReceiver;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+/**
+ * @author reghao
+ * @date 2024-01-26 20:02:50
+ */
+public interface NotifyReceiverRepository extends JpaRepository<NotifyReceiver, Integer> {
+    NotifyReceiver findByName(String name);
+    NotifyReceiver findByType(String type);
+}

+ 1 - 1
manager/src/main/java/cn/reghao/devops/manager/notification/model/BuildNotifyMsg.java

@@ -1,7 +1,7 @@
 package cn.reghao.devops.manager.notification.model;
 
 import cn.reghao.devops.manager.app.model.po.AppBuilding;
-import cn.reghao.devops.manager.notification.notifier.ding.DingMsg;
+import cn.reghao.devops.manager.notification.service.notifier.ding.DingMsg;
 import cn.reghao.jutil.jdk.converter.DateTimeConverter;
 import lombok.Data;
 

+ 1 - 1
manager/src/main/java/cn/reghao/devops/manager/notification/model/DeployNotifyMsg.java

@@ -2,7 +2,7 @@ package cn.reghao.devops.manager.notification.model;
 
 import cn.reghao.devops.manager.app.model.po.log.BuildLog;
 import cn.reghao.devops.manager.app.model.po.log.DeployLog;
-import cn.reghao.devops.manager.notification.notifier.ding.DingMsg;
+import cn.reghao.devops.manager.notification.service.notifier.ding.DingMsg;
 import cn.reghao.jutil.jdk.converter.DateTimeConverter;
 import cn.reghao.jutil.jdk.result.ResultStatus;
 import lombok.Data;

+ 9 - 0
manager/src/main/java/cn/reghao/devops/manager/notification/model/NotifyType.java

@@ -0,0 +1,9 @@
+package cn.reghao.devops.manager.notification.model;
+
+/**
+ * @author reghao
+ * @date 2024-01-26 21:52:32
+ */
+public enum NotifyType {
+    webhook, email
+}

+ 26 - 0
manager/src/main/java/cn/reghao/devops/manager/notification/model/po/EmailAccount.java

@@ -0,0 +1,26 @@
+package cn.reghao.devops.manager.notification.model.po;
+
+import cn.reghao.devops.manager.util.db.BaseEntity;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.persistence.Entity;
+import javax.validation.constraints.NotBlank;
+
+/**
+ * @author reghao
+ * @date 2023-10-30 14:41:19
+ */
+@Setter
+@Getter
+@Entity
+public class EmailAccount extends BaseEntity {
+    @NotBlank
+    private String smtp;
+    @NotBlank
+    private String username;
+    @NotBlank
+    private String password;
+    @NotBlank
+    private String personal;
+}

+ 28 - 0
manager/src/main/java/cn/reghao/devops/manager/notification/model/po/NotifyReceiver.java

@@ -0,0 +1,28 @@
+package cn.reghao.devops.manager.notification.model.po;
+
+import cn.reghao.devops.manager.notification.model.NotifyType;
+import cn.reghao.devops.manager.util.db.BaseEntity;
+import cn.reghao.devops.manager.util.validator.ValidEnum;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.validation.constraints.NotBlank;
+
+/**
+ * @author reghao
+ * @date 2021-03-18 21:01:46
+ */
+@Setter
+@Getter
+@Entity
+public class NotifyReceiver extends BaseEntity {
+    @Column(nullable = false, unique = true)
+    private String name;
+    @NotBlank
+    @ValidEnum(value = NotifyType.class, message = "请选择正确的通知类型")
+    private String type;
+    @NotBlank
+    private String url;
+}

+ 0 - 19
manager/src/main/java/cn/reghao/devops/manager/notification/notifier/email/EmailAccount.java

@@ -1,19 +0,0 @@
-package cn.reghao.devops.manager.notification.notifier.email;
-
-import lombok.Data;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.stereotype.Component;
-
-/**
- * @author reghao
- * @date 2023-10-30 14:41:19
- */
-@Data
-@Component
-@ConfigurationProperties(prefix = "email")
-public class EmailAccount {
-    private String smtp;
-    private String username;
-    private String password;
-    private String personal;
-}

+ 9 - 12
manager/src/main/java/cn/reghao/devops/manager/notification/NotifyService.java → manager/src/main/java/cn/reghao/devops/manager/notification/service/NotifyService.java

@@ -1,10 +1,10 @@
-package cn.reghao.devops.manager.notification;
+package cn.reghao.devops.manager.notification.service;
 
-import cn.reghao.devops.manager.notification.notifier.Notify;
-import cn.reghao.devops.manager.notification.notifier.ding.DingMsg;
-import cn.reghao.devops.manager.notification.notifier.ding.DingNotify;
-import cn.reghao.devops.manager.notification.notifier.email.EmailMsg;
-import cn.reghao.devops.manager.notification.notifier.email.EmailNotify;
+import cn.reghao.devops.manager.notification.service.notifier.Notify;
+import cn.reghao.devops.manager.notification.service.notifier.ding.DingMsg;
+import cn.reghao.devops.manager.notification.service.notifier.ding.DingNotify;
+import cn.reghao.devops.manager.notification.service.notifier.email.EmailMsg;
+import cn.reghao.devops.manager.notification.service.notifier.email.EmailNotify;
 import cn.reghao.jutil.jdk.thread.ThreadPoolWrapper;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
@@ -21,18 +21,15 @@ import java.util.concurrent.ExecutorService;
 @Service
 public class NotifyService {
     private final ExecutorService threadPool = ThreadPoolWrapper.threadPool("notify-service");
-    private final NotifyReceiver notifyReceiver;
     private final DingNotify dingNotify;
-    private final EmailNotify emailNotify;
+    private EmailNotify emailNotify;
 
-    public NotifyService(NotifyReceiver notifyReceiver, DingNotify dingNotify, EmailNotify emailNotify) {
-        this.notifyReceiver = notifyReceiver;
+    public NotifyService(DingNotify dingNotify) {
         this.dingNotify = dingNotify;
-        this.emailNotify = emailNotify;
     }
 
     public <T> void notify(T msg) {
-        String receiver = notifyReceiver.getUrl();
+        String receiver = "";
         notify(receiver, msg);
     }
 

+ 1 - 1
manager/src/main/java/cn/reghao/devops/manager/notification/notifier/Notify.java → manager/src/main/java/cn/reghao/devops/manager/notification/service/notifier/Notify.java

@@ -1,4 +1,4 @@
-package cn.reghao.devops.manager.notification.notifier;
+package cn.reghao.devops.manager.notification.service.notifier;
 
 /**
  * @author reghao

+ 1 - 1
manager/src/main/java/cn/reghao/devops/manager/notification/notifier/NotifyMsg.java → manager/src/main/java/cn/reghao/devops/manager/notification/service/notifier/NotifyMsg.java

@@ -1,4 +1,4 @@
-package cn.reghao.devops.manager.notification.notifier;
+package cn.reghao.devops.manager.notification.service.notifier;
 
 import lombok.AllArgsConstructor;
 import lombok.Data;

+ 1 - 1
manager/src/main/java/cn/reghao/devops/manager/notification/notifier/ding/DingMsg.java → manager/src/main/java/cn/reghao/devops/manager/notification/service/notifier/ding/DingMsg.java

@@ -1,4 +1,4 @@
-package cn.reghao.devops.manager.notification.notifier.ding;
+package cn.reghao.devops.manager.notification.service.notifier.ding;
 
 import lombok.Data;
 

+ 2 - 2
manager/src/main/java/cn/reghao/devops/manager/notification/notifier/ding/DingNotify.java → manager/src/main/java/cn/reghao/devops/manager/notification/service/notifier/ding/DingNotify.java

@@ -1,6 +1,6 @@
-package cn.reghao.devops.manager.notification.notifier.ding;
+package cn.reghao.devops.manager.notification.service.notifier.ding;
 
-import cn.reghao.devops.manager.notification.notifier.Notify;
+import cn.reghao.devops.manager.notification.service.notifier.Notify;
 import cn.reghao.jutil.jdk.http.WebRequest;
 import cn.reghao.jutil.jdk.http.WebResponse;
 import cn.reghao.jutil.jdk.serializer.JsonConverter;

+ 1 - 1
manager/src/main/java/cn/reghao/devops/manager/notification/notifier/email/EmailMsg.java → manager/src/main/java/cn/reghao/devops/manager/notification/service/notifier/email/EmailMsg.java

@@ -1,4 +1,4 @@
-package cn.reghao.devops.manager.notification.notifier.email;
+package cn.reghao.devops.manager.notification.service.notifier.email;
 
 import lombok.AllArgsConstructor;
 import lombok.Data;

+ 3 - 4
manager/src/main/java/cn/reghao/devops/manager/notification/notifier/email/EmailNotify.java → manager/src/main/java/cn/reghao/devops/manager/notification/service/notifier/email/EmailNotify.java

@@ -1,7 +1,7 @@
-package cn.reghao.devops.manager.notification.notifier.email;
+package cn.reghao.devops.manager.notification.service.notifier.email;
 
-import cn.reghao.devops.manager.notification.notifier.Notify;
-import org.springframework.stereotype.Component;
+import cn.reghao.devops.manager.notification.model.po.EmailAccount;
+import cn.reghao.devops.manager.notification.service.notifier.Notify;
 
 import javax.mail.MessagingException;
 import javax.mail.Session;
@@ -18,7 +18,6 @@ import java.util.Properties;
  * @author reghao
  * @date 2021-02-25 19:23:16
  */
-@Component
 public class EmailNotify implements Notify<EmailMsg> {
     private final String account;
     private final String password;

+ 3 - 12
manager/src/main/resources/application-dev.yml

@@ -1,14 +1,5 @@
 spring:
   datasource:
-    url: jdbc:mysql://localhost:3306/reghao_devops_rdb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8
-    username: dev
-    password: Dev@123456
-receiver:
-  name: ding-msgbot
-  type: webhook
-  url: https://oapi.dingtalk.com/robot/send?access_token=2ede844511f6a12a0429a25585222ef1f0eb99094421ea4b3155f17fda0f4662
-email:
-  smtp: smtp.163.com
-  username: gisgit@163.com
-  password: sirHdeKYn4PHcMP9
-  personal: admin@devops
+    url: jdbc:mysql://192.168.0.210:3306/reghao_devops_tdb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8
+    username: test
+    password: Test@123456

+ 1 - 10
manager/src/main/resources/application-test.yml

@@ -2,13 +2,4 @@ spring:
   datasource:
     url: jdbc:mysql://192.168.0.212:3306/reghao_devops_tdb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8
     username: test
-    password: Test@123456
-receiver:
-  name: ding-msgbot
-  type: webhook
-  url: https://oapi.dingtalk.com/robot/send?access_token=2ede844511f6a12a0429a25585222ef1f0eb99094421ea4b3155f17fda0f4662
-email:
-  smtp: smtp.163.com
-  username: gisgit@163.com
-  password: sirHdeKYn4PHcMP9
-  personal: admin@devops
+    password: Test@123456

+ 63 - 0
manager/src/main/resources/templates/sys/notify/email.html

@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org">
+<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})"></head>
+
+<body class="timo-layout-page">
+<div class="layui-card">
+    <div class="layui-card-header timo-card-header">
+        <span><i class="fa fa-bars"></i> 邮件账户配置</span>
+        <i class="layui-icon layui-icon-refresh refresh-btn"></i>
+    </div>
+    <div class="layui-card-body">
+        <div class="layui-row timo-card-screen put-row">
+            <div class="pull-right screen-btn-group">
+                <div class="btn-group-right">
+                    <button class="layui-btn open-popup" data-title="添加邮件账户" th:attr="data-url=@{/sys/notify/email/add}"
+                            data-size="640,480">
+                        <i class="fa fa-plus"></i> 添加
+                    </button>
+                </div>
+            </div>
+        </div>
+        <div class="timo-table-wrap">
+            <table class="layui-table timo-table">
+                <thead>
+                <tr>
+                    <th class="timo-table-checkbox">
+                        <label class="timo-checkbox"><input type="checkbox">
+                            <i class="layui-icon layui-icon-ok"></i></label>
+                    </th>
+                    <th class="sortable" data-field="smtp">SMTP</th>
+                    <th class="sortable" data-field="username">用户名</th>
+                    <th class="sortable" data-field="password">密码</th>
+                    <th class="sortable" data-field="personal">发件人</th>
+                    <th>操作</th>
+                </tr>
+                </thead>
+                <tbody>
+                <tr th:each="item:${list}">
+                    <td><label class="timo-checkbox"><input type="checkbox" th:value="${item.id}">
+                        <i class="layui-icon layui-icon-ok"></i></label></td>
+                    <td th:text="${item.smtp}">SMTP</td>
+                    <td th:text="${item.username}">用户名</td>
+                    <td th:text="${item.password}">密码</td>
+                    <td th:text="${item.personal}">发件人</td>
+                    <td>
+                        <a class="open-popup" data-title="编辑" th:attr="data-url=@{'/sys/notify/email/edit/'+${item.id}}"
+                           data-size="640,480" href="#">编辑</a>
+                        <a class="ajax-delete" th:attr="data-msg='确定要删除 '+ ${item.username} + '?'"
+                           th:href="@{'/api/sys/notify/email/' + ${item.id}}">删除</a>
+                    </td>
+                </tr>
+                </tbody>
+            </table>
+        </div>
+        <div th:replace="/common/fragment :: page"></div>
+    </div>
+</div>
+
+<script th:replace="/common/template :: script"></script>
+<script type="text/javascript">
+</script>
+</body>
+</html>

+ 50 - 0
manager/src/main/resources/templates/sys/notify/emailadd.html

@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org">
+
+<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})"></head>
+
+<body>
+<div class="layui-form timo-compile">
+    <form th:action="@{/api/sys/notify/email}">
+        <input type="hidden" name="id" th:value="${emailAccount?.id}"/>
+        <div class="layui-form-item">
+            <label class="layui-form-label required">账户 ID</label>
+            <div class="layui-input-inline">
+                <input class="layui-input" type="text" name="notifyAccountId" placeholder="请输入账户 ID" required th:value="${emailAccount?.notifyAccountId}">
+            </div>
+        </div>
+        <div class="layui-form-item">
+            <label class="layui-form-label required">用户名</label>
+            <div class="layui-input-inline">
+                <input class="layui-input" type="text" name="username" placeholder="请输入用户名" required th:value="${emailAccount?.username}">
+            </div>
+        </div>
+        <div class="layui-form-item">
+            <label class="layui-form-label required">密码</label>
+            <div class="layui-input-inline">
+                <input class="layui-input" type="text" name="password" placeholder="请输入密码" required th:value="${emailAccount?.password}">
+            </div>
+        </div>
+        <div class="layui-form-item">
+            <label class="layui-form-label required">SMTP</label>
+            <div class="layui-input-inline">
+                <input class="layui-input" type="text" name="smtp" placeholder="请输入 SMTP 地址" required th:value="${emailAccount?.smtp}">
+            </div>
+        </div>
+        <div class="layui-form-item">
+            <label class="layui-form-label required">发件人</label>
+            <div class="layui-input-inline">
+                <input class="layui-input" type="text" name="personal" placeholder="请输入发件人名字" required th:value="${emailAccount?.personal}">
+            </div>
+        </div>
+        <div class="layui-form-item timo-finally">
+            <button class="layui-btn ajax-submit"><i class="fa fa-check-circle"></i> 保存</button>
+            <button class="layui-btn btn-secondary close-popup"><i class="fa fa-times-circle"></i> 关闭</button>
+        </div>
+    </form>
+</div>
+<script th:replace="/common/template :: script"></script>
+<script type="text/javascript">
+</script>
+</body>
+</html>

+ 50 - 0
manager/src/main/resources/templates/sys/notify/emailedit.html

@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org">
+
+<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})"></head>
+
+<body>
+<div class="layui-form timo-compile">
+    <form th:action="@{/api/sys/notify/email}">
+        <input type="hidden" name="id" th:value="${emailAccount?.id}"/>
+        <div class="layui-form-item">
+            <label class="layui-form-label required">账户 ID</label>
+            <div class="layui-input-inline">
+                <input class="layui-input" type="text" name="notifyAccountId" placeholder="请输入账户 ID" required th:value="${emailAccount?.notifyAccountId}">
+            </div>
+        </div>
+        <div class="layui-form-item">
+            <label class="layui-form-label required">用户名</label>
+            <div class="layui-input-inline">
+                <input class="layui-input" type="text" name="username" placeholder="请输入用户名" required th:value="${emailAccount?.username}">
+            </div>
+        </div>
+        <div class="layui-form-item">
+            <label class="layui-form-label required">密码</label>
+            <div class="layui-input-inline">
+                <input class="layui-input" type="text" name="password" placeholder="请输入密码" required th:value="${emailAccount?.password}">
+            </div>
+        </div>
+        <div class="layui-form-item">
+            <label class="layui-form-label required">SMTP</label>
+            <div class="layui-input-inline">
+                <input class="layui-input" type="text" name="smtp" placeholder="请输入 SMTP 地址" required th:value="${emailAccount?.smtp}">
+            </div>
+        </div>
+        <div class="layui-form-item">
+            <label class="layui-form-label required">发件人</label>
+            <div class="layui-input-inline">
+                <input class="layui-input" type="text" name="personal" placeholder="请输入发件人名字" required th:value="${emailAccount?.personal}">
+            </div>
+        </div>
+        <div class="layui-form-item timo-finally">
+            <button class="layui-btn ajax-submit"><i class="fa fa-check-circle"></i> 保存</button>
+            <button class="layui-btn btn-secondary close-popup"><i class="fa fa-times-circle"></i> 关闭</button>
+        </div>
+    </form>
+</div>
+<script th:replace="/common/template :: script"></script>
+<script type="text/javascript">
+</script>
+</body>
+</html>

+ 61 - 0
manager/src/main/resources/templates/sys/notify/receiver.html

@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org">
+<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})"></head>
+
+<body class="timo-layout-page">
+<div class="layui-card">
+    <div class="layui-card-header timo-card-header">
+        <span><i class="fa fa-bars"></i> 通知接收配置</span>
+        <i class="layui-icon layui-icon-refresh refresh-btn"></i>
+    </div>
+    <div class="layui-card-body">
+        <div class="layui-row timo-card-screen put-row">
+            <div class="pull-right screen-btn-group">
+                <div class="btn-group-right">
+                    <button class="layui-btn open-popup" data-title="添加接收者" th:attr="data-url=@{/sys/notify/receiver/add}"
+                            data-size="640,480">
+                        <i class="fa fa-plus"></i> 添加
+                    </button>
+                </div>
+            </div>
+        </div>
+        <div class="timo-table-wrap">
+            <table class="layui-table timo-table">
+                <thead>
+                <tr>
+                    <th class="timo-table-checkbox">
+                        <label class="timo-checkbox"><input type="checkbox">
+                            <i class="layui-icon layui-icon-ok"></i></label>
+                    </th>
+                    <th class="sortable" data-field="notifyType">通知类型</th>
+                    <th class="sortable" data-field="notifyName">通知名字</th>
+                    <th class="sortable" data-field="receiver">接收地址</th>
+                    <th>操作</th>
+                </tr>
+                </thead>
+                <tbody>
+                <tr th:each="item:${list}">
+                    <td><label class="timo-checkbox"><input type="checkbox" th:value="${item.id}">
+                        <i class="layui-icon layui-icon-ok"></i></label></td>
+                    <td th:text="${item.type}">通知类型</td>
+                    <td th:text="${item.name}">通知名字</td>
+                    <td th:text="${item.url}">接收地址</td>
+                    <td>
+                        <a class="open-popup" data-title="编辑" th:attr="data-url=@{'/sys/notify/receiver/edit/'+${item.name}}"
+                           data-size="640,480" href="#">编辑</a>
+                        <a class="ajax-delete" th:attr="data-msg='确定要删除 '+ ${item.name} + '?'"
+                           th:href="@{'/sys/notify/receiver/delete/' + ${item.name}}">删除</a>
+                    </td>
+                </tr>
+                </tbody>
+            </table>
+        </div>
+        <div th:replace="/common/fragment :: page"></div>
+    </div>
+</div>
+
+<script th:replace="/common/template :: script"></script>
+<script type="text/javascript">
+</script>
+</body>
+</html>

+ 38 - 0
manager/src/main/resources/templates/sys/notify/receiveradd.html

@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org">
+
+<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})"></head>
+
+<body>
+<div class="layui-form timo-compile">
+    <form th:action="@{/sys/notify/receiver/save}">
+        <div class="layui-form-item">
+            <label class="layui-form-label required">通知类型</label>
+            <div class="layui-input-inline">
+                <select name="type">
+                    <option value="webhook">webhook</option>
+                    <option value="email">email</option>
+                </select>
+            </div>
+        </div>
+        <div class="layui-form-item">
+            <label class="layui-form-label required">通知名字</label>
+            <div class="layui-input-inline">
+                <input class="layui-input" type="text" name="name" placeholder="请输入通知名字" required>
+            </div>
+        </div>
+        <div class="layui-form-item">
+            <label class="layui-form-label required">接收者地址</label>
+            <div class="layui-input-inline">
+                <input class="layui-input" type="text" name="url" placeholder="请输入接收组者地址" required>
+            </div>
+        </div>
+        <div class="layui-form-item timo-finally">
+            <button class="layui-btn ajax-submit"><i class="fa fa-check-circle"></i> 保存</button>
+            <button class="layui-btn btn-secondary close-popup"><i class="fa fa-times-circle"></i> 关闭</button>
+        </div>
+    </form>
+</div>
+<script th:replace="/common/template :: script"></script>
+</body>
+</html>

+ 35 - 0
manager/src/main/resources/templates/sys/notify/receiveredit.html

@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org">
+
+<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})"></head>
+
+<body>
+<div class="layui-form timo-compile">
+    <form th:action="@{/sys/notify/receiver/save}">
+        <div class="layui-form-item">
+            <label class="layui-form-label required">通知类型</label>
+            <div class="layui-input-inline">
+                <input class="layui-input" type="text" name="type" required readonly th:value="${notifyReceiver.type}">
+            </div>
+        </div>
+        <div class="layui-form-item">
+            <label class="layui-form-label required">通知名字</label>
+            <div class="layui-input-inline">
+                <input class="layui-input" type="text" name="name" required th:value="${notifyReceiver.name}">
+            </div>
+        </div>
+        <div class="layui-form-item">
+            <label class="layui-form-label required">接收者地址</label>
+            <div class="layui-input-inline">
+                <input class="layui-input" type="text" name="url" required th:value="${notifyReceiver.url}">
+            </div>
+        </div>
+        <div class="layui-form-item timo-finally">
+            <button class="layui-btn ajax-submit"><i class="fa fa-check-circle"></i> 保存</button>
+            <button class="layui-btn btn-secondary close-popup"><i class="fa fa-times-circle"></i> 关闭</button>
+        </div>
+    </form>
+</div>
+<script th:replace="/common/template :: script"></script>
+</body>
+</html>

+ 30 - 3
manager/src/test/java/AppConfigTest.java

@@ -4,9 +4,13 @@ import cn.reghao.devops.manager.app.db.repository.AppDeployingRepository;
 import cn.reghao.devops.manager.app.db.repository.config.AppConfigRepository;
 import cn.reghao.devops.manager.app.db.repository.config.AppDeployConfigRepository;
 import cn.reghao.devops.manager.app.model.po.AppBuilding;
-import cn.reghao.devops.manager.notification.NotifyService;
-import cn.reghao.devops.manager.notification.notifier.ding.DingMsg;
-import cn.reghao.devops.manager.notification.notifier.email.EmailMsg;
+import cn.reghao.devops.manager.notification.service.NotifyService;
+import cn.reghao.devops.manager.notification.db.repository.EmailAccountRepository;
+import cn.reghao.devops.manager.notification.db.repository.NotifyReceiverRepository;
+import cn.reghao.devops.manager.notification.model.po.EmailAccount;
+import cn.reghao.devops.manager.notification.model.po.NotifyReceiver;
+import cn.reghao.devops.manager.notification.service.notifier.ding.DingMsg;
+import cn.reghao.devops.manager.notification.service.notifier.email.EmailMsg;
 import cn.reghao.devops.manager.util.ConsulNode;
 import cn.reghao.devops.manager.util.ConsulService;
 import lombok.extern.slf4j.Slf4j;
@@ -28,6 +32,29 @@ import java.util.List;
 @SpringBootTest(classes = ManagerApplication.class)
 @RunWith(SpringRunner.class)
 public class AppConfigTest {
+    @Autowired
+    NotifyReceiverRepository notifyReceiverRepository;
+    @Autowired
+    EmailAccountRepository emailAccountRepository;
+
+    @Test
+    public void initNotifyTest() throws InterruptedException {
+        NotifyReceiver notifyReceiver = new NotifyReceiver();
+        notifyReceiver.setName("ding-msgbot");
+        notifyReceiver.setType("webhook");
+        notifyReceiver.setUrl("https://oapi.dingtalk.com/robot/send?access_token=2ede844511f6a12a0429a25585222ef1f0eb99094421ea4b3155f17fda0f4662");
+        notifyReceiverRepository.save(notifyReceiver);
+
+        EmailAccount emailAccount = new EmailAccount();
+        emailAccount.setSmtp("smtp.163.com");
+        emailAccount.setUsername("gisgit@163.com");
+        emailAccount.setPassword("sirHdeKYn4PHcMP9");
+        emailAccount.setPersonal("admin@devops");
+        emailAccountRepository.save(emailAccount);
+
+    }
+
+
     @Autowired
     NotifyService notifyService;
     @Test