diff --git a/docs/docs.go b/docs/docs.go index 7694b0c..9b3702a 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -1401,6 +1401,58 @@ const docTemplate = `{ } } }, + "/api/wechat/subscribe": { + "post": { + "description": "根据模板ID发送订阅消息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "微信" + ], + "summary": "发送订阅消息", + "parameters": [ + { + "description": "请求参数", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/wechat.sendSubscribeMessageRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/wechat.sendSubscribeMessageResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/code.Failure" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/code.Failure" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/code.Failure" + } + } + } + } + }, "/api/wechat/template": { "post": { "description": "根据 AppID 获取微信小程序的模板ID", @@ -2528,6 +2580,44 @@ const docTemplate = `{ } } }, + "wechat.sendSubscribeMessageRequest": { + "type": "object", + "required": [ + "app_id", + "app_secret", + "template_id", + "touser" + ], + "properties": { + "app_id": { + "description": "微信小程序 AppID", + "type": "string" + }, + "app_secret": { + "description": "小程序 AppSecret", + "type": "string" + }, + "template_id": { + "description": "模板 ID", + "type": "string" + }, + "touser": { + "description": "接收者(用户)的 openid", + "type": "string" + } + } + }, + "wechat.sendSubscribeMessageResponse": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "success": { + "type": "boolean" + } + } + }, "wechat.templateRequest": { "type": "object", "required": [ diff --git a/docs/swagger.json b/docs/swagger.json index f7c604a..8fdfe7a 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -1393,6 +1393,58 @@ } } }, + "/api/wechat/subscribe": { + "post": { + "description": "根据模板ID发送订阅消息", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "微信" + ], + "summary": "发送订阅消息", + "parameters": [ + { + "description": "请求参数", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/wechat.sendSubscribeMessageRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/wechat.sendSubscribeMessageResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/code.Failure" + } + }, + "404": { + "description": "Not Found", + "schema": { + "$ref": "#/definitions/code.Failure" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/code.Failure" + } + } + } + } + }, "/api/wechat/template": { "post": { "description": "根据 AppID 获取微信小程序的模板ID", @@ -2520,6 +2572,44 @@ } } }, + "wechat.sendSubscribeMessageRequest": { + "type": "object", + "required": [ + "app_id", + "app_secret", + "template_id", + "touser" + ], + "properties": { + "app_id": { + "description": "微信小程序 AppID", + "type": "string" + }, + "app_secret": { + "description": "小程序 AppSecret", + "type": "string" + }, + "template_id": { + "description": "模板 ID", + "type": "string" + }, + "touser": { + "description": "接收者(用户)的 openid", + "type": "string" + } + } + }, + "wechat.sendSubscribeMessageResponse": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "success": { + "type": "boolean" + } + } + }, "wechat.templateRequest": { "type": "object", "required": [ diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 1e0d34c..12d49de 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -761,6 +761,33 @@ definitions: description: 用户昵称 type: string type: object + wechat.sendSubscribeMessageRequest: + properties: + app_id: + description: 微信小程序 AppID + type: string + app_secret: + description: 小程序 AppSecret + type: string + template_id: + description: 模板 ID + type: string + touser: + description: 接收者(用户)的 openid + type: string + required: + - app_id + - app_secret + - template_id + - touser + type: object + wechat.sendSubscribeMessageResponse: + properties: + message: + type: string + success: + type: boolean + type: object wechat.templateRequest: properties: app_id: @@ -1683,6 +1710,40 @@ paths: summary: 生成微信小程序二维码 tags: - 微信 + /api/wechat/subscribe: + post: + consumes: + - application/json + description: 根据模板ID发送订阅消息 + parameters: + - description: 请求参数 + in: body + name: request + required: true + schema: + $ref: '#/definitions/wechat.sendSubscribeMessageRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/wechat.sendSubscribeMessageResponse' + "400": + description: Bad Request + schema: + $ref: '#/definitions/code.Failure' + "404": + description: Not Found + schema: + $ref: '#/definitions/code.Failure' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/code.Failure' + summary: 发送订阅消息 + tags: + - 微信 /api/wechat/template: post: consumes: diff --git a/internal/api/wechat/mini_template.go b/internal/api/wechat/mini_template.go index 2605569..e3de0fe 100644 --- a/internal/api/wechat/mini_template.go +++ b/internal/api/wechat/mini_template.go @@ -3,9 +3,11 @@ package wechat import ( "fmt" "net/http" + "time" "mini-chat/internal/code" "mini-chat/internal/pkg/core" + "mini-chat/internal/pkg/miniprogram" "mini-chat/internal/pkg/validation" "gorm.io/gorm" @@ -90,3 +92,73 @@ func (h *handler) GetTemplate() core.HandlerFunc { ctx.Payload(res) } } + +type sendSubscribeMessageRequest struct { + AppID string `json:"app_id" binding:"required"` // 微信小程序 AppID + TemplateID string `json:"template_id" binding:"required"` // 模板 ID + AppSecret string `json:"app_secret" binding:"required"` // 小程序 AppSecret + Touser string `json:"touser" binding:"required"` // 接收者(用户)的 openid +} + +type sendSubscribeMessageResponse struct { + Success bool `json:"success"` + Message string `json:"message"` +} + +// SendSubscribeMessage 发送订阅消息 +// @Summary 发送订阅消息 +// @Description 根据模板ID发送订阅消息 +// @Tags 微信 +// @Accept json +// @Produce json +// @Param request body sendSubscribeMessageRequest true "请求参数" +// @Success 200 {object} sendSubscribeMessageResponse +// @Failure 400 {object} code.Failure +// @Failure 404 {object} code.Failure +// @Failure 500 {object} code.Failure +// @Router /api/wechat/subscribe [post] +func (h *handler) SendSubscribeMessage() core.HandlerFunc { + return func(ctx core.Context) { + req := new(sendSubscribeMessageRequest) + res := new(sendSubscribeMessageResponse) + + // 参数绑定和验证 + if err := ctx.ShouldBindJSON(req); err != nil { + ctx.AbortWithError(core.Error( + http.StatusBadRequest, + code.ParamBindError, + validation.Error(err), + )) + return + } + + // 发送模版消息 + accessToken, err := h.servicesMiniProgram.GetAccessToken(req.AppID, req.AppSecret, ctx) + if err != nil { + h.logger.Error(fmt.Sprintf("获取access_token失败: %s", err.Error())) + } else { + sendSubscribeMessageRequest := new(miniprogram.SendSubscribeMessageRequest) + sendSubscribeMessageRequest.Touser = req.Touser + sendSubscribeMessageRequest.TemplateID = req.TemplateID + sendSubscribeMessageRequest.Page = "pages/contact/index" + sendSubscribeMessageRequest.MiniprogramState = "developer" // 需要改成正式版 目前是体验版 跳转小程序类型:developer 为开发版;trial为体验版;formal为正式版;默认为正式版 + sendSubscribeMessageRequest.Lang = "zh_CN" + sendSubscribeMessageRequest.Data.Thing1.Value = "留言提醒" + sendSubscribeMessageRequest.Data.Time2.Value = time.Now().Format("2006-01-02 15:04:05") + sendSubscribeMessageRequest.Data.Thing4.Value = "您有一条新的消息..." + + sendSubscribeMessageResponse := new(miniprogram.SendSubscribeMessageResponse) + err = miniprogram.SendSubscribeMessage(accessToken, sendSubscribeMessageRequest, sendSubscribeMessageResponse) + if err != nil { + res.Success = false + res.Message = "发送订阅消息失败" + err.Error() + h.logger.Error(fmt.Sprintf("发送模版消息失败: %s", err.Error())) + } else { + res.Success = true + res.Message = "订阅消息发送成功" + } + } + + ctx.Payload(res) + } +} diff --git a/internal/api/wechat/miniprogram_login.go b/internal/api/wechat/miniprogram_login.go index 8fa127a..66b39da 100644 --- a/internal/api/wechat/miniprogram_login.go +++ b/internal/api/wechat/miniprogram_login.go @@ -11,7 +11,6 @@ import ( "mini-chat/internal/code" "mini-chat/internal/pkg/core" "mini-chat/internal/pkg/httpclient" - "mini-chat/internal/pkg/miniprogram" "mini-chat/internal/pkg/validation" "mini-chat/internal/repository/mysql/model" @@ -118,28 +117,6 @@ func (h *handler) MiniprogramLogin() core.HandlerFunc { return } - // 发送模版消息 - accessToken, err := h.servicesMiniProgram.GetAccessToken(req.AppID, miniProgram.AppSecret, ctx) - if err != nil { - h.logger.Error(fmt.Sprintf("获取access_token失败: %s", err.Error())) - } else { - sendSubscribeMessageRequest := new(miniprogram.SendSubscribeMessageRequest) - sendSubscribeMessageRequest.Touser = openID - sendSubscribeMessageRequest.TemplateID = miniProgram.TemplateID - sendSubscribeMessageRequest.Page = "pages/contact/index" - sendSubscribeMessageRequest.MiniprogramState = "trial" - sendSubscribeMessageRequest.Lang = "zh_CN" - sendSubscribeMessageRequest.Data.Thing1.Value = "测试(CC)" - sendSubscribeMessageRequest.Data.Time2.Value = "2025-10-27" - sendSubscribeMessageRequest.Data.Thing4.Value = "测试(CC)" - - sendSubscribeMessageResponse := new(miniprogram.SendSubscribeMessageResponse) - err = miniprogram.SendSubscribeMessage(accessToken, sendSubscribeMessageRequest, sendSubscribeMessageResponse) - if err != nil { - h.logger.Error(fmt.Sprintf("发送模版消息失败: %s", err.Error())) - } - } - res.Success = true res.Message = "登录成功" res.Token = token diff --git a/internal/router/router.go b/internal/router/router.go index b937d10..a786d53 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -74,6 +74,7 @@ func NewHTTPMux(logger logger.CustomLogger, db mysql.Repo, cron cron.Server) (co wechatApiRouter.POST("/qrcode", wechatHandler.GenerateQRCode()) // 生成微信小程序二维码(返回 Base64) wechatApiRouter.POST("/miniprogram/login", wechatHandler.MiniprogramLogin()) // 小程序登录 wechatApiRouter.POST("/template", wechatHandler.GetTemplate()) // 生成微信小程序模板消息 + wechatApiRouter.POST("/subscribe", wechatHandler.SendSubscribeMessage()) // 发送订阅消息 } // 管理端认证接口路由组