更新输入框边距规范,增加资源对接弹窗的布局修正,确保在小程序开发中避免文字贴边问题。补充相关口诀以提升开发一致性,并在经验清单中记录最新最佳实践。调整项目索引以反映最新进展,增强文档的可用性与可追溯性。

This commit is contained in:
Alex-larget
2026-03-03 11:12:56 +08:00
parent 8e2ea9b7c1
commit 3097d796e0
18 changed files with 220 additions and 94 deletions

View File

@@ -6,6 +6,7 @@ import (
"net/http"
"strconv"
"strings"
"sync"
"time"
"soul-api/internal/database"
@@ -13,6 +14,7 @@ import (
"soul-api/internal/wechat"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
// OrdersList GET /api/orders带用户昵称/头像/手机号,分销佣金按配置比例计算;支持分页 page、pageSize筛选 status搜索 search
@@ -29,50 +31,64 @@ func OrdersList(c *gin.Context) {
pageSize = 10
}
q := db.Model(&model.Order{})
if statusFilter != "" && statusFilter != "all" {
if statusFilter == "completed" {
q = q.Where("status IN ?", []string{"paid", "completed"})
} else {
q = q.Where("status = ?", statusFilter) // 含 refunded、pending、created、failed
// 预加载 referral_config避免订单循环内 N+1 查询
var refCfgRow model.SystemConfig
refCfg := (*model.SystemConfig)(nil)
if err := db.Where("config_key = ?", "referral_config").First(&refCfgRow).Error; err == nil {
refCfg = &refCfgRow
}
// 构建带筛选的查询count 与 list 共用条件)
applyOrdersFilter := func(q *gorm.DB) *gorm.DB {
if statusFilter != "" && statusFilter != "all" {
if statusFilter == "completed" {
q = q.Where("status IN ?", []string{"paid", "completed"})
} else {
q = q.Where("status = ?", statusFilter)
}
}
if search != "" {
pattern := "%" + search + "%"
q = q.Where("order_sn LIKE ? OR id LIKE ? OR user_id IN (SELECT id FROM users WHERE COALESCE(nickname,'') LIKE ? OR COALESCE(phone,'') LIKE ? OR id LIKE ?)",
pattern, pattern, pattern, pattern, pattern)
}
return q
}
if search != "" {
pattern := "%" + search + "%"
q = q.Where("order_sn LIKE ? OR id LIKE ? OR user_id IN (SELECT id FROM users WHERE COALESCE(nickname,'') LIKE ? OR COALESCE(phone,'') LIKE ? OR id LIKE ?)",
pattern, pattern, pattern, pattern, pattern)
}
var total int64
q.Count(&total)
var totalRevenue, todayRevenue float64
db.Model(&model.Order{}).Select("COALESCE(SUM(amount), 0)").
Where("status IN ?", []string{"paid", "completed"}).Scan(&totalRevenue)
todayStart := time.Now().Truncate(24 * time.Hour)
todayEnd := todayStart.Add(24 * time.Hour)
db.Model(&model.Order{}).Select("COALESCE(SUM(amount), 0)").
Where("status IN ? AND created_at >= ? AND created_at < ?", []string{"paid", "completed"}, todayStart, todayEnd).
Scan(&todayRevenue)
var orders []model.Order
query := db.Model(&model.Order{})
if statusFilter != "" && statusFilter != "all" {
if statusFilter == "completed" {
query = query.Where("status IN ?", []string{"paid", "completed"})
} else {
query = query.Where("status = ?", statusFilter)
}
}
if search != "" {
pattern := "%" + search + "%"
query = query.Where("order_sn LIKE ? OR id LIKE ? OR user_id IN (SELECT id FROM users WHERE COALESCE(nickname,'') LIKE ? OR COALESCE(phone,'') LIKE ? OR id LIKE ?)",
pattern, pattern, pattern, pattern, pattern)
}
if err := query.Order("created_at DESC").
Offset((page - 1) * pageSize).
Limit(pageSize).
Find(&orders).Error; err != nil {
c.JSON(http.StatusOK, gin.H{"success": false, "error": err.Error(), "orders": []interface{}{}, "total": 0})
var ordersErr error
var wg sync.WaitGroup
// 并行count、营收统计、订单列表
wg.Add(3)
go func() {
defer wg.Done()
applyOrdersFilter(db.Model(&model.Order{})).Count(&total)
}()
go func() {
defer wg.Done()
db.Model(&model.Order{}).Select("COALESCE(SUM(amount), 0)").
Where("status IN ?", []string{"paid", "completed"}).Scan(&totalRevenue)
todayStart := time.Now().Truncate(24 * time.Hour)
todayEnd := todayStart.Add(24 * time.Hour)
db.Model(&model.Order{}).Select("COALESCE(SUM(amount), 0)").
Where("status IN ? AND created_at >= ? AND created_at < ?", []string{"paid", "completed"}, todayStart, todayEnd).
Scan(&todayRevenue)
}()
go func() {
defer wg.Done()
query := applyOrdersFilter(db.Model(&model.Order{}))
ordersErr = query.Order("created_at DESC").
Offset((page - 1) * pageSize).
Limit(pageSize).
Find(&orders).Error
}()
wg.Wait()
if ordersErr != nil {
c.JSON(http.StatusOK, gin.H{"success": false, "error": ordersErr.Error(), "orders": []interface{}{}, "total": 0})
return
}
totalPages := int(total) / pageSize
@@ -147,7 +163,7 @@ func OrdersList(c *gin.Context) {
if u := userMap[*o.ReferrerID]; u != nil {
refUser = u
}
m["referrerEarnings"] = computeOrderCommission(db, &o, refUser)
m["referrerEarnings"] = computeOrderCommission(db, &o, refUser, refCfg)
} else {
m["referrerEarnings"] = nil
}