121 lines
3.1 KiB
Go
121 lines
3.1 KiB
Go
|
|
package admin_agent
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"fmt"
|
||
|
|
"time"
|
||
|
|
|
||
|
|
"jnc-server/app/main/api/internal/svc"
|
||
|
|
"jnc-server/app/main/api/internal/types"
|
||
|
|
"jnc-server/common/globalkey"
|
||
|
|
|
||
|
|
"github.com/zeromicro/go-zero/core/logx"
|
||
|
|
)
|
||
|
|
|
||
|
|
type AdminGetOrderTrendsLogic struct {
|
||
|
|
logx.Logger
|
||
|
|
ctx context.Context
|
||
|
|
svcCtx *svc.ServiceContext
|
||
|
|
}
|
||
|
|
|
||
|
|
func NewAdminGetOrderTrendsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AdminGetOrderTrendsLogic {
|
||
|
|
return &AdminGetOrderTrendsLogic{
|
||
|
|
Logger: logx.WithContext(ctx),
|
||
|
|
ctx: ctx,
|
||
|
|
svcCtx: svcCtx,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func (l *AdminGetOrderTrendsLogic) AdminGetOrderTrends(req *types.AdminGetOrderTrendsReq) (resp *types.AdminGetOrderTrendsResp, err error) {
|
||
|
|
// 1. Parse date parameters with default to last 30 days
|
||
|
|
var startDate, endDate time.Time
|
||
|
|
|
||
|
|
if req.StartDate != "" {
|
||
|
|
startDate, err = time.Parse("2006-01-02", req.StartDate)
|
||
|
|
if err != nil {
|
||
|
|
return nil, fmt.Errorf("invalid start_date format: %v", err)
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
// Default to 30 days ago
|
||
|
|
startDate = time.Now().AddDate(0, 0, -30)
|
||
|
|
}
|
||
|
|
|
||
|
|
if req.EndDate != "" {
|
||
|
|
endDate, err = time.Parse("2006-01-02", req.EndDate)
|
||
|
|
if err != nil {
|
||
|
|
return nil, fmt.Errorf("invalid end_date format: %v", err)
|
||
|
|
}
|
||
|
|
// Set end date to end of day
|
||
|
|
endDate = time.Date(endDate.Year(), endDate.Month(), endDate.Day(), 23, 59, 59, 0, time.Local)
|
||
|
|
} else {
|
||
|
|
// Default to today
|
||
|
|
endDate = time.Now()
|
||
|
|
}
|
||
|
|
|
||
|
|
// Ensure start date is before end date
|
||
|
|
if startDate.After(endDate) {
|
||
|
|
return nil, fmt.Errorf("start_date must be before end_date")
|
||
|
|
}
|
||
|
|
|
||
|
|
// 2. Query all commissions in date range
|
||
|
|
builder := l.svcCtx.AgentCommissionModel.SelectBuilder()
|
||
|
|
builder = builder.Where("del_state = ?", globalkey.DelStateNo)
|
||
|
|
builder = builder.Where("create_time >= ?", startDate)
|
||
|
|
builder = builder.Where("create_time <= ?", endDate)
|
||
|
|
|
||
|
|
commissions, err := l.svcCtx.AgentCommissionModel.FindAll(l.ctx, builder, "")
|
||
|
|
if err != nil {
|
||
|
|
return nil, fmt.Errorf("failed to query commissions: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
// 3. Group by date in Go
|
||
|
|
dateMap := make(map[string]*struct {
|
||
|
|
Amount float64
|
||
|
|
Count int64
|
||
|
|
})
|
||
|
|
|
||
|
|
for _, commission := range commissions {
|
||
|
|
date := commission.CreateTime.Format("2006-01-02")
|
||
|
|
if _, exists := dateMap[date]; !exists {
|
||
|
|
dateMap[date] = &struct {
|
||
|
|
Amount float64
|
||
|
|
Count int64
|
||
|
|
}{}
|
||
|
|
}
|
||
|
|
dateMap[date].Amount += commission.Amount
|
||
|
|
dateMap[date].Count++
|
||
|
|
}
|
||
|
|
|
||
|
|
// 4. Build sorted response
|
||
|
|
dates := make([]string, 0, len(dateMap))
|
||
|
|
amounts := make([]float64, 0, len(dateMap))
|
||
|
|
counts := make([]int64, 0, len(dateMap))
|
||
|
|
|
||
|
|
// Sort dates
|
||
|
|
sortedDates := make([]string, 0, len(dateMap))
|
||
|
|
for date := range dateMap {
|
||
|
|
sortedDates = append(sortedDates, date)
|
||
|
|
}
|
||
|
|
|
||
|
|
// Simple bubble sort (can be optimized with sort package)
|
||
|
|
for i := 0; i < len(sortedDates); i++ {
|
||
|
|
for j := i + 1; j < len(sortedDates); j++ {
|
||
|
|
if sortedDates[i] > sortedDates[j] {
|
||
|
|
sortedDates[i], sortedDates[j] = sortedDates[j], sortedDates[i]
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
for _, date := range sortedDates {
|
||
|
|
dates = append(dates, date)
|
||
|
|
amounts = append(amounts, dateMap[date].Amount)
|
||
|
|
counts = append(counts, dateMap[date].Count)
|
||
|
|
}
|
||
|
|
|
||
|
|
return &types.AdminGetOrderTrendsResp{
|
||
|
|
Dates: dates,
|
||
|
|
Amounts: amounts,
|
||
|
|
Counts: counts,
|
||
|
|
}, nil
|
||
|
|
}
|