wwh il y a 1 mois
Parent
commit
8257a4b086

+ 9 - 0
doc/产业数据模型及服务/科研开放数据接口/科研开放数据接口功能需求-草稿.md

@@ -0,0 +1,9 @@
1
+为高校、研究机构提供符合规范的脱敏牦牛种群健康、牧场管理等海量科研数据集,助力高原牧业关键技术攻关。
2
+
3
+对外提供数据接口:
4
+1. 提供牧场列表接口
5
+2. 牦牛资产档案列表接口
6
+3. 设计安全的 token 认证,避免未授权访问
7
+4. 符合规范、脱敏
8
+
9
+> 正式需求见同目录 `科研开放数据接口功能需求.md`(v1.0)。

+ 166 - 0
doc/产业数据模型及服务/科研开放数据接口/科研开放数据接口功能需求.md

@@ -0,0 +1,166 @@
1
+# 科研开放数据接口 — 功能需求
2
+
3
+## 1. 文档说明
4
+
5
+| 项 | 说明 |
6
+| --- | --- |
7
+| 模块名称 | 科研开放数据接口 |
8
+| 目标 | 为高校、研究机构提供符合规范的**脱敏**牦牛种群健康、牧场管理等科研数据集,助力高原牧业关键技术攻关 |
9
+| 关联系统 | 对外 HTTP 开放接口(**无**管理后台页面、**无**若依登录) |
10
+| 修订依据 | 产业数据模型及服务建设需求 |
11
+
12
+本文档仅描述**功能需求与业务规则**;接口路径、字段命名、实现细节见同目录 `科研开放数据接口技术方案.md`。
13
+
14
+---
15
+
16
+## 2. 业务背景
17
+
18
+县域牦牛产业数据汇聚于「产业数据模型及服务」模块(牧场管理、牦牛资产档案等)。科研合作方需要**只读**拉取结构化数据,且不得获取可直接识别个人或个体的敏感信息。
19
+
20
+---
21
+
22
+## 3. 功能范围
23
+
24
+**本期实现:**
25
+
26
+| 能力 | 说明 |
27
+| --- | --- |
28
+| 访问令牌 | 使用全局 `appKey` + `appSecret` 申请 Bearer Token |
29
+| 牧场列表 | 分页返回脱敏牧场数据 |
30
+| 牦牛资产档案列表 | 分页返回脱敏档案数据(种群健康研究字段) |
31
+
32
+**本期不实现:**
33
+
34
+- 按机构/高校区分凭证或配额
35
+- 管理后台维护客户端
36
+- 数据导出任务、订阅推送、Webhook
37
+- 明细子表(生理时序、生长曲线等)下钻接口
38
+- 若依用户 JWT 或菜单权限访问本开放接口
39
+
40
+---
41
+
42
+## 4. 访问流程
43
+
44
+```mermaid
45
+sequenceDiagram
46
+    participant Client as 科研调用方
47
+    participant API as 开放接口
48
+    participant DB as 产业数据库
49
+
50
+    Client->>API: POST /auth/token (appKey, appSecret)
51
+    API-->>Client: accessToken (Bearer)
52
+    Client->>API: GET /pastures 或 /yak-assets + Authorization
53
+    API->>DB: 查询 biz_pasture / biz_yak_asset
54
+    API-->>Client: 脱敏分页 JSON
55
+```
56
+
57
+1. 调用方使用配置的 **appKey / appSecret** 申请 Token。  
58
+2. 在 Token 有效期内,请求头携带 `Authorization: Bearer <accessToken>` 访问数据接口。  
59
+3. 服务端返回已脱敏字段;**不区分**具体合作机构。
60
+
61
+---
62
+
63
+## 5. 认证与安全
64
+
65
+| 项 | 要求 |
66
+| --- | --- |
67
+| 凭证 | 全局一对 `app-key` / `app-secret`(`application.yml` 配置) |
68
+| Token | JWT,独立于若依用户登录 Token |
69
+| 有效期 | 默认 120 分钟,可配置 |
70
+| 数据接口 | 除 Token 申请外,**必须**携带有效 Bearer Token,否则 401 |
71
+| 开关 | `research-open-api.enabled=false` 时接口返回 503 |
72
+| 生产 | 须修改默认 `app-key`、`app-secret`、`token-secret` |
73
+
74
+---
75
+
76
+## 6. 数据接口
77
+
78
+**Base Path**:`/open-api/v1/research`
79
+
80
+### 6.1 申请 Token
81
+
82
+| 项 | 说明 |
83
+| --- | --- |
84
+| 方法 | POST |
85
+| 路径 | `/auth/token` |
86
+| 请求体 | `appKey`、`appSecret`(JSON,小驼峰) |
87
+| 响应 | `accessToken`、`tokenType`(Bearer)、`expiresIn`(秒) |
88
+
89
+### 6.2 牧场列表
90
+
91
+| 项 | 说明 |
92
+| --- | --- |
93
+| 方法 | GET |
94
+| 路径 | `/pastures` |
95
+| 鉴权 | Bearer Token |
96
+| 分页 | `pageNum`(默认 1)、`pageSize`(默认 20,最大 200) |
97
+| 筛选 | `keyword`(牧场名称模糊)、`farmType` |
98
+
99
+**返回字段(脱敏后)**:`pastureId`、`pastureName`、`farmType`、`county`、`town`、`regionSummary`、`latitude`、`longitude`(约百米精度)、`floorArea`、`scaleBreeding`、`breedSpecies`、`introduction`、`personInCharge`(脱敏)、`contactPhone`(脱敏)。
100
+
101
+**不返回**:第三方编号、详细门牌地址、同步元数据、操作人等。
102
+
103
+### 6.3 牦牛资产档案列表
104
+
105
+| 项 | 说明 |
106
+| --- | --- |
107
+| 方法 | GET |
108
+| 路径 | `/yak-assets` |
109
+| 鉴权 | Bearer Token |
110
+| 分页 | 同 §6.2 |
111
+| 筛选 | `assetStatus`(1正常 2死淘 3丢失 4出栏)、`gender`(公/母)、`pastureId` |
112
+
113
+**返回字段(脱敏后)**:`subjectCode`(科研主体 pseudonym,替代明文牦牛编号)、`pastureName`、`enclosureName`、`gender`、`cattleVariety`、`ageMonths`、`birthYear`、`birthMonth`、`assetStatus`、`assetStatusLabel`、`entryWeightKg`、`source`、`breedingMethod`、`entryCycle`、`realtimeTemp`、`realtimeSteps`、`envTemp`、`fatherSubjectCode`、`motherSubjectCode`。
114
+
115
+**不返回**:`yakNo`、耳标号、第三方 ID、登记人、照片 URL、精确 GPS、备注等。
116
+
117
+---
118
+
119
+## 7. 脱敏规则摘要
120
+
121
+| 类型 | 规则 |
122
+| --- | --- |
123
+| 手机号 | 保留前 3 + 后 4,中间 `****` |
124
+| 负责人姓名 | 保留首字 + `*` |
125
+| 地址 | 仅区县 + 乡镇摘要,不含详细门牌 |
126
+| 经纬度 | 保留 3 位小数(约百米) |
127
+| 牦牛个体 | `subjectCode = YS` + 8 位本地 ID;系谱用 `YP`/`YM` + 哈希短码 |
128
+| 出生日期 | 仅返回 `birthYear`、`birthMonth` |
129
+
130
+---
131
+
132
+## 8. 响应格式
133
+
134
+统一 envelope(与第三方 OpenAPI 风格一致):
135
+
136
+| 字段 | 说明 |
137
+| --- | --- |
138
+| `code` | 200 成功;401 未授权;400 参数错误;503 未启用 |
139
+| `message` | 提示文案 |
140
+| `requestId` | 请求追踪 ID |
141
+| `data` | 业务数据 |
142
+| `timestamp` | ISO 时间戳 |
143
+
144
+列表类 `data` 为分页对象:`pageNum`、`pageSize`、`total`、`records[]`。
145
+
146
+---
147
+
148
+## 9. 与其他模块关系
149
+
150
+| 模块 | 关系 |
151
+| --- | --- |
152
+| 牧场管理 | 数据源 `biz_pasture` |
153
+| 牦牛资产档案管理 | 数据源 `biz_yak_asset` |
154
+| 若依权限体系 | **无**关联;开放接口走独立 Token |
155
+
156
+---
157
+
158
+## 10. 需求追溯
159
+
160
+| 能力 | 章节 |
161
+| --- | --- |
162
+| Token 认证 | §4、§5、§6.1 |
163
+| 牧场列表 | §6.2、§7 |
164
+| 牦牛档案列表 | §6.3、§7 |
165
+| 脱敏合规 | §7 |
166
+| 本期不实现 | §3 |

