package service import ( "fmt" "psi/constant" "psi/database" "psi/models" systemReq "psi/models/request" systemRes "psi/models/response" "psi/utils" "gorm.io/gorm" ) type InventoryService struct{} // GetInventoryList 获取库存汇总列表 func (s *InventoryService) GetInventoryList(req systemReq.GetInventoryListRequest, db ...*gorm.DB) (*systemRes.InventoryListResponse, error) { databaseConn := database.OptionalDB(db...) if req.Page < 1 { req.Page = 1 } if req.PageSize < 1 || req.PageSize > 100 { req.PageSize = 20 } query := databaseConn.Table("inventory"). Select(` inventory.product_id, p.name as product_name, p.barcode, p.appearance, p.price, inventory.warehouse_id, w.name as warehouse_name, w.code as warehouse_code, l.code as location_code, i.quantity as total_quantity, i.locked_quantity as locked_quantity `). Joins("LEFT JOIN inventory_detail i ON i.product_id = inventory.product_id"). Joins("LEFT JOIN location l ON l.id = i.location_id"). Joins("LEFT JOIN product p ON inventory.product_id = p.id AND p.is_del = 0"). Joins("LEFT JOIN warehouse w ON inventory.warehouse_id = w.id AND w.is_del = 0"). Where("inventory.is_del = ?", 0) if req.ProductId > 0 { query = query.Where("inventory.product_id = ?", req.ProductId) } 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+"%") } if req.Name != "" { query = query.Where("p.name LIKE ?", "%"+req.Name+"%") } var total int64 if err := query.Count(&total).Error; err != nil { return nil, utils.NewError("查询总数失败") } if total == 0 { return &systemRes.InventoryListResponse{ List: []systemRes.InventoryItem{}, Total: 0, Page: req.Page, PageSize: req.PageSize, }, nil } type InventorySummary struct { ProductID int64 `gorm:"column:product_id"` ProductName string `gorm:"column:product_name"` Appearance int64 `gorm:"column:appearance"` Barcode string `gorm:"column:barcode"` Price int64 `gorm:"column:price"` WarehouseID int64 `gorm:"column:warehouse_id"` WarehouseName string `gorm:"column:warehouse_name"` WarehouseCode string `gorm:"column:warehouse_code"` LocationCode string `gorm:"column:location_code"` TotalQuantity int64 `gorm:"column:total_quantity"` LockedQuantity int64 `gorm:"column:locked_quantity"` } var summaries []InventorySummary offset := (req.Page - 1) * req.PageSize if err := query.Order("i.updated_at DESC").Offset(offset).Limit(req.PageSize).Find(&summaries).Error; err != nil { return nil, utils.NewError("查询库存汇总列表失败") } items := make([]systemRes.InventoryItem, 0, len(summaries)) for _, summary := range summaries { items = append(items, systemRes.ConvertInventoryToItem( summary.ProductID, summary.ProductName, summary.Appearance, summary.Barcode, summary.Price, summary.WarehouseID, summary.WarehouseName, summary.WarehouseCode, summary.LocationCode, summary.TotalQuantity, summary.LockedQuantity, )) } return &systemRes.InventoryListResponse{ List: items, Total: total, Page: req.Page, PageSize: req.PageSize, }, nil } // GetInventoryGroupedList 获取按仓库库位分组的库存列表 func (s *InventoryService) GetInventoryGroupedList(req systemReq.GetInventoryGroupedListRequest, db ...*gorm.DB) (*systemRes.InventoryGroupedListResponse, error) { databaseConn := database.OptionalDB(db...) if req.Page < 1 { req.Page = 1 } if req.PageSize < 1 || req.PageSize > 100 { req.PageSize = 20 } // 第一步:查询仓库库位分组统计信息 groupQuery := databaseConn.Table("inventory_detail"). Select(` inventory_detail.warehouse_id, w.name as warehouse_name, w.code as warehouse_code, inventory_detail.location_id, l.code as location_code, COALESCE(SUM(inventory_detail.quantity), 0) as total_quantity, COALESCE(SUM(inventory_detail.locked_quantity), 0) as locked_quantity, COUNT(DISTINCT inventory_detail.product_id) as item_count `). Joins("LEFT JOIN warehouse w ON inventory_detail.warehouse_id = w.id AND w.is_del = 0"). Joins("LEFT JOIN location l ON inventory_detail.location_id = l.id AND l.is_del = 0"). Joins("LEFT JOIN product p ON inventory_detail.product_id = p.id AND p.is_del = 0"). Where("inventory_detail.is_del = ?", 0). Group("inventory_detail.warehouse_id, w.name, w.code, inventory_detail.location_id, l.code") 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) } if req.Keyword != "" { kw := "%" + req.Keyword + "%" groupQuery = groupQuery.Where("(l.code LIKE ? OR p.name LIKE ? OR p.barcode LIKE ?)", kw, kw, kw) } var total int64 if err := groupQuery.Count(&total).Error; err != nil { return nil, utils.NewError("查询总数失败") } if total == 0 { return &systemRes.InventoryGroupedListResponse{ List: []systemRes.InventoryGroupItem{}, Total: 0, Page: req.Page, PageSize: req.PageSize, }, nil } type GroupSummary struct { WarehouseID int64 `gorm:"column:warehouse_id"` WarehouseName string `gorm:"column:warehouse_name"` WarehouseCode string `gorm:"column:warehouse_code"` LocationID int64 `gorm:"column:location_id"` LocationCode string `gorm:"column:location_code"` TotalQuantity int64 `gorm:"column:total_quantity"` LockedQuantity int64 `gorm:"column:locked_quantity"` ItemCount int `gorm:"column:item_count"` } var groupSummaries []GroupSummary offset := (req.Page - 1) * req.PageSize if err := groupQuery.Order("inventory_detail.warehouse_id ASC, inventory_detail.location_id ASC").Offset(offset).Limit(req.PageSize).Find(&groupSummaries).Error; err != nil { return nil, utils.NewError("查询库存分组列表失败") } // 第二步:为每个分组查询详细的库存记录 groupList := make([]systemRes.InventoryGroupItem, 0, len(groupSummaries)) for _, group := range groupSummaries { // 查询该仓库库位下的所有库存明细 detailQuery := databaseConn.Table("inventory_detail"). Select(` inventory_detail.*, p.name as product_name, p.barcode, p.appearance, p.sale_price `). Joins("LEFT JOIN product p ON inventory_detail.product_id = p.id AND p.is_del = 0"). Where("inventory_detail.warehouse_id = ? AND inventory_detail.location_id = ? AND inventory_detail.is_del = ?", group.WarehouseID, group.LocationID, 0) if req.ProductId > 0 { detailQuery = detailQuery.Where("inventory_detail.product_id = ?", req.ProductId) } if req.Keyword != "" { kw := "%" + req.Keyword + "%" detailQuery = detailQuery.Where("(p.name LIKE ? OR p.barcode LIKE ?)", kw, kw) } var details []struct { models.InventoryDetail ProductName string `gorm:"column:product_name"` Barcode string `gorm:"column:barcode"` Appearance int64 `gorm:"column:appearance"` SalePrice int64 `gorm:"column:sale_price"` } if err := detailQuery.Order("inventory_detail.updated_at DESC").Find(&details).Error; err != nil { utils.ErrorLog(constant.LoggerChannelWork, map[string]interface{}{ "source": "查询库存明细", "warehouse_id": group.WarehouseID, "location_id": group.LocationID, "error": fmt.Sprintf("查询失败: %v", err), }) continue } detailItems := make([]systemRes.InventoryDetailItem, 0, len(details)) for _, detail := range details { detailItems = append(detailItems, systemRes.InventoryDetailItem{ ID: detail.ID, WarehouseID: detail.WarehouseID, WarehouseName: group.WarehouseName, LocationID: detail.LocationID, LocationCode: group.LocationCode, BatchNo: detail.BatchNo, ProductionDate: detail.ProductionDate, ExpiryDate: detail.ExpiryDate, Quantity: detail.Quantity, LockedQuantity: detail.LockedQuantity, CreatedAt: detail.CreatedAt, UpdatedAt: detail.UpdatedAt, ProductID: detail.ProductID, ProductName: detail.ProductName, Barcode: detail.Barcode, Appearance: detail.Appearance, SalePrice: detail.SalePrice, }) } groupList = append(groupList, systemRes.InventoryGroupItem{ WarehouseID: group.WarehouseID, WarehouseName: group.WarehouseName, WarehouseCode: group.WarehouseCode, LocationID: group.LocationID, LocationCode: group.LocationCode, TotalQuantity: group.TotalQuantity, LockedQuantity: group.LockedQuantity, ItemCount: group.ItemCount, Details: detailItems, }) } return &systemRes.InventoryGroupedListResponse{ List: groupList, Total: total, Page: req.Page, PageSize: req.PageSize, }, nil } // GetInventorySummary 获取库存统计信息 func (s *InventoryService) GetInventorySummary(db ...*gorm.DB) (*systemRes.InventorySummaryResponse, error) { databaseConn := database.OptionalDB(db...) response := &systemRes.InventorySummaryResponse{} // 1. 查询商品总种类数(同一个barcode算一个) productTypeQuery := databaseConn.Table("inventory_detail"). Joins("LEFT JOIN product p ON inventory_detail.product_id = p.id AND p.is_del = ?", 0). Where("inventory_detail.is_del = ?", 0) var productTypeCount int64 if err := productTypeQuery.Distinct("p.barcode").Count(&productTypeCount).Error; err != nil { utils.ErrorLog(constant.LoggerChannelWork, map[string]interface{}{ "source": "查询商品种类数", "error": fmt.Sprintf("查询失败: %v", err), }) return nil, utils.NewError("查询商品种类数失败") } response.ProductTypeCount = productTypeCount // 2. 查询商品总数(不去重,按库存明细记录数) productCountQuery := databaseConn.Table("inventory_detail"). Where("inventory_detail.is_del = ?", 0) var productCount int64 if err := productCountQuery.Count(&productCount).Error; err != nil { utils.ErrorLog(constant.LoggerChannelWork, map[string]interface{}{ "source": "查询商品总数", "error": fmt.Sprintf("查询失败: %v", err), }) return nil, utils.NewError("查询商品总数失败") } response.ProductCount = productCount // 3. 查询库存总量 totalQuantityQuery := databaseConn.Table("inventory_detail"). Select("COALESCE(SUM(quantity), 0)"). Where("inventory_detail.is_del = ?", 0) var totalQuantity int64 if err := totalQuantityQuery.Scan(&totalQuantity).Error; err != nil { utils.ErrorLog(constant.LoggerChannelWork, map[string]interface{}{ "source": "查询库存总量", "error": fmt.Sprintf("查询失败: %v", err), }) return nil, utils.NewError("查询库存总量失败") } response.TotalQuantity = totalQuantity // 4. 查询有货商品数量(库存大于0的商品种类,按barcode去重) availableProductQuery := databaseConn.Table("inventory_detail"). Joins("LEFT JOIN product p ON inventory_detail.product_id = p.id AND p.is_del = ?", 0). Where("inventory_detail.is_del = ?", 0). Where("inventory_detail.quantity > 0") var availableProductCount int64 if err := availableProductQuery.Distinct("p.barcode").Count(&availableProductCount).Error; err != nil { utils.ErrorLog(constant.LoggerChannelWork, map[string]interface{}{ "source": "查询有货商品数量", "error": fmt.Sprintf("查询失败: %v", err), }) return nil, utils.NewError("查询有货商品数量失败") } response.AvailableProductCount = availableProductCount // 5. 查询库位数(使用过的库位数量) locationQuery := databaseConn.Table("inventory_detail"). Select("COUNT(DISTINCT location_id)"). Where("inventory_detail.is_del = ?", 0) var locationCount int64 if err := locationQuery.Scan(&locationCount).Error; err != nil { utils.ErrorLog(constant.LoggerChannelWork, map[string]interface{}{ "source": "查询库位数", "error": fmt.Sprintf("查询失败: %v", err), }) return nil, utils.NewError("查询库位数失败") } response.LocationCount = locationCount return response, nil } // GetInventoryDetail 获取库存明细 func (s *InventoryService) GetInventoryDetail(productID int64, db ...*gorm.DB) (*systemRes.InventoryDetailResponse, error) { databaseConn := database.OptionalDB(db...) var product models.Product if err := databaseConn.Where("id = ? AND is_del = ?", productID, 0).First(&product).Error; err != nil { return nil, utils.NewError("商品不存在") } query := databaseConn.Model(&models.InventoryDetail{}). Select("inventory_detail.*, w.name as warehouse_name, l.code as location_code"). Joins("LEFT JOIN warehouse w ON inventory_detail.warehouse_id = w.id AND w.is_del = 0"). Joins("LEFT JOIN location l ON inventory_detail.location_id = l.id AND l.is_del = 0"). Where("inventory_detail.product_id = ? AND inventory_detail.is_del = ?", productID, 0) var total int64 if err := query.Count(&total).Error; err != nil { return nil, utils.NewError("查询总数失败") } var details []struct { models.InventoryDetail WarehouseName string `gorm:"column:warehouse_name"` LocationCode string `gorm:"column:location_code"` } if err := query.Order("inventory_detail.updated_at DESC").Find(&details).Error; err != nil { return nil, utils.NewError("查询库存明细失败") } // 查询该商品关联的任务信息 type TaskInfo struct { WaveNo string `gorm:"column:wave_no"` WaveTaskNo string `gorm:"column:wave_task_no"` OutTaskNo int64 `gorm:"column:out_task_no"` SalesOrderNo string `gorm:"column:sales_order_no"` ShippingNo string `gorm:"column:shipping_no"` } var taskInfo TaskInfo databaseConn.Table("wave_task_detail wtd"). Select(`COALESCE(wh.wave_no, '') as wave_no, COALESCE(wt.task_no, '') as wave_task_no, COALESCE(ot.out_task_id, 0) as out_task_no, COALESCE(so.so_no, '') as sales_order_no, COALESCE(sh.shipping_no, '') as shipping_no`). Joins("JOIN wave_task wt ON wt.id = wtd.wave_task_id AND wt.is_del = 0"). Joins("JOIN wave_header wh ON wh.id = wt.wave_id AND wh.is_del = 0"). Joins("LEFT JOIN out_task ot ON ot.wave_task_id = wt.id AND ot.is_del = 0"). Joins("LEFT JOIN sales_order so ON so.id = wh.related_order_id AND so.is_del = 0"). Joins("LEFT JOIN outbound_order obo ON obo.wave_task_id = wt.id AND obo.is_del = 0"). Joins("LEFT JOIN outbound_order_item oboi ON oboi.out_order_id = obo.id AND oboi.product_id = ? AND oboi.is_del = 0", productID). Joins("LEFT JOIN shipping_order_item soi ON soi.outbound_order_item_id = oboi.id AND soi.is_del = 0"). Joins("LEFT JOIN shipping_order sh ON sh.id = soi.shipping_order_id AND sh.is_del = 0"). Where("wtd.product_id = ? AND wtd.is_del = 0", productID). Order("wt.id DESC"). Limit(1). Scan(&taskInfo) items := make([]systemRes.InventoryDetailItem, 0, len(details)) for _, detail := range details { items = append(items, systemRes.ConvertInventoryDetailToItem( detail.InventoryDetail, detail.WarehouseName, detail.LocationCode, taskInfo.WaveNo, taskInfo.WaveTaskNo, taskInfo.OutTaskNo, taskInfo.SalesOrderNo, taskInfo.ShippingNo, )) } return &systemRes.InventoryDetailResponse{ ProductID: productID, ProductName: product.Name, List: items, Total: total, }, nil } // GetInventoryLogList 获取库存流水列表 func (s *InventoryService) GetInventoryLogList(req systemReq.GetInventoryLogListRequest, db ...*gorm.DB) (*systemRes.InventoryLogListResponse, error) { databaseConn := database.OptionalDB(db...) if req.Page < 1 { req.Page = 1 } if req.PageSize < 1 || req.PageSize > 100 { req.PageSize = 20 } query := databaseConn.Table("inventory_log"). Select(` inventory_log.*, w.name as warehouse_name, l.code as location_code, p.name as product_name, p.barcode `). Joins("LEFT JOIN warehouse w ON inventory_log.warehouse_id = w.id AND w.is_del = 0"). Joins("LEFT JOIN location l ON inventory_log.location_id = l.id AND l.is_del = 0"). Joins("LEFT JOIN product p ON inventory_log.product_id = p.id AND p.is_del = 0"). Where("inventory_log.is_del = ?", 0) if req.ISBN != "" { query = query.Where("p.barcode LIKE ?", "%"+req.ISBN+"%") } if req.BookName != "" { query = query.Where("p.name LIKE ?", "%"+req.BookName+"%") } 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) } if req.RelatedOrderNo != "" { query = query.Where("inventory_log.related_order_no LIKE ?", "%"+req.RelatedOrderNo+"%") } if req.StartDate > 0 { query = query.Where("inventory_log.created_at >= ?", req.StartDate) } if req.EndDate > 0 { query = query.Where("inventory_log.created_at <= ?", req.EndDate) } var total int64 if err := query.Count(&total).Error; err != nil { return nil, utils.NewError("查询总数失败") } if total == 0 { return &systemRes.InventoryLogListResponse{ List: []systemRes.InventoryLogItem{}, Total: 0, Page: req.Page, PageSize: req.PageSize, }, nil } var logs []struct { models.InventoryLog WarehouseName string `gorm:"column:warehouse_name"` LocationCode string `gorm:"column:location_code"` ProductName string `gorm:"column:product_name"` Barcode string `gorm:"column:barcode"` } offset := (req.Page - 1) * req.PageSize if err := query.Order("inventory_log.created_at DESC").Offset(offset).Limit(req.PageSize).Find(&logs).Error; err != nil { return nil, utils.NewError("查询库存流水列表失败") } items := make([]systemRes.InventoryLogItem, 0, len(logs)) for _, log := range logs { items = append(items, systemRes.ConvertInventoryLogToItem( log.InventoryLog, log.WarehouseName, log.LocationCode, log.ProductName, log.Barcode, )) } return &systemRes.InventoryLogListResponse{ List: items, Total: total, Page: req.Page, PageSize: req.PageSize, }, nil } // InventoryStatist 获取ISBN/品相的库存总数(跨所有商品和仓库) func (s *InventoryService) InventoryStatist(req systemReq.InventoryStatistRequest, db ...*gorm.DB) (*systemRes.InventoryStatistResponse, error) { databaseConn := database.OptionalDB(db...) if req.Barcode == "" && req.Appearance <= 0 { return nil, utils.NewError("条码和品相至少提供一个") } type InventoryTotal struct { Barcode string `gorm:"column:barcode"` Appearance int64 `gorm:"column:appearance"` TotalQuantity int64 `gorm:"column:total_quantity"` ProductCount int `gorm:"column:product_count"` } query := databaseConn.Table("inventory"). Select(` p.barcode, p.appearance, SUM(inventory.quantity) as total_quantity, COUNT(DISTINCT inventory.product_id) as product_count `). Joins("LEFT JOIN product p ON inventory.product_id = p.id AND p.is_del = 0"). Where("inventory.is_del = ?", 0) if req.Barcode != "" { query = query.Where("p.barcode = ?", req.Barcode) } if req.Appearance > 0 { query = query.Where("p.Appearance = ?", req.Appearance) } var total InventoryTotal if err := query.Group("p.barcode, p.appearance").Limit(1).Scan(&total).Error; err != nil { return nil, utils.NewError("查询库存总数失败") } return &systemRes.InventoryStatistResponse{ Barcode: total.Barcode, Appearance: total.Appearance, TotalQuantity: total.TotalQuantity, ProductCount: total.ProductCount, }, nil } // GetStockCheckList 获取盘库列表(不包含明细) func (s *InventoryService) GetStockCheckList(req systemReq.GetStockCheckListRequest, db ...*gorm.DB) (*systemRes.StockCheckListResponse, error) { databaseConn := database.OptionalDB(db...) if req.Page < 1 { req.Page = 1 } if req.PageSize < 1 || req.PageSize > 100 { req.PageSize = 20 } query := databaseConn.Table("stock_check"). Select(` stock_check.*, w.name as warehouse_name `). Joins("LEFT JOIN warehouse w ON stock_check.warehouse_id = w.id AND w.is_del = 0"). Where("stock_check.is_del = ?", 0) if req.WarehouseID > 0 { query = query.Where("stock_check.warehouse_id = ?", req.WarehouseID) } if req.Status > 0 { query = query.Where("stock_check.status = ?", req.Status) } if req.CheckNo != "" { query = query.Where("stock_check.check_no LIKE ?", "%"+req.CheckNo+"%") } if req.StartDate > 0 { query = query.Where("stock_check.created_at >= ?", req.StartDate) } if req.EndDate > 0 { query = query.Where("stock_check.created_at <= ?", req.EndDate) } var total int64 if err := query.Count(&total).Error; err != nil { return nil, utils.NewError("查询总数失败") } if total == 0 { return &systemRes.StockCheckListResponse{ List: []systemRes.StockCheckItem{}, Total: 0, Page: req.Page, PageSize: req.PageSize, }, nil } type StockCheckWithWarehouse struct { models.StockCheck WarehouseName string `gorm:"column:warehouse_name"` } var checks []StockCheckWithWarehouse offset := (req.Page - 1) * req.PageSize if err := query.Order("stock_check.created_at DESC").Offset(offset).Limit(req.PageSize).Find(&checks).Error; err != nil { return nil, utils.NewError("查询盘库列表失败") } items := make([]systemRes.StockCheckItem, 0, len(checks)) for _, check := range checks { item := systemRes.ConvertStockCheckToItem(check.StockCheck, check.WarehouseName) items = append(items, item) } return &systemRes.StockCheckListResponse{ List: items, Total: total, Page: req.Page, PageSize: req.PageSize, }, nil } // GetStockCheckDetail 获取盘库明细列表 func (s *InventoryService) GetStockCheckDetail(req systemReq.GetStockCheckDetailRequest, db ...*gorm.DB) (*systemRes.StockCheckDetailResponse, error) { databaseConn := database.OptionalDB(db...) if req.Page < 1 { req.Page = 1 } if req.PageSize < 1 || req.PageSize > 100 { req.PageSize = 20 } if req.StockCheckID == 0 { return nil, utils.NewError("盘库单ID不能为空") } query := databaseConn.Table("stock_check_item"). Select(` stock_check_item.*, p.name as product_name, p.barcode, l.code as location_code `). Joins("LEFT JOIN product p ON stock_check_item.product_id = p.id AND p.is_del = 0"). Joins("LEFT JOIN location l ON stock_check_item.location_id = l.id AND l.is_del = 0"). Where("stock_check_item.stock_check_id = ? AND stock_check_item.is_del = ?", req.StockCheckID, 0) var total int64 if err := query.Count(&total).Error; err != nil { return nil, utils.NewError("查询总数失败") } if total == 0 { return &systemRes.StockCheckDetailResponse{ List: []systemRes.StockCheckDetailItem{}, Total: 0, Page: req.Page, PageSize: req.PageSize, }, nil } type StockCheckItemWithInfo struct { models.StockCheckItem ProductName string `gorm:"column:product_name"` Barcode string `gorm:"column:barcode"` LocationCode string `gorm:"column:location_code"` } var items []StockCheckItemWithInfo offset := (req.Page - 1) * req.PageSize if err := query.Order("stock_check_item.created_at ASC").Offset(offset).Limit(req.PageSize).Find(&items).Error; err != nil { return nil, utils.NewError("查询盘库明细失败") } details := make([]systemRes.StockCheckDetailItem, 0, len(items)) for _, item := range items { detail := systemRes.StockCheckDetailItem{ ID: item.ID, ProductID: item.ProductID, ProductName: item.ProductName, Barcode: item.Barcode, LocationID: item.LocationID, LocationCode: item.LocationCode, BatchNo: item.BatchNo, ProductionDate: item.ProductionDate, ExpiryDate: item.ExpiryDate, SystemQuantity: item.SystemQuantity, ActualQuantity: item.ActualQuantity, DifferenceQuantity: item.DifferenceQuantity, Status: item.Status, StatusText: systemRes.GetStockCheckItemStatusText(item.Status), CheckOperator: item.CheckOperator, CheckOperatorID: item.CheckOperatorID, CheckTime: item.CheckTime, Remark: item.Remark, CreatedAt: item.CreatedAt, UpdatedAt: item.UpdatedAt, } details = append(details, detail) } return &systemRes.StockCheckDetailResponse{ List: details, Total: total, Page: req.Page, PageSize: req.PageSize, }, nil }