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%)
5.6 KiB
5.6 KiB
工具C - Pivot列顺åº<C3A5>优化总结
📋 问题æ<CB9C><C3A6>è¿°
**用户需æ±?*:长宽转æ<C2AC>¢å<C2A2>Žï¼Œåˆ—的排åº<C3A5>åº”è¯¥ä¸Žä¸Šä¼ æ–‡ä»¶æ—¶çš„åˆ—é¡ºåº<C3A5>ä¿<C3A4>æŒ<C3A6>一致ã€?
**当å‰<C3A5>问题**ï¼šç³»ç»ŸæŒ‰å—æ¯<C3A6>顺åº<C3A5>排列转æ<C2AC>¢å<C2A2>Žçš„列,导致顺åº<C3A5>与原文件ä¸<C3A4>一致ã€?
🎯 解决方案:方案A - Python端排�
æ ¸å¿ƒæ€<EFBFBD>è·¯
- Node.jså<73>Žç«¯ä»Žsession获å<C2B7>–*原始列顺åº?
- Node.jså<73>Žç«¯ä»Žæ•°æ<C2B0>®ä¸æ<C2AD><C3A6>å<EFBFBD>–**é€<C3A9>视列值的原始顺åº<C3A5>**(按首次出现顺åº<C3A5>ï¼?
- ä¼ é€’ç»™Python
- Python在pivotå<EFBFBD>Žï¼ŒæŒ‰åŽŸå§‹é¡ºåº<EFBFBD>é‡<EFBFBD>排列
🛠�实现细节
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>逻辑**ï¼?
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模型**�
class PivotRequest(BaseModel):
# ... åŽŸæœ‰å—æ®µ ...
original_column_order: List[str] = [] # �新增
pivot_value_order: List[str] = [] # �新增
调用pivot_long_to_wide�
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>–原始列顺åº?*ï¼?
const originalColumnOrder = session.columns || [];
**获å<C2B7>–é€<C3A9>视列值的原始顺åº<C3A5>**ï¼?
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ï¼?
executeResult = await quickActionService.executePivot(
fullData,
params,
session.columnMapping,
originalColumnOrder, // �新增
pivotValueOrder // �新增
);
4. Node.jså<73>Žç«¯ï¼ˆQuickActionService.tsï¼?
**方法ç¾å<C2BE><C3A5>**ï¼?
async executePivot(
data: any[],
params: PivotParams,
columnMapping?: any[],
originalColumnOrder?: string[], // �新增
pivotValueOrder?: string[] // �新增
): Promise<OperationResult>
ä¼ é€’ç»™Pythonï¼?
const response = await axios.post(`${PYTHON_SERVICE_URL}/api/operations/pivot`, {
// ... 原有å<E280B0>‚æ•° ...
original_column_order: originalColumnOrder || [], // �新增
pivot_value_order: pivotValueOrder || [], // �新增
});
📊 效果对比
修改å‰<EFBFBD>ï¼ˆæŒ‰å—æ¯<EFBFBD>顺åº<EFBFBD>)
Record ID | FMA___基线 | FMA___1个月 | 收缩压___基线 | 收缩压___1个月 | 体é‡<C3A9>___基线 | 体é‡<C3A9>___1个月
� � � � � � �
索引� F开� F开� S开�拼音) S开� T开� T开�
修改å<EFBFBD>Žï¼ˆæŒ‰åŽŸå§‹é¡ºåº<EFBFBD>)
Record ID | FMA___基线 | FMA___1个月 | 体é‡<C3A9>___基线 | 体é‡<C3A9>___1个月 | 收缩压___基线 | 收缩压___1个月
� � � � � � �
索引� 原文件第3� 原文件第3� 原文件第4� 原文件第4� 原文件第5� 原文件第5�
é€<EFBFBD>视值内部顺åº<EFBFBD>(按原始出现顺åº<EFBFBD>)
FMA___基线 | FMA___1个月 | FMA___2个月
� � �
首次出现 第二次出� 第三次出�
(而ä¸<C3A4>是按"1个月"ã€?2个月"ã€?基线"çš„å—æ¯<C3A6>顺åº<C3A5>)
âœ?å¼€å<E282AC>‘完æˆ?
修改文件清å<EFBFBD>•
- �
extraction_service/operations/pivot.py - �
extraction_service/main.py - �
backend/src/modules/dc/tool-c/controllers/QuickActionController.ts - �
backend/src/modules/dc/tool-c/services/QuickActionService.ts
优势
- âœ?列顺åº<C3A5>与原文件一致(用户熟悉ï¼?
- âœ?é€<C3A9>视值顺åº<C3A5>按时间顺åº<C3A5>(基线→1个月â†?个月ï¼?
- âœ?未选择的列也ä¿<C3A4>æŒ<C3A6>原始顺åº?
- âœ?导出Excel时顺åº<C3A5>æ£ç¡?
**å¼€å<E282AC>‘æ—¶é—?*ï¼?025-12-09
**状æ€?*:✅ 已完æˆ<C3A6>,ç‰å¾…测试