From 22fbdd774aceed69d9188e07819a9f06f765793c Mon Sep 17 00:00:00 2001 From: huangjiajun <582604932@qq.com> Date: Tue, 8 Aug 2023 10:00:10 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=AC=E4=BC=97=E5=8F=B7=E8=8F=9C=E5=8D=95?= =?UTF-8?q?=E6=A0=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/hdl/hdl_wechat.go | 13 +++++ app/md/md_wechat_menu.go | 27 ++++++++++ app/router/router.go | 2 + app/svc/svc_wechat.go | 110 +++++++++++++++++++++++++++++++++++++++ app/utils/wx.go | 20 +++++++ go.mod | 1 + 6 files changed, 173 insertions(+) create mode 100644 app/hdl/hdl_wechat.go create mode 100644 app/md/md_wechat_menu.go create mode 100644 app/svc/svc_wechat.go diff --git a/app/hdl/hdl_wechat.go b/app/hdl/hdl_wechat.go new file mode 100644 index 0000000..3dcd6a3 --- /dev/null +++ b/app/hdl/hdl_wechat.go @@ -0,0 +1,13 @@ +package hdl + +import ( + "applet/app/svc" + "github.com/gin-gonic/gin" +) + +func GetMenu(c *gin.Context) { + svc.GetMenu(c) +} +func SetMenu(c *gin.Context) { + svc.SetMenu(c) +} diff --git a/app/md/md_wechat_menu.go b/app/md/md_wechat_menu.go new file mode 100644 index 0000000..03599f8 --- /dev/null +++ b/app/md/md_wechat_menu.go @@ -0,0 +1,27 @@ +package md + +type WechatButton struct { + Name string `json:"name"` + SubButton []WechatSubButton `json:"sub_button,omitempty"` +} +type WechatSubButton struct { + Type string `json:"type"` + Name string `json:"name"` + Url string `json:"url"` + Appid string `json:"appid,omitempty"` + Pagepath string `json:"pagepath"` + Key string `json:"key,omitempty"` +} +type OffcialWechatButton struct { + Type string `json:"type,omitempty"` + Name string `json:"name"` + Key string `json:"key,omitempty"` + SubButton SubButtonMap `json:"sub_button,omitempty"` +} +type SubButtonMap struct { + List []WechatSubButton `json:"list"` +} + +type WechatReq struct { + Button []WechatButton `json:"button"` +} diff --git a/app/router/router.go b/app/router/router.go index e540dc7..ab11c51 100644 --- a/app/router/router.go +++ b/app/router/router.go @@ -65,6 +65,8 @@ func route(r *gin.RouterGroup) { r.GET("/qrcodeBatchDownload", hdl.QrcodeBatchDownload) //二维码批次-下载 r.Use(mw.Auth) // 以下接口需要JWT验证 { + r.GET("/wechat_menu/get", hdl.GetMenu) + r.POST("/wechat_menu/set", hdl.SetMenu) r.GET("/userInfo", hdl.UserInfo) //用户信息 r.GET("/sysCfg", hdl.GetSysCfg) //基础配置-获取 r.POST("/sysCfg", hdl.SetSysCfg) //基础配置-设置 diff --git a/app/svc/svc_wechat.go b/app/svc/svc_wechat.go new file mode 100644 index 0000000..d9cfd6c --- /dev/null +++ b/app/svc/svc_wechat.go @@ -0,0 +1,110 @@ +package svc + +import ( + "applet/app/db" + "applet/app/e" + "applet/app/enum" + "applet/app/md" + "applet/app/utils" + "applet/app/utils/cache" + "encoding/json" + "errors" + "github.com/gin-gonic/gin" + "github.com/tidwall/gjson" +) + +func GetMenu(c *gin.Context) { + sysCfgDb := db.SysCfgDb{} + sysCfgDb.Set() + one, _ := sysCfgDb.SysCfgGetOne("wechat_menu") + var menuList = make([]md.WechatButton, 0) + if one != nil && one.Val != "" { + json.Unmarshal([]byte(one.Val), &menuList) + } else { + token, err := GetWechatToken() + if err != nil { + e.OutErr(c, 400, err.Error()) + return + } + var offcialMenuList = make([]md.OffcialWechatButton, 0) + menu, err := utils.GetWechatSelfMenu(token) + menuStr := gjson.Get(menu, "selfmenu_info.button").String() + json.Unmarshal([]byte(menuStr), &offcialMenuList) + for _, v := range offcialMenuList { + var tmp = md.WechatButton{ + Name: v.Name, + SubButton: []md.WechatSubButton{}, + } + for _, v1 := range v.SubButton.List { + var tmpSub = md.WechatSubButton{ + Type: v1.Type, + Name: v1.Name, + Url: "", + Pagepath: "", + Appid: "", + } + if v1.Type == "miniprogram" { + tmpSub.Pagepath = v1.Pagepath + tmpSub.Appid = v1.Appid + tmpSub.Url = v1.Url + } + if v1.Type == "view" { + tmpSub.Url = v1.Url + } + tmp.SubButton = append(tmp.SubButton, tmpSub) + } + menuList = append(menuList, tmp) + } + sysCfgDb.SysCfgUpdate("wechat_menu", utils.SerializeStr(menuList)) + } + res := map[string]interface{}{ + "button": menuList, + } + e.OutSuc(c, res, nil) +} +func SetMenu(c *gin.Context) { + var args md.WechatReq + if err := c.ShouldBindJSON(&args); err != nil { + e.OutErr(c, e.ERR_INVALID_ARGS, err) + return + } + sysCfgDb := db.SysCfgDb{} + sysCfgDb.Set() + sysCfgDb.SysCfgUpdate("wechat_menu", utils.SerializeStr(args.Button)) + token, err := GetWechatToken() + if err != nil { + e.OutErr(c, 400, err.Error()) + return + } + menu, err := utils.SetWechatSelfMenu(token, args) + if err != nil { + e.OutErr(c, 400, err.Error()) + return + } + if gjson.Get(menu, "errcode").Int() != 0 { + e.OutErr(c, 400, e.NewErr(400, gjson.Get(menu, "errmsg").String())) + return + } + e.OutSuc(c, "success", nil) + return +} + +func GetWechatToken() (string, error) { + sysCfgDb := db.SysCfgDb{} + sysCfgDb.Set() + res := sysCfgDb.SysCfgFindWithDb(enum.WxOfficialAccountAppId, enum.WxOfficialAccountAppSecret) + key := "wechat_token" + redisStr, err := cache.GetString(key) + token := redisStr + if redisStr == "" || err != nil { + tokenStr, _ := utils.GetWechatToken(res[enum.WxOfficialAccountAppId], res[enum.WxOfficialAccountAppSecret]) + token = gjson.Get(tokenStr, "access_token").String() + if token == "" { + return "", errors.New(gjson.Get(tokenStr, "errmsg").String()) + } + expiresIn := gjson.Get(tokenStr, "expires_in").Int() + cache.SetEx(key, token, int(expiresIn)) + } + return token, nil + +} diff --git a/app/utils/wx.go b/app/utils/wx.go index 6967da5..e214614 100644 --- a/app/utils/wx.go +++ b/app/utils/wx.go @@ -1,8 +1,10 @@ package utils import ( + "applet/app/md" "crypto/sha1" "encoding/hex" + "fmt" "sort" "strings" ) @@ -29,3 +31,21 @@ func Sha1(str string) string { h.Write([]byte(str)) return hex.EncodeToString(h.Sum(nil)) } + +func GetWechatToken(appid, secret string) (string, error) { + get, err := CurlGet("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appid+"&secret="+secret, nil) + return string(get), err +} + +func GetWechatSelfMenu(token string) (string, error) { + get, err := CurlGet("https://api.weixin.qq.com/cgi-bin/get_current_selfmenu_info?access_token="+token, nil) + return string(get), err +} + +func SetWechatSelfMenu(token string, args md.WechatReq) (string, error) { + str := SerializeStr(args) + str = strings.ReplaceAll(str, "\\u0026", "&") + fmt.Println(str) + get, err := CurlPost("https://api.weixin.qq.com/cgi-bin/menu/create?access_token="+token, str, nil) + return string(get), err +} diff --git a/go.mod b/go.mod index 194e113..cd45cac 100644 --- a/go.mod +++ b/go.mod @@ -36,6 +36,7 @@ require ( github.com/sony/sonyflake v1.0.0 github.com/stretchr/testify v1.7.0 // indirect github.com/syyongx/php2go v0.9.4 + github.com/tidwall/gjson v1.14.1 github.com/ugorji/go v1.2.5 // indirect go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.16.0