Files
H3ConuMS-v2/CLAUDE.md
T
v6ole dcb2435514 ```
feat: 升级到v0.8.0版本并新增审计日志等功能

- 升级版本号从v0.7.0到v0.8.0
- 新增审计日志功能,支持全量操作记录、筛选查询和CSV导出
- 新增设备更换记录功能,支持MAC地址更换历史与库存序列号联动
- 新增iOS PWA主屏幕支持,实现standalone模式safe area适配
- 删除过时的技术流程文档
- 补充开发规范说明,包括Alembic迁移、Celery worker重建、区域管理员过滤等重要规则
```
2026-04-08 16:59:24 +08:00

14 KiB
Raw Blame History

H3C ONU设备管理系统 - Claude开发指南

项目概述

这是一个基于 Python FastAPI + Vue 3 的 H3C OLT 设备监控管理系统,用于监控 4000+ ONU 设备的在线状态。

当前版本: v0.8.0 开发状态: 核心功能已完成,权限与运维功能完善中

已实现功能

  • SSH 连接 H3C OLT 设备查询 ONU 状态(支持 More 分页、终端控制字符清理)
  • Excel 数据导入和批量管理
  • 定时自动状态检查(可配置间隔,最小5分钟)+ 手动触发
  • Casdoor 统一认证和 JWT 令牌管理
  • 设备管理(列表、详情、筛选、分页)
  • 统计仪表板(总数、在线、离线)+ 区域分布饼图 + 7天趋势折线图
  • 完整 RBAC 权限管理(角色、权限、用户管理页面)
  • OLT 管理(增删改查、批量导入、区域动态同步)
  • OLT 端口管理(查看端口状态、开关端口)
  • 重复 MAC 检测与清除
  • 新设备发现与信息补全
  • 快速扫描(多线程并发)
  • 环路检测
  • 系统设置(管理员可配置检查间隔,显示下次扫描时间/扫描中状态)
  • 库存管理模块(物料、序列号设备、出入库、盘点)
  • 每日状态快照(凌晨1点聚合,用于趋势图性能优化)
  • 审计日志(全量操作记录、筛选查询、CSV 导出)
  • 设备更换记录(MAC 地址更换历史,与库存序列号联动)
  • iOS PWA 主屏幕支持(standalone 模式 safe area 适配)

技术栈

  • 后端:Python FastAPI + PostgreSQL + Celery + Redis + Paramiko
  • 前端:Vue 3 + Element Plus + Pinia + Axios
  • 部署:Docker Compose

已实现的 API 端点

认证相关

  • GET /api/auth/login - 获取 Casdoor 登录 URL
  • POST /api/auth/callback - Casdoor 登录回调
  • GET /api/auth/profile - 获取当前用户信息

设备管理

  • GET /api/devices - 获取设备列表(分页、筛选)
  • GET /api/devices/{id} - 获取设备详情

状态检查

  • POST /api/check/status - 手动触发状态检查

数据导入

  • POST /api/import/upload - 上传并导入 Excel 文件

统计信息

  • GET /api/stats/summary - 获取统计摘要(总数、在线、离线)