+ 222 - 0
doc/产业数据模型及服务/科研开放数据接口/科研开放数据接口技术方案.md

@@ -0,0 +1,222 @@
1
+# 科研开放数据接口 — 技术方案
2
+
3
+> 依据:同目录 `科研开放数据接口功能需求.md`。对外只读开放 API;**无**前端页面、**无**新表。
4
+
5
+---
6
+
7
+## 1. 技术架构
8
+
9
+| 项 | 说明 |
10
+| --- | --- |
11
+| **后端** | RuoYi **v3.9.2**(**springboot2** 分支):JDK 8、Spring MVC、MyBatis |
12
+| **数据库** | 只读查询既有表 `biz_pasture`、`biz_yak_asset` |
13
+| **鉴权** | 独立 JWT + Servlet Filter;`@Anonymous` 绕过若依登录,Filter 校验 Bearer Token |
14
+| **响应** | `OpenApiResponse<T>` + `OpenApiPageResult<T>`(与第三方 farming OpenAPI 同结构) |
15
+
16
+**代码包**:`baqing-admin` → `com.ruoyi.web.modules.industryservice.research`
17
+
18
+| 类 | 职责 |
19
+| --- | --- |
20
+| `ResearchOpenApiController` | HTTP 入口 |
21
+| `ResearchOpenApiServiceImpl` | 分页查询 + 脱敏 VO 转换 |
22
+| `ResearchOpenApiTokenService` | 签发/校验 JWT |
23
+| `ResearchOpenApiAuthFilter` | 除 `/auth/token` 外校验 Token |
24
+| `ResearchOpenApiMasking` / `ResearchOpenApiSupport` | 脱敏与响应组装 |
25
+
26
+---
27
+
28
+## 2. 配置
29
+
30
+`application.yml` → `research-open-api`:
31
+
32
+| 键 | 说明 |
33
+| --- | --- |
34
+| `enabled` | 是否启用;`false` 时返回 503 |
35
+| `app-key` | 申请 Token 用(全局唯一) |
36
+| `app-secret` | 申请 Token 用 |
37
+| `token-secret` | JWT 签名密钥(**仅服务端**,勿下发) |
38
+| `token-expire-minutes` | Token 有效期,默认 120 |
39
+| `max-page-size` | 单页上限,默认 200 |
40
+
41
+**示例:**
42
+
43
+```yaml
44
+research-open-api:
45
+  enabled: true
46
+  app-key: research-open-demo-key
47
+  app-secret: research-open-demo-secret-change-me
48
+  token-secret: research-open-api-change-me-in-production
49
+  token-expire-minutes: 120
50
+  max-page-size: 200
51
+```
52
+
53
+---
54
+
55
+## 3. 接口设计
56
+
57
+**Base Path**:`/open-api/v1/research`
58
+
59
+### 3.1 申请 Token
60
+
61
+```
62
+POST /open-api/v1/research/auth/token
63
+Content-Type: application/json
64
+
65
+{"appKey":"research-open-demo-key","appSecret":"research-open-demo-secret-change-me"}
66
+```
67
+
68
+**成功响应 `data`:**
69
+
70
+```json
71
+{
72
+  "accessToken": "eyJhbGciOiJIUzUxMiJ9...",
73
+  "tokenType": "Bearer",
74
+  "expiresIn": 7200
75
+}
76
+```
77
+
78
+JWT Claims:`type=research_open_api`;**不含**机构 ID。
79
+
80
+### 3.2 牧场列表
81
+
82
+```
83
+GET /open-api/v1/research/pastures?pageNum=1&pageSize=20&keyword=
84
+Authorization: Bearer <accessToken>
85
+```
86
+
87
+**`records[]` 元素(ResearchPastureVo):**
88
+
89
+| 字段 | 类型 | 说明 |
90
+| --- | --- | --- |
91
+| `pastureId` | long | 本地牧场 ID |
92
+| `pastureName` | string | 牧场名称 |
93
+| `farmType` | string | 类型 |
94
+| `county` / `town` | string | 区县、乡镇 |
95
+| `regionSummary` | string | 区县+乡镇摘要 |
96
+| `latitude` / `longitude` | number | 约百米精度 |
97
+| `floorArea` / `scaleBreeding` / `breedSpecies` | string | 规模类 |
98
+| `introduction` | string | 简介 |
99
+| `personInCharge` | string | 脱敏负责人 |
100
+| `contactPhone` | string | 脱敏手机 |
101
+
102
+### 3.3 牦牛资产档案列表
103
+
104
+```
105
+GET /open-api/v1/research/yak-assets?pageNum=1&pageSize=20&assetStatus=1&gender=母&pastureId=
106
+Authorization: Bearer <accessToken>
107
+```
108
+
109
+**`records[]` 元素(ResearchYakAssetVo):**
110
+
111
+| 字段 | 类型 | 说明 |
112
+| --- | --- | --- |
113
+| `subjectCode` | string | 科研主体码,如 `YS00000088` |
114
+| `pastureName` / `enclosureName` | string | 牧场、圈舍名称 |
115
+| `gender` / `cattleVariety` | string | 性别、品种 |
116
+| `ageMonths` | int | 月龄 |
117
+| `birthYear` / `birthMonth` | int | 出生年月 |
118
+| `assetStatus` | int | 1~4 |
119
+| `assetStatusLabel` | string | 正常/死淘/丢失/出栏 |
120
+| `entryWeightKg` | decimal | 入栏体重 |
121
+| `source` / `breedingMethod` / `entryCycle` | string | 来源、养殖方式、周期 |
122
+| `realtimeTemp` / `realtimeSteps` / `envTemp` | number | IoT 快照 |
123
+| `fatherSubjectCode` / `motherSubjectCode` | string | 系谱 pseudonym |
124
+
125
+---
126
+
127
+## 4. 鉴权流程
128
+
129
+1. `ResearchOpenApiController` 标注 `@Anonymous` → Spring Security 放行。  
130
+2. `ResearchOpenApiAuthFilter` 拦截 `/open-api/v1/research/*`(**排除** `/auth/token`)。  
131
+3. 解析 `Authorization: Bearer …`,`ResearchOpenApiTokenService.validateToken` 验签与过期。  
132
+4. 失败返回 JSON `{ code:401, message:"..." }`,HTTP 401。
133
+
134
+Token 申请:`appKey`/`appSecret` 与配置项精确匹配后签发 JWT(HS512 + `token-secret`)。
135
+
136
+---
137
+
138
+## 5. 数据查询
139
+
140
+复用既有 Service / Mapper:
141
+
142
+| 接口 | Service | 表 | 条件 |
143
+| --- | --- | --- | --- |
144
+| 牧场列表 | `IBizPastureService.selectBizPastureList` | `biz_pasture` | `del_flag=0` |
145
+| 档案列表 | `IBizYakAssetService.selectBizYakAssetList` | `biz_yak_asset` | `del_flag=0`;支持 `assetStatus`、`gender`、`pastureId` |
146
+
147
+实体 → VO:`ResearchOpenApiSupport.toPastureVo` / `toYakAssetVo`(内部调用 `ResearchOpenApiMasking`)。
148
+
149
+---
150
+
151
+## 6. 脱敏实现
152
+
153
+| 方法 | 说明 |
154
+| --- | --- |
155
+| `maskPhone` | 复用 `SubsidyGrantRecordMasking.maskPhone` |
156
+| `maskPersonName` | 首字 + `*` |
157
+| `regionSummary` | 区县 + 乡镇 |
158
+| `roundCoordinate` | 经纬度 3 位小数 |
159
+| `subjectCode` | `YS` + 8 位 `id` |
160
+| `pseudonymCode` | 系谱编号哈希短码 |
161
+
162
+---
163
+
164
+## 7. 异常码
165
+
166
+| code | HTTP | 场景 |
167
+| --- | --- | --- |
168
+| 200 | 200 | 成功 |
169
+| 401 | 401 | appKey/appSecret 错误、Token 缺失/无效/过期 |
170
+| 400 | 200* | pageSize 超限(body.code=400) |
171
+| 503 | 503 | `enabled=false` 或未配置凭证 |
172
+
173
+\* 业务错误仍返回 JSON body,HTTP 状态与 `code` 一致(Filter 401/503;Controller 内 ServiceException 写入 body.code)。
174
+
175
+---
176
+
177
+## 8. 调用示例
178
+
179
+```bash
180
+# 1. 申请 Token
181
+curl -X POST "http://localhost:8010/open-api/v1/research/auth/token" \
182
+  -H "Content-Type: application/json" \
183
+  -d '{"appKey":"research-open-demo-key","appSecret":"research-open-demo-secret-change-me"}'
184
+
185
+# 2. 牧场列表
186
+curl "http://localhost:8010/open-api/v1/research/pastures?pageNum=1&pageSize=10" \
187
+  -H "Authorization: Bearer <accessToken>"
188
+
189
+# 3. 牦牛档案
190
+curl "http://localhost:8010/open-api/v1/research/yak-assets?pageNum=1&pageSize=10&assetStatus=1" \
191
+  -H "Authorization: Bearer <accessToken>"
192
+```
193
+
194
+---
195
+
196
+## 9. 测试
197
+
198
+见同目录 `科研开放数据接口测试用例.md`。单元测试:
199
+
200
+- `ResearchOpenApiMaskingTest`
201
+- `ResearchOpenApiTokenServiceTest`
202
+- `ResearchOpenApiControllerApiTest`
203
+
204
+---
205
+
206
+## 10. 需求追溯
207
+
208
+| 功能需求 | 技术落点 |
209
+| --- | --- |
210
+| §5 认证 | **§2** 配置、**§4** Filter + TokenService |
211
+| §6.2 牧场 | **§3.2**、**§5** BizPasture |
212
+| §6.3 档案 | **§3.3**、**§5** BizYakAsset |
213
+| §7 脱敏 | **§6** Masking |
214
+| §3 不实现机构区分 | 单一 app-key/secret,JWT 无 clientId |
215
+
216
+---
217
+
218
+## 11. 修订记录
219
+
220
+| 版本 | 日期 | 说明 |
221
+| --- | --- | --- |
222
+| 1.0 | 2026-07-04 | 初版:Token + 牧场/档案脱敏列表;全局一对凭证 |

