Files
AIclinicalresearch/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_Pivot列顺序优化总结.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

240 lines
5.6 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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.
# 工具C - Pivot列顺åº<C3A5>ä¼˜åŒæ€»ç»“
## 📋 问题æ<CB9C><C3A6>è¿°
**用户需æ±?*:长宽转æ<C2AC>¢å<C2A2>Žï¼Œåˆ—çš„æŽåº<C3A5>应该与上传æ‡ä»¶æ—¶çš„列顺åº<C3A5>ä¿<C3A4>æŒ<C3A6>一致ã€?
**当å‰<C3A5>问题**:系统按字æ¯<C3A6>顺åº<C3A5>æŽåˆ—转æ<C2AC>¢å<C2A2>Žçš„列,导致顺åº<C3A5>与原æ‡ä»¶ä¸<C3A4>一致ã€?
---
## 🎯 è§£å†³æ¹æ¡ˆï¼šæ¹æ¡ˆA - Python端æŽåº?
### 核心æ€<C3A6>è·¯
1. Node.jså<73>Žç«¯ä»Žsession获å<C2B7>**原始列顺åº?*
2. Node.jså<73>Žç«¯ä»Žæ•°æ<C2B0>®ä¸­æ<C2AD><C3A6>å<EFBFBD>**é€<C3A9>视列值的原å§é¡ºåº<C3A5>**ï¼ˆæŒ‰é¦æ¬¡å‡ºçŽ°é¡ºåº<C3A5>ï¼?
3. ä¼ é€ç»™Python
4. Python在pivotå<74>Žï¼ŒæŒ‰åŽŸå§é¡ºåº<C3A5>é‡<C3A9>æŽåˆ
---
## 🛠�实现细节
### 1. Python端(pivot.py�
**æ°å¢žå<C5BE>æ•°**ï¼?
- `original_column_order: List[str]`:原å§åˆ—顺åº<EFBFBD>(å¦`['Record ID', 'Event Name', 'FMA', '体é‡<C3A9>', '收缩åŽ?, ...]`ï¼?
- `pivot_value_order: List[str]`:é€<EFBFBD>视列值的原å§é¡ºåº<EFBFBD>(å¦`['基线', '1个月', '2个月', ...]`ï¼?
**æŽåº<C3A5>逻è¾**ï¼?
```python
if original_column_order:
# 1. 索引列å§ç»ˆåœ¨æœ€å‰<C3A5>é<EFBFBD>¢
final_cols = [index_column]
# 2. 按原å§åˆ—顺åº<C3A5>添加转æ<C2AC>¢å<C2A2>Žçš„åˆ?
for orig_col in original_column_order:
if orig_col in value_columns:
# 找出所有属于这个原列的新列
related_cols = [c for c in df_pivot.columns if c.startswith(f'{orig_col}___')]
# âœ?按é€<C3A9>视列的原å§é¡ºåº<C3A5>æŽåº<C3A5>
if pivot_value_order:
pivot_order_map = {val: idx for idx, val in enumerate(pivot_value_order)}
related_cols_sorted = sorted(
related_cols,
key=lambda c: pivot_order_map.get(c.split('___')[1], 999)
)
else:
related_cols_sorted = sorted(related_cols)
final_cols.extend(related_cols_sorted)
# 3. 添加未选æ©çš„列(ä¿<C3A4>æŒ<C3A6>原å§é¡ºåº<C3A5>)
if keep_unused_columns:
for orig_col in original_column_order:
if orig_col in df_pivot.columns and orig_col not in final_cols:
final_cols.append(orig_col)
# 4. é‡<C3A9>æŽåˆ?
df_pivot = df_pivot[final_cols]
```
### 2. Python端(main.py�
**PivotRequest模åž**ï¼?
```python
class PivotRequest(BaseModel):
# ... 原有字段 ...
original_column_order: List[str] = [] # �新增
pivot_value_order: List[str] = [] # �新增
```
**调用pivot_long_to_wide**�
```python
result_df = pivot_long_to_wide(
df,
request.index_column,
request.pivot_column,
request.value_columns,
request.aggfunc,
request.column_mapping,
request.keep_unused_columns,
request.unused_agg_method,
request.original_column_order, # �新增
request.pivot_value_order # �新增
)
```
### 3. Node.jså<73>Žç«¯ï¼ˆQuickActionController.tsï¼?
**获å<C2B7>原å§åˆ—顺åº?*ï¼?
```typescript
const originalColumnOrder = session.columns || [];
```
**获å<C2B7>é€<C3A9>视列值的原å§é¡ºåº<C3A5>**ï¼?
```typescript
const pivotColumn = params.pivotColumn;
const seenPivotValues = new Set();
const pivotValueOrder: string[] = [];
for (const row of fullData) {
const pivotValue = row[pivotColumn];
if (pivotValue !== null && pivotValue !== undefined && !seenPivotValues.has(pivotValue)) {
seenPivotValues.add(pivotValue);
pivotValueOrder.push(String(pivotValue));
}
}
```
**ä¼ é€ç»™QuickActionService**ï¼?
```typescript
executeResult = await quickActionService.executePivot(
fullData,
params,
session.columnMapping,
originalColumnOrder, // �新增
pivotValueOrder // �新增
);
```
### 4. Node.jså<73>Žç«¯ï¼ˆQuickActionService.tsï¼?
**æ¹æ³•ç­¾å<C2BE><C3A5>**ï¼?
```typescript
async executePivot(
data: any[],
params: PivotParams,
columnMapping?: any[],
originalColumnOrder?: string[], // �新增
pivotValueOrder?: string[] // �新增
): Promise<OperationResult>
```
**ä¼ é€ç»™Python**ï¼?
```typescript
const response = await axios.post(`${PYTHON_SERVICE_URL}/api/operations/pivot`, {
// ... 原有å<E280B0>æ•° ...
original_column_order: originalColumnOrder || [], // �新增
pivot_value_order: pivotValueOrder || [], // �新增
});
```
---
## 📊 效果对比
### 修改å‰<C3A5>(按字æ¯<C3A6>顺åº<C3A5>)
```
Record ID | FMA___基线 | FMA___1个月 | 收缩åŽ___基线 | 收缩åŽ___1个月 | 体é‡<C3A9>___基线 | 体é‡<C3A9>___1个月
� � � � � � �
索引� F开� F开� S开�拼音) S开� T开� T开�
```
### 修改å<C2B9>Žï¼ˆæŒ‰åŽŸå§é¡ºåº<C3A5>)
```
Record ID | FMA___基线 | FMA___1个月 | 体é‡<C3A9>___基线 | 体é‡<C3A9>___1个月 | 收缩åŽ___基线 | 收缩åŽ___1个月
� � � � � � �
索引åˆ? 原æ‡ä»¶ç¬¬3åˆ? 原æ‡ä»¶ç¬¬3åˆ? 原æ‡ä»¶ç¬¬4åˆ? 原æ‡ä»¶ç¬¬4åˆ? 原æ‡ä»¶ç¬¬5åˆ? 原æ‡ä»¶ç¬¬5åˆ?
```
### é€<C3A9>视值内部顺åº<C3A5>(按原å§å‡ºçŽ°é¡ºåº<C3A5>)
```
FMA___基线 | FMA___1个月 | FMA___2个月
� � �
首次出现 第二次出� 第三次出�
(而ä¸<EFBFBD>是按"1个月"ã€?2个月"ã€?基线"的字æ¯<C3A6>顺åº<C3A5>)
```
---
## âœ?å¼€å<E282AC>完æˆ?
### 修改æ‡ä»¶æ¸…å<E280A6>
1. �`extraction_service/operations/pivot.py`
2. �`extraction_service/main.py`
3. �`backend/src/modules/dc/tool-c/controllers/QuickActionController.ts`
4. �`backend/src/modules/dc/tool-c/services/QuickActionService.ts`
### 优势
- âœ?列顺åº<C3A5>与原æ‡ä»¶ä¸€è‡´ï¼ˆç”¨æˆ·ç†Ÿæ‰ï¼?
- âœ?é€<C3A9>视值顺åº<C3A5>按时间顺åº<C3A5>(基线↸ªæœˆâ†?个月ï¼?
- âœ?未选æ©çš„列也ä¿<C3A4>æŒ<C3A6>原å§é¡ºåº?
- âœ?导出Excel时顺åº<C3A5>æ­£ç¡?
---
**å¼€å<E282AC>æ—¶é—?*ï¼?025-12-09
**状æ€?*:✅ 已完æˆ<C3A6>,等待æµè¯•