Files
DjangoAdmin_Flask_EleVue/USAGE.md
T
DjangoAdmin DevandClaude 15f2a5e097 chore: 基线提交(重构前代码快照)
- git 初始化 + .gitignore 补全(根 .env / logs / instance / __pycache__ 等)
- 修复 utils/.gitignore 误将整个 utils/ 源码层忽略的问题,补入全部工具源码(含 ip2region.xdb)
- 含后端全部代码:application / extensions / utils / config / migrations
- 含前端 ui/(后续整体迁走)
- 不含根 .env(含密钥,本地保留)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-07 12:12:06 +08:00

384 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Flask+EleVue 使用文档
## 目录
- [环境配置](#环境配置)
- [基础配置](#基础配置)
- [数据库配置](#数据库配置)
- [Redis缓存配置](#redis缓存配置)
- [邮件配置](#邮件配置)
- [短信配置(阿里云)](#短信配置阿里云)
- [JWT令牌配置](#jwt令牌配置)
- [登录白名单配置](#登录白名单配置)
- [权限验证配置](#权限验证配置)
- [启动方式](#启动方式)
- [开发环境](#开发环境)
- [生产环境](#生产环境)
- [Docker部署](#docker部署)
- [Gunicorn参数调优](#gunicorn参数调优)
- [应用流程](#应用流程)
- [启动流程](#启动流程)
- [请求处理流程](#请求处理流程)
- [AOP事务管理](#aop事务管理)
- [邮件服务](#邮件服务)
- [短信服务](#短信服务)
---
## 环境配置
所有配置项在项目根目录 `.env` 文件中管理,应用启动时由 `python-dotenv` 自动加载。
### 基础配置
| 配置项 | 默认值 | 说明 |
|--------|--------|------|
| `FLASK_NAME` | Flask+EleVue旗舰版 | 应用名称 |
| `FLASK_VERSION` | v2.8.0 | 应用版本 |
| `FLASK_SECRET_KEY` | - | 应用秘钥,用于Session加密和CSRF保护,必须≥16字符 |
| `FLASK_HOST` | 127.0.0.1 | 运行地址。`0.0.0.0` 允许外部访问 |
| `FLASK_PORT` | 8021 | 运行端口 |
| `FLASK_ENV` | development | 环境标识:`development` / `production` |
| `FLASK_DEBUG` | True | 调试模式。**生产环境必须设为 False** |
| `FLASK_USE_RELOADER` | False | 自动重启(仅 DEBUG=True 时生效) |
| `PROXY_NUM` | 0 | 可信代理层数。Nginx后设为1 |
| `CORS_ALLOWED_ORIGINS` | - | CORS允许的源,逗号分隔。配置后支持携带凭证 |
| `FLASK_DEMO` | False | 演示模式,True时限制写操作 |
| `CAPTCHA_BYPASS_CODE` | 618618 | 万能验证码(仅DEMO模式生效,生产环境必须为空) |
| `FLASK_UPLOAD_DIR` | - | 文件上传存储目录 |
| `FLASK_FILE_URL` | - | 图片域名,用于生成完整URL |
| `UPLOAD_ALLOWED_EXTS` | .jpg,.jpeg,.png,... | 允许上传的文件扩展名 |
| `UPLOAD_MAX_SIZE_MB` | 10 | 上传文件大小上限(MB) |
### 数据库配置
| 配置项 | 默认值 | 说明 |
|--------|--------|------|
| `DB_DRIVER` | mysql | 数据库驱动:`mysql` / `pgsql` / `sqlite` |
| `DB_HOST` | 127.0.0.1 | 数据库地址 |
| `DB_PORT` | 3306 | 数据库端口 |
| `DB_DATABASE` | - | 数据库名称 |
| `DB_USERNAME` | root | 数据库账号 |
| `DB_PASSWORD` | - | 数据库密码 |
| `DB_PREFIX` | flask_ | 表前缀 |
| `DB_DEBUG` | True | 是否打印SQL日志 |
| `DB_SSL` | False | 是否启用SSL加密连接 |
连接池高级参数(取消注释即可生效):
| 配置项 | 默认值 | 说明 |
|--------|--------|------|
| `DB_POOL_SIZE` | 10 | 常驻连接数 |
| `DB_MAX_OVERFLOW` | 10 | 最大额外连接数 |
| `DB_POOL_RECYCLE` | 1800 | 连接回收时间(秒),应小于MySQL的wait_timeout |
| `DB_POOL_TIMEOUT` | 30 | 获取连接超时(秒) |
| `DB_POOL_PRE_PING` | True | 使用前检测连接存活 |
### Redis缓存配置
| 配置项 | 默认值 | 说明 |
|--------|--------|------|
| `REDIS_HOST` | 127.0.0.1 | Redis地址 |
| `REDIS_PORT` | 6379 | Redis端口 |
| `REDIS_PASSWORD` | - | Redis密码 |
| `REDIS_INDEX` | 0 | 库索引(0-15) |
| `REDIS_AUTH` | True | 是否需要认证 |
| `REDIS_DECODE_RESPONSES` | True | 是否自动解码 |
### 邮件配置
| 配置项 | 默认值 | 说明 |
|--------|--------|------|
| `MAIL_MAILER` | smtp | 邮寄方式:`smtp` / `sendmail` |
| `MAIL_SERVER` | smtp.163.com | SMTP服务器地址 |
| `MAIL_PORT` | 465 | SMTP端口(465=SSL,587=TLS) |
| `MAIL_USE_SSL` | True | 是否启用SSL |
| `MAIL_USERNAME` | - | 授权邮箱用户名 |
| `MAIL_PASSWORD` | - | 授权码(非登录密码) |
| `MAIL_ENCRYPTION` | - | 加密方式:`ssl` / `tls` |
| `MAIL_FROM_NAME` | - | 发件人名称 |
| `MAIL_FROM_ADDRESS` | - | 发件人地址 |
### 短信配置(阿里云)
| 配置项 | 默认值 | 说明 |
|--------|--------|------|
| `SMS_PROVIDER` | aliyun | 短信服务商(当前仅支持aliyun) |
| `SMS_ALIYUN_ACCESS_KEY_ID` | - | 阿里云 AccessKey ID |
| `SMS_ALIYUN_ACCESS_KEY_SECRET` | - | 阿里云 AccessKey Secret |
| `SMS_ALIYUN_SIGN_NAME` | - | 短信签名(需在阿里云审核通过) |
| `SMS_ALIYUN_ENDPOINT` | dysmsapi.aliyuncs.com | 接入点 |
| `SMS_ALIYUN_CONNECT_TIMEOUT` | 10000 | 连接超时(毫秒) |
| `SMS_ALIYUN_READ_TIMEOUT` | 10000 | 读取超时(毫秒) |
### JWT令牌配置
| 配置项 | 默认值 | 说明 |
|--------|--------|------|
| `JWT_SALT` | - | JWT签名密钥,至少32字节,务必使用强随机密钥 |
| `JWT_EXPIRE_MINUTES` | 20 | 令牌过期时间(分钟) |
生成密钥:
```bash
python -c "import secrets; print(secrets.token_urlsafe(48))"
```
### 登录白名单配置
白名单路径免登录验证,支持三种匹配模式:
| 配置项 | 说明 |
|--------|------|
| `LOGIN_WHITELIST_EXACT` | 精确匹配,逗号分隔。如 `/login,/captcha` |
| `LOGIN_WHITELIST_PREFIX` | 前缀匹配,逗号分隔。如 `/public,/static` |
| `LOGIN_WHITELIST_WILDCARD` | 通配符匹配,`*` 匹配任意字符,`?` 匹配单字符 |
| `LOGIN_WHITELIST_DEBUG` | 是否打印匹配调试日志 |
| `LOGIN_WHITELIST_LOG_ACCESS` | 白名单请求是否记录访问日志 |
### 权限验证配置
| 配置项 | 默认值 | 说明 |
|--------|--------|------|
| `PERMISSION_ENABLED` | True | 是否启用权限验证。False时所有请求放行 |
| `INTERNAL_API_KEY` | - | 内部调用API密钥,请求头携带 `X-Internal-API-Key` |
| `INTERNAL_ALLOWED_IPS` | 127.0.0.1 | 内部调用白名单IP,逗号分隔 |
---
## 启动方式
### 开发环境
```bash
# 安装依赖
pip install -r requirements.txt
# 启动后端(默认 127.0.0.1:8021)
python app.py
```
`python app.py` 执行 `__main__` 块,使用 `app.run()` 启动 Werkzeug 开发服务器。
开发环境支持 debug 模式和自动重载,由 `.env` 中 `FLASK_DEBUG` 和 `FLASK_USE_RELOADER` 控制。
前端开发服务器:
```bash
cd ui
pnpm install
pnpm run dev # 默认 localhost:8001,自动代理 /api 到后端 :8021
```
### 生产环境
```bash
gunicorn -c gunicorn.conf.py app:app
```
Gunicorn 通过 `app:app` 导入 Flask 应用对象,**不执行 `__main__` 块**。`gunicorn.conf.py` 中配置了 gevent worker,支持高并发。
关键区别:
| | 开发环境 | 生产环境 |
|---|---------|---------|
| 启动命令 | `python app.py` | `gunicorn -c gunicorn.conf.py app:app` |
| WSGI服务器 | Werkzeug | Gunicorn + gevent |
| Debug | 可开启 | 必须关闭 |
| 自动重载 | 可开启 | 不支持 |
| 并发模型 | 单进程 | 多worker + 协程 |
### Docker部署
```bash
cd docker
# 构建并启动
docker-compose up -d --build
# 查看日志
docker-compose logs -f flask_elevue
# 重新构建(代码更新后)
docker-compose up -d --build
# 停止
docker-compose down
```
Docker 容器内使用 Gunicorn 启动,Dockerfile 和 docker-compose.yml 已配置好 gevent worker。
### Gunicorn参数调优
所有参数通过环境变量覆盖,无需修改配置文件:
| 环境变量 | 默认值 | 说明 |
|----------|--------|------|
| `GUNICORN_BIND` | 0.0.0.0:8021 | 监听地址 |
| `GUNICORN_WORKERS` | 2*CPU+1 | worker数量 |
| `GUNICORN_WORKER_CONNECTIONS` | 1000 | 每worker协程数 |
| `GUNICORN_MAX_REQUESTS` | 1000 | 处理请求数后重启(防内存泄漏) |
| `GUNICORN_MAX_REQUESTS_JITTER` | 50 | 重启抖动,避免同时重启 |
| `GUNICORN_TIMEOUT` | 120 | worker超时(秒) |
| `GUNICORN_GRACEFUL_TIMEOUT` | 30 | 优雅关闭超时(秒) |
| `GUNICORN_LOG_LEVEL` | info | 日志级别 |
| `GUNICORN_ACCESS_LOG` | - | 访问日志路径(- 为stdout) |
| `GUNICORN_ERROR_LOG` | - | 错误日志路径(- 为stderr) |
Docker 中通过 docker-compose.yml 的 `environment` 注入:
```yaml
environment:
GUNICORN_WORKERS: 4
GUNICORN_WORKER_CONNECTIONS: 2000
```
---
## 应用流程
### 启动流程
```
app.py
└─ create_app() # 应用工厂
├─ Flask 核心对象创建
├─ Redis 配置
├─ 数据库配置加载
├─ JSON 序列化器设置
├─ CORS 跨域配置
├─ ProxyFix 可信代理配置
├─ register_operation_log() # 操作日志中间件(先于事务注册)
├─ register_transaction() # AOP 事务拦截器
├─ register_blueprint() # 蓝图自动发现与注册
├─ register_extends() # 扩展初始化(DB/Redis/Mail/...)
├─ register_middleware() # 登录验证中间件
└─ register_error_handlers() # 全局异常处理
```
### 请求处理流程
```
HTTP 请求
└─ before_request
├─ 操作日志记录(记录请求信息)
├─ AOP事务标记(标记事务开始)
├─ 登录验证(check_login,白名单路径跳过)
└─ 权限验证(check_permission 装饰器,超管/内部调用跳过)
└─ View 路由处理
└─ Service 业务逻辑
└─ Model 数据操作(flush,不commit)
└─ after_request
├─ AOP事务提交/回滚(POST/PUT/DELETE/PATCH,2xx且code=0时提交)
└─ 操作日志写入
└─ 响应返回
```
### AOP事务管理
框架通过 `application/middleware/transaction.py` 实现声明式事务管理,**业务代码无需手动 commit/rollback**。
- `before_request`:标记事务活跃
- `after_request`:
- 写操作(POST/PUT/DELETE/PATCH)且 HTTP 2xx 且响应 `code==0` → 自动提交
- 业务失败(`R.failed` 返回 HTTP 200 但 `code=1`)→ 自动回滚
- `teardown_request`:未处理异常时回滚
`BaseDB.save()` 和 `BaseDB.save_all()` 仅调用 `db.session.flush()`,由 AOP 拦截器统一提交。
特殊场景可使用:
- `@transactional` 装饰器
- `@transactional_response` 装饰器
- `TransactionContext` 上下文管理器
---
## 邮件服务
邮件服务封装在 `application/services/mail_svc.py`,基于 Flask-Mail,供业务模块和定时任务直接调用。
**调用方式:**
```python
from application.services import mail_svc
# 简单文本邮件
mail_svc.send_mail(to='user@example.com', subject='标题', body='内容')
# HTML 邮件
mail_svc.send_mail(to='user@example.com', subject='标题', html='<h1>Hello</h1>')
# 多收件人 + 抄送
mail_svc.send_mail(
to=['a@example.com', 'b@example.com'],
subject='标题',
body='内容',
cc=['cc@example.com'],
)
```
**参数说明:**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `to` | str / List[str] | 是 | 收件人 |
| `subject` | str | 是 | 邮件主题 |
| `body` | str | 否* | 纯文本正文 |
| `html` | str | 否* | HTML正文(与body至少提供一个) |
| `cc` | str / List[str] | 否 | 抄送 |
| `bcc` | str / List[str] | 否 | 密送 |
| `reply_to` | str | 否 | 回复地址 |
返回 `True` 表示发送成功,`False` 表示失败(异常已捕获并记录日志)。
**前置条件:** `.env` 中配置 `MAIL_SERVER`、`MAIL_USERNAME`、`MAIL_PASSWORD`。
---
## 短信服务
短信服务封装在 `application/services/sms_svc.py`,基于阿里云短信 SDK,供业务模块和定时任务直接调用。
**调用方式:**
```python
from application.services import sms_svc
# 模板短信
sms_svc.send_sms(
phone='13800138000',
template_code='SMS_123456',
template_params={'code': '123456'}
)
# 指定签名(覆盖默认签名)
sms_svc.send_sms(
phone='13800138000',
template_code='SMS_123456',
template_params={'code': '123456'},
sign_name='我的应用'
)
# 群发(多号码)
sms_svc.send_sms(
phone=['13800138000', '13900139000'],
template_code='SMS_123456',
template_params={'name': '张三'}
)
```
**参数说明:**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `phone` | str / List[str] | 是 | 手机号,支持单个或多个 |
| `template_code` | str | 是 | 短信模板CODE(阿里云控制台获取) |
| `template_params` | dict | 否 | 模板变量,如 `{'code': '123456'}` 对应 `${code}` |
| `sign_name` | str | 否 | 短信签名,默认使用配置中的 `SMS_ALIYUN_SIGN_NAME` |
返回 `True` 表示全部发送成功,`False` 表示至少一条失败。
**前置条件:**
1. `.env` 中配置 `SMS_ALIYUN_ACCESS_KEY_ID`、`SMS_ALIYUN_ACCESS_KEY_SECRET`、`SMS_ALIYUN_SIGN_NAME`
2. 安装依赖:`pip install alibabacloud-dysmsapi20170525 alibabacloud-tea-openapi`(已包含在 requirements.txt)