219 lines
5.6 KiB
Go
219 lines
5.6 KiB
Go
package controllers
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"io"
|
||
"strconv"
|
||
"strings"
|
||
|
||
"server/models"
|
||
"server/pkg/jwtutil"
|
||
"server/services/wechatmini"
|
||
"server/services/wechatmp"
|
||
|
||
beego "github.com/beego/beego/v2/server/web"
|
||
)
|
||
|
||
// =============================================================
|
||
// 平台端「微信小程序」配置:AppID / AppSecret / 启用开关 / 自动绑定
|
||
//
|
||
// 配置就绪后,uniapp 小程序端的登录页才会展示「微信手机号一键登录」入口
|
||
// (GET /auth/wechat/miniapp/config 返回 enabled)。
|
||
// AppSecret 掩码回显,提交空串或掩码表示不修改。
|
||
// =============================================================
|
||
|
||
// PlatformWechatMiniController 平台端微信小程序配置
|
||
type PlatformWechatMiniController struct {
|
||
beego.Controller
|
||
}
|
||
|
||
func (c *PlatformWechatMiniController) claims() (*jwtutil.Claims, error) {
|
||
auth := c.Ctx.Request.Header.Get("Authorization")
|
||
if auth == "" {
|
||
return nil, fmt.Errorf("未登录")
|
||
}
|
||
parts := strings.SplitN(auth, " ", 2)
|
||
if len(parts) != 2 || parts[0] != "Bearer" {
|
||
return nil, fmt.Errorf("认证信息格式错误")
|
||
}
|
||
claims, err := jwtutil.ParseToken(parts[1])
|
||
if err != nil {
|
||
return nil, fmt.Errorf("无效的token")
|
||
}
|
||
if claims.UserType != "platform" {
|
||
return nil, fmt.Errorf("无权访问")
|
||
}
|
||
return claims, nil
|
||
}
|
||
|
||
func (c *PlatformWechatMiniController) jsonErr(httpStatus, bizCode int, msg string) {
|
||
c.Ctx.Output.SetStatus(httpStatus)
|
||
c.Data["json"] = map[string]interface{}{"code": bizCode, "msg": msg}
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
func (c *PlatformWechatMiniController) ok(data interface{}, msg string) {
|
||
if msg == "" {
|
||
msg = "success"
|
||
}
|
||
resp := map[string]interface{}{"code": 200, "msg": msg}
|
||
if data != nil {
|
||
resp["data"] = data
|
||
}
|
||
c.Data["json"] = resp
|
||
_ = c.ServeJSON()
|
||
}
|
||
|
||
// GetConfig GET /platform/wechatMini/config
|
||
func (c *PlatformWechatMiniController) GetConfig() {
|
||
if _, err := c.claims(); err != nil {
|
||
c.jsonErr(401, 401, err.Error())
|
||
return
|
||
}
|
||
data := map[string]interface{}{
|
||
"app_id": "",
|
||
"app_secret": "",
|
||
"enabled": 0,
|
||
"auto_bind": 1,
|
||
"remark": "",
|
||
"configured": false,
|
||
}
|
||
if cfg, err := wechatmini.LoadConfig(); err == nil {
|
||
data["app_id"] = cfg.AppID
|
||
data["app_secret"] = wechatmp.MaskSecret(cfg.AppSecret)
|
||
data["remark"] = cfg.Remark
|
||
data["configured"] = cfg.AppID != "" && cfg.AppSecret != ""
|
||
if cfg.Enabled {
|
||
data["enabled"] = 1
|
||
}
|
||
if cfg.AutoBind {
|
||
data["auto_bind"] = 1
|
||
} else {
|
||
data["auto_bind"] = 0
|
||
}
|
||
}
|
||
c.ok(data, "获取成功")
|
||
}
|
||
|
||
// SaveConfig POST /platform/wechatMini/config
|
||
func (c *PlatformWechatMiniController) SaveConfig() {
|
||
if _, err := c.claims(); err != nil {
|
||
c.jsonErr(401, 401, err.Error())
|
||
return
|
||
}
|
||
var p struct {
|
||
AppID string `json:"app_id"`
|
||
AppSecret string `json:"app_secret"`
|
||
Enabled int `json:"enabled"`
|
||
AutoBind int `json:"auto_bind"`
|
||
Remark string `json:"remark"`
|
||
}
|
||
raw, err := io.ReadAll(c.Ctx.Request.Body)
|
||
if err != nil {
|
||
c.jsonErr(400, 400, "参数错误")
|
||
return
|
||
}
|
||
if err := json.Unmarshal(raw, &p); err != nil {
|
||
c.jsonErr(400, 400, "参数错误")
|
||
return
|
||
}
|
||
|
||
if err := wechatmini.SaveConfig(wechatmini.SaveInput{
|
||
AppID: p.AppID,
|
||
AppSecret: p.AppSecret,
|
||
Enabled: p.Enabled == 1,
|
||
AutoBind: p.AutoBind == 1,
|
||
Remark: p.Remark,
|
||
}); err != nil {
|
||
c.jsonErr(400, 400, err.Error())
|
||
return
|
||
}
|
||
c.ok(nil, "保存成功")
|
||
}
|
||
|
||
// ListApps GET /platform/wechatMini/apps 多小程序应用列表(AppSecret 不回显)
|
||
func (c *PlatformWechatMiniController) ListApps() {
|
||
if _, err := c.claims(); err != nil {
|
||
c.jsonErr(401, 401, err.Error())
|
||
return
|
||
}
|
||
rows, err := wechatmini.ListApps()
|
||
if err != nil {
|
||
c.jsonErr(500, 500, "获取应用列表失败")
|
||
return
|
||
}
|
||
type appDTO struct {
|
||
models.WechatMiniApp
|
||
Configured bool `json:"configured"` // AppSecret 已配置
|
||
}
|
||
list := make([]appDTO, 0, len(rows))
|
||
for _, r := range rows {
|
||
dto := appDTO{WechatMiniApp: r, Configured: r.AppSecret != ""}
|
||
list = append(list, dto)
|
||
}
|
||
c.ok(map[string]interface{}{"list": list}, "获取成功")
|
||
}
|
||
|
||
// SaveApp POST /platform/wechatMini/app/save 新增/更新应用
|
||
func (c *PlatformWechatMiniController) SaveApp() {
|
||
if _, err := c.claims(); err != nil {
|
||
c.jsonErr(401, 401, err.Error())
|
||
return
|
||
}
|
||
var p struct {
|
||
ID uint64 `json:"id"`
|
||
Name string `json:"name"`
|
||
AppID string `json:"app_id"`
|
||
AppSecret string `json:"app_secret"`
|
||
Enabled int `json:"enabled"`
|
||
AutoBind int `json:"auto_bind"`
|
||
Remark string `json:"remark"`
|
||
}
|
||
raw, err := io.ReadAll(c.Ctx.Request.Body)
|
||
if err != nil {
|
||
c.jsonErr(400, 400, "参数错误")
|
||
return
|
||
}
|
||
if err := json.Unmarshal(raw, &p); err != nil {
|
||
c.jsonErr(400, 400, "参数错误")
|
||
return
|
||
}
|
||
if strings.TrimSpace(p.Name) == "" {
|
||
c.jsonErr(400, 400, "应用名称不能为空")
|
||
return
|
||
}
|
||
id, err := wechatmini.SaveApp(wechatmini.SaveAppInput{
|
||
ID: p.ID,
|
||
Name: p.Name,
|
||
AppID: p.AppID,
|
||
AppSecret: p.AppSecret,
|
||
Enabled: p.Enabled == 1,
|
||
AutoBind: p.AutoBind == 1,
|
||
Remark: p.Remark,
|
||
})
|
||
if err != nil {
|
||
c.jsonErr(400, 400, err.Error())
|
||
return
|
||
}
|
||
c.ok(map[string]interface{}{"id": id}, "保存成功")
|
||
}
|
||
|
||
// DeleteApp POST /platform/wechatMini/app/delete/:id 软删应用并停用
|
||
func (c *PlatformWechatMiniController) DeleteApp() {
|
||
if _, err := c.claims(); err != nil {
|
||
c.jsonErr(401, 401, err.Error())
|
||
return
|
||
}
|
||
id, err := strconv.ParseUint(c.Ctx.Input.Param(":id"), 10, 64)
|
||
if err != nil || id == 0 {
|
||
c.jsonErr(400, 400, "无效ID")
|
||
return
|
||
}
|
||
if err := wechatmini.DeleteApp(id); err != nil {
|
||
c.jsonErr(400, 400, err.Error())
|
||
return
|
||
}
|
||
c.ok(nil, "已删除")
|
||
}
|