package applogic import ( "fmt" "strconv" "aijianzhan/platform/internal/authx" "aijianzhan/platform/internal/types" ) func (l *CrudLogic) Aggregate(slug, resource, groupBy, sumField string) (*types.AggregateResp, error) { tenantID := authx.TenantID(l.ctx) ref, err := l.svcCtx.Meta.ResolveResource(l.ctx, tenantID, slug, resource) if err != nil { return nil, err } if groupBy != "" { ok := false if ref.Resource.List != nil { for _, f := range ref.Resource.List.AllowedFilters { if f == groupBy { ok = true break } } } for _, f := range ref.Entity.Fields { if f.Name == groupBy { ok = true break } } if !ok { return nil, fmt.Errorf("group_by not allowed: %s", groupBy) } } items, total, err := l.svcCtx.CRUD.List(l.ctx, ref, tenantID, 1, 5000, nil, "") if err != nil { return nil, err } resp := &types.AggregateResp{Total: total, GroupBy: groupBy, SumField: sumField} if groupBy == "" { if sumField != "" { for _, it := range items { resp.Sum += toFloat(it[sumField]) } } return resp, nil } buckets := map[string]*types.AggregateBucket{} order := []string{} for _, it := range items { key := fmt.Sprint(it[groupBy]) if key == "" || key == "" { key = "(çİş)" } b, ok := buckets[key] if !ok { b = &types.AggregateBucket{Key: key} buckets[key] = b order = append(order, key) } b.Count++ if sumField != "" { b.Sum += toFloat(it[sumField]) resp.Sum += toFloat(it[sumField]) } } for _, k := range order { resp.Buckets = append(resp.Buckets, *buckets[k]) } return resp, nil } func toFloat(v any) float64 { switch t := v.(type) { case float64: return t case float32: return float64(t) case int: return float64(t) case int64: return float64(t) case string: n, _ := strconv.ParseFloat(t, 64) return n default: return 0 } }