From 713b0e723a9993339bad940480ab3af2f460bf72 Mon Sep 17 00:00:00 2001 From: summer <> Date: Fri, 17 Oct 2025 15:19:29 +0800 Subject: [PATCH] =?UTF-8?q?feat(1.0):=E5=A2=9E=E5=8A=A0=E5=AE=A2=E6=9C=8D?= =?UTF-8?q?=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/docs.go | 73 +++++++++++++ docs/swagger.json | 73 +++++++++++++ docs/swagger.yaml | 47 +++++++++ internal/api/admin/admin_rel_app.go | 156 ++++++++++++++++++++++++++++ internal/code/code.go | 1 + internal/code/zh-cn.go | 1 + internal/router/router.go | 1 + 7 files changed, 352 insertions(+) create mode 100755 internal/api/admin/admin_rel_app.go diff --git a/docs/docs.go b/docs/docs.go index 6664198..ecc0477 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -922,6 +922,58 @@ const docTemplate = `{ } } }, + "/admin/rel_app/{id}": { + "put": { + "security": [ + { + "LoginVerifyToken": [] + } + ], + "description": "客服关联小程序", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "管理端.客服管理" + ], + "summary": "客服关联小程序", + "parameters": [ + { + "type": "string", + "description": "客服编号ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "请求参数", + "name": "RequestBody", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/admin.relAppRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/admin.relAppResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/code.Failure" + } + } + } + } + }, "/admin/send_message": { "post": { "security": [ @@ -1385,6 +1437,27 @@ const docTemplate = `{ } } }, + "admin.relAppRequest": { + "type": "object", + "required": [ + "ids" + ], + "properties": { + "ids": { + "description": "小程序编号(多个用,分割)", + "type": "string" + } + } + }, + "admin.relAppResponse": { + "type": "object", + "properties": { + "message": { + "description": "提示信息", + "type": "string" + } + } + }, "app.adminSendMessageRequest": { "type": "object", "required": [ diff --git a/docs/swagger.json b/docs/swagger.json index 65cce33..26a5b86 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -914,6 +914,58 @@ } } }, + "/admin/rel_app/{id}": { + "put": { + "security": [ + { + "LoginVerifyToken": [] + } + ], + "description": "客服关联小程序", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "管理端.客服管理" + ], + "summary": "客服关联小程序", + "parameters": [ + { + "type": "string", + "description": "客服编号ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "请求参数", + "name": "RequestBody", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/admin.relAppRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/admin.relAppResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/code.Failure" + } + } + } + } + }, "/admin/send_message": { "post": { "security": [ @@ -1377,6 +1429,27 @@ } } }, + "admin.relAppRequest": { + "type": "object", + "required": [ + "ids" + ], + "properties": { + "ids": { + "description": "小程序编号(多个用,分割)", + "type": "string" + } + } + }, + "admin.relAppResponse": { + "type": "object", + "properties": { + "message": { + "description": "提示信息", + "type": "string" + } + } + }, "app.adminSendMessageRequest": { "type": "object", "required": [ diff --git a/docs/swagger.yaml b/docs/swagger.yaml index f0805b4..04dd342 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -131,6 +131,20 @@ definitions: description: 提示信息 type: string type: object + admin.relAppRequest: + properties: + ids: + description: 小程序编号(多个用,分割) + type: string + required: + - ids + type: object + admin.relAppResponse: + properties: + message: + description: 提示信息 + type: string + type: object app.adminSendMessageRequest: properties: app_id: @@ -1243,6 +1257,39 @@ paths: summary: 获取消息日志 tags: - 管理端.小程序 + /admin/rel_app/{id}: + put: + consumes: + - application/json + description: 客服关联小程序 + parameters: + - description: 客服编号ID + in: path + name: id + required: true + type: string + - description: 请求参数 + in: body + name: RequestBody + required: true + schema: + $ref: '#/definitions/admin.relAppRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/admin.relAppResponse' + "400": + description: Bad Request + schema: + $ref: '#/definitions/code.Failure' + security: + - LoginVerifyToken: [] + summary: 客服关联小程序 + tags: + - 管理端.客服管理 /admin/send_message: post: consumes: diff --git a/internal/api/admin/admin_rel_app.go b/internal/api/admin/admin_rel_app.go new file mode 100755 index 0000000..39a9747 --- /dev/null +++ b/internal/api/admin/admin_rel_app.go @@ -0,0 +1,156 @@ +package admin + +import ( + "fmt" + "net/http" + "strconv" + "strings" + "time" + + "mini-chat/internal/code" + "mini-chat/internal/pkg/core" + "mini-chat/internal/pkg/validation" + + "gorm.io/gorm" +) + +type relAppRequest struct { + Ids string `json:"ids" binding:"required"` // 小程序编号(多个用,分割) +} + +type relAppResponse struct { + Message string `json:"message"` // 提示信息 +} + +// RelApp 客服关联小程序 +// @Summary 客服关联小程序 +// @Description 客服关联小程序 +// @Tags 管理端.客服管理 +// @Accept json +// @Produce json +// @Param id path string true "客服编号ID" +// @Param RequestBody body relAppRequest true "请求参数" +// @Success 200 {object} relAppResponse +// @Failure 400 {object} code.Failure +// @Router /admin/rel_app/{id} [put] +// @Security LoginVerifyToken +func (h *handler) RelApp() core.HandlerFunc { + return func(ctx core.Context) { + req := new(relAppRequest) + res := new(relAppResponse) + if err := ctx.ShouldBindJSON(req); err != nil { + ctx.AbortWithError(core.Error( + http.StatusBadRequest, + code.ParamBindError, + validation.Error(err)), + ) + return + } + + if ctx.SessionUserInfo().IsSuper != 1 { + ctx.AbortWithError(core.Error( + http.StatusBadRequest, + code.RelAppError, + fmt.Sprintf("%s: %s", code.Text(code.RelAppError), "禁止操作")), + ) + return + } + + idList := strings.Split(req.Ids, ",") + if len(idList) == 0 || (len(idList) == 1 && idList[0] == "") { + ctx.AbortWithError(core.Error( + http.StatusBadRequest, + code.ParamBindError, + "编号不能为空"), + ) + return + } + + var ids []int32 + + for _, strID := range idList { + if strID == "" { + continue + } + + id, err := strconv.Atoi(strID) + if err != nil { + ctx.AbortWithError(core.Error( + http.StatusBadRequest, + code.ParamBindError, + fmt.Sprintf("无效的编号: %s", strID)), + ) + return + } + + ids = append(ids, int32(id)) + } + + if len(ids) == 0 { + ctx.AbortWithError(core.Error( + http.StatusBadRequest, + code.ParamBindError, + "编号不能为空"), + ) + return + } + + adminID, err := strconv.Atoi(ctx.Param("id")) + if err != nil { + ctx.AbortWithError(core.Error( + http.StatusBadRequest, + code.ParamBindError, + "未传递客服编号ID"), + ) + return + } + + checkInfo, err := h.readDB.Admin.WithContext(ctx.RequestContext()). + Where(h.readDB.Admin.ID.Eq(int32(adminID))). + First() + if err != nil && err != gorm.ErrRecordNotFound { + ctx.AbortWithError(core.Error( + http.StatusBadRequest, + code.RelAppError, + fmt.Sprintf("%s: %s", code.Text(code.RelAppError), err.Error())), + ) + return + } + + if checkInfo == nil { + ctx.AbortWithError(core.Error( + http.StatusBadRequest, + code.RelAppError, + fmt.Sprintf("%s: %s", code.Text(code.RelAppError), "该客服不存在")), + ) + return + } + + if checkInfo.IsSuper == 1 { + ctx.AbortWithError(core.Error( + http.StatusBadRequest, + code.RelAppError, + fmt.Sprintf("%s", "作为超级管理员,您拥有无需关联即可查看的权限。")), + ) + return + } + + if _, err := h.writeDB.MiniProgram.WithContext(ctx.RequestContext()). + Where(h.writeDB.MiniProgram.ID.In(ids...)). + Updates(map[string]interface{}{ + "admin_id": adminID, + "updated_user": ctx.SessionUserInfo().UserName, + "updated_at": time.Now(), + }); err != nil { + ctx.AbortWithError(core.Error( + http.StatusBadRequest, + code.RelAppError, + fmt.Sprintf("%s: %s", code.Text(code.RelAppError), err.Error())), + ) + return + } + + res.Message = "操作成功" + ctx.Payload(res) + } +} diff --git a/internal/code/code.go b/internal/code/code.go index e445950..01024ef 100644 --- a/internal/code/code.go +++ b/internal/code/code.go @@ -32,6 +32,7 @@ const ( ListAdminError = 20208 ModifyAdminError = 20209 DeleteAdminError = 20210 + RelAppError = 20211 CreateKeywordError = 20301 ListKeywordError = 20302 diff --git a/internal/code/zh-cn.go b/internal/code/zh-cn.go index 722dc1f..e340253 100644 --- a/internal/code/zh-cn.go +++ b/internal/code/zh-cn.go @@ -18,6 +18,7 @@ var zhCNText = map[int]string{ ListAdminError: "获取客服列表失败", ModifyAdminError: "修改客服失败", DeleteAdminError: "删除客服失败", + RelAppError: "关联小程序失败", CreateKeywordError: "创建关键字失败", DeleteKeywordError: "删除关键字失败", diff --git a/internal/router/router.go b/internal/router/router.go index 59d22d6..4857003 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -78,6 +78,7 @@ func NewHTTPMux(logger logger.CustomLogger, db mysql.Repo, cron cron.Server) (co adminAuthApiRouter.POST("/delete", adminHandler.DeleteAdmin()) // 删除客服 adminAuthApiRouter.PUT("/:id", adminHandler.ModifyAdmin()) // 编辑客服 adminAuthApiRouter.GET("/list", adminHandler.PageList()) // 客服列表 + adminAuthApiRouter.PUT("/rel_app/:id", adminHandler.RelApp()) // 关联小程序 adminAuthApiRouter.POST("/app/keyword", keywordHandler.CreateKeyword()) // 添加意图关键字 adminAuthApiRouter.PUT("/app/keyword/:id", keywordHandler.ModifyKeyword()) // 修改意图关键字