Files
AIclinicalresearch/docs/03-业务模块/DC-数据清洗整理/02-技术设计/API设计文档-DC模块(完整版).md
HaHafeng 1b53ab9d52 feat(aia): Complete AIA V2.0 with universal streaming capabilities
Major Changes:
- Add StreamingService with OpenAI Compatible format
- Upgrade Chat component V2 with Ant Design X integration
- Implement AIA module with 12 intelligent agents
- Update API routes to unified /api/v1 prefix
- Update system documentation

Backend (~1300 lines):
- common/streaming: OpenAI Compatible adapter
- modules/aia: 12 agents, conversation service, streaming integration
- Update route versions (RVW, PKB to v1)

Frontend (~3500 lines):
- modules/aia: AgentHub + ChatWorkspace (100% prototype restoration)
- shared/Chat: AIStreamChat, ThinkingBlock, useAIStream Hook
- Update API endpoints to v1

Documentation:
- AIA module status guide
- Universal capabilities catalog
- System overview updates
- All module documentation sync

Tested: Stream response verified, authentication working
Status: AIA V2.0 core completed (85%)
2026-01-14 19:15:01 +08:00

655 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# API霈曇恣<E69B87><E681A3>﹝ - 撌亙<E6928C>B嚗<42><E59A97><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>箏膥鈭綽<E988AD>
> **璅<E79285>**: DC<44>唳旿皜<E697BF><E79A9C><EFBFBD><EFBFBD> - 撌亙<E6928C>B
> **<2A><>𧋦**: V2.0 (MVP)
> **Base URL**: `/api/v1/dc/tool-b`
> **<2A>湔鰵<E6B994><EFBFBD>**: 2025-12-03
> **<2A><EFBFBD>?*: <20>?MVP摰峕<E691B0>嚗?銝服PI蝡舐<E89DA1><E88890><EFBFBD><E588B8>舐鍂嚗<E98D82>歇撉諹<E69289>嚗?
---
## <20><> <20><EFBFBD>
- [<EFBFBD><EFBFBD><EFBFBD>PI璁<EFBFBD><EFBFBD>](#銝<>api璁<69><E79281>)
- [鈭䎚<EFBFBD><EFBFBD>恕霂<EFBFBD><EFBFBD><EFBFBD><EFBFBD>](#鈭諹恕霂<E68195><E99C82><EFBFBD><EFBFBD>)
- [銝剹<EFBFBD><EFBFBD>PI蝡舐<EFBFBD>霂行<EFBFBD>](#銝学pi蝡舐<E89DA1>霂行<E99C82>)
- [<5B><EFBFBD><E49C98><EFBFBD>格芋<E6A0BC>尜(#<23>𥟇㺭<F0A59F87>格芋<E6A0BC>?
- [鈭𢛵<E988AD><F0A29BB5><EFBFBD>霂臬<E99C82><E887AC><EFBFBD>(#鈭娪<EFBFBD>霂臬<EFBFBD><EFBFBD>?
- [<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>](#<23><EFBFBD><EFBFBD><E689AF><EFBFBD><EFBFBD>)
---
## 銝<><E98A9D><EFBFBD>PI璁<49><E79281>
### 1.1 蝡舐<E89DA1><E88890>𡑒”
| # | <20><EFBFBD> | 頝臬<E9A09D> | 霂湔<E99C82> | <20>𡒊垢<F0A1928A><EFBFBD>?| <20>滨垢<E6BBA8><EFBFBD>?| 瘚贝<E7989A><E8B49D><EFBFBD>?|
|---|------|------|------|---------|---------|---------|
| 0 | POST | `/upload` | <20><>辣銝𠹺<E98A9D> | <20>?撌脣<E6928C><E884A3>?| <20>?撌脣笆<E884A3>?| <20>?<3F><EFBFBD> |
| 1 | POST | `/health-check` | <20>亙熒璉<E78692><E79289>?| <20>?撌脣<E6928C><E884A3>?| <20>?撌脣笆<E884A3>?| <20>?<3F><EFBFBD> |
| 2 | GET | `/templates` | <20><EFBFBD>璅⊥踎<E28AA5>𡑒” | <20>?撌脣<E6928C><E884A3>?| <20>?撌脣笆<E884A3>?| <20>?<3F><EFBFBD> |
| 3 | POST | `/tasks` | <20>𥕦遣<F0A595A6>𣂼<EFBFBD>隞餃𦛚 | <20>?撌脣<E6928C><E884A3>?| <20>?撌脣笆<E884A3>?| <20>?<3F><EFBFBD> |
| 4 | GET | `/tasks/:taskId/progress` | <20>亥砭隞餃𦛚餈𥕦漲 | <20>?撌脣<E6928C><E884A3>?| <20>?撌脣笆<E884A3>?| <20>?<3F><EFBFBD> |
| 5 | GET | `/tasks/:taskId/items` | <20><EFBFBD>撉諹<E69289>蝵烐聢<E78390>唳旿 | <20>?撌脣<E6928C><E884A3>?| <20>?撌脣笆<E884A3>?| <20>?<3F><EFBFBD> |
| 6 | POST | `/items/:itemId/resolve` | 鋆<><E98B86><EFBFBD><EFBFBD> | <20>?撌脣<E6928C><E884A3>?| <20>?撌脣笆<E884A3>?| <20>?<3F><EFBFBD> |
| 7 | GET | `/tasks/:taskId/export` | 撖澆枂Excel蝏𤘪<E89D8F> | <20>?撌脣<E6928C><E884A3>?| <20>?撌脣笆<E884A3>?| <20>?<3F><EFBFBD> |
**<EFBFBD>?MVP摰峕<E691B0><E5B395><EFBFBD><E59786><EFBFBD>2025-12-03嚗?*嚗?- <20>𡒊垢隞<E59EA2><E99A9E>嚗鰺2200銵䕘<E98AB5><E49598>俟ervice<63><65>ontroller<65><72>outes嚗?- <20>滨垢隞<E59EA2><E99A9E>嚗鰺1400銵䕘<E98AB5>5甇亙極雿𨀣<E99BBF>摰峕㟲摰䂿緵嚗?- <20>唳旿摨栞”嚗?撘㰘”撌脣<E6928C>撱綽<E692B1>3銝芷<E98A9D>霈暹芋<E69AB9>踹歇撠梁貌
- API撖寞𦻖嚗?銝芰垢<E88AB0><EFBFBD><E5ADB5><EFBFBD><E588B8>𣂼僎瘚贝<E7989A><E8B49D><EFBFBD>
- LLM靚<4D>鍂嚗鋽eepSeek-V3 + Qwen-Max <20>峕芋<E5B395><EFBFBD><EFBFBD><E99C82><EFBFBD>?- <20><EFBFBD>瘚贝<E7989A>嚗?<3F><EFBFBD><E288A0><EFBFBD><EFBFBD><EFBFBD><E6A0BC>𡝗<EFBFBD><F0A19D97><EFBFBD><EFBFBD>Token瘨<6E><E798A8>煫10k
- **撌脩䰻<E884A9><EFBFBD>**嚗?銝芣<E98A9D><E88AA3><EFBFBD>箏𦛚嚗<F0A69B9A><E59A97>`07-<2D><><EFBFBD><EFBFBD>箏𦛚/Tool-B<><42><EFBFBD><EFBFBD>箏𦛚皜<F0A69B9A><E79A9C>.md`嚗?
### 1.2 <20>𡁶鍂閫<E98D82><E996AB>
**霂瑟<E99C82>憭?*嚗?```http
Content-Type: application/json
Authorization: Bearer {token} # <20>芣䔉摰䂿緵
```
**<2A><EFBFBD><E6BB9A><EFBFBD>**嚗?```json
{
"data": {...}, // <20>𣂼<EFBFBD><F0A382BC><EFBFBD><E59789>? "error": "...", // 憭梯揖<E6A2AF><EFBFBD><E59789>? "code": 200
}
```
**HTTP<54><EFBFBD><E59786><EFBFBD>**嚗?- `200`: <20>𣂼<EFBFBD>
- `400`: 霂瑟<E99C82><E7919F><EFBFBD><EFBFBD>躰秤
- `401`: <20>芾恕霂?- `403`: <20><EFBFBD><E4ADBE>?- `404`: 韏<><E99F8F>銝滚<E98A9D><E6BB9A>?- `500`: <20>滚𦛚<E6BB9A><EFBFBD><E585B8><EFBFBD>霂?
---
## 鈭䎚<E988AD><E48E9A>恕霂<E68195><E99C82><EFBFBD><EFBFBD>
### 2.1 霈方<E99C88><E696B9><EFBFBD>
**敶枏<E695B6><E69E8F>嗆挾嚗㇈VP嚗?*嚗?- <20>?<3F><><EFBFBD>摰䂿緵霈方<E99C88>
- 雿輻鍂銝湔𧒄`userId`<60><><EFBFBD><EFBFBD><E59A97>霂瑟<E99C82>銝𠹺<E98A9D><F0A0B9BA><EFBFBD><EFBFBD><EFBFBD>
**<2A>芣䔉摰䂿緵嚗Ā1.0嚗?*嚗?```http
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
```
### 2.2 <20><><EFBFBD><E79285>
| <20><EFBFBD> | <20><><EFBFBD><EFBFBD><E996AC> | 霂湔<E99C82> |
|------|---------|------|
| <20>亙熒璉<E78692><E79289>?| user | <20><><EFBFBD>厩鍂<E58EA9>?|
| <20><EFBFBD>璅⊥踎 | user | <20><><EFBFBD>厩鍂<E58EA9>?|
| <20>𥕦遣隞餃𦛚 | user | <20><><EFBFBD>厩鍂<E58EA9>?|
| <20>亥砭隞餃𦛚 | owner | 隞<><EFBFBD><EFBFBD>撱箄<E692B1>?|
| 鋆<><E98B86><EFBFBD><EFBFBD> | owner | 隞<><EFBFBD><EFBFBD>撱箄<E692B1>?|
---
## 銝剹<E98A9D><E589B9>PI蝡舐<E89DA1>霂行<E99C82>
### 3.1 <20>亙熒璉<E78692><E79289>?
**蝡舐<E89DA1>**: `POST /api/v1/dc/tool-b/health-check`
**<2A><EFBFBD>?*: 璉<><E79289>乍xcel<65><EFBFBD><E39B96>唳旿韐券<E99F90>嚗峕㜃<E5B395><EFBFBD>韐券<E99F90><E588B8>唳旿
**霂瑟<E99C82>雿?*嚗?```json
{
"fileKey": "uploads/user123/data.xlsx",
"columnName": "<22><><EFBFBD><EFBFBD><EFBFBD>𧋦"
}
```
**霂瑟<E99C82><E7919F><EFBFBD>㺭**嚗?
| 摮埈挾 | 蝐餃<E89D90> | 敹<> | 霂湔<E99C82> |
|------|------|------|------|
| `fileKey` | string | <20>?| Storage銝剔<E98A9D><E58994><EFBFBD>辣頝臬<E9A09D> |
| `columnName` | string | <20>?| 閬<><E996AC><EFBFBD><EFBFBD><E4BAA6><EFBFBD> |
**<2A><EFBFBD>**嚗<><E59A97><EFBFBD>?- 200嚗㚁<E59A97>
```json
{
"status": "good",
"emptyRate": 0.12,
"avgLength": 256.8,
"totalRows": 500,
"estimatedTokens": 150000,
"message": "<22>亙熒摨西<E691A8>憟踝<E6869F><EFBFBD>恣瘨<E681A3><E798A8>㛖漲 150.0k Token嚗<6E><E59A97><E79285>蝥?300.0k Token嚗?
}
```
**<2A><EFBFBD>**嚗<>仃韐?- 200雿<30>tatus=bad嚗㚁<E59A97>
```json
{
"status": "bad",
"emptyRate": 0.85,
"avgLength": 256.8,
"totalRows": 500,
"estimatedTokens": 0,
"message": "蝛箏<E89D9B><EFBFBD><EFBFBD><E9A488>嚗?5.0%嚗㚁<E59A97>霂亙<E99C82>銝漤<E98A9D><E6BCA4><EFBFBD><EFBFBD>𣂼<EFBFBD>"
}
```
**<2A><EFBFBD>摮埈挾**嚗?
| 摮埈挾 | 蝐餃<E89D90> | 霂湔<E99C82> |
|------|------|------|
| `status` | string | `good` <20>?`bad` |
| `emptyRate` | number | 蝛箏<E89D9B><EFBFBD> (0-1) |
| `avgLength` | number | 撟喳<E6929F><E596B3><EFBFBD>𧋦<EFBFBD>踹漲 |
| `totalRows` | number | <20><EFBFBD><E9A489>?|
| `estimatedTokens` | number | 憸<>摯Token<65>?|
| `message` | string | <20>鞟內靽⊥<E99DBD> |
**銝𡁜𦛚閫<F0A69B9A><E996AB>**嚗?- 蝛箏<E89D9B><EFBFBD> > 80% <20>?`status = 'bad'`
- 撟喳<E6929F><E596B3>踹漲 < 10 <20>?`status = 'bad'`
- <20><EFBFBD><E88AA3><EFBFBD>100銵䕘<E98AB5><E49598><EFBFBD>隡睃<E99AA1>嚗?
**<2A>躰秤<E8BAB0><EFBFBD>**嚗?```json
{
"error": "<22>?<3F><><EFBFBD><EFBFBD><EFBFBD>𧋦'銝滚<E98A9D><E6BB9A>?,
"code": 400
}
```
---
### 3.2 <20><EFBFBD>璅⊥踎<E28AA5>𡑒”
**蝡舐<E89DA1>**: `GET /api/v1/dc/tool-b/templates`
**<2A><EFBFBD>?*: <20><EFBFBD><E79195><EFBFBD><EFBFBD><EFBFBD>霈曄<E99C88><E69B84>𣂼<EFBFBD>璅⊥踎
**霂瑟<E99C82>**: <20><EFBFBD><E683A9>?
**<2A><EFBFBD>**嚗?00嚗㚁<E59A97>
```json
{
"templates": [
{
"diseaseType": "lung_cancer",
"reportType": "pathology",
"displayName": "<22><EFBFBD><E7AE87><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",
"fields": [
{
"name": "<22><><EFBFBD>蝐餃<E89D90>",
"desc": "憒<><E68692>瘚豢隋<E8B1A2><EFBFBD><E689AF><EFBFBD><E48E9A><EFBFBD><EFBFBD><EFBFBD><E597A5><EFBFBD>",
"width": "w-40"
},
{
"name": "<22><><EFBFBD>蝔见漲",
"desc": "擃?銝?雿𤾸<E99BBF><F0A4BEB8>?,
"width": "w-32"
}
]
},
{
"diseaseType": "diabetes",
"reportType": "admission",
"displayName": "蝟硋倏<E7A18B><E5808F><EFBFBD><EFBFBD>扇敶?,
"fields": [...]
}
]
}
```
**<2A><EFBFBD>摮埈挾**嚗?
| 摮埈挾 | 蝐餃<E89D90> | 霂湔<E99C82> |
|------|------|------|
| `templates` | array | 璅⊥踎<E28AA5>𡑒” |
| `templates[].diseaseType` | string | <20><EFBFBD>蝐餃<E89D90> |
| `templates[].reportType` | string | <20><EFBFBD>蝐餃<E89D90> |
| `templates[].displayName` | string | <20>曄內<E69B84>滨妍 |
| `templates[].fields` | array | <20>𣂼<EFBFBD>摮埈挾<E59F88>滨蔭 |
**蝻枏<E89DBB>蝑𣇉裦**嚗?- 摰<E691B0>蝡舐<E89DA1>摮矋<E691AE>1撠𤩺𧒄
- <20>滚𦛚蝡舐<E89DA1>摮矋<E691AE>瘞訾<E7989E><EFBFBD><EFBFBD><EFBFBD><E59C88><EFBFBD>
---
### 3.3 <20>𥕦遣<F0A595A6>𣂼<EFBFBD>隞餃𦛚
**蝡舐<E89DA1>**: `POST /api/v1/dc/tool-b/tasks`
**<2A><EFBFBD>?*: <20>𥕦遣<F0A595A6><EFBFBD><E5AFA5>𣂼<EFBFBD>隞餃𦛚嚗峕綫<E5B395><E7B6AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
**霂瑟<E99C82>雿?*嚗?```json
{
"projectName": "<22><EFBFBD><E7AE87><EFBFBD><EFBFBD><EFBFBD>唳旿<E594B3>𣂼<EFBFBD>-2025Q1",
"fileKey": "uploads/user123/lung_cancer_pathology.xlsx",
"textColumn": "<22><><EFBFBD><EFBFBD><EFBFBD>𧋦",
"diseaseType": "lung_cancer",
"reportType": "pathology",
"targetFields": [
{
"name": "<22><><EFBFBD>蝐餃<E89D90>",
"desc": "憒<><E68692>瘚豢隋<E8B1A2><EFBFBD><E689AF><EFBFBD><E48E9A><EFBFBD><EFBFBD><EFBFBD><E597A5><EFBFBD>"
},
{
"name": "<22><><EFBFBD>蝔见漲",
"desc": "擃?銝?雿𤾸<E99BBF><F0A4BEB8>?
}
]
}
```
**霂瑟<E99C82><E7919F><EFBFBD>㺭**嚗?
| 摮埈挾 | 蝐餃<E89D90> | 敹<> | 霂湔<E99C82> |
|------|------|------|------|
| `projectName` | string | <20>?| 隞餃𦛚<E9A483>滨妍 |
| `fileKey` | string | <20>?| Storage銝剔<E98A9D><E58994><EFBFBD>辣頝臬<E9A09D> |
| `textColumn` | string | <20>?| <20><>𧋦<EFBFBD><EFBFBD> |
| `diseaseType` | string | <20>?| <20><EFBFBD>蝐餃<E89D90> |
| `reportType` | string | <20>?| <20><EFBFBD>蝐餃<E89D90> |
| `targetFields` | array | <20>?| <20>𣂼<EFBFBD>摮埈挾<E59F88>滨蔭 |
**<2A><EFBFBD>**嚗?00嚗㚁<E59A97>
```json
{
"taskId": "550e8400-e29b-41d4-a716-446655440000"
}
```
**瘚<><E7989A>**嚗?1. 撉諹<E69289><E8ABB9><EFBFBD>辣摮睃銁
2. 閫<><E996AB>Excel嚗𣬚<E59A97>霈⊥<E99C88><EFBFBD><E9A489>?3. <20>𥕦遣隞餃𦛚霈啣<E99C88>嚗ìtatus=pending嚗?4. <20><EFBFBD><E588B8><EFBFBD>BullMQ<4D><EFBFBD>
5. 蝡见朖餈𥪜<E9A488>taskId
**<2A>躰秤<E8BAB0><EFBFBD>**嚗?```json
{
"error": "<22><>辣銝滚<E98A9D><E6BB9A>? uploads/user123/lung_cancer_pathology.xlsx",
"code": 404
}
```
---
### 3.4 <20>亥砭隞餃𦛚餈𥕦漲
**蝡舐<E89DA1>**: `GET /api/v1/dc/tool-b/tasks/:taskId/progress`
**<2A><EFBFBD>?*: 摰墧𧒄<E5A2A7>亥砭隞餃𦛚憭<F0A69B9A><E686AD>餈𥕦漲
**霂瑟<E99C82>**:
```
GET /api/v1/dc/tool-b/tasks/550e8400-e29b-41d4-a716-446655440000/progress
```
**<2A><EFBFBD>**嚗?00嚗㚁<E59A97>
```json
{
"taskId": "550e8400-e29b-41d4-a716-446655440000",
"status": "processing",
"progress": 50,
"totalCount": 500,
"processedCount": 250,
"cleanCount": 200,
"conflictCount": 45,
"failedCount": 5,
"totalTokens": 75000,
"totalCost": 0.135,
"startedAt": "2025-11-27T10:00:00.000Z",
"completedAt": null
}
```
**<2A><EFBFBD>摮埈挾**嚗?
| 摮埈挾 | 蝐餃<E89D90> | 霂湔<E99C82> |
|------|------|------|
| `status` | string | `pending/processing/completed/failed` |
| `progress` | number | 餈𥕦漲<F0A595A6><EFBFBD>瘥?(0-100) |
| `totalCount` | number | <20>餉扇敶閙㺭 |
| `processedCount` | number | 撌脣<E6928C><E884A3><EFBFBD>㺭 |
| `cleanCount` | number | 銝<><E98A9D>渲扇敶閙㺭 |
| `conflictCount` | number | <20><EFBFBD>霈啣<E99C88><E595A3>?|
| `failedCount` | number | 憭梯揖霈啣<E99C88><E595A3>?|
| `totalTokens` | number | 蝝航恣Token<65>?|
| `totalCost` | number | 蝝航恣<E888AA>鞉𧋦($) |
**頧株砭撱箄悅**嚗?- 摰<E691B0>蝡舀<E89DA1>3蝘坿蔭霂<E99C82>甈?- 敶𨦨status = 'completed'`<EFBFBD><EFBFBD>蔭霂?
---
### 3.5 <20><EFBFBD>撉諹<E69289>蝵烐聢<E78390>唳旿
**蝡舐<E89DA1>**: `GET /api/v1/dc/tool-b/tasks/:taskId/items`
**<EFBFBD><EFBFBD>?*: <20><EFBFBD><E79195>峕芋<E5B395>𧢲<EFBFBD><F0A7A2B2>𣇉<EFBFBD><F0A38789><EFBFBD><E9A0A3><EFBFBD>鈭箏極鋆<E6A5B5><E98B86>
**霂瑟<E99C82>**:
```
GET /api/v1/dc/tool-b/tasks/550e8400.../items?page=1&limit=50&status=conflict
```
**<EFBFBD>亥砭<EFBFBD><EFBFBD>㺭**嚗?
| <20><>㺭 | 蝐餃<E89D90> | 敹<> | 暺䁅恕<E48185>?| 霂湔<E99C82> |
|------|------|------|--------|------|
| `page` | number | <20>?| 1 | 憿萇<E686BF> |
| `limit` | number | <20>?| 50 | 瘥誯△<E8AAAF><EFBFBD> |
| `status` | string | <20>?| - | 餈<><EFBFBD><EFBFBD>?|
**<EFBFBD><EFBFBD>**嚗?00嚗㚁<E59A97>
```json
{
"items": [
{
"id": "item-123",
"rowIndex": 5,
"originalText": "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>45撗<35><E69297>霂𦠜鱏銝箸絡瘨行<E798A8><EFBFBD><E689AF><EFBFBD>銝剖<E98A9D><E58996><EFBFBD><E59094>輻𠈔<E8BCBB><F0A08894>憭批<E686AD>3cm...",
"resultA": {
"<22><><EFBFBD>蝐餃<E89D90>": "瘚豢隋<E8B1A2><EFBFBD><E689AF>?,
"<EFBFBD><EFBFBD><EFBFBD>": "<EFBFBD><EFBFBD>?,
"<22>輻𠈔憭批<E686AD>": "3cm"
},
"resultB": {
"<22><><EFBFBD>蝐餃<E89D90>": "瘚豢隋<E8B1A2><EFBFBD><E689AF>?,
"<EFBFBD><EFBFBD><EFBFBD>": "<EFBFBD><EFBFBD>?,
"<22>輻𠈔憭批<E686AD>": "3.0cm"
},
"status": "conflict",
"conflictFields": ["<22>輻𠈔憭批<E686AD>"],
"finalResult": null
}
],
"pagination": {
"total": 45,
"page": 1,
"pageSize": 50,
"totalPages": 1
}
}
```
**<EFBFBD><EFBFBD>摮埈挾**嚗?
| 摮埈挾 | 蝐餃<E89D90> | 霂湔<E99C82> |
|------|------|------|
| `items` | array | 霈啣<E99C88><E595A3>𡑒” |
| `items[].status` | string | `clean/conflict/resolved/failed` |
| `items[].conflictFields` | array | <20><EFBFBD>摮埈挾<E59F88>𡑒” |
| `pagination` | object | <20><>△靽⊥<E99DBD> |
---
### 3.6 鋆<><E98B86><EFBFBD><EFBFBD>
**蝡舐<E89DA1>**: `POST /api/v1/dc/tool-b/items/:itemId/resolve`
**<EFBFBD><EFBFBD>?*: 鈭箏極<E7AE8F>㗇𥋘甇<F0A58B98><EFBFBD><EFBC86><EFBFBD><EFBFBD>𣇉<EFBFBD><F0A38789>?
**霂瑟<E99C82>**:
```json
{
"field": "<22>輻𠈔憭批<E686AD>",
"chosenValue": "3cm"
}
```
**霂瑟<E99C82><E7919F><EFBFBD>㺭**嚗?
| 摮埈挾 | 蝐餃<E89D90> | 敹<> | 霂湔<E99C82> |
|------|------|------|------|
| `field` | string | <20>?| <20><EFBFBD>摮埈挾<E59F88>?|
| `chosenValue` | string | <20>?| <20>㗇𥋘<E39787><F0A58B98><EFBFBD>?|
**<EFBFBD><EFBFBD>**嚗?00嚗㚁<E59A97>
```json
{
"success": true
}
```
**銝𡁜𦛚<F0A1819C><EFBFBD>**嚗?1. <20>湔鰵`finalResult[field] = chosenValue`
2. 隞𥳾conflictFields`銝剔宏<E58994>方砲摮埈挾
3.<><E68692><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E59689>湔鰵`status = 'resolved'`
---
### 3.7 撖澆枂蝏𤘪<E89D8F>
**蝡舐<E89DA1>**: `GET /api/v1/dc/tool-b/tasks/:taskId/export`
**<EFBFBD><EFBFBD>?*: 撖澆枂<E6BE86><E69E82><EFBFBD><E89D8F><EFBFBD>𣇉<EFBFBD><F0A38789>靝蛹Excel
**霂瑟<E99C82>**:
```
GET /api/v1/dc/tool-b/tasks/550e8400.../export?format=xlsx
```
**<EFBFBD>亥砭<EFBFBD><EFBFBD>㺭**嚗?
| <20><>㺭 | 蝐餃<E89D90> | 敹<> | 暺䁅恕<E48185>?| 霂湔<E99C82> |
|------|------|------|--------|------|
| `format` | string | <20>?| `xlsx` | 撖澆枂<E6BE86><EFBFBD>嚗䫤xlsx/csv` |
**<2A><EFBFBD>**嚗?00嚗㚁<E59A97>
- <20><>辣瘚<E8BEA3><E7989A>頧?- Content-Type: `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`
- Content-Disposition: `attachment; filename="extraction_result_2025-11-27.xlsx"`
**撖澆枂<E6BE86><E69E82>捆**嚗?- <20><><EFBFBD><EFBFBD><E7AC94>?+ <20><><EFBFBD><EFBFBD><E39787><EFBFBD>畾?- <20><EFBFBD><E88AB8>冑clean`<EFBFBD>䈣resolved`<60><EFBFBD><E59786><EFBFBD>霈啣<E99C88>
- <20><EFBFBD>霈啣<E99C88>銝滚紡<E6BB9A><EFBFBD><E7B6BD><EFBFBD>鈭箏極鋆<E6A5B5><E98B86>嚗?
---
## <20><EFBFBD><E49C98><EFBFBD>格芋<E6A0BC>?
### 4.1 HealthCheckResult
```typescript
interface HealthCheckResult {
status: 'good' | 'bad';
emptyRate: number;
avgLength: number;
totalRows: number;
estimatedTokens: number;
message: string;
}
```
### 4.2 Template
```typescript
interface Template {
diseaseType: string;
reportType: string;
displayName: string;
fields: TemplateField[];
}
interface TemplateField {
name: string;
desc: string;
width?: string;
}
```
### 4.3 ExtractionTask
```typescript
interface ExtractionTask {
id: string;
userId: string;
projectName: string;
sourceFileKey: string;
textColumn: string;
diseaseType: string;
reportType: string;
targetFields: TemplateField[];
status: 'pending' | 'processing' | 'completed' | 'failed';
totalCount: number;
processedCount: number;
cleanCount: number;
conflictCount: number;
failedCount: number;
totalTokens: number;
totalCost: number;
createdAt: Date;
startedAt?: Date;
completedAt?: Date;
}
```
### 4.4 ExtractionItem
```typescript
interface ExtractionItem {
id: string;
taskId: string;
rowIndex: number;
originalText: string;
resultA?: Record<string, any>;
resultB?: Record<string, any>;
status: 'pending' | 'clean' | 'conflict' | 'resolved' | 'failed';
conflictFields: string[];
finalResult?: Record<string, any>;
tokensA: number;
tokensB: number;
}
```
---
## 鈭𢛵<E988AD><F0A29BB5><EFBFBD>霂臬<E99C82><E887AC>?
### 5.1 <20>躰秤<E8BAB0><EFBFBD><E6BB9A><EFBFBD>
```json
{
"error": "<22>躰秤<E8BAB0>讛膩",
"code": 400,
"details": {
"field": "fileKey",
"reason": "<22><>辣銝滚<E98A9D><E6BB9A>?
}
}
```
### 5.2 撣貉<E692A3><E8B289>躰秤<E8BAB0>?
| HTTP<54><EFBFBD>?| code | 霂湔<E99C82> | 蝷箔<E89DB7> |
|----------|------|------|------|
| 400 | `INVALID_PARAMS` | <20><><EFBFBD>躰秤 | 蝻箏<E89DBB>fileKey |
| 400 | `COLUMN_NOT_FOUND` | <20>𦯀<EFBFBD>摮睃銁 | <20>?<3F><><EFBFBD><EFBFBD><EFBFBD>𧋦"銝滚<E98A9D><E6BB9A>?|
| 400 | `BAD_HEALTH` | <20>亙熒璉<E78692><E79289>交𧊋<E4BAA4><EFBFBD> | 蝛箏<E89D9B><EFBFBD><EFBFBD><E9A488> |
| 404 | `FILE_NOT_FOUND` | <20><>辣銝滚<E98A9D><E6BB9A>?| <20><>辣頝臬<E9A09D><E887AC><EFBFBD> |
| 404 | `TASK_NOT_FOUND` | 隞餃𦛚銝滚<E98A9D><E6BB9A>?| taskId<49><EFBFBD> |
| 403 | `FORBIDDEN` | <20><EFBFBD>霈輸䔮 | <20><EFBFBD>霈輸䔮<E8BCB8>芸楛<E88AB8><E6A59B><EFBFBD>?|
| 500 | `INTERNAL_ERROR` | <20>滚𦛚<E6BB9A><EFBFBD>霂?| <20>唳旿摨栞<E691A8><E6A09E>亙仃韐?|
### 5.3 <20>躰秤憭<E7A7A4><E686AD><EFBFBD><EFBFBD>雿喳<E99BBF>頝?
**摰<E691B0>蝡?*嚗?```typescript
try {
const response = await fetch('/api/v1/dc/tool-b/health-check', {
method: 'POST',
body: JSON.stringify({ fileKey, columnName })
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.error);
}
const data = await response.json();
if (data.status === 'bad') {
alert(data.message); // <20>亙熒璉<E78692><E79289>交𧊋<E4BAA4><EFBFBD>
return;
}
// 蝏抒賒銝衤<E98A9D>甇?} catch (error) {
console.error('<27>亙熒璉<E78692><E79289>亙仃韐?', error);
}
```
---
## <20><EFBFBD><E58786><EFBFBD><EFBFBD><E689AF><EFBFBD><EFBFBD>
### 6.1 <20><EFBFBD><E6BB9A>園𡢿<E59C92><EFBFBD>
| API | <20><EFBFBD> | 霂湔<E99C82> |
|-----|------|------|
| `/health-check` | < 3蝘?| Excel閫<6C><E996AB>+蝏蠘恣 |
| `/templates` | < 100ms | <20><><EFBFBD>蝻枏<E89DBB> |
| `/tasks` (create) | < 500ms | 敹恍<E695B9><EFBFBD>撱箏僎餈𥪜<E9A488> |
| `/tasks/:id/progress` | < 100ms | <20>唳旿摨枏<E691A8><E69E8F>亥砭 |
| `/tasks/:id/items` | < 500ms | <20><><EFBFBD>亥砭 |
| `/items/:id/resolve` | < 200ms | <20><EFBFBD><E99697>湔鰵 |
| `/tasks/:id/export` | < 10蝘?| <20><><EFBFBD>Excel<65><6C>辣 |
### 6.2 撟嗅<E6929F><EFBFBD><E686AD><EFBFBD><EFBFBD>
- **<2A>亙熒璉<E78692><E79289>?*: 10 req/s嚗㇆O撖<4F><E69296>嚗?- **隞餃𦛚<E9A483>𥕦遣**: 5 req/s嚗<73><E59A97><EFBFBD>交㺭<E4BAA4><EFBFBD>嚗?- **餈𥕦漲<F0A595A6>亥砭**: 100 req/s嚗<73>粉撖<E7B289><E69296><EFBFBD>虾蝻枏<E89DBB>嚗?- **撉諹<E69289>蝵烐聢**: 50 req/s嚗<73><E59A97>憿菜䰻霂<E99C82>
### 6.3 隡睃<E99AA1>蝑𣇉裦
**蝻枏<E89DBB>**嚗?- `/templates` <20>?瘞訾<E7989E>蝻枏<E89DBB><EFBFBD><E59A97>摮矋<E691AE>
- `/tasks/:id/progress` <20>?Redis蝻枏<E89DBB>嚗?蝘塬TL嚗?
**撘<>郊憭<E9838A><E686AD>**嚗?- 隞餃𦛚憭<F0A69B9A><E686AD>雿輻鍂BullMQ<4D>𤾸蝱<F0A4BEB8><EFBFBD>
- <20><EFBFBD><E8B8B9><EFBFBD><E9A483><EFBFBD>霂瑟<E99C82>
**<2A><>△**嚗?- 撉諹<E69289>蝵烐聢暺䁅恕50<35>?憿?- <20><>憭?000<30>?憿?
---
## 銝<><E98A9D><EFBFBD><EFBFBD><EFBFBD>祆綉<E7A586>?
### 7.1 API<50><49>𧋦蝑𣇉裦
**敶枏<E695B6><E69E8F><EFBFBD>𧋦**: `v1`
**URL<52><EFBFBD>**: `/api/v1/dc/tool-b/*`
**<2A><EFBFBD><E7A983>澆捆<E6BE86>輯笑**嚗?- v1<76><31>𧋦<EFBFBD>?026撟游<E6929F>靽脲<E99DBD>蝔喳<E89D94>
- <20><EFBFBD><E595A3><EFBFBD><EFBFBD><E69C9E><EFBFBD><EFBFBD><E58CA7>唳溶<E594B3>?- <20><EFBFBD><E6B8B8><EFBFBD><E689B9><EFBFBD><EFBFBD>2
### 7.2 摨笔<E691A8><E7AC94>𡁶䰻
敶𨯗PI<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>𧒄嚗?```http
HTTP/1.1 200 OK
X-API-Deprecated: true
X-API-Sunset: 2026-12-31
X-API-Replacement: /api/v2/dc/tool-b/health-check
```
---
## <20><EFBFBD><E68092><EFBFBD>霂?
### 8.1 Postman Collection
摰峕㟲<EFBFBD><EFBFBD>PI瘚贝<EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?```
docs/03-銝𡁜𦛚璅<E79285>/DC-<2D>唳旿皜<E697BF><E79A9C><EFBFBD><EFBFBD>/02-<2D><><EFBFBD>航挽霈?ToolB-API.postman_collection.json
```
### 8.2 蝷箔<E89DB7>霂瑟<E99C82>
**<2A>亙熒璉<E78692><E79289>?*嚗?```bash
curl -X POST http://localhost:3001/api/v1/dc/tool-b/health-check \
-H "Content-Type: application/json" \
-d '{
"fileKey": "uploads/test.xlsx",
"columnName": "<22><><EFBFBD><EFBFBD><EFBFBD>𧋦"
}'
```
**<2A><EFBFBD>璅⊥踎**嚗?```bash
curl http://localhost:3001/api/v1/dc/tool-b/templates
```
**<2A>𥕦遣隞餃𦛚**嚗?```bash
curl -X POST http://localhost:3001/api/v1/dc/tool-b/tasks \
-H "Content-Type: application/json" \
-d '{
"projectName": "瘚贝<E7989A>隞餃𦛚",
"fileKey": "uploads/test.xlsx",
"textColumn": "<22><><EFBFBD><EFBFBD><EFBFBD>𧋦",
"diseaseType": "lung_cancer",
"reportType": "pathology",
"targetFields": [{"name": "<22><><EFBFBD>蝐餃<E89D90>", "desc": "..."}]
}'
```
---
## 銋腈<E98A8B><E88588><EFBFBD>敶?
### 9.1 <20><EFBFBD><E8A9A8><EFBFBD>
- [<5B>唳旿摨栞挽霈⊥<E99C88>獢β(./<2F>唳旿摨栞挽霈⊥<E99C88>獢?撌亙<E6928C>B.md)
- [PRD<EFBFBD><EFBFBD>](../01-<2D><><EFBFBD><E79899><EFBFBD>?PRD嚗関ool B - <20><><EFBFBD>蝏𤘪<E89D8F><F0A498AA>𡝗㦤<F0A19D97>其犖 (The AI Structurer).md)
- [撘<><E69298>𤏸恣<F0A48FB8>哋(../04-撘<><E69298>𤏸恣<F0A48FB8>?撌亙<E6928C>B撘<42><E69298>𤏸恣<F0A48FB8>?<3F><><EFBFBD>蝏𤘪<E89D8F><F0A498AA>𡝗㦤<F0A19D97>其犖.md)
### 9.2 <20>䀹凒<E480B9><EFBFBD>
| <20><>𧋦 | <20><EFBFBD> | <20>䀹凒<E480B9><E58792>捆 |
|------|------|---------|
| V1.0 | 2025-11-27 | <20><EFBFBD><E598A5><EFBFBD>𧋦嚗?銝服PI蝡舐<E89DA1> |
---
**<EFBFBD><EFBFBD>﹝蝏𤘪<EFBFBD>** <20>?