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:
2026-01-16 13:42:10 +08:00
parent 98d862dbd4
commit 66255368b7
560 changed files with 70424 additions and 52353 deletions

View File

@@ -1,6 +1,6 @@
# Node.js 后端 - pino-pretty 问题修复记录
> **菫ョ螟肴慮髣エ**<2A>?025-12-24
> **修复时间**2025-12-24
> **问题原因**生产环境使用了开发依赖pino-pretty
> **解决方案**根据环境变量条件化使用pino-pretty
@@ -15,27 +15,27 @@ Error: unable to determine transport target for "pino-pretty"
```
### 根本原因
1. `pino-pretty` 譏ッ荳€荳?*devDependency**<EFBFBD>亥シ€蜿台セ晁オ厄シ<EFBFBD>
2. Dockerfile菴ソ逕ィ `npm ci --production` 蜿ェ螳芽」<EFBFBD>函莠ァ萓晁オ?
1. `pino-pretty` 是一个**devDependency**(开发依赖)
2. Dockerfile使用 `npm ci --production` 只安装生产依赖
3. `pino-pretty` **不会被安装到生产环境**
4. 菴?`src/index.ts` 荳ュ遑ャ郛也<EFBFBD>∽コ?`pino-pretty` 菴應クコ譌・蠢玲<EFBFBD>シ蠑丞喧蟾・蜈?
5. 逕滉コァ邇ッ蠅<EFBFBD>星蜉ィ譌カ謇セ荳榊芦 `pino-pretty`<EFBFBD>悟ッシ閾エ蟠ゥ貅?
4. `src/index.ts` 中硬编码了 `pino-pretty` 作为日志格式化工具
5. 生产环境启动时找不到 `pino-pretty`,导致崩溃
---
## 笨?隗」蜀ウ譁ケ譯<EFBDB9>
## ✅ 解决方案
### 1. 修改代码 - 条件化使用pino-pretty
**文件**`backend/src/index.ts`
**菫ョ謾ケ蜑搾シ育ャ?9-41陦鯉シ<E9AF89>**<2A>?
**修改前第29-41行**
```typescript
const fastify = Fastify({
logger: {
level: config.logLevel,
transport: {
target: 'pino-pretty', // 笶?遑ャ郛也<E9839B><E4B99F>シ檎函莠ァ邇ッ蠅<EFBDAF>シ壽冠髞?
target: 'pino-pretty', // ❌ 硬编码,生产环境会报错
options: {
colorize: true,
translateTime: 'HH:MM:ss Z',
@@ -46,7 +46,7 @@ const fastify = Fastify({
});
```
**菫ョ謾ケ蜷?*<2A>?
**修改后**
```typescript
// 生产环境使用JSON格式日志性能更好开发环境使用pino-pretty易读
const fastify = Fastify({
@@ -70,10 +70,10 @@ const fastify = Fastify({
});
```
**蜈ウ髞ョ謾ケ霑<EFBFBD>**<2A>?
- 笨?譬ケ謐ョ `NODE_ENV` 譚。莉カ蛹夜<E89BB9>鄂?
- 笨?逕滉コァ邇ッ蠅<EFBDAF>シ壻スソ逕ィ蜴溽函JSON譌・蠢暦シ域€ァ閭ス譖エ螂ス<E89E82>€ょ粋ELK/Loki遲画律蠢礼ウサ扈滂シ<E6BB82>
- 笨?蠑€蜿醍識蠅<E8AD98>シ壻スソ逕ィpino-pretty<74><EFBFBD>隸サ<E99AB8>御セソ莠手ー<E6898B>ッ包シ?
**关键改进**
- ✅ 根据 `NODE_ENV` 条件化配置
- ✅ 生产环境使用原生JSON日志性能更好适合ELK/Loki等日志系统
- ✅ 开发环境使用pino-pretty易读便于调试
### 2. 重新编译TypeScript
@@ -90,9 +90,9 @@ npm run build
docker build -t crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/backend-service:v1.2 .
```
**<EFBFBD>サコ扈捺棡**<2A>?
- 笨?譫<>サコ謌仙粥
- 笨?閠玲慮<E78EB2>?.4遘抵シ亥ソォ騾滂シ悟、ァ驛ィ蛻<EFBFBD>アゆスソ逕ィ郛灘ュ假シ?
**构建结果**
- ✅ 构建成功
- ✅ 耗时8.4秒(快速,大部分层使用缓存)
### 4. 推送到ACR
@@ -100,9 +100,9 @@ docker build -t crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-cli
docker push crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/backend-service:v1.2
```
**謗ィ騾∫サ捺<EFBFBD>?*<2A>?
- 笨?謗ィ騾∵<E9A8BE>蜉?
- 笨?Digest: `sha256:dd48750c5032681613776ea484a2194622e3926c6f49a1d7246105c090ecce35`
**推送结果**
- ✅ 推送成功
-Digest: `sha256:dd48750c5032681613776ea484a2194622e3926c6f49a1d7246105c090ecce35`
---
@@ -110,77 +110,77 @@ docker push crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinica
| 项目 | v1.0 | v1.1 | v1.2(最新) |
|------|------|------|-------------|
| **髣ョ鬚<EFBFBD>** | 郛コ蟆祖onfig | 笶?菫ョ螟<EFBDAE> | 笶?菫ョ螟<EFBDAE> |
| **髣ョ鬚<EFBFBD>** | - | pino-pretty | 笨?菫ョ螟<EFBDAE> |
| **迥カ諤?* | 笶?蜷ッ蜉ィ螟ア雍・ | 笶?蜷ッ蜉ィ螟ア雍・ | 笨?蠕<>ェ瑚ッ?|
| **菫ョ謾ケ蜀<EFBFBD>ョケ** | - | +config逶ョ蠖<EFBFBD> | +譚。莉カ蛹匁律蠢鈴<E8A0A2>鄂?|
| **<EFBFBD>サコ譌カ髣エ** | ~5<EFBFBD> | ~1<EFBFBD> | ~8遘?|
| **问题** | 缺少config | ❌ 修复 | ❌ 修复 |
| **问题** | - | pino-pretty | ✅ 修复 |
| **状态** | ❌ 启动失败 | ❌ 启动失败 | ✅ 待验证 |
| **修改内容** | - | +config目录 | +条件化日志配置 |
| **构建时间** | ~5分钟 | ~1分钟 | ~8|
---
## <EFBFBD>識 荳倶ク€豁・謫堺ス?
## 🎯 下一步操作
### 豁・鬪、1<EFBFBD>夂匳蠖百AE謗ァ蛻カ蜿?
### 步骤1登录SAE控制台
访问https://sae.console.aliyun.com/
### 步骤2更新镜像版本为 v1.2
1. 找到应用:`nodejs-backend-test`
2. 驟咲スョ邂。逅<EFBFBD> 竊?驛ィ鄂イ驟咲スョ 竊?髟懷ワ隶セ鄂ョ
3. 菫ョ謾ケ髟懷ワ迚域悽<EFBFBD>?
2. 配置管理 → 部署配置 → 镜像设置
3. 修改镜像版本:
```
backend-service:v1.1
謾ケ荳コ<EFBFBD>ackend-service:v1.2 笨?
改为backend-service:v1.2
```
### 步骤3重新部署并验证
1. 菫晏ュ伜ケカ驥肴眠驛ィ鄂?
1. 保存并重新部署
2. 查看实时日志
3. **謌仙粥譬<EFBFBD>ソ<EFBFBD>**<2A>?
3. **成功标志**
**笨?譛滓悍逧<E6828D>律蠢玲<E8A0A2>シ蠑?*<2A><>SON譬シ蠑擾シ御ク肴弍pretty譬シ蠑擾シ会シ<E4BC9A>
**✅ 期望的日志格式**JSON格式不是pretty格式
```json
{"level":30,"time":1703472498828,"pid":1,"hostname":"xxx","msg":"Server listening at http://0.0.0.0:3001"}
{"level":30,"time":1703472498830,"pid":1,"hostname":"xxx","msg":"Config loaded: /app/config/agents.yaml"}
{"level":30,"time":1703472498832,"pid":1,"hostname":"xxx","msg":"Database connected successfully"}
```
**笶?荳榊コ碑ッ・蜃コ邇?*<2A>?
**❌ 不应该出现**
- `Error: unable to determine transport target for "pino-pretty"`
- 莉サ菴募<EFBFBD>莠姿ino-pretty<EFBFBD>漠隸?
- 任何关于pino-pretty的错误
---
## <EFBFBD>投 荳コ莉€荵育函莠ァ邇ッ蠅<EFBDAF>ク咲畑pino-pretty<EFBFBD>?
## 📊 为什么生产环境不用pino-pretty
### 性能对比
| 指标 | 原生JSON | pino-pretty |
|------|---------|-------------|
| **蜷槫瑞驥?* | ~30,000 log/s | ~3,000 log/s |
| **CPU菴ソ逕ィ** | 菴?| 鬮假シ域<EFBDBC>シ蠑丞喧蠑€€<E9AB9E>?|
| **<EFBFBD>ュ倅スソ逕ィ** | 菴?| 鬮?|
| **騾ら畑蝨コ譎ッ** | 逕滉コァ邇ッ蠅<EFBDAF> | 蠑€蜿醍識蠅?|
| **吞吐量** | ~30,000 log/s | ~3,000 log/s |
| **CPU使用** | 低 | 高(格式化开销) |
| **内存使用** | 低 | 高 |
| **适用场景** | 生产环境 | 开发环境 |
### 日志系统集成
**逕滉コァ邇ッ蠅<EFBFBD>怙菴ウ螳櫁キ?*<2A>?
**生产环境最佳实践**
```
应用输出JSON日志
竊?
SAE/K8s謾カ髮<EFBFBD><EFBFBD>tdout/stderr<EFBFBD>?
竊?
譌・蠢礼ウサ扈滂シ<EFBFBD>LK/Loki/髦ソ驥御コ全LS<4C>?
竊?
蜿ッ隗<EFBFBD>喧蛻<EFBFBD><EFBFBD><EFBFBD>ibana/Grafana<EFBFBD>?
SAE/K8s收集stdout/stderr
日志系统ELK/Loki/阿里云SLS
可视化分析Kibana/Grafana
```
JSON譬シ蠑乗律蠢玲峩騾ょ粋<EFBFBD>?
- 笨?扈捺桷蛹匁衍隸「<E99AB8>亥ュ玲ョオ郤ァ謳懃エ「<EFBDB4><EFBDA2>
- 笨?譌・蠢苓★蜷亥柱蛻<E69FB1><E89BBB>?
- 笨?蜻願ュヲ隗<EFBDA6><E99A97>驟咲スョ
- 笨?諤ァ閭ス逶第而
JSON格式日志更适合:
- ✅ 结构化查询(字段级搜索)
- ✅ 日志聚合和分析
- ✅ 告警规则配置
- ✅ 性能监控
---
@@ -199,9 +199,9 @@ npm run dev
# 观察日志输出应该是JSON格式
```
### 豬玖ッ募シ€蜿醍識蠅<EFBFBD>律蠢玲<EFBFBD>シ蠑?
### 测试开发环境日志格式
```bash
# 隶セ鄂ョ蠑€蜿醍識蠅<EFBFBD>序驥?
# 设置开发环境变量
export NODE_ENV=development
# 启动应用
@@ -214,36 +214,35 @@ npm run dev
## 💡 经验教训
### 1. 蠑€蜿台セ晁オ也ョ。逅?
- 笨?**DO**<EFBFBD>壼ー<EFBFBD><EFBFBD>シ蠑丞喧蟾・蜈キ<EFBFBD>亥ヲino-pretty<EFBFBD>画叛蝨ィdevDependencies
- 笨?**DO**<EFBFBD>夂函莠ァ邇ッ蠅<EFBFBD>スソ逕ィ蜴溽函譌・蠢玲<EFBFBD>シ蠑?
- 笶?**DON'T**<EFBFBD>壼惠逕滉コァ邇ッ蠅<EFBFBD>セ晁オ謀evDependencies
### 1. 开发依赖管理
- **DO**将格式化工具如pino-pretty)放在devDependencies
- **DO**:生产环境使用原生日志格式
- **DON'T**在生产环境依赖devDependencies
### 2. 环境适配
- 笨?**DO**<EFBFBD><EFBFBD>ケ謐ョNODE_ENV驟咲スョ荳榊酔逧<EFBFBD>。御ク?
- 笨?**DO**<EFBFBD>夂函莠ァ邇ッ蠅<EFBFBD>シ伜<EFBFBD><EFBFBD>剔諤ァ閭ス
- 笨?**DO**<EFBFBD>壼シ€蜿醍識蠅<EFBFBD>シ伜<EFBFBD><EFBFBD>剔譏鍋畑諤?
- **DO**:根据NODE_ENV配置不同的行为
- **DO**:生产环境优先考虑性能
- **DO**:开发环境优先考虑易用性
### 3. Docker镜像优化
- 笨?**DO**<EFBFBD>壻スソ逕?`npm ci --production` 蜃丞ー城復蜒丈ス鍋ァッ
- 笨?**DO**<2A>壼惠莉」遐∽クュ騾る<E9A8BE>逕滉コァ邇ッ蠅<EFBDAF>
- 笶?**DON'T**<2A>壻クコ莠<EFBDBA>婿萓ソ蝨ィ逕滉コァ邇ッ蠅<EFBDAF>ョ芽」<E88ABD>園譛我セ晁オ?
- **DO**:使用 `npm ci --production` 减小镜像体积
- **DO**:在代码中适配生产环境
- **DON'T**:为了方便在生产环境安装所有依赖
---
## 📝 修复总结
**问题根源**:代码未适配生产环境(硬编码开发工具)
**菫ョ螟肴婿蠑<EFBFBD>**<EFBFBD>壽キサ蜉<EFBFBD>邇ッ蠅<EFBFBD>愛譁ュ<EFBFBD>梧擅莉カ蛹夜<EFBFBD>鄂?
**修复方式**:添加环境判断,条件化配置
**影响范围**:仅日志输出格式,不影响功能
**菫ョ螟肴慮髣エ**<EFBFBD>夂コヲ10蛻<EFBFBD><EFBFBD>育シ冶ッ?蛻<>帖 + 譫<>サコ8遘?+ 謗ィ騾?蛻<><EFBFBD>?
**迚域悽蜿?*<2A>1.2
**修复时间**约10分钟编译2分钟 + 构建8秒 + 推送1分钟
**版本号**v1.2
---
**<EFBFBD>。」蛻帛サコ譌カ髣エ**<EFBFBD>?025-12-24
**扈エ謚、莠コ蜻<EFBFBD>**<EFBFBD>夊ソ千サエ蝗「髦?
**文档创建时间**2025-12-24
**维护人员**:运维团队