feat: 添加仅已购用户筛选功能

This commit is contained in:
2025-12-20 23:30:51 +08:00
parent 257c9a286a
commit 661a595fa7
4 changed files with 67 additions and 8 deletions

View File

@@ -4,5 +4,7 @@ import "quyun/v2/app/requests"
type UserListQuery struct {
*requests.Pagination
Keyword *string `query:"keyword"`
Keyword *string `query:"keyword"` // 关键词(模糊匹配手机号/用户名;若为数字且>0则同时按用户 ID 精确匹配)
OnlyBought *bool `query:"onlyBought"` // 是否仅返回“购买数量>0”的用户true=仅已购用户false/空=全部用户)
}

View File

@@ -50,16 +50,57 @@ func (m *users) List(
query = query.Order(tbl.ID.Desc())
keyword := ""
if filter.Keyword != nil && *filter.Keyword != "" {
keyword = strings.TrimSpace(*filter.Keyword)
query = query.
Where(tbl.Phone.Like(database.WrapLike(*filter.Keyword))).
Or(tbl.Username.Like(database.WrapLike(*filter.Keyword)))
Where(tbl.Phone.Like(database.WrapLike(keyword))).
Or(tbl.Username.Like(database.WrapLike(keyword)))
if id, err := strconv.ParseInt(strings.TrimSpace(*filter.Keyword), 10, 64); err == nil && id > 0 {
if id, err := strconv.ParseInt(keyword, 10, 64); err == nil && id > 0 {
query = query.Or(tbl.ID.Eq(id))
}
}
if filter.OnlyBought != nil && *filter.OnlyBought {
// 仅返回“购买数量>0”的用户通过 JOIN user_posts 做存在性过滤。
// 注意FindByPage 内部用 Count(),在 GROUP BY 场景下可能不准确,这里改为手动 Count(DISTINCT users.id)。
tblUserPost, _ := models.UserPostQuery.QueryContext(ctx)
query = query.Join(tblUserPost, tbl.ID.EqCol(tblUserPost.UserID)).Group(tbl.ID)
offset := int(filter.Pagination.Offset())
limit := int(filter.Pagination.Limit)
items, err := query.Offset(offset).Limit(limit).Find()
if err != nil {
return nil, errors.Wrap(err, "query users error")
}
db := _db.WithContext(ctx).Model(&models.User{}).
Joins("JOIN user_posts ON user_posts.user_id = users.id")
if keyword != "" {
like := database.WrapLike(keyword)
args := []any{like, like}
where := "(users.phone LIKE ? OR users.username LIKE ?)"
if id, err := strconv.ParseInt(keyword, 10, 64); err == nil && id > 0 {
where = "(users.phone LIKE ? OR users.username LIKE ? OR users.id = ?)"
args = append(args, id)
}
db = db.Where(where, args...)
}
var cnt int64
if err := db.Distinct("users.id").Count(&cnt).Error; err != nil {
return nil, errors.Wrap(err, "count users error")
}
return &requests.Pager{
Items: items,
Total: cnt,
Pagination: *filter.Pagination,
}, nil
}
items, cnt, err := query.FindByPage(int(filter.Pagination.Offset()), int(filter.Pagination.Limit))
if err != nil {
return nil, errors.Wrap(err, "query users error")