metric-check-flow.md 12 KB

指标公式检查流程图

整体架构

┌─────────────┐
│   前端界面   │
│  (Browser)  │
└──────┬──────┘
       │ POST /api/data/metric/check
       │ {"formula": "销售额 = 单价 * 数量"}
       ↓
┌──────────────────────────────────────┐
│     API Layer (Flask Routes)          │
│  app/api/data_metric/routes.py       │
│                                       │
│  @bp.route('/data/metric/check')     │
│  def data_metric_check():            │
│    - 接收请求参数                     │
│    - 参数验证                         │
│    - 调用核心函数                     │
│    - 返回JSON响应                     │
└──────────────┬───────────────────────┘
               │
               │ metric_check(formula_text)
               ↓
┌──────────────────────────────────────┐
│   Business Logic Layer (Core)        │
│  app/core/data_metric/               │
│  metric_interface.py                 │
│                                       │
│  def metric_check(formula_text):     │
│    1. 解析公式                        │
│    2. 提取变量                        │
│    3. 查询数据库                      │
│    4. 返回结果                        │
└──────────────┬───────────────────────┘
               │
               │ Cypher Query
               ↓
┌──────────────────────────────────────┐
│     Data Layer (Neo4j)                │
│                                       │
│  MATCH (n:DataMeta)                  │
│  WHERE n.name CONTAINS $variable     │
│  RETURN n, id(n) as node_id          │
│  LIMIT 1                             │
└──────────────────────────────────────┘

详细流程

1. 公式解析流程

输入公式: "销售额 = (单价 * 数量) + 运费 - 10"
          │
          ↓
    按等号分割
          │
          ↓
┌─────────────────────────┐
│ 左侧: "销售额"           │ → 指标名称(暂不使用)
│ 右侧: "(单价*数量)+运费-10"│ → 计算表达式
└─────────┬───────────────┘
          │
          ↓
    正则分割运算符
    [+\-*/()()\[\]{}]
          │
          ↓
┌─────────────────────────┐
│ Tokens:                 │
│ ["单价", "数量",         │
│  "运费", "10"]          │
└─────────┬───────────────┘
          │
          ↓
    过滤中文变量
          │
          ↓
┌─────────────────────────┐
│ Variables:              │
│ ["单价", "数量", "运费"]│
└─────────┬───────────────┘
          │
          ↓
      变量去重
          │
          ↓
┌─────────────────────────┐
│ Unique Variables:       │
│ ["单价", "数量", "运费"]│
└─────────────────────────┘

2. 数据库查询流程

变量列表: ["单价", "数量", "运费"]
     │
     ↓
┌────────────────────────┐
│  for variable in list  │
└────┬───────────────────┘
     │
     ↓ 查询Neo4j
┌──────────────────────────────┐
│ MATCH (n:DataMeta)           │
│ WHERE n.name CONTAINS "单价" │
│ RETURN n, id(n)              │
└────┬─────────────────────────┘
     │
     ↓ 是否找到?
     │
     ├─ 是 ─→ ┌────────────────────┐
     │        │ {                  │
     │        │   variable: "单价" │
     │        │   name_zh: "单价"  │
     │        │   name_en: "price" │
     │        │   id: 101          │
     │        │   findit: 1        │
     │        │ }                  │
     │        └────────────────────┘
     │
     └─ 否 ─→ ┌────────────────────┐
              │ {                  │
              │   variable: "运费" │
              │   name_zh: ""      │
              │   name_en: ""      │
              │   id: null         │
              │   findit: 0        │
              │ }                  │
              └────────────────────┘

3. 响应构建流程

查询结果列表
     │
     ↓
┌──────────────────────────┐
│ [                        │
│   {variable:"单价",       │
│    findit:1, id:101},    │
│   {variable:"数量",       │
│    findit:1, id:102},    │
│   {variable:"运费",       │
│    findit:0, id:null}    │
│ ]                        │
└────┬─────────────────────┘
     │
     ↓ 包装成API响应
┌──────────────────────────┐
│ {                        │
│   code: 200,             │
│   message: "success",    │
│   data: [...]            │
│ }                        │
└────┬─────────────────────┘
     │
     ↓ JSON序列化
     │
     ↓ 返回给前端
┌──────────────────────────┐
│   前端显示结果            │
│   ✓ 单价: 已找到          │
│   ✓ 数量: 已找到          │
│   ✗ 运费: 未找到          │
└──────────────────────────┘

错误处理流程

