dengbiao 3 mesi fa
parent
commit
e37ea8b29f
22 ha cambiato i file con 3563 aggiunte e 53 eliminazioni
  1. +1
    -1
      app/db/dao/sys_cfg_dao.go
  2. +5
    -5
      app/db/implement/sys_cfg_implement.go
  3. +0
    -7
      app/db/model/sys_cfg.go
  4. +57
    -0
      app/enum/enum_sys_cfg.go
  5. +464
    -0
      app/hdl/hdl_set_center.go
  6. +64
    -0
      app/lib/wechat/enum/adunit_enum.go
  7. +68
    -0
      app/lib/wechat/helpers.go
  8. +7
    -0
      app/lib/wechat/md/cache_key_md.go
  9. +62
    -0
      app/lib/wechat/md/wechat_api_md.go
  10. +254
    -0
      app/lib/wechat/message.go
  11. +61
    -0
      app/lib/wechat/prpcrypt.go
  12. +322
    -0
      app/lib/wechat/wechat_api.go
  13. +11
    -0
      app/lib/wechat/wechat_err_code.go
  14. +200
    -0
      app/lib/wechat/wechat_message.go
  15. +50
    -0
      app/md/md_oss_bucket_region.go
  16. +49
    -0
      app/md/md_set_center.go
  17. +24
    -0
      app/router/router.go
  18. +17
    -39
      app/svc/svc_sys_cfg_get.go
  19. +690
    -0
      docs/docs.go
  20. +690
    -0
      docs/swagger.json
  21. +466
    -0
      docs/swagger.yaml
  22. +1
    -1
      go.mod

+ 1
- 1
app/db/dao/sys_cfg_dao.go Vedi File

@@ -1,6 +1,6 @@
package dao

import "applet/app/db/model"
import "code.fnuoos.com/zhimeng/model.git/src/model"

