销售单列表 详情 库存汇总 变动记录 销售金额

This commit is contained in:
97694731 2026-06-29 17:45:44 +08:00
parent b02fe84356
commit 3cb9221a95
9 changed files with 70 additions and 18 deletions

View File

@ -6,6 +6,7 @@ type GetInventoryListRequest struct {
PageSize int `form:"page_size"` // 分页大小
ProductId int64 `form:"product_id"` // 商品ID
WarehouseID int64 `form:"warehouse_id"` // 仓库ID
LocationID int64 `form:"location_id"` // 库位ID
ISBN string `form:"isbn"` // ISBN
Name string `form:"name"` // 商品名称
}
@ -16,6 +17,7 @@ type GetInventoryGroupedListRequest struct {
PageSize int `form:"page_size"` // 分页大小
ProductId int64 `form:"product_id"` // 商品ID
WarehouseID int64 `form:"warehouse_id"` // 仓库ID
LocationID int64 `form:"location_id"` // 库位ID
}
// GetInventoryDetailRequest 获取库存明细请求
@ -30,6 +32,7 @@ type GetInventoryLogListRequest struct {
ISBN string `form:"isbn"` // ISBN
BookName string `form:"book_name"` // 图书名称
WarehouseID int64 `form:"warehouse_id"` // 仓库ID
LocationID int64 `form:"location_id"` // 库位ID
ChangeType int8 `form:"change_type"` // 库存流水类型
RelatedOrderNo string `form:"related_order_no"` // 关联订单号
StartDate int64 `form:"start_date"` // 开始时间

View File

@ -8,6 +8,7 @@ type GetSalesOrderListRequest struct {
Status int8 `form:"status"`
CustomerID int64 `form:"customer_id"`
WarehouseID int64 `form:"warehouse_id"`
LocationID int64 `form:"location_id"`
StartDate int64 `form:"start_date"`
EndDate int64 `form:"end_date"`
AssociationOrderNo string `form:"association_order_no"`
@ -22,18 +23,13 @@ type GetSalesOrderDetailRequest struct {
// GetSalesOrderDetailListRequest 获取销售订单详情列表请求
type GetSalesOrderDetailListRequest struct {
Page int `form:"page"`
PageSize int `form:"page_size"`
//SoNo string `form:"so_no"`
//Status int8 `form:"status"`
//CustomerID int64 `form:"customer_id"`
//WarehouseID int64 `form:"warehouse_id"`
//StartDate int64 `form:"start_date"`
//EndDate int64 `form:"end_date"`
Page int `form:"page"`
PageSize int `form:"page_size"`
SoNo string `form:"so_no"`
Status int8 `form:"status"`
CustomerID int64 `form:"customer_id"`
WarehouseID int64 `form:"warehouse_id"`
LocationID int64 `form:"location_id"`
StartDate int64 `form:"start_date"`
EndDate int64 `form:"end_date"`
AssociationOrderNo string `form:"association_order_no"`

View File

@ -52,6 +52,7 @@ type SalesOrderItem struct {
SalesPersonID int64 `json:"sales_person_id"`
Remark string `json:"remark"`
LogisticsNo string `json:"logistics_no"`
LocationCode string `json:"location_code"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
}
@ -107,7 +108,7 @@ type SalesOrderDetailItem struct {
}
// ConvertSalesOrderToItem 将销售订单模型转换为响应项
func ConvertSalesOrderToItem(order models.SalesOrder, customerName string, warehouseName string, logisticsNo string) SalesOrderItem {
func ConvertSalesOrderToItem(order models.SalesOrder, customerName string, warehouseName string, logisticsNo string, locationCode string) SalesOrderItem {
return SalesOrderItem{
ID: order.ID,
SoNo: order.SoNo,
@ -129,6 +130,7 @@ func ConvertSalesOrderToItem(order models.SalesOrder, customerName string, wareh
SalesPersonID: order.SalesPersonID,
Remark: order.Remark,
LogisticsNo: logisticsNo,
LocationCode: locationCode,
CreatedAt: order.CreatedAt,
UpdatedAt: order.UpdatedAt,
}

View File

@ -5,11 +5,13 @@ type DashboardStatistResponse struct {
TotalOrderCount int64 `json:"total_order_count"` // 今日订单数
TotalReceivingCount int64 `json:"total_receiving_count"` // 今日入库数
TotalOutboundCount int64 `json:"total_outbound_count"` // 今日出库数
TotalSaleCount int64 `json:"total_sale_count"` // 今日销售数
TotalSaleCount int64 `json:"total_sale_count"` // 今日销售数(保留兼容)
TodaySaleAmount int64 `json:"today_sale_amount"` // 今日销售金额(分)
YesterdayOrderCount int64 `json:"yesterday_order_count"` // 昨日订单数
YesterdayReceivingCount int64 `json:"yesterday_receiving_count"` // 昨日入库数
YesterdayOutboundCount int64 `json:"yesterday_outbound_count"` // 昨日出库数
YesterdaySaleCount int64 `json:"yesterday_sale_count"` // 昨日销售数
YesterdaySaleCount int64 `json:"yesterday_sale_count"` // 昨日销售数(保留兼容)
YesterdaySaleAmount int64 `json:"yesterday_sale_amount"` // 昨日销售金额(分)
UserStats []UserStatItem `json:"user_stats"` // 个人统计数据
ProductTotal int64 `json:"product_total"` // 商品总量
InventoryTotal int64 `json:"inventory_total"` // 库存量

View File

@ -4,7 +4,7 @@ package response
type StoreInfoResponse struct {
StoreName string `json:"store_name"` // 店铺名称
StoreType string `json:"store_type"` // 店铺类型描述
SaleCount int64 `json:"sale_count"` // 销售数量(时间范围内该店铺的销售订单数
SaleAmount int64 `json:"sale_amount"` // 销售金额(时间范围内该店铺的销售订单总金额,单位:分
OutboundCount int64 `json:"outbound_count"` // 出库次数(当前表结构无店铺维度,暂返回 0
ReceivingCount int64 `json:"receiving_count"` // 入库次数(当前表结构无店铺维度,暂返回 0
OrderCount int64 `json:"order_count"` // 订单数量(同 sale_count从 sales_order 表统计)

View File

@ -51,6 +51,9 @@ func (s *InventoryService) GetInventoryList(req systemReq.GetInventoryListReques
if req.WarehouseID > 0 {
query = query.Where("inventory.warehouse_id = ?", req.WarehouseID)
}
if req.LocationID > 0 {
query = query.Where("i.location_id = ?", req.LocationID)
}
if req.ISBN != "" {
query = query.Where("p.barcode LIKE ?", "%"+req.ISBN+"%")
}
@ -148,6 +151,9 @@ func (s *InventoryService) GetInventoryGroupedList(req systemReq.GetInventoryGro
if req.WarehouseID > 0 {
groupQuery = groupQuery.Where("inventory_detail.warehouse_id = ?", req.WarehouseID)
}
if req.LocationID > 0 {
groupQuery = groupQuery.Where("inventory_detail.location_id = ?", req.LocationID)
}
var total int64
if err := groupQuery.Count(&total).Error; err != nil {
@ -459,6 +465,9 @@ func (s *InventoryService) GetInventoryLogList(req systemReq.GetInventoryLogList
if req.WarehouseID > 0 {
query = query.Where("inventory_log.warehouse_id = ?", req.WarehouseID)
}
if req.LocationID > 0 {
query = query.Where("inventory_log.location_id = ?", req.LocationID)
}
if req.ChangeType > 0 {
query = query.Where("inventory_log.change_type = ?", req.ChangeType)
}

View File

@ -60,6 +60,14 @@ func (s *SalesService) GetSalesOrderList(req systemReq.GetSalesOrderListRequest,
if req.ShopType > 0 {
query = query.Where("sales_order.shop_type = ?", req.ShopType)
}
if req.LocationID > 0 {
subQuery := databaseConn.Table("sales_order_item soi").
Select("DISTINCT soi.sales_order_id").
Joins("JOIN product p ON soi.product_id = p.id AND p.is_del = 0").
Joins("JOIN inventory_detail id ON p.id = id.product_id AND id.is_del = 0").
Where("id.location_id = ?", req.LocationID)
query = query.Where("sales_order.id IN (?)", subQuery)
}
var total int64
if err := query.Count(&total).Error; err != nil {
@ -109,6 +117,26 @@ func (s *SalesService) GetSalesOrderList(req systemReq.GetSalesOrderListRequest,
logByOrderID[row.SalesOrderID] = row.LogisticsNos
}
// 收集库位编码(通过 sales_order_item → product → inventory_detail → location 链路)
type locRow struct {
SalesOrderID int64 `gorm:"column:sales_order_id"`
LocationCodes string `gorm:"column:location_codes"`
}
var locRows []locRow
databaseConn.Table("sales_order_item").
Select("sales_order_id, COALESCE(GROUP_CONCAT(DISTINCT l.code SEPARATOR ', '), '') as location_codes").
Joins("JOIN product p ON sales_order_item.product_id = p.id AND p.is_del = 0").
Joins("JOIN inventory_detail id ON p.id = id.product_id AND id.is_del = 0").
Joins("JOIN location l ON id.location_id = l.id").
Where("sales_order_id IN ? AND sales_order_item.is_del = ?", orderIDs, 0).
Group("sales_order_id").
Scan(&locRows)
locByOrderID := make(map[int64]string, len(locRows))
for _, row := range locRows {
locByOrderID[row.SalesOrderID] = row.LocationCodes
}
orderItems := make([]systemRes.SalesOrderItem, 0, len(orders))
for _, order := range orders {
orderItems = append(orderItems, systemRes.ConvertSalesOrderToItem(
@ -116,6 +144,7 @@ func (s *SalesService) GetSalesOrderList(req systemReq.GetSalesOrderListRequest,
order.CustomerName,
order.WarehouseName,
logByOrderID[order.ID],
locByOrderID[order.ID],
))
}
@ -190,6 +219,14 @@ func (s *SalesService) GetSalesOrderDetailList(req systemReq.GetSalesOrderDetail
if req.ShopType > 0 {
query = query.Where("sales_order.shop_type = ?", req.ShopType)
}
if req.LocationID > 0 {
subQuery := databaseConn.Table("sales_order_item soi").
Select("DISTINCT soi.sales_order_id").
Joins("JOIN product p ON soi.product_id = p.id AND p.is_del = 0").
Joins("JOIN inventory_detail id ON p.id = id.product_id AND id.is_del = 0").
Where("id.location_id = ?", req.LocationID)
query = query.Where("sales_order.id IN (?)", subQuery)
}
var total int64
if err := query.Count(&total).Error; err != nil {

View File

@ -223,8 +223,8 @@ func (s *StatistService) getDashboardStatRealtime(databaseConn *gorm.DB, startDa
defer wg.Done()
statErr = databaseConn.Model(&models.SalesOrder{}).
Select(`
COALESCE(SUM(CASE WHEN created_at >= ? AND created_at <= ? THEN 1 ELSE 0 END), 0) as today_count,
COALESCE(SUM(CASE WHEN created_at >= ? AND created_at <= ? THEN 1 ELSE 0 END), 0) as yesterday_count
COALESCE(SUM(CASE WHEN created_at >= ? AND created_at <= ? THEN total_amount ELSE 0 END), 0) as today_count,
COALESCE(SUM(CASE WHEN created_at >= ? AND created_at <= ? THEN total_amount ELSE 0 END), 0) as yesterday_count
`, todayStart, todayEnd, yesterdayStart, yesterdayEnd).
Where("is_del = ?", 0).
Scan(&salesStat).Error
@ -338,11 +338,11 @@ func (s *StatistService) getDashboardStatRealtime(databaseConn *gorm.DB, startDa
TotalOrderCount: salesStat.TodayCount,
TotalReceivingCount: receivingStat.TodayCount,
TotalOutboundCount: outboundStat.TodayCount,
TotalSaleCount: salesStat.TodayCount,
TodaySaleAmount: salesStat.TodayCount,
YesterdayOrderCount: salesStat.YesterdayCount,
YesterdayReceivingCount: receivingStat.YesterdayCount,
YesterdayOutboundCount: outboundStat.YesterdayCount,
YesterdaySaleCount: salesStat.YesterdayCount,
YesterdaySaleAmount: salesStat.YesterdayCount,
UserStats: userStats,
ProductTotal: productTotal,
InventoryTotal: inventoryTotal,

View File

@ -76,6 +76,7 @@ func (s *StoreInfoService) StoreInfo(req systemReq.StoreInfoRequest, db ...*gorm
type storeStat struct {
ShopName string
SaleCount int64
SaleAmount int64
OutboundCount int64
ReceivingCount int64
ShippingCount int64
@ -93,10 +94,11 @@ func (s *StoreInfoService) StoreInfo(req systemReq.StoreInfoRequest, db ...*gorm
type row struct {
Name string `gorm:"column:sales_person"`
Cnt int64 `gorm:"column:cnt"`
Amt int64 `gorm:"column:amt"`
}
var rows []row
err := databaseConn.Raw(`
SELECT sales_person, COUNT(*) AS cnt
SELECT sales_person, COUNT(*) AS cnt, COALESCE(SUM(total_amount), 0) AS amt
FROM sales_order
WHERE is_del = 0 AND created_at >= ? AND created_at <= ? AND sales_person != ''
GROUP BY sales_person
@ -115,6 +117,7 @@ func (s *StoreInfoService) StoreInfo(req systemReq.StoreInfoRequest, db ...*gorm
statByName[n] = &storeStat{ShopName: n}
}
statByName[n].SaleCount = r.Cnt
statByName[n].SaleAmount = r.Amt
}
mu.Unlock()
}()
@ -254,7 +257,7 @@ func (s *StoreInfoService) StoreInfo(req systemReq.StoreInfoRequest, db ...*gorm
result = append(result, systemRes.StoreInfoResponse{
StoreName: name,
StoreType: storeType,
SaleCount: st.SaleCount,
SaleAmount: st.SaleAmount,
OutboundCount: st.OutboundCount,
ReceivingCount: st.ReceivingCount,
OrderCount: st.SaleCount,