213 lines
6.0 KiB
Go
213 lines
6.0 KiB
Go
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
|
||
}
|