167 lines
4.5 KiB
Go
167 lines
4.5 KiB
Go
package vip
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"chatapp3-golang/internal/model"
|
|
)
|
|
|
|
// PageOrders returns VIP purchase records for the admin page.
|
|
func (s *Service) PageOrders(
|
|
ctx context.Context,
|
|
sysOrigin string,
|
|
userID int64,
|
|
status string,
|
|
orderType string,
|
|
cursor int,
|
|
limit int,
|
|
) (*OrderPageResponse, error) {
|
|
sysOrigin = normalizeSysOrigin(sysOrigin)
|
|
if sysOrigin == "" {
|
|
return nil, NewAppError(http.StatusBadRequest, "bad_request", "sysOrigin is required")
|
|
}
|
|
page, size := normalizePage(cursor, limit)
|
|
|
|
query := s.db.WithContext(ctx).Model(&model.VipOrderRecord{}).Where("sys_origin = ?", sysOrigin)
|
|
if userID > 0 {
|
|
query = query.Where("user_id = ?", userID)
|
|
}
|
|
if normalizedStatus := strings.ToUpper(strings.TrimSpace(status)); normalizedStatus != "" {
|
|
query = query.Where("status = ?", normalizedStatus)
|
|
}
|
|
if normalizedType := strings.ToUpper(strings.TrimSpace(orderType)); normalizedType != "" {
|
|
query = query.Where("order_type = ?", normalizedType)
|
|
}
|
|
|
|
var total int64
|
|
if err := query.Count(&total).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
records := make([]VipOrderPayload, 0)
|
|
if total > 0 {
|
|
var rows []model.VipOrderRecord
|
|
if err := query.
|
|
Order("create_time desc").
|
|
Order("id desc").
|
|
Offset((page - 1) * size).
|
|
Limit(size).
|
|
Find(&rows).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
records = make([]VipOrderPayload, 0, len(rows))
|
|
for _, row := range rows {
|
|
records = append(records, orderPayloadFromModel(row))
|
|
}
|
|
}
|
|
|
|
return &OrderPageResponse{Records: records, Total: total}, nil
|
|
}
|
|
|
|
// PageUserStates returns the current VIP state rows for the admin page.
|
|
func (s *Service) PageUserStates(
|
|
ctx context.Context,
|
|
sysOrigin string,
|
|
userID int64,
|
|
status string,
|
|
cursor int,
|
|
limit int,
|
|
) (*UserStatePageResponse, error) {
|
|
sysOrigin = normalizeSysOrigin(sysOrigin)
|
|
if sysOrigin == "" {
|
|
return nil, NewAppError(http.StatusBadRequest, "bad_request", "sysOrigin is required")
|
|
}
|
|
now := time.Now()
|
|
if err := s.expireDueStates(ctx, sysOrigin, now); err != nil {
|
|
return nil, err
|
|
}
|
|
page, size := normalizePage(cursor, limit)
|
|
|
|
query := s.db.WithContext(ctx).Model(&model.UserVipState{}).Where("sys_origin = ?", sysOrigin)
|
|
if userID > 0 {
|
|
query = query.Where("user_id = ?", userID)
|
|
}
|
|
if normalizedStatus := strings.ToUpper(strings.TrimSpace(status)); normalizedStatus != "" {
|
|
query = query.Where("status = ?", normalizedStatus)
|
|
}
|
|
|
|
var total int64
|
|
if err := query.Count(&total).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
records := make([]UserVipStatePayload, 0)
|
|
if total > 0 {
|
|
var rows []model.UserVipState
|
|
if err := query.
|
|
Order("update_time desc").
|
|
Order("id desc").
|
|
Offset((page - 1) * size).
|
|
Limit(size).
|
|
Find(&rows).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
records = make([]UserVipStatePayload, 0, len(rows))
|
|
for idx := range rows {
|
|
records = append(records, statePayloadFromModel(&rows[idx], now))
|
|
}
|
|
}
|
|
|
|
return &UserStatePageResponse{Records: records, Total: total}, nil
|
|
}
|
|
|
|
// PageUserOrders returns the current user's VIP order records.
|
|
func (s *Service) PageUserOrders(ctx context.Context, user AuthUser, cursor int, limit int) (*OrderPageResponse, error) {
|
|
sysOrigin, err := normalizeUser(user)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return s.PageOrders(ctx, sysOrigin, user.UserID, "", "", cursor, limit)
|
|
}
|
|
|
|
func (s *Service) expireDueStates(ctx context.Context, sysOrigin string, now time.Time) error {
|
|
updates := map[string]any{
|
|
"level": 0,
|
|
"level_code": "",
|
|
"display_name": "",
|
|
"status": statusExpired,
|
|
"badge_resource_id": 0,
|
|
"badge_name": "",
|
|
"badge_url": "",
|
|
"avatar_frame_resource_id": 0,
|
|
"avatar_frame_name": "",
|
|
"avatar_frame_url": "",
|
|
"entry_effect_resource_id": 0,
|
|
"entry_effect_name": "",
|
|
"entry_effect_url": "",
|
|
"chat_bubble_resource_id": 0,
|
|
"chat_bubble_name": "",
|
|
"chat_bubble_url": "",
|
|
"float_picture_resource_id": 0,
|
|
"float_picture_name": "",
|
|
"float_picture_url": "",
|
|
"update_time": now,
|
|
}
|
|
return s.db.WithContext(ctx).
|
|
Model(&model.UserVipState{}).
|
|
Where("sys_origin = ? AND status = ? AND expire_at <= ?", sysOrigin, statusActive, now).
|
|
Updates(updates).Error
|
|
}
|
|
|
|
// ParseUserID parses optional userId filters from query strings.
|
|
func ParseUserID(raw string) int64 {
|
|
value := strings.TrimSpace(raw)
|
|
if value == "" {
|
|
return 0
|
|
}
|
|
parsed, err := strconv.ParseInt(value, 10, 64)
|
|
if err != nil {
|
|
return 0
|
|
}
|
|
return parsed
|
|
}
|