1. 页面概览

1.1 是什么

对象查询页面(ObjectQueryPage.vue)让用户以「选择对象 → 勾选字段 → 配置过滤/排序 → 执行」的方式对本体对象做结构化查询,结果以二维表格(行 × 列)渲染。它走的是 POST /objects/:id/query 语义查询接口:

本页与「SQL 工作台」形成互补:SQL 工作台用 FROM 对象名 写自由 SQL,本页则是表单化的 OOL 查询构造器,把对象查询语法(字段/过滤算子/排序/limit/offset/params)显式暴露给用户操作。

1.2 核心价值

维度说明
表单化 OOL无需写 SQL,下拉+勾选+动态行即可构造对象查询
十种过滤算子eq/ne/gt/gte/lt/lte/like/contains/in/is_null 覆盖常规条件
安全闸门后端白名单校验 + RLS/CLS 只读注入 + 参数绑定,防注入防越权
编辑态可见未合入的草稿修改会叠加到结果并用「已编辑」标记说明
二维结果行 × 列表格直接呈现,与后端 columns/rows 结构一一对应

1.3 一句话总结

在 Foundry 里「选对象、勾字段、配条件」做解查数,后端负责 OOL 翻译与 RLS/CLS 安全注入,前端把结果渲染成带「已编辑」标注的二维表格。

2. 访问入口

2.1 路由与菜单

2.2 认证与权限

2.3 端口与 API 前缀

3. 界面布局

页面纵向分为 5 个板块(从上到下):