type SysCfgDao interface {
SysCfgGetAll() (*[]model.SysCfg, error)


+ 5
- 5
app/db/implement/sys_cfg_implement.go Vedi File

@@ -2,10 +2,10 @@

import (
"applet/app/db/dao"
"applet/app/db/model"
"applet/app/md"
"applet/app/utils/cache"
"applet/app/utils/logx"
"code.fnuoos.com/zhimeng/model.git/src/model"
"fmt"
"xorm.io/xorm"
)
@@ -51,7 +51,7 @@ func (s SysCfgDb) SysCfgGetOne(key string) (*model.SysCfg, error) {
}

func (s SysCfgDb) SysCfgInsert(key, val, memo string) bool {
cfg := model.SysCfg{Key: key, Val: val, Memo: memo}
cfg := model.SysCfg{K: key, V: val, Memo: memo}
_, err := s.Db.InsertOne(&cfg)
if err != nil {
logx.Error(err)
@@ -61,7 +61,7 @@ func (s SysCfgDb) SysCfgInsert(key, val, memo string) bool {
}

func (s SysCfgDb) SysCfgUpdate(key, val string) bool {
cfg := model.SysCfg{Key: key, Val: val}
cfg := model.SysCfg{K: key, V: val}
_, err := s.Db.Where("`key`=?", key).Cols("val").Update(&cfg)
if err != nil {
logx.Error(err)
@@ -88,7 +88,7 @@ func (s SysCfgDb) SysCfgGetWithDb(HKey string) string {
}

// 设置缓存
_, err = cache.HSet(cacheKey, HKey, cfg.Val)
_, err = cache.HSet(cacheKey, HKey, cfg.V)
if err != nil {
_ = logx.Error(err)
return ""
@@ -100,7 +100,7 @@ func (s SysCfgDb) SysCfgGetWithDb(HKey string) string {
return ""
}
}
return cfg.Val
return cfg.V
}
return get
}


+ 0
- 7
app/db/model/sys_cfg.go Vedi File

@@ -1,7 +0,0 @@
package model

type SysCfg struct {
Key string `json:"key" xorm:"not null pk comment('键') VARCHAR(127)"`
Val string `json:"val" xorm:"comment('值') TEXT"`
Memo string `json:"memo" xorm:"not null default '' comment('备注') VARCHAR(255)"`
}

+ 57
- 0
app/enum/enum_sys_cfg.go Vedi File

@@ -0,0 +1,57 @@
package enum

type SysCfg string

const (
AppName = "app_name"

FileBucketHost = "file_bucket_host"
FileBucketRegion = "file_bucket_region"
FileBucketScheme = "file_bucket_scheme"
FileExt = "file_ext"
FileSecretKey = "file_secret_key"
FileUserUploadMaxSize = "file_user_upload_max_size"
FileAccessKey = "file_access_key"
FileBucket = "file_bucket"

WxOpenAppletServerDomain = "wx_open_applet_server_domain"
WxOpenAuthorizationEventReceivingConfiguration = "wx_open_authorization_event_receiving_configuration"
WxOpenDomainOfTheInitiatingPageForLoginAuthorization = "wx_open_domain_of_the_initiating_page_for_login_authorization"
WxOpenMessageAndEventReceptionConfiguration = "wx_open_message_and_event_reception_configuration"
WxOpenWhiteListIp = "wx_open_white_list_ip"
)

func (gt SysCfg) String() string {
switch gt {
case AppName:
return "项目名称"
case FileBucketHost:
return "对象存储域名"
case FileBucketRegion:
return "对象存储域名"
case FileBucketScheme:
return "文件上传模式"
case FileExt:
return "文件上传后缀,后台用户不限制后缀"
case FileSecretKey:
return "对象存储SecretToken"
case FileUserUploadMaxSize:
return "用户单文件最大上传大小,byte"
case FileAccessKey:
return "对象存储AccessToken"
case FileBucket:
return "对象存储bucket"
case WxOpenAppletServerDomain:
return "微信开放平台-小程序服务器域名"
case WxOpenAuthorizationEventReceivingConfiguration:
return "微信开放平台-授权事件接收配置"
case WxOpenDomainOfTheInitiatingPageForLoginAuthorization:
return "微信开放平台-登录授权的发起页域名"
case WxOpenMessageAndEventReceptionConfiguration:
return "微信开放平台-消息与事件接收配置"
case WxOpenWhiteListIp:
return "微信开放平台-白名单ip"
default:
return "未知"
}
}

+ 464
- 0
app/hdl/hdl_set_center.go Vedi File

@@ -0,0 +1,464 @@
package hdl

import (
"applet/app/cfg"
implement2 "applet/app/db/implement"
"applet/app/e"
"applet/app/enum"
"applet/app/lib/validate"
"applet/app/lib/wechat"
"applet/app/md"
"applet/app/svc"
"applet/app/utils"
db "code.fnuoos.com/zhimeng/model.git/src"
"code.fnuoos.com/zhimeng/model.git/src/super/implement"
"code.fnuoos.com/zhimeng/model.git/src/super/model"
"github.com/gin-gonic/gin"
"time"
)

// SetOss
// @Summary oss设置
// @Tags 设置中心-基础设置
// @Description 基础设置-oss设置
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Accept json
// @Produce json
// @Param args body md.SetOssReq true "请求参数"
// @Success 200 {string} "success"
// @Failure 400 {object} md.Response "具体错误"
// @Router /api/setCenter/basic/setOss [POST]
func SetOss(c *gin.Context) {
var req md.SetOssReq
err := c.ShouldBindJSON(&req)
if err != nil {
err = validate.HandleValidateErr(err)
err1 := err.(e.E)
e.OutErr(c, err1.Code, err1.Error())
return
}
masterId := svc.GetMasterId(c)
engine := db.DBs[masterId]
sysCfgDb := implement2.NewSysCfgDb(engine, masterId)
sysCfgDb.SysCfgUpdate(enum.FileAccessKey, req.FileAccessKey)
sysCfgDb.SysCfgUpdate(enum.FileSecretKey, req.FileSecretKey)
sysCfgDb.SysCfgUpdate(enum.FileBucketHost, req.FileBucketHost)
sysCfgDb.SysCfgUpdate(enum.FileBucketRegion, req.FileBucketRegion)
sysCfgDb.SysCfgUpdate(enum.FileBucket, req.FileBucket)
e.OutSuc(c, "success", nil)
return
}

// GetOss
// @Summary oss获取
// @Tags 设置中心-基础设置
// @Description 基础设置-oss获取
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Accept json
// @Produce json
// @Success 200 {object} md.SetOssResp
// @Failure 400 {object} md.Response "具体错误"
// @Router /api/setCenter/basic/getOss [GET]
func GetOss(c *gin.Context) {
masterId := svc.GetMasterId(c)
engine := db.DBs[masterId]
sysCfgDb := implement2.NewSysCfgDb(engine, masterId)
res := sysCfgDb.SysCfgFindWithDb(enum.FileAccessKey, enum.FileSecretKey, enum.FileBucketHost, enum.FileBucketRegion, enum.FileBucket)

e.OutSuc(c, md.SetOssResp{
Data: md.SetOssReq{
FileAccessKey: res[enum.FileAccessKey],
FileSecretKey: res[enum.FileSecretKey],
FileBucketHost: res[enum.FileBucketHost],
FileBucketRegion: res[enum.FileBucketRegion],
FileBucket: res[enum.FileBucket],
},
QiNiuBucketRegionList: md.QiNiuBucketRegionList,
}, nil)
return
}

// WxOpenSet
// @Summary 微信三方应用设置
// @Tags 设置中心-基础设置
// @Description 基础设置-微信三方应用设置
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Accept json
// @Produce json
// @Param args body md.WxOpenSetReq true "请求参数"
// @Success 200 {string} "success"
// @Failure 400 {object} md.Response "具体错误"
// @Router /api/setCenter/basic/wxOpenSet [POST]
func WxOpenSet(c *gin.Context) {
var req md.WxOpenSetReq
err := c.ShouldBindJSON(&req)
if err != nil {
err = validate.HandleValidateErr(err)
err1 := err.(e.E)
e.OutErr(c, err1.Code, err1.Error())
return
}
masterId := svc.GetMasterId(c)
//1、查找对应 wx_open_third_party_app_list 记录
wxOpenThirdPartyAppListDb := implement.NewWxOpenThirdPartyAppListDb(db.Db)
UserWxAppletList, err := wxOpenThirdPartyAppListDb.GetWxOpenThirdPartyAppList(utils.StrToInt(masterId))
if err != nil {
e.OutErr(c, e.ERR_DB_ORM, err.Error())
return
}
if UserWxAppletList == nil {
UserWxAppletList = &model.WxOpenThirdPartyAppList{
Uuid: utils.StrToInt(masterId),
Token: req.Token,
AesKey: req.AesKey,
Appid: req.Appid,
AppSecret: req.AppSecret,
ComponentVerifyTicket: "",
ComponentAccessToken: "",
CreateAt: time.Now().Format("2006-01-02 15:04:05"),
UpdateAt: time.Now().Format("2006-01-02 15:04:05"),
}
_, err = wxOpenThirdPartyAppListDb.WxOpenThirdPartyAppListInsert(UserWxAppletList)
if err != nil {
e.OutErr(c, e.ERR_DB_ORM, err.Error())
return
}
} else {
UserWxAppletList.Token = req.Token
UserWxAppletList.AesKey = req.AesKey
UserWxAppletList.Appid = req.Appid
UserWxAppletList.AppSecret = req.AppSecret
_, err = wxOpenThirdPartyAppListDb.UpdateWxOpenThirdPartyAppList(UserWxAppletList,
"token", "aes_key", "appid", "app_secret")
if err != nil {
e.OutErr(c, e.ERR_DB_ORM, err.Error())
return
}
}
e.OutSuc(c, "success", nil)
return
}

// WxOpenGet
// @Summary 微信三方应用获取
// @Tags 设置中心-基础设置
// @Description 基础设置-微信三方应用获取
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Accept json
// @Produce json
// @Success 200 {object} md.WxOpenGetResp
// @Failure 400 {object} md.Response "具体错误"
// @Router /api/setCenter/basic/wxOpenGet [GET]
func WxOpenGet(c *gin.Context) {
masterId := svc.GetMasterId(c)
//1、查找对应 wx_open_third_party_app_list 记录
wxOpenThirdPartyAppListDb := implement.NewWxOpenThirdPartyAppListDb(db.Db)
UserWxAppletList, err := wxOpenThirdPartyAppListDb.GetWxOpenThirdPartyAppList(utils.StrToInt(masterId))
if err != nil {
e.OutErr(c, e.ERR_DB_ORM, err.Error())
return
}
if UserWxAppletList == nil {
UserWxAppletList = &model.WxOpenThirdPartyAppList{
Uuid: utils.StrToInt(masterId),
Token: "",
AesKey: "",
Appid: "",
AppSecret: "",
ComponentVerifyTicket: "",
ComponentAccessToken: "",
CreateAt: time.Now().Format("2006-01-02 15:04:05"),
UpdateAt: time.Now().Format("2006-01-02 15:04:05"),
}
_, err = wxOpenThirdPartyAppListDb.WxOpenThirdPartyAppListInsert(UserWxAppletList)
if err != nil {
e.OutErr(c, e.ERR_DB_ORM, err.Error())
return
}
}
sysCfgDb := implement2.NewSysCfgDb(db.Db, "")
res := sysCfgDb.SysCfgFindWithDb(enum.WxOpenAppletServerDomain, enum.WxOpenAuthorizationEventReceivingConfiguration,
enum.WxOpenDomainOfTheInitiatingPageForLoginAuthorization, enum.WxOpenMessageAndEventReceptionConfiguration, enum.WxOpenWhiteListIp)
e.OutSuc(c, md.WxOpenGetResp{
Token: UserWxAppletList.Token,
AesKey: UserWxAppletList.AesKey,
Appid: UserWxAppletList.Appid,
AppSecret: UserWxAppletList.AppSecret,
WxOpenAppletServerDomain: res[enum.WxOpenAppletServerDomain],
WxOpenAuthorizationEventReceivingConfiguration: res[enum.WxOpenAuthorizationEventReceivingConfiguration],
WxOpenDomainOfTheInitiatingPageForLoginAuthorization: res[enum.WxOpenDomainOfTheInitiatingPageForLoginAuthorization],
WxOpenMessageAndEventReceptionConfiguration: res[enum.WxOpenMessageAndEventReceptionConfiguration],
WxOpenWhiteListIp: res[enum.WxOpenWhiteListIp],
}, nil)
return
}

type WxOpenThirdPartyAppList struct {
Id int `json:"id" xorm:"not null pk autoincr unique(IDX_UUID_TYPE) INT(11)"`
Uuid int `json:"uuid" xorm:"not null comment('站长id') index unique(IDX_UUID_TYPE) INT(10)"`
Token string `json:"token" xorm:"not null default '' comment('消息校验Token') VARCHAR(255)"`
AesKey string `json:"aes_key" xorm:"not null default '' comment('消息加解密Key') VARCHAR(255)"`
Appid string `json:"appid" xorm:"not null default '' comment('appid') CHAR(50)"`
AppSecret string `json:"app_secret" xorm:"not null default '' comment('appSecret') VARCHAR(255)"`
ComponentVerifyTicket string `json:"component_verify_ticket" xorm:"not null default '' comment('验证票据') VARCHAR(255)"`
ComponentAccessToken string `json:"component_access_token" xorm:"not null default '' comment('接口令牌') VARCHAR(255)"`
CreateAt string `json:"create_at" xorm:"not null default 'CURRENT_TIMESTAMP' DATETIME"`
UpdateAt string `json:"update_at" xorm:"not null default 'CURRENT_TIMESTAMP' DATETIME"`
}

// AppletList
// @Summary 列表
// @Tags 设置中心-小程序设置
// @Description 小程序设置-列表
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Accept json
// @Produce json
// @Success 200 {object} WxOpenThirdPartyAppList
// @Failure 400 {object} md.Response "具体错误"
// @Router /api/setCenter/applet/list [GET]
func AppletList(c *gin.Context) {
masterId := svc.GetMasterId(c)
//1、查找对应 user_wx_applet_list 记录
userWxAppletListDb := implement.NewUserWxAppletListDb(db.Db)
UserWxAppletList, err := userWxAppletListDb.GetUserWxAppletList(masterId)
if err != nil {
e.OutErr(c, e.ERR_DB_ORM, err.Error())
return
}
e.OutSuc(c, UserWxAppletList, nil)
return
}

// AppletAdd
// @Summary 新增
// @Tags 设置中心-小程序设置
// @Description 小程序设置-新增
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Accept json
// @Produce json
// @Param args body md.AppletAddReq true "请求参数"
// @Success 200 {string} "success"
// @Failure 400 {object} md.Response "具体错误"
// @Router /api/setCenter/applet/add [POST]
func AppletAdd(c *gin.Context) {
var req md.AppletAddReq
err := c.ShouldBindJSON(&req)
if err != nil {
err = validate.HandleValidateErr(err)
err1 := err.(e.E)
e.OutErr(c, err1.Code, err1.Error())
return
}
masterId := svc.GetMasterId(c)
//1、查找对应 user_wx_applet_list 记录
userWxAppletListDb := implement.NewUserWxAppletListDb(db.Db)
UserWxAppletList, err := userWxAppletListDb.GetUserWxAppletList(masterId)
if err != nil {
e.OutErr(c, e.ERR_DB_ORM, err.Error())
return
}
if UserWxAppletList != nil {
e.OutErr(c, e.ERR, "当前仅支持单个小程序")
return
}
_, err = userWxAppletListDb.UserWxAppletListInsert(&model.UserWxAppletList{
Name: req.Name,
Logo: req.Logo,
Appid: req.Appid,
OriginalId: req.OriginalId,
AuthorizerRefreshToken: "",
IsAuth: 0,
Uuid: masterId,
CreateAt: time.Now().Format("2006-01-02 15:04:05"),
UpdateAt: time.Now().Format("2006-01-02 15:04:05"),
})
if err != nil {
e.OutErr(c, e.ERR_DB_ORM, err.Error())
return
}

e.OutSuc(c, "success", nil)
return
}

// AppletUpdate
// @Summary 更新
// @Tags 设置中心-小程序设置
// @Description 小程序设置-更新
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Accept json
// @Produce json
// @Param args body md.AppletUpdateReq true "请求参数"
// @Success 200 {string} "success"
// @Failure 400 {object} md.Response "具体错误"
// @Router /api/setCenter/applet/update [POST]
func AppletUpdate(c *gin.Context) {
var req md.AppletUpdateReq
err := c.ShouldBindJSON(&req)
if err != nil {
err = validate.HandleValidateErr(err)
err1 := err.(e.E)
e.OutErr(c, err1.Code, err1.Error())
return
}
masterId := svc.GetMasterId(c)
//1、查找对应 user_wx_applet_list 记录
userWxAppletListDb := implement.NewUserWxAppletListDb(db.Db)
UserWxAppletList, err := userWxAppletListDb.GetUserWxAppletList(masterId)
if err != nil {
e.OutErr(c, e.ERR_DB_ORM, err.Error())
return
}
if UserWxAppletList == nil {
e.OutErr(c, e.ERR_NO_DATA, "未查询到对应记录")
return
}
UserWxAppletList.Logo = req.Logo
UserWxAppletList.Name = req.Logo
_, err = userWxAppletListDb.UpdateUserWxAppletList(UserWxAppletList, "logo", "name")
if err != nil {
e.OutErr(c, e.ERR_DB_ORM, err.Error())
return
}

e.OutSuc(c, "success", nil)
return
}

// AppletDelete
// @Summary 删除
// @Tags 设置中心-小程序设置
// @Description 小程序设置-删除
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Accept json
// @Produce json
// @Success 200 {string} "success"
// @Failure 400 {object} md.Response "具体错误"
// @Router /v1/banner/delete/{$id} [DELETE]
func AppletDelete(c *gin.Context) {
id := c.Param("id")

masterId := svc.GetMasterId(c)
//1、查找对应 user_wx_applet_list 记录
userWxAppletListDb := implement.NewUserWxAppletListDb(db.Db)
UserWxAppletList, err := userWxAppletListDb.GetUserWxAppletList(masterId)
if err != nil {
e.OutErr(c, e.ERR_DB_ORM, err.Error())
return
}
if UserWxAppletList == nil {
e.OutErr(c, e.ERR_NO_DATA, "未查询到对应记录")
return
}

_, err = userWxAppletListDb.UserWxAppletListDelete(id)
if err != nil {
e.OutErr(c, e.ERR_DB_ORM, err.Error())
return
}
e.OutSuc(c, "success", nil)
return
}

// AppletAuthorize
// @Summary 设置中心-基础设置-微信三方应用获取
// @Tags 设置中心
// @Description 设置中心-基础设置
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Accept json
// @Produce json
// @Success 200 {string} "微信授权界面url"
// @Failure 400 {object} md.Response "具体错误"
// @Router /api/setCenter/applet/authorize [GET]
func AppletAuthorize(c *gin.Context) {
masterId := svc.GetMasterId(c)
url := "http://super.advertisement.dengbiao.top/api/wxOpen/getPreAuthCode?master_id=" + masterId
if cfg.Prd {
url = "http://super.advertisement.dengbiao.top/api/wxOpen/getPreAuthCode?master_id=" + masterId
}
e.OutSuc(c, map[string]string{
"url": url,
}, nil)
return
}

// AppletUnauthorized
// @Summary 设置中心-基础设置-微信三方应用获取
// @Tags 设置中心
// @Description 设置中心-基础设置
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Accept json
// @Produce json
// @Success 200 {string} "success"
// @Failure 400 {object} md.Response "具体错误"
// @Router /api/setCenter/applet/unauthorized [GET]
func AppletUnauthorized(c *gin.Context) {
appId := c.DefaultQuery("app_id", "")
masterId := svc.GetMasterId(c)
//1、查找对应 user_wx_applet_list 记录
userWxAppletListDb := implement.NewUserWxAppletListDb(db.Db)
UserWxAppletList, err := userWxAppletListDb.GetUserWxAppletList(masterId)
if err != nil {
e.OutErr(c, e.ERR_DB_ORM, err.Error())
return
}
if UserWxAppletList == nil {
e.OutErr(c, e.ERR_NO_DATA, "未查询到对应记录")
return
}

wxOpenThirdPartyAppListDb := implement.NewWxOpenThirdPartyAppListDb(db.Db)
wxOpenThirdPartyAppList, err := wxOpenThirdPartyAppListDb.GetWxOpenThirdPartyAppList(utils.StrToInt(masterId))
if err != nil {
e.OutErr(c, e.ERR, err.Error())
return
}
if wxOpenThirdPartyAppList == nil {
e.OutErr(c, e.ERR_NOT_FAN, "未查询到对应三方应用记录")
return
}

wxApiService, err := wechat.NewWxApiService(masterId, wxOpenThirdPartyAppList.Appid, wxOpenThirdPartyAppList.AppSecret)
if err != nil {
e.OutErr(c, e.ERR, err.Error())
return
}
err = wxApiService.DelAuthorize(appId)
if err != nil {
e.OutErr(c, e.ERR, err.Error())
return
}
e.OutSuc(c, "success", nil)
return
}

// ShareIndex
// @Summary 邀请链接
// @Tags 设置中心-邀请链接
// @Description 邀请链接界面接口
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Accept json
// @Produce json
// @Success 200 {object} md.ShareIndexResp
// @Failure 400 {object} md.Response "具体错误"
// @Router /api/setCenter/share/index [GET]
func ShareIndex(c *gin.Context) {
masterId := svc.GetMasterId(c)
userAppDomainDb := implement.NewUserAppDomainDb(db.DBs[masterId])
agent, err := userAppDomainDb.GetAppDomainByType("agent", masterId)
if err != nil {
e.OutErr(c, e.ERR_DB_ORM, err.Error())
return
}
medium, err := userAppDomainDb.GetAppDomainByType("medium", masterId)
if err != nil {
e.OutErr(c, e.ERR_DB_ORM, err.Error())
return
}
e.OutSuc(c, md.ShareIndexResp{
MasterId: masterId,
AgentDomain: agent.Domain,
MediumDomain: medium.Domain,
}, nil)
return
}

+ 64
- 0
app/lib/wechat/enum/adunit_enum.go Vedi File

@@ -0,0 +1,64 @@
package enum

type AdunitType string //广告单元类型

const (
AdunitTypeForBanner = "SLOT_ID_WEAPP_BANNER"
AdunitTypeForRewardVideo = "SLOT_ID_WEAPP_REWARD_VIDEO"
AdunitTypeForInterstitial = "SLOT_ID_WEAPP_INTERSTITIAL"
AdunitTypeForVideoFeeds = "SLOT_ID_WEAPP_VIDEO_FEEDS"
AdunitTypeForVideoBegin = "SLOT_ID_WEAPP_VIDEO_BEGIN"
)

func (gt AdunitType) String() string {
switch gt {
case AdunitTypeForBanner:
return "小程序banner"
case AdunitTypeForRewardVideo:
return "小程序激励视频"
case AdunitTypeForInterstitial:
return "小程序插屏广告"
case AdunitTypeForVideoFeeds:
return "小程序视频广告"
case AdunitTypeForVideoBegin:
return "小程序视频贴片广告"
default:
return "未知"
}
}

type AdunitStatus string //广告单元开关状态

const (
AdunitStatusForOn = "AD_UNIT_STATUS_ON"
AdunitStatusForOff = "AD_UNIT_STATUS_OFF"
)

func (gt AdunitStatus) String() string {
switch gt {
case AdunitStatusForOn:
return "开通"
case AdunitStatusForOff:
return "关闭"
default:
return "未知"
}
}

type SetCoverAdposStatus int32 //广告单元开关状态

const (
SetCoverAdposStatusForOn = 1
SetCoverAdposStatusForOff = 4
)

func (gt SetCoverAdposStatus) String() string {
switch gt {
case SetCoverAdposStatusForOn:
return "开通"
case SetCoverAdposStatusForOff:
return "关闭"
default:
return "未知"
}
}

+ 68
- 0
app/lib/wechat/helpers.go Vedi File

@@ -0,0 +1,68 @@
package wechat

import (
"bytes"
"crypto/sha1"
"fmt"
"io"
"math/rand"
"sort"
"strings"
)

// GetSignature 获取签名
func GetSignature(timestamp, nonce string, encrypted string, token string) string {
data := []string{
encrypted,
token,
timestamp,
nonce,
}
sort.Strings(data)
s := sha1.New()
_, err := io.WriteString(s, strings.Join(data, ""))
if err != nil {
panic("签名错误:sign error")
}
return fmt.Sprintf("%x", s.Sum(nil))
}

func makeRandomString(length int) string {
randStr := ""
strSource := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyl"
maxLength := len(strSource) - 1
for i := 0; i < length; i++ {
randomNum := rand.Intn(maxLength)
randStr += strSource[randomNum : randomNum+1]
}
return randStr
}

func pKCS7Pad(plainText []byte, blockSize int) []byte {
// block size must be bigger or equal 2
if blockSize < 1<<1 {
panic("block size is too small (minimum is 2 bytes)")
}
// block size up to 255 requires 1 byte padding
if blockSize < 1<<8 {
// calculate padding length
padLen := padLength(len(plainText), blockSize)

// define PKCS7 padding block
padding := bytes.Repeat([]byte{byte(padLen)}, padLen)

// apply padding
padded := append(plainText, padding...)
return padded
}
// block size bigger or equal 256 is not currently supported
panic("unsupported block size")
}

func padLength(sliceLength, blockSize int) int {
padLen := blockSize - sliceLength%blockSize
if padLen == 0 {
padLen = blockSize
}
return padLen
}

+ 7
- 0
app/lib/wechat/md/cache_key_md.go Vedi File

@@ -0,0 +1,7 @@
package md

const (
MasterComponentVerifyTicket = "master_component_verify_ticket:%s"
MasterComponentAccessToken = "master_component_access_token:%s"
//MasterApiAuthorizerToken = "master_api_authorizer_token:%s:%s" //站长id:小程序授权id
)

+ 62
- 0
app/lib/wechat/md/wechat_api_md.go Vedi File

@@ -0,0 +1,62 @@
package md

type GetComponentAccessToken struct {
ComponentAccessToken string `json:"component_access_token" example:"第三方平台 access_token"`
ExpiresIn int `json:"expires_in" example:"有效期,单位:秒"`
}

type GetPreAuthCode struct {
PreAuthCode string `json:"pre_auth_code" example:"预授权码"`
ExpiresIn int `json:"expires_in" example:"有效期,单位:秒"`
}

type GetAuthorizerAccessTokenByAuthCode struct {
AuthorizationInfo struct {
AuthorizerAppid string `json:"authorizer_appid" example:"授权方 appid"`
AuthorizerAccessToken string `json:"authorizer_access_token" example:"接口调用令牌"`
ExpiresIn int `json:"expires_in" example:"authorizer_access_token 的有效期(在授权的公众号/小程序具备API权限时,才有此返回值),单位:秒"`
AuthorizerRefreshToken string `json:"authorizer_refresh_token" example:"刷新令牌(在授权的公众号具备API权限时,才有此返回值),刷新令牌主要用于第三方平台获取和刷新已授权用户的 authorizer_access_token。一旦丢失,只能让用户重新授权,才能再次拿到新的刷新令牌。用户重新授权后,之前的刷新令牌会失效"`
} `json:"authorization_info" example:"预授权码"`
}

type ApiAuthorizerToken struct {
AuthorizerAccessToken string `json:"authorizer_access_token" example:"接口调用令牌"`
ExpiresIn int `json:"expires_in" example:"authorizer_access_token 的有效期(在授权的公众号/小程序具备API权限时,才有此返回值),单位:秒"`
AuthorizerRefreshToken string `json:"authorizer_refresh_token" example:"刷新令牌(在授权的公众号具备API权限时,才有此返回值),刷新令牌主要用于第三方平台获取和刷新已授权用户的 authorizer_access_token。一旦丢失,只能让用户重新授权,才能再次拿到新的刷新令牌。用户重新授权后,之前的刷新令牌会失效"`
}

type DelAuthorize struct {
ErrCode int `json:"errcode" example:"错误码"`
ErrMsg string `json:"errmsg" example:"错误信息"`
}

type AgencyCreateAdunit struct {
Ret int `json:"ret" example:"错误码"`
ErrMsg string `json:"err_msg" example:"错误信息"`
AdUnitId string `json:"ad_unit_id" example:"广告单元ID"`
}

type AgencyUpdateAdunit struct {
Ret int `json:"ret" example:"错误码"`
ErrMsg string `json:"err_msg" example:"错误信息"`
}

type SetCoverAdposStatus struct {
Ret int `json:"ret" example:"错误码"`
ErrMsg string `json:"err_msg" example:"错误信息"`
}

type GetAdunitList struct {
Ret int `json:"ret" example:"错误码"`
ErrMsg string `json:"err_msg" example:"错误信息"`
AdUnit []struct {
AdSlot string `json:"ad_slot" example:"广告位类型名称"`
AdUnitId string `json:"ad_unit_id" example:"广告单元ID"`
AdUnitName string `json:"ad_unit_name" example:"广告单元名称"`
AdUnitSize []map[string]interface{} `json:"ad_unit_size" example:"广告单元大小"`
AdUnitStatus int `json:"ad_unit_status" example:"广告单元开关状态 1:开启 2:关闭"`
VideoDurationMax int `json:"video_duration_max" example:"广告展示时长最大值"`
VideoDurationMin int `json:"video_duration_min" example:"广告展示时长最小值"`
} `json:"ad_unit"`
TotalNum int `json:"total_num" example:"总广告单元数据量"`
}

+ 254
- 0
app/lib/wechat/message.go Vedi File

@@ -0,0 +1,254 @@
package wechat

import (
"bytes"
"encoding/binary"
"encoding/xml"
"errors"
"strconv"
"time"
)

var EventTicket = "component_verify_ticket" //ticket推送
var EventUnauthorized = "unauthorized" //取消授权
var EventUpdateAuthorized = "updateauthorized" //更新授权
var EventAuthorized = "authorized" //授权成功

var MsgTypeText = "text" //文本消息
var MsgTypeImage = "image" //文本消息
var MsgTypeVoice = "voice" //语音消息
var MsgTypeVideo = "Video" //视频消息
var MsgTypeMusic = "music" //音乐消息
var MsgTypeNews = "news" //图文消息

// EventMessageBody 事件推送
type EventMessageBody struct {
XMLName xml.Name `xml:"xml"`
AppId string `xml:"AppId" json:"app_id"`
CreateTime int `xml:"CreateTime" json:"create_time"`
InfoType string `xml:"InfoType" json:"info_type"`
ComponentVerifyTicket string `xml:"ComponentVerifyTicket" json:"component_verify_ticket"`
AuthorizerAppid string `xml:"AuthorizerAppid" json:"authorizer_appid"`
AuthorizationCode string `xml:"AuthorizationCode" json:"authorization_code"`
AuthorizationCodeExpiredTime string `xml:"AuthorizationCodeExpiredTime" json:"authorization_code_expired_time"`
PreAuthCode string `xml:"PreAuthCode" json:"pre_auth_code"`
}

// MessageBodyDecrypt 消息体
type MessageBodyDecrypt struct {
XMLName xml.Name `xml:"xml"`
ToUserName string `xml:"ToUserName"`
FromUserName string `xml:"FromUserName"`
CreateTime string `xml:"CreateTime"`
MsgType string `xml:"MsgType"`
Url string `xml:"Url"`
PicUrl string `xml:"PicUrl"`
MediaId string `xml:"MediaId"`
ThumbMediaId string `xml:"ThumbMediaId"`
Content string `xml:"Content"`
MsgId int `xml:"MsgId"`
Location_X string `xml:"Location_x"`
Location_Y string `xml:"Location_y"`
Label string `xml:"Label"`
}

type MessageEncryptBody struct {
XMLName xml.Name `xml:"xml"`
Encrypt CDATA `xml:"Encrypt"`
MsgSignature CDATA `xml:"MsgSignature"`
TimeStamp string `xml:"TimeStamp"`
Nonce CDATA `xml:"Nonce"`
}

type MessageText struct {
XMLName xml.Name `xml:"xml"`
ToUserName CDATA `xml:"ToUserName"`
FromUserName CDATA `xml:"FromUserName"`
CreateTime string `xml:"CreateTime"`
MsgType CDATA `xml:"MsgType"`
Content CDATA `xml:"Content"`
}

type MessageImage struct {
XMLName xml.Name `xml:"xml"`
ToUserName CDATA `xml:"ToUserName"`
FromUserName CDATA `xml:"FromUserName"`
CreateTime string `xml:"CreateTime"`
MsgType CDATA `xml:"MsgType"`
Image Media `xml:"Image"`
}

type MessageVoice struct {
XMLName xml.Name `xml:"xml"`
ToUserName CDATA `xml:"ToUserName"`
FromUserName CDATA `xml:"FromUserName"`
CreateTime string `xml:"CreateTime"`
MsgType CDATA `xml:"MsgType"`
Voice Media `xml:"Voice"`
}

type MessageVideo struct {
XMLName xml.Name `xml:"xml"`
ToUserName CDATA `xml:"ToUserName"`
FromUserName CDATA `xml:"FromUserName"`
CreateTime string `xml:"CreateTime"`
MsgType CDATA `xml:"MsgType"`
Video Video `xml:"Video"`
}

type MessageMusic struct {
XMLName xml.Name `xml:"xml"`
ToUserName CDATA `xml:"ToUserName"`
FromUserName CDATA `xml:"FromUserName"`
CreateTime string `xml:"CreateTime"`
MsgType CDATA `xml:"MsgType"`
Music Music `xml:"Music"`
}

type MessageArticle struct {
XMLName xml.Name `xml:"xml"`
ToUserName CDATA `xml:"ToUserName"`
FromUserName CDATA `xml:"FromUserName"`
CreateTime string `xml:"CreateTime"`
MsgType CDATA `xml:"MsgType"`
ArticleCount string `xml:"ArticleCount"`
Articles []ArticleItem `xml:"Articles"`
}

type CDATA struct {
Text string `xml:",innerxml"`
}

type Media struct {
MediaId CDATA `xml:"MediaId"`
}

type Video struct {
MediaId CDATA `xml:"MediaId"`
Title CDATA `xml:"Title"`
Description CDATA `xml:"Description"`
}

type Music struct {
Title CDATA `xml:"Title"`
Description CDATA `xml:"Description"`
MusicUrl CDATA `xml:"MusicUrl"`
HQMusicUrl CDATA `xml:"HQMusicUrl"`
ThumbMediaId CDATA `xml:"ThumbMediaId"`
}

type ArticleItem struct {
Title CDATA `xml:"Title"`
Description CDATA `xml:"Description"`
PicUrl CDATA `xml:"PicUrl"`
Url CDATA `xml:"Url"`
}

func FormatMessage(plainText []byte, data interface{}) (*interface{}, error) {
length := GetMessageLength(plainText)
err := xml.Unmarshal(plainText[20:20+length], data)
if err != nil {
return nil, errors.New("格式化消息失败:format message error")
}
return &data, nil
}

func GetMessageLength(plainText []byte) int32 {
// Read length
buf := bytes.NewBuffer(plainText[16:20])
var length int32
err := binary.Read(buf, binary.BigEndian, &length)
if err != nil {
panic("获取消息长度失败:read message length error")
}
return length
}

func ValueToCDATA(content string) CDATA {
return CDATA{"<![CDATA[" + content + "]]>"}
}

// FormatTextMessage 格式化文本消息
func FormatTextMessage(fromUserName string, toUserName string, content string) []byte {
timestamp := strconv.Itoa(int(time.Now().Unix()))
textMessage := MessageText{FromUserName: ValueToCDATA(fromUserName), ToUserName: ValueToCDATA(toUserName), Content: ValueToCDATA(content), CreateTime: timestamp, MsgType: ValueToCDATA(MsgTypeText)}
messageBytes, err := xml.MarshalIndent(textMessage, " ", " ")
if err != nil {
panic("格式化文本消息失败:xml marsha1 error;" + err.Error())
}
return messageBytes
}

// FormatImageMessage 格式化图片消息
func FormatImageMessage(fromUserName string, toUserName string, mediaId string) []byte {
timestamp := strconv.Itoa(int(time.Now().Unix()))
imageMessage := MessageImage{FromUserName: ValueToCDATA(fromUserName), ToUserName: ValueToCDATA(toUserName), CreateTime: timestamp, MsgType: ValueToCDATA(MsgTypeImage), Image: Media{ValueToCDATA(mediaId)}}
messageBytes, err := xml.MarshalIndent(imageMessage, " ", " ")
if err != nil {
panic("格式化图片消息失败:xml marsha1 error;" + err.Error())
}
return messageBytes
}

// FormatVoiceMessage 格式语音消息
func FormatVoiceMessage(fromUserName string, toUserName string, mediaId string) []byte {
timestamp := strconv.Itoa(int(time.Now().Unix()))
voiceMessage := MessageVoice{FromUserName: ValueToCDATA(fromUserName), ToUserName: ValueToCDATA(toUserName), CreateTime: timestamp, MsgType: ValueToCDATA(MsgTypeVoice), Voice: Media{ValueToCDATA(mediaId)}}
messageBytes, err := xml.MarshalIndent(voiceMessage, " ", " ")
if err != nil {
panic("格式化语音消息失败:xml marsha1 error;" + err.Error())
}
return messageBytes
}

// FormatVideoMessage 格式化视频消息
func FormatVideoMessage(fromUserName string, toUserName string, mediaId string, title string, description string) []byte {
timestamp := strconv.Itoa(int(time.Now().Unix()))
videoMessage := MessageVideo{FromUserName: ValueToCDATA(fromUserName), ToUserName: ValueToCDATA(toUserName), CreateTime: timestamp, MsgType: ValueToCDATA(MsgTypeVideo), Video: Video{
MediaId: ValueToCDATA(mediaId),
Title: ValueToCDATA(title),
Description: ValueToCDATA(description),
}}
messageBytes, err := xml.MarshalIndent(videoMessage, " ", " ")
if err != nil {
panic("格式化语音消息失败:xml marsha1 error;" + err.Error())
}
return messageBytes
}

// FormatMusicMessage 格式化音乐消息
func FormatMusicMessage(fromUserName string, toUserName string, thumbMediaId string, title string, description string, musicUrl string, hQMusicUrl string) []byte {
timestamp := strconv.Itoa(int(time.Now().Unix()))
musicMessage := MessageMusic{FromUserName: ValueToCDATA(fromUserName), ToUserName: ValueToCDATA(toUserName), CreateTime: timestamp, MsgType: ValueToCDATA(MsgTypeMusic), Music: Music{
Title: ValueToCDATA(title),
Description: ValueToCDATA(description),
MusicUrl: ValueToCDATA(musicUrl),
HQMusicUrl: ValueToCDATA(hQMusicUrl),
ThumbMediaId: ValueToCDATA(thumbMediaId),
}}
messageBytes, err := xml.MarshalIndent(musicMessage, " ", " ")
if err != nil {
panic("格式化音乐消息失败:xml marsha1 error;" + err.Error())
}
return messageBytes
}

// FormatArticlesMessage 格式化音乐消息
func FormatArticlesMessage(fromUserName string, toUserName string, items []ArticleItem) []byte {
timestamp := strconv.Itoa(int(time.Now().Unix()))
articleNum := strconv.Itoa(len(items))
musicMessage := MessageArticle{FromUserName: ValueToCDATA(fromUserName), ToUserName: ValueToCDATA(toUserName), CreateTime: timestamp, MsgType: ValueToCDATA(MsgTypeNews), Articles: items, ArticleCount: articleNum}
messageBytes, err := xml.MarshalIndent(musicMessage, " ", " ")
if err != nil {
panic("格式化图文消息失败:xml marsha1 error;" + err.Error())
}
return messageBytes
}

// FormatEncryptData 格式化微信加密数据
func FormatEncryptData(encrypted string, token string) MessageEncryptBody {
nonce := makeRandomString(16)
timestamp := strconv.Itoa(int(time.Now().Unix()))
data := MessageEncryptBody{Encrypt: ValueToCDATA(encrypted), Nonce: ValueToCDATA(nonce), MsgSignature: ValueToCDATA(GetSignature(timestamp, nonce, encrypted, token)), TimeStamp: timestamp}
return data
}

+ 61
- 0
app/lib/wechat/prpcrypt.go Vedi File

@@ -0,0 +1,61 @@
package wechat

import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/base64"
"io"
)

type prpCrypt struct {
Key []byte
Iv []byte
}

func NewPrpCrypt(aesKey string) *prpCrypt {
instance := new(prpCrypt)
//网络字节序
instance.Key, _ = base64.StdEncoding.DecodeString(aesKey + "=")
instance.Iv = randomIv()
return instance
}

func randomIv() []byte {
iv := make([]byte, aes.BlockSize)
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
panic("random iv error")
}
return iv
}

func (prp *prpCrypt) decrypt(encrypted string) ([]byte, error) {
encryptedBytes, _ := base64.StdEncoding.DecodeString(encrypted)
k := len(prp.Key) //PKCS#7
if len(encryptedBytes)%k != 0 {
panic("ciphertext size is not multiple of aes key length")
}
block, err := aes.NewCipher(prp.Key)
if err != nil {
return nil, err
}
blockMode := cipher.NewCBCDecrypter(block, prp.Iv)
plainText := make([]byte, len(encryptedBytes))
blockMode.CryptBlocks(plainText, encryptedBytes)
return plainText, nil
}

func (prp *prpCrypt) encrypt(plainText []byte) ([]byte, error) {
k := len(prp.Key)
if len(plainText)%k != 0 {
plainText = pKCS7Pad(plainText, k)
}
block, err := aes.NewCipher(prp.Key)
if err != nil {
return nil, err
}
cipherData := make([]byte, len(plainText))
blockMode := cipher.NewCBCEncrypter(block, prp.Iv)
blockMode.CryptBlocks(cipherData, plainText)
return cipherData, nil
}

+ 322
- 0
app/lib/wechat/wechat_api.go Vedi File

@@ -0,0 +1,322 @@
package wechat

import (
"applet/app/cfg"
"applet/app/lib/wechat/enum"
"applet/app/lib/wechat/md"
"applet/app/utils"
"applet/app/utils/cache"
db "code.fnuoos.com/zhimeng/model.git/src"
"code.fnuoos.com/zhimeng/model.git/src/super/implement"
"encoding/json"
"errors"
"fmt"
)

type WxApiService struct {
ComponentAppid string `json:"component_appid"`
ComponentAppsecret string `json:"component_appsecret"`
ComponentVerifyTicket string `json:"component_verify_ticket"`
MasterId string `json:"master_id"`
Host string `json:"host"`
}

func NewWxApiService(masterId, componentAppid, componentAppsecret string) (wxApiService WxApiService, err error) { // set方法
wxApiService.MasterId = masterId
wxApiService.ComponentAppid = componentAppid
wxApiService.ComponentAppsecret = componentAppsecret
wxApiService.Host = "http://super.advertisement.dengbiao.top"
if cfg.Prd {
wxApiService.Host = "http://www.baidu.com"
}
cacheKey := fmt.Sprintf(md.MasterComponentVerifyTicket, wxApiService.MasterId)
cacheComponentVerifyTicket, _ := cache.GetString(cacheKey)
if cacheComponentVerifyTicket == "" {
return wxApiService, errors.New("微信验证票据ticket未获取到")
}
wxApiService.ComponentVerifyTicket = cacheComponentVerifyTicket
return
}

// GetComponentAccessToken 获取接口调用令牌token
func (wxApiService *WxApiService) GetComponentAccessToken() (cacheComponentAccessToken string, err error) { // set方法
cacheKey := fmt.Sprintf(md.MasterComponentAccessToken, wxApiService.MasterId)
cacheComponentAccessToken, _ = cache.GetString(cacheKey)
if cacheComponentAccessToken == "" {
url := "https://api.weixin.qq.com/cgi-bin/component/api_component_token"
params := map[string]string{
"component_appid": wxApiService.ComponentAppid,
"component_appsecret": wxApiService.ComponentAppsecret,
"component_verify_ticket": wxApiService.ComponentVerifyTicket,
}
postBody, err1 := utils.CurlPost(url, utils.SerializeStr(params), nil)
if err1 != nil {
return cacheComponentAccessToken, err1
}
var postData md.GetComponentAccessToken
err = json.Unmarshal(postBody, &postData)
if err != nil {
return
}
if postData.ComponentAccessToken == "" {
err = errors.New("获取接口令牌token失败")
return
}
cacheComponentAccessToken = postData.ComponentAccessToken
cache.SetEx(cacheKey, cacheComponentAccessToken, postData.ExpiresIn-600)
wxOpenThirdPartyAppListDb := implement.NewWxOpenThirdPartyAppListDb(db.Db)
wxOpenThirdPartyAppList, err1 := wxOpenThirdPartyAppListDb.GetWxOpenThirdPartyAppListByAppId(wxApiService.ComponentAppid)
if err1 != nil {
return cacheComponentAccessToken, err1
}
if wxOpenThirdPartyAppList == nil {
err = errors.New("未查询到对应三方应用App记录")
return
}
wxOpenThirdPartyAppList.ComponentAccessToken = cacheComponentAccessToken
_, err = wxOpenThirdPartyAppListDb.UpdateWxOpenThirdPartyAppList(wxOpenThirdPartyAppList, "component_access_token")
if err != nil {
return
}
}
return
}

// GetAuth 获取接口调用令牌
func (wxApiService *WxApiService) GetAuth(appId string) (cacheApiAuthorizerToken string, err error) { // set方法
userWxAppletListDb := implement.NewUserWxAppletListDb(db.Db)
userWxAppletList, err1 := userWxAppletListDb.GetUserWxAppletListByAppId(appId)
if err1 != nil {
return cacheApiAuthorizerToken, err1
}
if userWxAppletList == nil {
err = errors.New("未查询到对应小程序App记录")
return
}

//获取/刷新接口调用令牌
componentAccessToken, err := wxApiService.GetComponentAccessToken()
if err != nil {
return
}
url := "https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token?component_access_token=" + componentAccessToken
params := map[string]string{
"component_appid": wxApiService.ComponentAppid,
"authorizer_appid": appId,
"authorizer_refresh_token": userWxAppletList.AuthorizerRefreshToken,
}
postBody, err := utils.CurlPost(url, utils.SerializeStr(params), nil)
if err != nil {
return
}

var resp md.ApiAuthorizerToken
err = json.Unmarshal(postBody, &resp)
if err != nil {
return
}
if resp.AuthorizerAccessToken == "" {
err = errors.New("获取/刷新接口调用令牌")
return
}
cacheApiAuthorizerToken = resp.AuthorizerAccessToken
return
}

// GetPreAuthCode 获取预授权码
func (wxApiService *WxApiService) GetPreAuthCode() (preAuthCode string, err error) { // set方法
componentAccessToken, err := wxApiService.GetComponentAccessToken()
if err != nil {
return
}
url := "https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token=" + componentAccessToken
params := map[string]string{
"component_appid": wxApiService.ComponentAppid,
}
postBody, err := utils.CurlPost(url, utils.SerializeStr(params), nil)
if err != nil {
return
}
var postData md.GetPreAuthCode
err = json.Unmarshal(postBody, &postData)
if err != nil {
return
}
if postData.PreAuthCode == "" {
err = errors.New("获取预授权码失败")
return
}
preAuthCode = postData.PreAuthCode
return
}

// GetAuthorizerAccessTokenByAuthCode 使用授权码获取授权信息
func (wxApiService *WxApiService) GetAuthorizerAccessTokenByAuthCode(authCode string) (resp md.GetAuthorizerAccessTokenByAuthCode, err error) { // set方法
componentAccessToken, err := wxApiService.GetComponentAccessToken()
if err != nil {
return
}
url := "https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token=" + componentAccessToken
params := map[string]string{
"component_appid": wxApiService.ComponentAppid,
"authorization_code": authCode,
}
postBody, err := utils.CurlPost(url, utils.SerializeStr(params), nil)
if err != nil {
return
}
err = json.Unmarshal(postBody, &resp)
if err != nil {
return
}
if resp.AuthorizationInfo.AuthorizerAppid == "" {
err = errors.New("获取授权信息失败")
return
}
return
}

// DelAuthorize 取消授权
func (wxApiService *WxApiService) DelAuthorize(appId string) (err error) { // set方法
apiAuthorizerToken, err := wxApiService.GetAuth(appId)
if err != nil {
return
}
url := "https://api.weixin.qq.com/wxaapi/wxaembedded/del_authorize?access_token=" + apiAuthorizerToken
params := map[string]string{
"appid": appId,
}
postBody, err := utils.CurlPost(url, utils.SerializeStr(params), nil)
if err != nil {
return
}
var resp md.DelAuthorize
err = json.Unmarshal(postBody, &resp)
if err != nil {
return
}
if resp.ErrCode != 0 {
err = errors.New(resp.ErrMsg)
}
return
}

// AgencyCreateAdunit 创建广告单元
func (wxApiService *WxApiService) AgencyCreateAdunit(appId, name string, adunitType enum.AdunitType) (err error, adUnitId string) { // set方法
apiAuthorizerToken, err := wxApiService.GetAuth(appId)
if err != nil {
return
}
url := "https://api.weixin.qq.com/wxa/operationams?action=agency_create_adunit&access_token=" + apiAuthorizerToken
params := map[string]interface{}{
"name": name,
"type": string(adunitType),
}
if adunitType == enum.AdunitTypeForVideoFeeds {
params["video_duration_min"] = 6
params["video_duration_max"] = 60
}
postBody, err := utils.CurlPost(url, utils.SerializeStr(params), nil)
if err != nil {
return
}
var resp md.AgencyCreateAdunit
err = json.Unmarshal(postBody, &resp)
if err != nil {
return
}
if resp.Ret != 0 {
err = errors.New(resp.ErrMsg)
}
adUnitId = resp.AdUnitId
return
}

// AgencyUpdateAdunit 更新广告单元
func (wxApiService *WxApiService) AgencyUpdateAdunit(appId, adUnitId, name string, adunitType enum.AdunitType, adunitStatus enum.AdunitStatus) (err error) { // set方法
apiAuthorizerToken, err := wxApiService.GetAuth(appId)
if err != nil {
return
}
url := "https://api.weixin.qq.com/wxa/operationams?action=agency_update_adunit&access_token=" + apiAuthorizerToken
params := map[string]interface{}{
"name": name,
"ad_unit_id": adUnitId,
"status": string(adunitStatus),
}
if adunitType == enum.AdunitTypeForVideoFeeds {
params["video_duration_min"] = 6
params["video_duration_max"] = 60
}
postBody, err := utils.CurlPost(url, utils.SerializeStr(params), nil)
if err != nil {
return
}
var resp md.AgencyUpdateAdunit
err = json.Unmarshal(postBody, &resp)
if err != nil {
return
}
if resp.Ret != 0 {
err = errors.New(resp.ErrMsg)
}
return
}

// SetCoverAdposStatus 设置小程序封面广告位开关状态
func (wxApiService *WxApiService) SetCoverAdposStatus(appId string, setCoverAdposStatus enum.SetCoverAdposStatus) (err error) { // set方法
apiAuthorizerToken, err := wxApiService.GetAuth(appId)
if err != nil {
return
}
url := "https://api.weixin.qq.com/wxa/operationams?action=agency_set_cover_adpos_status&access_token=" + apiAuthorizerToken
params := map[string]interface{}{
"status": int32(setCoverAdposStatus),
}
postBody, err := utils.CurlPost(url, utils.SerializeStr(params), nil)
if err != nil {
return
}
var resp md.SetCoverAdposStatus
err = json.Unmarshal(postBody, &resp)
if err != nil {
return
}
if resp.Ret != 0 {
err = errors.New(resp.ErrMsg)
}
return
}

/*
GetAdunitList 获取广告位(除封面广告位)或指定广告单元的信息
@params adSlot 广告位类型名称(非必传)
@params adUnitId 广告单元ID(非必传)
@Remark 返回的广告单元列表按照创建时间倒序,请以分页的形式获取。当需要获取全部广告位的清单时,无需传递广告位类型名称及广告单元ID;当需要获取某类型广告位的清单时,仅需传递广告位类型名称;当需要获取某广告位 id 的数据时,仅需传递广告单元ID。
*/
func (wxApiService *WxApiService) GetAdunitList(appId string, page, pageSize int, adSlot enum.AdunitType, adUnitId string) (err error, resp md.GetAdunitList) { // set方法
apiAuthorizerToken, err := wxApiService.GetAuth(appId)
if err != nil {
return
}
url := "https://api.weixin.qq.com/wxa/operationams?action=agency_get_adunit_list&access_token=" + apiAuthorizerToken
params := map[string]interface{}{
"page": page,
"pageSize": pageSize,
"ad_slot": adSlot,
"ad_unit_id": adUnitId,
}
postBody, err := utils.CurlPost(url, utils.SerializeStr(params), nil)
if err != nil {
return
}

err = json.Unmarshal(postBody, &resp)
if err != nil {
return
}
if resp.Ret != 0 {
err = errors.New(resp.ErrMsg)
}
return
}

+ 11
- 0
app/lib/wechat/wechat_err_code.go Vedi File

@@ -0,0 +1,11 @@
package wechat

var SuccessCode = 0
var ValidateSignatureError = -40001
var ParseXmlError = -40002
var ComputeSignatureError = -40003
var IllegalAesKey = -40004
var ValidateAppidError = -40005
var EncryptAESError = -40006
var DecryptAESError = -40007
var IllegalBuffer = -40008

+ 200
- 0
app/lib/wechat/wechat_message.go Vedi File

@@ -0,0 +1,200 @@
package wechat

import (
"bytes"
"encoding/base64"
"encoding/binary"
"encoding/xml"
"errors"
"fmt"
)

type msgCrypt struct {
token string
aesKey string
appid string
}

// EventEncryptRequest 微信事件推送结构体
type EventEncryptRequest struct {
XMLName xml.Name `xml:"xml"`
Encrypt string `xml:"Encrypt"`
Appid string `xml:"Appid"`
}

// MessageEncryptRequest 微信消息加密结构体
type MessageEncryptRequest struct {
XMLName xml.Name `xml:"xml"`
Encrypt string `xml:"Encrypt"`
MsgSignature string `xml:"MsgSignature"`
TimeStamp string `xml:"TimeStamp"`
Nonce string `xml:"Nonce"`
}

// NewWechatMsgCrypt 实例化微信加解密
func NewWechatMsgCrypt(token string, aesKey string, appid string) *msgCrypt {
instance := new(msgCrypt)
instance.token = token
instance.aesKey = aesKey
instance.appid = appid
return instance
}

// WechatEventDecrypt 微信事件推送解密
func (w *msgCrypt) WechatEventDecrypt(eventRequest EventEncryptRequest, msgSignature string, timestamp, nonce string) EventMessageBody {
errCode, data := w.decryptMsg(msgSignature, timestamp, nonce, eventRequest.Encrypt)
if errCode != SuccessCode {
panic(fmt.Sprintf("消息解密失败,code:%d", errCode))
}
message := EventMessageBody{}
_, err := FormatMessage(data, &message)
if err != nil {
panic(fmt.Sprintf("消息格式化失败,%s", err.Error()))
}
return message
}

// WechatMessageDecrypt 微信消息解密
func (w *msgCrypt) WechatMessageDecrypt(messageEncryptRequest MessageEncryptRequest) interface{} {
errCode, data := w.decryptMsg(messageEncryptRequest.MsgSignature, messageEncryptRequest.TimeStamp, messageEncryptRequest.Nonce, messageEncryptRequest.Encrypt)
if errCode != SuccessCode {
panic(fmt.Sprintf("消息解密失败,code:%d", errCode))
}
message := MessageBodyDecrypt{}
_, err := FormatMessage(data, &message)
if err != nil {
panic(fmt.Sprintf("消息格式化失败,%s", err.Error()))
}
return message
}

// WechatTextMessage 微信文本消息加密
func (w *msgCrypt) WechatTextMessage(fromUserName string, toUserName string, content string) MessageEncryptBody {
message := FormatTextMessage(fromUserName, toUserName, content)
encrypted, err := w.encryptMsg(message)
if err != nil {
panic("消息加密失败:" + err.Error())
}
data := FormatEncryptData(encrypted, w.token)
return data
}

// WechatImageMessage 微信图片消息加密
func (w *msgCrypt) WechatImageMessage(fromUserName string, toUserName string, mediaId string) MessageEncryptBody {
message := FormatImageMessage(fromUserName, toUserName, mediaId)
encrypted, err := w.encryptMsg(message)
if err != nil {
panic("消息加密失败:" + err.Error())
}
data := FormatEncryptData(encrypted, w.token)
return data
}

// WechatVoiceMessage 微信语音消息加密
func (w *msgCrypt) WechatVoiceMessage(fromUserName string, toUserName string, mediaId string) MessageEncryptBody {
message := FormatVoiceMessage(fromUserName, toUserName, mediaId)
encrypted, err := w.encryptMsg(message)
if err != nil {
panic("消息加密失败:" + err.Error())
}
data := FormatEncryptData(encrypted, w.token)
return data
}

// WechatVideoMessage 微信视频消息加密
func (w *msgCrypt) WechatVideoMessage(fromUserName string, toUserName string, mediaId string, title string, description string) MessageEncryptBody {
message := FormatVideoMessage(fromUserName, toUserName, mediaId, title, description)
encrypted, err := w.encryptMsg(message)
if err != nil {
panic("消息加密失败:" + err.Error())
}
data := FormatEncryptData(encrypted, w.token)
return data
}

// WechatMusicMessage 微信音乐消息加密
func (w *msgCrypt) WechatMusicMessage(fromUserName string, toUserName string, thumbMediaId string, title string, description string, musicUrl string, hQMusicUrl string) MessageEncryptBody {
message := FormatMusicMessage(fromUserName, toUserName, thumbMediaId, title, description, musicUrl, hQMusicUrl)
encrypted, err := w.encryptMsg(message)
if err != nil {
panic("消息加密失败:" + err.Error())
}
data := FormatEncryptData(encrypted, w.token)
return data
}

// WechatArticlesMessage 微信图文消息加密
func (w *msgCrypt) WechatArticlesMessage(fromUserName string, toUserName string, items []ArticleItem) MessageEncryptBody {
message := FormatArticlesMessage(fromUserName, toUserName, items)
encrypted, err := w.encryptMsg(message)
if err != nil {
panic("消息加密失败:" + err.Error())
}
data := FormatEncryptData(encrypted, w.token)
return data
}

// decryptMsg aes消息解密
func (w *msgCrypt) decryptMsg(msgSignature string, timestamp, nonce string, encrypted string) (int, []byte) {
//验证aes
if len(w.aesKey) != 43 {
return IllegalAesKey, nil
}
//判断签名是否一致
if err := w.validSignature(msgSignature, timestamp, nonce, encrypted); err != nil {
return ValidateSignatureError, nil
}
//解密
prp := NewPrpCrypt(w.aesKey)
plainText, err := prp.decrypt(encrypted)
if err != nil {
return DecryptAESError, nil
}
//验证appid是否一致(消息来源是否一致)
if err := w.validMessageSource(plainText); err != nil {
return ValidateAppidError, nil
}
return SuccessCode, plainText
}

// encryptMsg aes消息加密
func (w *msgCrypt) encryptMsg(message []byte) (string, error) {
//计算消息长度
buf := new(bytes.Buffer)
err := binary.Write(buf, binary.BigEndian, int32(len(message)))
if err != nil {
return "", err
}
messageLength := buf.Bytes()
//生成随机字符串
randBytes := []byte(makeRandomString(16))
plainData := bytes.Join([][]byte{randBytes, messageLength, message, []byte(w.appid)}, nil)
prp := NewPrpCrypt(w.aesKey)
//消息加密
encrypted, err := prp.encrypt(plainData)
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(encrypted), nil
}

// validSignature 验证签名是否一致
func (w *msgCrypt) validSignature(msgSignature string, timestamp, nonce string, encrypted string) error {
validSignature := GetSignature(timestamp, nonce, encrypted, w.token)
if validSignature != msgSignature {
return errors.New("签名不一致:valid sign error")
}
return nil
}

// validMessageSource 验证消息来源
func (w *msgCrypt) validMessageSource(plainText []byte) error {
messageLength := GetMessageLength(plainText)
//获取appid位置
appIdStartPos := 20 + messageLength
id := plainText[appIdStartPos : int(appIdStartPos)+len(w.appid)]
if string(id) != w.appid {
return errors.New("消息来源不一致:Appid is invalid")
}
return nil
}

+ 50
- 0
app/md/md_oss_bucket_region.go Vedi File

@@ -0,0 +1,50 @@
package md

type QiNiuBucketRegion struct {
RegionId string `json:"region_id" example:"区域id"`
RegionName string `json:"region_name" example:"区域名称"`
RegionDomain string `json:"region_domain" example:"区域域名"`
}

var QiNiuBucketRegionList = []QiNiuBucketRegion{
{
RegionId: "z0",
RegionName: "华东-浙江",
RegionDomain: "up-z0.qiniup.com",
},
{
RegionId: "cn-east-2",
RegionName: "华东-浙江2",
RegionDomain: "up-cn-east-2.qiniup.com",
},
{
RegionId: "z1",
RegionName: "华北-河北",
RegionDomain: "up-z1.qiniup.com",
},
{
RegionId: "z2",
RegionName: "华南-广东",
RegionDomain: "up-z2.qiniup.com",
},
{
RegionId: "na0",
RegionName: "北美-洛杉矶",
RegionDomain: "up-na0.qiniup.com",
},
{
RegionId: "as0",
RegionName: "亚太-新加坡(原东南亚)",
RegionDomain: "up-as0.qiniup.com",
},
{
RegionId: "ap-southeast-2",
RegionName: "亚太-河内",
RegionDomain: "up-ap-southeast-2.qiniup.com",
},
{
RegionId: "ap-southeast-3",
RegionName: "亚太-胡志明",
RegionDomain: "up-ap-southeast-3.qiniup.com",
},
}

+ 49
- 0
app/md/md_set_center.go Vedi File

@@ -0,0 +1,49 @@
package md

type SetOssReq struct {
FileAccessKey string `json:"file_access_key" binding:"required" example:"对象存储AccessToken"`
FileSecretKey string `json:"file_secret_key" binding:"required" example:"对象存储SecretToken"`
FileBucketHost string `json:"file_bucket_host" binding:"required" example:"对象存储域名"`
FileBucketRegion string `json:"file_bucket_region" binding:"required" example:"文件所属区域"`
FileBucket string `json:"file_bucket" binding:"required" example:"对象存储bucket(空间)"`
}
type SetOssResp struct {
Data SetOssReq `json:"data"` //数据内容
QiNiuBucketRegionList []QiNiuBucketRegion `json:"qi_niu_bucket_region_list"` //七牛云存储区域列表
}

type WxOpenSetReq struct {
Token string `json:"token" binding:"required" example:"消息校验Token"`
AesKey string `json:"aes_key" binding:"required" example:"消息加解密Key"`
Appid string `json:"appid" binding:"required" example:"appid"`
AppSecret string `json:"app_secret" binding:"required" example:"appSecret"`
}
type WxOpenGetResp struct {
Token string `json:"token" example:"消息校验Token"`
AesKey string `json:"aes_key" example:"消息加解密Key"`
Appid string `json:"appid" example:"appid"`
AppSecret string `json:"app_secret" example:"appSecret"`
WxOpenAppletServerDomain string `json:"wx_open_applet_server_domain" example:"微信开放平台-小程序服务器域名"`
WxOpenAuthorizationEventReceivingConfiguration string `json:"wx_open_authorization_event_receiving_configuration" example:"微信开放平台-授权事件接收配置"`
WxOpenDomainOfTheInitiatingPageForLoginAuthorization string `json:"wx_open_domain_of_the_initiating_page_for_login_authorization" example:"微信开放平台-登录授权的发起页域名"`
WxOpenMessageAndEventReceptionConfiguration string `json:"wx_open_message_and_event_reception_configuration" example:"微信开放平台-消息与事件接收配置"`
WxOpenWhiteListIp string `json:"wx_open_white_list_ip" example:"微信开放平台-白名单ip"`
}

type AppletAddReq struct {
Name string `json:"name" binding:"required" example:"小程序名称"`
Logo string `json:"logo" binding:"required" example:"小程序logo"`
Appid string `json:"appid" binding:"required" example:"授权小程序appid"`
OriginalId string `json:"original_id" binding:"required" example:"授权小程序原始id"`
}
type AppletUpdateReq struct {
Id int `json:"id" binding:"required"`
Name string `json:"name" binding:"required" example:"小程序名称"`
Logo string `json:"logo" binding:"required" example:"小程序logo"`
}

type ShareIndexResp struct {
MasterId string `json:"master_id"`
AgentDomain string `json:"agent_domain" example:"代理分享地址"`
MediumDomain string `json:"medium_domain" example:"媒体分享地址"`
}

+ 24
- 0
app/router/router.go Vedi File

@@ -65,6 +65,7 @@ func route(r *gin.RouterGroup) {
rRole(r.Group("/role")) //权限管理
rAgentQualification(r.Group("/agentQualification")) //渠道-资质
rMediumQualification(r.Group("/mediumQualification")) //媒体-资质
rSetCenter(r.Group("/setCenter")) //设置中心
}

func rRole(r *gin.RouterGroup) {
@@ -99,3 +100,26 @@ func rMediumQualification(r *gin.RouterGroup) {
r.POST("/contact", hdl.MediumQualificationContactInfo) //联系方式
r.POST("/contact/audit", hdl.MediumQualificationContactInfoAudit) //联系方式
}
func rSetCenter(r *gin.RouterGroup) {
rBasicSetCenter := r.Group("/basic")
{
rBasicSetCenter.POST("/setOss", hdl.SetOss)
rBasicSetCenter.GET("/getOss", hdl.GetOss)
rBasicSetCenter.POST("/wxOpenSet", hdl.WxOpenSet)
rBasicSetCenter.GET("/wxOpenGet", hdl.WxOpenGet)
}
rAppletSetCenter := r.Group("/applet")
{
rAppletSetCenter.GET("/list", hdl.AppletList)
rAppletSetCenter.POST("/add", hdl.AppletAdd)
rAppletSetCenter.POST("/update", hdl.AppletUpdate)
rAppletSetCenter.DELETE("/delete/:id", hdl.AppletDelete)
rAppletSetCenter.GET("/authorize", hdl.AppletAuthorize)
rAppletSetCenter.GET("/unauthorized", hdl.AppletUnauthorized)
}
rShareSetCenter := r.Group("/share")
{
rShareSetCenter.GET("/index", hdl.ShareIndex)
}

}

+ 17
- 39
app/svc/svc_sys_cfg_get.go Vedi File

@@ -1,6 +1,7 @@
package svc

import (
"applet/app/db/implement"
db "code.fnuoos.com/zhimeng/model.git/src"
"github.com/gin-gonic/gin"
"xorm.io/xorm"
@@ -11,9 +12,10 @@ import (

// 单挑记录获取
func SysCfgGet(c *gin.Context, key string) string {
mid := c.GetString("mid")
eg := db.DBs[mid]
return db.SysCfgGetWithDb(eg, mid, key)
masterId := GetMasterId(c)
eg := db.DBs[masterId]
sysCfgDb := implement.NewSysCfgDb(eg, masterId)
return sysCfgDb.SysCfgGetWithDb(key)
}

// 多条记录获取
@@ -22,7 +24,7 @@ func SysCfgFind(c *gin.Context, keys ...string) map[string]string {
if c == nil {
masterId = ""
} else {
masterId = c.GetString("mid")
masterId = GetMasterId(c)
}
tmp := SysCfgFindComm(masterId, keys...)
return tmp
@@ -36,51 +38,23 @@ func SysCfgFindComm(masterId string, keys ...string) map[string]string {
}
res := map[string]string{}
//TODO::判断keys长度(大于10个直接查数据库)
sysCfgDb := implement.NewSysCfgDb(eg, masterId)
if len(keys) > 10 {
cfgList, _ := db.SysCfgGetAll(eg)
cfgList, _ := sysCfgDb.SysCfgGetAll()
if cfgList == nil {
return nil
}
for _, v := range *cfgList {
res[v.Key] = v.Val
res[v.K] = v.V
}
} else {
for _, key := range keys {
res[key] = db.SysCfgGetWithDb(eg, masterId, key)
res[key] = sysCfgDb.SysCfgGetWithDb(key)
}
}
return res
}

// 多条记录获取
func EgSysCfgFind(keys ...string) map[string]string {
var e *xorm.Engine
res := map[string]string{}
if len(res) == 0 {
cfgList, _ := db.SysCfgGetAll(e)
if cfgList == nil {
return nil
}
for _, v := range *cfgList {
res[v.Key] = v.Val
}
// 先不设置缓存
// cache.SetJson(md.KEY_SYS_CFG_CACHE, res, 60)
}
if len(keys) == 0 {
return res
}
tmp := map[string]string{}
for _, v := range keys {
if val, ok := res[v]; ok {
tmp[v] = val
} else {
tmp[v] = ""
}
}
return tmp
}

// 清理系统配置信息
func SysCfgCleanCache() {
cache.Del(md.KEY_SYS_CFG_CACHE)
@@ -88,13 +62,17 @@ func SysCfgCleanCache() {

// 写入系统设置
func SysCfgSet(c *gin.Context, key, val, memo string) bool {
cfg, err := db.SysCfgGetOne(db.DBs[c.GetString("mid")], key)
masterId := GetMasterId(c)
eg := db.DBs[masterId]
sysCfgDb := implement.NewSysCfgDb(eg, masterId)

cfg, err := sysCfgDb.SysCfgGetOne(key)
if err != nil || cfg == nil {
return db.SysCfgInsert(db.DBs[c.GetString("mid")], key, val, memo)
return sysCfgDb.SysCfgInsert(key, val, memo)
}
if memo != "" && cfg.Memo != memo {
cfg.Memo = memo
}
SysCfgCleanCache()
return db.SysCfgUpdate(db.DBs[c.GetString("mid")], key, val, cfg.Memo)
return sysCfgDb.SysCfgUpdate(key, val)
}

+ 690
- 0
docs/docs.go Vedi File

@@ -1265,6 +1265,422 @@ const docTemplate = `{
}
}
},
"/api/setCenter/applet/add": {
"post": {
"description": "小程序设置-新增",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"设置中心-小程序设置"
],
"summary": "新增",
"parameters": [
{
"type": "string",
"description": "验证参数Bearer和token空格拼接",
"name": "Authorization",
"in": "header",
"required": true
},
{
"description": "请求参数",
"name": "args",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/md.AppletAddReq"
}
}
],
"responses": {
"200": {
"description": "success",
"schema": {
"type": "string"
}
},
"400": {
"description": "具体错误",
"schema": {
"$ref": "#/definitions/md.Response"
}
}
}
}
},
"/api/setCenter/applet/authorize": {
"get": {
"description": "设置中心-基础设置",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"设置中心"
],
"summary": "设置中心-基础设置-微信三方应用获取",
"parameters": [
{
"type": "string",
"description": "验证参数Bearer和token空格拼接",
"name": "Authorization",
"in": "header",
"required": true
}
],
"responses": {
"200": {
"description": "微信授权界面url",
"schema": {
"type": "string"
}
},
"400": {
"description": "具体错误",
"schema": {
"$ref": "#/definitions/md.Response"
}
}
}
}
},
"/api/setCenter/applet/list": {
"get": {
"description": "小程序设置-列表",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"设置中心-小程序设置"
],
"summary": "列表",
"parameters": [
{
"type": "string",
"description": "验证参数Bearer和token空格拼接",
"name": "Authorization",
"in": "header",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/hdl.WxOpenThirdPartyAppList"
}
},
"400": {
"description": "具体错误",
"schema": {
"$ref": "#/definitions/md.Response"
}
}
}
}
},
"/api/setCenter/applet/unauthorized": {
"get": {
"description": "设置中心-基础设置",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"设置中心"
],
"summary": "设置中心-基础设置-微信三方应用获取",
"parameters": [
{
"type": "string",
"description": "验证参数Bearer和token空格拼接",
"name": "Authorization",
"in": "header",
"required": true
}
],
"responses": {
"200": {
"description": "success",
"schema": {
"type": "string"
}
},
"400": {
"description": "具体错误",
"schema": {
"$ref": "#/definitions/md.Response"
}
}
}
}
},
"/api/setCenter/applet/update": {
"post": {
"description": "小程序设置-更新",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"设置中心-小程序设置"
],
"summary": "更新",
"parameters": [
{
"type": "string",
"description": "验证参数Bearer和token空格拼接",
"name": "Authorization",
"in": "header",
"required": true
},
{
"description": "请求参数",
"name": "args",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/md.AppletUpdateReq"
}
}
],
"responses": {
"200": {
"description": "success",
"schema": {
"type": "string"
}
},
"400": {
"description": "具体错误",
"schema": {
"$ref": "#/definitions/md.Response"
}
}
}
}
},
"/api/setCenter/basic/getOss": {
"get": {
"description": "基础设置-oss获取",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"设置中心-基础设置"
],
"summary": "oss获取",
"parameters": [
{
"type": "string",
"description": "验证参数Bearer和token空格拼接",
"name": "Authorization",
"in": "header",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/md.SetOssResp"
}
},
"400": {
"description": "具体错误",
"schema": {
"$ref": "#/definitions/md.Response"
}
}
}
}
},
"/api/setCenter/basic/setOss": {
"post": {
"description": "基础设置-oss设置",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"设置中心-基础设置"
],
"summary": "oss设置",
"parameters": [
{
"type": "string",
"description": "验证参数Bearer和token空格拼接",
"name": "Authorization",
"in": "header",
"required": true
},
{
"description": "请求参数",
"name": "args",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/md.SetOssReq"
}
}
],
"responses": {
"200": {
"description": "success",
"schema": {
"type": "string"
}
},
"400": {
"description": "具体错误",
"schema": {
"$ref": "#/definitions/md.Response"
}
}
}
}
},
"/api/setCenter/basic/wxOpenGet": {
"get": {
"description": "基础设置-微信三方应用获取",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"设置中心-基础设置"
],
"summary": "微信三方应用获取",
"parameters": [
{
"type": "string",
"description": "验证参数Bearer和token空格拼接",
"name": "Authorization",
"in": "header",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/md.WxOpenGetResp"
}
},
"400": {
"description": "具体错误",
"schema": {
"$ref": "#/definitions/md.Response"
}
}
}
}
},
"/api/setCenter/basic/wxOpenSet": {
"post": {
"description": "基础设置-微信三方应用设置",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"设置中心-基础设置"
],
"summary": "微信三方应用设置",
"parameters": [
{
"type": "string",
"description": "验证参数Bearer和token空格拼接",
"name": "Authorization",
"in": "header",
"required": true
},
{
"description": "请求参数",
"name": "args",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/md.WxOpenSetReq"
}
}
],
"responses": {
"200": {
"description": "success",
"schema": {
"type": "string"
}
},
"400": {
"description": "具体错误",
"schema": {
"$ref": "#/definitions/md.Response"
}
}
}
}
},
"/api/setCenter/share/index": {
"get": {
"description": "邀请链接界面接口",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"设置中心-邀请链接"
],
"summary": "邀请链接",
"parameters": [
{
"type": "string",
"description": "验证参数Bearer和token空格拼接",
"name": "Authorization",
"in": "header",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/md.ShareIndexResp"
}
},
"400": {
"description": "具体错误",
"schema": {
"$ref": "#/definitions/md.Response"
}
}
}
}
},
"/role/permissionGroupList": {
"get": {
"description": "权限管理-权限组列表",
@@ -1309,9 +1725,82 @@ const docTemplate = `{
}
}
}
},
"/v1/banner/delete/{$id}": {
"delete": {
"description": "小程序设置-删除",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"设置中心-小程序设置"
],
"summary": "删除",
"parameters": [
{
"type": "string",
"description": "验证参数Bearer和token空格拼接",
"name": "Authorization",
"in": "header",
"required": true
}
],
"responses": {
"200": {
"description": "success",
"schema": {
"type": "string"
}
},
"400": {
"description": "具体错误",
"schema": {
"$ref": "#/definitions/md.Response"
}
}
}
}
}
},
"definitions": {
"hdl.WxOpenThirdPartyAppList": {
"type": "object",
"properties": {
"aes_key": {
"type": "string"
},
"app_secret": {
"type": "string"
},
"appid": {
"type": "string"
},
"component_access_token": {
"type": "string"
},
"component_verify_ticket": {
"type": "string"
},
"create_at": {
"type": "string"
},
"id": {
"type": "integer"
},
"token": {
"type": "string"
},
"update_at": {
"type": "string"
},
"uuid": {
"type": "integer"
}
}
},
"md.AddAdminReq": {
"type": "object",
"required": [
@@ -1662,6 +2151,54 @@ const docTemplate = `{
}
}
},
"md.AppletAddReq": {
"type": "object",
"required": [
"appid",
"logo",
"name",
"original_id"
],
"properties": {
"appid": {
"type": "string",
"example": "授权小程序appid"
},
"logo": {
"type": "string",
"example": "小程序logo"
},
"name": {
"type": "string",
"example": "小程序名称"
},
"original_id": {
"type": "string",
"example": "授权小程序原始id"
}
}
},
"md.AppletUpdateReq": {
"type": "object",
"required": [
"id",
"logo",
"name"
],
"properties": {
"id": {
"type": "integer"
},
"logo": {
"type": "string",
"example": "小程序logo"
},
"name": {
"type": "string",
"example": "小程序名称"
}
}
},
"md.BindAdminRoleReq": {
"type": "object",
"required": [
@@ -1923,6 +2460,23 @@ const docTemplate = `{
}
}
},
"md.QiNiuBucketRegion": {
"type": "object",
"properties": {
"region_domain": {
"type": "string",
"example": "区域域名"
},
"region_id": {
"type": "string",
"example": "区域id"
},
"region_name": {
"type": "string",
"example": "区域名称"
}
}
},
"md.RegisterForAgentReq": {
"type": "object",
"required": [
@@ -2011,6 +2565,74 @@ const docTemplate = `{
}
}
},
"md.SetOssReq": {
"type": "object",
"required": [
"file_access_key",
"file_bucket",
"file_bucket_host",
"file_bucket_region",
"file_secret_key"
],
"properties": {
"file_access_key": {
"type": "string",
"example": "对象存储AccessToken"
},
"file_bucket": {
"type": "string",
"example": "对象存储bucket(空间)"
},
"file_bucket_host": {
"type": "string",
"example": "对象存储域名"
},
"file_bucket_region": {
"type": "string",
"example": "文件所属区域"
},
"file_secret_key": {
"type": "string",
"example": "对象存储SecretToken"
}
}
},
"md.SetOssResp": {
"type": "object",
"properties": {
"data": {
"description": "数据内容",
"allOf": [
{
"$ref": "#/definitions/md.SetOssReq"
}
]
},
"qi_niu_bucket_region_list": {
"description": "七牛云存储区域列表",
"type": "array",
"items": {
"$ref": "#/definitions/md.QiNiuBucketRegion"
}
}
}
},
"md.ShareIndexResp": {
"type": "object",
"properties": {
"agent_domain": {
"type": "string",
"example": "代理分享地址"
},
"master_id": {
"type": "string"
},
"medium_domain": {
"type": "string",
"example": "媒体分享地址"
}
}
},
"md.UpdateAdminReq": {
"type": "object",
"required": [
@@ -2081,6 +2703,74 @@ const docTemplate = `{
"type": "integer"
}
}
},
"md.WxOpenGetResp": {
"type": "object",
"properties": {
"aes_key": {
"type": "string",
"example": "消息加解密Key"
},
"app_secret": {
"type": "string",
"example": "appSecret"
},
"appid": {
"type": "string",
"example": "appid"
},
"token": {
"type": "string",
"example": "消息校验Token"
},
"wx_open_applet_server_domain": {
"type": "string",
"example": "微信开放平台-小程序服务器域名"
},
"wx_open_authorization_event_receiving_configuration": {
"type": "string",
"example": "微信开放平台-授权事件接收配置"
},
"wx_open_domain_of_the_initiating_page_for_login_authorization": {
"type": "string",
"example": "微信开放平台-登录授权的发起页域名"
},
"wx_open_message_and_event_reception_configuration": {
"type": "string",
"example": "微信开放平台-消息与事件接收配置"
},
"wx_open_white_list_ip": {
"type": "string",
"example": "微信开放平台-白名单ip"
}
}
},
"md.WxOpenSetReq": {
"type": "object",
"required": [
"aes_key",
"app_secret",
"appid",
"token"
],
"properties": {
"aes_key": {
"type": "string",
"example": "消息加解密Key"
},
"app_secret": {
"type": "string",
"example": "appSecret"
},
"appid": {
"type": "string",
"example": "appid"
},
"token": {
"type": "string",
"example": "消息校验Token"
}
}
}
},
"securityDefinitions": {


+ 690
- 0
docs/swagger.json Vedi File

@@ -1257,6 +1257,422 @@
}
}
},
"/api/setCenter/applet/add": {
"post": {
"description": "小程序设置-新增",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"设置中心-小程序设置"
],
"summary": "新增",
"parameters": [
{
"type": "string",
"description": "验证参数Bearer和token空格拼接",
"name": "Authorization",
"in": "header",
"required": true
},
{
"description": "请求参数",
"name": "args",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/md.AppletAddReq"
}
}
],
"responses": {
"200": {
"description": "success",
"schema": {
"type": "string"
}
},
"400": {
"description": "具体错误",
"schema": {
"$ref": "#/definitions/md.Response"
}
}
}
}
},
"/api/setCenter/applet/authorize": {
"get": {
"description": "设置中心-基础设置",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"设置中心"
],
"summary": "设置中心-基础设置-微信三方应用获取",
"parameters": [
{
"type": "string",
"description": "验证参数Bearer和token空格拼接",
"name": "Authorization",
"in": "header",
"required": true
}
],
"responses": {
"200": {
"description": "微信授权界面url",
"schema": {
"type": "string"
}
},
"400": {
"description": "具体错误",
"schema": {
"$ref": "#/definitions/md.Response"
}
}
}
}
},
"/api/setCenter/applet/list": {
"get": {
"description": "小程序设置-列表",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"设置中心-小程序设置"
],
"summary": "列表",
"parameters": [
{
"type": "string",
"description": "验证参数Bearer和token空格拼接",
"name": "Authorization",
"in": "header",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/hdl.WxOpenThirdPartyAppList"
}
},
"400": {
"description": "具体错误",
"schema": {
"$ref": "#/definitions/md.Response"
}
}
}
}
},
"/api/setCenter/applet/unauthorized": {
"get": {
"description": "设置中心-基础设置",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"设置中心"
],
"summary": "设置中心-基础设置-微信三方应用获取",
"parameters": [
{
"type": "string",
"description": "验证参数Bearer和token空格拼接",
"name": "Authorization",
"in": "header",
"required": true
}
],
"responses": {
"200": {
"description": "success",
"schema": {
"type": "string"
}
},
"400": {
"description": "具体错误",
"schema": {
"$ref": "#/definitions/md.Response"
}
}
}
}
},
"/api/setCenter/applet/update": {
"post": {
"description": "小程序设置-更新",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"设置中心-小程序设置"
],
"summary": "更新",
"parameters": [
{
"type": "string",
"description": "验证参数Bearer和token空格拼接",
"name": "Authorization",
"in": "header",
"required": true
},
{
"description": "请求参数",
"name": "args",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/md.AppletUpdateReq"
}
}
],
"responses": {
"200": {
"description": "success",
"schema": {
"type": "string"
}
},
"400": {
"description": "具体错误",
"schema": {
"$ref": "#/definitions/md.Response"
}
}
}
}
},
"/api/setCenter/basic/getOss": {
"get": {
"description": "基础设置-oss获取",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"设置中心-基础设置"
],
"summary": "oss获取",
"parameters": [
{
"type": "string",
"description": "验证参数Bearer和token空格拼接",
"name": "Authorization",
"in": "header",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/md.SetOssResp"
}
},
"400": {
"description": "具体错误",
"schema": {
"$ref": "#/definitions/md.Response"
}
}
}
}
},
"/api/setCenter/basic/setOss": {
"post": {
"description": "基础设置-oss设置",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"设置中心-基础设置"
],
"summary": "oss设置",
"parameters": [
{
"type": "string",
"description": "验证参数Bearer和token空格拼接",
"name": "Authorization",
"in": "header",
"required": true
},
{
"description": "请求参数",
"name": "args",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/md.SetOssReq"
}
}
],
"responses": {
"200": {
"description": "success",
"schema": {
"type": "string"
}
},
"400": {
"description": "具体错误",
"schema": {
"$ref": "#/definitions/md.Response"
}
}
}
}
},
"/api/setCenter/basic/wxOpenGet": {
"get": {
"description": "基础设置-微信三方应用获取",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"设置中心-基础设置"
],
"summary": "微信三方应用获取",
"parameters": [
{
"type": "string",
"description": "验证参数Bearer和token空格拼接",
"name": "Authorization",
"in": "header",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/md.WxOpenGetResp"
}
},
"400": {
"description": "具体错误",
"schema": {
"$ref": "#/definitions/md.Response"
}
}
}
}
},
"/api/setCenter/basic/wxOpenSet": {
"post": {
"description": "基础设置-微信三方应用设置",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"设置中心-基础设置"
],
"summary": "微信三方应用设置",
"parameters": [
{
"type": "string",
"description": "验证参数Bearer和token空格拼接",
"name": "Authorization",
"in": "header",
"required": true
},
{
"description": "请求参数",
"name": "args",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/md.WxOpenSetReq"
}
}
],
"responses": {
"200": {
"description": "success",
"schema": {
"type": "string"
}
},
"400": {
"description": "具体错误",
"schema": {
"$ref": "#/definitions/md.Response"
}
}
}
}
},
"/api/setCenter/share/index": {
"get": {
"description": "邀请链接界面接口",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"设置中心-邀请链接"
],
"summary": "邀请链接",
"parameters": [
{
"type": "string",
"description": "验证参数Bearer和token空格拼接",
"name": "Authorization",
"in": "header",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/md.ShareIndexResp"
}
},
"400": {
"description": "具体错误",
"schema": {
"$ref": "#/definitions/md.Response"
}
}
}
}
},
"/role/permissionGroupList": {
"get": {
"description": "权限管理-权限组列表",
@@ -1301,9 +1717,82 @@
}
}
}
},
"/v1/banner/delete/{$id}": {
"delete": {
"description": "小程序设置-删除",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"设置中心-小程序设置"
],
"summary": "删除",
"parameters": [
{
"type": "string",
"description": "验证参数Bearer和token空格拼接",
"name": "Authorization",
"in": "header",
"required": true
}
],
"responses": {
"200": {
"description": "success",
"schema": {
"type": "string"
}
},
"400": {
"description": "具体错误",
"schema": {
"$ref": "#/definitions/md.Response"
}
}
}
}
}
},
"definitions": {
"hdl.WxOpenThirdPartyAppList": {
"type": "object",
"properties": {
"aes_key": {
"type": "string"
},
"app_secret": {
"type": "string"
},
"appid": {
"type": "string"
},
"component_access_token": {
"type": "string"
},
"component_verify_ticket": {
"type": "string"
},
"create_at": {
"type": "string"
},
"id": {
"type": "integer"
},
"token": {
"type": "string"
},
"update_at": {
"type": "string"
},
"uuid": {
"type": "integer"
}
}
},
"md.AddAdminReq": {
"type": "object",
"required": [
@@ -1654,6 +2143,54 @@
}
}
},
"md.AppletAddReq": {
"type": "object",
"required": [
"appid",
"logo",
"name",
"original_id"
],
"properties": {
"appid": {
"type": "string",
"example": "授权小程序appid"
},
"logo": {
"type": "string",
"example": "小程序logo"
},
"name": {
"type": "string",
"example": "小程序名称"
},
"original_id": {
"type": "string",
"example": "授权小程序原始id"
}
}
},
"md.AppletUpdateReq": {
"type": "object",
"required": [
"id",
"logo",
"name"
],
"properties": {
"id": {
"type": "integer"
},
"logo": {
"type": "string",
"example": "小程序logo"
},
"name": {
"type": "string",
"example": "小程序名称"
}
}
},
"md.BindAdminRoleReq": {
"type": "object",
"required": [
@@ -1915,6 +2452,23 @@
}
}
},
"md.QiNiuBucketRegion": {
"type": "object",
"properties": {
"region_domain": {
"type": "string",
"example": "区域域名"
},
"region_id": {
"type": "string",
"example": "区域id"
},
"region_name": {
"type": "string",
"example": "区域名称"
}
}
},
"md.RegisterForAgentReq": {
"type": "object",
"required": [
@@ -2003,6 +2557,74 @@
}
}
},
"md.SetOssReq": {
"type": "object",
"required": [
"file_access_key",
"file_bucket",
"file_bucket_host",
"file_bucket_region",
"file_secret_key"
],
"properties": {
"file_access_key": {
"type": "string",
"example": "对象存储AccessToken"
},
"file_bucket": {
"type": "string",
"example": "对象存储bucket(空间)"
},
"file_bucket_host": {
"type": "string",
"example": "对象存储域名"
},
"file_bucket_region": {
"type": "string",
"example": "文件所属区域"
},
"file_secret_key": {
"type": "string",
"example": "对象存储SecretToken"
}
}
},
"md.SetOssResp": {
"type": "object",
"properties": {
"data": {
"description": "数据内容",
"allOf": [
{
"$ref": "#/definitions/md.SetOssReq"
}
]
},
"qi_niu_bucket_region_list": {
"description": "七牛云存储区域列表",
"type": "array",
"items": {
"$ref": "#/definitions/md.QiNiuBucketRegion"
}
}
}
},
"md.ShareIndexResp": {
"type": "object",
"properties": {
"agent_domain": {
"type": "string",
"example": "代理分享地址"
},
"master_id": {
"type": "string"
},
"medium_domain": {
"type": "string",
"example": "媒体分享地址"
}
}
},
"md.UpdateAdminReq": {
"type": "object",
"required": [
@@ -2073,6 +2695,74 @@
"type": "integer"
}
}
},
"md.WxOpenGetResp": {
"type": "object",
"properties": {
"aes_key": {
"type": "string",
"example": "消息加解密Key"
},
"app_secret": {
"type": "string",
"example": "appSecret"
},
"appid": {
"type": "string",
"example": "appid"
},
"token": {
"type": "string",
"example": "消息校验Token"
},
"wx_open_applet_server_domain": {
"type": "string",
"example": "微信开放平台-小程序服务器域名"
},
"wx_open_authorization_event_receiving_configuration": {
"type": "string",
"example": "微信开放平台-授权事件接收配置"
},
"wx_open_domain_of_the_initiating_page_for_login_authorization": {
"type": "string",
"example": "微信开放平台-登录授权的发起页域名"
},
"wx_open_message_and_event_reception_configuration": {
"type": "string",
"example": "微信开放平台-消息与事件接收配置"
},
"wx_open_white_list_ip": {
"type": "string",
"example": "微信开放平台-白名单ip"
}
}
},
"md.WxOpenSetReq": {
"type": "object",
"required": [
"aes_key",
"app_secret",
"appid",
"token"
],
"properties": {
"aes_key": {
"type": "string",
"example": "消息加解密Key"
},
"app_secret": {
"type": "string",
"example": "appSecret"
},
"appid": {
"type": "string",
"example": "appid"
},
"token": {
"type": "string",
"example": "消息校验Token"
}
}
}
},
"securityDefinitions": {


+ 466
- 0
docs/swagger.yaml Vedi File

@@ -1,4 +1,27 @@
definitions:
hdl.WxOpenThirdPartyAppList:
properties:
aes_key:
type: string
app_secret:
type: string
appid:
type: string
component_access_token:
type: string
component_verify_ticket:
type: string
create_at:
type: string
id:
type: integer
token:
type: string
update_at:
type: string
uuid:
type: integer
type: object
md.AddAdminReq:
properties:
memo:
@@ -244,6 +267,41 @@ definitions:
$ref: '#/definitions/md.SelectData'
type: array
type: object
md.AppletAddReq:
properties:
appid:
example: 授权小程序appid
type: string
logo:
example: 小程序logo
type: string
name:
example: 小程序名称
type: string
original_id:
example: 授权小程序原始id
type: string
required:
- appid
- logo
- name
- original_id
type: object
md.AppletUpdateReq:
properties:
id:
type: integer
logo:
example: 小程序logo
type: string
name:
example: 小程序名称
type: string
required:
- id
- logo
- name
type: object
md.BindAdminRoleReq:
properties:
adm_id:
@@ -427,6 +485,18 @@ definitions:
$ref: '#/definitions/md.SelectData'
type: array
type: object
md.QiNiuBucketRegion:
properties:
region_domain:
example: 区域域名
type: string
region_id:
example: 区域id
type: string
region_name:
example: 区域名称
type: string
type: object
md.RegisterForAgentReq:
properties:
code:
@@ -488,6 +558,53 @@ definitions:
example: 值
type: string
type: object
md.SetOssReq:
properties:
file_access_key:
example: 对象存储AccessToken
type: string
file_bucket:
example: 对象存储bucket(空间)
type: string
file_bucket_host:
example: 对象存储域名
type: string
file_bucket_region:
example: 文件所属区域
type: string
file_secret_key:
example: 对象存储SecretToken
type: string
required:
- file_access_key
- file_bucket
- file_bucket_host
- file_bucket_region
- file_secret_key
type: object
md.SetOssResp:
properties:
data:
allOf:
- $ref: '#/definitions/md.SetOssReq'
description: 数据内容
qi_niu_bucket_region_list:
description: 七牛云存储区域列表
items:
$ref: '#/definitions/md.QiNiuBucketRegion'
type: array
type: object
md.ShareIndexResp:
properties:
agent_domain:
example: 代理分享地址
type: string
master_id:
type: string
medium_domain:
example: 媒体分享地址
type: string
type: object
md.UpdateAdminReq:
properties:
adm_id:
@@ -536,6 +653,56 @@ definitions:
- role_id
- state
type: object
md.WxOpenGetResp:
properties:
aes_key:
example: 消息加解密Key
type: string
app_secret:
example: appSecret
type: string
appid:
example: appid
type: string
token:
example: 消息校验Token
type: string
wx_open_applet_server_domain:
example: 微信开放平台-小程序服务器域名
type: string
wx_open_authorization_event_receiving_configuration:
example: 微信开放平台-授权事件接收配置
type: string
wx_open_domain_of_the_initiating_page_for_login_authorization:
example: 微信开放平台-登录授权的发起页域名
type: string
wx_open_message_and_event_reception_configuration:
example: 微信开放平台-消息与事件接收配置
type: string
wx_open_white_list_ip:
example: 微信开放平台-白名单ip
type: string
type: object
md.WxOpenSetReq:
properties:
aes_key:
example: 消息加解密Key
type: string
app_secret:
example: appSecret
type: string
appid:
example: appid
type: string
token:
example: 消息校验Token
type: string
required:
- aes_key
- app_secret
- appid
- token
type: object
host: localhost:1002 or xxxx.advertisement.dengbiao.top
info:
contact:
@@ -1366,6 +1533,280 @@ paths:
summary: 修改角色状态
tags:
- 权限管理
/api/setCenter/applet/add:
post:
consumes:
- application/json
description: 小程序设置-新增
parameters:
- description: 验证参数Bearer和token空格拼接
in: header
name: Authorization
required: true
type: string
- description: 请求参数
in: body
name: args
required: true
schema:
$ref: '#/definitions/md.AppletAddReq'
produces:
- application/json
responses:
"200":
description: success
schema:
type: string
"400":
description: 具体错误
schema:
$ref: '#/definitions/md.Response'
summary: 新增
tags:
- 设置中心-小程序设置
/api/setCenter/applet/authorize:
get:
consumes:
- application/json
description: 设置中心-基础设置
parameters:
- description: 验证参数Bearer和token空格拼接
in: header
name: Authorization
required: true
type: string
produces:
- application/json
responses:
"200":
description: 微信授权界面url
schema:
type: string
"400":
description: 具体错误
schema:
$ref: '#/definitions/md.Response'
summary: 设置中心-基础设置-微信三方应用获取
tags:
- 设置中心
/api/setCenter/applet/list:
get:
consumes:
- application/json
description: 小程序设置-列表
parameters:
- description: 验证参数Bearer和token空格拼接
in: header
name: Authorization
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/hdl.WxOpenThirdPartyAppList'
"400":
description: 具体错误
schema:
$ref: '#/definitions/md.Response'
summary: 列表
tags:
- 设置中心-小程序设置
/api/setCenter/applet/unauthorized:
get:
consumes:
- application/json
description: 设置中心-基础设置
parameters:
- description: 验证参数Bearer和token空格拼接
in: header
name: Authorization
required: true
type: string
produces:
- application/json
responses:
"200":
description: success
schema:
type: string
"400":
description: 具体错误
schema:
$ref: '#/definitions/md.Response'
summary: 设置中心-基础设置-微信三方应用获取
tags:
- 设置中心
/api/setCenter/applet/update:
post:
consumes:
- application/json
description: 小程序设置-更新
parameters:
- description: 验证参数Bearer和token空格拼接
in: header
name: Authorization
required: true
type: string
- description: 请求参数
in: body
name: args
required: true
schema:
$ref: '#/definitions/md.AppletUpdateReq'
produces:
- application/json
responses:
"200":
description: success
schema:
type: string
"400":
description: 具体错误
schema:
$ref: '#/definitions/md.Response'
summary: 更新
tags:
- 设置中心-小程序设置
/api/setCenter/basic/getOss:
get:
consumes:
- application/json
description: 基础设置-oss获取
parameters:
- description: 验证参数Bearer和token空格拼接
in: header
name: Authorization
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/md.SetOssResp'
"400":
description: 具体错误
schema:
$ref: '#/definitions/md.Response'
summary: oss获取
tags:
- 设置中心-基础设置
/api/setCenter/basic/setOss:
post:
consumes:
- application/json
description: 基础设置-oss设置
parameters:
- description: 验证参数Bearer和token空格拼接
in: header
name: Authorization
required: true
type: string
- description: 请求参数
in: body
name: args
required: true
schema:
$ref: '#/definitions/md.SetOssReq'
produces:
- application/json
responses:
"200":
description: success
schema:
type: string
"400":
description: 具体错误
schema:
$ref: '#/definitions/md.Response'
summary: oss设置
tags:
- 设置中心-基础设置
/api/setCenter/basic/wxOpenGet:
get:
consumes:
- application/json
description: 基础设置-微信三方应用获取
parameters:
- description: 验证参数Bearer和token空格拼接
in: header
name: Authorization
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/md.WxOpenGetResp'
"400":
description: 具体错误
schema:
$ref: '#/definitions/md.Response'
summary: 微信三方应用获取
tags:
- 设置中心-基础设置
/api/setCenter/basic/wxOpenSet:
post:
consumes:
- application/json
description: 基础设置-微信三方应用设置
parameters:
- description: 验证参数Bearer和token空格拼接
in: header
name: Authorization
required: true
type: string
- description: 请求参数
in: body
name: args
required: true
schema:
$ref: '#/definitions/md.WxOpenSetReq'
produces:
- application/json
responses:
"200":
description: success
schema:
type: string
"400":
description: 具体错误
schema:
$ref: '#/definitions/md.Response'
summary: 微信三方应用设置
tags:
- 设置中心-基础设置
/api/setCenter/share/index:
get:
consumes:
- application/json
description: 邀请链接界面接口
parameters:
- description: 验证参数Bearer和token空格拼接
in: header
name: Authorization
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/md.ShareIndexResp'
"400":
description: 具体错误
schema:
$ref: '#/definitions/md.Response'
summary: 邀请链接
tags:
- 设置中心-邀请链接
/role/permissionGroupList:
get:
consumes:
@@ -1396,6 +1837,31 @@ paths:
summary: 权限组列表
tags:
- 权限管理
/v1/banner/delete/{$id}:
delete:
consumes:
- application/json
description: 小程序设置-删除
parameters:
- description: 验证参数Bearer和token空格拼接
in: header
name: Authorization
required: true
type: string
produces:
- application/json
responses:
"200":
description: success
schema:
type: string
"400":
description: 具体错误
schema:
$ref: '#/definitions/md.Response'
summary: 删除
tags:
- 设置中心-小程序设置
securityDefinitions:
MasterID:
in: header


+ 1
- 1
go.mod Vedi File

@@ -5,7 +5,7 @@ go 1.18
//replace code.fnuoos.com/zhimeng/model.git => E:/company/ad/models

require (
code.fnuoos.com/zhimeng/model.git v0.0.3-0.20240820125928-6ce4c06dda24
code.fnuoos.com/zhimeng/model.git v0.0.3-0.20240822024421-0129770e24d7
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5
github.com/boombuler/barcode v1.0.1
github.com/dchest/uniuri v0.0.0-20200228104902-7aecb25e1fe5


Caricamento…
Annulla
Salva