diff --git a/go.mod b/go.mod index 11e9aba..d6e94eb 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module message-nest go 1.20 require ( + github.com/blinkbean/dingtalk v0.0.0-20230927120905-796332ac4ba1 github.com/dgrijalva/jwt-go v3.1.0+incompatible github.com/gin-gonic/gin v1.9.1 github.com/go-ini/ini v1.32.1-0.20180214101753-32e4be5f41bb @@ -11,7 +12,6 @@ require ( github.com/go-playground/validator/v10 v10.16.0 github.com/google/uuid v1.5.0 github.com/jinzhu/gorm v0.0.0-20180213101209-6e1387b44c64 - github.com/markbates/pkger v0.17.1 github.com/robfig/cron/v3 v3.0.1 github.com/sirupsen/logrus v1.9.3 github.com/unknwon/com v1.0.1 @@ -19,7 +19,6 @@ require ( ) require ( - github.com/blinkbean/dingtalk v0.0.0-20230927120905-796332ac4ba1 // indirect github.com/bytedance/sonic v1.10.2 // indirect github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect github.com/chenzhuoyu/iasm v0.9.1 // indirect @@ -28,12 +27,12 @@ require ( github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-sql-driver/mysql v1.4.1-0.20190510102335-877a9775f068 // indirect - github.com/gobuffalo/here v0.6.0 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/jinzhu/inflection v0.0.0-20170102125226-1c35d901db3d // indirect github.com/jinzhu/now v1.0.1 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.6 // indirect + github.com/kr/pretty v0.1.0 // indirect github.com/leodido/go-urn v1.2.4 // indirect github.com/lib/pq v1.2.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect @@ -52,6 +51,7 @@ require ( google.golang.org/appengine v1.6.3 // indirect google.golang.org/protobuf v1.32.0 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect + gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect gopkg.in/ini.v1 v1.47.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index e792ff9..610e305 100644 --- a/go.sum +++ b/go.sum @@ -37,8 +37,6 @@ github.com/go-playground/validator/v10 v10.16.0 h1:x+plE831WK4vaKHO/jpgUGsvLKIqR github.com/go-playground/validator/v10 v10.16.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-sql-driver/mysql v1.4.1-0.20190510102335-877a9775f068 h1:q2kwd9Bcgl2QpSi/Wjcx9jzwyICt3EWTP5to43QhwaA= github.com/go-sql-driver/mysql v1.4.1-0.20190510102335-877a9775f068/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/gobuffalo/here v0.6.0 h1:hYrd0a6gDmWxBM4TnrGw8mQg24iSVoIkHEk7FodQcBI= -github.com/gobuffalo/here v0.6.0/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= @@ -75,8 +73,6 @@ github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/markbates/pkger v0.17.1 h1:/MKEtWqtc0mZvu9OinB9UzVN9iYCwLWuyUv4Bw+PCno= -github.com/markbates/pkger v0.17.1/go.mod h1:0JoVlrol20BSywW79rN3kdFFsE5xYM+rSCQDXbLhiuI= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q= @@ -104,7 +100,6 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= @@ -161,8 +156,6 @@ gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AW gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw= gopkg.in/ini.v1 v1.47.0 h1:XAVsOWcIxjm6JVEbCbSZgSBZIF0BrCzXs4orAQr6uc8= gopkg.in/ini.v1 v1.47.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/models/send_ins.go b/models/send_ins.go index b8e9417..74f4771 100644 --- a/models/send_ins.go +++ b/models/send_ins.go @@ -14,7 +14,11 @@ type SendTasksIns struct { // InsEmailConfig 实例里面的邮箱config type InsEmailConfig struct { ToAccount string `json:"to_account" validate:"required,email" label:"收件邮箱"` - Title string `json:"title" validate:"required,max=150" label:"邮箱标题"` + //Title string `json:"title" validate:"required,max=150" label:"邮箱标题"` +} + +// InsEmailConfig 实例里面的邮箱config +type InsDtalkConfig struct { } // ManyAddTaskIns 批量添加实例 diff --git a/models/send_tasks.go b/models/send_tasks.go index d1e0a12..b07bda7 100644 --- a/models/send_tasks.go +++ b/models/send_tasks.go @@ -122,6 +122,7 @@ func GetTasksIns(id string) (TaskIns, error) { Select(fmt.Sprintf("%s.*, %s.name as way_name", insTable, waysTable)). Joins(fmt.Sprintf("JOIN %s ON %s.way_id = %s.id", waysTable, insTable, waysTable)). Where(fmt.Sprintf("%s.task_id = ?", insTable), id). + Order(fmt.Sprintf("%s.created_on DESC", insTable)). Scan(&taskIns) taskResult.ID = task.ID diff --git a/pkg/message/dtalk.go b/pkg/message/dtalk.go index 09bd60b..abc32f8 100644 --- a/pkg/message/dtalk.go +++ b/pkg/message/dtalk.go @@ -1,9 +1,89 @@ package message -type DTalkMessage struct { - WebhookUrl string +import ( + "bytes" + "crypto/hmac" + "crypto/sha256" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "time" +) + +type response struct { + Code int `json:"errcode"` + Msg string `json:"errmsg"` } -func (d *DTalkMessage) send(content string) { +type Dtalk struct { + AccessToken string + Secret string +} +func (t *Dtalk) Request(msg interface{}) ([]byte, error) { + b, err := json.Marshal(msg) + if err != nil { + return nil, err + } + resp, err := http.Post(t.getURL(), "application/json", bytes.NewBuffer(b)) + if err != nil { + return nil, err + } + + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + var r response + err = json.Unmarshal(body, &r) + if err != nil { + return body, err + } + if r.Code != 0 { + return body, errors.New(fmt.Sprintf("response error: %s", string(body))) + } + return body, err +} + +// SendMessageText Function to send message +func (t *Dtalk) SendMessageText(text string, at ...string) ([]byte, error) { + msg := map[string]interface{}{ + "msgtype": "text", + "text": map[string]string{ + "content": text, + }, + } + resp, err := t.Request(msg) + return resp, err +} + +func (t *Dtalk) SendMessageMarkdown(title, text string, at ...string) ([]byte, error) { + msg := map[string]interface{}{ + "msgtype": "markdown", + "markdown": map[string]string{ + "title": title, + "text": text, + }, + } + resp, err := t.Request(msg) + return resp, err +} + +func (t *Dtalk) hmacSha256(stringToSign string, secret string) string { + h := hmac.New(sha256.New, []byte(secret)) + h.Write([]byte(stringToSign)) + return base64.StdEncoding.EncodeToString(h.Sum(nil)) +} + +func (t *Dtalk) getURL() string { + wh := "https://oapi.dingtalk.com/robot/send?access_token=" + t.AccessToken + timestamp := time.Now().UnixNano() / 1e6 + stringToSign := fmt.Sprintf("%d\n%s", timestamp, t.Secret) + sign := t.hmacSha256(stringToSign, t.Secret) + url := fmt.Sprintf("%s×tamp=%d&sign=%s", wh, timestamp, sign) + return url } diff --git a/routers/api/v1/send_message.go b/routers/api/v1/send_message.go index 91a11c7..0acdd93 100644 --- a/routers/api/v1/send_message.go +++ b/routers/api/v1/send_message.go @@ -11,6 +11,7 @@ import ( type SendMessageReq struct { TaskID string `json:"task_id" validate:"required,len=36" label:"任务id"` Text string `json:"text" validate:"required" label:"文本内容"` + Title string `json:"title" label:"消息标题"` HTML string `json:"html" label:"html内容"` MarkDown string `json:"markdown" label:"markdown内容"` Mode string `json:"mode" label:"是否异步发送"` @@ -31,11 +32,12 @@ func DoSendMassage(c *gin.Context) { msgService := send_message_service.SendMessageService{ TaskID: req.TaskID, + Title: req.Title, Text: req.Text, HTML: req.HTML, MarkDown: req.MarkDown, } - if req.Mode != "async" { + if req.Mode == "sync" { // 同步发送 err := msgService.Send() if err != "" { diff --git a/service/cron_service/cron_service.go b/service/cron_service/cron_service.go index 10e65c4..5e695d8 100644 --- a/service/cron_service/cron_service.go +++ b/service/cron_service/cron_service.go @@ -44,6 +44,7 @@ func ClearLogs() { // 启动注册清除任务定时任务 func (cs *CronService) InitLogsCronRun() { + // 注册任务 setting, err := models.GetSettingByKey(constant.LogsCleanSectionName, constant.LogsCleanCronKeyName) if err != nil { logging.Logger.Error(fmt.Sprintf("获取日志的cron失败,原因:%s", err)) @@ -52,6 +53,12 @@ func (cs *CronService) InitLogsCronRun() { Schedule: setting.Value, Job: ClearLogs, }) + + // 添加任务 + err = models.AddSendTaskWithID("日志定时清除", constant.CleanLogsTaskId, "admin") + if err != nil { + logging.Logger.Error(fmt.Sprintf("添加日志定时清除任务失败,原因:%s", err)) + } } // 更新清除任务定时任务 diff --git a/service/send_ins_service/send_ins.go b/service/send_ins_service/send_ins.go index 352724b..70e361b 100644 --- a/service/send_ins_service/send_ins.go +++ b/service/send_ins_service/send_ins.go @@ -30,6 +30,10 @@ func (sw *SendTaskInsService) ValidateDiffIns(ins models.SendTasksIns) (string, _, Msg := app.CommonPlaygroundValid(emailConfig) return Msg, emailConfig } + if ins.WayType == "Dtalk" { + var Config models.InsDtalkConfig + return "", Config + } return "未知的渠道的config校验", empty } diff --git a/service/send_message_service/send_dtalk.go b/service/send_message_service/send_dtalk.go new file mode 100644 index 0000000..49b8827 --- /dev/null +++ b/service/send_message_service/send_dtalk.go @@ -0,0 +1,45 @@ +package send_message_service + +import ( + "fmt" + "message-nest/models" + "message-nest/pkg/message" + "message-nest/service/send_ins_service" + "message-nest/service/send_way_service" +) + +type DtalkService struct { +} + +// SendDtalkMessage 执行发送钉钉 +func (s *DtalkService) SendDtalkMessage(auth send_way_service.WayDetailDTalk, ins models.SendTasksIns, typeC string, title string, content string) string { + insService := send_ins_service.SendTaskInsService{} + errStr, c := insService.ValidateDiffIns(ins) + if errStr != "" { + return errStr + } + _, ok := c.(models.InsDtalkConfig) + if !ok { + return "钉钉config校验失败" + } + + errMsg := "" + cli := message.Dtalk{ + AccessToken: auth.AccessToken, + Secret: auth.Secret, + } + if typeC == "text" { + _, err := cli.SendMessageText(content) + if err != nil { + errMsg = fmt.Sprintf("发送失败:%s", ins.ContentType) + } + } else if typeC == "markdown" { + _, err := cli.SendMessageMarkdown(title, content) + if err != nil { + errMsg = fmt.Sprintf("发送失败:%s", ins.ContentType) + } + } else { + errMsg = fmt.Sprintf("未知的钉钉发送内容类型:%s", ins.ContentType) + } + return errMsg +} diff --git a/service/send_message_service/send_email.go b/service/send_message_service/send_email.go index 449a5a4..829b7b5 100644 --- a/service/send_message_service/send_email.go +++ b/service/send_message_service/send_email.go @@ -12,7 +12,7 @@ type EmailService struct { } // SendTaskEmail 执行发送邮件 -func (s *EmailService) SendTaskEmail(auth send_way_service.WayDetailEmail, ins models.SendTasksIns, typeC string, content string) string { +func (s *EmailService) SendTaskEmail(auth send_way_service.WayDetailEmail, ins models.SendTasksIns, typeC string, title string, content string) string { insService := send_ins_service.SendTaskInsService{} errStr, c := insService.ValidateDiffIns(ins) if errStr != "" { @@ -27,9 +27,9 @@ func (s *EmailService) SendTaskEmail(auth send_way_service.WayDetailEmail, ins m errMsg := "" emailer.Init(auth.Server, auth.Port, auth.Account, auth.Passwd) if typeC == "text" { - errMsg = emailer.SendTextMessage(config.ToAccount, config.Title, content) + errMsg = emailer.SendTextMessage(config.ToAccount, title, content) } else if typeC == "html" { - errMsg = emailer.SendHtmlMessage(config.ToAccount, config.Title, content) + errMsg = emailer.SendHtmlMessage(config.ToAccount, title, content) } else { errMsg = fmt.Sprintf("未知的邮件发送内容类型:%s", ins.ContentType) } diff --git a/service/send_message_service/send_message.go b/service/send_message_service/send_message.go index b0589a4..c024518 100644 --- a/service/send_message_service/send_message.go +++ b/service/send_message_service/send_message.go @@ -23,6 +23,7 @@ func errStrIsSuccess(errStr string) int { type SendMessageService struct { TaskID string + Title string Text string HTML string MarkDown string @@ -46,6 +47,7 @@ func (sm *SendMessageService) Send() string { errStr := "" sm.LogsAndStatusMark(fmt.Sprintf("开始任务[%s]的发送", sm.TaskID), sm.Status) + sm.LogsAndStatusMark(fmt.Sprintf("发送标题:%s \n", sm.Title), sm.Status) sendTaskService := send_task_service.SendTaskService{ ID: sm.TaskID, @@ -93,13 +95,21 @@ func (sm *SendMessageService) Send() string { // 邮箱类型的实例发送 emailAuth, ok := msgObj.(send_way_service.WayDetailEmail) if ok { + //continue es := EmailService{} - errMsg := es.SendTaskEmail(emailAuth, ins.SendTasksIns, typeC, content) + errMsg := es.SendTaskEmail(emailAuth, ins.SendTasksIns, typeC, sm.Title, content) sm.LogsAndStatusMark(sm.TransError(errMsg), errStrIsSuccess(errMsg)) continue } - - sm.LogsAndStatusMark(fmt.Sprintf("未知渠道的发信实例: %s", ins.ID), sm.Status) + // 钉钉类型的实例发送 + dtalkAuth, ok := msgObj.(send_way_service.WayDetailDTalk) + if ok { + es := DtalkService{} + errMsg := es.SendDtalkMessage(dtalkAuth, ins.SendTasksIns, typeC, sm.Title, content) + sm.LogsAndStatusMark(sm.TransError(errMsg), errStrIsSuccess(errMsg)) + continue + } + sm.LogsAndStatusMark(fmt.Sprintf("发送失败:未知渠道的发信实例: %s\n", ins.ID), SendFail) } @@ -165,6 +175,7 @@ func (sm *SendMessageService) GetSendMsg(ins models.SendTasksIns) (string, strin logging.Logger.Error("text节点数据为空!") return "text", "" } else { + logging.Logger.Error(fmt.Sprintf("没有找到%s对应的消息,使用text消息替代!", ins.ContentType)) return "text", content } } else { diff --git a/service/send_way_service/send_way.go b/service/send_way_service/send_way.go index d2c466f..9dbf921 100644 --- a/service/send_way_service/send_way.go +++ b/service/send_way_service/send_way.go @@ -4,6 +4,7 @@ import ( "encoding/json" "errors" "fmt" + "github.com/blinkbean/dingtalk" "message-nest/models" "message-nest/pkg/app" "message-nest/pkg/message" @@ -33,7 +34,9 @@ type WayDetailEmail struct { // WayDetailDTalk 钉钉渠道明细字段 type WayDetailDTalk struct { - WebhookUrl string `validate:"required,url" label:"钉钉webhookUrl地址"` + AccessToken string `json:"access_token" validate:"required,max=100" label:"钉钉access_token"` + Keys string `json:"keys" validate:"max=200" label:"钉钉关键字"` + Secret string `json:"secret" validate:"max=100" label:"钉钉加签秘钥"` } func (sw *SendWay) GetByID() (interface{}, error) { @@ -106,12 +109,22 @@ func (sw *SendWay) ValidateDiffWay() (string, interface{}) { // TestSendWay 尝试带发信测试连通性 func (sw *SendWay) TestSendWay(msgObj interface{}) string { + testMsg := "This is a test message from message-nest." emailAuth, ok := msgObj.(WayDetailEmail) if ok { var emailer message.EmailMessage emailer.Init(emailAuth.Server, 465, emailAuth.Account, emailAuth.Passwd) - errMsg := emailer.SendTextMessage(emailAuth.Account, "test", "This is a test email from message-nest.") + errMsg := emailer.SendTextMessage(emailAuth.Account, "test email", testMsg) return errMsg } + dtalkAuth, ok := msgObj.(WayDetailDTalk) + if ok { + cli := dingtalk.InitDingTalkWithSecret(dtalkAuth.AccessToken, dtalkAuth.Secret) + err := cli.SendTextMessage(testMsg + dtalkAuth.Keys) + if err != nil { + return fmt.Sprintf("发送失败:%s", err) + } + return "" + } return fmt.Sprintf("未知的发信渠道校验: %s", sw.Type) } diff --git a/web/src/constant.js b/web/src/constant.js index 5b8f0d6..7c62d03 100644 --- a/web/src/constant.js +++ b/web/src/constant.js @@ -13,24 +13,54 @@ const CONSTANT = { type: 'Email', label: '邮箱', inputs: [ - { subLabel: 'smtp服务地址', value: '', col: 'server' }, - { subLabel: 'smtp服务端口', value: '', col: 'port' }, - { subLabel: '邮箱账号', value: '', col: 'account' }, - { subLabel: '邮箱密码', value: '', col: 'passwd' }, - { subLabel: '渠道名', value: '', col: 'name' }, - ] + { subLabel: 'smtp服务地址', value: '', col: 'server', desc: "smtp@xyz.com" }, + { subLabel: 'smtp服务端口', value: '', col: 'port', desc: "port" }, + { subLabel: '邮箱账号', value: '', col: 'account', desc: "邮箱账号" }, + { subLabel: '邮箱密码', value: '', col: 'passwd', desc: "邮箱密码" }, + { subLabel: '渠道名', value: '', col: 'name', desc: "想要设置的渠道名字" }, + ], + taskInsRadios: [ + { subLabel: 'text', content: 'text' }, + { subLabel: 'html', content: 'html' }, + ], + taskInsInputs: [ + { value: '', col: 'to_account', desc: "目的邮箱账号(发给谁)" }, + // { value: '', col: 'title', desc: "邮箱标题" }, + + ], }, { type: 'Dtalk', label: '钉钉', inputs: [ - { subLabel: 'webhook地址', value: '', col: 'webhook_url' }, - { subLabel: '渠道名', value: '', col: 'name' }, - ] + { subLabel: 'access_token', value: '', col: 'access_token', desc: "钉钉webhook中的access_token" }, + // { subLabel: '关键字过滤', value: '', col: 'keys', desc: "使用的关键字过滤,多个使用|隔开" }, + { subLabel: '加签', value: '', col: 'secret', desc: "加签的签名,SEC开头" }, + { subLabel: '渠道名', value: '', col: 'name', desc: "想要设置的渠道名字" }, + ], + tips: { + text: "输入框说明", desc: "钉钉支持加签和关键字过滤,如果是配置了关键字过滤,只需要消息里面包含了关键字,就会发送" + }, + taskInsRadios: [ + { subLabel: 'text', content: 'text' }, + { subLabel: 'markdown', content: 'markdown' }, + ], + taskInsInputs: [ + // { value: '', col: 'to_account', desc: "目的邮箱账号(发给fsfsf谁)" }, + // { value: '', col: 'title', desc: "邮箱标题fsfsf" }, + ], }, ], LOGO: ``, } + +CONSTANT.WAYS_DATA_MAP = {}; +CONSTANT.WAYS_DATA.forEach(element => { + CONSTANT.WAYS_DATA_MAP[element.type] = element +}); + +console.log('xxxxxxxx', CONSTANT.WAYS_DATA_MAP) + export { CONSTANT } \ No newline at end of file diff --git a/web/src/util/commonUtils.js b/web/src/util/commonUtils.js new file mode 100644 index 0000000..6ef6ddf --- /dev/null +++ b/web/src/util/commonUtils.js @@ -0,0 +1,39 @@ + + + +class CommonUtils { + + + // static getCurlString(task_id, options) { + // let data = { task_id: task_id }; + // data.title = 'message title'; + // data.text = 'Hello World!'; + // if (options.html) { + // data.html = '

Hello World!

'; + // } + // if (options.markdown) { + // data.html = '**Hello World!**'; + // } + // let dataStr = JSON.stringify(data, null, 4); + // let example = `curl -X POST --location '${gethttpOrigin()}/api/v1/message/send' \\ + // --header 'Content-Type: application/json' \\ + // --data '${dataStr}'`; + // return example; + // } + + static formatInsConfigDisplay = (scope) => { + if (!scope.row.config) { + return "" + } + if (scope.row.way_type == "Email") { + let config = JSON.parse(scope.row.config) + let info = `发送账号:${config.to_account}` + return info + } else { + return "暂无" + } + } + +} + +export { CommonUtils }; diff --git a/web/src/util/viewApi.js b/web/src/util/viewApi.js index 4631adf..b353518 100644 --- a/web/src/util/viewApi.js +++ b/web/src/util/viewApi.js @@ -8,13 +8,14 @@ class ApiStrGenerate { static getCurlString(task_id, options) { - let data = { task_id: task_id, mode: "async" }; + let data = { task_id: task_id }; + data.title = 'message title'; data.text = 'Hello World!'; - if (options.html) { + if (options.html ) { data.html = '

Hello World!

'; } - if (options.markdown) { - data.html = '** Hello World! **'; + if (options.markdown ) { + data.markdown = '**Hello World!**'; } let dataStr = JSON.stringify(data, null, 4); let example = `curl -X POST --location '${gethttpOrigin()}/api/v1/message/send' \\ diff --git a/web/src/views/common/textTips.vue b/web/src/views/common/textTips.vue new file mode 100644 index 0000000..9462f8d --- /dev/null +++ b/web/src/views/common/textTips.vue @@ -0,0 +1,32 @@ + + + + + \ No newline at end of file diff --git a/web/src/views/tabsTools/sendLogs/sendLogs.vue b/web/src/views/tabsTools/sendLogs/sendLogs.vue index 4a5e57e..1f78274 100644 --- a/web/src/views/tabsTools/sendLogs/sendLogs.vue +++ b/web/src/views/tabsTools/sendLogs/sendLogs.vue @@ -6,7 +6,7 @@
- + diff --git a/web/src/views/tabsTools/sendTasks/sendTasks.vue b/web/src/views/tabsTools/sendTasks/sendTasks.vue index 70d663f..bbf63cd 100644 --- a/web/src/views/tabsTools/sendTasks/sendTasks.vue +++ b/web/src/views/tabsTools/sendTasks/sendTasks.vue @@ -13,16 +13,24 @@
- + @@ -75,7 +83,7 @@ export default { // confirmBtnVisible: false, tableData: [], total: CONSTANT.TOTAL, - pageSize: CONSTANT.PAGE_SIZE, + pageSize: CONSTANT.PAGE_SIZE, currPage: CONSTANT.PAGE, displayCols: [ { 'col': 'id', 'label': '任务ID' }, @@ -86,7 +94,9 @@ export default { options: [ { label: '邮箱', value: 'Email' }, { label: '钉钉', value: 'Dtalk' } - ] + ], + sysKeptTaskIds: [CONSTANT.LOG_TASK_ID], + }); const handleEdit = (index, row) => { @@ -122,7 +132,7 @@ export default { } const handleViewLogs = (index, row) => { - router.push('/sendlogs?name=' + row.name, { replace: true }); + router.push('/sendlogs?taskid=' + row.id, { replace: true }); } const filterFunc = async () => { diff --git a/web/src/views/tabsTools/sendTasks/view/addTaskPopUp.vue b/web/src/views/tabsTools/sendTasks/view/addTaskPopUp.vue index 0717198..00da5ee 100644 --- a/web/src/views/tabsTools/sendTasks/view/addTaskPopUp.vue +++ b/web/src/views/tabsTools/sendTasks/view/addTaskPopUp.vue @@ -37,19 +37,21 @@ 渠道创建时间:{{ currWayTmp.created_on }}
- - text - html + + + {{ item.content }} +
- - - 暂存 + +
+ 暂存
@@ -97,6 +99,7 @@ import { QuestionFilled } from '@element-plus/icons-vue' import { v4 as uuidv4 } from 'uuid'; import { usePageState } from '@/store/page_sate.js'; import { request } from '@/api/api' +import { CONSTANT } from '@/constant' export default defineComponent({ @@ -114,9 +117,8 @@ export default defineComponent({ isShowAddBox: false, searchWayID: '', currWayTmp: {}, - currInsInput: { - content_type: 'text' - }, + currInsInput: {}, + currInsInputContentType: 'text', currTaskInput: { taskName: '', taskId: uuidv4(), @@ -139,7 +141,8 @@ export default defineComponent({ // 页面每次弹出,重置数据 const resetPageInitData = () => { state.insTableData = []; - state.currInsInput = { content_type: 'text' }; + state.currInsInputContentType = 'text'; + state.currInsInput = {}; state.currWayTmp = {}; state.searchWayID = ''; state.isShowAddBox = false; @@ -163,8 +166,8 @@ export default defineComponent({ way_id: state.currWayTmp.id, way_type: state.currWayTmp.type, way_name: state.currWayTmp.name, - content_type: state.currInsInput.content_type, - config: JSON.stringify({ to_account: state.currInsInput.toAccount, title: state.currInsInput.title }) + content_type: state.currInsInputContentType, + config: JSON.stringify(state.currInsInput) }; state.insTableData.push(insData); } @@ -175,6 +178,10 @@ export default defineComponent({ state.isShowAddBox = Boolean(data.data); if (data.data) { state.currWayTmp = data.data; + // 初始化currInsInput + CONSTANT.WAYS_DATA_MAP[data.data.type].taskInsInputs.forEach(element => { + state.currInsInput[element.col] = "" + }); } } @@ -184,8 +191,6 @@ export default defineComponent({ return postData } - - const handleSubmit = async () => { let postData = getFinalData(); const rsp = await request.post('/sendtasks/ins/addmany', postData); @@ -196,17 +201,12 @@ export default defineComponent({ } const formatExtraInfo = (scope) => { - if (!scope.row.config) { - return "" - } - let config = JSON.parse(scope.row.config) - let info = `发送账号:${config.to_account}\n标题:${config.title}` - return info + return CommonUtils.formatInsConfigDisplay(scope); } return { ...toRefs(state), handleCancer, handleSubmit, - searchID, formatExtraInfo, + searchID, formatExtraInfo, CONSTANT, clickStore, insRowStyle }; }, diff --git a/web/src/views/tabsTools/sendTasks/view/editTaskPopUp.vue b/web/src/views/tabsTools/sendTasks/view/editTaskPopUp.vue index 1a9c5fc..982897d 100644 --- a/web/src/views/tabsTools/sendTasks/view/editTaskPopUp.vue +++ b/web/src/views/tabsTools/sendTasks/view/editTaskPopUp.vue @@ -2,8 +2,6 @@
@@ -29,15 +27,19 @@ 渠道创建时间:{{ currWayTmp.created_on }}
- - text - html + + + {{ item.content }} + +
- - + + +
添加 @@ -87,6 +89,8 @@ import { usePageState } from '@/store/page_sate.js'; import { request } from '@/api/api' import tableDeleteButton from '@/views/common/tableDeleteButton.vue' import { ElMessage } from 'element-plus' +import { CONSTANT } from '@/constant' +import { CommonUtils } from "@/util/commonUtils.js"; export default defineComponent({ @@ -104,6 +108,7 @@ export default defineComponent({ isShow: false, isShowAddBox: false, searchWayID: '', + currInsInputContentType: '', currWayTmp: {}, currInsInput: {}, currTaskInput: { @@ -140,7 +145,9 @@ export default defineComponent({ state.insTableData = []; state.currInsInput = {}; state.currWayTmp = {}; + state.currInsInput = {}; state.searchWayID = ''; + state.currInsInputContentType = ''; state.isShowAddBox = false; state.currTaskInput = { taskName: '', @@ -162,12 +169,7 @@ export default defineComponent({ } const formatExtraInfo = (scope) => { - if (!scope.row.config) { - return "" - } - let config = JSON.parse(scope.row.config) - let info = `发送账号:${config.to_account}\n标题:${config.title}` - return info + return CommonUtils.formatInsConfigDisplay(scope); } const searchID = async () => { @@ -186,8 +188,8 @@ export default defineComponent({ way_id: state.currWayTmp.id, way_type: state.currWayTmp.type, way_name: state.currWayTmp.name, - content_type: state.currInsInput.content_type, - config: JSON.stringify({ to_account: state.currInsInput.toAccount, title: state.currInsInput.title }) + content_type: state.currInsInputContentType, + config: JSON.stringify(state.currInsInput) } return postData } @@ -210,7 +212,7 @@ export default defineComponent({ } return { - ...toRefs(state), handleCancer, handleAddSubmit, handleEditTask, + ...toRefs(state), handleCancer, handleAddSubmit, handleEditTask,CONSTANT, searchID, handleDelete, insRowStyle, formatExtraInfo }; }, diff --git a/web/src/views/tabsTools/sendTasks/view/viewTaskAPIPopUp.vue b/web/src/views/tabsTools/sendTasks/view/viewTaskAPIPopUp.vue index daab544..b802dae 100644 --- a/web/src/views/tabsTools/sendTasks/view/viewTaskAPIPopUp.vue +++ b/web/src/views/tabsTools/sendTasks/view/viewTaskAPIPopUp.vue @@ -8,9 +8,9 @@
实例的内容类型大体上可以可以分为text、html、markdown
- 发送的消息会优先现在相应的类型消息进行发送,如果没有,将使用传的text消息进行发送 + 发送的消息会优先现在相应的类型消息进行发送,如果没有,将使用传的text消息进行发送
- ** text节点必传,指定mode=async将异步发送,否则同步发送 + ** text节点必传,指定mode=sync将同步发送,默认异步发送 @@ -40,6 +40,7 @@ import { usePageState } from '@/store/page_sate.js'; import Prism from "prismjs"; import { ApiStrGenerate } from "@/util/viewApi.js"; import { QuestionFilled } from '@element-plus/icons-vue' +import { request } from '@/api/api' export default defineComponent({ components: { @@ -70,10 +71,24 @@ export default defineComponent({ } } - const renderApiString = () => { + // 获取接口查看格式 + const getViewOptions = async (taskId) => { + let params = { id: taskId }; + const rsp = await request.get('/sendtasks/ins/gettask', { params: params }); + let insTableData = await rsp.data.data.ins_data; + + let viewOptions = {} + insTableData.forEach(element => { + viewOptions[element.content_type] = 1; + }); + return viewOptions + } + + const renderApiString = async () => { let task_id = pageState.ShowDialogData[props.componentName].rowData.id; + let options = await getViewOptions(task_id) if (state.activeName == 'curl') { - state.currCode = ApiStrGenerate.getCurlString(task_id, {}); + state.currCode = ApiStrGenerate.getCurlString(task_id, options); } setTimeout(() => { Prism.highlightAll() diff --git a/web/src/views/tabsTools/sendWays/sendWays.vue b/web/src/views/tabsTools/sendWays/sendWays.vue index 8a02bb1..db35820 100644 --- a/web/src/views/tabsTools/sendWays/sendWays.vue +++ b/web/src/views/tabsTools/sendWays/sendWays.vue @@ -18,7 +18,7 @@
- + + \ No newline at end of file diff --git a/web/src/views/tabsTools/settings/view/about.vue b/web/src/views/tabsTools/settings/view/about.vue index f3c3716..35e16a2 100644 --- a/web/src/views/tabsTools/settings/view/about.vue +++ b/web/src/views/tabsTools/settings/view/about.vue @@ -4,7 +4,7 @@
版本功能说明 - +