┌──────────────────────────────────────────────────────────────┐
│ ① 页头:标题「对象语义查询」                                    │
│ ② 操作结果提示条(alert,失败红,可关闭)                        │
│ ③ 选择对象卡片                                                 │
│    ├─ 对象类型 * 下拉(显示名(name · #id))                   │
│    └─ 对象信息(display_name · 表 xxx · 数据源 #N)             │
│ ④ 查询配置卡片(选中对象后出现)                               │
│    ├─ 查询字段 fields 多选(不选=全部列,计数标签)             │
│    ├─ 过滤条件 filters(+ 过滤条件 动态行)                     │
│    └─ 排序字段 order_by / limit / 降序 order_desc 复选框         │
│    └─ [查询] 按钮                                              │
│ ⑤ 查询结果卡片(共 N 行 × M 列 + 已编辑列标记)                │
└──────────────────────────────────────────────────────────────┘

各板块职责:

4. 交互元素详解

4.1 对象类型下拉

属性
控件<select v-model.number=selectedObjectId>
数据来源GET /api/v1/ontology/objectsonMounted(fetchObjects) 拉取,data.data 数组)
占位项「选择对象类型」(value=null,disabled)
选项格式display_name || name(name · #id),value 为 object_type.id
交互效果@change="loadDetail" 选中即加载详情;切换对象时清空上次结果与错误

4.2 对象信息展示

选中对象后 loadDetailGET /ontology/objects/:iddata.data 存为 detail,展示「display_name || name · 表 base_table || '-' · 数据源 #data_source_id」;未选中时显示灰色「选择对象后自动加载属性清单...」。loadDetail 还会把 queryForm.limit 兜底为 100(limit || 100)。

4.3 查询字段 fields 多选

属性
控件每个属性一个 checkbox(.row-check),标签为 p.name + 灰色 p.data_type
数据来源detail.properties(对象详情属性数组)
计数标题右侧蓝色计数 {{ queryForm.fields.length }}
语义不选 = 全部列(请求体传空数组 fields: []);选中的属性名进入 fields
空态对象无属性时显示「该对象暂无属性。」

4.4 过滤条件 filters 动态行

属性
添加按钮「+ 过滤条件」(.sub-title 右侧小按钮),push 一条 {field:'', op:'eq', value:''}
行结构字段下拉 + 算子下拉 + 值输入框 + 「删除」按钮
字段下拉选项为 detail.properties[].name,占位「字段」(disabled 空值)
算子下拉filterOps 十种:eq, ne, gt, gte, lt, lte, like, contains, in, is_null
值输入框placeholder「值(in 用逗号分隔)」;算子为 is_null 时输入框禁用(无需值)
删除按钮「删除」调 removeRow(filters, i) 从数组移除该行
空态无过滤条件时显示「暂无过滤条件。」
提交处理只提交 f.field 非空的行;op !== 'is_null' 时带 valueis_null 省略 value

4.5 排序与分页

字段控件说明
排序字段 order_by<select>选项为属性名,空值「不排序」
limit<input type=number min=1>默认 100,空值提交时兜底 100
降序 order_desccheckbox勾选后请求体 order_desc: true

4.6 「查询」按钮

属性
按钮文字「查询」(查询中变「查询中...」并禁用)
前置校验未选对象时提示「请先选择对象类型」
请求体{fields, filters, order_by, order_desc, limit, offset: 0, params: {}}
失败queryError 红条显示「查询失败:<error>」,结果清空
成功queryResult = {columns, rows, editedFields}queried = true

4.7 查询结果表格

元素说明
标题「查询结果」+「共 N 行 × M 列」
表头queryResult.columns 逐列渲染;列在 editedFields 中时追加「已编辑」黄色小标签(title「该列叠加了编辑态未合并的值」)
单元格formatCell(cell)null 显示空串,对象/数组转 JSON,其余 String()
空行rows.length === 0 时渲染跨列灰字「无查询结果」
未查询态!queryResult && queried 时显示「请先选择对象并配置查询条件,然后点击"查询"。」

5. 后端关联

5.1 API 客户端

5.2 端点表

方法路径请求体说明
GET/ontology/objects对象类型列表(data.data 数组,含 object_type
GET/ontology/objects/:id对象详情(data.data,含 object_type/properties
POST/objects/:id/queryOOL 查询请求体执行对象语义查询(路径不带 /ontology
POST/ontology/objects/:id/query同左语义等价别名路径

查询请求体(后端 objectQueryRequest):

{
  "fields": ["amount", "status"],
  "filters": [
    { "field": "amount", "op": "gt", "value": 1000 },
    { "field": "status", "op": "in", "value": ["paid", "shipped"] },
    { "field": "deleted_at", "op": "is_null" }
  ],
  "order_by": "created_at",
  "order_desc": true,
  "limit": 100,
  "offset": 0,
  "traverse": [],
  "params": {}
}

5.3 响应结构

统一包装 {code: 0, data: ...}datadomain.QueryResult

{
  "code": 0,
  "data": {
    "columns": ["id", "amount", "status", "created_at"],
    "rows": [
      [1, 2500.0, "paid", "2026-08-29T10:00:00Z"],
      [2, 300.0, "shipped", "2026-08-28T09:00:00Z"]
    ],
    "edited_fields": ["status"]
  }
}

5.4 关联模块表

后端包职责
foundry/semanticSemanticQueryService.Execute:OOL 翻译(白名单校验 + RLS/CLS 注入)→ 连接器真实执行 → 编辑态叠加
foundry/server/semantic_handlers.gohandleObjectQuery:解析对象 id、注入 params.user_id、调用 Execute
foundry/ontology对象类型/属性/链接元数据、GetLatestEditValues 编辑态读取
platform/connector数据源连接器执行物理查询
platform/authRLS/CLS 注入与对象级 ontology:<name>:read 授权

5.5 关键机制

OOL 过滤算子:后端语义包定义算子全集为 eq / ne / not_eq(ne 别名)/ gt / gte / lt / lte / like / contains / starts_with / in / is_null / and / or / not;前端页面暴露其中十种(eq/ne/gt/gte/lt/lte/like/contains/in/is_null)。in 的值可为标量/切片,页面提示「in 用逗号分隔」。值一律参数化绑定,不拼接进 SQL。

安全注入handleObjectQueryreq.Params["user_id"] = currentUserID(c);语义服务 Translate 阶段做属性白名单校验(字段必须是本体属性集合成员,含 linkName.propName 关联属性),再经 ApplyRLS/ApplyCLS 注入只读安全口径。

对象级可见性:查询入口经 authorizeObjectRead 校验 ontology:<对象名>:read,无读权限返回 403 明确错误(不静默放行);内部调度路径或 apps 组件加载(APP-06 已知路径)可跳过。

编辑态叠加applyEditOverlay 按主对象行 id 批量取 LoadEditValues 最新值覆盖源表列(仅主对象 t0 属性,traverse/link 关联对象列为后续层);被覆盖的属性写入 edited_fields 并剥离注入的主键列,保证输出列契约稳定。

Traverse 遍历式扩展:请求体 traverse 支持沿 link 进入相邻对象再过滤(then_filters/select 限相邻对象属性,禁点号引用,可嵌套 ≤3 层)。本页前端未暴露 traverse 编辑 UI,但请求体已透传空数组,供 API 调用方直接使用。

6. 核心流程详解

6.1 主流程:执行一次对象查询

  1. 页面加载 onMounted(fetchObjects)GET /ontology/objects 填充对象下拉;
  2. 选择对象 → loadDetailGET /ontology/objects/:id → 渲染属性多选/过滤字段/排序字段,limit 兜底 100;
  3. 勾选查询字段(不选=全部列),按需点「+ 过滤条件」添加过滤行并选算子填值;
  4. 选择排序字段、勾选降序、设置 limit;
  5. 点「查询」→ POST /objects/:id/query(body 见 5.2)→ 后端翻译+注入+执行;
  6. 结果渲染二维表格,edited_fields 中的列显示「已编辑」标签。

6.2 分支流程:is_null 过滤

算子选 is_null 时值输入框禁用且提交时省略 value(后端 is_null 不需要值)。例:过滤已删除行用 {field: "deleted_at", op: "is_null"}

6.3 分支流程:in 多值过滤

算子选 in 时值按逗号分隔输入,如 paid, shipped。注意:前端把值作为字符串提交(out.value = f.value),若需数值列表由后端语义解析处理;逗号分隔是页面提示约定。

6.4 结果导出(数据如何落盘)

本页当前不提供内置导出按钮——结果以二维表格在页面上渲染。若需要将结果导出为 CSV 落地,可采用以下途径:

说明:以上导出途径中,仅 SQL 工作台与审计页有现成按钮;对象查询页的导出属后续增强项(见第 9 章)。

6.5 编辑态叠加语义

当对象存在未合入的草稿修改(如 Action 测试/应用写入的编辑态),查询结果会叠加最新编辑值:被覆盖的属性列带「已编辑」标签;未 SELECT 该属性的列不受影响;聚合场景下编辑态叠加会回退为行级+内存聚合(超 10000 行标 approximate),保证行级与聚合一致。

7. 权限与安全

8. 常见问题与排错

8.1 点「查询」提示「查询失败:...」

8.2 「已编辑」列标记出现了但值「不新」

8.3 查询结果只有一行「无查询结果」

8.4 字段下拉/过滤字段为空

8.5 limit 填写无效(如 0 或负数)

9. 已知缺陷与边界

说明
无内置导出按钮本页结果以二维表格呈现,未提供「导出 CSV」按钮(见 6.4 的替代途径)
前端未暴露 traverse请求体透传 traverse: [],但页面没有遍历式编辑 UI,需 API 调用方自行构造
无 offset 编辑控件请求体固定 offset: 0,前端不提供翻页
过滤值统一字符串前端把过滤 value 作为字符串提交,数值语义由后端按列类型解析
编辑态仅主对象叠加traverse/link 关联对象列的编辑态为后续层,不叠加
关联列显示linkName.propName 关联字段若勾选会出现在 columns,单元格对象/数组转 JSON 文本

后端文件

项目文档

相邻页面链接