Browse Source

feat(): notify dingding

Espoir 3 years ago
parent
commit
04d61a2fc7

+ 14 - 9
server/config.yaml

@@ -34,6 +34,11 @@ email:
   secret: 'xxx'
   nickname: 'test'
 
+dingding:
+  url: 'https://oapi.dingtalk.com/robot/send'
+  secret: 'SEC38425b7bd57c6bca9ce20611c41b437994ed65e0ddbd42e840ffa7a8c7da2106'
+  token: '77d18293e221b3b7bdae7330d19a213c3cbb20fa07de5f4c273c0363ae475c34'
+
 # casbin configuration
 casbin:
   model-path: './resource/rbac_model.conf'
@@ -55,15 +60,15 @@ captcha:
 # mysql connect configuration
 # 未初始化之前请勿手动修改数据库信息!!!如果一定要手动初始化请看(https://www.github.com/flipped-aurora/gin-vue-admin/server.com/docs/first)
 mysql:
-  path: ''
-  config: ''
-  db-name: ''
-  username: ''
-  password: ''
-  max-idle-conns: 10
-  max-open-conns: 100
-  log-mode: false
-  log-zap: ""
+  path: 8.141.51.112:3306
+  config: charset=utf8mb4&parseTime=True&loc=Local
+  db-name: gva
+  username: root
+  password: 768f952daae626d9
+  max-idle-conns: 0
+  max-open-conns: 0
+  log-mode: ""
+  log-zap: false
 
 # local configuration
 local:

+ 8 - 7
server/config/config.go

