Browse Source

公众号菜单栏

master
huangjiajun 1 year ago
parent
commit
22fbdd774a
6 changed files with 173 additions and 0 deletions
  1. +13
    -0
      app/hdl/hdl_wechat.go
  2. +27
    -0
      app/md/md_wechat_menu.go
  3. +2
    -0
      app/router/router.go
  4. +110
    -0
      app/svc/svc_wechat.go
  5. +20
    -0
      app/utils/wx.go
  6. +1
    -0
      go.mod

+ 13
- 0
app/hdl/hdl_wechat.go View File

@@ -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)
}

+ 27
- 0
app/md/md_wechat_menu.go View File

@@ -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"`
}

+ 2
- 0
app/router/router.go View File

@@ -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) //基础配置-设置


+ 110
- 0
app/svc/svc_wechat.go View File

@@ -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

}

+ 20
- 0
app/utils/wx.go View File

@@ -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
}

+ 1
- 0
go.mod View File

@@ -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


Loading…
Cancel
Save