feat(小程序): 添加检查小程序状态接口
refactor(测试): 移除测试中的硬编码凭证 fix(模板消息): 将小程序状态改为正式版 docs(swagger): 更新API文档并移除密码必填限制
This commit is contained in:
parent
53cb31f6ce
commit
084b802b05
65
docs/docs.go
65
docs/docs.go
@ -15,6 +15,49 @@ const docTemplate = `{
|
||||
"host": "{{.Host}}",
|
||||
"basePath": "{{.BasePath}}",
|
||||
"paths": {
|
||||
"/api/admin/app/check_status": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"LoginVerifyToken": []
|
||||
}
|
||||
],
|
||||
"description": "管理端根据 app_id 调用外部验证服务获取状态(正常/封禁/未知)",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"管理端.小程序"
|
||||
],
|
||||
"summary": "检查小程序状态",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "小程序ID",
|
||||
"name": "app_id",
|
||||
"in": "query",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/app.checkAppStatusResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/code.Failure"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/admin/app/create": {
|
||||
"post": {
|
||||
"security": [
|
||||
@ -1657,7 +1700,6 @@ const docTemplate = `{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"nickname",
|
||||
"password",
|
||||
"username"
|
||||
],
|
||||
"properties": {
|
||||
@ -1772,6 +1814,27 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"app.checkAppStatusResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"app_id": {
|
||||
"description": "小程序ID",
|
||||
"type": "string"
|
||||
},
|
||||
"check_status_text": {
|
||||
"description": "状态文字描述",
|
||||
"type": "string"
|
||||
},
|
||||
"code": {
|
||||
"description": "外部接口返回的状态码",
|
||||
"type": "integer"
|
||||
},
|
||||
"status": {
|
||||
"description": "外部接口返回的状态",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"app.createAppRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
|
||||
@ -7,6 +7,49 @@
|
||||
},
|
||||
"basePath": "/",
|
||||
"paths": {
|
||||
"/api/admin/app/check_status": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"LoginVerifyToken": []
|
||||
}
|
||||
],
|
||||
"description": "管理端根据 app_id 调用外部验证服务获取状态(正常/封禁/未知)",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"管理端.小程序"
|
||||
],
|
||||
"summary": "检查小程序状态",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "小程序ID",
|
||||
"name": "app_id",
|
||||
"in": "query",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/app.checkAppStatusResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/code.Failure"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/admin/app/create": {
|
||||
"post": {
|
||||
"security": [
|
||||
@ -1649,7 +1692,6 @@
|
||||
"type": "object",
|
||||
"required": [
|
||||
"nickname",
|
||||
"password",
|
||||
"username"
|
||||
],
|
||||
"properties": {
|
||||
@ -1764,6 +1806,27 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"app.checkAppStatusResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"app_id": {
|
||||
"description": "小程序ID",
|
||||
"type": "string"
|
||||
},
|
||||
"check_status_text": {
|
||||
"description": "状态文字描述",
|
||||
"type": "string"
|
||||
},
|
||||
"code": {
|
||||
"description": "外部接口返回的状态码",
|
||||
"type": "integer"
|
||||
},
|
||||
"status": {
|
||||
"description": "外部接口返回的状态",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"app.createAppRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
|
||||
@ -122,7 +122,6 @@ definitions:
|
||||
type: string
|
||||
required:
|
||||
- nickname
|
||||
- password
|
||||
- username
|
||||
type: object
|
||||
admin.modifyAdminResponse:
|
||||
@ -187,6 +186,21 @@ definitions:
|
||||
description: 符合查询条件的总记录数
|
||||
type: integer
|
||||
type: object
|
||||
app.checkAppStatusResponse:
|
||||
properties:
|
||||
app_id:
|
||||
description: 小程序ID
|
||||
type: string
|
||||
check_status_text:
|
||||
description: 状态文字描述
|
||||
type: string
|
||||
code:
|
||||
description: 外部接口返回的状态码
|
||||
type: integer
|
||||
status:
|
||||
description: 外部接口返回的状态
|
||||
type: string
|
||||
type: object
|
||||
app.createAppRequest:
|
||||
properties:
|
||||
app_id:
|
||||
@ -889,6 +903,33 @@ paths:
|
||||
summary: 编辑小程序
|
||||
tags:
|
||||
- 管理端.小程序
|
||||
/api/admin/app/check_status:
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 管理端根据 app_id 调用外部验证服务获取状态(正常/封禁/未知)
|
||||
parameters:
|
||||
- description: 小程序ID
|
||||
in: query
|
||||
name: app_id
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/app.checkAppStatusResponse'
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
$ref: '#/definitions/code.Failure'
|
||||
security:
|
||||
- LoginVerifyToken: []
|
||||
summary: 检查小程序状态
|
||||
tags:
|
||||
- 管理端.小程序
|
||||
/api/admin/app/create:
|
||||
post:
|
||||
consumes:
|
||||
|
||||
114
internal/api/app/app_check_status.go
Normal file
114
internal/api/app/app_check_status.go
Normal file
@ -0,0 +1,114 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"mini-chat/internal/code"
|
||||
"mini-chat/internal/pkg/core"
|
||||
"mini-chat/internal/pkg/httpclient"
|
||||
"mini-chat/internal/pkg/validation"
|
||||
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// checkAppStatusRequest 请求参数
|
||||
// 功能描述:用于检查指定小程序(app_id)的运行状态
|
||||
// 参数说明:
|
||||
// - AppID(string): 小程序ID,必填,通过query参数传入(form:"app_id")
|
||||
// 返回值:无(该函数返回一个core.HandlerFunc处理器,在HTTP请求完成后通过ctx.Payload返回JSON数据)
|
||||
type checkAppStatusRequest struct {
|
||||
AppID string `form:"app_id" binding:"required"` // 小程序ID
|
||||
}
|
||||
|
||||
// checkAppStatusResponse 响应数据结构
|
||||
// 功能描述:返回外部验证服务的状态码与状态文本,并提供统一的文字描述
|
||||
// 字段说明:
|
||||
// - AppID(string): 小程序ID
|
||||
// - Code(int): 外部接口返回的状态码,1表示正常,0表示封禁,其它表示未知
|
||||
// - Status(string): 外部接口返回的原始状态描述
|
||||
// - CheckStatusText(string): 根据Code映射得到的中文状态文字(正常/封禁/未知)
|
||||
type checkAppStatusResponse struct {
|
||||
AppID string `json:"app_id"` // 小程序ID
|
||||
Code int `json:"code"` // 外部接口返回的状态码
|
||||
CheckStatusText string `json:"check_status_text"` // 状态文字描述
|
||||
}
|
||||
|
||||
// CheckAppStatus 检查小程序状态
|
||||
// @Summary 检查小程序状态
|
||||
// @Description 管理端根据 app_id 调用外部验证服务获取状态(正常/封禁/未知)
|
||||
// @Tags 管理端.小程序
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param app_id query string true "小程序ID"
|
||||
// @Success 200 {object} checkAppStatusResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/admin/app/check_status [get]
|
||||
// @Security LoginVerifyToken
|
||||
func (h *handler) CheckAppStatus() core.HandlerFunc {
|
||||
return func(ctx core.Context) {
|
||||
// 绑定请求参数
|
||||
req := new(checkAppStatusRequest)
|
||||
if err := ctx.ShouldBindForm(req); err != nil {
|
||||
ctx.AbortWithError(core.Error(
|
||||
http.StatusBadRequest,
|
||||
code.ParamBindError,
|
||||
validation.Error(err)),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// 调用外部验证服务
|
||||
// 外部接口: https://api.wxapi.work/xcx/checkxcx.php?appid=<AppID>
|
||||
// 期望返回: {"code":1, "appid":"xxx", "status":"ok"}
|
||||
type externalCheckResp struct {
|
||||
Code int `json:"code"`
|
||||
Appid string `json:"appid"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
checkRes := new(externalCheckResp)
|
||||
response, err := httpclient.GetHttpClientWithContext(ctx.RequestContext()).R().
|
||||
SetQueryParams(map[string]string{
|
||||
"appid": req.AppID,
|
||||
}).
|
||||
SetResult(checkRes).
|
||||
Get("https://api.wxapi.work/xcx/checkxcx.php")
|
||||
|
||||
if err != nil {
|
||||
// 记录请求错误
|
||||
h.logger.Error("请求APP验证服务失败", zap.Error(err))
|
||||
ctx.AbortWithError(core.Error(
|
||||
http.StatusBadRequest,
|
||||
code.ListAppError,
|
||||
fmt.Sprintf("%s:%s", code.Text(code.ListAppError), err.Error()),
|
||||
))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查响应状态码
|
||||
if response.IsError() {
|
||||
h.logger.Error(fmt.Sprintf("请求APP验证服务异常(%d)", response.StatusCode()))
|
||||
}
|
||||
|
||||
// 将外部返回的code映射为中文状态
|
||||
statusText := "未知"
|
||||
switch checkRes.Code {
|
||||
case 1:
|
||||
statusText = "正常"
|
||||
case 0:
|
||||
statusText = "封禁"
|
||||
default:
|
||||
statusText = "未知"
|
||||
}
|
||||
|
||||
// 组织响应数据并返回
|
||||
res := &checkAppStatusResponse{
|
||||
AppID: req.AppID,
|
||||
Code: checkRes.Code,
|
||||
CheckStatusText: statusText,
|
||||
}
|
||||
|
||||
ctx.Payload(res)
|
||||
}
|
||||
}
|
||||
@ -158,7 +158,7 @@ func (h *handler) SendSubscribeMessage() core.HandlerFunc {
|
||||
sendSubscribeMessageReq.Touser = req.Touser
|
||||
sendSubscribeMessageReq.TemplateID = req.TemplateID
|
||||
sendSubscribeMessageReq.Page = "pages/index/detail?url=1"
|
||||
sendSubscribeMessageReq.MiniprogramState = "developer" // 需要改成正式版 目前是体验版 跳转小程序类型:developer 为开发版;trial为体验版;formal为正式版;默认为正式版
|
||||
sendSubscribeMessageReq.MiniprogramState = "formal" // 需要改成正式版 目前是体验版 跳转小程序类型:developer 为开发版;trial为体验版;formal 为正式版;默认为正式版
|
||||
sendSubscribeMessageReq.Lang = "zh_CN"
|
||||
sendSubscribeMessageReq.Data.Thing1.Value = "留言提醒"
|
||||
sendSubscribeMessageReq.Data.Time2.Value = time.Now().Format("2006-01-02 15:04:05")
|
||||
|
||||
@ -6,7 +6,7 @@ import (
|
||||
|
||||
func TestGetAccessToken(t *testing.T) {
|
||||
res := new(AccessTokenResponse)
|
||||
err := GetAccessToken("wx26ad074017e1e63f", "026c19ce4f3bb090c56573024c59a8be", res)
|
||||
err := GetAccessToken("", "", res)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ import (
|
||||
|
||||
func TestSendSubscribeMessage(t *testing.T) {
|
||||
res := new(AccessTokenResponse)
|
||||
err := GetAccessToken("wx26ad074017e1e63f", "026c19ce4f3bb090c56573024c59a8be", res)
|
||||
err := GetAccessToken("", "", res)
|
||||
if err != nil {
|
||||
t.Errorf("获取 access_token 错误: %s", err.Error())
|
||||
}
|
||||
@ -17,9 +17,9 @@ func TestSendSubscribeMessage(t *testing.T) {
|
||||
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)"
|
||||
sendSubscribeMessageRequest.Data.Thing1.Value = "测试"
|
||||
sendSubscribeMessageRequest.Data.Time2.Value = "2020-1-27"
|
||||
sendSubscribeMessageRequest.Data.Thing3.Value = "测试"
|
||||
|
||||
sendSubscribeMessageResponse := new(SendSubscribeMessageResponse)
|
||||
err = SendSubscribeMessage(res.AccessToken, sendSubscribeMessageRequest, sendSubscribeMessageResponse)
|
||||
|
||||
@ -84,6 +84,7 @@ func NewHTTPMux(logger logger.CustomLogger, db mysql.Repo, cron cron.Server) (co
|
||||
adminAuthApiRouter.POST("/app/delete", appHandler.DeleteApp()) // 删除小程序
|
||||
adminAuthApiRouter.PUT("/app/:id", appHandler.ModifyApp()) // 修改小程序
|
||||
adminAuthApiRouter.GET("/apps", appHandler.PageList()) // 小程序列表
|
||||
adminAuthApiRouter.GET("/app/check_status", appHandler.CheckAppStatus()) // 检查小程序状态
|
||||
|
||||
adminAuthApiRouter.POST("/create", adminHandler.CreateAdmin()) // 新增客服
|
||||
adminAuthApiRouter.POST("/delete", adminHandler.DeleteAdmin()) // 删除客服
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user