@@ -1,13 +1,14 @@
 package config
 
 type Server struct {
-	JWT     JWT     `mapstructure:"jwt" json:"jwt" yaml:"jwt"`
-	Zap     Zap     `mapstructure:"zap" json:"zap" yaml:"zap"`
-	Redis   Redis   `mapstructure:"redis" json:"redis" yaml:"redis"`
-	Email   Email   `mapstructure:"email" json:"email" yaml:"email"`
-	Casbin  Casbin  `mapstructure:"casbin" json:"casbin" yaml:"casbin"`
-	System  System  `mapstructure:"system" json:"system" yaml:"system"`
-	Captcha Captcha `mapstructure:"captcha" json:"captcha" yaml:"captcha"`
+	JWT      JWT      `mapstructure:"jwt" json:"jwt" yaml:"jwt"`
+	Zap      Zap      `mapstructure:"zap" json:"zap" yaml:"zap"`
+	Redis    Redis    `mapstructure:"redis" json:"redis" yaml:"redis"`
+	Email    Email    `mapstructure:"email" json:"email" yaml:"email"`
+	DingDing DingDing `mapstructure:"dingding" json:"dingding" yaml:"dingding"`
+	Casbin   Casbin   `mapstructure:"casbin" json:"casbin" yaml:"casbin"`
+	System   System   `mapstructure:"system" json:"system" yaml:"system"`
+	Captcha  Captcha  `mapstructure:"captcha" json:"captcha" yaml:"captcha"`
 	// auto
 	AutoCode Autocode `mapstructure:"autoCode" json:"autoCode" yaml:"autoCode"`
 	// gorm

+ 7 - 0
server/config/dingding.go

@@ -0,0 +1,7 @@
+package config
+
+type DingDing struct {
+	Url    string `mapstructure:"url" json:"url" yaml:"url"`          // 发件人  你自己要发邮件的邮箱
+	Token  string `mapstructure:"token" json:"token" yaml:"token"`    // 服务器地址 例如 smtp.qq.com  请前往QQ或者你要发邮件的邮箱查看其smtp协议
+	Secret string `mapstructure:"secret" json:"secret" yaml:"secret"` // 密钥    用于登录的密钥 最好不要用邮箱密码 去邮箱smtp申请一个用于登录的密钥
+}

+ 8 - 0
server/initialize/router.go

@@ -4,6 +4,7 @@ import (
 	//email "github.com/flipped-aurora/gva-plug-email"   // 在线仓库模式
 	"github.com/flipped-aurora/gin-vue-admin/server/plugin/email" // 本地插件仓库地址模式
 	"github.com/flipped-aurora/gin-vue-admin/server/plugin/example_plugin"
+	"github.com/flipped-aurora/gin-vue-admin/server/plugin/notify"
 	"net/http"
 
 	_ "github.com/flipped-aurora/gin-vue-admin/server/docs"
@@ -65,6 +66,13 @@ func Routers() *gin.Engine {
 	//  添加开放权限的插件 示例
 	PluginInit(PublicGroup, example_plugin.ExamplePlugin)
 
+	//  钉钉通知,暂时开放权限
+	PluginInit(PublicGroup, notify.CreateDDPlug(
+		global.GVA_CONFIG.DingDing.Url,
+		global.GVA_CONFIG.DingDing.Secret,
+		global.GVA_CONFIG.DingDing.Token,
+	))
+
 	//  添加跟角色挂钩权限的插件 示例 本地示例模式于在线仓库模式注意上方的import 可以自行切换 效果相同
 	PluginInit(PrivateGroup, email.CreateEmailPlug(
 		global.GVA_CONFIG.Email.To,

+ 14 - 0
server/plugin/notify/README.MD

@@ -0,0 +1,14 @@
+## GVA 钉钉群通知插件
+
+### 使用步骤
+
+#### 1. 
+
+config.yaml 文件中配置钉钉通知的URL ,Token 等
+
+#### 2. 配置说明
+
+
+
+### 方法API
+

+ 21 - 0
server/plugin/notify/api/api.go

@@ -0,0 +1,21 @@
+package api
+
+import (
+	"github.com/flipped-aurora/gin-vue-admin/server/global"
+	"github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
+	"github.com/flipped-aurora/gin-vue-admin/server/plugin/notify/service"
+	"github.com/gin-gonic/gin"
+	"go.uber.org/zap"
+)
+
+type Api struct {
+}
+
+func (s *Api) NotifyController(c *gin.Context) {
+	if err := service.ServiceGroupApp.Send(); err != nil {
+		global.GVA_LOG.Error("发送失败!", zap.Any("err", err))
+		response.FailWithMessage("发送失败", c)
+	} else {
+		response.OkWithData("发送成功", c)
+	}
+}

+ 7 - 0
server/plugin/notify/api/enter.go

@@ -0,0 +1,7 @@
+package api
+
+type ApiGroup struct {
+	Api
+}
+
+var ApiGroupApp = new(ApiGroup)

+ 7 - 0
server/plugin/notify/config/dingding.go

@@ -0,0 +1,7 @@
+package config
+
+type DingDing struct {
+	Url    string `mapstructure:"url" json:"url" yaml:"url"`          // Url
+	Token  string `mapstructure:"token" json:"token" yaml:"token"`    // Token
+	Secret string `mapstructure:"secret" json:"secret" yaml:"secret"` // 密钥
+}

+ 5 - 0
server/plugin/notify/global/gloabl.go

@@ -0,0 +1,5 @@
+package global
+
+import "github.com/flipped-aurora/gin-vue-admin/server/plugin/notify/config"
+
+var GlobalConfig = new(config.DingDing)

+ 28 - 0
server/plugin/notify/main.go

@@ -0,0 +1,28 @@
+package notify
+
+import (
+	"github.com/flipped-aurora/gin-vue-admin/server/plugin/notify/global"
+	"github.com/flipped-aurora/gin-vue-admin/server/plugin/notify/router"
+	"github.com/gin-gonic/gin"
+)
+
+type ddPlugin struct {
+	Secret string
+	Token  string
+	Url    string
+}
+
+func CreateDDPlug(Url string, Secret string, Token string) *ddPlugin {
+	global.GlobalConfig.Secret = Secret
+	global.GlobalConfig.Token = Token
+	global.GlobalConfig.Url = Url
+	return &ddPlugin{}
+}
+
+func (*ddPlugin) Register(group *gin.RouterGroup) {
+	router.RouterGroupApp.InitRouter(group)
+}
+
+func (*ddPlugin) RouterPath() string {
+	return "notify"
+}

+ 7 - 0
server/plugin/notify/router/enter.go

@@ -0,0 +1,7 @@
+package router
+
+type RouterGroup struct {
+	NotifyRouter
+}
+
+var RouterGroupApp = new(RouterGroup)

+ 18 - 0
server/plugin/notify/router/router.go

@@ -0,0 +1,18 @@
+package router
+
+import (
+	"github.com/flipped-aurora/gin-vue-admin/server/middleware"
+	"github.com/flipped-aurora/gin-vue-admin/server/plugin/notify/api"
+	"github.com/gin-gonic/gin"
+)
+
+type NotifyRouter struct {
+}
+
+func (s *NotifyRouter) InitRouter(Router *gin.RouterGroup) {
+	emailRouter := Router.Use(middleware.OperationRecord())
+	var Controller = api.ApiGroupApp.Api.NotifyController
+	{
+		emailRouter.POST("dingding", Controller)
+	}
+}

+ 7 - 0
server/plugin/notify/service/enter.go

@@ -0,0 +1,7 @@
+package service
+
+type ServiceGroup struct {
+	NotifyService
+}
+
+var ServiceGroupApp = new(ServiceGroup)

+ 114 - 0
server/plugin/notify/service/notify.go

@@ -0,0 +1,114 @@
+package service
+
+import (
+	"bytes"
+	"crypto/hmac"
+	"crypto/sha256"
+	"encoding/base64"
+	"encoding/json"
+	"fmt"
+	"github.com/flipped-aurora/gin-vue-admin/server/plugin/notify/global"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+	"time"
+)
+
+type NotifyService struct {
+}
+
+func SendTextMessage(content string) error {
+	msg := map[string]interface{}{
+		"msgtype": "text",
+		"text": map[string]string{
+			"content": content,
+		},
+		//"at": map[string]interface{}{
+		//	"atMobiles": atMobiles,
+		//	"isAtAll":   isAtAll,
+		//},
+	}
+	return SendMessage(msg)
+}
+
+func SendMessage(msg interface{}) error {
+	body := bytes.NewBuffer(nil)
+	err := json.NewEncoder(body).Encode(msg)
+	if err != nil {
+		return fmt.Errorf("msg json failed, msg: %v, err: %v", msg, err.Error())
+	}
+
+	value := url.Values{}
+	value.Set("access_token", global.GlobalConfig.Token)
+	if global.GlobalConfig.Secret != "" {
+		t := time.Now().UnixNano() / 1e6
+		value.Set("timestamp", fmt.Sprintf("%d", t))
+		value.Set("sign", sign(t, global.GlobalConfig.Secret))
+	}
+
+	request, err := http.NewRequest(http.MethodPost, global.GlobalConfig.Url, body)
+	if err != nil {
+		return fmt.Errorf("error request: %v", err.Error())
+	}
+	request.URL.RawQuery = value.Encode()
+	request.Header.Add("Content-Type", "application/json")
+	res, err := (&http.Client{}).Do(request)
+	if err != nil {
+		return fmt.Errorf("send dingTalk message failed, error: %v", err.Error())
+	}
+	defer func() { _ = res.Body.Close() }()
+	result, err := ioutil.ReadAll(res.Body)
+
+	if res.StatusCode != 200 {
+		return fmt.Errorf("send dingTalk message failed, %s", httpError(request, res, result, "http code is not 200"))
+	}
+	if err != nil {
+		return fmt.Errorf("send dingTalk message failed, %s", httpError(request, res, result, err.Error()))
+	}
+
+	type response struct {
+		ErrCode int `json:"errcode"`
+	}
+	var ret response
+
+	if err := json.Unmarshal(result, &ret); err != nil {
+		return fmt.Errorf("send dingTalk message failed, %s", httpError(request, res, result, err.Error()))
+	}
+
+	if ret.ErrCode != 0 {
+		return fmt.Errorf("send dingTalk message failed, %s", httpError(request, res, result, "errcode is not 0"))
+	}
+
+	return nil
+}
+
+func httpError(request *http.Request, response *http.Response, body []byte, error string) string {
+	return fmt.Sprintf(
+		"http request failure, error: %s, status code: %d, %s %s, body:\n%s",
+		error,
+		response.StatusCode,
+		request.Method,
+		request.URL.String(),
+		string(body),
+	)
+}
+func sign(t int64, secret string) string {
+	strToHash := fmt.Sprintf("%d\n%s", t, secret)
+	hmac256 := hmac.New(sha256.New, []byte(secret))
+	hmac256.Write([]byte(strToHash))
+	data := hmac256.Sum(nil)
+	return base64.StdEncoding.EncodeToString(data)
+}
+
+//@author: [Espoir](https://github.com/nightsimon)
+//@function: NotifyController
+//@description: 钉钉通知测试
+//@return: err error
+
+func (e *NotifyService) Send() (err error) {
+	err = SendTextMessage("test")
+	if err != nil {
+		return err
+	}
+	return err
+}

+ 1 - 0
server/plugin/notify/utils/utils.go

@@ -0,0 +1 @@
+package utils