299 lines
7.4 KiB
Markdown
299 lines
7.4 KiB
Markdown
---
|
||
title: 数据查询
|
||
description: describe / loaddata / page / loaddatabysql / nextid / nextcode
|
||
pageClass: g3-api
|
||
---
|
||
|
||
# 数据查询
|
||
|
||
六个只读接口。除了 `nextid`(纯取号,不碰数据库),其余都会落到**当前机构自己的数据库**上执行。
|
||
|
||
共用规则:
|
||
|
||
- **表名、视图名、列名都会先过标识符校验**(只允许 `[A-Za-z_][A-Za-z0-9_]*`,可带限定名如 `dbo.v_x`),不会做字符串拼接 —— 所以别指望能塞入非法标识符。
|
||
- `search_condition` 是**原样拼进 `WHERE` 的 SQL 条件片段**;拼好的整条 SQL 之后会过只读校验(禁分号、禁注释、禁写关键字),所以它只能是布尔表达式。
|
||
- `order_by` 由后端校验并加 `[]`:支持 `字段 [ASC|DESC]`,或 `CASE ... END` 表达式,多列用逗号分隔。
|
||
- 返回的行是普通对象,键是**库里的原始列名**。
|
||
|
||
## `POST` `/data/describe`
|
||
|
||
探测表或视图的列结构,用于动态列、字段同步。
|
||
|
||
<G3ApiParams>
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|---|---|---|---|
|
||
| `table` | string | 是 | 表或视图名 |
|
||
|
||
</G3ApiParams>
|
||
|
||
<G3ApiPayload title="请求体">
|
||
|
||
```json
|
||
{
|
||
"table": "v_b_othercompany"
|
||
}
|
||
```
|
||
|
||
</G3ApiPayload>
|
||
|
||
<G3ApiPayload title="响应" :code="0">
|
||
|
||
```json
|
||
{
|
||
"code": 0,
|
||
"message": "操作成功",
|
||
"data": [
|
||
{ "name": "b_id", "type": "varchar", "nullable": false, "size": 32 },
|
||
{ "name": "b_name", "type": "nvarchar", "nullable": true, "size": 128 }
|
||
]
|
||
}
|
||
```
|
||
|
||
</G3ApiPayload>
|
||
|
||
`type` 是数据库原生类型名(`varchar` / `nvarchar` / `decimal` / `datetime2` / `rowversion` …)。表不存在或没有可识别字段时返回 `1000`。
|
||
|
||
## `POST` `/data/loaddata`
|
||
|
||
按视图 + 条件 + 排序 + 字段列表查询。
|
||
|
||
<G3ApiParams>
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|---|---|---|---|
|
||
| `view_name` | string | 是 | 表或视图名 |
|
||
| `search_columns` | string[] | | 只取这些列;省略等价于 `*` |
|
||
| `search_condition` | string | | `WHERE` 片段 |
|
||
| `order_by` | string | | 排序,多列逗号分隔 |
|
||
|
||
</G3ApiParams>
|
||
|
||
<G3ApiPayload title="请求体">
|
||
|
||
```json
|
||
{
|
||
"view_name": "v_b_othercompany",
|
||
"search_columns": ["b_id", "b_name", "b_canuse"],
|
||
"search_condition": "b_canuse = 1",
|
||
"order_by": "b_id ASC, b_name DESC"
|
||
}
|
||
```
|
||
|
||
</G3ApiPayload>
|
||
|
||
<G3ApiPayload title="响应" :code="0">
|
||
|
||
```json
|
||
{
|
||
"code": 0,
|
||
"message": "操作成功",
|
||
"data": [{ "b_id": "C001", "b_name": "XX 公司", "b_canuse": 1 }]
|
||
}
|
||
```
|
||
|
||
</G3ApiPayload>
|
||
|
||
> **没有行数上限。** `loaddata` 会把命中的行全部返回;列表页请用 `/data/page`。它的典型用途是取一个小字典(下拉选项)或按主键取单行。
|
||
|
||
## `POST` `/data/page`
|
||
|
||
分页查询。
|
||
|
||
<G3ApiParams>
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|---|---|---|---|
|
||
| `view_name` | string | 是 | 表或视图名 |
|
||
| `order_by` | string | 是 | 分页必须有序(SQL Server 的 `OFFSET / FETCH` 要求) |
|
||
| `search_columns` | string[] | | 只取这些列 |
|
||
| `search_condition` | string | | `WHERE` 片段 |
|
||
| `page_no` | number | | 默认 `1`,从 1 开始 |
|
||
| `page_size` | number | | 默认 `20` |
|
||
|
||
</G3ApiParams>
|
||
|
||
<G3ApiPayload title="请求体">
|
||
|
||
```json
|
||
{
|
||
"view_name": "v_b_othercompany",
|
||
"search_condition": "b_canuse = 1",
|
||
"order_by": "b_id ASC",
|
||
"page_no": 2,
|
||
"page_size": 20
|
||
}
|
||
```
|
||
|
||
</G3ApiPayload>
|
||
|
||
<G3ApiPayload title="响应" :code="0">
|
||
|
||
```json
|
||
{
|
||
"code": 0,
|
||
"message": "操作成功",
|
||
"data": {
|
||
"rows": [{ "b_id": "C021", "b_name": "XX 公司" }],
|
||
"row_count": 20,
|
||
"total": 137,
|
||
"page_no": 2,
|
||
"page_size": 20
|
||
}
|
||
}
|
||
```
|
||
|
||
</G3ApiPayload>
|
||
|
||
<G3ApiParams title="data 字段">
|
||
|
||
| 字段 | 说明 |
|
||
|---|---|
|
||
| `rows` | 当前页数据 |
|
||
| `row_count` | **当前页**的行数(等于 `rows.length`) |
|
||
| `total` | 命中总行数 |
|
||
| `page_no` / `page_size` | 回显请求里的分页参数 |
|
||
|
||
</G3ApiParams>
|
||
|
||
> `row_count` 不是总行数,**总行数是 `total`**。算总页数用 `total`,别用 `row_count`。
|
||
>
|
||
> `page_no` 或 `page_size` 小于 1、或不是整数,都会得到 `1000`(`page_no 必须是大于 0 的整数`)。
|
||
|
||
翻到最后一页之后(`page_no` 超出范围)`rows` 为空,但 `total` 仍然正确 —— 所以判断「没数据」和「翻过了头」要靠 `total`。
|
||
|
||
## `POST` `/data/loaddatabysql`
|
||
|
||
配置表达不出来的复杂只读查询走这里。
|
||
|
||
<G3ApiParams>
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|---|---|---|---|
|
||
| `sql` | string | 是 | 必须以 `SELECT` 或 `WITH` 开头 |
|
||
|
||
</G3ApiParams>
|
||
|
||
<G3ApiPayload title="请求体">
|
||
|
||
```json
|
||
{
|
||
"sql": "SELECT TOP 10 b_id, b_name FROM v_b_othercompany ORDER BY b_id"
|
||
}
|
||
```
|
||
|
||
</G3ApiPayload>
|
||
|
||
<G3ApiPayload title="响应" :code="0">
|
||
|
||
```json
|
||
{
|
||
"code": 0,
|
||
"message": "操作成功",
|
||
"data": [{ "b_id": "C001", "b_name": "XX 公司" }]
|
||
}
|
||
```
|
||
|
||
</G3ApiPayload>
|
||
|
||
被拒的情况(都是 `1000`):不是 `SELECT` / `WITH` 开头、包含 `;`、包含注释(`--` 或 `/* */`)、出现 `insert` `update` `delete` `drop` `truncate` `alter` `exec` `grant` 等关键字。
|
||
|
||
> 判定前会先把**字符串字面量整体掩掉**,所以在 `WHERE b_name = 'insert'` 这类写法里,字面量里的关键字不会误判。反过来也说明:不能在字面量之外藏写操作。
|
||
|
||
## `POST` `/data/nextid`
|
||
|
||
取雪花 ID。
|
||
|
||
<G3ApiParams>
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|---|---|---|---|
|
||
| `count` | number | | 默认 `1`;`<= 1` 时 `data` 是单个 id,否则是数组 |
|
||
|
||
</G3ApiParams>
|
||
|
||
请求体**可以整个省略** —— 不带 body 或传 `{}` 是等价的,`count` 都取默认的 `1`:
|
||
|
||
<G3ApiPayload title="请求体">
|
||
|
||
```json
|
||
{}
|
||
```
|
||
|
||
</G3ApiPayload>
|
||
|
||
<G3ApiPayload title="响应" :code="0">
|
||
|
||
```json
|
||
{
|
||
"code": 0,
|
||
"message": "操作成功",
|
||
"data": "1873456789012345678"
|
||
}
|
||
```
|
||
|
||
</G3ApiPayload>
|
||
|
||
`count: 3` 时:
|
||
|
||
<G3ApiPayload title="响应" :code="0">
|
||
|
||
```json
|
||
{
|
||
"code": 0,
|
||
"message": "操作成功",
|
||
"data": [
|
||
"1873456789012345678",
|
||
"1873456789012345679",
|
||
"1873456789012345680"
|
||
]
|
||
}
|
||
```
|
||
|
||
</G3ApiPayload>
|
||
|
||
> 返回的是**字符串**(见 [快速开始](/api/getting-started) 里的序列化约定),不要转成数字。
|
||
|
||
## `POST` `/data/nextcode`
|
||
|
||
按模块配置的自动编码规则取业务编码(规则来自 `s_autocode`:前缀、日期格式、序号位数、分隔符、重置周期等)。
|
||
|
||
<G3ApiParams>
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|---|---|---|---|
|
||
| `moduleId` | string | 是 | 模块编码(注意是 camelCase 的 `moduleId`) |
|
||
| `count` | number | | 默认 `1`;`<= 1` 时返回单个字符串,否则返回数组 |
|
||
|
||
</G3ApiParams>
|
||
|
||
<G3ApiPayload title="请求体">
|
||
|
||
```json
|
||
{
|
||
"moduleId": "othercompany",
|
||
"count": 1
|
||
}
|
||
```
|
||
|
||
</G3ApiPayload>
|
||
|
||
<G3ApiPayload title="响应" :code="0">
|
||
|
||
```json
|
||
{
|
||
"code": 0,
|
||
"message": "操作成功",
|
||
"data": "HT20261012001"
|
||
}
|
||
```
|
||
|
||
</G3ApiPayload>
|
||
|
||
行为要点:
|
||
|
||
- **会占用号段** —— 服务端取号后立即把序号写回 `s_autocode`,所以连续调用得到的是不同编码。别拿它做「探测一下看看格式」的试调,试出来的号就废了。
|
||
- 生成时会**检查目标表里该编码是否已存在**,已被占用(比如人工插过一条)就自动往后顺延,所以不一定严格等于「当前序号 + 1」。
|
||
- 模块没有配置启用的编码规则、或没配保存表 → `1000`(`当前模块未配置启用的自动编码规则` / `模块未配置保存表,无法生成自动编号`)。
|
||
- 生成的编码超过目标字段长度 → `1000`(`自动编号长度超过目标字段长度`)。
|