130 lines
3.7 KiB
Go
130 lines
3.7 KiB
Go
package handler
|
||
|
||
import (
|
||
"encoding/json"
|
||
"net/http"
|
||
|
||
"silk-server-go/internal/middleware"
|
||
"silk-server-go/internal/model"
|
||
"silk-server-go/internal/service"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
"gorm.io/gorm"
|
||
)
|
||
|
||
// RegisterWechatRoutes 注册微信订阅消息路由(骨架,配置占位)
|
||
func RegisterWechatRoutes(rg *gin.RouterGroup, db *gorm.DB, wechat *service.WechatService) {
|
||
read := middleware.RequirePermission(db, "notification:read")
|
||
write := middleware.RequirePermission(db, "notification:write")
|
||
rg.GET("/wechat/binding", read, getWechatBinding(db))
|
||
rg.POST("/wechat/bind", write, bindWechat(db, wechat))
|
||
rg.POST("/wechat/subscribe", write, updateWechatSubscribe(db))
|
||
}
|
||
|
||
// getWechatBinding 当前用户的微信绑定与授权模板
|
||
func getWechatBinding(db *gorm.DB) gin.HandlerFunc {
|
||
return func(c *gin.Context) {
|
||
uid := currentUserID(c)
|
||
if uid == nil {
|
||
c.JSON(http.StatusUnauthorized, gin.H{"error": "未登录"})
|
||
return
|
||
}
|
||
var b model.WechatBinding
|
||
if db.Where("user_id = ?", *uid).First(&b).Error != nil {
|
||
c.JSON(http.StatusOK, gin.H{"bound": false})
|
||
return
|
||
}
|
||
c.JSON(http.StatusOK, gin.H{
|
||
"bound": true,
|
||
"openId": b.OpenID,
|
||
"authorized": b.AuthorizedTemplates,
|
||
})
|
||
}
|
||
}
|
||
|
||
// bindWechat 用 wx.login 的 code 换 openid 并绑定当前用户
|
||
func bindWechat(db *gorm.DB, wechat *service.WechatService) gin.HandlerFunc {
|
||
return func(c *gin.Context) {
|
||
uid := currentUserID(c)
|
||
if uid == nil {
|
||
c.JSON(http.StatusUnauthorized, gin.H{"error": "未登录"})
|
||
return
|
||
}
|
||
var body struct {
|
||
Code string `json:"code"`
|
||
}
|
||
if err := c.ShouldBindJSON(&body); err != nil || body.Code == "" {
|
||
c.JSON(http.StatusBadRequest, gin.H{"error": "缺少 code"})
|
||
return
|
||
}
|
||
openid, err := wechat.Code2Session(c.Request.Context(), body.Code)
|
||
if err != nil {
|
||
c.JSON(http.StatusBadGateway, gin.H{"error": err.Error()})
|
||
return
|
||
}
|
||
var b model.WechatBinding
|
||
if db.Where("user_id = ?", *uid).First(&b).Error != nil {
|
||
b = model.WechatBinding{UserID: *uid, OpenID: openid}
|
||
if err := db.Create(&b).Error; err != nil {
|
||
c.JSON(http.StatusInternalServerError, gin.H{"error": "绑定失败"})
|
||
return
|
||
}
|
||
} else {
|
||
db.Model(&model.WechatBinding{}).Where("id = ?", b.ID).Update("open_id", openid)
|
||
}
|
||
c.JSON(http.StatusOK, gin.H{"bound": true, "openId": openid})
|
||
}
|
||
}
|
||
|
||
// updateWechatSubscribe 更新用户对某场景的订阅授权(alarm/inspection)
|
||
func updateWechatSubscribe(db *gorm.DB) gin.HandlerFunc {
|
||
return func(c *gin.Context) {
|
||
uid := currentUserID(c)
|
||
if uid == nil {
|
||
c.JSON(http.StatusUnauthorized, gin.H{"error": "未登录"})
|
||
return
|
||
}
|
||
var body struct {
|
||
Template string `json:"template"`
|
||
Authorized bool `json:"authorized"`
|
||
}
|
||
if err := c.ShouldBindJSON(&body); err != nil || body.Template == "" {
|
||
c.JSON(http.StatusBadRequest, gin.H{"error": "缺少 template"})
|
||
return
|
||
}
|
||
var b model.WechatBinding
|
||
if db.Where("user_id = ?", *uid).First(&b).Error != nil {
|
||
c.JSON(http.StatusNotFound, gin.H{"error": "请先绑定微信"})
|
||
return
|
||
}
|
||
var templates []string
|
||
if len(b.AuthorizedTemplates) > 0 {
|
||
_ = json.Unmarshal(b.AuthorizedTemplates, &templates)
|
||
}
|
||
templates = toggleTemplate(templates, body.Template, body.Authorized)
|
||
raw, _ := json.Marshal(templates)
|
||
db.Model(&model.WechatBinding{}).Where("id = ?", b.ID).Update("authorized_templates", raw)
|
||
c.JSON(http.StatusOK, gin.H{"authorized": templates})
|
||
}
|
||
}
|
||
|
||
// toggleTemplate 增删授权模板键
|
||
func toggleTemplate(list []string, key string, add bool) []string {
|
||
out := make([]string, 0, len(list))
|
||
exists := false
|
||
for _, k := range list {
|
||
if k == key {
|
||
exists = true
|
||
if add {
|
||
out = append(out, k)
|
||
}
|
||
continue
|
||
}
|
||
out = append(out, k)
|
||
}
|
||
if add && !exists {
|
||
out = append(out, key)
|
||
}
|
||
return out
|
||
}
|