You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

116 lines
3.9 KiB

package console
import (
"strings"
"yunyan/comm"
"yunyan/pb"
"github.com/gin-gonic/gin"
)
// userFeedbackListReq 用户反馈列表筛选。
//
// User 一栏多用:UID 精确,手机号 / 邮箱 / 用户名 / 登录账号模糊。
// 客服转来的线索形态不定,让人先选「按什么查」只是多一步。
// Content 只搜反馈正文。时间区间是 [start, end),结束日由前端按当天 24:00 换算。
type userFeedbackListReq struct {
User string `json:"user"`
Content string `json:"content"`
Start int64 `json:"start"`
End int64 `json:"end"`
Page int `json:"page"`
PageSize int `json:"page_size"`
}
// userFeedbackItem 列表行。用户字段来自提交时仍在库里的 user 行;
// 账号已注销删掉时这几列为空,uid 仍在。
type userFeedbackItem struct {
Id uint64 `json:"id" gorm:"column:id"`
Uid string `json:"uid" gorm:"column:uid"`
Message string `json:"message" gorm:"column:message"`
Version string `json:"version" gorm:"column:version"`
Phonemodel string `json:"phonemodel" gorm:"column:phonemodel"`
Channel int32 `json:"channel" gorm:"column:channel"`
Createtime int64 `json:"createtime" gorm:"column:createtime"`
Name string `json:"name" gorm:"column:name"`
Phone string `json:"phone" gorm:"column:phone"`
Mail string `json:"mail" gorm:"column:mail"`
Account string `json:"account" gorm:"column:account"`
}
// buildUserFeedbackWhere 拼筛选条件。表别名 f = userfeedback,u = user。
func buildUserFeedbackWhere(req *userFeedbackListReq) (string, []interface{}) {
conds := make([]string, 0, 4)
args := make([]interface{}, 0, 8)
if kw := strings.TrimSpace(req.User); kw != "" {
like := "%" + kw + "%"
conds = append(conds, "(f.uid = ? OR u.phone LIKE ? OR u.mail LIKE ? OR u.name LIKE ? OR u.account LIKE ?)")
args = append(args, kw, like, like, like, like)
}
if kw := strings.TrimSpace(req.Content); kw != "" {
conds = append(conds, "f.message LIKE ?")
args = append(args, "%"+kw+"%")
}
if req.Start > 0 {
conds = append(conds, "f.createtime >= ?")
args = append(args, req.Start)
}
if req.End > 0 {
conds = append(conds, "f.createtime < ?")
args = append(args, req.End)
}
if len(conds) == 0 {
return "1=1", args
}
return strings.Join(conds, " AND "), args
}
// getUserFeedbacks 所选应用业务库里的用户反馈,按提交时间倒序。
func (this *serverComp) getUserFeedbacks(c *gin.Context) {
appId := parseAppId(c.GetHeader("X-App-Id"))
if !this.requireAppScope(c, appId) {
return
}
conn, err := this.module.registry.getServiceDB(appId)
if err != nil {
writeErr(c, pb.ErrorCode_DBError, err.Error())
return
}
req := &userFeedbackListReq{}
_ = c.ShouldBindJSON(req)
if req.PageSize <= 0 {
req.PageSize = 20
}
if req.PageSize > userListPageMax {
req.PageSize = userListPageMax
}
if req.Page < 0 {
req.Page = 0
}
where, args := buildUserFeedbackWhere(req)
base := conn.Table(comm.TableUserFeedback+" AS f").
Joins("LEFT JOIN `"+comm.TableUser+"` AS u ON u.uid = f.uid").
Where(where, args...)
var total int64
if err := base.Count(&total).Error; err != nil {
writeErr(c, pb.ErrorCode_DBError, err.Error())
return
}
rows := make([]*userFeedbackItem, 0, req.PageSize)
if total > 0 {
// Count 已经用过这条链,再查要重新起一条,否则 Limit 会叠在已执行的语句上。
if err := conn.Table(comm.TableUserFeedback+" AS f").
Select("f.id, f.uid, f.message, f.version, f.phonemodel, f.channel, f.createtime, u.name, u.phone, u.mail, u.account").
Joins("LEFT JOIN `"+comm.TableUser+"` AS u ON u.uid = f.uid").
Where(where, args...).
Order("f.createtime DESC, f.id DESC").
Limit(req.PageSize).Offset(req.Page * req.PageSize).
Find(&rows).Error; err != nil {
writeErr(c, pb.ErrorCode_DBError, err.Error())
return
}
}
writeOK(c, gin.H{"items": rows, "total": total, "page": req.Page, "page_size": req.PageSize})
}