依据:同目录
科研开放数据接口功能需求.md。对外只读开放 API;无前端页面、无新表。
| 项 | 说明 |
|---|---|
| 后端 | RuoYi v3.9.2(springboot2 分支):JDK 8、Spring MVC、MyBatis |
| 数据库 | 只读查询既有表 biz_pasture、biz_yak_asset |
| 鉴权 | 独立 JWT + Servlet Filter;@Anonymous 绕过若依登录,Filter 校验 Bearer Token |
| 响应 | OpenApiResponse<T> + OpenApiPageResult<T>(与第三方 farming OpenAPI 同结构) |
代码包:baqing-admin → com.ruoyi.web.modules.industryservice.research
| 类 | 职责 |
|---|---|
ResearchOpenApiController |
HTTP 入口 |
ResearchOpenApiServiceImpl |
分页查询 + 脱敏 VO 转换 |
ResearchOpenApiTokenService |
签发/校验 JWT |
ResearchOpenApiAuthFilter |
除 /auth/token 外校验 Token |
ResearchOpenApiMasking / ResearchOpenApiSupport |
脱敏与响应组装 |
application.yml → research-open-api:
| 键 | 说明 |
|---|---|
enabled |
是否启用;false 时返回 503 |
app-key |
申请 Token 用(全局唯一) |
app-secret |
申请 Token 用 |
token-secret |
JWT 签名密钥(仅服务端,勿下发) |
token-expire-minutes |
Token 有效期,默认 120 |
max-page-size |
单页上限,默认 200 |
示例:
research-open-api:
enabled: true
app-key: research-open-demo-key
app-secret: research-open-demo-secret-change-me
token-secret: research-open-api-change-me-in-production
token-expire-minutes: 120
max-page-size: 200
Base Path:/open-api/v1/research
POST /open-api/v1/research/auth/token
Content-Type: application/json
{"appKey":"research-open-demo-key","appSecret":"research-open-demo-secret-change-me"}
成功响应 data:
{
"accessToken": "eyJhbGciOiJIUzUxMiJ9...",
"tokenType": "Bearer",
"expiresIn": 7200
}
JWT Claims:type=research_open_api;不含机构 ID。
GET /open-api/v1/research/pastures?pageNum=1&pageSize=20&keyword=
Authorization: Bearer <accessToken>
records[] 元素(ResearchPastureVo):
| 字段 | 类型 | 说明 |
|---|---|---|
pastureId |
long | 本地牧场 ID |
pastureName |
string | 牧场名称 |
farmType |
string | 类型 |
county / town |
string | 区县、乡镇 |
regionSummary |
string | 区县+乡镇摘要 |
latitude / longitude |
number | 约百米精度 |
floorArea / scaleBreeding / breedSpecies |
string | 规模类 |
introduction |
string | 简介 |
personInCharge |
string | 脱敏负责人 |
contactPhone |
string | 脱敏手机 |
GET /open-api/v1/research/yak-assets?pageNum=1&pageSize=20&assetStatus=1&gender=母&pastureId=
Authorization: Bearer <accessToken>
records[] 元素(ResearchYakAssetVo):
| 字段 | 类型 | 说明 |
|---|---|---|
subjectCode |
string | 科研主体码,如 YS00000088 |
pastureName / enclosureName |
string | 牧场、圈舍名称 |
gender / cattleVariety |
string | 性别、品种 |
ageMonths |
int | 月龄 |
birthYear / birthMonth |
int | 出生年月 |
assetStatus |
int | 1~4 |
assetStatusLabel |
string | 正常/死淘/丢失/出栏 |
entryWeightKg |
decimal | 入栏体重 |
source / breedingMethod / entryCycle |
string | 来源、养殖方式、周期 |
realtimeTemp / realtimeSteps / envTemp |
number | IoT 快照 |
fatherSubjectCode / motherSubjectCode |
string | 系谱 pseudonym |
ResearchOpenApiController 标注 @Anonymous → Spring Security 放行。ResearchOpenApiAuthFilter 拦截 /open-api/v1/research/*(排除 /auth/token)。Authorization: Bearer …,ResearchOpenApiTokenService.validateToken 验签与过期。{ code:401, message:"..." },HTTP 401。Token 申请:appKey/appSecret 与配置项精确匹配后签发 JWT(HS512 + token-secret)。
复用既有 Service / Mapper:
| 接口 | Service | 表 | 条件 |
|---|---|---|---|
| 牧场列表 | IBizPastureService.selectBizPastureList |
biz_pasture |
del_flag=0 |
| 档案列表 | IBizYakAssetService.selectBizYakAssetList |
biz_yak_asset |
del_flag=0;支持 assetStatus、gender、pastureId |
实体 → VO:ResearchOpenApiSupport.toPastureVo / toYakAssetVo(内部调用 ResearchOpenApiMasking)。
| 方法 | 说明 |
|---|---|
maskPhone |
复用 SubsidyGrantRecordMasking.maskPhone |
maskPersonName |
首字 + * |
regionSummary |
区县 + 乡镇 |
roundCoordinate |
经纬度 3 位小数 |
subjectCode |
YS + 8 位 id |
pseudonymCode |
系谱编号哈希短码 |
| code | HTTP | 场景 |
|---|---|---|
| 200 | 200 | 成功 |
| 401 | 401 | appKey/appSecret 错误、Token 缺失/无效/过期 |
| 400 | 200* | pageSize 超限(body.code=400) |
| 503 | 503 | enabled=false 或未配置凭证 |
* 业务错误仍返回 JSON body,HTTP 状态与 code 一致(Filter 401/503;Controller 内 ServiceException 写入 body.code)。
# 1. 申请 Token
curl -X POST "http://localhost:8010/open-api/v1/research/auth/token" \
-H "Content-Type: application/json" \
-d '{"appKey":"research-open-demo-key","appSecret":"research-open-demo-secret-change-me"}'
# 2. 牧场列表
curl "http://localhost:8010/open-api/v1/research/pastures?pageNum=1&pageSize=10" \
-H "Authorization: Bearer <accessToken>"
# 3. 牦牛档案
curl "http://localhost:8010/open-api/v1/research/yak-assets?pageNum=1&pageSize=10&assetStatus=1" \
-H "Authorization: Bearer <accessToken>"
见同目录 科研开放数据接口测试用例.md。单元测试:
ResearchOpenApiMaskingTestResearchOpenApiTokenServiceTestResearchOpenApiControllerApiTest| 功能需求 | 技术落点 |
|---|---|
| §5 认证 | §2 配置、§4 Filter + TokenService |
| §6.2 牧场 | §3.2、§5 BizPasture |
| §6.3 档案 | §3.3、§5 BizYakAsset |
| §7 脱敏 | §6 Masking |
| §3 不实现机构区分 | 单一 app-key/secret,JWT 无 clientId |
| 版本 | 日期 | 说明 |
|---|---|---|
| 1.0 | 2026-07-04 | 初版:Token + 牧场/档案脱敏列表;全局一对凭证 |