# python-admin **Repository Path**: nidu/python-admin ## Basic Information - **Project Name**: python-admin - **Description**: No description available - **Primary Language**: Python - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-09-18 - **Last Updated**: 2026-09-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: Python, FastAPI, admin ## README # python-admin 基于 **Python 3.12 + FastAPI** 的单体后台管理服务,对标 Java Cola DDD Demo 的接口契约, 保留 `/admin-api/v1`、`/app-api/v1` 路径及 camelCase 请求/响应格式。 > 当前为开发阶段实现,不应直接用于生产环境。 --- ## 已实现功能 ### 系统管理(`/admin-api/v1/system/`) | 模块 | 功能 | 状态 | |------|------|------| | **认证** `auth` | 账号密码登录、短信登录、注册、JWT 刷新、登出;登录日志记录真实客户端 IP、User-Agent、TraceID | ✅ 完整 | | **用户** `users` | 用户 CRUD、角色分配、重置密码、个人资料、Excel 批量导入/导出、下载导入模板 | ✅ 完整 | | **角色** `roles` | 角色 CRUD、菜单权限分配、数据权限范围 | ✅ 完整 | | **菜单** `menus` | 目录/菜单/按钮树形 CRUD、权限标识管理 | ✅ 完整 | | **部门** `departments` | 树形部门 CRUD、负责人绑定 | ✅ 完整 | | **公司** `companies` | 公司 CRUD | ✅ 完整 | | **岗位** `positions` | 岗位 CRUD | ✅ 完整 | | **字典** `dictionaries` | 字典类型 + 字典数据 CRUD | ✅ 完整 | | **系统配置** `configs` | 配置项 CRUD(key/value 键值对,无 status 字段)| ✅ 完整 | | **国际化** `i18n` | 多语言词条 CRUD | ✅ 完整 | | **租户** `tenants` | 租户 + 套餐 CRUD、账户数量/有效期管理 | ✅ 完整 | | **在线用户** `online_users` | 基于登录日志统计在线用户、强制退出(无 Redis,使用 LOGOUT_DELETE 日志标记)| ✅ 完整 | | **社交客户端** `social_clients` | 社交登录客户端配置 CRUD、状态启用/禁用 | ✅ 完整 | | **社交用户** `social_users` | 社交用户分页、解绑、删除 | ✅ 完整 | | **缓存预热** `cache` | preload 列表/触发接口 | ⚠️ 占位 | ### 会员管理(`/app-api/v1/member/` + `/admin-api/v1/member/`) | 模块 | 功能 | 状态 | |------|------|------| | **会员认证** `auth` | 手机号/短信登录、注册、JWT 刷新、登出;同步写入登录日志(含 IP、UA、TraceID)| ✅ 完整 | | **会员用户** `users` | 后台管理 CRUD、个人资料、Excel 导入/导出 | ✅ 完整 | | **会员标签** `tags` | 标签 CRUD | ✅ 完整 | | **会员等级** `levels` | 等级 CRUD | ✅ 完整 | | **会员分组** `groups` | 分组 CRUD | ✅ 完整 | ### OAuth2(`/admin-api/v1/oauth2/`) | 模块 | 状态 | |------|------| | 客户端管理 | ✅ 完整 | | 授权码流程(authorization_code grant)| ✅ 完整 | | 密码模式(password grant)| ✅ 完整 | | 刷新令牌(refresh_token grant)| ✅ 完整 | | 访问/刷新令牌管理 | ✅ 完整 | ### 基础设施(`/admin-api/v1/infra/`) | 模块 | 功能 | 状态 | |------|------|------| | **文件** `files` | 文件上传(本地存储)、文件配置管理(存储类型/访问模式)、公开访问 | ✅ 完整 | | **短信** `sms` | 渠道/模板/验证码/日志管理;验证码发送使用 Mock 适配器;登录/注册/改密均做验证码校验 | ✅ 完整 | | **邮件** `mail` | 账号/模板/日志管理;通过 SMTP 同步发送 | ✅ 完整 | | **站内信** `notifications` | 消息模板/消息记录/通知公告 CRUD、批量标记已读 | ✅ 完整 | | **验证码** `captcha` | 图形验证码(自定义 SVG)生成与校验(Redis 存储)| ✅ 完整 | | **行政区划** `area` | 国家/省/市/区多级查询(Admin + App 两套路由)| ✅ 完整 | | **审计日志** `audit_logs` | 操作日志、登录日志(含真实 IP/UA/TraceID)、API 访问日志;支持导出和清空 | ✅ 完整 | --- ## 核心基础能力 ### 请求链路追踪(对标 Java `TraceWebFilter`) `RequestContextMiddleware` 在每次请求时: 1. 从 `X-Trace-Id` 请求头读取 trace ID,校验格式(`^[A-Za-z0-9._-]+$`,≤64字符) 2. 格式无效或缺失时自动生成 UUID hex 作为 trace ID 3. 写入 `request.state.trace_id`,通过 `core/web_utils.get_trace_id()` 供各层使用 4. 在响应头写回 `X-Trace-Id` ### 客户端信息提取(对标 Java `WebUtils`) `core/web_utils.py` 提供三个工具函数: | 函数 | 说明 | |------|------| | `get_client_ip(request)` | 按优先级依次读取 `X-Forwarded-For`、`X-Real-IP`、`CF-Connecting-IP`、`True-Client-IP`,降级到直连 IP | | `get_user_agent(request)` | 读取 `User-Agent` 请求头 | | `get_trace_id(request)` | 读取中间件已处理的 `request.state.trace_id` | 代理头名称常量集中定义在 `shared/constants.RequestHeaderConstants.PROXY_IP_HEADERS`,避免重复。 ### 登录事件系统 所有认证端点(管理端 + 会员端)均通过 `LoginEvent` 写入 `infra_login_log`: - 字段:`login_type`(登录/短信/社交/登出/强制登出)、`trace_id`、`user_id`、`username`、`user_type`、`user_ip`、`user_agent`、`login_time`、`result`、`error_msg` - 登录成功时同步更新 `sys_user.login_ip` 和 `login_time` ### 认证与权限 - **密码**:BCrypt(兼容 Spring Security `BCryptPasswordEncoder` strength=10) - **JWT**:Access Token + Refresh Token,分别签发不同 `type` 字段 - **权限聚合**:超级管理员固定 `*:*:*`;普通用户从角色→菜单表聚合实际权限标识 - **多租户**:`BaseRepository` 自动过滤 `tenant_id`,防止跨租户数据泄露 ### Excel 导入/导出 `shared/excel.py` 封装 `openpyxl`,提供通用工具: - `build_workbook(headers, rows)` — 构建带样式(蓝底白字)标题行的工作簿 - `workbook_to_bytes(wb)` — 序列化为 `.xlsx` 字节流 - `parse_workbook(data)` — 解析上传的 Excel,返回 `(headers, rows)` 管理端用户和会员用户均支持导入模板下载、批量导入(含错误统计)、全量导出。 --- ## 技术栈 | 类别 | 技术 | |------|------| | 运行时 | Python `>=3.12,<3.13` | | Web 框架 | FastAPI、Pydantic v2、Uvicorn | | ORM | SQLAlchemy 2 Async、aiomysql、Alembic | | 数据库 | MySQL 8(生产)、SQLite + aiosqlite(测试)| | 缓存 | Redis 7(验证码、会话)| | 异步任务 | Celery + RabbitMQ | | 认证 | PyJWT、BCrypt | | 文件存储 | 本地文件系统(S3/MinIO 适配器接口已定义,尚未实现)| | 邮件 | aiosmtplib | | Excel | openpyxl | | 结构化日志 | structlog | | 质量工具 | Ruff、mypy、Bandit、pytest | 完整依赖约束见 [pyproject.toml](pyproject.toml)。 --- ## 目录结构 ```text src/fast_admin/ ├── core/ # 配置、数据库、安全(JWT/BCrypt)、中间件、异常、事件总线、web_utils ├── shared/ # 常量/枚举/错误码、响应封装、分页、BaseRepository、RequestContext ├── modules/ │ ├── system/ # 管理后台系统域(用户/角色/菜单/租户/字典/配置/在线用户/社交 等) │ ├── member/ # 会员域(认证/用户/标签/等级/分组) │ ├── oauth2/ # OAuth2 域(客户端/授权/令牌) │ └── infra/ # 基础设施(文件/短信/邮件/通知/验证码/区划/审计日志) ├── adapters/ # 文件存储、短信、邮件、社交登录适配器接口与实现 └── workers/ # Celery 应用与异步任务定义 ``` 每个功能模块按 `api.py → service.py → repository.py → models.py` 组织, 请求/响应模型位于 `schemas.py`,对象转换位于 `convertor.py`。 --- ## 本地启动 ### 1. 准备 Python 环境 需要 Python 3.12.x 和 Docker Desktop。 ```powershell py -3.12 -m venv .venv .\.venv\Scripts\Activate.ps1 pip install --upgrade pip pip install -e ".[dev]" aiosqlite Copy-Item .env.example .env ``` > `aiosqlite` 是测试夹具所需的运行时依赖,尚未写入 `pyproject.toml` 开发依赖。 ### 2. 启动基础设施 ```powershell docker compose -f deploy/compose.yaml up -d ``` 默认服务: | 服务 | 地址 | |------|------| | MySQL 8 | `localhost:3306` | | Redis | `localhost:6379` | | RabbitMQ | `localhost:5672`(管理端 `http://localhost:15672`)| | MinIO | `localhost:9000`(控制台 `http://localhost:9001`)| ### 3. 初始化数据库 `migrations/versions/` 目前为空,需先生成初始迁移: ```powershell alembic revision --autogenerate -m "initial schema" alembic upgrade head ``` > 团队协作时由一人生成并提交初始 revision,其余成员只执行 `alembic upgrade head`。 ### 4. 启动 API 服务 ```powershell python -m uvicorn fast_admin.main:app --host 0.0.0.0 --port 8088 --reload ``` | 端点 | 地址 | |------|------| | Swagger UI | `http://localhost:8088/docs` | | OpenAPI JSON | `http://localhost:8088/openapi.json` | | 存活检查 | `http://localhost:8088/health/live` | | 就绪检查 | `http://localhost:8088/health/ready` | ### 5. 创建初始管理用户 ```http POST /admin-api/v1/system/auth/register Content-Type: application/json { "username": "admin", "password": "ChangeMe123!", "mobile": "13800138088" } ``` 返回的 `accessToken` 通过 `Authorization: Bearer ` 访问受保护接口。 --- ## Celery Worker ```powershell # Linux / WSL2 / Docker 容器中运行 celery -A fast_admin.workers.celery_app:celery_app worker --loglevel=INFO ``` > Celery 不支持原生 Windows Worker,Windows 开发环境请在 WSL2 或 Linux 容器中运行。 --- ## 测试与质量检查 ```powershell python -m compileall -q src tests migrations # 语法检查 python -m pytest # 全量测试 python -m ruff check src tests # Lint python -m ruff format --check src tests # 格式检查 python -m mypy src # 类型检查 python -m bandit -r src # 安全扫描 ``` > 当前执行环境必须是 Python 3.12;不可用 Python 3.13/3.14 代替。 --- ## 已知限制 | 领域 | 问题 | |------|------| | **数据库迁移** | `migrations/versions/` 无初始 revision,首次部署需手动生成 | | **社交登录** | `social_login` 方法抛 `NOT_IMPLEMENTED`;`adapters/social_auth/` 接口已定义,适配器尚未实现 | | **JWT 吊销** | Logout 仅写入登出日志,token 自然过期(30分钟);即时吊销需 DB 黑名单或 Redis | | **在线用户踢出** | `kick_user` 写入 `LOGOUT_DELETE` 日志,但已颁发的 JWT 仍在有效期内可继续使用 | | **缓存预热** | `/system/cache/preload*` 返回空响应,无实际业务逻辑 | | **文件存储** | 仅支持本地存储;S3/MinIO 适配器 Protocol 已定义,尚未实现 | | **Celery 任务** | 短信、邮件、通知、导出、日志清理等任务为骨架实现(仅记录日志),Service 层直接调用适配器同步执行 | | **健康检查** | `health/live` 和 `health/ready` 只返回静态 `{"status": "ok"}`,未检查数据库/Redis/MQ 状态 | | **测试依赖** | `aiosqlite` 未写入 `pyproject.toml`;测试使用 SQLite,与生产 MySQL 8 方言存在差异 | | **会员积分** | 积分/经验变更无流水写入(domain_service 含 TODO 注释)| | **依赖锁文件** | 无 `requirements.lock`,依赖构建不可完全复现 | 处理上述模块时必须同时更新需求、架构文档和测试状态,不能只删除 TODO 注释。 --- ## 协作说明 - 自动化开发代理先阅读 [AGENTS.md](AGENTS.md)。 - Claude Code 先阅读 [CLAUDE.md](CLAUDE.md)。 - 项目专用开发流程见 [skills/SKILL.md](skills/SKILL.md)。 - 原始接口契约为 [python_admin-demo.md](python_admin-demo.md);实现与文档冲突时先记录差异并补充契约测试。