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 }