各种配置项修复,优化到后台管理端配置
Build docker and publish / build (20.15.1) (push) Has been cancelled

This commit is contained in:
2026-03-04 17:58:40 -08:00
parent 149dfe1ac3
commit 4752f844ef
31 changed files with 1467 additions and 148 deletions
+58 -8
View File
@@ -2,6 +2,8 @@ package user
import (
"context"
"fmt"
"strings"
"time"
"gorm.io/gorm"
@@ -16,17 +18,19 @@ func (m *customUserModel) FindActiveSubscribesByUserIds(ctx context.Context, use
type Result struct {
UserId int64
Name string
Quantity int64
UpdatedAt *time.Time
}
var results []Result
// Query latest active subscription for each user
err := m.QueryNoCacheCtx(ctx, &results, func(conn *gorm.DB, v interface{}) error {
return conn.Table("user_subscribe").
Select("user_subscribe.user_id, subscribe.name, user_subscribe.updated_at").
Joins("LEFT JOIN subscribe ON user_subscribe.subscribe_id = subscribe.id").
Where("user_subscribe.user_id IN ? AND user_subscribe.status IN (0, 1) AND user_subscribe.expire_time > ?", userIds, time.Now()).
Order("user_subscribe.created_at ASC"). // Ascending so we can overwrite in map to get the latest
return conn.Table("user_subscribe us").
Select("us.user_id, subscribe.name, COALESCE(o.quantity, 1) AS quantity, us.updated_at").
Joins("LEFT JOIN subscribe ON us.subscribe_id = subscribe.id").
Joins("LEFT JOIN `order` o ON o.id = (SELECT MAX(o2.id) FROM `order` o2 WHERE o2.user_id = us.user_id AND o2.subscribe_id = us.subscribe_id AND o2.status IN (2, 5))").
Where("us.user_id IN ? AND us.status IN (0, 1) AND us.expire_time > ?", userIds, time.Now()).
Order("us.created_at ASC, us.id ASC"). // Ascending so we can overwrite in map to get the latest
Scan(v).Error
})
@@ -35,11 +39,57 @@ func (m *customUserModel) FindActiveSubscribesByUserIds(ctx context.Context, use
}
userMap := make(map[int64]*UserStatusInfo)
packageTotals := make(map[int64]map[string]int64)
packageOrder := make(map[int64][]string)
for _, r := range results {
userMap[r.UserId] = &UserStatusInfo{
MemberStatus: r.Name,
LastTrafficAt: r.UpdatedAt,
name := strings.TrimSpace(r.Name)
if name == "" {
name = "Unknown"
}
quantity := r.Quantity
if quantity <= 0 {
quantity = 1
}
if _, ok := packageTotals[r.UserId]; !ok {
packageTotals[r.UserId] = make(map[string]int64)
}
if _, exists := packageTotals[r.UserId][name]; !exists {
packageOrder[r.UserId] = append(packageOrder[r.UserId], name)
}
packageTotals[r.UserId][name] += quantity
info, ok := userMap[r.UserId]
if !ok {
info = &UserStatusInfo{}
userMap[r.UserId] = info
}
info.MemberStatus = formatPackageDisplay(name, quantity)
if r.UpdatedAt != nil && (info.LastTrafficAt == nil || r.UpdatedAt.After(*info.LastTrafficAt)) {
info.LastTrafficAt = r.UpdatedAt
}
}
for userID, info := range userMap {
orderedNames := packageOrder[userID]
if len(orderedNames) == 0 {
continue
}
parts := make([]string, 0, len(orderedNames))
for _, name := range orderedNames {
parts = append(parts, formatPackageDisplay(name, packageTotals[userID][name]))
}
info.PurchasedPackage = strings.Join(parts, ", ")
}
return userMap, nil
}
func formatPackageDisplay(name string, quantity int64) string {
if quantity <= 1 {
return name
}
return fmt.Sprintf("%s*%d", name, quantity)
}