package admin_dashboard import ( "context" "time" "ycc-server/common/globalkey" "ycc-server/common/xerr" "github.com/pkg/errors" "ycc-server/app/main/api/internal/svc" "ycc-server/app/main/api/internal/types" "github.com/zeromicro/go-zero/core/logx" ) type AdminGetDashboardStatisticsLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext } func NewAdminGetDashboardStatisticsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AdminGetDashboardStatisticsLogic { return &AdminGetDashboardStatisticsLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, } } func (l *AdminGetDashboardStatisticsLogic) AdminGetDashboardStatistics() (resp *types.AdminGetDashboardStatisticsResp, err error) { // 使用Asia/Shanghai时区 loc, _ := time.LoadLocation("Asia/Shanghai") now := time.Now().In(loc) // 计算时间范围 todayStart := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, loc) todayEnd := todayStart.AddDate(0, 0, 1) yesterdayStart := todayStart.AddDate(0, 0, -1) yesterdayEnd := todayStart monthStart := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, loc) monthEnd := monthStart.AddDate(0, 1, 0) // 1. 订单统计 orderStats, err := l.calculateOrderStatistics(todayStart, todayEnd, yesterdayStart, yesterdayEnd, monthStart, monthEnd) if err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "计算订单统计失败, %v", err) } // 2. 营收统计 revenueStats, err := l.calculateRevenueStatistics(todayStart, todayEnd, yesterdayStart, yesterdayEnd, monthStart, monthEnd) if err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "计算营收统计失败, %v", err) } // 3. 代理统计 agentStats, err := l.calculateAgentStatistics(todayStart, monthStart) if err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "计算代理统计失败, %v", err) } // 4. 利润统计 profitStats, err := l.calculateProfitStatistics(todayStart, todayEnd, monthStart, monthEnd, revenueStats) if err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "计算利润统计失败, %v", err) } // 5. 订单趋势(最近7天) orderTrend, err := l.calculateOrderTrend(now, loc) if err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "计算订单趋势失败, %v", err) } // 6. 营收趋势(最近7天) revenueTrend, err := l.calculateRevenueTrend(now, loc) if err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "计算营收趋势失败, %v", err) } return &types.AdminGetDashboardStatisticsResp{ OrderStats: orderStats, RevenueStats: revenueStats, AgentStats: agentStats, ProfitStats: profitStats, OrderTrend: orderTrend, RevenueTrend: revenueTrend, }, nil } // calculateOrderStatistics 计算订单统计 func (l *AdminGetDashboardStatisticsLogic) calculateOrderStatistics(todayStart, todayEnd, yesterdayStart, yesterdayEnd, monthStart, monthEnd time.Time) (types.AdminOrderStatistics, error) { var stats types.AdminOrderStatistics // 今日订单数 todayBuilder := l.svcCtx.OrderModel.SelectBuilder(). Where("status = ? AND create_time >= ? AND create_time < ?", "paid", todayStart, todayEnd) todayCount, err := l.svcCtx.OrderModel.FindCount(l.ctx, todayBuilder, "id") if err != nil { return stats, err } stats.TodayCount = todayCount // 昨日订单数 yesterdayBuilder := l.svcCtx.OrderModel.SelectBuilder(). Where("status = ? AND create_time >= ? AND create_time < ?", "paid", yesterdayStart, yesterdayEnd) yesterdayCount, err := l.svcCtx.OrderModel.FindCount(l.ctx, yesterdayBuilder, "id") if err != nil { return stats, err } stats.YesterdayCount = yesterdayCount // 当月订单数 monthBuilder := l.svcCtx.OrderModel.SelectBuilder(). Where("status = ? AND create_time >= ? AND create_time < ?", "paid", monthStart, monthEnd) monthCount, err := l.svcCtx.OrderModel.FindCount(l.ctx, monthBuilder, "id") if err != nil { return stats, err } stats.MonthCount = monthCount // 总订单数 totalBuilder := l.svcCtx.OrderModel.SelectBuilder(). Where("status = ?", "paid") totalCount, err := l.svcCtx.OrderModel.FindCount(l.ctx, totalBuilder, "id") if err != nil { return stats, err } stats.TotalCount = totalCount // 计算变化率 if stats.YesterdayCount > 0 { stats.ChangeRate = float64(stats.TodayCount-stats.YesterdayCount) / float64(stats.YesterdayCount) * 100 } else if stats.TodayCount > 0 { stats.ChangeRate = 100 // 从0增长到有值,算100%增长 } return stats, nil } // calculateRevenueStatistics 计算营收统计 func (l *AdminGetDashboardStatisticsLogic) calculateRevenueStatistics(todayStart, todayEnd, yesterdayStart, yesterdayEnd, monthStart, monthEnd time.Time) (types.AdminRevenueStatistics, error) { var stats types.AdminRevenueStatistics // 今日营收 todayBuilder := l.svcCtx.OrderModel.SelectBuilder(). Where("status = ? AND create_time >= ? AND create_time < ?", "paid", todayStart, todayEnd) todayAmount, err := l.svcCtx.OrderModel.FindSum(l.ctx, todayBuilder, "amount") if err != nil { return stats, err } stats.TodayAmount = todayAmount // 昨日营收 yesterdayBuilder := l.svcCtx.OrderModel.SelectBuilder(). Where("status = ? AND create_time >= ? AND create_time < ?", "paid", yesterdayStart, yesterdayEnd) yesterdayAmount, err := l.svcCtx.OrderModel.FindSum(l.ctx, yesterdayBuilder, "amount") if err != nil { return stats, err } stats.YesterdayAmount = yesterdayAmount // 当月营收 monthBuilder := l.svcCtx.OrderModel.SelectBuilder(). Where("status = ? AND create_time >= ? AND create_time < ?", "paid", monthStart, monthEnd) monthAmount, err := l.svcCtx.OrderModel.FindSum(l.ctx, monthBuilder, "amount") if err != nil { return stats, err } stats.MonthAmount = monthAmount // 总营收 totalBuilder := l.svcCtx.OrderModel.SelectBuilder(). Where("status = ?", "paid") totalAmount, err := l.svcCtx.OrderModel.FindSum(l.ctx, totalBuilder, "amount") if err != nil { return stats, err } stats.TotalAmount = totalAmount // 计算变化率 if stats.YesterdayAmount > 0 { stats.ChangeRate = (stats.TodayAmount - stats.YesterdayAmount) / stats.YesterdayAmount * 100 } else if stats.TodayAmount > 0 { stats.ChangeRate = 100 // 从0增长到有值,算100%增长 } return stats, nil } // calculateAgentStatistics 计算代理统计 func (l *AdminGetDashboardStatisticsLogic) calculateAgentStatistics(todayStart, monthStart time.Time) (types.AdminAgentStatistics, error) { var stats types.AdminAgentStatistics // 代理总数 totalBuilder := l.svcCtx.AgentModel.SelectBuilder() totalCount, err := l.svcCtx.AgentModel.FindCount(l.ctx, totalBuilder, "id") if err != nil { return stats, err } stats.TotalCount = totalCount // 今日新增 todayBuilder := l.svcCtx.AgentModel.SelectBuilder(). Where("create_time >= ?", todayStart) todayNew, err := l.svcCtx.AgentModel.FindCount(l.ctx, todayBuilder, "id") if err != nil { return stats, err } stats.TodayNew = todayNew // 当月新增 monthBuilder := l.svcCtx.AgentModel.SelectBuilder(). Where("create_time >= ?", monthStart) monthNew, err := l.svcCtx.AgentModel.FindCount(l.ctx, monthBuilder, "id") if err != nil { return stats, err } stats.MonthNew = monthNew return stats, nil } // calculateProfitStatistics 计算利润统计 func (l *AdminGetDashboardStatisticsLogic) calculateProfitStatistics(todayStart, todayEnd, monthStart, monthEnd time.Time, revenueStats types.AdminRevenueStatistics) (types.AdminProfitStatistics, error) { var stats types.AdminProfitStatistics // 公司交税比例(6%) const companyTaxRate = 0.06 // 今日利润计算 // 今日营收 todayRevenue := revenueStats.TodayAmount // 今日佣金 todayCommissionBuilder := l.svcCtx.AgentCommissionModel.SelectBuilder(). Where("del_state = ? AND status != ? AND create_time >= ? AND create_time < ?", globalkey.DelStateNo, 3, todayStart, todayEnd) todayCommission, err := l.svcCtx.AgentCommissionModel.FindSum(l.ctx, todayCommissionBuilder, "amount") if err != nil { return stats, err } // 今日返利 todayRebateBuilder := l.svcCtx.AgentRebateModel.SelectBuilder(). Where("del_state = ? AND status != ? AND create_time >= ? AND create_time < ?", globalkey.DelStateNo, 3, todayStart, todayEnd) todayRebate, err := l.svcCtx.AgentRebateModel.FindSum(l.ctx, todayRebateBuilder, "rebate_amount") if err != nil { return stats, err } // 今日公司交税(订单金额的6%) todayCompanyTax := todayRevenue * companyTaxRate // 今日平台收入税(agent_withdrawal_tax表中tax_status=2的tax_amount总和) todayTaxIncomeBuilder := l.svcCtx.AgentWithdrawalTaxModel.SelectBuilder(). Where("del_state = ? AND tax_status = ? AND create_time >= ? AND create_time < ?", globalkey.DelStateNo, 2, todayStart, todayEnd) todayTaxIncome, err := l.svcCtx.AgentWithdrawalTaxModel.FindSum(l.ctx, todayTaxIncomeBuilder, "tax_amount") if err != nil { return stats, err } // 今日利润 = 营收 - 佣金 - 返利 - 公司交税 + 平台收入税 stats.TodayProfit = todayRevenue - todayCommission - todayRebate - todayCompanyTax + todayTaxIncome if todayRevenue > 0 { stats.TodayProfitRate = stats.TodayProfit / todayRevenue * 100 } // 当月利润计算 // 当月营收 monthRevenue := revenueStats.MonthAmount // 当月佣金 monthCommissionBuilder := l.svcCtx.AgentCommissionModel.SelectBuilder(). Where("del_state = ? AND status != ? AND create_time >= ? AND create_time < ?", globalkey.DelStateNo, 3, monthStart, monthEnd) monthCommission, err := l.svcCtx.AgentCommissionModel.FindSum(l.ctx, monthCommissionBuilder, "amount") if err != nil { return stats, err } // 当月返利 monthRebateBuilder := l.svcCtx.AgentRebateModel.SelectBuilder(). Where("del_state = ? AND status != ? AND create_time >= ? AND create_time < ?", globalkey.DelStateNo, 3, monthStart, monthEnd) monthRebate, err := l.svcCtx.AgentRebateModel.FindSum(l.ctx, monthRebateBuilder, "rebate_amount") if err != nil { return stats, err } // 当月公司交税 monthCompanyTax := monthRevenue * companyTaxRate // 当月平台收入税 monthTaxIncomeBuilder := l.svcCtx.AgentWithdrawalTaxModel.SelectBuilder(). Where("del_state = ? AND tax_status = ? AND create_time >= ? AND create_time < ?", globalkey.DelStateNo, 2, monthStart, monthEnd) monthTaxIncome, err := l.svcCtx.AgentWithdrawalTaxModel.FindSum(l.ctx, monthTaxIncomeBuilder, "tax_amount") if err != nil { return stats, err } // 当月利润 stats.MonthProfit = monthRevenue - monthCommission - monthRebate - monthCompanyTax + monthTaxIncome if monthRevenue > 0 { stats.MonthProfitRate = stats.MonthProfit / monthRevenue * 100 } // 总利润计算 // 总营收 totalRevenue := revenueStats.TotalAmount // 总佣金 totalCommissionBuilder := l.svcCtx.AgentCommissionModel.SelectBuilder(). Where("del_state = ? AND status != ?", globalkey.DelStateNo, 3) totalCommission, err := l.svcCtx.AgentCommissionModel.FindSum(l.ctx, totalCommissionBuilder, "amount") if err != nil { return stats, err } // 总返利 totalRebateBuilder := l.svcCtx.AgentRebateModel.SelectBuilder(). Where("del_state = ? AND status != ?", globalkey.DelStateNo, 3) totalRebate, err := l.svcCtx.AgentRebateModel.FindSum(l.ctx, totalRebateBuilder, "rebate_amount") if err != nil { return stats, err } // 总公司交税 totalCompanyTax := totalRevenue * companyTaxRate // 总平台收入税 totalTaxIncomeBuilder := l.svcCtx.AgentWithdrawalTaxModel.SelectBuilder(). Where("del_state = ? AND tax_status = ?", globalkey.DelStateNo, 2) totalTaxIncome, err := l.svcCtx.AgentWithdrawalTaxModel.FindSum(l.ctx, totalTaxIncomeBuilder, "tax_amount") if err != nil { return stats, err } // 总利润 stats.TotalProfit = totalRevenue - totalCommission - totalRebate - totalCompanyTax + totalTaxIncome if totalRevenue > 0 { stats.TotalProfitRate = stats.TotalProfit / totalRevenue * 100 } return stats, nil } // calculateOrderTrend 计算订单趋势(最近7天) func (l *AdminGetDashboardStatisticsLogic) calculateOrderTrend(now time.Time, loc *time.Location) ([]types.AdminTrendData, error) { var trend []types.AdminTrendData // 计算最近7天的日期 for i := 6; i >= 0; i-- { date := now.AddDate(0, 0, -i) dateStart := time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, loc) dateEnd := dateStart.AddDate(0, 0, 1) // 查询当天的订单数 builder := l.svcCtx.OrderModel.SelectBuilder(). Where("status = ? AND create_time >= ? AND create_time < ?", "paid", dateStart, dateEnd) count, err := l.svcCtx.OrderModel.FindCount(l.ctx, builder, "id") if err != nil { return nil, err } trend = append(trend, types.AdminTrendData{ Date: date.Format("01-02"), Value: float64(count), }) } return trend, nil } // calculateRevenueTrend 计算营收趋势(最近7天) func (l *AdminGetDashboardStatisticsLogic) calculateRevenueTrend(now time.Time, loc *time.Location) ([]types.AdminTrendData, error) { var trend []types.AdminTrendData // 计算最近7天的日期 for i := 6; i >= 0; i-- { date := now.AddDate(0, 0, -i) dateStart := time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, loc) dateEnd := dateStart.AddDate(0, 0, 1) // 查询当天的营收 builder := l.svcCtx.OrderModel.SelectBuilder(). Where("status = ? AND create_time >= ? AND create_time < ?", "paid", dateStart, dateEnd) amount, err := l.svcCtx.OrderModel.FindSum(l.ctx, builder, "amount") if err != nil { return nil, err } trend = append(trend, types.AdminTrendData{ Date: date.Format("01-02"), Value: amount, }) } return trend, nil }