mirror of
https://gitee.com/goploy/goploy.git
synced 2024-11-29 10:47:39 +08:00
Added: notification template
This commit is contained in:
parent
76232013a6
commit
5c24cb9d50
16
CHANGELOG.md
16
CHANGELOG.md
@ -4,6 +4,22 @@ All notable changes to the "goploy" extension will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||
|
||||
## [1.17.2] - 2024-06-12
|
||||
|
||||
### Added
|
||||
|
||||
- notification template
|
||||
|
||||
|
||||
### Changed
|
||||
|
||||
- router order
|
||||
|
||||
### Bug fixed
|
||||
|
||||
- fix unknown driver
|
||||
- fix deploy page css
|
||||
|
||||
## [1.17.1] - 2024-06-06
|
||||
|
||||
### Changed
|
||||
|
7
build.sh
7
build.sh
@ -23,16 +23,19 @@ then
|
||||
fi
|
||||
|
||||
|
||||
echo "Building goploy";
|
||||
|
||||
echo "env GOOS=linux go build -o goploy cmd/server/main.go";
|
||||
env GOOS=linux go build -o goploy cmd/server/main.go
|
||||
|
||||
echo "env GOOS=linux GOARCH=arm64 go build -o goploy_arm64 cmd/server/main.go";
|
||||
env GOOS=linux GOARCH=arm64 go build -o goploy_arm64 cmd/server/main.go
|
||||
|
||||
echo "env GOOS=darwin GOARCH=arm64 go build -o goploy_arm64.mac cmd/server/main.go";
|
||||
env GOOS=darwin GOARCH=arm64 go build -o goploy_arm64.mac cmd/server/main.go
|
||||
|
||||
echo "env GOOS=darwin go build -o goploy.mac cmd/server/main.go";
|
||||
env GOOS=darwin go build -o goploy.mac cmd/server/main.go
|
||||
|
||||
echo "env GOOS=windows go build -o goploy.exe cmd/server/main.go";
|
||||
env GOOS=windows go build -o goploy.exe cmd/server/main.go
|
||||
|
||||
|
||||
|
73
cmd/server/api/notification/handler.go
Normal file
73
cmd/server/api/notification/handler.go
Normal file
@ -0,0 +1,73 @@
|
||||
// Copyright 2022 The Goploy Authors. All rights reserved.
|
||||
// Use of this source code is governed by a GPLv3-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package notification
|
||||
|
||||
import (
|
||||
"github.com/zhenorzz/goploy/cmd/server/api"
|
||||
"github.com/zhenorzz/goploy/cmd/server/api/middleware"
|
||||
"github.com/zhenorzz/goploy/config"
|
||||
"github.com/zhenorzz/goploy/internal/model"
|
||||
"github.com/zhenorzz/goploy/internal/server"
|
||||
"github.com/zhenorzz/goploy/internal/server/response"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type Notification api.API
|
||||
|
||||
func (n Notification) Handler() []server.Route {
|
||||
return []server.Route{
|
||||
server.NewRoute("/notification/getList", http.MethodGet, n.GetList).Permissions(config.ShowNotificationPage),
|
||||
server.NewRoute("/notification/edit", http.MethodPut, n.Edit).Permissions(config.EditNotification).LogFunc(middleware.AddOPLog),
|
||||
}
|
||||
}
|
||||
|
||||
// GetList lists notification template
|
||||
// @Summary List notification template
|
||||
// @Tags Notification
|
||||
// @Produce json
|
||||
// @Security ApiKeyHeader || ApiKeyQueryParam || NamespaceHeader || NamespaceQueryParam
|
||||
// @Success 200 {object} response.JSON{data=notification.GetList.RespData}
|
||||
// @Router /notification/getList [get]
|
||||
func (Notification) GetList(*server.Goploy) server.Response {
|
||||
list, err := model.NotificationTemplate{}.GetList()
|
||||
if err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
|
||||
type RespData struct {
|
||||
List model.NotificationTemplates `json:"list"`
|
||||
}
|
||||
|
||||
return response.JSON{
|
||||
Data: RespData{List: list},
|
||||
}
|
||||
}
|
||||
|
||||
// Edit edits the notification template
|
||||
// @Summary Edit the notification template
|
||||
// @Tags Notification
|
||||
// @Produce json
|
||||
// @Security ApiKeyHeader || ApiKeyQueryParam || NamespaceHeader || NamespaceQueryParam
|
||||
// @Param request body notification.Edit.ReqData true "body params"
|
||||
// @Success 200 {object} response.JSON
|
||||
// @Router /notification/edit [put]
|
||||
func (Notification) Edit(gp *server.Goploy) server.Response {
|
||||
type ReqData struct {
|
||||
ID int64 `json:"id" validate:"required,gt=0"`
|
||||
Title string `json:"title" validate:"required"`
|
||||
Template string `json:"template" validate:"required"`
|
||||
}
|
||||
var reqData ReqData
|
||||
if err := gp.Decode(&reqData); err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
|
||||
err := model.NotificationTemplate{ID: reqData.ID, Title: reqData.Title, Template: reqData.Template}.EditRow()
|
||||
if err != nil {
|
||||
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||
}
|
||||
|
||||
return response.JSON{}
|
||||
}
|
@ -16,6 +16,7 @@ import (
|
||||
logApi "github.com/zhenorzz/goploy/cmd/server/api/log"
|
||||
"github.com/zhenorzz/goploy/cmd/server/api/monitor"
|
||||
"github.com/zhenorzz/goploy/cmd/server/api/namespace"
|
||||
"github.com/zhenorzz/goploy/cmd/server/api/notification"
|
||||
"github.com/zhenorzz/goploy/cmd/server/api/project"
|
||||
"github.com/zhenorzz/goploy/cmd/server/api/repository"
|
||||
"github.com/zhenorzz/goploy/cmd/server/api/role"
|
||||
@ -49,7 +50,7 @@ var (
|
||||
s string
|
||||
)
|
||||
|
||||
const appVersion = "1.17.1"
|
||||
const appVersion = "1.17.2"
|
||||
|
||||
func init() {
|
||||
flag.StringVar(&config.AssetDir, "asset-dir", "", "default: ./")
|
||||
@ -64,7 +65,7 @@ func init() {
|
||||
}
|
||||
|
||||
// @title Goploy
|
||||
// @version 1.17.1
|
||||
// @version 1.17.2
|
||||
// @description A web deployment system tool!
|
||||
// @contact.name zhenorzz
|
||||
// @contact.url https://github.com/zhenorzz/goploy
|
||||
@ -130,6 +131,7 @@ func main() {
|
||||
srv.Router.Register(cron.Cron{})
|
||||
srv.Router.Register(agent.Agent{})
|
||||
srv.Router.Register(template.Template{})
|
||||
srv.Router.Register(notification.Notification{})
|
||||
srv.Router.Register(ws.GetHub())
|
||||
go func() {
|
||||
c := make(chan os.Signal, 1)
|
||||
@ -188,9 +190,9 @@ func install() {
|
||||
println("Start to install the database...")
|
||||
|
||||
// open connection without database
|
||||
runner, err := model.Open(config.DBConfig{
|
||||
Host: cfg.DB.Host, User: cfg.DB.User, Password: cfg.DB.Password, Port: cfg.DB.Port,
|
||||
})
|
||||
dbConfig := cfg.DB
|
||||
dbConfig.Database = ""
|
||||
runner, err := model.Open(dbConfig)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -197,7 +197,6 @@ func (gsync *Gsync) exec() {
|
||||
log.Errorf(projectLogFormat, gsync.Project.ID, err)
|
||||
}
|
||||
gsync.notify(model.ProjectFail, err.Error())
|
||||
|
||||
}()
|
||||
|
||||
err = gsync.repoStage()
|
||||
|
@ -1,14 +1,8 @@
|
||||
package deploy
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/zhenorzz/goploy/internal/model"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"github.com/zhenorzz/goploy/internal/notify"
|
||||
)
|
||||
|
||||
// commit id
|
||||
@ -16,172 +10,18 @@ import (
|
||||
// server ip & name
|
||||
// deploy user name
|
||||
// deploy time
|
||||
func (gsync *Gsync) notify(deployState int, detail string) {
|
||||
func (gsync *Gsync) notify(deployState uint8, detail string) {
|
||||
if gsync.Project.NotifyType == 0 {
|
||||
return
|
||||
}
|
||||
serverList := ""
|
||||
for _, projectServer := range gsync.ProjectServers {
|
||||
if projectServer.Server.Name != projectServer.Server.IP {
|
||||
serverList += projectServer.Server.Name + "(" + projectServer.Server.IP + ")"
|
||||
} else {
|
||||
serverList += projectServer.Server.IP
|
||||
}
|
||||
serverList += ", "
|
||||
}
|
||||
serverList = strings.TrimRight(serverList, ", ")
|
||||
project := gsync.Project
|
||||
commitInfo := gsync.CommitInfo
|
||||
var err error
|
||||
var resp *http.Response
|
||||
if project.NotifyType == model.NotifyWeiXin {
|
||||
type markdown struct {
|
||||
Content string `json:"content"`
|
||||
}
|
||||
type message struct {
|
||||
Msgtype string `json:"msgtype"`
|
||||
Markdown markdown `json:"markdown"`
|
||||
}
|
||||
content := "Deploy: <font color=\"warning\">" + project.Name + "</font>\n"
|
||||
content += "Publisher: <font color=\"comment\">" + project.PublisherName + "</font>\n"
|
||||
content += "Author: <font color=\"comment\">" + commitInfo.Author + "</font>\n"
|
||||
if commitInfo.Tag != "" {
|
||||
content += "Tag: <font color=\"comment\">" + commitInfo.Tag + "</font>\n"
|
||||
}
|
||||
content += "Branch: <font color=\"comment\">" + commitInfo.Branch + "</font>\n"
|
||||
content += "CommitSHA: <font color=\"comment\">" + commitInfo.Commit + "</font>\n"
|
||||
content += "CommitMessage: <font color=\"comment\">" + commitInfo.Message + "</font>\n"
|
||||
content += "ServerList: <font color=\"comment\">" + serverList + "</font>\n"
|
||||
if deployState == model.ProjectFail {
|
||||
content += "State: <font color=\"red\">fail</font> \n"
|
||||
content += "> Detail: <font color=\"comment\">" + detail + "</font>"
|
||||
} else {
|
||||
content += "State: <font color=\"green\">success</font>"
|
||||
}
|
||||
|
||||
msg := message{
|
||||
Msgtype: "markdown",
|
||||
Markdown: markdown{
|
||||
Content: content,
|
||||
},
|
||||
}
|
||||
b, _ := json.Marshal(msg)
|
||||
resp, err = http.Post(project.NotifyTarget, "application/json", bytes.NewBuffer(b))
|
||||
} else if project.NotifyType == model.NotifyDingTalk {
|
||||
type markdown struct {
|
||||
Title string `json:"title"`
|
||||
Text string `json:"text"`
|
||||
}
|
||||
type message struct {
|
||||
Msgtype string `json:"msgtype"`
|
||||
Markdown markdown `json:"markdown"`
|
||||
}
|
||||
text := "#### Deploy:" + project.Name + " \n "
|
||||
text += "#### Publisher:" + project.PublisherName + " \n "
|
||||
text += "#### Author:" + commitInfo.Author + " \n "
|
||||
if commitInfo.Tag != "" {
|
||||
text += "#### Tag:" + commitInfo.Tag + " \n "
|
||||
}
|
||||
text += "#### Branch:" + commitInfo.Branch + " \n "
|
||||
text += "#### CommitSHA:" + commitInfo.Commit + " \n "
|
||||
text += "#### CommitMessage:" + commitInfo.Message + " \n "
|
||||
text += "#### ServerList:" + serverList + " \n "
|
||||
if deployState == model.ProjectFail {
|
||||
text += "#### State: <font color=\"red\">fail</font> \n "
|
||||
text += "> Detail: <font color=\"comment\">" + detail + "</font>"
|
||||
} else {
|
||||
text += "#### State: <font color=\"green\">success</font>"
|
||||
}
|
||||
_ = notify.Send(fmt.Sprintf("project%d-deploy", project.ID), notify.UseByDeploy, notify.DeployData{
|
||||
DeployState: deployState,
|
||||
Project: project,
|
||||
ProjectServers: gsync.ProjectServers,
|
||||
CommitInfo: gsync.CommitInfo,
|
||||
DeployDetail: detail,
|
||||
}, project.NotifyType, project.NotifyTarget)
|
||||
|
||||
msg := message{
|
||||
Msgtype: "markdown",
|
||||
Markdown: markdown{
|
||||
Title: project.Name,
|
||||
Text: text,
|
||||
},
|
||||
}
|
||||
b, _ := json.Marshal(msg)
|
||||
resp, err = http.Post(project.NotifyTarget, "application/json", bytes.NewBuffer(b))
|
||||
} else if project.NotifyType == model.NotifyFeiShu {
|
||||
type content struct {
|
||||
Text string `json:"text"`
|
||||
}
|
||||
type message struct {
|
||||
MsgType string `json:"msg_type"`
|
||||
Content content `json:"content"`
|
||||
}
|
||||
text := ""
|
||||
text += "Deploy:" + project.Name + "\n"
|
||||
text += "Publisher: " + project.PublisherName + "\n"
|
||||
text += "Author: " + commitInfo.Author + "\n"
|
||||
if commitInfo.Tag != "" {
|
||||
text += "Tag: " + commitInfo.Tag + "\n"
|
||||
}
|
||||
text += "Branch: " + commitInfo.Branch + "\n"
|
||||
text += "CommitSHA: " + commitInfo.Commit + "\n"
|
||||
text += "CommitMessage: " + commitInfo.Message + "\n"
|
||||
text += "ServerList: " + serverList + "\n"
|
||||
if deployState == model.ProjectFail {
|
||||
text += "State: fail\n "
|
||||
text += "Detail: " + detail
|
||||
} else {
|
||||
text += "State: success"
|
||||
}
|
||||
|
||||
msg := message{
|
||||
MsgType: "text",
|
||||
Content: content{
|
||||
Text: text,
|
||||
},
|
||||
}
|
||||
b, _ := json.Marshal(msg)
|
||||
resp, err = http.Post(project.NotifyTarget, "application/json", bytes.NewBuffer(b))
|
||||
} else if project.NotifyType == model.NotifyCustom {
|
||||
type message struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Data struct {
|
||||
ProjectID int64 `json:"projectId"`
|
||||
ProjectName string `json:"projectName"`
|
||||
Publisher string `json:"publisher"`
|
||||
Author string `json:"author"`
|
||||
Branch string `json:"branch"`
|
||||
Tag string `json:"tag"`
|
||||
CommitSHA string `json:"commitSHA"`
|
||||
CommitMessage string `json:"commitMessage"`
|
||||
ServerList string `json:"serverList"`
|
||||
} `json:"data"`
|
||||
}
|
||||
code := 0
|
||||
if deployState == model.ProjectFail {
|
||||
code = 1
|
||||
}
|
||||
msg := message{
|
||||
Code: code,
|
||||
Message: detail,
|
||||
}
|
||||
msg.Data.ProjectID = project.ID
|
||||
msg.Data.ProjectName = project.Name
|
||||
msg.Data.Publisher = project.PublisherName
|
||||
msg.Data.Author = commitInfo.Author
|
||||
msg.Data.Branch = commitInfo.Branch
|
||||
msg.Data.Tag = commitInfo.Tag
|
||||
msg.Data.CommitSHA = commitInfo.Commit
|
||||
msg.Data.CommitMessage = commitInfo.Message
|
||||
msg.Data.ServerList = serverList
|
||||
b, _ := json.Marshal(msg)
|
||||
resp, err = http.Post(project.NotifyTarget, "application/json", bytes.NewBuffer(b))
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("projectID: %d notify exec err: %s", project.ID, err))
|
||||
} else {
|
||||
responseData, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("projectID: %d notify read body err: %s", project.ID, err))
|
||||
} else {
|
||||
log.Trace(fmt.Sprintf("projectID: %d notify success: %s", project.ID, string(responseData)))
|
||||
}
|
||||
_ = resp.Body.Close()
|
||||
}
|
||||
}
|
||||
|
@ -270,9 +270,10 @@ func (gsync *Gsync) serverStage() error {
|
||||
for i := 0; i < len(gsync.ProjectServers); i++ {
|
||||
msg := <-ch
|
||||
if msg.state == model.ProjectFail {
|
||||
message += msg.serverName + " error message: " + msg.detail
|
||||
message += msg.serverName + " error message: " + msg.detail + ", "
|
||||
}
|
||||
}
|
||||
message = strings.TrimRight(message, ", ")
|
||||
close(ch)
|
||||
|
||||
if message != "" {
|
||||
|
@ -7,10 +7,12 @@ package task
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/zhenorzz/goploy/cmd/server/ws"
|
||||
"github.com/zhenorzz/goploy/internal/model"
|
||||
"github.com/zhenorzz/goploy/internal/monitor"
|
||||
"github.com/zhenorzz/goploy/internal/notify"
|
||||
"strconv"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
@ -98,12 +100,14 @@ func monitorTask() {
|
||||
monitorCache.errorTimes++
|
||||
log.Error("m " + m.Name + " encounter error, " + monitorErrorContent)
|
||||
if m.Times <= uint16(monitorCache.errorTimes) {
|
||||
if body, err := m.Notify(monitorErrorContent); err != nil {
|
||||
if err := notify.Send(fmt.Sprintf("monitor%d", m.ID), notify.UseByMonitor, notify.MonitorData{
|
||||
Monitor: m,
|
||||
ErrorMsg: monitorErrorContent,
|
||||
}, m.NotifyType, m.NotifyTarget); err != nil {
|
||||
log.Error("m " + m.Name + " notify error, " + err.Error())
|
||||
} else {
|
||||
monitorCache.errorTimes = 0
|
||||
monitorCache.silentCycle = 1
|
||||
log.Trace("m " + m.Name + " notify return " + body)
|
||||
_ = m.UpdateLatestErrorContent(monitorErrorContent)
|
||||
ws.Send(ws.Data{
|
||||
Type: ws.TypeMonitor,
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"fmt"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/zhenorzz/goploy/internal/model"
|
||||
"github.com/zhenorzz/goploy/internal/notify"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
@ -108,12 +109,11 @@ func serverMonitorTask() {
|
||||
}
|
||||
serverCaches[serverMonitor.ServerID] = server
|
||||
}
|
||||
body, err := serverMonitor.Notify(serverCaches[serverMonitor.ServerID], cycleValue)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("monitor task %d notify error, %s", serverMonitor.ID, err.Error()))
|
||||
} else {
|
||||
log.Trace(fmt.Sprintf("monitor task %d notify return %s", serverMonitor.ID, body))
|
||||
}
|
||||
_ = notify.Send(fmt.Sprintf("server-monitor%d", serverMonitor.ID), notify.UseByServerMonitor, notify.ServerMonitorData{
|
||||
Server: serverCaches[serverMonitor.ServerID],
|
||||
ServerMonitor: serverMonitor,
|
||||
CycleValue: cycleValue,
|
||||
}, serverMonitor.NotifyType, serverMonitor.NotifyTarget)
|
||||
}
|
||||
serverMonitorCaches[serverMonitor.ID] = monitorCache
|
||||
}
|
||||
|
@ -11,12 +11,11 @@ const (
|
||||
ShowSFTPLogPage = 4
|
||||
ShowTerminalLogPage = 5
|
||||
ShowTerminalRecord = 6
|
||||
Member = 7
|
||||
Setting = 7
|
||||
ShowMemberPage = 8
|
||||
AddMember = 9
|
||||
EditMember = 10
|
||||
DeleteMember = 11
|
||||
Namespace = 12
|
||||
ShowNamespacePage = 13
|
||||
AddNamespace = 14
|
||||
EditNamespace = 15
|
||||
@ -90,4 +89,6 @@ const (
|
||||
DeleteNginxConfig = 83
|
||||
UnbindServerProject = 84
|
||||
ManageRepository = 85
|
||||
ShowNotificationPage = 85
|
||||
EditNotification = 85
|
||||
)
|
||||
|
104
database/1.17.2.sql
Normal file
104
database/1.17.2.sql
Normal file
@ -0,0 +1,104 @@
|
||||
CREATE TABLE IF NOT EXISTS `notification_template` (
|
||||
`id` int unsigned auto_increment,
|
||||
`type` tinyint unsigned default 0 not null,
|
||||
`use_by` varchar(255) default '' not null,
|
||||
`title` varchar(255) default '' not null,
|
||||
`template` text not null,
|
||||
`insert_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 collate = utf8mb4_general_ci;
|
||||
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (86, 12, 'ShowNotificationPage', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (87, 12, 'EditNotification', 0, '');
|
||||
|
||||
UPDATE `permission` set `name` = 'Setting' WHERE `id` = 7;
|
||||
UPDATE `permission` set `pid` = 7 WHERE `pid` = 12;
|
||||
|
||||
DELETE FROM `permission` WHERE `id` = 12;
|
||||
|
||||
INSERT INTO goploy.notification_template (id, type, use_by, title, template) VALUES (1, 1, 'deploy', '{{ .Project.Name }}', 'Deploy: <font color="warning">{{ .Project.Name }}</font>
|
||||
Publisher: <font color="comment">{{ .Project.PublisherName }}</font>
|
||||
Author: <font color="comment">{{ .CommitInfo.Author }}</font>
|
||||
{{ if ne .CommitInfo.Tag }}Tag: <font color="comment">{{ .CommitInfo.Tag }}</font>{{ end }}
|
||||
Branch: <font color="comment">{{ .CommitInfo.Branch }}</font>
|
||||
CommitSHA: <font color="comment">{{ .CommitInfo.Commit }}</font>
|
||||
CommitMessage: <font color="comment">{{ .CommitInfo.Message }}</font>
|
||||
ServerList:<font color="comment">
|
||||
{{- range .ProjectServers}}
|
||||
{{- if ne .Server.Name .Server.IP}}
|
||||
{{- .Server.Name}}({{.Server.IP}})
|
||||
{{- else}}
|
||||
{{- .Server.IP}}
|
||||
{{- end}}
|
||||
{{- end}}
|
||||
</font>
|
||||
{{- if eq .DeployState 2 }}
|
||||
State: <font color="green">success</font>
|
||||
{{- else }}
|
||||
State: <font color="red">fail</font>
|
||||
{{- end }}
|
||||
{{- if ne .DeployDetail ""}}
|
||||
Detail: <font color="comment">{{.DeployDetail}}</font>
|
||||
{{- end }}');
|
||||
INSERT INTO goploy.notification_template (id, type, use_by, title, template) VALUES (2, 2, 'deploy', '{{ .Project.Name }}', '#### Deploy:{{ .Project.Name }}
|
||||
#### Publisher:{{ .Project.PublisherName }}
|
||||
#### Author:{{ .CommitInfo.Author }}
|
||||
#### {{ if ne .CommitInfo.Tag }}Tag: {{ .CommitInfo.Tag }}{{ end }}
|
||||
#### Branch:{{ .CommitInfo.Branch }}
|
||||
#### CommitSHA:{{ .CommitInfo.Commit }}
|
||||
#### CommitMessage: {{ .CommitInfo.Message }}
|
||||
#### ServerList:
|
||||
{{- range .ProjectServers}}
|
||||
{{- if ne .Server.Name .Server.IP}}
|
||||
{{- .Server.Name}}({{.Server.IP}})
|
||||
{{- else}}
|
||||
{{- .Server.IP}}
|
||||
{{- end}}
|
||||
{{- end}}
|
||||
####
|
||||
{{- if eq .DeployState 2 }}State: <font color="green">success</font>
|
||||
{{- else }}State: <font color="red">fail</font>
|
||||
{{- end }}
|
||||
{{- if ne .DeployDetail ""}}
|
||||
> Detail: <font color="comment">{{.DeployDetail}}</font>
|
||||
{{- end }}
|
||||
');
|
||||
INSERT INTO goploy.notification_template (id, type, use_by, title, template) VALUES (3, 3, 'deploy', 'Deploy: {{ .Project.Name }}', 'Publisher: {{ .Project.PublisherName }}
|
||||
Author: {{ .CommitInfo.Author }}
|
||||
{{ if ne .CommitInfo.Tag "" }}Tag: {{ .CommitInfo.Tag }}{{ end }}
|
||||
Branch: {{ .CommitInfo.Branch }}
|
||||
CommitSHA: {{ .CommitInfo.Commit }}
|
||||
CommitMessage: {{ .CommitInfo.Message }}
|
||||
ServerList:
|
||||
{{- range .ProjectServers}}
|
||||
{{- if ne .Server.Name .Server.IP}}
|
||||
{{- .Server.Name}}({{.Server.IP}}),
|
||||
{{- else}}
|
||||
{{- .Server.IP}},
|
||||
{{- end}}
|
||||
{{- end}}
|
||||
{{- if eq .DeployState 2 }}
|
||||
State: success
|
||||
{{- else }}
|
||||
State: fail
|
||||
{{- end }}
|
||||
{{- if ne .DeployDetail ""}}
|
||||
Detail: {{.DeployDetail }}
|
||||
{{- end }}');
|
||||
INSERT INTO goploy.notification_template (id, type, use_by, title, template) VALUES (4, 1, 'monitor', '{{ .Monitor.Name }}', 'Monitor: <font color="warning">{{ .Monitor.Name }}</font>
|
||||
> <font color="warning">can not access</font>
|
||||
> <font color="comment">{{ .ErrorMsg }}</font>');
|
||||
INSERT INTO goploy.notification_template (id, type, use_by, title, template) VALUES (5, 2, 'monitor', '{{ .Monitor.Name }}', '#### Monitor: {{ .Monitor.Name }} can not access
|
||||
{{ .ErrorMsg }}');
|
||||
INSERT INTO goploy.notification_template (id, type, use_by, title, template) VALUES (6, 3, 'monitor', '{{ .Monitor.Name }}', 'can not access
|
||||
detail: {{ .ErrorMsg }}');
|
||||
INSERT INTO goploy.notification_template (id, type, use_by, title, template) VALUES (7, 1, 'server_monitor', '{{ .Server.Name }} {{ .ServerMonitor.Item }} Warning', 'Server: {{ .Server.Name }}({{ .Server.Description }})
|
||||
Item: <font color="warning">{{ .ServerMonitor.Item }} warning</font>
|
||||
Event: {{ .ServerMonitor.Formula }} value: {{ .CycleValue }}, {{ .ServerMonitor.Operator }} {{ .ServerMonitor.Value }}');
|
||||
INSERT INTO goploy.notification_template (id, type, use_by, title, template) VALUES (8, 2, 'server_monitor', '{{ .Server.Name }} {{ .ServerMonitor.Item }} Warning', 'Server: {{ .Server.Name }}({{ .Server.Description }})
|
||||
Item: {{ .ServerMonitor.Item }} warning
|
||||
Event: {{ .ServerMonitor.Formula }} value: {{ .CycleValue }}, {{ .ServerMonitor.Operator }} {{ .ServerMonitor.Value }}');
|
||||
INSERT INTO goploy.notification_template (id, type, use_by, title, template) VALUES (9, 3, 'server_monitor', '{{ .Server.Name }} {{ .ServerMonitor.Item }} Warning', 'Server: {{ .Server.Name }}({{ .Server.Description }})
|
||||
Item: {{ .ServerMonitor.Item }} warning
|
||||
Event: {{ .ServerMonitor.Formula }} value: {{ .CycleValue }}, {{ .ServerMonitor.Operator }} {{ .ServerMonitor.Value }}');
|
@ -389,10 +389,21 @@ CREATE TABLE IF NOT EXISTS `terminal_log` (
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `notification_template` (
|
||||
`id` int unsigned auto_increment,
|
||||
`type` tinyint unsigned default 0 not null,
|
||||
`use_by` varchar(255) default '' not null,
|
||||
`title` varchar(255) default '' not null,
|
||||
`template` text not null,
|
||||
`insert_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 collate = utf8mb4_general_ci;
|
||||
|
||||
INSERT IGNORE INTO `user`(`id`, `account`, `password`, `name`, `contact`, `state`, `super_manager`) VALUES (1, 'admin', '$2a$10$89ZJ2xeJj35GOw11Qiucr.phaEZP4.kBX6aKTs7oWFp1xcGBBgijm', '超管', '', 1, 1);
|
||||
INSERT IGNORE INTO `namespace`(`id`, `name`) VALUES (1, 'goploy');
|
||||
INSERT IGNORE INTO `namespace_user`(`id`, `namespace_id`, `user_id`, `role_id`) VALUES (1, 1, 1, 0);
|
||||
INSERT IGNORE INTO `system_config` (`id`, `key`, `value`) VALUES (1, 'version', '1.17.1');
|
||||
INSERT IGNORE INTO `system_config` (`id`, `key`, `value`) VALUES (1, 'version', '1.17.2');
|
||||
INSERT IGNORE INTO `role`(`id`, `name`, `description`) VALUES (1, 'manager', '');
|
||||
INSERT IGNORE INTO `role`(`id`, `name`, `description`) VALUES (2, 'member', '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (1, 0, 'Log', 0, '');
|
||||
@ -401,22 +412,21 @@ INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALU
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (4, 1, 'ShowSFTPLogPage', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (5, 1, 'ShowTerminalLogPage', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (6, 1, 'ShowTerminalRecord', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (7, 0, 'Member', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (7, 0, 'Setting', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (8, 7, 'ShowMemberPage', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (9, 7, 'AddMember', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (10, 7, 'EditMember', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (11, 7, 'DeleteMember', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (12, 0, 'Namespace', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (13, 12, 'ShowNamespacePage', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (14, 12, 'AddNamespace', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (15, 12, 'EditNamespace', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (16, 12, 'AddNamespaceUser', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (17, 12, 'DeleteNamespaceUser', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (18, 12, 'ShowRolePage', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (19, 12, 'AddRole', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (20, 12, 'EditRole', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (21, 12, 'DeleteRole', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (22, 12, 'EditPermission', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (13, 7, 'ShowNamespacePage', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (14, 7, 'AddNamespace', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (15, 7, 'EditNamespace', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (16, 7, 'AddNamespaceUser', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (17, 7, 'DeleteNamespaceUser', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (18, 7, 'ShowRolePage', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (19, 7, 'AddRole', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (20, 7, 'EditRole', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (21, 7, 'DeleteRole', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (22, 7, 'EditPermission', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (23, 0, 'Server', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (24, 23, 'ShowServerPage', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (25, 23, 'AddServer', 0, '');
|
||||
@ -479,6 +489,9 @@ INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALU
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (83, 23, 'DeleteNginxConfig', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (84, 23, 'UnbindServerProject', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (85, 43, 'ManageRepository', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (86, 7, 'ShowNotificationPage', 0, '');
|
||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (87, 7, 'EditNotification', 0, '');
|
||||
|
||||
INSERT IGNORE INTO `role_permission`(`role_id`, `permission_id`) VALUES (1, 14);
|
||||
INSERT IGNORE INTO `role_permission`(`role_id`, `permission_id`) VALUES (1, 15);
|
||||
INSERT IGNORE INTO `role_permission`(`role_id`, `permission_id`) VALUES (1, 16);
|
||||
@ -534,4 +547,90 @@ INSERT IGNORE INTO `role_permission`(`role_id`, `permission_id`) VALUES (2, 57);
|
||||
INSERT IGNORE INTO `role_permission`(`role_id`, `permission_id`) VALUES (2, 59);
|
||||
INSERT IGNORE INTO `role_permission`(`role_id`, `permission_id`) VALUES (2, 60);
|
||||
INSERT IGNORE INTO `role_permission`(`role_id`, `permission_id`) VALUES (2, 61);
|
||||
INSERT IGNORE INTO `role_permission`(`role_id`, `permission_id`) VALUES (2, 67);
|
||||
INSERT IGNORE INTO `role_permission`(`role_id`, `permission_id`) VALUES (2, 67);
|
||||
|
||||
INSERT INTO `notification_template` (id, type, use_by, title, template) VALUES (1, 1, 'deploy', '{{ .Project.Name }}', 'Deploy: <font color="warning">{{ .Project.Name }}</font>
|
||||
Publisher: <font color="comment">{{ .Project.PublisherName }}</font>
|
||||
Author: <font color="comment">{{ .CommitInfo.Author }}</font>
|
||||
{{ if ne .CommitInfo.Tag }}Tag: <font color="comment">{{ .CommitInfo.Tag }}</font>{{ end }}
|
||||
Branch: <font color="comment">{{ .CommitInfo.Branch }}</font>
|
||||
CommitSHA: <font color="comment">{{ .CommitInfo.Commit }}</font>
|
||||
CommitMessage: <font color="comment">{{ .CommitInfo.Message }}</font>
|
||||
ServerList:<font color="comment">
|
||||
{{- range .ProjectServers}}
|
||||
{{- if ne .Server.Name .Server.IP}}
|
||||
{{- .Server.Name}}({{.Server.IP}})
|
||||
{{- else}}
|
||||
{{- .Server.IP}}
|
||||
{{- end}}
|
||||
{{- end}}
|
||||
</font>
|
||||
{{- if eq .DeployState 2 }}
|
||||
State: <font color="green">success</font>
|
||||
{{- else }}
|
||||
State: <font color="red">fail</font>
|
||||
{{- end }}
|
||||
{{- if ne .DeployDetail ""}}
|
||||
Detail: <font color="comment">{{.DeployDetail}}</font>
|
||||
{{- end }}');
|
||||
INSERT INTO `notification_template` (id, type, use_by, title, template) VALUES (2, 2, 'deploy', '{{ .Project.Name }}', '#### Deploy:{{ .Project.Name }}
|
||||
#### Publisher:{{ .Project.PublisherName }}
|
||||
#### Author:{{ .CommitInfo.Author }}
|
||||
#### {{ if ne .CommitInfo.Tag }}Tag: {{ .CommitInfo.Tag }}{{ end }}
|
||||
#### Branch:{{ .CommitInfo.Branch }}
|
||||
#### CommitSHA:{{ .CommitInfo.Commit }}
|
||||
#### CommitMessage: {{ .CommitInfo.Message }}
|
||||
#### ServerList:
|
||||
{{- range .ProjectServers}}
|
||||
{{- if ne .Server.Name .Server.IP}}
|
||||
{{- .Server.Name}}({{.Server.IP}})
|
||||
{{- else}}
|
||||
{{- .Server.IP}}
|
||||
{{- end}}
|
||||
{{- end}}
|
||||
####
|
||||
{{- if eq .DeployState 2 }}State: <font color="green">success</font>
|
||||
{{- else }}State: <font color="red">fail</font>
|
||||
{{- end }}
|
||||
{{- if ne .DeployDetail ""}}
|
||||
> Detail: <font color="comment">{{.DeployDetail}}</font>
|
||||
{{- end }}
|
||||
');
|
||||
INSERT INTO `notification_template` (id, type, use_by, title, template) VALUES (3, 3, 'deploy', 'Deploy: {{ .Project.Name }}', 'Publisher: {{ .Project.PublisherName }}
|
||||
Author: {{ .CommitInfo.Author }}
|
||||
{{ if ne .CommitInfo.Tag "" }}Tag: {{ .CommitInfo.Tag }}{{ end }}
|
||||
Branch: {{ .CommitInfo.Branch }}
|
||||
CommitSHA: {{ .CommitInfo.Commit }}
|
||||
CommitMessage: {{ .CommitInfo.Message }}
|
||||
ServerList:
|
||||
{{- range .ProjectServers}}
|
||||
{{- if ne .Server.Name .Server.IP}}
|
||||
{{- .Server.Name}}({{.Server.IP}}),
|
||||
{{- else}}
|
||||
{{- .Server.IP}},
|
||||
{{- end}}
|
||||
{{- end}}
|
||||
{{- if eq .DeployState 2 }}
|
||||
State: success
|
||||
{{- else }}
|
||||
State: fail
|
||||
{{- end }}
|
||||
{{- if ne .DeployDetail ""}}
|
||||
Detail: {{.DeployDetail }}
|
||||
{{- end }}');
|
||||
INSERT INTO `notification_template` (id, type, use_by, title, template) VALUES (4, 1, 'monitor', '{{ .Monitor.Name }}', 'Monitor: <font color="warning">{{ .Monitor.Name }}</font>
|
||||
> <font color="warning">can not access</font>
|
||||
> <font color="comment">{{ .ErrorMsg }}</font>');
|
||||
INSERT INTO `notification_template` (id, type, use_by, title, template) VALUES (5, 2, 'monitor', '{{ .Monitor.Name }}', '#### Monitor: {{ .Monitor.Name }} can not access
|
||||
{{ .ErrorMsg }}');
|
||||
INSERT INTO `notification_template` (id, type, use_by, title, template) VALUES (6, 3, 'monitor', '{{ .Monitor.Name }}', 'can not access
|
||||
detail: {{ .ErrorMsg }}');
|
||||
INSERT INTO `notification_template` (id, type, use_by, title, template) VALUES (7, 1, 'server_monitor', '{{ .Server.Name }} {{ .ServerMonitor.Item }} Warning', 'Server: {{ .Server.Name }}({{ .Server.Description }})
|
||||
Item: <font color="warning">{{ .ServerMonitor.Item }} warning</font>
|
||||
Event: {{ .ServerMonitor.Formula }} value: {{ .CycleValue }}, {{ .ServerMonitor.Operator }} {{ .ServerMonitor.Value }}');
|
||||
INSERT INTO `notification_template` (id, type, use_by, title, template) VALUES (8, 2, 'server_monitor', '{{ .Server.Name }} {{ .ServerMonitor.Item }} Warning', 'Server: {{ .Server.Name }}({{ .Server.Description }})
|
||||
Item: {{ .ServerMonitor.Item }} warning
|
||||
Event: {{ .ServerMonitor.Formula }} value: {{ .CycleValue }}, {{ .ServerMonitor.Operator }} {{ .ServerMonitor.Value }}');
|
||||
INSERT INTO `notification_template` (id, type, use_by, title, template) VALUES (9, 3, 'server_monitor', '{{ .Server.Name }} {{ .ServerMonitor.Item }} Warning', 'Server: {{ .Server.Name }}({{ .Server.Description }})
|
||||
Item: {{ .ServerMonitor.Item }} warning
|
||||
Event: {{ .ServerMonitor.Formula }} value: {{ .CycleValue }}, {{ .ServerMonitor.Operator }} {{ .ServerMonitor.Value }}');
|
@ -1,7 +1,7 @@
|
||||
# Import sql manually https://github.com/zhenorzz/goploy/blob/master/model/sql/goploy.sql
|
||||
FROM alpine
|
||||
LABEL maintainer="zhenorzz@gmail.com"
|
||||
ARG GOPLOY_VER=v1.17.1
|
||||
ARG GOPLOY_VER=v1.17.2
|
||||
ENV GOPLOY_VER=${GOPLOY_VER}
|
||||
|
||||
RUN echo "https://mirrors.aliyun.com/alpine/latest-stable/main/" > /etc/apk/repositories
|
||||
|
@ -5,10 +5,7 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
sq "github.com/Masterminds/squirrel"
|
||||
@ -237,106 +234,3 @@ func (m Monitor) UpdateLatestErrorContent(errorContent string) error {
|
||||
Exec()
|
||||
return err
|
||||
}
|
||||
|
||||
func (m Monitor) Notify(errMsg string) (string, error) {
|
||||
var err error
|
||||
var resp *http.Response
|
||||
if m.NotifyType == NotifyWeiXin {
|
||||
type markdown struct {
|
||||
Content string `json:"content"`
|
||||
}
|
||||
type message struct {
|
||||
Msgtype string `json:"msgtype"`
|
||||
Markdown markdown `json:"markdown"`
|
||||
}
|
||||
content := "Monitor: <font color=\"warning\">" + m.Name + "</font>\n "
|
||||
content += "> <font color=\"warning\">can not access</font> \n "
|
||||
content += "> <font color=\"comment\">" + errMsg + "</font> \n "
|
||||
|
||||
msg := message{
|
||||
Msgtype: "markdown",
|
||||
Markdown: markdown{
|
||||
Content: content,
|
||||
},
|
||||
}
|
||||
b, _ := json.Marshal(msg)
|
||||
resp, err = http.Post(m.NotifyTarget, "application/json", bytes.NewBuffer(b))
|
||||
} else if m.NotifyType == NotifyDingTalk {
|
||||
type markdown struct {
|
||||
Title string `json:"title"`
|
||||
Text string `json:"text"`
|
||||
}
|
||||
type message struct {
|
||||
Msgtype string `json:"msgtype"`
|
||||
Markdown markdown `json:"markdown"`
|
||||
}
|
||||
text := "#### Monitor: " + m.Name + " can not access \n >" + errMsg
|
||||
|
||||
msg := message{
|
||||
Msgtype: "markdown",
|
||||
Markdown: markdown{
|
||||
Title: m.Name,
|
||||
Text: text,
|
||||
},
|
||||
}
|
||||
b, _ := json.Marshal(msg)
|
||||
resp, err = http.Post(m.NotifyTarget, "application/json", bytes.NewBuffer(b))
|
||||
} else if m.NotifyType == NotifyFeiShu {
|
||||
type content struct {
|
||||
Text string `json:"text"`
|
||||
}
|
||||
type message struct {
|
||||
MsgType string `json:"msg_type"`
|
||||
Content content `json:"content"`
|
||||
}
|
||||
|
||||
text := m.Name + " can not access\n "
|
||||
text += "detail: " + errMsg
|
||||
|
||||
msg := message{
|
||||
MsgType: "text",
|
||||
Content: content{
|
||||
Text: text,
|
||||
},
|
||||
}
|
||||
b, _ := json.Marshal(msg)
|
||||
resp, err = http.Post(m.NotifyTarget, "application/json", bytes.NewBuffer(b))
|
||||
} else if m.NotifyType == NotifyCustom {
|
||||
type message struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Data struct {
|
||||
MonitorName string `json:"monitorName"`
|
||||
Type int `json:"type"`
|
||||
Target MonitorTarget `json:"target"`
|
||||
Second int `json:"second"`
|
||||
Times uint16 `json:"times"`
|
||||
Error string `json:"error"`
|
||||
} `json:"data"`
|
||||
}
|
||||
code := 0
|
||||
msg := message{
|
||||
Code: code,
|
||||
Message: m.Name + " can not access",
|
||||
}
|
||||
msg.Data.MonitorName = m.Name
|
||||
msg.Data.Type = m.Type
|
||||
msg.Data.Target = m.Target
|
||||
msg.Data.Second = m.Second
|
||||
msg.Data.Times = m.Times
|
||||
msg.Data.Error = errMsg
|
||||
b, _ := json.Marshal(msg)
|
||||
resp, err = http.Post(m.NotifyTarget, "application/json", bytes.NewBuffer(b))
|
||||
}
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
responseData, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
} else {
|
||||
return string(responseData), err
|
||||
}
|
||||
}
|
||||
|
112
internal/model/notification_template.go
Normal file
112
internal/model/notification_template.go
Normal file
@ -0,0 +1,112 @@
|
||||
// Copyright 2022 The Goploy Authors. All rights reserved.
|
||||
// Use of this source code is governed by a GPLv3-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
sq "github.com/Masterminds/squirrel"
|
||||
)
|
||||
|
||||
const notificationTemplateTable = "`notification_template`"
|
||||
|
||||
type NotificationTemplate struct {
|
||||
ID int64 `json:"id"`
|
||||
Type uint8 `json:"type"`
|
||||
UseBy string `json:"useBy"`
|
||||
Title string `json:"title"`
|
||||
Template string `json:"template"`
|
||||
InsertTime string `json:"insertTime,omitempty"`
|
||||
UpdateTime string `json:"updateTime,omitempty"`
|
||||
}
|
||||
|
||||
type NotificationTemplates []NotificationTemplate
|
||||
|
||||
func (nt NotificationTemplate) EditRow() error {
|
||||
_, err := sq.
|
||||
Update(notificationTemplateTable).
|
||||
Set("template", nt.Template).
|
||||
Set("title", nt.Title).
|
||||
Where(sq.Eq{"id": nt.ID}).
|
||||
RunWith(DB).
|
||||
Exec()
|
||||
return err
|
||||
}
|
||||
|
||||
func (nt NotificationTemplate) GetList() (NotificationTemplates, error) {
|
||||
rows, err := sq.
|
||||
Select("id, use_by, type, title, template, insert_time, update_time").
|
||||
From(notificationTemplateTable).
|
||||
OrderBy("id DESC").
|
||||
RunWith(DB).
|
||||
Query()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
notificationTemplates := NotificationTemplates{}
|
||||
for rows.Next() {
|
||||
var notificationTemplate NotificationTemplate
|
||||
|
||||
if err := rows.Scan(
|
||||
¬ificationTemplate.ID,
|
||||
¬ificationTemplate.UseBy,
|
||||
¬ificationTemplate.Type,
|
||||
¬ificationTemplate.Title,
|
||||
¬ificationTemplate.Template,
|
||||
¬ificationTemplate.InsertTime,
|
||||
¬ificationTemplate.UpdateTime); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
notificationTemplates = append(notificationTemplates, notificationTemplate)
|
||||
}
|
||||
|
||||
return notificationTemplates, nil
|
||||
}
|
||||
|
||||
func (nt NotificationTemplate) GetAll() (NotificationTemplates, error) {
|
||||
rows, err := sq.
|
||||
Select("id, use_by, type, template").
|
||||
From(notificationTemplateTable).
|
||||
OrderBy("id DESC").
|
||||
RunWith(DB).
|
||||
Query()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
notificationTemplates := NotificationTemplates{}
|
||||
for rows.Next() {
|
||||
var notificationTemplate NotificationTemplate
|
||||
|
||||
if err := rows.Scan(¬ificationTemplate.ID, ¬ificationTemplate.UseBy, ¬ificationTemplate.Type, ¬ificationTemplate.Template); err != nil {
|
||||
return notificationTemplates, err
|
||||
}
|
||||
notificationTemplates = append(notificationTemplates, notificationTemplate)
|
||||
}
|
||||
return notificationTemplates, nil
|
||||
}
|
||||
|
||||
func (nt NotificationTemplate) GetData() (NotificationTemplate, error) {
|
||||
var notificationTemplate NotificationTemplate
|
||||
err := sq.
|
||||
Select("use_by, type, template").
|
||||
From(notificationTemplateTable).
|
||||
Where(sq.Eq{"id": nt.ID}).
|
||||
RunWith(DB).
|
||||
QueryRow().
|
||||
Scan(¬ificationTemplate.UseBy, ¬ificationTemplate.Type, ¬ificationTemplate.Template)
|
||||
return notificationTemplate, err
|
||||
}
|
||||
|
||||
func (nt NotificationTemplate) GetTemplate() (NotificationTemplate, error) {
|
||||
var notificationTemplate NotificationTemplate
|
||||
err := sq.
|
||||
Select("title, template").
|
||||
From(notificationTemplateTable).
|
||||
Where(sq.Eq{"use_by": nt.UseBy}).
|
||||
Where(sq.Eq{"type": nt.Type}).
|
||||
RunWith(DB).
|
||||
QueryRow().
|
||||
Scan(¬ificationTemplate.Title, ¬ificationTemplate.Template)
|
||||
return notificationTemplate, err
|
||||
}
|
@ -5,13 +5,7 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
sq "github.com/Masterminds/squirrel"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
const serverMonitorTable = "`server_monitor`"
|
||||
@ -219,99 +213,3 @@ func (sm ServerMonitor) DeleteRow() error {
|
||||
Exec()
|
||||
return err
|
||||
}
|
||||
|
||||
func (sm ServerMonitor) Notify(server Server, cycleValue string) (string, error) {
|
||||
var err error
|
||||
var resp *http.Response
|
||||
if sm.NotifyType == NotifyWeiXin {
|
||||
type markdown struct {
|
||||
Content string `json:"content"`
|
||||
}
|
||||
type message struct {
|
||||
Msgtype string `json:"msgtype"`
|
||||
Markdown markdown `json:"markdown"`
|
||||
}
|
||||
content := fmt.Sprintf("Server: %s(%s)\n ", server.Name, server.Description)
|
||||
content += "Item: <font color=\"warning\">" + sm.Item + " warning</font>\n "
|
||||
content += fmt.Sprintf("Event: %s value: %s, %s %s \n ", sm.Formula, cycleValue, sm.Operator, sm.Value)
|
||||
|
||||
msg := message{
|
||||
Msgtype: "markdown",
|
||||
Markdown: markdown{
|
||||
Content: content,
|
||||
},
|
||||
}
|
||||
b, _ := json.Marshal(msg)
|
||||
resp, err = http.Post(sm.NotifyTarget, "application/json", bytes.NewBuffer(b))
|
||||
} else if sm.NotifyType == NotifyDingTalk {
|
||||
type markdown struct {
|
||||
Title string `json:"title"`
|
||||
Text string `json:"text"`
|
||||
}
|
||||
type message struct {
|
||||
Msgtype string `json:"msgtype"`
|
||||
Markdown markdown `json:"markdown"`
|
||||
}
|
||||
content := fmt.Sprintf("Server: %s(%s)\n ", server.Name, server.Description)
|
||||
content += "Item: " + sm.Item + "\n "
|
||||
content += fmt.Sprintf("Event: %s value: %s, %s %s \n ", sm.Formula, cycleValue, sm.Operator, sm.Value)
|
||||
|
||||
msg := message{
|
||||
Msgtype: "markdown",
|
||||
Markdown: markdown{
|
||||
Title: fmt.Sprintf("%s %s warning", server.Name, sm.Item),
|
||||
Text: content,
|
||||
},
|
||||
}
|
||||
b, _ := json.Marshal(msg)
|
||||
resp, err = http.Post(sm.NotifyTarget, "application/json", bytes.NewBuffer(b))
|
||||
} else if sm.NotifyType == NotifyFeiShu {
|
||||
type message struct {
|
||||
Title string `json:"title"`
|
||||
Text string `json:"text"`
|
||||
}
|
||||
|
||||
content := fmt.Sprintf("Server: %s(%s)\n ", server.Name, server.Description)
|
||||
content += "Item: " + sm.Item + "\n "
|
||||
content += fmt.Sprintf("Event: %s value: %s, %s %s \n ", sm.Formula, cycleValue, sm.Operator, sm.Value)
|
||||
|
||||
msg := message{
|
||||
Title: fmt.Sprintf("%s %s warning", server.Name, sm.Item),
|
||||
Text: content,
|
||||
}
|
||||
b, _ := json.Marshal(msg)
|
||||
resp, err = http.Post(sm.NotifyTarget, "application/json", bytes.NewBuffer(b))
|
||||
} else if sm.NotifyType == NotifyCustom {
|
||||
type message struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Data struct {
|
||||
Server Server `json:"server"`
|
||||
MonitorRule ServerMonitor `json:"monitorRule"`
|
||||
Value string `json:"value"`
|
||||
Time string `json:"time"`
|
||||
} `json:"data"`
|
||||
}
|
||||
code := 0
|
||||
msg := message{
|
||||
Code: code,
|
||||
Message: fmt.Sprintf("%s %s warning", server.Name, sm.Item),
|
||||
}
|
||||
msg.Data.Server = server
|
||||
msg.Data.MonitorRule = sm
|
||||
msg.Data.Value = cycleValue
|
||||
msg.Data.Time = time.Now().Format("2006-01-02 15:04:05")
|
||||
b, _ := json.Marshal(msg)
|
||||
resp, err = http.Post(sm.NotifyTarget, "application/json", bytes.NewBuffer(b))
|
||||
}
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
responseData, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
} else {
|
||||
return string(responseData), err
|
||||
}
|
||||
}
|
||||
|
167
internal/notify/notify.go
Normal file
167
internal/notify/notify.go
Normal file
@ -0,0 +1,167 @@
|
||||
package notify
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/zhenorzz/goploy/internal/model"
|
||||
"github.com/zhenorzz/goploy/internal/repo"
|
||||
"io"
|
||||
"net/http"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
type DeployData struct {
|
||||
DeployState uint8
|
||||
Project model.Project
|
||||
ProjectServers model.ProjectServers
|
||||
CommitInfo repo.CommitInfo
|
||||
DeployDetail string
|
||||
}
|
||||
|
||||
type MonitorData struct {
|
||||
Monitor model.Monitor
|
||||
ErrorMsg string
|
||||
}
|
||||
|
||||
type ServerMonitorData struct {
|
||||
Server model.Server
|
||||
ServerMonitor model.ServerMonitor
|
||||
CycleValue string
|
||||
}
|
||||
|
||||
const (
|
||||
UseByDeploy = "deploy"
|
||||
UseByMonitor = "monitor"
|
||||
UseByServerMonitor = "server_monitor"
|
||||
)
|
||||
|
||||
func Send(name string, useBy string, data any, notifyType uint8, notifyTarget string) error {
|
||||
if notifyType == model.NotifyCustom {
|
||||
type message struct {
|
||||
Data any `json:"data"`
|
||||
}
|
||||
msg := message{
|
||||
Data: data,
|
||||
}
|
||||
b, _ := json.Marshal(msg)
|
||||
_, err := http.Post(notifyTarget, "application/json", bytes.NewBuffer(b))
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("%s notify exec err: %s", name, err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
notificationData, err := model.NotificationTemplate{UseBy: useBy, Type: notifyType}.GetTemplate()
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("%s could not find notification template: %s", name, err))
|
||||
return err
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
|
||||
tmpl, err := template.New(name + "title").Parse(notificationData.Title)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("%s parse notification title error: %s", name, err))
|
||||
return err
|
||||
}
|
||||
|
||||
err = tmpl.Execute(&buf, data)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("%s execute notification title error: %s", name, err))
|
||||
return err
|
||||
}
|
||||
|
||||
title := buf.String()
|
||||
|
||||
tmpl, err = template.New(name + "template").Parse(notificationData.Template)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("%s parse notification template error: %s", name, err))
|
||||
return err
|
||||
}
|
||||
|
||||
buf.Reset()
|
||||
|
||||
err = tmpl.Execute(&buf, data)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("%s execute notification template error: %s", name, err))
|
||||
return err
|
||||
}
|
||||
|
||||
text := buf.String()
|
||||
|
||||
println(title)
|
||||
|
||||
println(text)
|
||||
|
||||
var resp *http.Response
|
||||
if notifyType == model.NotifyWeiXin {
|
||||
type markdown struct {
|
||||
Content string `json:"content"`
|
||||
}
|
||||
type message struct {
|
||||
Msgtype string `json:"msgtype"`
|
||||
Markdown markdown `json:"markdown"`
|
||||
}
|
||||
|
||||
text = title + "\n" + text
|
||||
msg := message{
|
||||
Msgtype: "markdown",
|
||||
Markdown: markdown{
|
||||
Content: text,
|
||||
},
|
||||
}
|
||||
b, _ := json.Marshal(msg)
|
||||
resp, err = http.Post(notifyTarget, "application/json", bytes.NewBuffer(b))
|
||||
} else if notifyType == model.NotifyDingTalk {
|
||||
type markdown struct {
|
||||
Title string `json:"title"`
|
||||
Text string `json:"text"`
|
||||
}
|
||||
type message struct {
|
||||
Msgtype string `json:"msgtype"`
|
||||
Markdown markdown `json:"markdown"`
|
||||
}
|
||||
msg := message{
|
||||
Msgtype: "markdown",
|
||||
Markdown: markdown{
|
||||
Title: title,
|
||||
Text: text,
|
||||
},
|
||||
}
|
||||
b, _ := json.Marshal(msg)
|
||||
resp, err = http.Post(notifyTarget, "application/json", bytes.NewBuffer(b))
|
||||
} else if notifyType == model.NotifyFeiShu {
|
||||
type content struct {
|
||||
Text string `json:"text"`
|
||||
}
|
||||
type message struct {
|
||||
MsgType string `json:"msg_type"`
|
||||
Content content `json:"content"`
|
||||
}
|
||||
text = title + "\n" + text
|
||||
msg := message{
|
||||
MsgType: "text",
|
||||
Content: content{
|
||||
Text: text,
|
||||
},
|
||||
}
|
||||
b, _ := json.Marshal(msg)
|
||||
resp, err = http.Post(notifyTarget, "application/json", bytes.NewBuffer(b))
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("%s notify exec err: %s", name, err))
|
||||
return err
|
||||
} else if resp != nil {
|
||||
responseData, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("%s notify read body err: %s", name, err))
|
||||
} else {
|
||||
log.Trace(fmt.Sprintf("%s notify success: %s", name, string(responseData)))
|
||||
}
|
||||
_ = resp.Body.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "goploy",
|
||||
"version": "1.17.1",
|
||||
"version": "1.17.2",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
33
web/src/api/notification.ts
Normal file
33
web/src/api/notification.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import { Request, ID } from './types'
|
||||
|
||||
export interface NotificationData {
|
||||
id: number
|
||||
useBy: string
|
||||
type: number
|
||||
title: string
|
||||
template: string
|
||||
insertTime: string
|
||||
updateTime: string
|
||||
}
|
||||
|
||||
export class NotificationList extends Request {
|
||||
readonly url = '/notification/getList'
|
||||
readonly method = 'get'
|
||||
|
||||
public declare datagram: {
|
||||
list: NotificationData[]
|
||||
}
|
||||
}
|
||||
|
||||
export class NotificationEdit extends Request {
|
||||
readonly url = '/notification/edit'
|
||||
readonly method = 'put'
|
||||
public param: {
|
||||
id: number
|
||||
template: string
|
||||
}
|
||||
constructor(param: NotificationEdit['param']) {
|
||||
super()
|
||||
this.param = param
|
||||
}
|
||||
}
|
1
web/src/icons/svg/notifySetting.svg
Normal file
1
web/src/icons/svg/notifySetting.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1717659845942" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6115" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M961.834667 89.045333a42.666667 42.666667 0 0 1 0 26.965334l-273.024 819.029333a42.666667 42.666667 0 0 1-78.336 6.186667l-180.437334-347.392-347.392-180.48a42.666667 42.666667 0 0 1 6.186667-78.293334l819.029333-273.024a42.666667 42.666667 0 0 1 53.973334 27.008z m-107.946667 80.938667L211.498667 384.085333l244.181333 126.890667a21.248 21.248 0 0 1 5.162667-8.277333l90.496-90.496a21.333333 21.333333 0 0 1 30.165333 0l30.208 30.165333a21.333333 21.333333 0 0 1 0 30.165333l-90.538667 90.496a21.248 21.248 0 0 1-8.32 5.12l126.890667 244.224 214.186667-642.389333z" fill="#000000" opacity=".65" p-id="6116"></path></svg>
|
After Width: | Height: | Size: 955 B |
@ -1,4 +1,5 @@
|
||||
{
|
||||
"title": "Title",
|
||||
"default": "Default",
|
||||
"select": "Select",
|
||||
"name": "Name",
|
||||
@ -171,9 +172,11 @@
|
||||
"serverCrontab": "Crontab UI",
|
||||
"serverCron": "Cron",
|
||||
"serverNginx": "Nginx",
|
||||
"namespace": "Namespace",
|
||||
"setting": "Setting",
|
||||
"namespaceSetting": "NS setting",
|
||||
"roleSetting": "Role setting",
|
||||
"memberSetting": "Member setting",
|
||||
"notificationSetting": "Notify setting",
|
||||
"member": "Member",
|
||||
"log": "Log",
|
||||
"loginLog": "Login log",
|
||||
|
@ -1,4 +1,5 @@
|
||||
{
|
||||
"title": "标题",
|
||||
"default": "默认",
|
||||
"select": "选择",
|
||||
"name": "名称",
|
||||
@ -153,9 +154,11 @@
|
||||
"serverCrontab": "Crontab UI",
|
||||
"serverCron": "定时任务",
|
||||
"serverNginx": "Nginx管理",
|
||||
"namespace": "空间",
|
||||
"setting": "设置",
|
||||
"namespaceSetting": "空间设置",
|
||||
"roleSetting": "角色设置",
|
||||
"memberSetting": "成员设置",
|
||||
"notificationSetting": "推送设置",
|
||||
"member": "成员设置",
|
||||
"log": "日志",
|
||||
"loginLog": "登录日志",
|
||||
@ -171,7 +174,7 @@
|
||||
"ShowSFTPLogPage": "查看SFTP日志",
|
||||
"ShowTerminalLogPage": "查看终端日志",
|
||||
"ShowTerminalRecord": "查看终端录屏",
|
||||
"Member": "成员管理",
|
||||
"Setting": "设置",
|
||||
"ShowMemberPage": "查看成员设置",
|
||||
"AddMember": "新增成员",
|
||||
"EditMember": "编辑成员",
|
||||
@ -186,6 +189,8 @@
|
||||
"AddRole": "新增角色",
|
||||
"EditRole": "编辑角色",
|
||||
"DeleteRole": "删除角色",
|
||||
"ShowNotificationPage": "查看推送设置",
|
||||
"EditNotification": "编辑推送设置",
|
||||
"EditPermission": "编辑角色权限",
|
||||
"Server": "服务器管理",
|
||||
"ShowServerPage": "查看服务器设置",
|
||||
|
@ -5,12 +5,11 @@ export default Object.freeze({
|
||||
ShowSFTPLogPage: 4,
|
||||
ShowTerminalLogPage: 5,
|
||||
ShowTerminalRecord: 6,
|
||||
Member: 7,
|
||||
Setting: 7,
|
||||
ShowMemberPage: 8,
|
||||
AddMember: 9,
|
||||
EditMember: 10,
|
||||
DeleteMember: 11,
|
||||
Namespace: 12,
|
||||
ShowNamespacePage: 13,
|
||||
AddNamespace: 14,
|
||||
EditNamespace: 15,
|
||||
@ -84,4 +83,6 @@ export default Object.freeze({
|
||||
DeleteNginxConfig: 83,
|
||||
UnbindServerProject: 84,
|
||||
ManageRepository: 85,
|
||||
ShowNotificationPage: 86,
|
||||
EditNotification: 87,
|
||||
})
|
||||
|
@ -169,19 +169,19 @@ export default <RouteRecordRaw[]>[
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/namespace',
|
||||
path: '/setting',
|
||||
component: Layout,
|
||||
redirect: '/namespace/index',
|
||||
name: 'namespace',
|
||||
redirect: '/setting/namespace',
|
||||
name: 'setting',
|
||||
meta: {
|
||||
title: 'namespace',
|
||||
icon: 'namespace',
|
||||
title: 'setting',
|
||||
icon: 'setting',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
name: 'NamespaceIndex',
|
||||
component: () => import('@/views/namespace/index.vue'),
|
||||
path: 'namespace',
|
||||
name: 'NamespaceSetting',
|
||||
component: () => import('@/views/setting/namespace.vue'),
|
||||
meta: {
|
||||
title: 'namespaceSetting',
|
||||
icon: 'namespaceSetting',
|
||||
@ -190,36 +190,34 @@ export default <RouteRecordRaw[]>[
|
||||
},
|
||||
{
|
||||
path: 'role',
|
||||
name: 'NamespaceRole',
|
||||
component: () => import('@/views/namespace/role.vue'),
|
||||
name: 'RoleSetting',
|
||||
component: () => import('@/views/setting/role.vue'),
|
||||
meta: {
|
||||
title: 'roleSetting',
|
||||
icon: 'roleSetting',
|
||||
permissions: [permission.ShowRolePage],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/member',
|
||||
component: Layout,
|
||||
redirect: '/member/index',
|
||||
name: 'member',
|
||||
meta: {
|
||||
title: 'member',
|
||||
icon: 'user',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
name: 'MemberIndex',
|
||||
component: () => import('@/views/member/index.vue'),
|
||||
path: 'member',
|
||||
name: 'MemberSetting',
|
||||
component: () => import('@/views/setting/member.vue'),
|
||||
meta: {
|
||||
title: 'member',
|
||||
title: 'memberSetting',
|
||||
icon: 'user',
|
||||
permissions: [permission.ShowMemberPage],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'notification',
|
||||
name: 'NotificationSetting',
|
||||
component: () => import('@/views/setting/notification.vue'),
|
||||
meta: {
|
||||
title: 'notificationSetting',
|
||||
icon: 'notifySetting',
|
||||
permissions: [permission.ShowNotificationPage],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -111,7 +111,7 @@
|
||||
:href="row.name"
|
||||
target="_blank"
|
||||
:underline="false"
|
||||
class="card-title__text"
|
||||
class="card-title__link"
|
||||
style="color: inherit"
|
||||
>
|
||||
{{ row.name }}
|
||||
@ -292,6 +292,9 @@
|
||||
<el-row style="white-space: pre-wrap" v-html="publishFormProps.title" />
|
||||
</template>
|
||||
<el-row>
|
||||
<el-row v-if="selectedItem.deployState === DeployState.Uninitialized">
|
||||
{{ $t('initial') }}
|
||||
</el-row>
|
||||
<el-row
|
||||
v-for="(variable, index) in publishFormProps.customVariables"
|
||||
:key="index"
|
||||
@ -323,11 +326,13 @@
|
||||
>
|
||||
</el-input>
|
||||
</el-row>
|
||||
<el-row style="width: 100%">
|
||||
<el-row
|
||||
v-if="selectedItem.deployState !== DeployState.Uninitialized"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-checkbox
|
||||
v-model="publishFormProps.selectCommit"
|
||||
:label="`Select Commit (default lastest ${selectedItem.branch})`"
|
||||
:disabled="publishFormProps.selectTag"
|
||||
@change="handleSelectCommit"
|
||||
/>
|
||||
<el-row
|
||||
@ -338,7 +343,10 @@
|
||||
{{ publishFormProps.commit }}
|
||||
</el-row>
|
||||
</el-row>
|
||||
<el-row style="width: 100%; margin-top: 10px">
|
||||
<el-row
|
||||
v-if="selectedItem.deployState !== DeployState.Uninitialized"
|
||||
style="width: 100%; margin-top: 10px"
|
||||
>
|
||||
<el-checkbox
|
||||
v-model="publishFormProps.selectServer"
|
||||
:label="`Select Server (default all)`"
|
||||
@ -662,7 +670,7 @@ function handleRebuilt() {
|
||||
tableData.value[projectIndex].deployState = 1
|
||||
}
|
||||
|
||||
function handleSelectCommit(state) {
|
||||
function handleSelectCommit(state: boolean) {
|
||||
if (state == false) {
|
||||
publishFormProps.value.branch = ''
|
||||
publishFormProps.value.commit = ''
|
||||
@ -679,7 +687,7 @@ function handleSelectServer() {
|
||||
})
|
||||
}
|
||||
|
||||
function handleCancelSelectCommit(state) {
|
||||
function handleCancelSelectCommit() {
|
||||
publishFormProps.value.branch = ''
|
||||
publishFormProps.value.commit = ''
|
||||
publishFormProps.value.selectCommit = false
|
||||
@ -758,7 +766,7 @@ function publish(data: ProjectData) {
|
||||
const customVariables = deepClone(data.script.customVariables)
|
||||
publishFormProps.value.customVariables =
|
||||
customVariables &&
|
||||
customVariables.map((item) => {
|
||||
customVariables.map((item: any) => {
|
||||
if (item.type == 'list') {
|
||||
item.value = ''
|
||||
}
|
||||
@ -880,6 +888,13 @@ function restorePublishForm() {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
flex: 1;
|
||||
}
|
||||
.card-title__link {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,7 +165,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default { name: 'MemberIndex' }
|
||||
export default { name: 'MemberSetting' }
|
||||
</script>
|
||||
<script lang="ts" setup>
|
||||
import permission from '@/permission'
|
@ -127,7 +127,7 @@
|
||||
</el-row>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
export default { name: 'NamespaceIndex' }
|
||||
export default { name: 'NamespaceSetting' }
|
||||
</script>
|
||||
<script lang="ts" setup>
|
||||
import permission from '@/permission'
|
170
web/src/views/setting/notification.vue
Normal file
170
web/src/views/setting/notification.vue
Normal file
@ -0,0 +1,170 @@
|
||||
<template>
|
||||
<el-row class="app-container">
|
||||
<el-row class="app-bar" type="flex" justify="space-between"></el-row>
|
||||
<el-row class="app-table">
|
||||
<el-table
|
||||
:key="tableHeight"
|
||||
v-loading="tableLoading"
|
||||
highlight-current-row
|
||||
height="100%"
|
||||
:data="tableData"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column prop="id" label="ID" width="80" />
|
||||
<el-table-column prop="useBy" :label="'Use By'" width="100" />
|
||||
<el-table-column prop="title" :label="$t('title')" width="200" />
|
||||
<el-table-column prop="type" :label="$t('type')" width="100">
|
||||
<template #default="scope">
|
||||
{{ $t(`webhookOption[${scope.row.type || 0}]`) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="template" :label="$t('template')" />
|
||||
<el-table-column
|
||||
prop="insertTime"
|
||||
:label="$t('insertTime')"
|
||||
width="160"
|
||||
align="center"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="updateTime"
|
||||
:label="$t('updateTime')"
|
||||
width="160"
|
||||
align="center"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="operation"
|
||||
:label="$t('op')"
|
||||
width="100"
|
||||
align="center"
|
||||
:fixed="$store.state.app.device === 'mobile' ? false : 'right'"
|
||||
>
|
||||
<template #default="scope">
|
||||
<Button
|
||||
type="primary"
|
||||
:icon="Edit"
|
||||
:permissions="[permission.EditNotification]"
|
||||
@click="handleEdit(scope.row)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-row>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="$t('setting')"
|
||||
:fullscreen="$store.state.app.device === 'mobile'"
|
||||
>
|
||||
<el-form
|
||||
ref="form"
|
||||
:model="formData"
|
||||
label-width="80px"
|
||||
:label-position="
|
||||
$store.state.app.device === 'desktop' ? 'right' : 'top'
|
||||
"
|
||||
>
|
||||
<el-form-item
|
||||
:label="$t('title')"
|
||||
prop="title"
|
||||
:rules="[
|
||||
{ required: true, message: 'Title required', trigger: 'blur' },
|
||||
]"
|
||||
>
|
||||
<el-input v-model="formData.title" autocomplete="off" />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('template')"
|
||||
prop="template"
|
||||
:rules="[
|
||||
{ required: true, message: 'Template required', trigger: 'blur' },
|
||||
]"
|
||||
>
|
||||
<el-input
|
||||
v-model="formData.template"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 8 }"
|
||||
autocomplete="off"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="dialogVisible = false">{{ $t('cancel') }}</el-button>
|
||||
<el-button
|
||||
:disabled="formProps.disabled"
|
||||
type="primary"
|
||||
@click="submit"
|
||||
>
|
||||
{{ $t('confirm') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</el-row>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
export default { name: 'NotificationSetting' }
|
||||
</script>
|
||||
<script lang="ts" setup>
|
||||
import permission from '@/permission'
|
||||
import Button from '@/components/Permission/Button.vue'
|
||||
import { Edit } from '@element-plus/icons-vue'
|
||||
import {
|
||||
NotificationList,
|
||||
NotificationEdit,
|
||||
NotificationData,
|
||||
} from '@/api/notification'
|
||||
import getTableHeight from '@/composables/tableHeight'
|
||||
import type { ElForm } from 'element-plus'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const { tableHeight } = getTableHeight()
|
||||
const dialogVisible = ref(false)
|
||||
const tableLoading = ref(false)
|
||||
const tableData = ref<NotificationList['datagram']['list']>([])
|
||||
const selectedItem = ref<NotificationData>()
|
||||
const form = ref<InstanceType<typeof ElForm>>()
|
||||
const tempFormData = { id: 0, title: '', template: '' }
|
||||
const formData = ref(tempFormData)
|
||||
const formProps = ref({ disabled: false })
|
||||
|
||||
getList()
|
||||
|
||||
function getList() {
|
||||
tableLoading.value = true
|
||||
new NotificationList()
|
||||
.request()
|
||||
.then((response) => {
|
||||
tableData.value = response.data.list
|
||||
})
|
||||
.finally(() => {
|
||||
tableLoading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
function handleEdit(data: NotificationData) {
|
||||
formData.value = Object.assign({}, data)
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
function submit() {
|
||||
form.value?.validate((valid) => {
|
||||
if (valid) {
|
||||
edit()
|
||||
return Promise.resolve(true)
|
||||
} else {
|
||||
return Promise.reject(false)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function edit() {
|
||||
formProps.value.disabled = true
|
||||
new NotificationEdit(formData.value)
|
||||
.request()
|
||||
.then(() => {
|
||||
getList()
|
||||
ElMessage.success('Success')
|
||||
})
|
||||
.finally(() => {
|
||||
formProps.value.disabled = dialogVisible.value = false
|
||||
})
|
||||
}
|
||||
</script>
|
@ -169,7 +169,7 @@
|
||||
</el-row>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
export default { name: 'NamespaceRole' }
|
||||
export default { name: 'RoleSetting' }
|
||||
</script>
|
||||
<script lang="ts" setup>
|
||||
import pms from '@/permission'
|
Loading…
Reference in New Issue
Block a user