package model import ( "context" "fmt" "github.com/zeromicro/go-zero/core/stores/cache" "github.com/zeromicro/go-zero/core/stores/sqlx" ) var _ InvProductModel = (*customInvProductModel)(nil) type StockGroupResult struct { Name string `db:"name"` Count int64 `db:"count"` Quantity float64 `db:"quantity"` } type ( InvProductModel interface { invProductModel FindList(ctx context.Context, tenantId string, page, pageSize int64, productName, spec, color, location string, status int64) ([]*InvProduct, int64, error) FindStockSummary(ctx context.Context, tenantId string) (productCount, totalPieces, totalRolls int64, totalCostValue, totalSalesValue float64, err error) FindGroupByColor(ctx context.Context, tenantId string) ([]StockGroupResult, error) FindGroupByLocation(ctx context.Context, tenantId string) ([]StockGroupResult, error) } customInvProductModel struct { *defaultInvProductModel } ) func NewInvProductModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) InvProductModel { return &customInvProductModel{ defaultInvProductModel: newInvProductModel(conn, c, opts...), } } func (m *customInvProductModel) FindList(ctx context.Context, tenantId string, page, pageSize int64, productName, spec, color, location string, status int64) ([]*InvProduct, int64, error) { where := "WHERE deleted_at IS NULL AND tenant_id = ?" args := []interface{}{tenantId} if productName != "" { where += " AND product_name LIKE ?" args = append(args, "%"+productName+"%") } if spec != "" { where += " AND spec LIKE ?" args = append(args, "%"+spec+"%") } if color != "" { where += " AND color = ?" args = append(args, color) } if location != "" { where += " AND location = ?" args = append(args, location) } if status >= 0 { where += " AND status = ?" args = append(args, status) } var total int64 countQuery := fmt.Sprintf("SELECT COUNT(*) FROM %s %s", m.table, where) err := m.QueryRowNoCacheCtx(ctx, &total, countQuery, args...) if err != nil { return nil, 0, err } var list []*InvProduct query := fmt.Sprintf("SELECT %s FROM %s %s ORDER BY created_at DESC LIMIT ? OFFSET ?", invProductRows, m.table, where) args = append(args, pageSize, (page-1)*pageSize) err = m.QueryRowsNoCacheCtx(ctx, &list, query, args...) if err != nil { return nil, 0, err } return list, total, nil } func (m *customInvProductModel) FindStockSummary(ctx context.Context, tenantId string) (productCount, totalPieces, totalRolls int64, totalCostValue, totalSalesValue float64, err error) { var summary struct { ProductCount int64 `db:"product_count"` TotalPieces int64 `db:"total_pieces"` TotalRolls int64 `db:"total_rolls"` TotalCostValue float64 `db:"total_cost_value"` TotalSalesValue float64 `db:"total_sales_value"` } query := fmt.Sprintf("SELECT COUNT(*) AS product_count, COALESCE(SUM(unit_pieces), 0) AS total_pieces, COALESCE(SUM(unit_rolls), 0) AS total_rolls, COALESCE(SUM(stock_quantity * cost_price), 0) AS total_cost_value, COALESCE(SUM(stock_quantity * sales_price), 0) AS total_sales_value FROM %s WHERE deleted_at IS NULL AND tenant_id = ?", m.table) err = m.QueryRowNoCacheCtx(ctx, &summary, query, tenantId) if err != nil { return 0, 0, 0, 0, 0, err } return summary.ProductCount, summary.TotalPieces, summary.TotalRolls, summary.TotalCostValue, summary.TotalSalesValue, nil } func (m *customInvProductModel) FindGroupByColor(ctx context.Context, tenantId string) ([]StockGroupResult, error) { var list []StockGroupResult query := fmt.Sprintf("SELECT color AS name, COUNT(*) AS count, COALESCE(SUM(stock_quantity), 0) AS quantity FROM %s WHERE deleted_at IS NULL AND tenant_id = ? GROUP BY color ORDER BY count DESC", m.table) err := m.QueryRowsNoCacheCtx(ctx, &list, query, tenantId) if err != nil { return nil, err } return list, nil } func (m *customInvProductModel) FindGroupByLocation(ctx context.Context, tenantId string) ([]StockGroupResult, error) { var list []StockGroupResult query := fmt.Sprintf("SELECT location AS name, COUNT(*) AS count, COALESCE(SUM(stock_quantity), 0) AS quantity FROM %s WHERE deleted_at IS NULL AND tenant_id = ? GROUP BY location ORDER BY count DESC", m.table) err := m.QueryRowsNoCacheCtx(ctx, &list, query, tenantId) if err != nil { return nil, err } return list, nil }