bindbox-game/internal/api/keyword/keyword_list.go
2025-10-21 10:30:53 +08:00

213 lines
6.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package keyword
import (
"fmt"
"net/http"
"strings"
"mini-chat/internal/code"
"mini-chat/internal/pkg/core"
"mini-chat/internal/pkg/timeutil"
"mini-chat/internal/pkg/validation"
"gorm.io/gorm"
)
type keywordPageListRequest struct {
AppID string `form:"app_id" binding:"required"` // 小程序ID
Keyword string `form:"keyword"` // 意图关键字
Page int `form:"page"` // 当前页码,默认为第一页
PageSize int `form:"page_size"` // 每页返回的数据量
}
type keywordListData struct {
ID int32 `json:"id"` // 关键字编号
AppID string `json:"app_id"` // 小程序ID
Keyword string `json:"keyword"` // 意图关键字
CreatedUser string `json:"created_user"` // 创建人
CreatedAt string `json:"created_at"` // 创建时间
UpdatedUser string `json:"updated_user"` // 更新人
UpdatedAt string `json:"updated_at"` // 更新时间
MaterialTypeCount string `json:"material_type_count"` // 素材类型数量
}
type keywordPageListResponse struct {
Page int `json:"page"` // 当前页码
PageSize int `json:"page_size"` // 每页返回的数据量
Total int64 `json:"total"` // 符合查询条件的总记录数
List []keywordListData `json:"list"`
}
// KeywordPageList 获取意图关键字列表
// @Summary 获取意图关键字列表
// @Description 获取意图关键字列表
// @Tags 管理端.意图关键字
// @Accept json
// @Produce json
// @Param app_id query int true "小程序ID"
// @Param keyword query string false "意图关键字"
// @Param page query int true "当前页码" default(1)
// @Param page_size query int true "每页返回的数据量,最多 100 条" default(20)
// @Success 200 {object} keywordPageListResponse
// @Failure 400 {object} code.Failure
// @Router /api/admin/app/keywords [get]
// @Security LoginVerifyToken
func (h *handler) KeywordPageList() core.HandlerFunc {
return func(ctx core.Context) {
req := new(keywordPageListRequest)
res := new(keywordPageListResponse)
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.ListKeywordError,
fmt.Sprintf("%s: 一次最多只能查询 100 条", code.Text(code.ListKeywordError)),
))
return
}
query := h.readDB.AppKeyword.WithContext(ctx.RequestContext())
query = query.Where(h.readDB.AppKeyword.AppID.Eq(req.AppID))
if req.Keyword != "" {
query = query.Where(h.readDB.AppKeyword.Keyword.Like(fmt.Sprintf("%%%s%%", req.Keyword)))
}
listQueryDB := query.Session(&gorm.Session{})
countQueryDB := query.Session(&gorm.Session{})
resultData, err := listQueryDB.
Order(h.readDB.AppKeyword.ID.Desc()).
Limit(req.PageSize).
Offset((req.Page - 1) * req.PageSize).
Find()
if err != nil {
ctx.AbortWithError(core.Error(
http.StatusBadRequest,
code.ListKeywordError,
fmt.Sprintf("%s%s", code.Text(code.ListKeywordError), err.Error())),
)
return
}
count, err := countQueryDB.Count()
if err != nil {
ctx.AbortWithError(core.Error(
http.StatusBadRequest,
code.ListKeywordError,
fmt.Sprintf("%s%s", code.Text(code.ListKeywordError), err.Error())),
)
return
}
res.Page = req.Page
res.PageSize = req.PageSize
res.Total = count
res.List = make([]keywordListData, len(resultData))
var keywordIDs []int32
for _, v := range resultData {
keywordIDs = append(keywordIDs, v.ID)
}
keywordIDMaterialTypeCountMap, err := h.contactMaterialTypeCount(keywordIDs)
if err != nil {
ctx.AbortWithError(core.Error(
http.StatusBadRequest,
code.ListKeywordError,
fmt.Sprintf("%s%s", code.Text(code.ListKeywordError), err.Error())),
)
return
}
for k, v := range resultData {
res.List[k] = keywordListData{
ID: v.ID,
AppID: v.AppID,
Keyword: v.Keyword,
CreatedUser: v.CreatedUser,
CreatedAt: timeutil.FriendlyTime(v.CreatedAt),
UpdatedUser: v.UpdatedUser,
UpdatedAt: timeutil.FriendlyTime(v.UpdatedAt),
MaterialTypeCount: keywordIDMaterialTypeCountMap[v.ID],
}
}
ctx.Payload(res)
}
}
func (h *handler) contactMaterialTypeCount(keywordIDs []int32) (map[int32]string, error) {
var results []struct {
KeywordID int32
Type int
Count int `db:"count"`
}
if err := h.readDB.AppKeywordReply.
Select(h.readDB.AppKeywordReply.KeywordID, h.readDB.AppKeywordReply.Type, h.readDB.AppKeywordReply.ID.Count().As("count")).
Where(h.readDB.AppKeywordReply.KeywordID.In(keywordIDs...)).
Group(h.readDB.AppKeywordReply.KeywordID, h.readDB.AppKeywordReply.Type).
Scan(&results); err != nil {
return nil, err
}
keywordIDMap := make(map[int32]string)
typeMap := map[int]string{
1: "文本",
2: "图片",
3: "语音条",
4: "视频",
5: "小程序",
6: "地理位置",
7: "链接",
8: "GIF图",
9: "名片",
10: "文件",
11: "转人工",
}
for _, result := range results {
keywordID := result.KeywordID
typeDesc := fmt.Sprintf("%d条%s", result.Count, typeMap[result.Type])
if currentString, exists := keywordIDMap[keywordID]; exists {
keywordIDMap[keywordID] = currentString + "、" + typeDesc + "、"
} else {
keywordIDMap[keywordID] = "1 组话术(共" + typeDesc
}
}
for keywordID, resultString := range keywordIDMap {
// 查找最后一个逗号的位置
commaIndex := strings.LastIndex(resultString, "、")
// 如果找到逗号,替换为右括号
if commaIndex != -1 {
keywordIDMap[keywordID] = resultString[:commaIndex] + ""
} else {
keywordIDMap[keywordID] += ""
}
}
return keywordIDMap, nil
}