package service import ( "gorm.io/gorm" "psi/database" "psi/models" systemReq "psi/models/request" systemRes "psi/models/response" "psi/utils" "time" ) type StatistService struct{} // DashboardStatist 获取仪表盘统计数据 func (s *StatistService) DashboardStatist(req systemReq.DashboardStatistRequest, db ...*gorm.DB) (*systemRes.DashboardStatistResponse, error) { databaseConn := database.OptionalDB(db...) // 计算今日的时间范围(如果未指定) now := time.Now() startOfDay := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()).Unix() endOfDay := time.Date(now.Year(), now.Month(), now.Day(), 23, 59, 59, 0, now.Location()).Unix() if req.StartDate == 0 { req.StartDate = startOfDay } if req.EndDate == 0 { req.EndDate = endOfDay } // 查询今日销售订单总数 var totalSaleCount int64 saleOrderQuery := databaseConn.Model(&models.SalesOrder{}). Where("created_at >= ? AND created_at <= ? AND is_del = ?", req.StartDate, req.EndDate, 0) saleOrderQuery.Count(&totalSaleCount) // 从 statist 表查询总入库和出库次数 var totalReceivingCount, totalOutboundCount int64 statistQuery := databaseConn.Model(&models.Statist{}). Where("stat_date >= ? AND stat_date <= ? AND is_del = ?", req.StartDate, req.EndDate, 0) var statistList []models.Statist if err := statistQuery.Find(&statistList).Error; err != nil { return nil, utils.NewError("查询统计数据失败") } if len(statistList) == 0 { return &systemRes.DashboardStatistResponse{ TotalReceivingCount: 0, TotalOutboundCount: 0, TotalSaleCount: totalSaleCount, UserStats: []systemRes.UserStatItem{}, }, nil } for _, stat := range statistList { totalReceivingCount += stat.ReceivingNum totalOutboundCount += stat.OutboundNum } // 查询个人统计数据 var userStats []systemRes.UserStatItem // 按用户分组统计 type UserStatGroup struct { CreateBy int64 `gorm:"column:create_by"` TotalReceiving int64 `gorm:"column:total_receiving"` TotalOutbound int64 `gorm:"column:total_outbound"` } var userStatGroups []UserStatGroup databaseConn.Model(&models.Statist{}). Select("create_by, SUM(receiving_num) as total_receiving, SUM(outbound_num) as total_outbound"). Where("stat_date >= ? AND stat_date <= ? AND is_del = ?", req.StartDate, req.EndDate, 0). Group("create_by"). Scan(&userStatGroups) // 获取用户信息并构建返回数据 for _, group := range userStatGroups { var employee models.Employee if err := database.DB.Where("id = ?", group.CreateBy).First(&employee).Error; err == nil { userStats = append(userStats, systemRes.UserStatItem{ UserID: employee.ID, UserName: employee.Username, ReceivingCount: group.TotalReceiving, OutboundCount: group.TotalOutbound, }) } } return &systemRes.DashboardStatistResponse{ TotalReceivingCount: totalReceivingCount, TotalOutboundCount: totalOutboundCount, TotalSaleCount: totalSaleCount, UserStats: userStats, }, nil } // GetWarehouseStatist 获取仓库统计数据 func (s *StatistService) GetWarehouseStatist(req systemReq.WarehouseStatistRequest, db ...*gorm.DB) (*systemRes.WarehouseStatistResponse, error) { databaseConn := database.OptionalDB(db...) now := time.Now() startOfDay := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()).Unix() endOfDay := time.Date(now.Year(), now.Month(), now.Day(), 23, 59, 59, 0, now.Location()).Unix() yesterdayStart := time.Date(now.Year(), now.Month(), now.Day()-1, 0, 0, 0, 0, now.Location()).Unix() yesterdayEnd := time.Date(now.Year(), now.Month(), now.Day()-1, 23, 59, 59, 0, now.Location()).Unix() if req.StartDate == 0 { req.StartDate = startOfDay } if req.EndDate == 0 { req.EndDate = endOfDay } type WarehouseStat struct { ProductTotal int64 `gorm:"column:product_total"` InventoryTotal int64 `gorm:"column:inventory_total"` } var warehouseStat WarehouseStat databaseConn.Table("(?) as p", databaseConn.Model(&models.Product{}).Where("is_del = ?", 0).Select("COUNT(*) as product_total")). Select(` p.product_total, COALESCE((SELECT SUM(quantity) FROM inventory WHERE is_del = ?), 0) as inventory_total `, 0). Scan(&warehouseStat) type DailyStat struct { TodayInbound int64 `gorm:"column:today_inbound"` TodayOutbound int64 `gorm:"column:today_outbound"` YesterdayInbound int64 `gorm:"column:yesterday_inbound"` YesterdayOutbound int64 `gorm:"column:yesterday_outbound"` } var dailyStat DailyStat databaseConn.Model(&models.Statist{}). Select(` COALESCE(SUM(CASE WHEN stat_date >= ? AND stat_date <= ? THEN receiving_num ELSE 0 END), 0) as today_inbound, COALESCE(SUM(CASE WHEN stat_date >= ? AND stat_date <= ? THEN outbound_num ELSE 0 END), 0) as today_outbound, COALESCE(SUM(CASE WHEN stat_date >= ? AND stat_date <= ? THEN receiving_num ELSE 0 END), 0) as yesterday_inbound, COALESCE(SUM(CASE WHEN stat_date >= ? AND stat_date <= ? THEN outbound_num ELSE 0 END), 0) as yesterday_outbound `, req.StartDate, req.EndDate, req.StartDate, req.EndDate, yesterdayStart, yesterdayEnd, yesterdayStart, yesterdayEnd). Where("is_del = ?", 0). Scan(&dailyStat) return &systemRes.WarehouseStatistResponse{ ProductTotal: warehouseStat.ProductTotal, InventoryTotal: warehouseStat.InventoryTotal, TodayInbound: dailyStat.TodayInbound, TodayOutbound: dailyStat.TodayOutbound, YesterdayInbound: dailyStat.YesterdayInbound, YesterdayOutbound: dailyStat.YesterdayOutbound, }, nil } // GetOrderStatist 获取订单统计数据 func (s *StatistService) GetOrderStatist(req systemReq.OrderStatistRequest, db ...*gorm.DB) (*systemRes.OrderStatistResponse, error) { databaseConn := database.OptionalDB(db...) now := time.Now() startOfDay := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()).Unix() endOfDay := time.Date(now.Year(), now.Month(), now.Day(), 23, 59, 59, 0, now.Location()).Unix() yesterdayStart := time.Date(now.Year(), now.Month(), now.Day()-1, 0, 0, 0, 0, now.Location()).Unix() yesterdayEnd := time.Date(now.Year(), now.Month(), now.Day()-1, 23, 59, 59, 0, now.Location()).Unix() if req.StartDate == 0 { req.StartDate = startOfDay } if req.EndDate == 0 { req.EndDate = endOfDay } const ( StatusDraft = 1 StatusConfirmed = 2 StatusShipped = 5 StatusCancelled = 6 ) type OrderDailyStat struct { TodayQuantity int64 `gorm:"column:today_quantity"` TodayAmount int64 `gorm:"column:today_amount"` TodayShipped int64 `gorm:"column:today_shipped"` TodayUnshipped int64 `gorm:"column:today_unshipped"` TodayPending int64 `gorm:"column:today_pending"` YesterdayQuantity int64 `gorm:"column:yesterday_quantity"` YesterdayAmount int64 `gorm:"column:yesterday_amount"` YesterdayShipped int64 `gorm:"column:yesterday_shipped"` YesterdayUnshipped int64 `gorm:"column:yesterday_unshipped"` YesterdayPending int64 `gorm:"column:yesterday_pending"` } var orderStat OrderDailyStat databaseConn.Model(&models.SalesOrder{}). Select(` COALESCE(SUM(CASE WHEN created_at >= ? AND created_at <= ? THEN 1 ELSE 0 END), 0) as today_quantity, COALESCE(SUM(CASE WHEN created_at >= ? AND created_at <= ? THEN total_amount ELSE 0 END), 0) as today_amount, COALESCE(SUM(CASE WHEN created_at >= ? AND created_at <= ? AND status = ? THEN 1 ELSE 0 END), 0) as today_shipped, COALESCE(SUM(CASE WHEN created_at >= ? AND created_at <= ? AND status NOT IN (?, ?) THEN 1 ELSE 0 END), 0) as today_unshipped, COALESCE(SUM(CASE WHEN created_at >= ? AND created_at <= ? AND status IN (?, ?) THEN 1 ELSE 0 END), 0) as today_pending, COALESCE(SUM(CASE WHEN created_at >= ? AND created_at <= ? THEN 1 ELSE 0 END), 0) as yesterday_quantity, COALESCE(SUM(CASE WHEN created_at >= ? AND created_at <= ? THEN total_amount ELSE 0 END), 0) as yesterday_amount, COALESCE(SUM(CASE WHEN created_at >= ? AND created_at <= ? AND status = ? THEN 1 ELSE 0 END), 0) as yesterday_shipped, COALESCE(SUM(CASE WHEN created_at >= ? AND created_at <= ? AND status NOT IN (?, ?) THEN 1 ELSE 0 END), 0) as yesterday_unshipped, COALESCE(SUM(CASE WHEN created_at >= ? AND created_at <= ? AND status IN (?, ?) THEN 1 ELSE 0 END), 0) as yesterday_pending `, req.StartDate, req.EndDate, req.StartDate, req.EndDate, req.StartDate, req.EndDate, StatusShipped, req.StartDate, req.EndDate, StatusShipped, StatusCancelled, req.StartDate, req.EndDate, StatusDraft, StatusConfirmed, yesterdayStart, yesterdayEnd, yesterdayStart, yesterdayEnd, yesterdayStart, yesterdayEnd, StatusShipped, yesterdayStart, yesterdayEnd, StatusShipped, StatusCancelled, yesterdayStart, yesterdayEnd, StatusDraft, StatusConfirmed). Where("is_del = ?", 0). Scan(&orderStat) return &systemRes.OrderStatistResponse{ Today: systemRes.OrderStatItem{ Quantity: orderStat.TodayQuantity, Amount: orderStat.TodayAmount, Shipped: orderStat.TodayShipped, Unshipped: orderStat.TodayUnshipped, Pending: orderStat.TodayPending, }, Yesterday: systemRes.OrderStatItem{ Quantity: orderStat.YesterdayQuantity, Amount: orderStat.YesterdayAmount, Shipped: orderStat.YesterdayShipped, Unshipped: orderStat.YesterdayUnshipped, Pending: orderStat.YesterdayPending, }, }, nil }