+ 77 - 0
doc/产业数据模型及服务/科研开放数据接口/科研开放数据接口测试用例.md

@@ -0,0 +1,77 @@
1
+# 科研开放数据接口 — 测试用例
2
+
3
+> 依据:`科研开放数据接口功能需求.md`、`科研开放数据接口技术方案.md`  
4
+> **Base Path**:`/open-api/v1/research`(默认服务 `http://localhost:8010`)
5
+
6
+**通用前置**:`application.yml` 中 `research-open-api.enabled=true`,且已配置有效的 `app-key` / `app-secret` / `token-secret`。
7
+
8
+**测试凭证(示例,与配置一致)**:
9
+
10
+| 项 | 值 |
11
+| --- | --- |
12
+| appKey | `research-open-demo-key` |
13
+| appSecret | `research-open-demo-secret-change-me` |
14
+
15
+---
16
+
17
+## 一、单元测试用例
18
+
19
+| 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 |
20
+| --- | --- | --- | --- | --- | --- | --- | --- | --- |
21
+| KYKF-UT-001 | 脱敏 | 手机号脱敏 | 单元测试 | JUnit5 | §7 | — | `maskPhone("13812345678")` | `138****5678` |
22
+| KYKF-UT-002 | 脱敏 | 负责人脱敏 | 单元测试 | JUnit5 | §7 | — | `maskPersonName("张三")` | `张*` |
23
+| KYKF-UT-003 | 脱敏 | 牧场 VO 无第三方 ID | 单元测试 | JUnit5 | §6.2 | 构造 BizPasture | `toPastureVo` | 含 `regionSummary`;无 `externalId`、无详细地址 |
24
+| KYKF-UT-004 | 脱敏 | 档案 subjectCode | 单元测试 | JUnit5 | §6.3 | id=88 | `toYakAssetVo` | `subjectCode=YS00000088`;无 `yakNo` |
25
+| KYKF-UT-005 | Token | 合法凭证签发校验 | 单元测试 | JUnit5 | §5 | enabled=true | `issueToken` → `validateToken` | 不抛异常 |
26
+| KYKF-UT-006 | Token | 错误 secret 拒绝 | 单元测试 | JUnit5 | §5 | — | `issueToken(key, wrong)` | 抛 ServiceException 401 |
27
+
28
+---
29
+
30
+## 二、接口测试用例
31
+
32
+| 用例编号 | 测试模块 | 测试项 | 测试类型 | 测试工具 | 测试目的 | 前置条件 | 测试步骤 | 预期结果 |
33
+| --- | --- | --- | --- | --- | --- | --- | --- | --- |
34
+| KYKF-API-001 | 认证 | 申请 Token 成功 | 接口测试 | curl/Postman | §6.1 | enabled=true | POST `/auth/token` 正确 body | `code=200`;`data.accessToken` 非空;`tokenType=Bearer` |
35
+| KYKF-API-002 | 认证 | 错误 appSecret | 接口测试 | curl | §5 | — | POST 错误 secret | `code=401` |
36
+| KYKF-API-003 | 认证 | 未带 Token 访问数据 | 接口测试 | curl | §5 | — | GET `/pastures` 无 Header | HTTP 401;`code=401` |
37
+| KYKF-API-004 | 认证 | 过期/伪造 Token | 接口测试 | curl | §5 | — | GET `/pastures` Bearer 无效串 | HTTP 401 |
38
+| KYKF-API-005 | 牧场 | 分页列表 | 接口测试 | curl | §6.2 | 有效 Token;库有数据 | GET `/pastures?pageNum=1&pageSize=10` | `code=200`;`data.records` 数组;字段符合 ResearchPastureVo |
39
+| KYKF-API-006 | 牧场 | keyword 筛选 | 接口测试 | curl | §6.2 | 已知牧场名 | GET `keyword=片段` | 仅匹配名称的记录 |
40
+| KYKF-API-007 | 档案 | 分页列表 | 接口测试 | curl | §6.3 | 有效 Token | GET `/yak-assets?pageNum=1&pageSize=10` | `code=200`;含 `subjectCode`;无明文编号字段 |
41
+| KYKF-API-008 | 档案 | assetStatus 筛选 | 接口测试 | curl | §6.3 | 有 status=1 数据 | GET `assetStatus=1` | 均为正常状态 |
42
+| KYKF-API-009 | 档案 | pastureId 筛选 | 接口测试 | curl | §6.3 | 已知 pastureId | GET `pastureId=` | 仅该牧场档案 |
43
+| KYKF-API-010 | 分页 | pageSize 超限 | 接口测试 | curl | 技术§2 | — | GET `pageSize=500` | `code=400` |
44
+| KYKF-API-011 | 开关 | enabled=false | 接口测试 | curl | §5 | 关闭 enabled 重启 | POST `/auth/token` | HTTP 503 或 `code=503` |
45
+| KYKF-API-012 | 脱敏 | 响应无敏感原文字段 | 接口测试 | curl | §7 | 库含手机/编号 | GET 两接口 | JSON 无 `yakNo`、`earTagNumber`、`externalId`、`detailAddress` |
46
+
47
+---
48
+
49
+## 三、需求追溯矩阵
50
+
51
+| 功能需求 | 单元 | 接口 |
52
+| --- | --- | --- |
53
+| §5 Token 认证 | UT-005~006 | API-001~004、011 |
54
+| §6.2 牧场列表 | UT-003 | API-005~006 |
55
+| §6.3 档案列表 | UT-004 | API-007~009 |
56
+| §7 脱敏 | UT-001~004 | API-012 |
57
+| §2 分页 | — | API-010 |
58
+| §3 无机构区分 | UT-005 | API-001(单一凭证) |
59
+
60
+**用例统计**:单元 **6**、接口 **12**,合计 **18** 条。
61
+
62
+---
63
+
64
+## 四、Postman / curl 快速脚本
65
+
66
+```bash
67
+BASE=http://localhost:8010/open-api/v1/research
68
+TOKEN=$(curl -s -X POST "$BASE/auth/token" \
69
+  -H "Content-Type: application/json" \
70
+  -d '{"appKey":"research-open-demo-key","appSecret":"research-open-demo-secret-change-me"}' \
71
+  | jq -r '.data.accessToken')
72
+
73
+curl -s "$BASE/pastures?pageNum=1&pageSize=5" -H "Authorization: Bearer $TOKEN"
74
+curl -s "$BASE/yak-assets?pageNum=1&pageSize=5&assetStatus=1" -H "Authorization: Bearer $TOKEN"
75
+```
76
+
77
+(Windows 环境可用 PowerShell `Invoke-RestMethod`,见技术方案 **§8**。)