Files
test/app/api/advanced_api.py
T
2026-09-21 19:03:31 +08:00

102 lines
4.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""通用高级筛选与聚合接口(需求 2.7.1 / 2.7.2)。"""
from __future__ import annotations
from fastapi import APIRouter
from app.core.deps import DbSession, ReadAccount
from app.core.response import Resp, ok
from app.schema.advanced_schema import AggregationParams, AggregationResult, QueryRequest
from app.service.advanced_service import AdvancedQueryService
router = APIRouter(prefix="/advanced", tags=["2.7 高级筛选与聚合"])
@router.get("/meta", summary="可选模型与字段白名单(前端规则构建器用)")
def meta(_: ReadAccount):
return ok(AdvancedQueryService.meta())
@router.post("/query", summary="2.7.1 通用高级筛选(支持嵌套 AND/OR、8 种操作符)")
def advanced_query(db: DbSession, _: ReadAccount, payload: QueryRequest):
result = AdvancedQueryService.execute(db, payload)
return ok(result, msg=f"命中 {result['total']} 条")
@router.post(
"/aggregate",
response_model=Resp[AggregationResult],
summary="2.7.2 通用分组聚合(count/avg/sum/max/min,可带 having)",
)
def advanced_aggregate(db: DbSession, _: ReadAccount, payload: AggregationParams):
return ok(AdvancedQueryService.aggregate(db, payload))
@router.get("/examples", summary="规则示例(直接复制改改就能用)")
def examples(_: ReadAccount):
return ok(
[
{
"title": "年龄大于 25 且(薪资 >= 15000 或 班级名含 Java)—— 需求 2.7.1 的原始示例",
"body": {
"model": "student",
"rules": [
{"field": "age", "operator": ">", "value": 25},
{"field": "gender", "operator": "=", "value": "男"},
{
"logic": "OR",
"sub_rules": [
{"field": "salary", "operator": ">=", "value": 15000},
{"field": "class_name", "operator": "like", "value": "Java"},
],
},
],
"order_by": "salary",
"order": "desc",
"page": 1,
"page_size": 10,
},
},
{
"title": "2026 年入学的、30 岁以下、学历在大专/本科之间的学生",
"body": {
"model": "student",
"rules": [
{"field": "age", "operator": "between", "value": [18, 30]},
{"field": "enroll_date", "operator": ">=", "value": "2026-01-01"},
{"field": "education", "operator": "in", "value": ["大专", "本科"]},
],
"fields": ["stu_no", "name", "age", "education", "class_name", "enroll_date"],
},
},
{
"title": "成绩在 60-70 分之间的成绩记录(含学生与班级)",
"body": {
"model": "score",
"rules": [
{"field": "score", "operator": "between", "value": [60, 70]},
{"field": "exam_seq", "operator": "<=", "value": 3},
],
"order_by": "score",
"order": "asc",
},
},
{
"title": "聚合:按班级算平均薪资、最高薪资,只看平均薪资 > 10000 的班",
"body": {
"model": "employment",
"group_by": ["class_name"],
"metrics": [
{"func": "count", "alias": "人数"},
{"func": "avg", "field": "salary", "alias": "平均薪资"},
{"func": "max", "field": "salary", "alias": "最高薪资"},
],
"having": [{"field": "平均薪资", "operator": ">", "value": 10000}],
"order_by": "平均薪资",
"order": "desc",
"limit": 20,
},
},
]
)