请求到达
    │
    ↓
┌───────────────┐
│ 参数验证       │ ─┬─→ formula为空 ──→ 返回错误
└───────┬───────┘  │
        │          └─→ 无formula字段 ─→ 返回错误
        ↓
┌───────────────┐
│ 公式验证       │ ──→ 无等号 ──→ 返回空数组
└───────┬───────┘
        │
        ↓
┌───────────────┐
│ 变量提取       │ ──→ 无中文变量 ──→ 返回空数组
└───────┬───────┘
        │
        ↓
┌───────────────┐
│ 数据库查询     │ ─┬─→ 连接失败 ──→ 返回空数组
└───────┬───────┘  │
        │          └─→ 查询异常 ──→ 记录日志,返回错误
        │
        ↓
    正常返回

数据流图

┌─────────┐
│  前端   │
└────┬────┘
     │
     │ 1. 用户输入公式
     │    "销售额 = 单价 * 数量"
     │
     ↓
┌─────────────┐
│  API接口    │
└──────┬──────┘
       │
       │ 2. 解析并验证
       │    formula_text = "销售额 = 单价 * 数量"
       │
       ↓
┌──────────────────┐
│  核心业务逻辑     │
└───────┬──────────┘
        │
        │ 3. 提取变量
        │    variables = ["单价", "数量"]
        │
        ↓
┌──────────────┐
│   Neo4j     │ ←─ 4. 查询元数据
└──────┬───────┘    "MATCH (n:DataMeta) WHERE..."
       │
       │ 5. 返回节点数据
       │    [{name:"单价", en_name:"price", id:101}, ...]
       │
       ↓
┌──────────────────┐
│  核心业务逻辑     │
└───────┬──────────┘
        │
        │ 6. 格式化结果
        │    [{variable:"单价", findit:1, id:101}, ...]
        │
        ↓
┌─────────────┐
│  API接口    │
└──────┬──────┘
       │
       │ 7. JSON响应
       │    {code:200, message:"success", data:[...]}
       │
       ↓
┌─────────┐
│  前端   │
└─────────┘
    显示结果

时序图

前端          API接口         核心函数         Neo4j
 │              │               │              │
 │─POST────────→│               │              │
 │ formula      │               │              │
 │              │               │              │
 │              │─调用─────────→│              │
 │              │ metric_check  │              │
 │              │               │              │
 │              │               │─解析公式────→│
 │              │               │              │
 │              │               │←提取变量─────│
 │              │               │ ["单价","数量"]│
 │              │               │              │
 │              │               │─查询: 单价──→│
 │              │               │              │
 │              │               │←返回节点────│
 │              │               │ {id:101,...} │
 │              │               │              │
 │              │               │─查询: 数量──→│
 │              │               │              │
 │              │               │←返回节点────│
 │              │               │ {id:102,...} │
 │              │               │              │
 │              │←返回结果─────│              │
 │              │ [findit:1,...]│              │
 │              │               │              │
 │←JSON响应────│               │              │
 │ {code:200}   │               │              │
 │              │               │              │

状态转换图

[开始]
   │
   ↓
[接收请求] ─错误─→ [返回错误响应]
   │
   │ 成功
   ↓
[解析公式] ─无等号─→ [返回空数组]
   │
   │ 有等号
   ↓
[提取变量] ─无变量─→ [返回空数组]
   │
   │ 有变量
   ↓
[查询数据库] ─连接失败─→ [返回空数组]
   │
   │ 连接成功
   ↓
[处理每个变量]
   │
   ├─找到匹配─→ [findit=1]
   │              │
   └─未找到───→ [findit=0]
                  │
                  ↓
             [收集结果]
                  │
                  ↓
             [返回成功响应]
                  │
                  ↓
                [结束]

关键决策点

1. 公式是否有效?
   ├─ 是: 继续
   └─ 否: 返回错误

2. 是否提取到变量?
   ├─ 是: 查询数据库
   └─ 否: 返回空数组

3. 数据库连接是否正常?
   ├─ 是: 执行查询
   └─ 否: 返回空数组

4. 是否找到匹配?
   ├─ 是: findit=1
   └─ 否: findit=0

5. 是否还有更多变量?
   ├─ 是: 继续查询
   └─ 否: 返回结果

说明:

  • 实线箭头 (→): 正常流程
  • 虚线箭头 (⇢): 数据流
  • 分支 (├─): 决策点
  • 单向箭头 (↓): 顺序执行