优化小程序部分

This commit is contained in:
hero920103 committed 2026-10-31 19:17:37 +08:00
1 parent 727319a6eb
commit d4e89788c5
46 files changed
+4906 -63

No files matched your search

+232
View File
@@ -208,3 +208,235 @@ func (c *PlatformWechatMiniController) DeleteApp() {
}
c.ok(nil, "已删除")
}
// =============================================================
// 消息推送配置(小程序后台「开发管理 → 开发设置 → 消息推送」)
// =============================================================
// GetPushConfig GET /platform/wechatMini/app/push?app_id=xxx
// 返回该小程序的推送参数与「回调地址」(填到微信后台 URL),AESKey 掩码回显
func (c *PlatformWechatMiniController) GetPushConfig() {
if _, err := c.claims(); err != nil {
code := identity.Status(err)
c.jsonErr(code, code, err.Error())
return
}
appID := strings.TrimSpace(c.GetString("app_id"))
if appID == "" {
c.jsonErr(400, 400, "缺少 app_id")
return
}
cfg, err := wechatmini.LoadPushConfigByAppID(appID)
if err != nil {
c.jsonErr(400, 400, "小程序不存在或消息推送未配置")
return
}
c.ok(map[string]interface{}{
"app_id": cfg.AppID,
"token": cfg.Token,
"aes_key": wechatmp.MaskSecret(cfg.AESKey),
"encrypt_mode": cfg.EncryptMode,
"data_format": cfg.DataFormat,
"push_reply": cfg.ReplyText,
"callback_url": wechatmini.PushCallbackURL(),
"configured": cfg.Token != "",
}, "获取成功")
}
// SavePushConfig POST /platform/wechatMini/app/push/save
func (c *PlatformWechatMiniController) SavePushConfig() {
if _, err := c.claims(); err != nil {
code := identity.Status(err)
c.jsonErr(code, code, err.Error())
return
}
var p struct {
AppID string `json:"app_id"`
Token string `json:"token"`
AESKey string `json:"aes_key"`
EncryptMode string `json:"encrypt_mode"`
DataFormat string `json:"data_format"`
PushReply string `json:"push_reply"`
}
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.AppID) == "" {
c.jsonErr(400, 400, "缺少 app_id")
return
}
if err := wechatmini.SavePushConfig(wechatmini.SavePushConfigInput{
AppID: p.AppID,
Token: p.Token,
AESKey: p.AESKey,
EncryptMode: p.EncryptMode,
DataFormat: p.DataFormat,
ReplyText: p.PushReply,
}); err != nil {
c.jsonErr(400, 400, err.Error())
return
}
c.ok(map[string]interface{}{"callback_url": wechatmini.PushCallbackURL()}, "保存成功")
}
// GeneratePushSecret POST /platform/wechatMini/app/push/generate
// 生成随机 Token 与 EncodingAESKey(43 位字母数字)
func (c *PlatformWechatMiniController) GeneratePushSecret() {
if _, err := c.claims(); err != nil {
code := identity.Status(err)
c.jsonErr(code, code, err.Error())
return
}
c.ok(map[string]interface{}{
"token": wechatmini.GeneratePushToken(),
"aes_key": wechatmini.GeneratePushAESKey(),
}, "生成成功")
}
// =============================================================
// 订阅消息模板(小程序后台「功能 → 订阅消息」选用模板后在此登记)
// =============================================================
// ListTemplates GET /platform/wechatMini/templates?app_id=xxx
func (c *PlatformWechatMiniController) ListTemplates() {
if _, err := c.claims(); err != nil {
code := identity.Status(err)
c.jsonErr(code, code, err.Error())
return
}
appID := strings.TrimSpace(c.GetString("app_id"))
rows, err := wechatmini.ListTemplates(appID)
if err != nil {
c.jsonErr(500, 500, "获取模板列表失败")
return
}
c.ok(map[string]interface{}{"list": rows}, "获取成功")
}
// SaveTemplate POST /platform/wechatMini/template/save
func (c *PlatformWechatMiniController) SaveTemplate() {
if _, err := c.claims(); err != nil {
code := identity.Status(err)
c.jsonErr(code, code, err.Error())
return
}
var p struct {
ID uint64 `json:"id"`
AppID string `json:"app_id"`
Code string `json:"code"`
TemplateID string `json:"template_id"`
Title string `json:"title"`
Page string `json:"page"`
Fields string `json:"fields"`
Enabled int `json:"enabled"`
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.SaveTemplate(wechatmini.TemplateInput{
ID: p.ID,
AppID: p.AppID,
Code: p.Code,
TemplateID: p.TemplateID,
Title: p.Title,
Page: p.Page,
Fields: p.Fields,
Enabled: p.Enabled == 1,
Remark: p.Remark,
}); err != nil {
c.jsonErr(400, 400, err.Error())
return
}
c.ok(nil, "保存成功")
}
// DeleteTemplate POST /platform/wechatMini/template/delete/:id
func (c *PlatformWechatMiniController) DeleteTemplate() {
if _, err := c.claims(); err != nil {
code := identity.Status(err)
c.jsonErr(code, code, 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.DeleteTemplate(id); err != nil {
c.jsonErr(400, 400, err.Error())
return
}
c.ok(nil, "已删除")
}
// TestTemplate POST /platform/wechatMini/template/test
// 给指定租户用户发一条测试订阅消息,验证模板与字段映射是否正确
func (c *PlatformWechatMiniController) TestTemplate() {
if _, err := c.claims(); err != nil {
code := identity.Status(err)
c.jsonErr(code, code, err.Error())
return
}
var p struct {
TenantUserID uint64 `json:"tenant_user_id"`
AppID string `json:"app_id"`
Code string `json:"code"`
Title string `json:"title"`
Content string `json:"content"`
}
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 p.TenantUserID == 0 {
c.jsonErr(400, 400, "请指定测试用户(租户用户ID)")
return
}
code := strings.TrimSpace(p.Code)
if code == "" {
code = wechatmini.SceneNotice
}
title := strings.TrimSpace(p.Title)
if title == "" {
title = "测试提醒"
}
content := strings.TrimSpace(p.Content)
if content == "" {
content = "这是一条订阅消息测试,收到说明配置正确。"
}
res := wechatmini.PushSubscribeToTenantUser(p.TenantUserID, code, strings.TrimSpace(p.AppID), map[string]string{
"title": title,
"content": content,
})
if res.Sent > 0 {
c.ok(map[string]interface{}{"sent": res.Sent}, "已发送")
return
}
if len(res.Errors) > 0 {
msg := res.Errors[0].Error()
if hint := wechatmini.ExplainSubscribeError(res.Errors[0]); hint != "" {
msg = hint
}
c.jsonErr(400, 400, msg)
return
}
c.jsonErr(400, 400, "未发送:该用户没有授权订阅,或模板未配置/未启用")
}