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,26 +1,26 @@
|
||||
# 平台基础设施验证报告
|
||||
|
||||
> **<EFBFBD>交<EFBFBD>嚗?* 2025-11-17
|
||||
> **撉諹<EFBFBD>蝐餃<EFBFBD>嚗?* <20>蠘<EFBFBD>瘚贝<E7989A> + <20><><EFBFBD>瘚贝<E7989A>
|
||||
> **撉諹<EFBFBD><EFBFBD>臬<EFBFBD>嚗?* <20>砍𧑐撘<F0A79190><E69298>𤑳㴓憓<E3B493><E68693>Windows嚗?
|
||||
> **撉諹<EFBFBD><EFBFBD>嗆<EFBFBD><EFBFBD><EFBFBD>** <20>?<3F>券<EFBFBD><E588B8>朞<EFBFBD>
|
||||
> **日期:** 2025-11-17
|
||||
> **验证类型:** 功能测试 + 集成测试
|
||||
> **验证环境:** 本地开发环境(Windows)
|
||||
> **验证状态:** ✅ 全部通过
|
||||
|
||||
---
|
||||
|
||||
## 📋 验证总览
|
||||
|
||||
| 璅∪<EFBFBD> | <20>嗆<EFBFBD>?| 瘚贝<E7989A><E8B49D><EFBFBD>捆 | 蝏𤘪<E89D8F> |
|
||||
| 模块 | 状态 | 测试内容 | 结果 |
|
||||
|------|------|---------|------|
|
||||
| **摮睃<EFBFBD><EFBFBD>滚𦛚** | <EFBFBD>?<3F>朞<EFBFBD> | 銝𠹺<E98A9D>/銝贝蝸/<2F>𣳇膄/摮睃銁<E79D83>扳<EFBFBD><E689B3>?| 100% |
|
||||
| **<EFBFBD>亙<EFBFBD>蝟餌<EFBFBD>** | <EFBFBD>?<3F>朞<EFBFBD> | Info/Warn/Error/Context<EFBFBD>亙<EFBFBD> | 100% |
|
||||
| **蝻枏<EFBFBD><EFBFBD>滚𦛚** | <EFBFBD>?<3F>朞<EFBFBD> | Set/Get/Has/Delete/<EFBFBD>寥<EFBFBD><EFBFBD>滢<EFBFBD> | 100% |
|
||||
| **撘<EFBFBD>郊隞餃𦛚** | <EFBFBD>?<3F>朞<EFBFBD> | <20>𥕦遣隞餃𦛚/<2F>亥砭<E4BAA5>嗆<EFBFBD>?| 100% |
|
||||
| **<EFBFBD>亙熒璉<EFBFBD><EFBFBD>?* | <20>?<3F>朞<EFBFBD> | Liveness/Readiness/霂衣<EFBFBD>璉<EFBFBD><EFBFBD>?| 100% |
|
||||
| **<EFBFBD>唳旿摨栞<EFBFBD><EFBFBD>交<EFBFBD>** | <EFBFBD>?<3F>朞<EFBFBD> | 餈墧𦻖<E5A2A7>啁<EFBFBD><E59581>?隡㗛<E99AA1><E3979B>喲𡡒 | 100% |
|
||||
| **<EFBFBD>臬<EFBFBD><EFBFBD>滨蔭** | <EFBFBD>?<3F>朞<EFBFBD> | <20>滨蔭<E6BBA8>㰘蝸/撉諹<E69289> | 100% |
|
||||
| **<EFBFBD>烐綉<EFBFBD><EFBFBD><EFBFBD>** | <EFBFBD>?<3F>朞<EFBFBD> | <20>唳旿摨?<3F><><EFBFBD><EFBFBD>烐綉 | 100% |
|
||||
| **存储服务** | ✅ 通过 | 上传/下载/删除/存在性检查 | 100% |
|
||||
| **日志系统** | ✅ 通过 | Info/Warn/Error/Context日志 | 100% |
|
||||
| **缓存服务** | ✅ 通过 | Set/Get/Has/Delete/批量操作 | 100% |
|
||||
| **异步任务** | ✅ 通过 | 创建任务/查询状态 | 100% |
|
||||
| **健康检查** | ✅ 通过 | Liveness/Readiness/详细检查 | 100% |
|
||||
| **数据库连接池** | ✅ 通过 | 连接数监控/优雅关闭 | 100% |
|
||||
| **环境配置** | ✅ 通过 | 配置加载/验证 | 100% |
|
||||
| **监控指标** | ✅ 通过 | 数据库/内存监控 | 100% |
|
||||
|
||||
**<EFBFBD>颱<EFBFBD><EFBFBD>朞<EFBFBD><EFBFBD><EFBFBD><EFBFBD>** 8/8 = 100% <EFBFBD>?
|
||||
**总体通过率:** 8/8 = 100% ✅
|
||||
|
||||
---
|
||||
|
||||
@@ -28,9 +28,9 @@
|
||||
|
||||
### 1. 存储服务(LocalAdapter)✅
|
||||
|
||||
**瘚贝<EFBFBD>API嚗?* `GET /test/platform`
|
||||
**测试API:** `GET /test/platform`
|
||||
|
||||
**瘚贝<EFBFBD>蝏𤘪<EFBFBD>嚗?*
|
||||
**测试结果:**
|
||||
```json
|
||||
{
|
||||
"status": "passed",
|
||||
@@ -41,55 +41,55 @@
|
||||
}
|
||||
```
|
||||
|
||||
**撉諹<EFBFBD>憿寧𤌍嚗?*
|
||||
- <EFBFBD>?<3F><>辣銝𠹺<E98A9D>嚗𡁏<E59A97><F0A1818F>煺<EFBFBD>隡惩<E99AA1> `uploads/test/` <EFBFBD>桀<EFBFBD>
|
||||
- <EFBFBD>?<3F><>辣銝贝蝸嚗𡁏<E59A97><F0A1818F>煺<EFBFBD>頧踝<E9A0A7>憭批<E686AD> 51 bytes
|
||||
- <EFBFBD>?<3F><>捆撉諹<E69289>嚗帋<E59A97>隡惩<E99AA1>銝贝蝸<E8B49D><E89DB8>捆摰<E68D86><E691B0>銝<EFBFBD><E98A9D>?
|
||||
- <EFBFBD>?摮睃銁<E79D83>扳<EFBFBD><E689B3>伐<EFBFBD><E4BC90><EFBFBD>辣摮睃銁璉<E98A81>瘚𧢲迤撣?
|
||||
- <EFBFBD>?<3F><>辣<EFBFBD>𣳇膄嚗𡁏<E59A97><F0A1818F><EFBFBD><EFBFBD><EFBFBD>?
|
||||
**验证项目:**
|
||||
- ✅ 文件上传:成功上传到 `uploads/test/` 目录
|
||||
- ✅ 文件下载:成功下载,大小 51 bytes
|
||||
- ✅ 内容验证:上传和下载内容完全一致
|
||||
- ✅ 存在性检查:文件存在检测正常
|
||||
- ✅ 文件删除:清理成功
|
||||
|
||||
**摰䂿緵<EFBFBD><EFBFBD>辣嚗?*
|
||||
- `backend/src/common/storage/LocalAdapter.ts` <EFBFBD>?
|
||||
- `backend/src/common/storage/StorageFactory.ts` <EFBFBD>?
|
||||
- `backend/src/common/storage/index.ts` <EFBFBD>?
|
||||
**实现文件:**
|
||||
- `backend/src/common/storage/LocalAdapter.ts` ✅
|
||||
- `backend/src/common/storage/StorageFactory.ts` ✅
|
||||
- `backend/src/common/storage/index.ts` ✅
|
||||
|
||||
---
|
||||
|
||||
### 2. 日志系统(Winston)✅
|
||||
|
||||
**瘚贝<EFBFBD>蝏𤘪<EFBFBD>嚗?*
|
||||
**测试结果:**
|
||||
```json
|
||||
{
|
||||
"status": "passed",
|
||||
"message": "<EFBFBD>亙<EFBFBD>撌脰<EFBFBD><EFBFBD>箏<EFBFBD><EFBFBD>批<EFBFBD><EFBFBD>?
|
||||
"message": "日志已输出到控制台"
|
||||
}
|
||||
```
|
||||
|
||||
**撉諹<EFBFBD>憿寧𤌍嚗?*
|
||||
- <EFBFBD>?Info 蝥批<EFBFBD><EFBFBD>亙<EFBFBD>嚗𡁏迤撣貉<EFBFBD><EFBFBD>?
|
||||
- <EFBFBD>?Warn 蝥批<EFBFBD><EFBFBD>亙<EFBFBD>嚗𡁏迤撣貉<EFBFBD><EFBFBD>?
|
||||
- <EFBFBD>?Error 蝥批<EFBFBD><EFBFBD>亙<EFBFBD>嚗𡁏迤撣貉<EFBFBD><EFBFBD>?
|
||||
- <EFBFBD>?撣虫<E692A3>銝𧢲<E98A9D><F0A7A2B2><EFBFBD>𠯫敹梹<E695B9>`logger.child()` 甇<EFBFBD>虜撌乩<EFBFBD>
|
||||
- <EFBFBD>?JSON <EFBFBD>澆<EFBFBD>嚗𡁶<EFBFBD>鈭抒㴓憓<EFBFBD>𣈲<EFBFBD>?
|
||||
- <EFBFBD>?敶抵𠧧颲枏枂嚗𡁜<E59A97><F0A1819C>𤑳㴓憓<E3B493>𣈲<EFBFBD>?
|
||||
**验证项目:**
|
||||
- ✅ Info 级别日志:正常输出
|
||||
- ✅ Warn 级别日志:正常输出
|
||||
- ✅ Error 级别日志:正常输出
|
||||
- ✅ 带上下文的日志:`logger.child()` 正常工作
|
||||
- ✅ JSON 格式:生产环境支持
|
||||
- ✅ 彩色输出:开发环境支持
|
||||
|
||||
**<EFBFBD>亙<EFBFBD>蝷箔<EFBFBD>嚗?*
|
||||
**日志示例:**
|
||||
```
|
||||
[2025-11-17T23:54:17.877Z] [aiclinical-backend] info: 存储服务测试通过 {"key":"test/verification-1763423657877.txt"}
|
||||
[2025-11-17T23:54:17.880Z] [aiclinical-backend] info: 缓存服务测试通过
|
||||
[2025-11-17T23:54:17.882Z] [aiclinical-backend] info: 异步任务测试通过 {"jobId":"15ca17e0-1b97-4afa-ae61-b69c1b676264"}
|
||||
[2025-11-17T23:54:17.883Z] [aiclinical-backend] info: <EFBFBD>?撟喳蝱<E596B3>箇<EFBFBD>霈暹鴌撉諹<E69289>嚗𡁜<E59A97><F0A1819C>券<EFBFBD>朞<EFBFBD> {"tests":["storage","logging","cache","jobQueue"]}
|
||||
[2025-11-17T23:54:17.883Z] [aiclinical-backend] info: ✅ 平台基础设施验证:全部通过 {"tests":["storage","logging","cache","jobQueue"]}
|
||||
```
|
||||
|
||||
**摰䂿緵<EFBFBD><EFBFBD>辣嚗?*
|
||||
- `backend/src/common/logging/logger.ts` <EFBFBD>?
|
||||
- `backend/src/common/logging/index.ts` <EFBFBD>?
|
||||
**实现文件:**
|
||||
- `backend/src/common/logging/logger.ts` ✅
|
||||
- `backend/src/common/logging/index.ts` ✅
|
||||
|
||||
---
|
||||
|
||||
### 3. 缓存服务(MemoryCacheAdapter)✅
|
||||
|
||||
**瘚贝<EFBFBD>蝏𤘪<EFBFBD>嚗?*
|
||||
**测试结果:**
|
||||
```json
|
||||
{
|
||||
"status": "passed",
|
||||
@@ -100,25 +100,25 @@
|
||||
}
|
||||
```
|
||||
|
||||
**撉諹<EFBFBD>憿寧𤌍嚗?*
|
||||
- <EFBFBD>?霈曄蔭蝻枏<E89DBB>嚗䫤cache.set()` <20>𣂼<EFBFBD>
|
||||
- <EFBFBD>?<3F>瑕<EFBFBD>蝻枏<E89DBB>嚗䫤cache.get()` 餈𥪜<E9A488>甇<EFBFBD>&<EFBFBD>唳旿
|
||||
- <EFBFBD>?摮睃銁<E79D83>扳<EFBFBD><E689B3>伐<EFBFBD>`cache.has()` 甇<EFBFBD>虜
|
||||
- <EFBFBD>?<3F><>捆撉諹<E69289>嚗𡁶<E59A97>摮睃<E691AE>摰孵<E691B0><E5ADB5>其<EFBFBD><E585B6>?
|
||||
- <EFBFBD>?<3F>寥<EFBFBD><E5AFA5>滢<EFBFBD>嚗䫤cache.mset()` <20>?`cache.mget()` 甇<>虜
|
||||
- <EFBFBD>?<3F>𣳇膄蝻枏<E89DBB>嚗䫤cache.delete()` <20>𣂼<EFBFBD>
|
||||
- <EFBFBD>?TTL <EFBFBD>舀<EFBFBD>嚗?0蝘坿<E89D98><E59DBF><EFBFBD>𧒄<EFBFBD>湔迤撣?
|
||||
**验证项目:**
|
||||
- ✅ 设置缓存:`cache.set()` 成功
|
||||
- ✅ 获取缓存:`cache.get()` 返回正确数据
|
||||
- ✅ 存在性检查:`cache.has()` 正常
|
||||
- ✅ 内容验证:缓存内容完全一致
|
||||
- ✅ 批量操作:`cache.mset()` 和 `cache.mget()` 正常
|
||||
- ✅ 删除缓存:`cache.delete()` 成功
|
||||
- ✅ TTL 支持:10秒过期时间正常
|
||||
|
||||
**摰䂿緵<EFBFBD><EFBFBD>辣嚗?*
|
||||
- `backend/src/common/cache/MemoryCacheAdapter.ts` <EFBFBD>?
|
||||
- `backend/src/common/cache/CacheFactory.ts` <EFBFBD>?
|
||||
- `backend/src/common/cache/index.ts` <EFBFBD>?
|
||||
**实现文件:**
|
||||
- `backend/src/common/cache/MemoryCacheAdapter.ts` ✅
|
||||
- `backend/src/common/cache/CacheFactory.ts` ✅
|
||||
- `backend/src/common/cache/index.ts` ✅
|
||||
|
||||
---
|
||||
|
||||
### 4. 异步任务(MemoryQueue)✅
|
||||
|
||||
**瘚贝<EFBFBD>蝏𤘪<EFBFBD>嚗?*
|
||||
**测试结果:**
|
||||
```json
|
||||
{
|
||||
"status": "passed",
|
||||
@@ -127,30 +127,30 @@
|
||||
}
|
||||
```
|
||||
|
||||
**撉諹<EFBFBD>憿寧𤌍嚗?*
|
||||
- <EFBFBD>?<3F>𥕦遣隞餃𦛚嚗䫤jobQueue.push()` <20>𣂼<EFBFBD>
|
||||
- <EFBFBD>?<3F><><EFBFBD>隞餃𦛚ID嚗䦧UID <20>澆<EFBFBD>甇<EFBFBD>&
|
||||
- <EFBFBD>?<3F>亥砭隞餃𦛚嚗䫤jobQueue.getJob()` 餈𥪜<E9A488>隞餃𦛚<E9A483>嗆<EFBFBD>?
|
||||
- <EFBFBD>?隞餃𦛚<E9A483>嗆<EFBFBD><E59786><EFBFBD><EFBFBD>嘥<EFBFBD><E598A5>嗆<EFBFBD><E59786>蛹 `pending`
|
||||
- <EFBFBD>?隞餃𦛚<E9A483>唳旿嚗帋遙<E5B88B>⊥㺭<E28AA5>格迤蝖桐<E89D96>摮?
|
||||
**验证项目:**
|
||||
- ✅ 创建任务:`jobQueue.push()` 成功
|
||||
- ✅ 生成任务ID:UUID 格式正确
|
||||
- ✅ 查询任务:`jobQueue.getJob()` 返回任务状态
|
||||
- ✅ 任务状态:初始状态为 `pending`
|
||||
- ✅ 任务数据:任务数据正确保存
|
||||
|
||||
**摰䂿緵<EFBFBD><EFBFBD>辣嚗?*
|
||||
- `backend/src/common/jobs/MemoryQueue.ts` <EFBFBD>?
|
||||
- `backend/src/common/jobs/JobFactory.ts` <EFBFBD>?
|
||||
- `backend/src/common/jobs/types.ts` <EFBFBD>?
|
||||
- `backend/src/common/jobs/index.ts` <EFBFBD>?
|
||||
**实现文件:**
|
||||
- `backend/src/common/jobs/MemoryQueue.ts` ✅
|
||||
- `backend/src/common/jobs/JobFactory.ts` ✅
|
||||
- `backend/src/common/jobs/types.ts` ✅
|
||||
- `backend/src/common/jobs/index.ts` ✅
|
||||
|
||||
---
|
||||
|
||||
### 5. <EFBFBD>亙熒璉<EFBFBD><EFBFBD>亦垢<EFBFBD>?<3F>?
|
||||
### 5. 健康检查端点 ✅
|
||||
|
||||
**瘚贝<EFBFBD>蝡舐<EFBFBD>嚗?*
|
||||
**测试端点:**
|
||||
|
||||
#### 5.1 Liveness 端点
|
||||
|
||||
**霂瑟<EFBFBD>嚗?* `GET /health/liveness`
|
||||
**请求:** `GET /health/liveness`
|
||||
|
||||
**<EFBFBD>滚<EFBFBD>嚗?*
|
||||
**响应:**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
@@ -159,17 +159,17 @@
|
||||
}
|
||||
```
|
||||
|
||||
<EFBFBD>?**<2A>嗆<EFBFBD><E59786><EFBFBD>嚗?* 200 OK
|
||||
<EFBFBD>?**<2A>滚<EFBFBD><E6BB9A>園𡢿嚗?* < 10ms
|
||||
<EFBFBD>?**<2A>券<EFBFBD>䈑<EFBFBD>** SAE 摮䀹暑璉<EFBFBD><EFBFBD>?
|
||||
✅ **状态码:** 200 OK
|
||||
✅ **响应时间:** < 10ms
|
||||
✅ **用途:** SAE 存活检查
|
||||
|
||||
---
|
||||
|
||||
#### 5.2 Readiness 端点
|
||||
|
||||
**霂瑟<EFBFBD>嚗?* `GET /health/readiness`
|
||||
**请求:** `GET /health/readiness`
|
||||
|
||||
**<EFBFBD>滚<EFBFBD>嚗?*
|
||||
**响应:**
|
||||
```json
|
||||
{
|
||||
"status": "degraded",
|
||||
@@ -199,17 +199,17 @@
|
||||
}
|
||||
```
|
||||
|
||||
<EFBFBD>?**<2A>唳旿摨𤘪<E691A8><F0A498AA>伐<EFBFBD>** <20>朞<EFBFBD>嚗<EFBFBD><E59A97><EFBFBD>交迤撣賂<E692A3>
|
||||
<EFBFBD>𩤃<EFBFBD> **<EFBFBD><EFBFBD><EFBFBD>璉<EFBFBD><EFBFBD>伐<EFBFBD>** <20>滨漣嚗?27MB RSS嚗峕迤撣貉<E692A3><E8B289>湛<EFBFBD>
|
||||
<EFBFBD>?**<2A>券<EFBFBD>䈑<EFBFBD>** SAE 撠梁貌璉<EFBFBD><EFBFBD>?
|
||||
✅ **数据库检查:** 通过(连接正常)
|
||||
⚠️ **内存检查:** 降级(127MB RSS,正常范围)
|
||||
✅ **用途:** SAE 就绪检查
|
||||
|
||||
---
|
||||
|
||||
#### 5.3 霂衣<EFBFBD><EFBFBD>亙熒璉<EFBFBD><EFBFBD>亦垢<EFBFBD>?
|
||||
#### 5.3 详细健康检查端点
|
||||
|
||||
**霂瑟<EFBFBD>嚗?* `GET /health`
|
||||
**请求:** `GET /health`
|
||||
|
||||
**<EFBFBD>滚<EFBFBD>嚗?*
|
||||
**响应:**
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
@@ -248,73 +248,73 @@
|
||||
}
|
||||
```
|
||||
|
||||
<EFBFBD>?**<2A>唳旿摨枏<E691A8>摨娍𧒄<E5A88D>湛<EFBFBD>** 2ms嚗<EFBFBD><EFBFBD>蝘<EFBFBD>嚗?
|
||||
<EFBFBD>?**<2A>唳旿摨栞<E691A8><E6A09E>交㺭嚗?* 1/400 (0%)
|
||||
<EFBFBD>?**餈鞱<E9A488><E99EB1>臬<EFBFBD>嚗?* Node v22.18.0
|
||||
<EFBFBD>?**<2A><><EFBFBD>雿輻鍂嚗?* 127MB RSS嚗<EFBFBD>迤撣賂<EFBFBD>
|
||||
<EFBFBD>?**<2A>券<EFBFBD>䈑<EFBFBD>** 撘<><E69298>𤏸<EFBFBD>霂訫<E99C82><E8A8AB>烐綉
|
||||
✅ **数据库响应时间:** 2ms(优秀)
|
||||
✅ **数据库连接数:** 1/400 (0%)
|
||||
✅ **运行环境:** Node v22.18.0
|
||||
✅ **内存使用:** 127MB RSS(正常)
|
||||
✅ **用途:** 开发调试和监控
|
||||
|
||||
**摰䂿緵<EFBFBD><EFBFBD>辣嚗?*
|
||||
- `backend/src/common/health/healthCheck.ts` <EFBFBD>?
|
||||
- `backend/src/common/health/index.ts` <EFBFBD>?
|
||||
**实现文件:**
|
||||
- `backend/src/common/health/healthCheck.ts` ✅
|
||||
- `backend/src/common/health/index.ts` ✅
|
||||
|
||||
---
|
||||
|
||||
### 6. <EFBFBD>唳旿摨栞<EFBFBD><EFBFBD>交<EFBFBD> <20>?
|
||||
### 6. 数据库连接池 ✅
|
||||
|
||||
**<EFBFBD>滨蔭<EFBFBD><EFBFBD>辣嚗?* `backend/src/config/database.ts`
|
||||
**配置文件:** `backend/src/config/database.ts`
|
||||
|
||||
**撉諹<EFBFBD>憿寧𤌍嚗?*
|
||||
- <EFBFBD>?Prisma <EFBFBD>嘥<EFBFBD><EFBFBD>𡝗<EFBFBD><EFBFBD>?
|
||||
- <EFBFBD>?餈墧𦻖瘙𣳇<E79899>蝵格迤蝖?
|
||||
- <EFBFBD>?餈墧𦻖<E5A2A7>啗恣蝞梹<E89D9E>`(400 / 20) - 2 = 18` 瘥誩<EFBFBD>靘?
|
||||
- <EFBFBD>?隡㗛<E99AA1><E3979B>喲𡡒嚗锭IGTERM/SIGINT 靽∪噡憭<EFBFBD><EFBFBD>
|
||||
- <EFBFBD>?餈墧𦻖<E5A2A7>啁<EFBFBD><E59581>改<EFBFBD>`getDatabaseConnectionCount()` 甇<EFBFBD>虜
|
||||
**验证项目:**
|
||||
- ✅ Prisma 初始化成功
|
||||
- ✅ 连接池配置正确
|
||||
- ✅ 连接数计算:`(400 / 20) - 2 = 18` 每实例
|
||||
- ✅ 优雅关闭:SIGTERM/SIGINT 信号处理
|
||||
- ✅ 连接数监控:`getDatabaseConnectionCount()` 正常
|
||||
|
||||
**<EFBFBD>滨蔭<EFBFBD><EFBFBD>㺭嚗?*
|
||||
**配置参数:**
|
||||
```typescript
|
||||
connectionLimit = calculateConnectionLimit(
|
||||
DB_MAX_CONNECTIONS = 400, // RDS最大连接数
|
||||
MAX_INSTANCES = 20 // SAE最大实例数
|
||||
)
|
||||
// 蝏𤘪<EFBFBD>嚗𡁏<EFBFBD>摰硺<EFBFBD>18銝芾<EFBFBD><EFBFBD>?
|
||||
// 结果:每实例18个连接
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 7. <EFBFBD>臬<EFBFBD><EFBFBD>滨蔭蝞∠<EFBFBD> <20>?
|
||||
### 7. 环境配置管理 ✅
|
||||
|
||||
**<EFBFBD>滨蔭<EFBFBD><EFBFBD>辣嚗?* `backend/src/config/env.ts`
|
||||
**配置文件:** `backend/src/config/env.ts`
|
||||
|
||||
**撉諹<EFBFBD>憿寧𤌍嚗?*
|
||||
- <EFBFBD>?<3F>臬<EFBFBD><E887AC>㗛<EFBFBD><E3979B>㰘蝸嚗𡁏<E59A97><F0A1818F>匧<EFBFBD><E58CA7><EFBFBD><EFBFBD>㗛<EFBFBD>撌脣<E6928C>頧?
|
||||
- <EFBFBD>?<3F>滨蔭撉諹<E69289>嚗䫤validateEnv()` 甇<>虜
|
||||
- <EFBFBD>?暺䁅恕<E48185>潘<EFBFBD><E6BD98>芾挽蝵桃<E89DB5><E6A183>舫<EFBFBD>匧<EFBFBD><E58CA7>譍蝙<E8AD8D>券<EFBFBD>霈文<E99C88>?
|
||||
- <EFBFBD>?蝐餃<E89D90>摰匧<E691B0>嚗関ypeScript 蝐餃<E89D90>璉<EFBFBD><E79289>仿<EFBFBD>朞<EFBFBD>
|
||||
**验证项目:**
|
||||
- ✅ 环境变量加载:所有必需变量已加载
|
||||
- ✅ 配置验证:`validateEnv()` 正常
|
||||
- ✅ 默认值:未设置的可选变量使用默认值
|
||||
- ✅ 类型安全:TypeScript 类型检查通过
|
||||
|
||||
**<EFBFBD>滨蔭<EFBFBD><EFBFBD>掩嚗?*
|
||||
- <EFBFBD>?摨𠉛鍂<F0A0899B>滨蔭嚗<E894AD>垢<EFBFBD><E59EA2><EFBFBD><EFBFBD>㴓憓<E3B493><E68693>
|
||||
- <EFBFBD>?<3F>唳旿摨㯄<E691A8>蝵殷<E89DB5>URL<52><4C><EFBFBD><EFBFBD>交<EFBFBD>嚗?
|
||||
- <EFBFBD>?摮睃<E691AE><E79D83>滨蔭嚗<E894AD>掩<EFBFBD>卝<EFBFBD><E58D9D>楝敺<E6A59D><E695BA>
|
||||
- <EFBFBD>?蝻枏<E89DBB><E69E8F>滨蔭嚗<E894AD>掩<EFBFBD>卝<EFBFBD><E58D9D>edis嚗?
|
||||
- <EFBFBD>?隞餃𦛚<E9A483>笔<EFBFBD><E7AC94>滨蔭嚗<E894AD>掩<EFBFBD>页<EFBFBD>
|
||||
- <EFBFBD>?<3F>亙<EFBFBD><E4BA99>滨蔭嚗<E894AD>漣<EFBFBD>怒<EFBFBD><E68092><EFBFBD><EFBFBD>∪<EFBFBD>嚗?
|
||||
- <EFBFBD>?LLM<EFBFBD>滨蔭嚗㇁PI撖<EFBFBD>𤨎嚗?
|
||||
- <EFBFBD>?<3F>蠘<EFBFBD>撘<EFBFBD><E69298>喉<EFBFBD>Feature Flags嚗?
|
||||
**配置分类:**
|
||||
- ✅ 应用配置(端口、环境)
|
||||
- ✅ 数据库配置(URL、连接池)
|
||||
- ✅ 存储配置(类型、路径)
|
||||
- ✅ 缓存配置(类型、Redis)
|
||||
- ✅ 任务队列配置(类型)
|
||||
- ✅ 日志配置(级别、服务名)
|
||||
- ✅ LLM配置(API密钥)
|
||||
- ✅ 功能开关(Feature Flags)
|
||||
|
||||
---
|
||||
|
||||
### 8. <EFBFBD>烐綉<EFBFBD><EFBFBD><EFBFBD> <20>?
|
||||
### 8. 监控指标 ✅
|
||||
|
||||
**摰䂿緵<EFBFBD><EFBFBD>辣嚗?* `backend/src/common/monitoring/metrics.ts`
|
||||
**实现文件:** `backend/src/common/monitoring/metrics.ts`
|
||||
|
||||
**撉諹<EFBFBD>憿寧𤌍嚗?*
|
||||
- <EFBFBD>?<3F>唳旿摨栞<E691A8><E6A09E>交㺭<E4BAA4>烐綉嚗䫤Metrics.recordDBConnectionCount()`
|
||||
- <EFBFBD>?<3F><><EFBFBD>雿輻鍂<E8BCBB>烐綉嚗䫤Metrics.recordMemoryUsage()`
|
||||
- <EFBFBD>?<3F>𡃏郎<F0A1838F>蠘<EFBFBD>嚗朞<E59A97><E69C9E>交㺭>80%<25>嗅<EFBFBD>霅?
|
||||
- <EFBFBD>?<3F>亙<EFBFBD>颲枏枂嚗𡁏<E59A97><F0A1818F>㗇<EFBFBD><E39787><EFBFBD><EFBFBD><EFBFBD>箏<EFBFBD><E7AE8F>亙<EFBFBD>蝟餌<E89D9F>
|
||||
**验证项目:**
|
||||
- ✅ 数据库连接数监控:`Metrics.recordDBConnectionCount()`
|
||||
- ✅ 内存使用监控:`Metrics.recordMemoryUsage()`
|
||||
- ✅ 告警功能:连接数>80%时告警
|
||||
- ✅ 日志输出:所有指标输出到日志系统
|
||||
|
||||
**<EFBFBD>烐綉<EFBFBD>唳旿嚗?*
|
||||
**监控数据:**
|
||||
```
|
||||
[Monitoring] Database connection count
|
||||
current: 1
|
||||
@@ -330,58 +330,58 @@ connectionLimit = calculateConnectionLimit(
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD>圲 靽桀<E99DBD><E6A180><EFBFBD>䔮憸?
|
||||
## 🔧 修复的问题
|
||||
|
||||
### <EFBFBD>桅<EFBFBD> 1嚗𡁜<E59A97>摨瑟<E691A8><E7919F>亥楝<E4BAA5>勗<EFBFBD>蝒?
|
||||
### 问题 1:健康检查路由冲突
|
||||
|
||||
**<EFBFBD>躰秤嚗?*
|
||||
**错误:**
|
||||
```
|
||||
FastifyError [Error]: Method 'GET' already declared for route '/health'
|
||||
```
|
||||
|
||||
**<EFBFBD>笔<EFBFBD>嚗?* `/health` 頝舐眏<E88890>其舅銝芸𧑐<E88AB8>寞釣<E5AF9E>䕘<EFBFBD>`index.ts` <EFBFBD>?`healthCheck.ts`嚗?
|
||||
**原因:** `/health` 路由在两个地方注册(`index.ts` 和 `healthCheck.ts`)
|
||||
|
||||
**閫<EFBFBD><EFBFBD>嚗?* 蝘駁膄 `index.ts` 銝剔<EFBFBD><EFBFBD>滚<EFBFBD>頝舐眏嚗𣬚<EFBFBD>銝<EFBFBD><EFBFBD>?`registerHealthRoutes()` 銝剜釣<EFBFBD>?
|
||||
**解决:** 移除 `index.ts` 中的重复路由,统一在 `registerHealthRoutes()` 中注册
|
||||
|
||||
**<EFBFBD><EFBFBD>辣嚗?*
|
||||
- `backend/src/index.ts` <EFBFBD>?
|
||||
- `backend/src/common/health/healthCheck.ts` <EFBFBD>?
|
||||
**文件:**
|
||||
- `backend/src/index.ts` ✅
|
||||
- `backend/src/common/health/healthCheck.ts` ✅
|
||||
|
||||
---
|
||||
|
||||
### 问题 2:TypeScript 接口导出错误
|
||||
|
||||
**<EFBFBD>躰秤嚗?*
|
||||
**错误:**
|
||||
```
|
||||
SyntaxError: The requested module './StorageAdapter.js' does not provide an export named 'StorageAdapter'
|
||||
```
|
||||
|
||||
**<EFBFBD>笔<EFBFBD>嚗?* TypeScript <20>亙藁<E4BA99>刻<EFBFBD>銵峕𧒄銝滚<E98A9D><E6BB9A>剁<EFBFBD>銝滩<E98A9D>雿輻鍂<E8BCBB>桅<EFBFBD>𡁶<EFBFBD> `export { }` 撖澆枂
|
||||
**原因:** TypeScript 接口在运行时不存在,不能使用普通的 `export { }` 导出
|
||||
|
||||
**閫<EFBFBD><EFBFBD>嚗?* 雿輻鍂 `export type { }` 撖澆枂<EFBFBD>亙藁蝐餃<EFBFBD>
|
||||
**解决:** 使用 `export type { }` 导出接口类型
|
||||
|
||||
**靽格㺿<EFBFBD><EFBFBD>辣嚗?*
|
||||
**修改文件:**
|
||||
```typescript
|
||||
// 靽格㺿<EFBFBD>?
|
||||
// 修改前
|
||||
export { StorageAdapter } from './StorageAdapter.js'
|
||||
|
||||
// 靽格㺿<EFBFBD>?
|
||||
// 修改后
|
||||
export type { StorageAdapter } from './StorageAdapter.js'
|
||||
```
|
||||
|
||||
**敶勗<EFBFBD><EFBFBD><EFBFBD>辣嚗?*
|
||||
- `backend/src/common/storage/index.ts` <EFBFBD>?
|
||||
**影响文件:**
|
||||
- `backend/src/common/storage/index.ts` ✅
|
||||
|
||||
---
|
||||
|
||||
### 问题 3:Winston 依赖缺失
|
||||
|
||||
**<EFBFBD>躰秤嚗?* <20>曆<EFBFBD><E69B86>唳芋<E594B3>?`winston`
|
||||
**错误:** 找不到模块 `winston`
|
||||
|
||||
**閫<EFBFBD><EFBFBD>嚗?* 摰㕑<E691B0>靘肽<E99D98>
|
||||
**解决:** 安装依赖
|
||||
```bash
|
||||
npm install winston
|
||||
# @types/winston 銝漤<EFBFBD>閬<EFBFBD><EFBFBD>鋆<EFBFBD><EFBFBD>winston<EFBFBD>芸蒂蝐餃<EFBFBD>摰帋<EFBFBD>嚗?
|
||||
# @types/winston 不需要安装(winston自带类型定义)
|
||||
```
|
||||
|
||||
---
|
||||
@@ -392,29 +392,29 @@ npm install winston
|
||||
|
||||
| 文件 | 行数 | 说明 |
|
||||
|------|------|------|
|
||||
| `common/storage/StorageAdapter.ts` | 68 | 摮睃<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>冽𦻖<EFBFBD>?|
|
||||
| `common/storage/StorageAdapter.ts` | 68 | 存储适配器接口 |
|
||||
| `common/storage/LocalAdapter.ts` | 95 | 本地存储实现 |
|
||||
| `common/storage/OSSAdapter.ts` | 145 | OSS存储实现(预留) |
|
||||
| `common/storage/StorageFactory.ts` | 45 | 摮睃<EFBFBD>撌亙<EFBFBD>蝐?|
|
||||
| `common/storage/StorageFactory.ts` | 45 | 存储工厂类 |
|
||||
| `common/storage/index.ts` | 43 | 统一导出 |
|
||||
| `common/logging/logger.ts` | 72 | Winston日志配置 |
|
||||
| `common/logging/index.ts` | 11 | 统一导出 |
|
||||
| `common/cache/CacheAdapter.ts` | 77 | 蝻枏<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>冽𦻖<EFBFBD>?|
|
||||
| `common/cache/CacheAdapter.ts` | 77 | 缓存适配器接口 |
|
||||
| `common/cache/MemoryCacheAdapter.ts` | 181 | 内存缓存实现 |
|
||||
| `common/cache/RedisCacheAdapter.ts` | 212 | Redis缓存实现(预留) |
|
||||
| `common/cache/CacheFactory.ts` | 100 | 蝻枏<EFBFBD>撌亙<EFBFBD>蝐?|
|
||||
| `common/cache/CacheFactory.ts` | 100 | 缓存工厂类 |
|
||||
| `common/cache/index.ts` | 52 | 统一导出 |
|
||||
| `common/jobs/types.ts` | 82 | 任务类型定义 |
|
||||
| `common/jobs/MemoryQueue.ts` | 234 | 内存队列实现 |
|
||||
| `common/jobs/JobFactory.ts` | 84 | 任务队列工厂 |
|
||||
| `common/jobs/index.ts` | 54 | 统一导出 |
|
||||
| `common/health/healthCheck.ts` | 224 | <EFBFBD>亙熒璉<EFBFBD><EFBFBD>亥楝<EFBFBD>?|
|
||||
| `common/health/healthCheck.ts` | 224 | 健康检查路由 |
|
||||
| `common/health/index.ts` | 24 | 统一导出 |
|
||||
| `common/monitoring/metrics.ts` | 375 | 监控指标收集 |
|
||||
| `common/monitoring/index.ts` | 41 | 统一导出 |
|
||||
| `config/env.ts` | 180 | 环境配置管理 |
|
||||
| `test-platform-api.ts` | 133 | 测试API(临时) |
|
||||
| **<EFBFBD>餉恣** | **2,532銵?* | **22銝芣<EFBFBD>隞?* |
|
||||
| **总计** | **2,532行** | **22个文件** |
|
||||
|
||||
### 更新文件
|
||||
|
||||
@@ -422,28 +422,28 @@ npm install winston
|
||||
|------|---------|
|
||||
| `backend/src/index.ts` | 注册健康检查和测试API |
|
||||
| `backend/src/config/database.ts` | 添加连接池和优雅关闭 |
|
||||
| <EFBFBD><EFBFBD>﹝嚗?1銝迎<E98A9D> | <20>湔鰵<E6B994>嗆<EFBFBD><E59786><EFBFBD>﹝<EFBFBD><EFB99D><EFBFBD><EFBFBD>𤏸<EFBFBD><F0A48FB8>?|
|
||||
| 文档(11个) | 更新架构文档和开发规范 |
|
||||
|
||||
---
|
||||
|
||||
## 🎯 验收结论
|
||||
|
||||
### <EFBFBD>?<3F>券<EFBFBD><E588B8>朞<EFBFBD>憿寧𤌍
|
||||
### ✅ 全部通过项目
|
||||
|
||||
1. **存储服务** - LocalAdapter 完整实现并验证通过
|
||||
2. **日志系统** - Winston 配置完成,支持结构化日志
|
||||
3. **缓存服务** - MemoryCacheAdapter 完整实现
|
||||
4. **异步任务** - MemoryQueue 完整实现
|
||||
5. **<EFBFBD>亙熒璉<EFBFBD><EFBFBD>?* - 銝劐葵蝡舐<E89DA1><E88890>券<EFBFBD>甇<EFBFBD>虜
|
||||
6. **<EFBFBD>唳旿摨栞<EFBFBD><EFBFBD>交<EFBFBD>** - <EFBFBD>滨蔭甇<EFBFBD>&嚗𣬚<EFBFBD><EFBFBD>扳迤撣?
|
||||
7. **<EFBFBD>臬<EFBFBD><EFBFBD>滨蔭** - <EFBFBD>㰘蝸<EFBFBD>屸<EFBFBD>霂<EFBFBD>迤撣?
|
||||
5. **健康检查** - 三个端点全部正常
|
||||
6. **数据库连接池** - 配置正确,监控正常
|
||||
7. **环境配置** - 加载和验证正常
|
||||
8. **监控指标** - 数据采集正常
|
||||
|
||||
### <EFBFBD><EFBFBD> <20>臭誑撘<E8AA91>憪?ASL 璅∪<E79285>撘<EFBFBD><E69298>?
|
||||
### 🚀 可以开始 ASL 模块开发
|
||||
|
||||
**撟喳蝱<EFBFBD>箇<EFBFBD>霈暹鴌撌脣停蝏迎<EFBFBD><EFBFBD><EFBFBD><EFBFBD>匧<EFBFBD><EFBFBD>賡<EFBFBD>霂<EFBFBD><EFBFBD>朞<EFBFBD>嚗?*
|
||||
**平台基础设施已就绪,所有功能验证通过!**
|
||||
|
||||
銝𡁜𦛚璅∪<EFBFBD>撘<EFBFBD><EFBFBD>烐𧒄<EFBFBD>臭誑<EFBFBD>湔𦻖雿輻鍂嚗?
|
||||
业务模块开发时可以直接使用:
|
||||
|
||||
```typescript
|
||||
import { storage } from '@/common/storage'
|
||||
@@ -452,21 +452,21 @@ import { cache } from '@/common/cache'
|
||||
import { jobQueue } from '@/common/jobs'
|
||||
```
|
||||
|
||||
**<EFBFBD>嗡誨<EFBFBD><EFBFBD>㴓憓<EFBFBD><EFBFBD><EFBFBD>g<EFBFBD>** <20>芷<EFBFBD>靽格㺿<E6A0BC>臬<EFBFBD><E887AC>㗛<EFBFBD>嚗峕<E59A97><E5B395><EFBFBD><EFBFBD>孵𢆡銝𡁜𦛚隞<F0A69B9A><E99A9E>嚗?
|
||||
**零代码环境切换:** 只需修改环境变量,无需改动业务代码!
|
||||
|
||||
---
|
||||
|
||||
## 📝 后续工作
|
||||
|
||||
### 敶枏<EFBFBD><EFBFBD>臭誑<EFBFBD>𡁶<EFBFBD>嚗<EFBFBD>𧋦<EFBFBD>啁㴓憓<EFBFBD><EFBFBD><EFBFBD>?
|
||||
### 当前可以做的(本地环境)✅
|
||||
|
||||
- <EFBFBD>?撘<><E69298>?ASL 璅∪<E79285>嚗<EFBFBD>蝙<EFBFBD>?LocalAdapter嚗?
|
||||
- <EFBFBD>?撘<><E69298>穃<EFBFBD>隞碶<E99A9E><E7A2B6>⊥芋<E28AA5>?
|
||||
- <EFBFBD>?<3F>砍𧑐瘚贝<E7989A><E8B49D>屸<EFBFBD>霂?
|
||||
- ✅ 开发 ASL 模块(使用 LocalAdapter)
|
||||
- ✅ 开发其他业务模块
|
||||
- ✅ 本地测试和验证
|
||||
|
||||
### 鈭𤑳垢<EFBFBD>函蔡<EFBFBD>漤<EFBFBD>閬<EFBFBD><EFBFBD><EFBFBD>?<3F><>
|
||||
### 云端部署前需要做的 🔄
|
||||
|
||||
1. **摰㕑<EFBFBD>鈭烐<EFBFBD><EFBFBD>∩<EFBFBD>韏?*
|
||||
1. **安装云服务依赖**
|
||||
```bash
|
||||
npm install ali-oss # 阿里云OSS
|
||||
npm install ioredis # Redis
|
||||
@@ -486,34 +486,34 @@ import { jobQueue } from '@/common/jobs'
|
||||
|
||||
4. **部署测试**
|
||||
- SAE 环境部署
|
||||
- 餈墧𦻖瘙䭾<EFBFBD>霂?
|
||||
- <EFBFBD>亙熒璉<EFBFBD><EFBFBD>仿<EFBFBD>霂?
|
||||
- 连接池测试
|
||||
- 健康检查验证
|
||||
- 性能测试
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD>?<3F>餌<EFBFBD>
|
||||
## ✨ 总结
|
||||
|
||||
**摰墧鴌<EFBFBD>園𡢿嚗?* 2025-11-17嚗?憭抬<E686AD>
|
||||
**摰墧鴌<EFBFBD><EFBFBD>捆嚗?* 8銝芸像<E88AB8>啣抅蝖<E68A85>霈暹鴌璅∪<E79285>
|
||||
**实施时间:** 2025-11-17(1天)
|
||||
**实施内容:** 8个平台基础设施模块
|
||||
**代码量:** 2,532行新代码
|
||||
**测试通过率:** 100%
|
||||
**<EFBFBD>函蔡撠梁貌摨佗<EFBFBD>** <20>砍𧑐<E7A08D>臬<EFBFBD> <20>?/ 鈭𤑳垢<F0A491B3>臬<EFBFBD> <20><>嚗<EFBFBD><E59A97>摰㕑<E691B0>靘肽<E99D98>嚗?
|
||||
**部署就绪度:** 本地环境 ✅ / 云端环境 🔄(需安装依赖)
|
||||
|
||||
**<EFBFBD>詨<EFBFBD><EFBFBD>鞉<EFBFBD>嚗?*
|
||||
- <EFBFBD>?<3F><><EFBFBD><EFBFBD>冽芋撘誩<E69298><E8AAA9>堆<EFBFBD><E5A086>舀<EFBFBD><E88880>嗡誨<E597A1><E8AAA8>㴓憓<E3B493><E68693><EFBFBD>?
|
||||
- <EFBFBD>?摰峕㟲<E5B395><E39FB2>像<EFBFBD>啣抅蝖<E68A85>霈暹鴌雿梶頂
|
||||
- <EFBFBD>?<3F><><EFBFBD>匧<EFBFBD><E58CA7>賜<EFBFBD>餈<EFBFBD><E9A488><EFBFBD><EFBFBD><EFBFBD>霂閖<E99C82>霂?
|
||||
- <EFBFBD>?<3F><>﹝摰峕㟲嚗峕鰵鈭箏虾敹恍<E695B9>煺<EFBFBD><E785BA>?
|
||||
- <EFBFBD>?銝?ASL 璅∪<E79285>撘<EFBFBD><E69298>穃<EFBFBD>憟賢<E6869F>憭?
|
||||
**核心成果:**
|
||||
- ✅ 适配器模式实现,支持零代码环境切换
|
||||
- ✅ 完整的平台基础设施体系
|
||||
- ✅ 所有功能经过实际测试验证
|
||||
- ✅ 文档完整,新人可快速上手
|
||||
- ✅ 为 ASL 模块开发做好准备
|
||||
|
||||
**銝衤<EFBFBD>甇伐<EFBFBD>** <20><> 撘<>憪?ASL-AI<41>箄<EFBFBD><E7AE84><EFBFBD>讃璅∪<E79285>撘<EFBFBD><E69298>𡢅<EFBFBD>
|
||||
**下一步:** 🚀 开始 ASL-AI智能文献模块开发!
|
||||
|
||||
---
|
||||
|
||||
**<EFBFBD>亙<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>園𡢿嚗?* 2025-11-17 23:54
|
||||
**报告生成时间:** 2025-11-17 23:54
|
||||
**验证执行人:** AI Assistant + 用户
|
||||
**<EFBFBD>亙<EFBFBD><EFBFBD>嗆<EFBFBD><EFBFBD><EFBFBD>** <20>?摰峕<E691B0>
|
||||
**报告状态:** ✅ 完成
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user