docs: camera_code改造测试报告
添加完整的测试报告文档,包括: - 测试概述与环境要求 - 数据库迁移验证步骤 - 功能测试用例(摄像头创建、ROI截图、配置推送) - 数据一致性测试 - 异常测试场景 - 性能测试 - 集成测试场景 - 回归测试 - 测试清单与风险评估 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
546
docs/camera_code改造测试报告.md
Normal file
546
docs/camera_code改造测试报告.md
Normal file
@@ -0,0 +1,546 @@
|
||||
# camera_code 改造测试报告
|
||||
|
||||
## 一、测试概述
|
||||
|
||||
**测试目标**: 验证 camera_code 全链路改造的功能完整性和数据一致性
|
||||
|
||||
**测试时间**: 2026-02-13
|
||||
|
||||
**改造范围**:
|
||||
- 后端:数据库、StreamProxy模块、AIoT模块
|
||||
- 前端:摄像头管理、ROI配置、API调用
|
||||
|
||||
**测试环境要求**:
|
||||
- MySQL 5.7+
|
||||
- Redis 6.0+
|
||||
- ZLMediaKit 流媒体服务器
|
||||
- 前端开发环境(Node.js 18+)
|
||||
- 后端 Java 环境(JDK 17+)
|
||||
|
||||
---
|
||||
|
||||
## 二、测试准备
|
||||
|
||||
### 2.1 数据库迁移验证
|
||||
|
||||
**脚本位置**: `C:\workspace\wvp-platform\数据库\aiot\迁移-添加camera_code字段.sql`
|
||||
|
||||
**执行步骤**:
|
||||
```bash
|
||||
# 1. 进入SQL脚本目录
|
||||
cd C:\workspace\wvp-platform\数据库\aiot
|
||||
|
||||
# 2. 执行迁移脚本(需要MySQL客户端)
|
||||
mysql -h localhost -u root -p your_database < 迁移-添加camera_code字段.sql
|
||||
```
|
||||
|
||||
**预期结果**:
|
||||
1. ✅ `wvp_stream_proxy` 表新增 `camera_code` 字段
|
||||
2. ✅ 现有数据自动生成 `camera_code`(格式:`cam_xxxxxxxxxxxx`)
|
||||
3. ✅ `camera_code` 字段设置为 NOT NULL 和 UNIQUE 约束
|
||||
4. ✅ `wvp_ai_roi` 表的 `camera_id` 字段更新为对应的 `camera_code`
|
||||
5. ✅ 验证查询显示无重复、无格式错误
|
||||
|
||||
**验证SQL**:
|
||||
```sql
|
||||
-- 检查字段是否添加成功
|
||||
SHOW COLUMNS FROM wvp_stream_proxy LIKE 'camera_code';
|
||||
|
||||
-- 检查唯一索引
|
||||
SHOW INDEX FROM wvp_stream_proxy WHERE Key_name = 'uk_camera_code';
|
||||
|
||||
-- 检查数据完整性(应返回0)
|
||||
SELECT COUNT(*) FROM wvp_stream_proxy WHERE camera_code IS NULL;
|
||||
|
||||
-- 检查格式正确性(应返回0)
|
||||
SELECT COUNT(*) FROM wvp_stream_proxy
|
||||
WHERE camera_code NOT REGEXP '^cam_[a-f0-9]{12}$';
|
||||
|
||||
-- 检查ROI表迁移情况
|
||||
SELECT COUNT(*) FROM wvp_ai_roi r
|
||||
LEFT JOIN wvp_stream_proxy sp ON r.camera_id = sp.camera_code
|
||||
WHERE sp.camera_code IS NULL;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 三、功能测试用例
|
||||
|
||||
### 3.1 新增摄像头 - camera_code 自动生成
|
||||
|
||||
**测试目的**: 验证创建摄像头时 camera_code 自动生成逻辑
|
||||
|
||||
**前置条件**:
|
||||
- 系统正常运行
|
||||
- 流媒体服务器在线
|
||||
|
||||
**测试步骤**:
|
||||
1. 访问前端摄像头管理页面
|
||||
2. 点击"新增摄像头"按钮
|
||||
3. 填写摄像头信息:
|
||||
- 名称:测试摄像头001
|
||||
- 拉流地址:rtsp://example.com/test/stream1
|
||||
- 超时时间:默认
|
||||
- 注意:**不需要手动填写 app 字段**(系统自动生成)
|
||||
4. 提交保存
|
||||
|
||||
**预期结果**:
|
||||
1. ✅ 摄像头创建成功
|
||||
2. ✅ 系统自动生成 `camera_code`(格式:`cam_xxxxxxxxxxxx`)
|
||||
3. ✅ `app` 字段自动设置为与 `camera_code` 相同
|
||||
4. ✅ `stream` 字段为系统生成的唯一标识
|
||||
5. ✅ 数据库 `wvp_stream_proxy` 表中插入新记录
|
||||
|
||||
**验证SQL**:
|
||||
```sql
|
||||
SELECT id, camera_code, app, stream, name, src_url
|
||||
FROM wvp_stream_proxy
|
||||
WHERE name = '测试摄像头001';
|
||||
```
|
||||
|
||||
**重点检查**:
|
||||
- `camera_code` 格式符合 `^cam_[a-f0-9]{12}$`
|
||||
- `app` = `camera_code`
|
||||
- `camera_code` 在全表唯一
|
||||
|
||||
---
|
||||
|
||||
### 3.2 ROI 截图功能 - cameraCode 参数
|
||||
|
||||
**测试目的**: 验证 ROI 截图接口改用 cameraCode 参数
|
||||
|
||||
**前置条件**:
|
||||
- 摄像头已创建并在线推流
|
||||
- 流媒体服务器正常
|
||||
|
||||
**测试步骤**:
|
||||
1. 访问 ROI 配置页面
|
||||
2. 选择已创建的摄像头
|
||||
3. 点击"获取截图"按钮
|
||||
4. 观察网络请求(F12开发者工具)
|
||||
|
||||
**预期结果**:
|
||||
1. ✅ 请求 URL:`/api/ai/roi/snap?cameraCode=cam_xxxxxxxxxxxx`
|
||||
2. ✅ 使用 `cameraCode` 参数(而非旧的 `app`/`stream`)
|
||||
3. ✅ 后端通过 `cameraCode` 查询 `StreamProxy` 对象
|
||||
4. ✅ 获取到正确的 `app` 和 `stream` 值
|
||||
5. ✅ 调用 ZLM 截图接口成功,返回图片数据
|
||||
|
||||
**验证方法**:
|
||||
```javascript
|
||||
// 浏览器控制台查看请求
|
||||
// Network > Headers > Request URL
|
||||
// 应包含 cameraCode=cam_xxxxxxxxxxxx
|
||||
```
|
||||
|
||||
**错误处理测试**:
|
||||
- 使用不存在的 `cameraCode` → 返回 404 Not Found
|
||||
- 流媒体服务器离线 → 返回 503 Service Unavailable
|
||||
|
||||
---
|
||||
|
||||
### 3.3 配置推送到 Redis - camera_code 字段
|
||||
|
||||
**测试目的**: 验证配置推送使用 camera_code 查询和生成配置
|
||||
|
||||
**前置条件**:
|
||||
- Redis 服务正常
|
||||
- ROI 已配置并绑定算法
|
||||
- Edge 设备在线
|
||||
|
||||
**测试步骤**:
|
||||
1. 访问配置管理页面
|
||||
2. 创建或更新 ROI 配置
|
||||
3. 绑定算法模板
|
||||
4. 执行"配置推送"操作
|
||||
5. 检查 Redis 中的配置数据
|
||||
|
||||
**预期结果**:
|
||||
1. ✅ 配置构建时使用 `camera_code` 查询 `StreamProxy`
|
||||
2. ✅ 优先使用 `StreamProxy.srcUrl` 作为 `rtsp_url`
|
||||
3. ✅ Redis 配置中包含 `camera_code` 字段
|
||||
4. ✅ 保留 `camera_id` 字段向后兼容(值为 `app/stream`)
|
||||
5. ✅ StreamProxy 不存在时降级使用 MediaServer 构建 URL
|
||||
|
||||
**验证命令**:
|
||||
```bash
|
||||
# 连接 Redis 检查配置
|
||||
redis-cli
|
||||
|
||||
# 查看配置 key
|
||||
KEYS aiot:edge:config:*
|
||||
|
||||
# 查看具体配置内容
|
||||
GET aiot:edge:config:{edge_device_id}
|
||||
|
||||
# 检查配置 JSON 中的字段
|
||||
# 应包含:
|
||||
# - camera_code: "cam_xxxxxxxxxxxx"
|
||||
# - camera_id: "app/stream" (向后兼容)
|
||||
# - rtsp_url: 优先来自 StreamProxy.srcUrl
|
||||
```
|
||||
|
||||
**配置示例**:
|
||||
```json
|
||||
{
|
||||
"cameras": [
|
||||
{
|
||||
"camera_code": "cam_a1b2c3d4e5f6",
|
||||
"camera_id": "cam_a1b2c3d4e5f6/stream_12345",
|
||||
"rtsp_url": "rtsp://example.com/test/stream1",
|
||||
"rois": [
|
||||
{
|
||||
"roi_id": "roi_001",
|
||||
"coordinates": [...],
|
||||
"algorithms": [...]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3.4 前端展示和交互
|
||||
|
||||
**测试目的**: 验证前端页面正确使用 camera_code
|
||||
|
||||
**测试用例 3.4.1 - 摄像头管理页面**:
|
||||
|
||||
**测试步骤**:
|
||||
1. 访问摄像头管理页面
|
||||
2. 查看摄像头列表
|
||||
3. 新增/编辑摄像头
|
||||
|
||||
**预期结果**:
|
||||
1. ✅ 列表正确显示 `cameraCode` 字段
|
||||
2. ✅ 新增表单**隐藏** `app` 输入框(自动生成)
|
||||
3. ✅ API 调用使用新的 `cameraCode` 字段
|
||||
4. ✅ 数据保存后正确回显
|
||||
|
||||
**测试用例 3.4.2 - ROI 配置页面**:
|
||||
|
||||
**测试步骤**:
|
||||
1. 访问 ROI 配置页面
|
||||
2. 选择摄像头
|
||||
3. 获取截图
|
||||
4. 配置 ROI 区域
|
||||
|
||||
**预期结果**:
|
||||
1. ✅ 摄像头选择器显示 `cameraCode` 和名称
|
||||
2. ✅ 截图请求使用 `cameraCode` 参数
|
||||
3. ✅ ROI 保存时关联正确的 `cameraCode`
|
||||
4. ✅ 配置查询使用 `cameraCode` 匹配
|
||||
|
||||
---
|
||||
|
||||
## 四、数据一致性测试
|
||||
|
||||
### 4.1 迁移数据验证
|
||||
|
||||
**测试目的**: 确保历史数据正确迁移
|
||||
|
||||
**验证SQL**:
|
||||
```sql
|
||||
-- 1. 检查所有 camera_code 都已生成
|
||||
SELECT COUNT(*) AS total,
|
||||
COUNT(camera_code) AS has_code
|
||||
FROM wvp_stream_proxy;
|
||||
-- total 应等于 has_code
|
||||
|
||||
-- 2. 检查 camera_code 格式
|
||||
SELECT id, camera_code
|
||||
FROM wvp_stream_proxy
|
||||
WHERE camera_code NOT REGEXP '^cam_[a-f0-9]{12}$';
|
||||
-- 应返回空
|
||||
|
||||
-- 3. 检查唯一性
|
||||
SELECT camera_code, COUNT(*) AS cnt
|
||||
FROM wvp_stream_proxy
|
||||
GROUP BY camera_code
|
||||
HAVING cnt > 1;
|
||||
-- 应返回空
|
||||
|
||||
-- 4. 检查 ROI 表关联
|
||||
SELECT r.roi_id, r.camera_id, r.name
|
||||
FROM wvp_ai_roi r
|
||||
LEFT JOIN wvp_stream_proxy sp ON r.camera_id = sp.camera_code
|
||||
WHERE sp.camera_code IS NULL;
|
||||
-- 应返回空(所有 ROI 都能找到对应的 camera_code)
|
||||
```
|
||||
|
||||
### 4.2 新旧数据兼容性
|
||||
|
||||
**测试场景**: 系统同时存在迁移的旧数据和新创建的数据
|
||||
|
||||
**验证点**:
|
||||
1. ✅ 旧数据的 `camera_code` 格式正确
|
||||
2. ✅ 新数据的 `camera_code` 与旧数据不冲突
|
||||
3. ✅ ROI 查询同时支持新旧数据
|
||||
4. ✅ 配置推送对新旧数据处理一致
|
||||
|
||||
---
|
||||
|
||||
## 五、异常测试
|
||||
|
||||
### 5.1 camera_code 重复冲突
|
||||
|
||||
**测试目的**: 验证重试机制
|
||||
|
||||
**模拟方法**:
|
||||
- 理论上 UUID 生成的12位哈希极低概率重复
|
||||
- 系统已实现最多3次重试机制
|
||||
|
||||
**预期结果**:
|
||||
- ✅ 第一次冲突时自动重试
|
||||
- ✅ 3次都冲突则抛出异常
|
||||
- ✅ 错误日志记录详细信息
|
||||
|
||||
### 5.2 StreamProxy 不存在
|
||||
|
||||
**测试场景**: 使用无效的 cameraCode 调用接口
|
||||
|
||||
**测试步骤**:
|
||||
1. 调用截图接口:`/api/ai/roi/snap?cameraCode=cam_invalid123`
|
||||
2. 调用配置推送时 ROI 关联了不存在的 camera_code
|
||||
|
||||
**预期结果**:
|
||||
- ✅ 截图接口返回 404 Not Found
|
||||
- ✅ 配置推送时跳过该摄像头或使用降级逻辑
|
||||
- ✅ 错误日志记录
|
||||
|
||||
### 5.3 数据库迁移失败回滚
|
||||
|
||||
**测试场景**: 迁移脚本执行失败
|
||||
|
||||
**可能原因**:
|
||||
- 数据库权限不足
|
||||
- 表不存在
|
||||
- 字段已存在
|
||||
|
||||
**验证方法**:
|
||||
```sql
|
||||
-- 检查迁移是否完成
|
||||
SHOW COLUMNS FROM wvp_stream_proxy LIKE 'camera_code';
|
||||
|
||||
-- 如果失败,检查错误日志
|
||||
SHOW ENGINE INNODB STATUS;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、性能测试
|
||||
|
||||
### 6.1 camera_code 生成性能
|
||||
|
||||
**测试方法**: 批量创建摄像头
|
||||
|
||||
**测试步骤**:
|
||||
1. 使用脚本批量调用新增摄像头接口
|
||||
2. 创建 100 个摄像头
|
||||
3. 记录平均响应时间
|
||||
|
||||
**预期结果**:
|
||||
- ✅ 单次生成 camera_code 耗时 < 5ms
|
||||
- ✅ 数据库唯一索引查询性能正常
|
||||
- ✅ 重试机制不影响整体性能
|
||||
|
||||
### 6.2 查询性能
|
||||
|
||||
**测试SQL**:
|
||||
```sql
|
||||
-- 1. 按 camera_code 查询(应使用唯一索引)
|
||||
EXPLAIN SELECT * FROM wvp_stream_proxy WHERE camera_code = 'cam_a1b2c3d4e5f6';
|
||||
-- type: const 或 eq_ref
|
||||
|
||||
-- 2. ROI 关联查询
|
||||
EXPLAIN SELECT r.*, sp.name, sp.src_url
|
||||
FROM wvp_ai_roi r
|
||||
INNER JOIN wvp_stream_proxy sp ON r.camera_id = sp.camera_code
|
||||
WHERE sp.camera_code = 'cam_a1b2c3d4e5f6';
|
||||
-- 应使用索引
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 七、集成测试场景
|
||||
|
||||
### 场景1: 完整业务流程
|
||||
|
||||
**流程步骤**:
|
||||
1. 新增摄像头(自动生成 camera_code)
|
||||
2. 创建 ROI 区域(关联 camera_code)
|
||||
3. 绑定算法模板
|
||||
4. 获取截图验证(使用 cameraCode 参数)
|
||||
5. 推送配置到 Redis(包含 camera_code)
|
||||
6. Edge 设备消费配置
|
||||
|
||||
**验证点**:
|
||||
- ✅ 每个步骤数据传递正确
|
||||
- ✅ camera_code 作为全局唯一标识贯穿全流程
|
||||
- ✅ 前后端数据一致
|
||||
|
||||
### 场景2: 多摄像头配置
|
||||
|
||||
**测试步骤**:
|
||||
1. 创建 5 个摄像头
|
||||
2. 为每个摄像头配置 2-3 个 ROI
|
||||
3. 绑定不同算法
|
||||
4. 批量推送配置
|
||||
|
||||
**验证点**:
|
||||
- ✅ 所有 camera_code 唯一
|
||||
- ✅ ROI 正确关联到对应摄像头
|
||||
- ✅ Redis 配置结构正确
|
||||
- ✅ 无数据混乱
|
||||
|
||||
---
|
||||
|
||||
## 八、回归测试
|
||||
|
||||
### 8.1 旧功能验证
|
||||
|
||||
**测试项**:
|
||||
- ✅ 摄像头列表查询
|
||||
- ✅ 摄像头编辑/删除
|
||||
- ✅ 流媒体代理功能
|
||||
- ✅ 国标设备对接
|
||||
- ✅ 录像管理
|
||||
|
||||
**预期**: 所有旧功能正常工作,不受 camera_code 改造影响
|
||||
|
||||
### 8.2 API 兼容性
|
||||
|
||||
**验证点**:
|
||||
- ✅ 新接口正确处理 cameraCode
|
||||
- ✅ 旧接口(如果有)仍可用或有明确废弃提示
|
||||
- ✅ 响应数据结构兼容
|
||||
|
||||
---
|
||||
|
||||
## 九、测试总结
|
||||
|
||||
### 9.1 测试清单
|
||||
|
||||
| 测试项 | 优先级 | 状态 | 备注 |
|
||||
|--------|--------|------|------|
|
||||
| 数据库迁移脚本执行 | P0 | ⏳待测 | 需要MySQL环境 |
|
||||
| camera_code 自动生成 | P0 | ⏳待测 | 核心功能 |
|
||||
| camera_code 唯一性 | P0 | ⏳待测 | 数据完整性 |
|
||||
| ROI 截图接口 cameraCode 参数 | P0 | ⏳待测 | API改造 |
|
||||
| 配置推送 camera_code 字段 | P0 | ⏳待测 | Redis配置 |
|
||||
| 前端摄像头管理页面 | P1 | ⏳待测 | UI交互 |
|
||||
| 前端 ROI 配置页面 | P1 | ⏳待测 | UI交互 |
|
||||
| 数据一致性验证 | P0 | ⏳待测 | 迁移验证 |
|
||||
| 异常处理测试 | P1 | ⏳待测 | 容错机制 |
|
||||
| 性能测试 | P2 | ⏳待测 | 非阻塞 |
|
||||
|
||||
### 9.2 风险评估
|
||||
|
||||
**高风险项**:
|
||||
1. 数据库迁移失败 → **建议先备份数据库**
|
||||
2. 历史数据 camera_code 生成冲突 → 已有重试机制
|
||||
3. ROI 表 camera_id 更新不完整 → 迁移脚本有验证SQL
|
||||
|
||||
**缓解措施**:
|
||||
- 在测试环境先完整执行一遍
|
||||
- 准备回滚方案
|
||||
- 监控生产环境日志
|
||||
|
||||
### 9.3 建议测试顺序
|
||||
|
||||
1. **第一阶段(核心功能)**:
|
||||
- 数据库迁移
|
||||
- camera_code 自动生成
|
||||
- 数据一致性验证
|
||||
|
||||
2. **第二阶段(接口改造)**:
|
||||
- ROI 截图接口
|
||||
- 配置推送功能
|
||||
- API 调用验证
|
||||
|
||||
3. **第三阶段(前端集成)**:
|
||||
- 摄像头管理页面
|
||||
- ROI 配置页面
|
||||
- 端到端流程测试
|
||||
|
||||
4. **第四阶段(回归测试)**:
|
||||
- 旧功能验证
|
||||
- 性能测试
|
||||
- 异常场景
|
||||
|
||||
### 9.4 部署前检查项
|
||||
|
||||
- [ ] 数据库迁移脚本在测试环境验证通过
|
||||
- [ ] 所有 P0 测试用例通过
|
||||
- [ ] 前后端代码已同步部署
|
||||
- [ ] Redis 配置结构兼容旧版本(向后兼容)
|
||||
- [ ] 回滚方案准备就绪
|
||||
- [ ] 监控告警配置完成
|
||||
|
||||
---
|
||||
|
||||
## 十、附录
|
||||
|
||||
### 附录A: 相关代码文件清单
|
||||
|
||||
**后端文件**:
|
||||
- `StreamProxy.java` - 新增 cameraCode 字段
|
||||
- `StreamProxyMapper.java` - 新增 selectByCameraCode 查询
|
||||
- `StreamProxyProvider.java` - SQL 生成逻辑
|
||||
- `StreamProxyServiceImpl.java` - 自动生成和查询实现
|
||||
- `IStreamProxyService.java` - 接口声明
|
||||
- `AiRoiController.java` - snap 接口改造
|
||||
- `AiRedisConfigServiceImpl.java` - 配置推送改造
|
||||
|
||||
**前端文件**:
|
||||
- `apps/web-antd/src/api/aiot/device/index.ts` - API 类型定义
|
||||
- `apps/web-antd/src/views/aiot/device/camera/index.vue` - 摄像头管理页面
|
||||
- `apps/web-antd/src/views/aiot/device/roi/index.vue` - ROI 配置页面
|
||||
- `apps/web-antd/src/views/aiot/device/roi/components/*.vue` - ROI 子组件
|
||||
|
||||
**数据库文件**:
|
||||
- `数据库/aiot/迁移-添加camera_code字段.sql` - 迁移脚本
|
||||
|
||||
### 附录B: Git 提交记录
|
||||
|
||||
```
|
||||
450afb811 feat(aiot): 配置推送使用camera_code查询StreamProxy
|
||||
6d1e1d0bc feat(aiot): snap接口改用cameraCode参数查询StreamProxy
|
||||
3792a3061 feat(streamProxy): 实现camera_code自动生成和查询逻辑
|
||||
754677e11 feat(streamProxy): Service接口新增getStreamProxyByCameraCode方法
|
||||
2b61113ba feat(streamProxy): Provider增加camera_code的SQL处理
|
||||
2e89c2a62 feat(streamProxy): Mapper新增selectByCameraCode查询方法
|
||||
b542432dc feat(streamProxy): StreamProxy增加cameraCode字段
|
||||
0c8037726 fix(aiot): 迁移脚本增加camera_code格式验证
|
||||
731291217 feat(aiot): 添加camera_code字段迁移脚本
|
||||
ac345a472 feat(aiot): ROI配置页面改用cameraCode参数和截图调用
|
||||
4bbc4b16d feat(aiot): 摄像头管理页面改用cameraCode,隐藏app输入
|
||||
2583ed533 feat(aiot): Camera接口增加cameraCode字段,getSnapUrl改用cameraCode
|
||||
```
|
||||
|
||||
### 附录C: 测试数据示例
|
||||
|
||||
**摄像头测试数据**:
|
||||
```sql
|
||||
INSERT INTO wvp_stream_proxy (camera_code, app, stream, name, src_url, timeout, enable)
|
||||
VALUES
|
||||
('cam_test1234567', 'cam_test1234567', 'stream_001', '测试摄像头001', 'rtsp://example.com/test1', 30, 1),
|
||||
('cam_test7654321', 'cam_test7654321', 'stream_002', '测试摄像头002', 'rtsp://example.com/test2', 30, 1);
|
||||
```
|
||||
|
||||
**ROI 测试数据**:
|
||||
```sql
|
||||
INSERT INTO wvp_ai_roi (roi_id, camera_id, name, points)
|
||||
VALUES
|
||||
('roi_001', 'cam_test1234567', 'ROI区域1', '[[0,0],[100,0],[100,100],[0,100]]'),
|
||||
('roi_002', 'cam_test1234567', 'ROI区域2', '[[200,200],[300,200],[300,300],[200,300]]');
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**文档版本**: v1.0
|
||||
**创建时间**: 2026-02-13
|
||||
**创建人**: AI开发团队
|
||||
**审核状态**: 待审核
|
||||
Reference in New Issue
Block a user