chore: initial commit of ai site platform
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
91
platform/internal/logic/applogic/aggregate.go
Normal file
91
platform/internal/logic/applogic/aggregate.go
Normal file
@@ -0,0 +1,91 @@
|
||||
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 == "<nil>" {
|
||||
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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user