229 lines
9.2 KiB
Go
229 lines
9.2 KiB
Go
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
|
|
}
|