fix(dc/tool-c): Fix special character handling and improve UX
Major fixes: - Fix pivot transformation with special characters in column names - Fix compute column validation for Chinese punctuation - Fix recode dialog to fetch unique values from full dataset via new API - Add column mapping mechanism to handle special characters Database migration: - Add column_mapping field to dc_tool_c_sessions table - Migration file: 20251208_add_column_mapping UX improvements: - Darken table grid lines for better visibility - Reduce column width by 40% with tooltip support - Insert new columns next to source columns - Preserve original row order after operations - Add notice about 50-row preview limit Modified files: - Backend: SessionService, SessionController, QuickActionService, routes - Python: pivot.py, compute.py, recode.py, binning.py, conditional.py - Frontend: DataGrid, RecodeDialog, index.tsx, ag-grid-custom.css - Database: schema.prisma, migration SQL Status: Code complete, database migrated, ready for testing
This commit is contained in:
@@ -18,6 +18,12 @@ import * as xlsx from 'xlsx';
|
||||
|
||||
// ==================== 类型定义 ====================
|
||||
|
||||
interface ColumnMapping {
|
||||
originalName: string;
|
||||
safeName: string;
|
||||
displayName: string;
|
||||
}
|
||||
|
||||
interface SessionData {
|
||||
id: string;
|
||||
userId: string;
|
||||
@@ -26,6 +32,7 @@ interface SessionData {
|
||||
totalRows: number;
|
||||
totalCols: number;
|
||||
columns: string[];
|
||||
columnMapping?: ColumnMapping[]; // ✨ 新增:列名映射
|
||||
encoding: string | null;
|
||||
fileSize: number;
|
||||
createdAt: Date;
|
||||
@@ -102,8 +109,12 @@ export class SessionService {
|
||||
const totalRows = data.length;
|
||||
const totalCols = Object.keys(data[0] || {}).length;
|
||||
const columns = Object.keys(data[0] || {});
|
||||
|
||||
// ✨ 生成列名映射(解决特殊字符问题)
|
||||
const columnMapping = this.generateColumnMapping(columns);
|
||||
|
||||
logger.info(`[SessionService] 解析完成: ${totalRows}行 x ${totalCols}列`);
|
||||
logger.info(`[SessionService] 列名映射: ${columnMapping.length}个列`);
|
||||
|
||||
// 4. 上传到OSS(使用平台storage服务)
|
||||
const timestamp = Date.now();
|
||||
@@ -130,6 +141,7 @@ export class SessionService {
|
||||
totalRows,
|
||||
totalCols,
|
||||
columns: columns, // Prisma会自动转换为JSONB
|
||||
columnMapping: JSON.parse(JSON.stringify(columnMapping)), // ✨ 存储列名映射
|
||||
encoding: 'utf-8', // 默认utf-8,后续可扩展检测
|
||||
fileSize: fileBuffer.length,
|
||||
dataStats: JSON.parse(JSON.stringify(dataStats)), // ✨ 存储统计信息(转换为JSON)
|
||||
@@ -370,12 +382,15 @@ export class SessionService {
|
||||
|
||||
// 4. 更新Session元数据
|
||||
const newColumns = Object.keys(processedData[0] || {});
|
||||
const newColumnMapping = this.generateColumnMapping(newColumns); // ✨ 重新生成列名映射
|
||||
|
||||
await prisma.dcToolCSession.update({
|
||||
where: { id: sessionId },
|
||||
data: {
|
||||
totalRows: processedData.length,
|
||||
totalCols: newColumns.length,
|
||||
columns: newColumns,
|
||||
columnMapping: JSON.parse(JSON.stringify(newColumnMapping)), // ✨ 更新列名映射
|
||||
updatedAt: new Date(),
|
||||
},
|
||||
});
|
||||
@@ -517,6 +532,29 @@ export class SessionService {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* ✨ 生成安全的列名映射
|
||||
*
|
||||
* 解决特殊字符问题:表头包含括号、等号等特殊字符会导致Python处理失败
|
||||
*
|
||||
* @param originalColumns - 原始列名数组
|
||||
* @returns 列名映射数组
|
||||
*/
|
||||
private generateColumnMapping(originalColumns: string[]): ColumnMapping[] {
|
||||
return originalColumns.map((originalName, index) => {
|
||||
// 安全列名:col_0, col_1, col_2...
|
||||
const safeName = `col_${index}`;
|
||||
// 显示名称:用于前端展示(保持原始名称)
|
||||
const displayName = originalName;
|
||||
|
||||
return {
|
||||
originalName,
|
||||
safeName,
|
||||
displayName,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测列的数据类型
|
||||
*
|
||||
@@ -571,6 +609,7 @@ export class SessionService {
|
||||
totalRows: session.totalRows,
|
||||
totalCols: session.totalCols,
|
||||
columns: session.columns as string[],
|
||||
columnMapping: session.columnMapping as ColumnMapping[] | undefined, // ✨ 返回列名映射
|
||||
encoding: session.encoding,
|
||||
fileSize: session.fileSize,
|
||||
createdAt: session.createdAt,
|
||||
|
||||
Reference in New Issue
Block a user