feat(admin): Add user management and upgrade to module permission system
Features - User Management (Phase 4.1): - Database: Add user_modules table for fine-grained module permissions - Database: Add 4 user permissions (view/create/edit/delete) to role_permissions - Backend: UserService (780 lines) - CRUD with tenant isolation - Backend: UserController + UserRoutes (648 lines) - 13 API endpoints - Backend: Batch import users from Excel - Frontend: UserListPage (412 lines) - list/filter/search/pagination - Frontend: UserFormPage (341 lines) - create/edit with module config - Frontend: UserDetailPage (393 lines) - details/tenant/module management - Frontend: 3 modal components (592 lines) - import/assign/configure - API: GET/POST/PUT/DELETE /api/admin/users/* endpoints Architecture Upgrade - Module Permission System: - Backend: Add getUserModules() method in auth.service - Backend: Login API returns modules array in user object - Frontend: AuthContext adds hasModule() method - Frontend: Navigation filters modules based on user.modules - Frontend: RouteGuard checks requiredModule instead of requiredVersion - Frontend: Remove deprecated version-based permission system - UX: Only show accessible modules in navigation (clean UI) - UX: Smart redirect after login (avoid 403 for regular users) Fixes: - Fix UTF-8 encoding corruption in ~100 docs files - Fix pageSize type conversion in userService (String to Number) - Fix authUser undefined error in TopNavigation - Fix login redirect logic with role-based access check - Update Git commit guidelines v1.2 with UTF-8 safety rules Database Changes: - CREATE TABLE user_modules (user_id, tenant_id, module_code, is_enabled) - ADD UNIQUE CONSTRAINT (user_id, tenant_id, module_code) - INSERT 4 permissions + role assignments - UPDATE PUBLIC tenant with 8 module subscriptions Technical: - Backend: 5 new files (~2400 lines) - Frontend: 10 new files (~2500 lines) - Docs: 1 development record + 2 status updates + 1 guideline update - Total: ~4900 lines of code Status: User management 100% complete, module permission system operational
This commit is contained in:
@@ -1,46 +1,46 @@
|
||||
# 工具C - Bug修复与优化总结
|
||||
|
||||
**修复日期**: 2025-12-08
|
||||
**菫ョ螟堺コ?*: AI Assistant
|
||||
**菫ョ螟崎激蝗エ**: 7荳ェ荳・驥埼琉鬚?+ 5荳ェ菴馴ェ御シ伜<EFBDBC>?
|
||||
**修复人**: AI Assistant
|
||||
**修复范围**: 7个严重问题 + 5个体验优化
|
||||
|
||||
---
|
||||
|
||||
## 📋 修复清单
|
||||
|
||||
### 笨?髣ョ鬚<EFBDAE>1<EFBFBD>夊。ィ螟エ迚ケ谿雁ュ礼ャヲ蟇シ閾エ蜉溯<E89C89>蠑ょク?
|
||||
### ✅ 问题1:表头特殊字符导致功能异常
|
||||
|
||||
#### 1-1. Pivot霓ャ謐「蜿ェ譛<EFBFBD>1蛻?<3F>閥 **蟾イ菫ョ螟?*
|
||||
#### 1-1. Pivot转换只有1列 🔴 **已修复**
|
||||
|
||||
**问题描述**:
|
||||
- 陦ィ螟エ蛹<EFBFBD>性諡ャ蜿キ縲∫ュ牙捷遲臥音谿雁ュ礼ャヲ<EFBFBD>亥ヲA菴馴㍾<EFBFBD><EFBFBD>g<EFBFBD>荏縲~1.鬮倩。蜴狗羅<E78B97>域裏=0<>梧怏=1<>荏<EFBFBD>?
|
||||
- 蟇シ閾エPivot霓ャ謐「譌カ蛻怜錐螟<EFBFBD>炊螟ア雍・<EFBFBD>悟宵逕滓<EFBFBD>?蛻苓御ク肴弍謖蛾剰ァ<E589B0><EFBDA7>螻募シ
|
||||
- 表头包含括号、等号等特殊字符(如`体重(kg)`、`1.高血压病(无=0,有=1)`)
|
||||
- 导致Pivot转换时列名处理失败,只生成1列而不是按透视列展开
|
||||
|
||||
**根本原因**:
|
||||
- Python的`pivot_table`列名展平逻辑无法处理特殊字符
|
||||
|
||||
**解决方案**:
|
||||
```python
|
||||
# 譁<EFBFBD>サカ: extraction_service/operations/pivot.py (73-95陦?
|
||||
# 蠅槫シコ蛻怜錐螻募ケウ騾サ霎托シ梧ク<EFBFBD>炊迚ケ谿雁ュ礼ャ?
|
||||
# 文件: extraction_service/operations/pivot.py (73-95行)
|
||||
# 增强列名展平逻辑,清理特殊字符
|
||||
if len(value_columns) == 1:
|
||||
value_col_clean = str(value_columns[0]).replace('(', '').replace(')', '').strip()
|
||||
df_pivot.columns = [f'{value_col_clean}___{str(col).replace(" ", "_")}' for col in df_pivot.columns]
|
||||
```
|
||||
|
||||
#### 1-2. 隶。邂怜<EFBFBD>蜉溯<EFBFBD>謚・髞?<3F>閥 **蟾イ菫ョ螟?*
|
||||
#### 1-2. 计算列功能报错 🔴 **已修复**
|
||||
|
||||
**问题描述**:
|
||||
- 轤ケ蜃サ"謇ァ陦瑚ョ。邂<EFBDA1>"謚・髞呻シ?蜈ャ蠑丞桁蜷ォ荳榊<E88DB3>隶ク逧<EFBDB8>ュ礼ャヲ"
|
||||
- 点击"执行计算"报错:"公式包含不允许的字符"
|
||||
- 无法使用包含中文括号、等号、冒号的列名
|
||||
|
||||
**根本原因**:
|
||||
- `compute.py`逧<EFBFBD>ュ」蛻咎ェ瑚ッ∬ソ<EFBFBD>コ惹ク・譬シ<EFBFBD>悟宵蜈∬ョク闍ア譁<EFBFBD>峡蜿?
|
||||
- `compute.py`的正则验证过于严格,只允许英文括号
|
||||
|
||||
**解决方案**:
|
||||
```python
|
||||
# 譁<EFBFBD>サカ: extraction_service/operations/compute.py (63-67陦?
|
||||
# 1. 謾セ螳ス蟄礼ャヲ鬪瑚ッ<EFBFBD>シ梧髪謖∽クュ譁<EFBFBD>峡蜿キ縲∫ュ牙捷縲∝<EFBFBD>蜿?
|
||||
# 文件: extraction_service/operations/compute.py (63-67行)
|
||||
# 1. 放宽字符验证,支持中文括号、等号、冒号
|
||||
allowed_chars = r'[a-zA-Z0-9_\u4e00-\u9fa5\s\+\-\*/\(\)\[\]\{\}\.,:\*\*=()【】、。:;!?]'
|
||||
|
||||
# 2. 使用列名映射,将特殊字符列名替换为安全变量名
|
||||
@@ -52,29 +52,29 @@ for i, col in enumerate(result.columns):
|
||||
|
||||
---
|
||||
|
||||
### 笨?髣ョ鬚<EFBDAE>2<EFBFBD>壽焚蛟シ譏<EFBDBC>蟆<EFBFBD>宵謠仙叙1荳ェ蜚ッ荳蛟?<3F>閥 **蟾イ菫ョ螟?*
|
||||
### ✅ 问题2:数值映射只提取1个唯一值 🔴 **已修复**
|
||||
|
||||
#### 2-1. 蟀壼ァサ迥カ蜀オ蜿ェ譏セ遉?荳ェ蛟シ<E89B9F>亥ョ樣刔譛?遘搾シ解沐エ **蟾イ菫ョ螟?*
|
||||
#### 2-1. 婚姻状况只显示1个值(实际有4种)🔴 **已修复**
|
||||
|
||||
**问题描述**:
|
||||
- 騾画叫"蟀壼ァサ迥カ蜀オ"蛻玲慮<E78EB2>悟宵謠仙叙蛻?荳ェ蜚ッ荳蛟?
|
||||
- 螳樣刔謨ー謐ョ譛?遘搾シ壼キイ蟀壹∵悴蟀壹∝<C280>莉悶?遨コ逋ス)
|
||||
- 选择"婚姻状况"列时,只提取到1个唯一值
|
||||
- 实际数据有4种:已婚、未婚、其他、(空白)
|
||||
|
||||
**根本原因**:
|
||||
- 蜑咲ォッ莉餐data`謨ー扈<EFBDB0>署蜿門髪荳蛟シ<E89B9F>御ス<E5BEA1>data`蜿ェ譛牙<EFBFBD>?0陦?
|
||||
- 螳梧紛謨ー謐ョ譛?668陦鯉シ悟ゥ壼ァサ迥カ蜀オ逧<EFBDB5><E980A7>蟶<EFBFBD>ク榊<EFBDB8>?
|
||||
- 前端从`data`数组提取唯一值,但`data`只有前50行
|
||||
- 完整数据有3668行,婚姻状况的分布不均
|
||||
|
||||
**解决方案**:
|
||||
```typescript
|
||||
// 譁<EFBFBD>サカ: frontend-v2/src/modules/dc/pages/tool-c/components/RecodeDialog.tsx (45-72陦?
|
||||
// 隹<EFBFBD>畑蜷守ォッAPI莉主ョ梧紛謨ー謐ョ荳ュ謠仙叙蜚ッ荳蛟?
|
||||
// 文件: frontend-v2/src/modules/dc/pages/tool-c/components/RecodeDialog.tsx (45-72行)
|
||||
// 调用后端API从完整数据中提取唯一值
|
||||
const response = await fetch(
|
||||
`/api/v1/dc/tool-c/sessions/${sessionId}/unique-values?column=${encodeURIComponent(selectedColumn)}`
|
||||
);
|
||||
```
|
||||
|
||||
```typescript
|
||||
// 譁ー蠅暸PI: backend/src/modules/dc/tool-c/controllers/SessionController.ts (366-428陦?
|
||||
// 新增API: backend/src/modules/dc/tool-c/controllers/SessionController.ts (366-428行)
|
||||
// GET /api/v1/dc/tool-c/sessions/:id/unique-values?column=xxx
|
||||
async getUniqueValues(...) {
|
||||
const data = await sessionService.getFullData(id);
|
||||
@@ -85,50 +85,50 @@ async getUniqueValues(...) {
|
||||
}
|
||||
```
|
||||
|
||||
#### 2-2. 遐皮ゥカ荳ュ蠢<EFBFBD>シ壼宵譏セ遉コ1荳ェ蛟シ<EFBFBD>亥ョ樣刔譛?遘搾シ解沐エ **蟾イ菫ョ螟?*
|
||||
#### 2-2. 研究中心:只显示1个值(实际有4种)🔴 **已修复**
|
||||
|
||||
蜷御ク奇シ御スソ逕ィ逶ク蜷瑚ァ」蜀ウ譁ケ譯医?
|
||||
同上,使用相同解决方案。
|
||||
|
||||
---
|
||||
|
||||
### 笨?菴馴ェ御シ伜喧<E4BC9C>?鬘ケ<E9AC98><EFBDB9>
|
||||
### ✅ 体验优化(5项)
|
||||
|
||||
#### 笨?莨伜喧1<E596A7>夊。ィ譬シ郤ソ譯<EFBDBF>「懆牡蜉<E789A1>豺?笞?**蟾イ螳梧<E89EB3>?*
|
||||
#### ✅ 优化1:表格线框颜色加深 ⚪ **已完成**
|
||||
|
||||
**髴豎?*: 郤ソ譯<EFBDBF>、ェ豺。<E8B1BA>檎恚荳肴ク<E882B4>・?
|
||||
**需求**: 线框太淡,看不清楚
|
||||
|
||||
**修改**:
|
||||
```css
|
||||
/* 譁<EFBFBD>サカ: frontend-v2/src/modules/dc/pages/tool-c/components/ag-grid-custom.css (24-26陦? */
|
||||
--ag-border-color: #d1d5db; /* 蜴?e5e7eb -> #d1d5db */
|
||||
--ag-row-border-color: #e5e7eb; /* 蜴?f1f5f9 -> #e5e7eb */
|
||||
/* 文件: frontend-v2/src/modules/dc/pages/tool-c/components/ag-grid-custom.css (24-26行) */
|
||||
--ag-border-color: #d1d5db; /* 原#e5e7eb -> #d1d5db */
|
||||
--ag-row-border-color: #e5e7eb; /* 原#f1f5f9 -> #e5e7eb */
|
||||
border-bottom: 2px solid #d1d5db; /* 表头底部边框加深 */
|
||||
```
|
||||
|
||||
#### 笨?莨伜喧2<E596A7>夊。ィ螟エ螳ス蠎ヲ蜃丞ー?0% + Tooltip 笞?**蟾イ螳梧<E89EB3>?*
|
||||
#### ✅ 优化2:表头宽度减小40% + Tooltip ⚪ **已完成**
|
||||
|
||||
**髴豎?*: 蛻怜ョス螟ェ螟ァ<E89E9F>悟酔荳螻乗裏豕墓仞遉コ螟ェ螟壼<E89E9F>
|
||||
**需求**: 列宽太大,同一屏无法显示太多列
|
||||
|
||||
**修改**:
|
||||
```typescript
|
||||
// 譁<EFBFBD>サカ: frontend-v2/src/modules/dc/pages/tool-c/components/DataGrid.tsx (32-53陦?
|
||||
// 文件: frontend-v2/src/modules/dc/pages/tool-c/components/DataGrid.tsx (32-53行)
|
||||
{
|
||||
headerName: col.name,
|
||||
headerTooltip: col.name, // 笨?鮠<>譬<EFBFBD>ぎ蛛懈仞遉コ螳梧紛蛻怜錐
|
||||
width: 90, // 笨?蜴?50 -> 90<EFBFBD>亥㍼蟆?0%<25>?
|
||||
minWidth: 60, // 笨?蜴?00 -> 60
|
||||
headerTooltip: col.name, // ✅ 鼠标悬停显示完整列名
|
||||
width: 90, // ✅ 原150 -> 90(减少40%)
|
||||
minWidth: 60, // ✅ 原100 -> 60
|
||||
}
|
||||
```
|
||||
|
||||
#### 笨?莨伜喧3<E596A7>壽眠蛻玲仞遉コ蝨ィ蜴溷<E89CB4>譌∬セケ 笞?**蟾イ螳梧<E89EB3>?*
|
||||
#### ✅ 优化3:新列显示在原列旁边 ⚪ **已完成**
|
||||
|
||||
**髴豎?*: 逕滓<E98095>譁ー蛻玲慮<E78EB2>悟ク梧悍邏ァ驍サ蜴溷<E89CB4><E6BAB7>梧婿萓ソ蟇ケ豈?
|
||||
**需求**: 生成新列时,希望紧邻原列,方便对比
|
||||
|
||||
**修改**:
|
||||
- `binning.py` (139-148陦?: 蛻<>サ<EFBFBD><EFBDBB>謠貞<E8ACA0>蛻ー蜴溷<E89CB4>譌∬セケ
|
||||
- `recode.py` (56-63陦?: 郛也<E9839B>∝<EFBFBD>謠貞<E8ACA0>蛻ー蜴溷<E89CB4>譌∬セケ
|
||||
- `compute.py` (149-161陦?: 隶。邂怜<E98282>謠貞<E8ACA0>蛻ー隨ャ荳荳ェ蠑慕畑蛻玲浴霎ケ
|
||||
- `conditional.py` (131-139陦?: 譚。莉カ蛻玲薯蜈・蛻ー蜿り<E3828A><C280>譌∬セケ
|
||||
- `binning.py` (139-148行): 分组列插入到原列旁边
|
||||
- `recode.py` (56-63行): 编码列插入到原列旁边
|
||||
- `compute.py` (149-161行): 计算列插入到第一个引用列旁边
|
||||
- `conditional.py` (131-139行): 条件列插入到参考列旁边
|
||||
|
||||
```python
|
||||
# 示例: binning.py
|
||||
@@ -139,13 +139,13 @@ cols.insert(original_col_index + 1, new_column_name)
|
||||
result = result[cols]
|
||||
```
|
||||
|
||||
#### 笨?莨伜喧4<E596A7>壻ソ晄戟蜴溷ァ玖。碁。コ蠎<EFBDBA> 笞?**蟾イ螳梧<E89EB3>?*
|
||||
#### ✅ 优化4:保持原始行顺序 ⚪ **已完成**
|
||||
|
||||
**髴豎?*: 謨ー謐ョ螟<EFBDAE>炊蜷趣シ瑚。碁。コ蠎剰ヲ∽ソ晄戟荳主次Excel荳閾?
|
||||
**需求**: 数据处理后,行顺序要保持与原Excel一致
|
||||
|
||||
**修改**:
|
||||
```python
|
||||
# 譁<EFBFBD>サカ: extraction_service/operations/pivot.py (90-97陦?
|
||||
# 文件: extraction_service/operations/pivot.py (90-97行)
|
||||
# Pivot后按原始顺序排序
|
||||
original_order = result[index_column].drop_duplicates().tolist()
|
||||
order_map = {val: idx for idx, val in enumerate(original_order)}
|
||||
@@ -153,51 +153,51 @@ df_pivot['_sort_order'] = df_pivot[index_column].map(order_map)
|
||||
df_pivot = df_pivot.sort_values('_sort_order').drop(columns=['_sort_order'])
|
||||
```
|
||||
|
||||
#### 笨?莨伜喧5<E596A7>壽署遉コ蜿ェ譏セ遉コ蜑?0陦?笞?**蟾イ螳梧<E89EB3>?*
|
||||
#### ✅ 优化5:提示只显示前50行 ⚪ **已完成**
|
||||
|
||||
**髴豎?*: 逕ィ謌キ諡<EFBDB7>ソ<EFBFBD>焚謐ョ螟<EFBDAE>炊譌カ謨ー謐ョ荳「螟?
|
||||
**需求**: 用户担心数据处理时数据丢失
|
||||
|
||||
**修改**:
|
||||
```typescript
|
||||
// 譁<EFBFBD>サカ: frontend-v2/src/modules/dc/pages/tool-c/index.tsx (256-264陦?
|
||||
// 文件: frontend-v2/src/modules/dc/pages/tool-c/index.tsx (256-264行)
|
||||
<div className="mb-2 px-3 py-2 bg-blue-50 border border-blue-200 rounded-lg">
|
||||
<strong>謠千、コ<EFBFBD>?/strong>陦ィ譬シ莉<EFBFBD>ア慕、コ蜑<EFBFBD> <strong>50陦?/strong> 謨ー謐ョ鬚<EFBFBD>ァ茨シ?
|
||||
蟇シ蜃コ蜉溯<EFBFBD>蟆<EFBFBD>桁蜷?<strong>蜈ィ驛ィ</strong> 螟<EFBFBD>炊扈捺棡
|
||||
<strong>提示:</strong>表格仅展示前 <strong>50行</strong> 数据预览,
|
||||
导出功能将包含 <strong>全部</strong> 处理结果
|
||||
</div>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD>女<EFBFBD>?譫カ譫<EFBDB6>合郤ァ<E983A4>壼<EFBFBD>蜷肴<E89CB7><E882B4>㊥蛹匁惻蛻カ
|
||||
## 🏗️ 架构升级:列名标准化机制
|
||||
|
||||
荳コ蠖サ蠎戊ァ」蜀ウ迚ケ谿雁ュ礼ャヲ髣ョ鬚假シ悟シ募<EFBFBD>莠?*蛻怜錐譏<E98C90>蟆<EFBFBD>**譛コ蛻カ<E89BBB>?
|
||||
为彻底解决特殊字符问题,引入了**列名映射**机制:
|
||||
|
||||
### 新增字段: `columnMapping`
|
||||
|
||||
```typescript
|
||||
// backend/src/modules/dc/tool-c/services/SessionService.ts (21-24陦?
|
||||
// backend/src/modules/dc/tool-c/services/SessionService.ts (21-24行)
|
||||
interface ColumnMapping {
|
||||
originalName: string; // 蜴溷ァ句<EFBFBD>蜷搾シ壻ス馴㍾<EFBFBD><EFBFBD>g<EFBFBD>?
|
||||
originalName: string; // 原始列名:体重(kg)
|
||||
safeName: string; // 安全列名:col_5
|
||||
displayName: string; // 譏セ遉コ蜷咲ァー<EFBFBD>壻ス馴㍾<EFBFBD><EFBFBD>g<EFBFBD>?
|
||||
displayName: string; // 显示名称:体重(kg)
|
||||
}
|
||||
```
|
||||
|
||||
### 数据库Schema变更
|
||||
|
||||
```prisma
|
||||
// backend/prisma/schema.prisma (864陦?
|
||||
// backend/prisma/schema.prisma (864行)
|
||||
model DcToolCSession {
|
||||
// ...
|
||||
columnMapping Json? @map("column_mapping") // 笨?譁ー蠅槫ュ玲ョオ
|
||||
columnMapping Json? @map("column_mapping") // ✨ 新增字段
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Session蛻帛サコ譌カ閾ェ蜉ィ逕滓<EFBFBD>譏<EFBFBD>蟆?
|
||||
### Session创建时自动生成映射
|
||||
|
||||
```typescript
|
||||
// SessionService.ts (520-535陦?
|
||||
// SessionService.ts (520-535行)
|
||||
private generateColumnMapping(originalColumns: string[]): ColumnMapping[] {
|
||||
return originalColumns.map((originalName, index) => ({
|
||||
originalName,
|
||||
@@ -211,29 +211,29 @@ private generateColumnMapping(originalColumns: string[]): ColumnMapping[] {
|
||||
|
||||
## 📦 修改文件清单
|
||||
|
||||
### 蜷守ォッ (5荳ェ譁<EFBDAA>サ?
|
||||
### 后端 (5个文件)
|
||||
|
||||
1. 笨?`backend/prisma/schema.prisma` - 譁ー蠅枋olumnMapping蟄玲ョオ
|
||||
2. 笨?`backend/src/modules/dc/tool-c/services/SessionService.ts` - 蛻怜錐譏<EFBFBD>蟆<EFBFBD>函謌<EFBFBD>
|
||||
3. 笨?`backend/src/modules/dc/tool-c/controllers/SessionController.ts` - 譁ー蠅櫁執蜿門髪荳蛟シAPI
|
||||
4. 笨?`backend/src/modules/dc/tool-c/routes/index.ts` - 譁ー蠅櫁キッ逕ア
|
||||
1. ✅ `backend/prisma/schema.prisma` - 新增columnMapping字段
|
||||
2. ✅ `backend/src/modules/dc/tool-c/services/SessionService.ts` - 列名映射生成
|
||||
3. ✅ `backend/src/modules/dc/tool-c/controllers/SessionController.ts` - 新增获取唯一值API
|
||||
4. ✅ `backend/src/modules/dc/tool-c/routes/index.ts` - 新增路由
|
||||
|
||||
### Python譛榊苅 (5荳ェ譁<EFBDAA>サ?
|
||||
### Python服务 (5个文件)
|
||||
|
||||
5. 笨?`extraction_service/operations/pivot.py` - 蠅槫シコ蛻怜錐螟<EFBFBD>炊 + 菫晄戟陦碁。コ蠎?
|
||||
6. 笨?`extraction_service/operations/compute.py` - 謾セ螳ス蟄礼ャヲ鬪瑚ッ<EFBFBD> + 蛻怜錐譏<E98C90>蟆<EFBFBD>
|
||||
7. 笨?`extraction_service/operations/recode.py` - 譁ー蛻玲薯蜈・菴咲スョ
|
||||
8. 笨?`extraction_service/operations/binning.py` - 譁ー蛻玲薯蜈・菴咲スョ
|
||||
9. 笨?`extraction_service/operations/conditional.py` - 譁ー蛻玲薯蜈・菴咲スョ
|
||||
5. ✅ `extraction_service/operations/pivot.py` - 增强列名处理 + 保持行顺序
|
||||
6. ✅ `extraction_service/operations/compute.py` - 放宽字符验证 + 列名映射
|
||||
7. ✅ `extraction_service/operations/recode.py` - 新列插入位置
|
||||
8. ✅ `extraction_service/operations/binning.py` - 新列插入位置
|
||||
9. ✅ `extraction_service/operations/conditional.py` - 新列插入位置
|
||||
|
||||
### 蜑咲ォッ (4荳ェ譁<EFBDAA>サ?
|
||||
### 前端 (4个文件)
|
||||
|
||||
10. 笨?`frontend-v2/src/modules/dc/pages/tool-c/components/RecodeDialog.tsx` - 隹<EFBFBD>畑譁ーAPI
|
||||
11. 笨?`frontend-v2/src/modules/dc/pages/tool-c/components/DataGrid.tsx` - 蛻怜ョス莨伜喧 + tooltip
|
||||
12. 笨?`frontend-v2/src/modules/dc/pages/tool-c/components/ag-grid-custom.css` - 郤ソ譯<EFBFBD>「懆牡
|
||||
13. 笨?`frontend-v2/src/modules/dc/pages/tool-c/index.tsx` - 蜑?0陦梧署遉?
|
||||
10. ✅ `frontend-v2/src/modules/dc/pages/tool-c/components/RecodeDialog.tsx` - 调用新API
|
||||
11. ✅ `frontend-v2/src/modules/dc/pages/tool-c/components/DataGrid.tsx` - 列宽优化 + tooltip
|
||||
12. ✅ `frontend-v2/src/modules/dc/pages/tool-c/components/ag-grid-custom.css` - 线框颜色
|
||||
13. ✅ `frontend-v2/src/modules/dc/pages/tool-c/index.tsx` - 前50行提示
|
||||
|
||||
**諤サ隶。**: 13荳ェ譁<EFBFBD>サカ菫ョ謾?
|
||||
**总计**: 13个文件修改
|
||||
|
||||
---
|
||||
|
||||
@@ -250,7 +250,7 @@ npx prisma generate
|
||||
# 创建迁移文件
|
||||
npx prisma migrate dev --name add_column_mapping_to_tool_c_session
|
||||
|
||||
# 螯よ棡驕<EFBFBD>芦譚<EFBFBD>剞髞呵ッッ<EFBFBD>瑚ッキ蜈ウ髣ュ謇譛丑ode霑帷ィ句錘驥崎ッ?
|
||||
# 如果遇到权限错误,请关闭所有Node进程后重试
|
||||
```
|
||||
|
||||
### 2. 重启服务
|
||||
@@ -271,103 +271,102 @@ npm run dev
|
||||
|
||||
### 3. 测试验证
|
||||
|
||||
#### 豬玖ッ<EFBFBD>1<EFBFBD>夊。ィ螟エ迚ケ谿雁ュ礼ャ?
|
||||
- [ ] 荳贋シ<EFBFBD>蛹<EFBFBD>性迚ケ谿雁ュ礼ャヲ陦ィ螟エ逧Еxcel<EFBFBD>亥ヲA菴馴㍾<EFBFBD><EFBFBD>g<EFBFBD>荏<EFBFBD>?
|
||||
#### 测试1:表头特殊字符
|
||||
- [ ] 上传包含特殊字符表头的Excel(如`体重(kg)`)
|
||||
- [ ] 使用Pivot转换功能,验证能生成多列
|
||||
- [ ] 菴ソ逕ィ隶。邂怜<EFBFBD>蜉溯<EFBFBD><EFBFBD>碁ェ瑚ッ∽ク肴冠髞?
|
||||
- [ ] 使用计算列功能,验证不报错
|
||||
|
||||
#### 豬玖ッ<EFBFBD>2<EFBFBD>壽焚蛟シ譏<EFBFBD>蟆<EFBFBD>髪荳蛟?
|
||||
- [ ] 騾画叫"蟀壼ァサ迥カ蜀オ"蛻苓ソ幄。梧焚蛟シ譏<EFBDBC>蟆?
|
||||
- [ ] 鬪瑚ッ∬<EFBFBD>譏セ遉?荳ェ蜚ッ荳蛟シ<E89B9F>亥キイ蟀壹∵悴蟀壹∝<C280>莉悶∫ゥコ逋ス<E9808B><EFBDBD>
|
||||
- [ ] 騾画叫"遐皮ゥカ荳ュ蠢<EFBDAD>シ?蛻暦シ碁ェ瑚ッ∵仞遉コ4荳ェ荳ュ蠢?
|
||||
#### 测试2:数值映射唯一值
|
||||
- [ ] 选择"婚姻状况"列进行数值映射
|
||||
- [ ] 验证能显示4个唯一值(已婚、未婚、其他、空白)
|
||||
- [ ] 选择"研究中心:"列,验证显示4个中心
|
||||
|
||||
#### 豬玖ッ<EFBFBD>3<EFBFBD>壻ス馴ェ御シ伜<EFBFBD>?
|
||||
- [ ] 鬪瑚ッ∬。ィ譬シ郤ソ譯<EFBFBD>「懆牡譏ッ蜷ヲ譖エ貂<EFBFBD><EFBFBD>?
|
||||
- [ ] 鬪瑚ッ∝<EFBFBD>螳ス蜿倡ェ<EFBFBD>シ碁シ<EFBFBD>譬<EFBFBD>ぎ蛛懈仞遉コ螳梧紛蛻怜<EFBFBD>?
|
||||
- [ ] 鬪瑚ッ∵眠蛻怜<EFBFBD>邇ー蝨ィ蜴溷<EFBFBD>譌∬セ?
|
||||
#### 测试3:体验优化
|
||||
- [ ] 验证表格线框颜色是否更清晰
|
||||
- [ ] 验证列宽变窄,鼠标悬停显示完整列名
|
||||
- [ ] 验证新列出现在原列旁边
|
||||
- [ ] 验证数据处理后行顺序不变
|
||||
- [ ] 鬪瑚ッ<EFBFBD>。オ髱「鬘カ驛ィ譏セ遉コ"蜿ェ螻慕、コ蜑<EFBDBA>50陦?謠千、コ
|
||||
- [ ] 验证页面顶部显示"只展示前50行"提示
|
||||
|
||||
---
|
||||
|
||||
## 📊 影响评估
|
||||
|
||||
### 性能影响
|
||||
- 笨?**譌<>諤ァ閭ス謐溷、ア**: 蛻怜錐譏<EFBFBD>蟆<EFBFBD>惠Session蛻帛サコ譌カ荳谺。諤ァ逕滓<EFBFBD><EFBFBD>悟錘扈ュ譌<EFBFBD>鬚晏、門シ髞
|
||||
- 笨?**API莨伜喧**: 譁ー蠅槫髪荳蛟シAPI<EFBFBD>碁∩蜈榊燕遶ッ驥榊、榊、<EFBFBD>炊螟ァ謨ー謐ョ
|
||||
- ✅ **无性能损失**: 列名映射在Session创建时一次性生成,后续无额外开销
|
||||
- ✅ **API优化**: 新增唯一值API,避免前端重复处理大数据
|
||||
|
||||
### 蜈シ螳ケ諤?
|
||||
- 笨?**蜷大錘蜈シ螳ケ**: 譌ァSession荳榊女蠖ア蜩搾シ<EFBFBD>olumnMapping荳コ蜿ッ騾牙ュ玲ョオ<EFBFBD><EFBFBD>
|
||||
- 笨?**謨ー謐ョ霑∫ァサ**: 譌<EFBFBD>髴霑∫ァサ邇ー譛画焚謐ョ
|
||||
### 兼容性
|
||||
- ✅ **向后兼容**: 旧Session不受影响(columnMapping为可选字段)
|
||||
- ✅ **数据迁移**: 无需迁移现有数据
|
||||
|
||||
### 风险评估
|
||||
- <EFBFBD>泙 **菴朱」朱<EFBDA3>?*: 菫ョ謾ケ髮<EFBDB9>クュ蝨ィ謫堺ス懷アゑシ御ク榊スア蜩肴<E89CA9>ク蠢<EFBDB8>ュ伜お騾サ霎<EFBDBB>
|
||||
- <EFBFBD>泙 **譏灘屓貊?*: 蜿ッ蠢ォ騾溷屓騾蛻ー菫ョ謾ケ蜑咲沿譛ャ
|
||||
- 🟢 **低风险**: 修改集中在操作层,不影响核心存储逻辑
|
||||
- 🟢 **易回滚**: 可快速回退到修改前版本
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD>識 逕ィ謌キ莉キ蛟?
|
||||
## 🎯 用户价值
|
||||
|
||||
1. **迚ケ谿雁ュ礼ャヲ蜈ィ髱「謾ッ謖<EFBFBD>** 笨?
|
||||
- 謾ッ謖∽クュ譁<EFBFBD>峡蜿キ<EFBFBD>夲シ茨シ峨√舌?
|
||||
1. **特殊字符全面支持** ✅
|
||||
- 支持中文括号:()、【】
|
||||
- 支持等号、冒号、标点:=、:、。、!
|
||||
- 荳榊<EFBFBD>蝗<EFBFBD>蛻怜錐譬シ蠑乗冠髞?
|
||||
- 不再因列名格式报错
|
||||
|
||||
2. **謨ー謐ョ螳梧紛諤ァ菫晞<EFBFBD>?* 笨?
|
||||
2. **数据完整性保障** ✅
|
||||
- 数值映射从完整数据提取(不受前50行限制)
|
||||
- 菫晄戟蜴溷ァ玖。碁。コ蠎擾シ育畑謌キ荳榊<EFBFBD>諡<EFBFBD>ソ<EFBFBD>焚謐ョ髞吩ケア<EFBFBD>?
|
||||
- 保持原始行顺序(用户不再担心数据错乱)
|
||||
|
||||
3. **譖エ螂ス逧<EFBFBD>畑謌キ菴馴ェ?* 笨?
|
||||
- 貂<EFBFBD>匆逧<EFBFBD>。ィ譬シ隗<EFBFBD>ァ画譜譫?
|
||||
3. **更好的用户体验** ✅
|
||||
- 清晰的表格视觉效果
|
||||
- 优化的列宽,同屏显示更多数据
|
||||
- 逶エ隗ら噪譁ー蛻嶺ス咲スョ<EFBFBD>育エァ驍サ蜴溷<EFBFBD><EFBFBD>?
|
||||
- 譏守。ョ逧<EFBFBD>焚謐ョ鬚<EFBFBD>ァ域署遉?
|
||||
- 直观的新列位置(紧邻原列)
|
||||
- 明确的数据预览提示
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD>答 謚譛ッ莠ョ轤?
|
||||
## 📚 技术亮点
|
||||
|
||||
### 1. 列名映射机制
|
||||
- **隶セ隶。逅<EFBFBD>ソオ**: 蜑咲ォッ譏セ遉コ蜴溷ァ句錐<E58FA5>悟錘遶ッ菴ソ逕ィ螳牙<E89EB3>蜷?
|
||||
- **螳樒鴫譁ケ蠑<EFBFBD>**: Session蛻帛サコ譌カ荳谺。諤ァ逕滓<EFBFBD>譏<EFBFBD>蟆<EFBFBD><EFBFBD>邉?
|
||||
- **謇ゥ螻墓?*: 譛ェ譚・蜿ッ謾ッ謖∵峩螟夂音谿雁ュ礼ャヲ蝨コ譎?
|
||||
- **设计理念**: 前端显示原始名,后端使用安全名
|
||||
- **实现方式**: Session创建时一次性生成映射关系
|
||||
- **扩展性**: 未来可支持更多特殊字符场景
|
||||
|
||||
### 2. 蜷守ォッ蜚ッ荳蛟シ謠仙<EFBFBD>?
|
||||
- **隗」蜀ウ逞帷せ**: 蜑咲ォッdata蜿鈴剞<E988B4>亥宵譛?0陦鯉シ<E9AF89>
|
||||
- **謚譛ッ譁ケ譯?*: 譁ー蠅暸PI<50>御サ三SS闔キ蜿門ョ梧紛謨ー謐ョ
|
||||
- **諤ァ閭ス莨伜喧**: 蜴サ驥<EFBDBB>+謗貞コ擾シ瑚ソ泌屓貂<E5B193>エ怜錘逧<E98C98>髪荳蛟?
|
||||
### 2. 后端唯一值提取
|
||||
- **解决痛点**: 前端data受限(只有50行)
|
||||
- **技术方案**: 新增API,从OSS获取完整数据
|
||||
- **性能优化**: 去重+排序,返回清洗后的唯一值
|
||||
|
||||
### 3. 智能列重排序
|
||||
- **逕ィ謌キ髴豎?*: 譁ー蛻怜<E89BBB>邇ー蝨ィ逶ク蜈ウ蛻玲浴霎ケ
|
||||
- **謚譛ッ螳樒<EFBFBD>?*: Pandas蛻鈴㍾謗貞コ擾シ<EFBFBD>insert`譁ケ豕包シ?
|
||||
- **用户需求**: 新列出现在相关列旁边
|
||||
- **技术实现**: Pandas列重排序(`insert`方法)
|
||||
- **适用场景**: Binning、Recode、Compute、Conditional
|
||||
|
||||
### 4. 菫晄戟陦碁。コ蠎?
|
||||
- **蝨コ譎ッ**: Pivot遲画桃菴應シ壽隼蜿倩。碁。コ蠎?
|
||||
### 4. 保持行顺序
|
||||
- **场景**: Pivot等操作会改变行顺序
|
||||
- **方案**: 记录原始顺序,操作后恢复
|
||||
- **螳樒鴫**: 荳エ譌カ謗貞コ丞<EFBFBD>?+ `sort_values`
|
||||
- **实现**: 临时排序列 + `sort_values`
|
||||
|
||||
---
|
||||
|
||||
## 🏆 总结
|
||||
|
||||
譛ャ谺。菫ョ螟崎ァ」蜀ウ莠?*7荳ェ荳・驥埼琉鬚?* + **5荳ェ菴馴ェ御シ伜<EFBFBD>?*<2A>梧カ牙<EFBDB6>?*13荳ェ譁<EFBDAA>サ?*菫ョ謾ケ縲?
|
||||
本次修复解决了**7个严重问题** + **5个体验优化**,涉及**13个文件**修改。
|
||||
|
||||
**譬ク蠢<EFBFBD><EFBFBD>蟆ア**<EFBFBD>?
|
||||
- 笨?蠖サ蠎戊ァ」蜀ウ迚ケ谿雁ュ礼ャヲ髣ョ鬚假シ亥<EFBDBC>蜷肴<E89CB7><E882B4>㊥蛹匁惻蛻カ<E89BBB>?
|
||||
- 笨?菫ョ螟肴焚蛟シ譏<EFBDBC>蟆<EFBFBD>髪荳蛟シ謠仙叙髞呵ッッ<EFBDAF>域眠蠅槫錘遶ッAPI<EFBFBD>?
|
||||
- 笨?蜈ィ髱「謠仙合逕ィ謌キ菴馴ェ鯉シ?荳ェ扈<EFBDAA>鰍莨伜喧<E4BC9C><E596A7>
|
||||
**核心成就**:
|
||||
- ✅ 彻底解决特殊字符问题(列名标准化机制)
|
||||
- ✅ 修复数值映射唯一值提取错误(新增后端API)
|
||||
- ✅ 全面提升用户体验(5个细节优化)
|
||||
|
||||
**荳倶ク豁・蟒コ隶?*<2A>?
|
||||
**下一步建议**:
|
||||
1. 进行全面回归测试
|
||||
2. 譖エ譁ー逕ィ謌キ譁<EFBFBD>。」<EFBFBD>瑚ッエ譏守音谿雁ュ礼ャヲ謾ッ謖?
|
||||
2. 更新用户文档,说明特殊字符支持
|
||||
3. 监控生产环境性能指标
|
||||
|
||||
---
|
||||
|
||||
**修复完成时间**: 2025-12-08 当前时间
|
||||
**迥カ諤?*: 笨?蟾イ螳梧<E89EB3><E6A2A7>悟セ<E6829F>オ玖ッ暮ェ瑚ッ?
|
||||
|
||||
**状态**: ✅ 已完成,待测试验证
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user