diff --git a/docs/docs.go b/docs/docs.go index eeb5494..e44bc8c 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -150,6 +150,167 @@ const docTemplate = `{ } } }, + "/admin/app/keyword/material/{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/keyword.modifyKeywordMaterialRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/keyword.modifyKeywordMaterialResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/code.Failure" + } + } + } + }, + "post": { + "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/keyword.createKeywordMaterialRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/keyword.createKeywordMaterialResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/code.Failure" + } + } + } + } + }, + "/admin/app/keyword/materials": { + "get": { + "security": [ + { + "LoginVerifyToken": [] + } + ], + "description": "获取意图关键字素材列表", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "管理端.意图关键字" + ], + "summary": "获取意图关键字素材列表", + "parameters": [ + { + "type": "integer", + "description": "意图关键字ID", + "name": "keyword_id", + "in": "query", + "required": true + }, + { + "type": "integer", + "default": 1, + "description": "当前页码", + "name": "page", + "in": "query", + "required": true + }, + { + "type": "integer", + "default": 20, + "description": "每页返回的数据量,最多 100 条", + "name": "page_size", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/keyword.keywordMaterialPageListResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/code.Failure" + } + } + } + } + }, "/admin/app/keyword/{id}": { "put": { "security": [ @@ -688,6 +849,30 @@ const docTemplate = `{ } } }, + "keyword.createKeywordMaterialRequest": { + "type": "object", + "required": [ + "material_list" + ], + "properties": { + "material_list": { + "description": "素材列表", + "type": "array", + "items": { + "$ref": "#/definitions/keyword.keywordMaterial" + } + } + } + }, + "keyword.createKeywordMaterialResponse": { + "type": "object", + "properties": { + "message": { + "description": "提示信息", + "type": "string" + } + } + }, "keyword.createKeywordRequest": { "type": "object", "required": [ @@ -764,6 +949,84 @@ const docTemplate = `{ } } }, + "keyword.keywordMaterial": { + "type": "object", + "required": [ + "content", + "interval_seconds", + "type" + ], + "properties": { + "content": { + "description": "素材内容", + "type": "string" + }, + "interval_seconds": { + "description": "发送间隔时间(单位:秒)", + "type": "integer" + }, + "type": { + "description": "素材类型(1:文本 2:图片)", + "type": "integer" + } + } + }, + "keyword.keywordMaterialListData": { + "type": "object", + "properties": { + "content": { + "description": "素材内容", + "type": "string" + }, + "created_at": { + "description": "创建时间", + "type": "string" + }, + "created_user": { + "description": "创建人", + "type": "string" + }, + "id": { + "description": "主键ID", + "type": "integer" + }, + "interval_seconds": { + "description": "素材发送间隔时间(单位:秒)", + "type": "integer" + }, + "keyword_id": { + "description": "意图关键字ID", + "type": "integer" + }, + "type": { + "description": "素材类型(1:文本 2:图片)", + "type": "integer" + } + } + }, + "keyword.keywordMaterialPageListResponse": { + "type": "object", + "properties": { + "list": { + "type": "array", + "items": { + "$ref": "#/definitions/keyword.keywordMaterialListData" + } + }, + "page": { + "description": "当前页码", + "type": "integer" + }, + "page_size": { + "description": "每页返回的数据量", + "type": "integer" + }, + "total": { + "description": "符合查询条件的总记录数", + "type": "integer" + } + } + }, "keyword.keywordPageListResponse": { "type": "object", "properties": { @@ -787,6 +1050,37 @@ const docTemplate = `{ } } }, + "keyword.modifyKeywordMaterialRequest": { + "type": "object", + "required": [ + "content", + "interval_seconds", + "type" + ], + "properties": { + "content": { + "description": "素材内容", + "type": "string" + }, + "interval_seconds": { + "description": "发送间隔时间(单位:秒)", + "type": "integer" + }, + "type": { + "description": "素材类型(1:文本 2:图片)", + "type": "integer" + } + } + }, + "keyword.modifyKeywordMaterialResponse": { + "type": "object", + "properties": { + "message": { + "description": "提示信息", + "type": "string" + } + } + }, "keyword.modifyKeywordRequest": { "type": "object", "required": [ diff --git a/docs/swagger.json b/docs/swagger.json index cd0dd69..0715dff 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -142,6 +142,167 @@ } } }, + "/admin/app/keyword/material/{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/keyword.modifyKeywordMaterialRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/keyword.modifyKeywordMaterialResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/code.Failure" + } + } + } + }, + "post": { + "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/keyword.createKeywordMaterialRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/keyword.createKeywordMaterialResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/code.Failure" + } + } + } + } + }, + "/admin/app/keyword/materials": { + "get": { + "security": [ + { + "LoginVerifyToken": [] + } + ], + "description": "获取意图关键字素材列表", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "管理端.意图关键字" + ], + "summary": "获取意图关键字素材列表", + "parameters": [ + { + "type": "integer", + "description": "意图关键字ID", + "name": "keyword_id", + "in": "query", + "required": true + }, + { + "type": "integer", + "default": 1, + "description": "当前页码", + "name": "page", + "in": "query", + "required": true + }, + { + "type": "integer", + "default": 20, + "description": "每页返回的数据量,最多 100 条", + "name": "page_size", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/keyword.keywordMaterialPageListResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/code.Failure" + } + } + } + } + }, "/admin/app/keyword/{id}": { "put": { "security": [ @@ -680,6 +841,30 @@ } } }, + "keyword.createKeywordMaterialRequest": { + "type": "object", + "required": [ + "material_list" + ], + "properties": { + "material_list": { + "description": "素材列表", + "type": "array", + "items": { + "$ref": "#/definitions/keyword.keywordMaterial" + } + } + } + }, + "keyword.createKeywordMaterialResponse": { + "type": "object", + "properties": { + "message": { + "description": "提示信息", + "type": "string" + } + } + }, "keyword.createKeywordRequest": { "type": "object", "required": [ @@ -756,6 +941,84 @@ } } }, + "keyword.keywordMaterial": { + "type": "object", + "required": [ + "content", + "interval_seconds", + "type" + ], + "properties": { + "content": { + "description": "素材内容", + "type": "string" + }, + "interval_seconds": { + "description": "发送间隔时间(单位:秒)", + "type": "integer" + }, + "type": { + "description": "素材类型(1:文本 2:图片)", + "type": "integer" + } + } + }, + "keyword.keywordMaterialListData": { + "type": "object", + "properties": { + "content": { + "description": "素材内容", + "type": "string" + }, + "created_at": { + "description": "创建时间", + "type": "string" + }, + "created_user": { + "description": "创建人", + "type": "string" + }, + "id": { + "description": "主键ID", + "type": "integer" + }, + "interval_seconds": { + "description": "素材发送间隔时间(单位:秒)", + "type": "integer" + }, + "keyword_id": { + "description": "意图关键字ID", + "type": "integer" + }, + "type": { + "description": "素材类型(1:文本 2:图片)", + "type": "integer" + } + } + }, + "keyword.keywordMaterialPageListResponse": { + "type": "object", + "properties": { + "list": { + "type": "array", + "items": { + "$ref": "#/definitions/keyword.keywordMaterialListData" + } + }, + "page": { + "description": "当前页码", + "type": "integer" + }, + "page_size": { + "description": "每页返回的数据量", + "type": "integer" + }, + "total": { + "description": "符合查询条件的总记录数", + "type": "integer" + } + } + }, "keyword.keywordPageListResponse": { "type": "object", "properties": { @@ -779,6 +1042,37 @@ } } }, + "keyword.modifyKeywordMaterialRequest": { + "type": "object", + "required": [ + "content", + "interval_seconds", + "type" + ], + "properties": { + "content": { + "description": "素材内容", + "type": "string" + }, + "interval_seconds": { + "description": "发送间隔时间(单位:秒)", + "type": "integer" + }, + "type": { + "description": "素材类型(1:文本 2:图片)", + "type": "integer" + } + } + }, + "keyword.modifyKeywordMaterialResponse": { + "type": "object", + "properties": { + "message": { + "description": "提示信息", + "type": "string" + } + } + }, "keyword.modifyKeywordRequest": { "type": "object", "required": [ diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 4405446..1dddb41 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -129,6 +129,22 @@ definitions: description: 描述信息 type: string type: object + keyword.createKeywordMaterialRequest: + properties: + material_list: + description: 素材列表 + items: + $ref: '#/definitions/keyword.keywordMaterial' + type: array + required: + - material_list + type: object + keyword.createKeywordMaterialResponse: + properties: + message: + description: 提示信息 + type: string + type: object keyword.createKeywordRequest: properties: app_id: @@ -183,6 +199,62 @@ definitions: description: 更新人 type: string type: object + keyword.keywordMaterial: + properties: + content: + description: 素材内容 + type: string + interval_seconds: + description: 发送间隔时间(单位:秒) + type: integer + type: + description: 素材类型(1:文本 2:图片) + type: integer + required: + - content + - interval_seconds + - type + type: object + keyword.keywordMaterialListData: + properties: + content: + description: 素材内容 + type: string + created_at: + description: 创建时间 + type: string + created_user: + description: 创建人 + type: string + id: + description: 主键ID + type: integer + interval_seconds: + description: 素材发送间隔时间(单位:秒) + type: integer + keyword_id: + description: 意图关键字ID + type: integer + type: + description: 素材类型(1:文本 2:图片) + type: integer + type: object + keyword.keywordMaterialPageListResponse: + properties: + list: + items: + $ref: '#/definitions/keyword.keywordMaterialListData' + type: array + page: + description: 当前页码 + type: integer + page_size: + description: 每页返回的数据量 + type: integer + total: + description: 符合查询条件的总记录数 + type: integer + type: object keyword.keywordPageListResponse: properties: list: @@ -199,6 +271,28 @@ definitions: description: 符合查询条件的总记录数 type: integer type: object + keyword.modifyKeywordMaterialRequest: + properties: + content: + description: 素材内容 + type: string + interval_seconds: + description: 发送间隔时间(单位:秒) + type: integer + type: + description: 素材类型(1:文本 2:图片) + type: integer + required: + - content + - interval_seconds + - type + type: object + keyword.modifyKeywordMaterialResponse: + properties: + message: + description: 提示信息 + type: string + type: object keyword.modifyKeywordRequest: properties: keyword: @@ -403,6 +497,110 @@ paths: summary: 修改意图关键字 tags: - 管理端.意图关键字 + /admin/app/keyword/material/{id}: + post: + 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/keyword.createKeywordMaterialRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/keyword.createKeywordMaterialResponse' + "400": + description: Bad Request + schema: + $ref: '#/definitions/code.Failure' + security: + - LoginVerifyToken: [] + summary: 配置意图关键字素材 + tags: + - 管理端.意图关键字 + 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/keyword.modifyKeywordMaterialRequest' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/keyword.modifyKeywordMaterialResponse' + "400": + description: Bad Request + schema: + $ref: '#/definitions/code.Failure' + security: + - LoginVerifyToken: [] + summary: 修改意图关键字素材 + tags: + - 管理端.意图关键字 + /admin/app/keyword/materials: + get: + consumes: + - application/json + description: 获取意图关键字素材列表 + parameters: + - description: 意图关键字ID + in: query + name: keyword_id + required: true + type: integer + - default: 1 + description: 当前页码 + in: query + name: page + required: true + type: integer + - default: 20 + description: 每页返回的数据量,最多 100 条 + in: query + name: page_size + required: true + type: integer + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/keyword.keywordMaterialPageListResponse' + "400": + description: Bad Request + schema: + $ref: '#/definitions/code.Failure' + security: + - LoginVerifyToken: [] + summary: 获取意图关键字素材列表 + tags: + - 管理端.意图关键字 /admin/app/keywords: get: consumes: diff --git a/internal/api/keyword/keyword_material_create.go b/internal/api/keyword/keyword_material_create.go new file mode 100644 index 0000000..b363588 --- /dev/null +++ b/internal/api/keyword/keyword_material_create.go @@ -0,0 +1,143 @@ +package keyword + +import ( + "fmt" + "net/http" + "strconv" + "time" + + "mini-chat/internal/code" + "mini-chat/internal/pkg/core" + "mini-chat/internal/pkg/validation" + "mini-chat/internal/repository/mysql/model" + + "gorm.io/gorm" +) + +type keywordMaterial struct { + Type int32 `json:"type" binding:"required"` // 素材类型(1:文本 2:图片) + Content string `json:"content" binding:"required"` // 素材内容 + IntervalSeconds int32 `json:"interval_seconds" binding:"required"` // 发送间隔时间(单位:秒) +} + +type createKeywordMaterialRequest struct { + MaterialList []keywordMaterial `json:"material_list" binding:"required"` // 素材列表 +} + +type createKeywordMaterialResponse struct { + Message string `json:"message"` // 提示信息 +} + +// CreateKeywordMaterial 配置意图关键字素材 +// @Summary 配置意图关键字素材 +// @Description 配置意图关键字素材 +// @Tags 管理端.意图关键字 +// @Accept json +// @Produce json +// @Param id path string true "编号ID" +// @Param RequestBody body createKeywordMaterialRequest true "请求参数" +// @Success 200 {object} createKeywordMaterialResponse +// @Failure 400 {object} code.Failure +// @Router /admin/app/keyword/material/{id} [post] +// @Security LoginVerifyToken +func (h *handler) CreateKeywordMaterial() core.HandlerFunc { + return func(ctx core.Context) { + req := new(createKeywordMaterialRequest) + res := new(createKeywordMaterialResponse) + if err := ctx.ShouldBindJSON(req); err != nil { + ctx.AbortWithError(core.Error( + http.StatusBadRequest, + code.ParamBindError, + validation.Error(err)), + ) + return + } + + ID, err := strconv.Atoi(ctx.Param("id")) + if err != nil { + ctx.AbortWithError(core.Error( + http.StatusBadRequest, + code.ParamBindError, + "未传递编号ID。"), + ) + return + } + + if len(req.MaterialList) == 0 { + ctx.AbortWithError(core.Error( + http.StatusBadRequest, + code.CreateKeywordMaterialError, + fmt.Sprintf("%s: 未配置素材", code.Text(code.CreateKeywordMaterialError))), + ) + return + } + + info, err := h.readDB.AppKeyword.WithContext(ctx.RequestContext()). + Where(h.readDB.AppKeyword.ID.Eq(int32(ID))). + First() + if err != nil && err != gorm.ErrRecordNotFound { + ctx.AbortWithError(core.Error( + http.StatusBadRequest, + code.CreateKeywordMaterialError, + fmt.Sprintf("%s: %s", code.Text(code.CreateKeywordMaterialError), err.Error())), + ) + return + } + + if info == nil { + ctx.AbortWithError(core.Error( + http.StatusBadRequest, + code.CreateKeywordMaterialError, + fmt.Sprintf("%s: 意图关键字编号(%d)不存在。", code.Text(code.CreateKeywordMaterialError), ID)), + ) + return + } + + // 先删除旧数据 + if _, err := h.writeDB.AppKeywordReply.WithContext(ctx.RequestContext()). + Where(h.writeDB.AppKeywordReply.KeywordID.Eq(int32(ID))). + Delete(); err != nil { + ctx.AbortWithError(core.Error( + http.StatusBadRequest, + code.CreateKeywordMaterialError, + fmt.Sprintf("%s: %s", code.Text(code.CreateKeywordMaterialError), err.Error())), + ) + return + } + + var keywordMaterials []*model.AppKeywordReply + for i := 0; i < len(req.MaterialList); i++ { + if req.MaterialList[i].Type == 0 || req.MaterialList[i].Content == "" || req.MaterialList[i].IntervalSeconds == 0 { + ctx.AbortWithError(core.Error( + http.StatusBadRequest, + code.CreateKeywordMaterialError, + fmt.Sprintf("%s: 配置素材数据不完整,请检查。", code.Text(code.CreateKeywordMaterialError))), + ) + return + } + + keywordMaterials = append(keywordMaterials, &model.AppKeywordReply{ + KeywordID: int32(ID), + AppID: info.AppID, + Type: req.MaterialList[i].Type, + Content: req.MaterialList[i].Content, + IntervalSeconds: req.MaterialList[i].IntervalSeconds, + CreatedUser: ctx.SessionUserInfo().UserName, + CreatedAt: time.Now(), + }) + } + + // 批量插入 + if err := h.writeDB.AppKeywordReply.WithContext(ctx.RequestContext()).CreateInBatches(keywordMaterials, len(req.MaterialList)); err != nil { + ctx.AbortWithError(core.Error( + http.StatusBadRequest, + code.CreateKeywordMaterialError, + fmt.Sprintf("%s: %s", code.Text(code.CreateKeywordMaterialError), err.Error())), + ) + return + } + + res.Message = "操作成功" + ctx.Payload(res) + } +} diff --git a/internal/api/keyword/keyword_material_list.go b/internal/api/keyword/keyword_material_list.go new file mode 100644 index 0000000..003d311 --- /dev/null +++ b/internal/api/keyword/keyword_material_list.go @@ -0,0 +1,130 @@ +package keyword + +import ( + "fmt" + "net/http" + + "mini-chat/internal/code" + "mini-chat/internal/pkg/core" + "mini-chat/internal/pkg/timeutil" + "mini-chat/internal/pkg/validation" + + "gorm.io/gorm" +) + +type keywordMaterialPageListRequest struct { + KeywordID int32 `form:"keyword_id" binding:"required"` // 意图关键字ID + Page int `form:"page"` // 当前页码,默认为第一页 + PageSize int `form:"page_size"` // 每页返回的数据量 +} + +type keywordMaterialListData struct { + ID int32 `json:"id"` // 主键ID + KeywordID int32 `json:"keyword_id"` // 意图关键字ID + Type int32 `json:"type"` // 素材类型(1:文本 2:图片) + Content string `json:"content"` // 素材内容 + IntervalSeconds int32 `json:"interval_seconds"` // 素材发送间隔时间(单位:秒) + CreatedUser string `json:"created_user"` // 创建人 + CreatedAt string `json:"created_at"` // 创建时间 +} + +type keywordMaterialPageListResponse struct { + Page int `json:"page"` // 当前页码 + PageSize int `json:"page_size"` // 每页返回的数据量 + Total int64 `json:"total"` // 符合查询条件的总记录数 + List []keywordMaterialListData `json:"list"` +} + +// KeywordMaterialPageList 获取意图关键字素材列表 +// @Summary 获取意图关键字素材列表 +// @Description 获取意图关键字素材列表 +// @Tags 管理端.意图关键字 +// @Accept json +// @Produce json +// @Param keyword_id query int true "意图关键字ID" +// @Param page query int true "当前页码" default(1) +// @Param page_size query int true "每页返回的数据量,最多 100 条" default(20) +// @Success 200 {object} keywordMaterialPageListResponse +// @Failure 400 {object} code.Failure +// @Router /admin/app/keyword/materials [get] +// @Security LoginVerifyToken +func (h *handler) KeywordMaterialPageList() core.HandlerFunc { + return func(ctx core.Context) { + req := new(keywordMaterialPageListRequest) + res := new(keywordMaterialPageListResponse) + if err := ctx.ShouldBindForm(req); err != nil { + ctx.AbortWithError(core.Error( + http.StatusBadRequest, + code.ParamBindError, + validation.Error(err)), + ) + return + } + + if req.Page == 0 { + req.Page = 1 + } + + if req.PageSize == 0 { + req.PageSize = 20 + } + + if req.PageSize > 100 { + ctx.AbortWithError(core.Error( + http.StatusBadRequest, + code.ListKeywordMaterialError, + fmt.Sprintf("%s: 一次最多只能查询 100 条", code.Text(code.ListKeywordMaterialError)), + )) + return + } + + query := h.readDB.AppKeywordReply.WithContext(ctx.RequestContext()) + query = query.Where(h.readDB.AppKeywordReply.KeywordID.Eq(req.KeywordID)) + + listQueryDB := query.Session(&gorm.Session{}) + countQueryDB := query.Session(&gorm.Session{}) + + resultData, err := listQueryDB. + Order(h.readDB.AppKeywordReply.ID.Asc()). + Limit(req.PageSize). + Offset((req.Page - 1) * req.PageSize). + Find() + if err != nil { + ctx.AbortWithError(core.Error( + http.StatusBadRequest, + code.ListKeywordMaterialError, + fmt.Sprintf("%s:%s", code.Text(code.ListKeywordMaterialError), err.Error())), + ) + return + } + + count, err := countQueryDB.Count() + if err != nil { + ctx.AbortWithError(core.Error( + http.StatusBadRequest, + code.ListKeywordMaterialError, + fmt.Sprintf("%s:%s", code.Text(code.ListKeywordMaterialError), err.Error())), + ) + return + } + + res.Page = req.Page + res.PageSize = req.PageSize + res.Total = count + res.List = make([]keywordMaterialListData, len(resultData)) + + for k, v := range resultData { + res.List[k] = keywordMaterialListData{ + ID: v.ID, + KeywordID: v.KeywordID, + Type: v.Type, + Content: v.Content, + IntervalSeconds: v.IntervalSeconds, + CreatedUser: v.CreatedUser, + CreatedAt: timeutil.FriendlyTime(v.CreatedAt), + } + } + + ctx.Payload(res) + } +} diff --git a/internal/api/keyword/keyword_material_modify.go b/internal/api/keyword/keyword_material_modify.go new file mode 100644 index 0000000..8e62261 --- /dev/null +++ b/internal/api/keyword/keyword_material_modify.go @@ -0,0 +1,103 @@ +package keyword + +import ( + "fmt" + "net/http" + "strconv" + "time" + + "mini-chat/internal/code" + "mini-chat/internal/pkg/core" + "mini-chat/internal/pkg/validation" + + "gorm.io/gorm" +) + +type modifyKeywordMaterialRequest struct { + Type int32 `json:"type" binding:"required"` // 素材类型(1:文本 2:图片) + Content string `json:"content" binding:"required"` // 素材内容 + IntervalSeconds int32 `json:"interval_seconds" binding:"required"` // 发送间隔时间(单位:秒) +} + +type modifyKeywordMaterialResponse struct { + Message string `json:"message"` // 提示信息 +} + +// ModifyKeywordMaterial 修改意图关键字素材 +// @Summary 修改意图关键字素材 +// @Description 修改意图关键字素材 +// @Tags 管理端.意图关键字 +// @Accept json +// @Produce json +// @Param id path string true "素材编号ID" +// @Param RequestBody body modifyKeywordMaterialRequest true "请求参数" +// @Success 200 {object} modifyKeywordMaterialResponse +// @Failure 400 {object} code.Failure +// @Router /admin/app/keyword/material/{id} [put] +// @Security LoginVerifyToken +func (h *handler) ModifyKeywordMaterial() core.HandlerFunc { + return func(ctx core.Context) { + req := new(modifyKeywordMaterialRequest) + res := new(modifyKeywordMaterialResponse) + if err := ctx.ShouldBindJSON(req); err != nil { + ctx.AbortWithError(core.Error( + http.StatusBadRequest, + code.ParamBindError, + validation.Error(err)), + ) + return + } + + ID, err := strconv.Atoi(ctx.Param("id")) + if err != nil { + ctx.AbortWithError(core.Error( + http.StatusBadRequest, + code.ParamBindError, + "未传递编号ID。"), + ) + return + } + + info, err := h.readDB.AppKeywordReply.WithContext(ctx.RequestContext()). + Where(h.readDB.AppKeywordReply.ID.Eq(int32(ID))). + First() + if err != nil && err != gorm.ErrRecordNotFound { + ctx.AbortWithError(core.Error( + http.StatusBadRequest, + code.ModifyKeywordMaterialError, + fmt.Sprintf("%s: %s", code.Text(code.ModifyKeywordMaterialError), err.Error())), + ) + return + } + + if info == nil { + ctx.AbortWithError(core.Error( + http.StatusBadRequest, + code.ModifyKeywordMaterialError, + fmt.Sprintf("%s: 意图关键字素材编号(%d)不存在。", code.Text(code.ModifyKeywordMaterialError), ID)), + ) + return + } + + updateData := map[string]interface{}{ + "type": req.Type, + "content": req.Content, + "interval_seconds": req.IntervalSeconds, + "updated_user": ctx.SessionUserInfo().UserName, + "updated_at": time.Now(), + } + + if _, err := h.writeDB.AppKeywordReply.WithContext(ctx.RequestContext()). + Where(h.writeDB.AppKeywordReply.ID.Eq(int32(ID))). + Updates(updateData); err != nil { + ctx.AbortWithError(core.Error( + http.StatusBadRequest, + code.ModifyKeywordMaterialError, + fmt.Sprintf("%s: %s", code.Text(code.ModifyKeywordMaterialError), err.Error())), + ) + } + + res.Message = "操作成功" + ctx.Payload(res) + } +} diff --git a/internal/code/code.go b/internal/code/code.go index e199ac3..1c281e8 100644 --- a/internal/code/code.go +++ b/internal/code/code.go @@ -27,10 +27,14 @@ const ( ListAppError = 20203 ModifyAppError = 20204 - CreateKeywordError = 20301 - ListKeywordError = 20302 - ModifyKeywordError = 20303 - DeleteKeywordError = 20304 + CreateKeywordError = 20301 + ListKeywordError = 20302 + ModifyKeywordError = 20303 + DeleteKeywordError = 20304 + CreateKeywordMaterialError = 20305 + ListKeywordMaterialError = 20306 + ModifyKeywordMaterialError = 20307 + DeleteKeywordMaterialError = 20308 ) func Text(code int) string { diff --git a/internal/code/zh-cn.go b/internal/code/zh-cn.go index 06675fe..425a461 100644 --- a/internal/code/zh-cn.go +++ b/internal/code/zh-cn.go @@ -13,8 +13,12 @@ var zhCNText = map[int]string{ ListAppError: "获取小程序列表失败", ModifyAppError: "修改小程序失败", - CreateKeywordError: "创建关键字失败", - DeleteKeywordError: "删除关键字失败", - ListKeywordError: "获取关键字列表失败", - ModifyKeywordError: "修改关键字失败", + CreateKeywordError: "创建关键字失败", + DeleteKeywordError: "删除关键字失败", + ListKeywordError: "获取关键字列表失败", + ModifyKeywordError: "修改关键字失败", + CreateKeywordMaterialError: "创建关键字素材失败", + DeleteKeywordMaterialError: "删除关键字素材失败", + ListKeywordMaterialError: "获取关键字素材列表失败", + ModifyKeywordMaterialError: "修改关键字素材失败", } diff --git a/internal/router/router.go b/internal/router/router.go index 5b289e1..911f872 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -65,10 +65,13 @@ func NewHTTPMux(logger logger.CustomLogger, db mysql.Repo, cron cron.Server) (co adminAuthApiRouter.PUT("/app/:id", appHandler.ModifyApp()) // 修改小程序 adminAuthApiRouter.GET("/apps", appHandler.PageList()) // 小程序列表 - adminAuthApiRouter.POST("/app/keyword", keywordHandler.CreateKeyword()) // 添加意图关键字 - adminAuthApiRouter.PUT("/app/keyword/:id", keywordHandler.ModifyKeyword()) // 修改意图关键字 - adminAuthApiRouter.DELETE("/app/keyword/:id", keywordHandler.DeleteKeyword()) // 删除意图关键字 - adminAuthApiRouter.GET("/app/keywords", keywordHandler.KeywordPageList()) // 获取意图关键字列表 + adminAuthApiRouter.POST("/app/keyword", keywordHandler.CreateKeyword()) // 添加意图关键字 + adminAuthApiRouter.PUT("/app/keyword/:id", keywordHandler.ModifyKeyword()) // 修改意图关键字 + adminAuthApiRouter.DELETE("/app/keyword/:id", keywordHandler.DeleteKeyword()) // 删除意图关键字 + adminAuthApiRouter.GET("/app/keywords", keywordHandler.KeywordPageList()) // 获取意图关键字列表 + adminAuthApiRouter.POST("/app/keyword/material/:id", keywordHandler.CreateKeywordMaterial()) // 配置意图关键字素材 + adminAuthApiRouter.PUT("/app/keyword/material/:id", keywordHandler.ModifyKeywordMaterial()) // 修改意图关键字素材 + adminAuthApiRouter.GET("/app/keyword/materials", keywordHandler.KeywordMaterialPageList()) // 获取意图关键字素材列表 } return mux, nil diff --git a/internal/services/material.go b/internal/services/material.go new file mode 100644 index 0000000..c29fe43 --- /dev/null +++ b/internal/services/material.go @@ -0,0 +1,9 @@ +package services + +type TextMessage struct { + Message string `json:"message"` +} + +type PictureMessage struct { + ImgURL string `json:"img_url"` +}