package service import ( "encoding/json" "fmt" "gorm.io/gorm" "psi/database" "psi/models" systemReq "psi/models/request" systemRes "psi/models/response" "psi/utils" "time" ) type WaveService struct{} // GetWaveTaskList 获取波次任务列表 func (s *WaveService) GetWaveTaskList(req systemReq.GetWaveTaskListRequest, creatorID int64, role int64, db ...*gorm.DB) (*systemRes.WaveTaskListResponse, error) { databaseConn := database.OptionalDB(db...) if req.Page < 1 { req.Page = 1 } if req.PageSize < 1 || req.PageSize > 100 { req.PageSize = 20 } query := databaseConn.Model(&models.WaveTask{}).Where("wave_task.is_del = ?", 0) if req.AssigneeID > 0 { query = query.Joins("INNER JOIN wave_header wh ON wave_task.wave_id = wh.id AND wh.is_del = 0"). Where("wave_task.assignee_id = ?", creatorID) } else if req.AssigneeID == 0 { query = query.Joins("INNER JOIN wave_header wh ON wave_task.wave_id = wh.id AND wh.is_del = 0") } //else { // if req.AssigneeID > 0 { // query = query.Where("wave_task.assignee_id = ?", req.AssigneeID) // } // query = query.Joins("LEFT JOIN wave_header wh ON wave_task.wave_id = wh.id AND wh.is_del = 0") //} if req.TaskNo != "" { query = query.Where("wave_task.task_no = ?", req.TaskNo) } if req.TaskType > 0 { query = query.Where("wave_task.type = ?", req.TaskType) } if req.Status > 0 { query = query.Where("wave_task.status = ?", req.Status) } if req.WaveNo != "" { query = query.Where("wh.wave_no LIKE ?", "%"+req.WaveNo+"%") } var total int64 if err := query.Count(&total).Error; err != nil { return nil, utils.NewError("查询总数失败") } // 打印SQL调试 sqlStmt := query.Session(&gorm.Session{DryRun: true}).Find(&[]models.WaveTask{}).Statement fmt.Println("Generated SQL:", sqlStmt.SQL.String(), "Vars:", sqlStmt.Vars) // 打印total fmt.Println("Total:", total) if total == 0 { return &systemRes.WaveTaskListResponse{ List: []systemRes.WaveTaskItem{}, Total: 0, Page: req.Page, PageSize: req.PageSize, }, nil } var tasks []systemRes.TaskWithWave offset := (req.Page - 1) * req.PageSize batchSubQuery := databaseConn.Model(&models.WaveTaskDetail{}). Select("wave_task_id, MAX(batch_no) as wave_task_batch_no"). Where("is_del = ?", 0). Group("wave_task_id") // 打印组装后的SQL dryQuery := query.Session(&gorm.Session{DryRun: true}). Select("wave_task.*, wh.wave_no,wh.related_order_id as out_order_id, r.id as receiving_order_id, d.wave_task_batch_no"). Joins("LEFT JOIN receiving_order r ON r.wave_task_id = wave_task.id AND r.is_del = 0"). Joins("LEFT JOIN (?) d ON d.wave_task_id = wave_task.id", batchSubQuery). Order("wave_task.created_at DESC"). Offset(offset). Limit(req.PageSize). Find(&tasks) fmt.Printf("[GetWaveTaskList] SQL: %s | Vars: %v\n", dryQuery.Statement.SQL.String(), dryQuery.Statement.Vars) if err := query.Select("wave_task.*, wh.wave_no,wh.related_order_id as out_order_id, r.id as receiving_order_id, d.wave_task_batch_no"). Joins("LEFT JOIN receiving_order r ON r.wave_task_id = wave_task.id AND r.is_del = 0"). Joins("LEFT JOIN (?) d ON d.wave_task_id = wave_task.id", batchSubQuery). Order("wave_task.created_at DESC"). Offset(offset). Limit(req.PageSize). Find(&tasks).Error; err != nil { return nil, utils.NewError("查询波次任务列表失败") } taskItems := make([]systemRes.WaveTaskItem, 0, len(tasks)) for _, task := range tasks { taskItems = append(taskItems, systemRes.ConvertWaveTaskToItem(task.WaveTask, task.WaveNo, task.OutOrderId, task.ReceivingOrderId, task.BatchNo)) } todayInboundWaves, yesterdayInboundWaves, todayInboundQty, yesterdayInboundQty, todayOutboundQty, yesterdayOutboundQty := s.getWaveTaskStatistics(databaseConn) return &systemRes.WaveTaskListResponse{ List: taskItems, Total: total, Page: req.Page, PageSize: req.PageSize, TodayInboundWaves: todayInboundWaves, YesterdayInboundWaves: yesterdayInboundWaves, TodayInboundQty: todayInboundQty, YesterdayInboundQty: yesterdayInboundQty, TodayOutboundQty: todayOutboundQty, YesterdayOutboundQty: yesterdayOutboundQty, }, nil } // getWaveTaskStatistics 获取波次任务统计数据 func (s *WaveService) getWaveTaskStatistics(db *gorm.DB) (int64, int64, int64, int64, int64, int64) { now := time.Now() todayStart := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()).Unix() yesterdayStart := time.Date(now.Year(), now.Month(), now.Day()-1, 0, 0, 0, 0, now.Location()).Unix() yesterdayEnd := todayStart var todayInboundWaves, yesterdayInboundWaves int64 var todayInboundQty, yesterdayInboundQty int64 var todayOutboundQty, yesterdayOutboundQty int64 db.Model(&models.WaveHeader{}). Where("is_del = ? AND direction = ? AND created_at >= ?", 0, 1, todayStart). Count(&todayInboundWaves) db.Model(&models.WaveHeader{}). Where("is_del = ? AND direction = ? AND created_at >= ? AND created_at < ?", 0, 1, yesterdayStart, yesterdayEnd). Count(&yesterdayInboundWaves) db.Table("wave_task_detail wtd"). Joins("INNER JOIN wave_task wt ON wt.id = wtd.wave_task_id AND wt.is_del = ?", 0). Joins("INNER JOIN wave_header wh ON wh.id = wt.wave_id AND wh.is_del = ? AND wh.direction = ?", 0, 1). Where("wtd.is_del = ? AND wt.created_at >= ?", 0, todayStart). Select("COALESCE(SUM(wtd.actual_quantity), 0)"). Scan(&todayInboundQty) db.Table("wave_task_detail wtd"). Joins("INNER JOIN wave_task wt ON wt.id = wtd.wave_task_id AND wt.is_del = ?", 0). Joins("INNER JOIN wave_header wh ON wh.id = wt.wave_id AND wh.is_del = ? AND wh.direction = ?", 0, 1). Where("wtd.is_del = ? AND wt.created_at >= ? AND wt.created_at < ?", 0, yesterdayStart, yesterdayEnd). Select("COALESCE(SUM(wtd.actual_quantity), 0)"). Scan(&yesterdayInboundQty) db.Table("wave_task_detail wtd"). Joins("INNER JOIN wave_task wt ON wt.id = wtd.wave_task_id AND wt.is_del = ?", 0). Joins("INNER JOIN wave_header wh ON wh.id = wt.wave_id AND wh.is_del = ? AND wh.direction = ?", 0, 2). Where("wtd.is_del = ? AND wt.created_at >= ?", 0, todayStart). Select("COALESCE(SUM(wtd.actual_quantity), 0)"). Scan(&todayOutboundQty) db.Table("wave_task_detail wtd"). Joins("INNER JOIN wave_task wt ON wt.id = wtd.wave_task_id AND wt.is_del = ?", 0). Joins("INNER JOIN wave_header wh ON wh.id = wt.wave_id AND wh.is_del = ? AND wh.direction = ?", 0, 2). Where("wtd.is_del = ? AND wt.created_at >= ? AND wt.created_at < ?", 0, yesterdayStart, yesterdayEnd). Select("COALESCE(SUM(wtd.actual_quantity), 0)"). Scan(&yesterdayOutboundQty) return todayInboundWaves, yesterdayInboundWaves, todayInboundQty, yesterdayInboundQty, todayOutboundQty, yesterdayOutboundQty } // GetWaveTaskDetail 获取波次任务详情 func (s *WaveService) GetWaveTaskDetail(id int64, creatorID int64, role int64, db ...*gorm.DB) (*systemRes.WaveTaskDetailResponse, error) { databaseConn := database.OptionalDB(db...) query := databaseConn.Model(&models.WaveTask{}). Where("wave_task.id = ? AND wave_task.is_del = ?", id, 0) if role == 128 { query = query.Joins("INNER JOIN wave_header wh ON wave_task.wave_id = wh.id AND wh.is_del = 0"). Where("wh.creator_id = ?", creatorID) } var task models.WaveTask result := query.First(&task) if result.Error != nil { return nil, utils.NewError("波次任务不存在") } var wave models.WaveHeader databaseConn.Where("id = ? AND is_del = ?", task.WaveID, 0).First(&wave) var details []systemRes.DetailWithInfo detailQuery := databaseConn.Model(&models.WaveTaskDetail{}). Select("wave_task_detail.*, p.name as product_name, p.barcode as product_code, p.sale_price, p.live_image, l.code as location_code"). Joins("LEFT JOIN product p ON wave_task_detail.product_id = p.id AND p.is_del = 0"). Joins("LEFT JOIN location l ON wave_task_detail.location_id = l.id AND l.is_del = 0"). Where("wave_task_detail.wave_task_id = ? AND wave_task_detail.is_del = ?", task.ID, 0) // 打印SQL调试 sqlStmt := detailQuery.Session(&gorm.Session{DryRun: true}).Find(&[]systemRes.DetailWithInfo{}).Statement fmt.Println("Generated SQL:", sqlStmt.SQL.String(), "Vars:", sqlStmt.Vars) detailQuery.Find(&details) detailItems := make([]systemRes.WaveTaskDetailItem, 0, len(details)) for _, detail := range details { var liveImage []string if len(detail.LiveImage) > 0 { json.Unmarshal(detail.LiveImage, &liveImage) } detailItems = append(detailItems, systemRes.WaveTaskDetailItem{ ID: detail.ID, WaveTaskID: detail.WaveTaskID, ProductID: detail.ProductID, ProductName: detail.ProductName, ProductCode: detail.ProductCode, SalePrice: detail.SalePrice, LiveImage: liveImage, LocationID: detail.LocationID, LocationCode: detail.LocationCode, BatchNo: detail.BatchNo, PlannedQuantity: detail.PlannedQuantity, ActualQuantity: detail.ActualQuantity, Status: detail.Status, StatusText: systemRes.GetWaveTaskDetailStatusText(detail.Status), CreatedAt: detail.CreatedAt, UpdatedAt: detail.UpdatedAt, }) } detailResponse := systemRes.ConvertWaveTaskToDetail(task, wave.WaveNo, detailItems) return &detailResponse, nil } // GetWaveStatusById 根据波次ID获取波次任务状态 func (s *WaveService) GetWaveStatusById(id int64, db ...*gorm.DB) (*models.WaveTask, error) { databaseConn := database.OptionalDB(db...) var waveTask models.WaveTask if err := databaseConn.Where("wave_id = ? AND is_del = ?", id, 0).First(&waveTask).Error; err != nil { return nil, utils.NewError("波次任务不存在") } return &waveTask, nil }