2026-02-25 11:52:11 +08:00
package handler
import (
"encoding/json"
"net/http"
2026-02-25 16:26:13 +08:00
"strconv"
"strings"
"time"
2026-02-25 11:52:11 +08:00
"soul-api/internal/database"
"soul-api/internal/model"
"github.com/gin-gonic/gin"
)
2026-02-25 16:26:13 +08:00
// OrdersList GET /api/orders( 带用户昵称/头像/手机号,分销佣金按配置比例计算;支持分页 page、pageSize, 筛选 status, 搜索 search)
2026-02-25 11:52:11 +08:00
func OrdersList ( c * gin . Context ) {
db := database . DB ( )
2026-02-25 16:26:13 +08:00
page , _ := strconv . Atoi ( c . DefaultQuery ( "page" , "1" ) )
pageSize , _ := strconv . Atoi ( c . DefaultQuery ( "pageSize" , "10" ) )
statusFilter := c . Query ( "status" )
search := strings . TrimSpace ( c . Query ( "search" ) )
if page < 1 {
page = 1
}
if pageSize < 1 || pageSize > 100 {
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 )
}
}
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 )
2026-02-25 11:52:11 +08:00
var orders [ ] model . Order
2026-02-25 16:26:13 +08:00
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 } )
2026-02-25 11:52:11 +08:00
return
}
2026-02-25 16:26:13 +08:00
totalPages := int ( total ) / pageSize
if int ( total ) % pageSize > 0 {
totalPages ++
}
2026-02-25 11:52:11 +08:00
if len ( orders ) == 0 {
2026-02-25 16:26:13 +08:00
c . JSON ( http . StatusOK , gin . H {
"success" : true , "orders" : [ ] interface { } { } ,
"total" : total , "page" : page , "pageSize" : pageSize , "totalPages" : totalPages ,
} )
2026-02-25 11:52:11 +08:00
return
}
// 分销比例(与支付回调一致)
distributorShare := 0.9
var cfg model . SystemConfig
if err := db . Where ( "config_key = ?" , "referral_config" ) . First ( & cfg ) . Error ; err == nil {
var config map [ string ] interface { }
if _ = json . Unmarshal ( cfg . ConfigValue , & config ) ; config [ "distributorShare" ] != nil {
if share , ok := config [ "distributorShare" ] . ( float64 ) ; ok {
distributorShare = share / 100
}
}
}
// 收集订单中的 user_id、referrer_id, 查用户信息
userIDs := make ( map [ string ] bool )
for _ , o := range orders {
if o . UserID != "" {
userIDs [ o . UserID ] = true
}
if o . ReferrerID != nil && * o . ReferrerID != "" {
userIDs [ * o . ReferrerID ] = true
}
}
ids := make ( [ ] string , 0 , len ( userIDs ) )
for id := range userIDs {
ids = append ( ids , id )
}
var users [ ] model . User
if len ( ids ) > 0 {
db . Where ( "id IN ?" , ids ) . Find ( & users )
}
userMap := make ( map [ string ] * model . User )
for i := range users {
userMap [ users [ i ] . ID ] = & users [ i ]
}
getStr := func ( s * string ) string {
if s == nil || * s == "" {
return ""
}
return * s
}
out := make ( [ ] gin . H , 0 , len ( orders ) )
for _ , o := range orders {
// 序列化订单为基础字段
b , _ := json . Marshal ( o )
var m map [ string ] interface { }
_ = json . Unmarshal ( b , & m )
// 用户信息
if u := userMap [ o . UserID ] ; u != nil {
m [ "userNickname" ] = getStr ( u . Nickname )
m [ "userPhone" ] = getStr ( u . Phone )
m [ "userAvatar" ] = getStr ( u . Avatar )
} else {
m [ "userNickname" ] = ""
m [ "userPhone" ] = ""
m [ "userAvatar" ] = ""
}
// 推荐人信息
if o . ReferrerID != nil && * o . ReferrerID != "" {
if u := userMap [ * o . ReferrerID ] ; u != nil {
m [ "referrerNickname" ] = getStr ( u . Nickname )
m [ "referrerCode" ] = getStr ( u . ReferralCode )
}
}
// 分销佣金:仅对已支付且存在推荐人的订单,按配置比例计算(与支付回调口径一致)
status := getStr ( o . Status )
if status == "paid" && o . ReferrerID != nil && * o . ReferrerID != "" {
m [ "referrerEarnings" ] = o . Amount * distributorShare
} else {
m [ "referrerEarnings" ] = nil
}
out = append ( out , m )
}
2026-02-25 16:26:13 +08:00
c . JSON ( http . StatusOK , gin . H {
"success" : true , "orders" : out ,
"total" : total , "page" : page , "pageSize" : pageSize , "totalPages" : totalPages ,
"totalRevenue" : totalRevenue , "todayRevenue" : todayRevenue ,
} )
}
// MiniprogramOrders GET /api/miniprogram/orders 小程序-当前用户订单列表(按 userId 过滤,返回 data)
func MiniprogramOrders ( c * gin . Context ) {
userID := c . Query ( "userId" )
if userID == "" {
c . JSON ( http . StatusOK , gin . H { "success" : true , "data" : [ ] interface { } { } } )
return
}
db := database . DB ( )
var orders [ ] model . Order
if err := db . Where ( "user_id = ?" , userID ) . Order ( "created_at DESC" ) . Find ( & orders ) . Error ; err != nil {
c . JSON ( http . StatusOK , gin . H { "success" : true , "data" : [ ] interface { } { } } )
return
}
out := make ( [ ] gin . H , 0 , len ( orders ) )
for _ , o := range orders {
desc := ""
if o . Description != nil {
desc = * o . Description
}
productID := ""
if o . ProductID != nil {
productID = * o . ProductID
}
status := "created"
if o . Status != nil {
status = * o . Status
}
out = append ( out , gin . H {
"id" : o . ID , "order_sn" : o . OrderSN , "user_id" : o . UserID ,
"product_id" : productID , "product_type" : o . ProductType ,
"product_name" : desc , "section_id" : productID ,
"amount" : o . Amount , "status" : status ,
"created_at" : o . CreatedAt ,
} )
}
c . JSON ( http . StatusOK , gin . H { "success" : true , "data" : out } )
2026-02-25 11:52:11 +08:00
}