227 lines
5.6 KiB
Go
227 lines
5.6 KiB
Go
package services
|
|
|
|
import (
|
|
"context"
|
|
|
|
"quyun/v2/app/requests"
|
|
"quyun/v2/database/models"
|
|
|
|
"github.com/pkg/errors"
|
|
"github.com/samber/lo"
|
|
"go.ipao.vip/gen"
|
|
)
|
|
|
|
// @provider
|
|
type users struct{}
|
|
|
|
// List returns a paginated list of users
|
|
func (m *users) List(
|
|
ctx context.Context,
|
|
pagination *requests.Pagination,
|
|
conds ...gen.Condition,
|
|
) (*requests.Pager, error) {
|
|
pagination.Format()
|
|
_, query := models.UserQuery.QueryContext(ctx)
|
|
|
|
items, cnt, err := query.Where(conds...).FindByPage(int(pagination.Offset()), int(pagination.Limit))
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "query users error")
|
|
}
|
|
|
|
return &requests.Pager{
|
|
Items: items,
|
|
Total: cnt,
|
|
Pagination: *pagination,
|
|
}, nil
|
|
}
|
|
|
|
// PostList returns a paginated list of posts for a user
|
|
func (m *users) PostList(
|
|
ctx context.Context,
|
|
userId int64,
|
|
pagination *requests.Pagination,
|
|
conds ...gen.Condition,
|
|
) (*requests.Pager, error) {
|
|
pagination.Format()
|
|
// stmt := SELECT(tbl.AllColumns).
|
|
// FROM(tbl.
|
|
// RIGHT_JOIN(
|
|
// tblUserPosts,
|
|
// tblUserPosts.PostID.EQ(tbl.ID),
|
|
// ),
|
|
// ).
|
|
// WHERE(CondTrue(cond...)).
|
|
// ORDER_BY(tblUserPosts.ID.DESC()).
|
|
// LIMIT(pagination.Limit).
|
|
// OFFSET(pagination.Offset)
|
|
// m.log().Infof("sql: %s", stmt.DebugSql())
|
|
|
|
// var posts []Posts
|
|
// err := stmt.QueryContext(ctx, db, &posts)
|
|
// if err != nil {
|
|
// if errors.Is(err, qrm.ErrNoRows) {
|
|
// return &requests.Pager{
|
|
// Items: nil,
|
|
// Total: 0,
|
|
// Pagination: *pagination,
|
|
// }, nil
|
|
// }
|
|
// m.log().Errorf("error querying posts: %v", err)
|
|
// return nil, err
|
|
// }
|
|
|
|
// // total count
|
|
// var cnt struct {
|
|
// Cnt int64
|
|
// }
|
|
|
|
// stmtCnt := tblUserPosts.SELECT(COUNT(tblUserPosts.ID).AS("cnt")).WHERE(tblUserPosts.UserID.EQ(Int64(userId)))
|
|
// m.log().Infof("sql: %s", stmtCnt.DebugSql())
|
|
|
|
// if err := stmtCnt.QueryContext(ctx, db, &cnt); err != nil {
|
|
// m.log().Errorf("error counting users: %v", err)
|
|
// return nil, err
|
|
// }
|
|
|
|
// return &requests.Pager{
|
|
// Items: posts,
|
|
// Total: cnt.Cnt,
|
|
// Pagination: *pagination,
|
|
// }, nil
|
|
return nil, nil
|
|
}
|
|
|
|
// GetUsersMapByIDs
|
|
func (m *users) GetUsersMapByIDs(ctx context.Context, ids []int64) (map[int64]*models.User, error) {
|
|
if len(ids) == 0 {
|
|
return nil, nil
|
|
}
|
|
|
|
tbl, query := models.UserQuery.QueryContext(ctx)
|
|
items, err := query.Where(tbl.ID.In(ids...)).Find()
|
|
if err != nil {
|
|
return nil, errors.Wrapf(err, "failed to get users by ids:%v", ids)
|
|
}
|
|
|
|
return lo.KeyBy(items, func(item *models.User) int64 {
|
|
return item.ID
|
|
}), nil
|
|
}
|
|
|
|
// BatchCheckHasBought checks if the user has bought the given post IDs
|
|
func (m *users) BatchCheckHasBought(ctx context.Context, userId int64, postIDs []int64) (map[int64]bool, error) {
|
|
tbl, query := models.UserPostQuery.QueryContext(ctx)
|
|
userPosts, err := query.
|
|
Where(
|
|
tbl.UserID.Eq(userId),
|
|
tbl.PostID.In(postIDs...),
|
|
).
|
|
Find()
|
|
if err != nil {
|
|
return nil, errors.Wrapf(err, "check user has bought failed, user_id: %d, post_ids: %+v", userId, postIDs)
|
|
}
|
|
|
|
result := make(map[int64]bool)
|
|
for _, postID := range postIDs {
|
|
result[postID] = false
|
|
}
|
|
|
|
for _, post := range userPosts {
|
|
result[post.PostID] = true
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
// HasBought
|
|
func (m *users) HasBought(ctx context.Context, userID, postID int64) (bool, error) {
|
|
tbl, query := models.UserPostQuery.QueryContext(ctx)
|
|
cnt, err := query.
|
|
Where(
|
|
tbl.UserID.Eq(userID),
|
|
tbl.PostID.Eq(postID),
|
|
).
|
|
Count()
|
|
if err != nil {
|
|
return false, errors.Wrap(err, "failed to check user bought")
|
|
}
|
|
return cnt > 0, nil
|
|
}
|
|
|
|
// SetUsername
|
|
func (m *users) SetUsername(ctx context.Context, userID int64, username string) error {
|
|
tbl, query := models.UserQuery.QueryContext(ctx)
|
|
_, err := query.
|
|
Where(
|
|
tbl.ID.Eq(userID),
|
|
).
|
|
Update(tbl.Username, username)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// BuyPosts
|
|
func (m *users) BuyPosts(ctx context.Context, userID, postID, price int64) error {
|
|
model := &models.UserPost{UserID: userID, PostID: postID, Price: price}
|
|
return model.Create(ctx)
|
|
}
|
|
|
|
// RevokePosts
|
|
func (m *users) RevokeUserPosts(ctx context.Context, userID, postID int64) error {
|
|
tbl, query := models.UserPostQuery.QueryContext(ctx)
|
|
_, err := query.Where(
|
|
tbl.UserID.Eq(userID),
|
|
tbl.PostID.Eq(postID),
|
|
).Delete()
|
|
return err
|
|
}
|
|
|
|
// FindByID
|
|
func (m *users) FindByID(ctx context.Context, userID int64) (*models.User, error) {
|
|
tbl, query := models.UserQuery.QueryContext(ctx)
|
|
user, err := query.Where(tbl.ID.Eq(userID)).First()
|
|
if err != nil {
|
|
return nil, errors.Wrapf(err, "find by id failed, id: %d", userID)
|
|
}
|
|
return user, nil
|
|
}
|
|
|
|
// SetBalance
|
|
func (m *users) SetBalance(ctx context.Context, userID, balance int64) error {
|
|
tbl, query := models.UserQuery.QueryContext(ctx)
|
|
_, err := query.Where(tbl.ID.Eq(userID)).Update(tbl.Balance, balance)
|
|
|
|
return err
|
|
}
|
|
|
|
// AddBalance adds the given amount to the user's balance
|
|
func (m *users) AddBalance(ctx context.Context, userID, amount int64) error {
|
|
tbl, query := models.UserQuery.QueryContext(ctx)
|
|
_, err := query.Where(tbl.ID.Eq(userID)).Inc(tbl.Balance, amount)
|
|
return err
|
|
}
|
|
|
|
// Desc desc the given amount to the user's balance
|
|
func (m *users) DescBalance(ctx context.Context, userID, amount int64) error {
|
|
user, err := m.FindByID(ctx, userID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if user.Balance < amount {
|
|
return errors.New("balance not enough")
|
|
}
|
|
tbl, query := models.UserQuery.QueryContext(ctx)
|
|
_, err = query.Where(tbl.ID.Eq(userID)).Inc(tbl.Balance, -amount)
|
|
return err
|
|
}
|
|
|
|
// Count
|
|
func (m *users) Count(ctx context.Context, conds ...gen.Condition) (int64, error) {
|
|
_, query := models.UserQuery.QueryContext(ctx)
|
|
if len(conds) > 0 {
|
|
query = query.Where(conds...)
|
|
}
|
|
return query.Count()
|
|
}
|