系统

  • GET /health - 健康检查
  • GET /docs - API 文档(Swagger UI

Rules

代码规范

Python 后端规范

  • 遵循 PEP 8 规范
  • 使用 Black 进行代码格式化
  • 使用 isort 进行导入排序
  • 使用类型注解(Type Hints
  • 异步函数使用 async/await
  • 错误处理使用自定义异常类

Vue 前端规范

  • 使用 Composition APIsetup script
  • 组件使用 PascalCase 命名
  • 使用 TypeScript 类型检查
  • 遵循 Vue 官方风格指南
  • 使用 ESLint + Prettier 格式化

Git 提交规范

使用 Conventional Commits 格式:

<type>(<scope>): <subject>

类型:feat, fix, docs, style, refactor, test, chore
示例:feat(device): 添加设备导入功能

架构规则

后端架构

  • 分层架构API → Service → Model
  • API 层:仅处理请求/响应,调用 Service
  • Service 层:业务逻辑,不直接操作数据库
  • Model 层SQLAlchemy 模型定义
  • 异步任务:耗时操作使用 Celery

前端架构

  • 组件分类
    • components/common/:通用组件
    • components/business/:业务组件
    • views/:页面组件
  • 状态管理:使用 Pinia stores
  • API 调用:统一在 api/ 目录封装

安全规则

数据安全

  • SSH 密码必须加密存储(使用 Fernet 加密)
  • 敏感信息通过环境变量配置
  • 数据库连接使用 SSL
  • 定期备份数据(90天历史记录)

应用安全

  • 所有 API 端点需要认证(除登录接口)
  • 实现 CSRF 保护
  • 输入验证使用 Pydantic
  • SQL 注入防护(使用 ORM
  • XSS 防护(前端转义)

访问控制

  • 基于 RBAC 的权限控制
  • 数据级权限过滤(按区域/学校)
  • 操作审计日志记录
  • 设备信息变更需要审核

性能规则

数据库优化

  • 为常用查询字段添加索引
  • 使用连接池(pool_size=20
  • 避免 N+1 查询问题
  • 定期清理历史数据(保留90天)

缓存策略

  • Redis 缓存热点数据(设备状态)
  • 缓存过期时间:30分钟
  • 手动刷新有5分钟冷却限制

异步处理

  • SSH 状态检查使用 Celery 异步任务
  • 批量导入使用后台任务
  • 定时任务使用 Celery Beat

开发规则

环境配置

  • 开发环境使用 .env.development
  • 生产环境使用 .env.production
  • 不提交 .env 文件到 Git
  • 提供 .env.example 模板

测试要求

  • 核心业务逻辑需要单元测试
  • API 端点需要集成测试
  • 测试覆盖率目标:≥80%

文档要求

  • API 变更及时更新 Swagger 文档
  • 复杂业务逻辑添加注释
  • 重要配置添加说明

部署规则

Docker 部署

  • 使用 Docker Compose 编排
  • 外部 PostgreSQL 和 Redis(不在容器内)
  • 日志挂载到宿主机
  • 使用 Nginx 反向代理

环境变量

必需配置:

  • DATABASE_URLPostgreSQL 连接字符串
  • REDIS_URLRedis 连接字符串
  • CASDOOR_*Casdoor 认证配置
  • SECRET_KEY:应用密钥

监控告警

  • 健康检查端点:/health
  • 性能指标端点:/metrics
  • 日志级别:生产环境使用 INFO

部署陷阱与经验教训

修改代码后必须重新构建镜像

问题:修改了宿主机上的源码后,直接 docker compose up -ddocker compose restart 不会让容器使用新代码。容器运行的是构建时打包进镜像的旧代码。

正确流程

# 1. 重新构建镜像(必须加 --no-cache 确保不用旧层)
docker compose build --no-cache backend   # 或 frontend,或两者

# 2. 重新创建容器(必须用 rm + up,或 up --force-recreate
docker compose rm -f backend
docker compose up -d backend

# 3. 如有数据库模型变更,执行迁移
docker compose exec backend alembic upgrade head

不要用

  • docker compose restart:只重启进程,不更新镜像
  • docker compose up -d(无 build):容器配置变了会重建,但镜像不变

端口被占用导致容器启动但无端口映射

问题:如果宿主机端口已被其他容器占用,新容器会启动成功(docker compose up 不报错),但端口映射为空 {},外部无法访问。

排查方法

# 检查端口映射是否正常
docker inspect <container> --format '{{json .NetworkSettings.Ports}}'

# 查看谁占用了端口
docker ps | grep <port>

解决方法:先停掉占用端口的旧容器,再 docker compose rm -f && docker compose up -d

frontend 容器必须配置 VITE_API_PROXY_TARGET

问题:根目录 docker-compose.yml 的 frontend 服务如果没有配置 VITE_API_PROXY_TARGETVite 代理会默认打到 http://localhost:8001,导致所有 /api 请求 500 或无法到达后端。

必须在 docker-compose.yml 中配置

frontend:
  build: ./frontend
  ports:
    - "5173:5173"
  environment:
    - VITE_API_PROXY_TARGET=http://backend:8000

新增数据库模型后必须执行迁移

问题:新增了 SQLAlchemy 模型(如 DeviceDailySnapshotSystemSetting),重建镜像后如果不执行 alembic upgrade head,表不存在会导致 500 错误。

每次新增模型的完整流程

# 1. 创建迁移文件(在宿主机或容器内)
docker compose exec backend alembic revision --autogenerate -m "描述"

# 2. 重建镜像
docker compose build --no-cache backend

# 3. 重启容器
docker compose rm -f backend && docker compose up -d backend

# 4. 执行迁移
docker compose exec backend alembic upgrade head

Alembic 迁移文件 revision ID 不能重复

问题:手动创建迁移文件时,如果 revision 字段与已有文件重复,alembic upgrade head 会报 Multiple head revisions are present 错误。

规则:手动创建迁移文件时,revision ID 使用不与现有文件冲突的唯一字符串(如 h8i9j0k1l2m3),并确认 down_revision 指向正确的上一个版本。

Celery worker 必须重建才能识别新任务

问题:新增 Celery 任务模块后,如果只重建 backend 而不重建 celery-workerworker 不会注册新任务,消息会被丢弃并报 KeyError

规则:新增任务模块后,backend 和 celery-worker 都必须重建:

docker compose build --no-cache backend celery-worker
docker compose rm -f backend celery-worker
docker compose up -d backend celery-worker

验证任务是否注册:

docker compose exec celery-worker celery -A celery_worker.celery_app inspect registered

区域管理员多区域过滤必须用 .in_() 而非 ==

问题assigned_area 字段存储逗号分隔的多个区域(如 "城区,郊区"),用 == 只能匹配整个字符串,导致多区域管理员只能看到第一个区域的数据。

规则:所有涉及 assigned_area 的过滤都必须先 split 再用 .in_()

areas = [a.strip() for a in current['assigned_area'].split(',') if a.strip()]
query = query.filter(Model.region.in_(areas))

Vite dev server 通过反向代理访问需配置 allowedHosts

问题:通过域名反向代理访问 Vite dev server 时,会报 Blocked request. This host is not allowed

解决:在 vite.config.js 中设置:

server: {
  allowedHosts: ['all', 'your-domain.com'],
}

iOS PWA standalone 模式与 Safari 的 safe area 差异

问题env(safe-area-inset-top) 在 Safari 浏览器中为 0(有地址栏占位),在 standalone 模式(添加到主屏幕)下为真实刘海高度(44-59px)。直接使用会导致 Safari 中布局正常但 standalone 中顶栏/弹窗重叠。

规则:所有 safe area 相关样式必须包在 @media (display-mode: standalone) 中,Safari 不受影响:

@media (display-mode: standalone) {
  .mobile-topbar {
    height: calc(52px + env(safe-area-inset-top));
  }
}

ElMessage 的 offset 通过 src/utils/message.js 封装统一处理,所有页面从该文件导入而非直接从 element-plus 导入。

Docker healthcheck 镜像内无 curl

问题backend 镜像基于 Python slim,没有 curlhealthcheck 用 curl 会导致所有依赖服务启动失败。

规则healthcheck 使用 Python 内置模块:

healthcheck:
  test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"]
  interval: 15s
  timeout: 10s
  retries: 5
  start_period: 40s

项目结构

H3ConuMS2/
├── backend/              # Python 后端
│   ├── app/
│   │   ├── api/         # API 路由
│   │   ├── core/        # 核心配置
│   │   ├── models/      # 数据模型
│   │   ├── schemas/     # Pydantic 模式
│   │   ├── services/    # 业务逻辑
│   │   ├── tasks/       # Celery 任务
│   │   └── utils/       # 工具函数
│   ├── alembic/         # 数据库迁移
│   └── tests/           # 测试代码
├── frontend/            # Vue 前端
│   └── src/
│       ├── api/         # API 调用
│       ├── components/  # 组件
│       ├── router/      # 路由
│       ├── stores/      # 状态管理
│       ├── views/       # 页面
│       └── utils/       # 工具函数
├── deploy/              # 部署配置
│   ├── docker-compose.yml
│   └── nginx.conf
└── docs/                # 文档

核心业务逻辑

SSH 状态检查流程

  1. 从数据库获取 OLT 设备配置
  2. 建立 SSH 连接(使用连接池)
  3. 执行命令:display onu slot {slot_number}
  4. 解析返回结果:
    • 包含 "Up" → 在线
    • 包含 "Offline" → 离线
  5. 更新设备状态到数据库
  6. 记录历史状态

权限控制逻辑

  • 超级管理员:所有权限
  • 管理员:管理所有设备和用户
  • 区域管理员:管理指定区域的设备
  • 学校管理员:管理指定学校的设备
  • 普通用户:只读权限

数据导入流程

  1. 上传 Excel 文件
  2. 使用 Pandas 解析数据
  3. 数据验证(MAC 地址格式、必填字段)
  4. 批量插入数据库
  5. 返回导入结果(成功/失败记录)

开发指南

快速启动

后端

cd backend
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

前端

cd frontend
npm install
npm run dev

Celery Worker

cd backend
celery -A app.core.celery_app worker --loglevel=info

Celery Beat

cd backend
celery -A app.core.celery_app beat --loglevel=info

Docker 部署

# 配置环境变量
cp backend/.env.example backend/.env

# 启动所有服务
docker-compose up -d

# 初始化数据库
docker-compose exec backend python scripts/init_db.py

数据库迁移

# 创建迁移
alembic revision --autogenerate -m "描述"
/home/v6ole/pyproject/H3ConuMS2/CLAUDE.md
# 执行迁移
alembic upgrade head

# 回滚
alembic downgrade -1

添加新功能

  1. 后端 API

    • app/api/v1/ 创建路由文件
    • app/services/ 创建服务文件
    • app/schemas/ 定义请求/响应模式
    • app/models/ 定义数据模型(如需要)
  2. 前端页面

    • views/ 创建页面组件
    • api/ 添加 API 调用
    • router/ 添加路由配置
    • stores/ 添加状态管理(如需要)

常见问题

SSH 连接失败

  • 检查网络连通性
  • 验证 SSH 凭证
  • 检查防火墙设置
  • 查看日志:docker-compose logs backend

数据库连接失败

  • 检查 DATABASE_URL 配置
  • 验证数据库服务状态
  • 检查网络权限

Casdoor 登录失败

  • 检查 Casdoor 服务状态
  • 验证 CASDOOR_* 配置
  • 检查回调地址配置

参考文档