Files
tmp/aiPrompt.md
2026-05-25 19:52:24 +08:00

305 lines
13 KiB
Markdown
Raw Permalink 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.
# AI 开发提示词 — 项目架构与模块开发规范
> 在向 AI 提出开发需求时将以下提示词附加在需求描述之后AI 即可按照项目架构规范生成代码,避免多人协作时的合并冲突。
---
## 提示词内容(复制到你的需求后面)
```
## 项目架构与模块开发规范
### 一、项目概述
Under18 是一个前后端分离的 RBAC 权限管理脚手架,提供用户、角色、权限、字典、标签、日志等通用功能模块。采用模块化自动注册架构,新增功能模块时**严禁修改任何共享/公共文件**,所有新代码必须放在独立模块文件中。
**技术栈:**
- 后端FastAPI + SQLAlchemy异步+ PostgreSQL + Alembic
- 前端Vue 3 + Vite 5 + Element Plus + Pinia + Vue Router 4
- 缓存cachetools.TTLCache进程内替代 Redis
- 认证JWTHS256Access Token 120min + Refresh Token 7天
### 二、后端规范FastAPI
#### 2.1 分层架构
```
API 层 (app/api/{模块名}.py) — 路由定义、参数校验(Schema)、权限注入、响应封装
↓ 调用
Service 层 (app/services/{模块名}_service.py) — 纯业务逻辑,静态方法,接收 AsyncSession
↓ 操作
Model 层 (app/models/{模块名}.py) — ORM 映射,继承 Base + TimestampMixin + SoftDeleteMixin
```
#### 2.2 新增模块只需创建以下独立文件,不需要修改任何已有文件:
1. **`backend/app/models/{模块名}.py`** — ORM 模型定义
- 从 `app.core.database` 导入 `Base`
- 从 `app.models.mixins` 导入 `TimestampMixin, SoftDeleteMixin`(日志类模型可不加 SoftDeleteMixin
- 模型类继承:`class SysXxx(Base, TimestampMixin, SoftDeleteMixin)`
- 关联表many-to-many使用 `Table()` 定义在同一文件中
- 每个模型需实现 `to_dict()` 方法手动序列化
- 表名统一使用 `sys_` 前缀
2. **`backend/app/schemas/{模块名}.py`** — Pydantic 请求/响应模型
- 每个模块的 schema 独立一个文件
- 命名规范:`XxxCreateRequest`、`XxxUpdateRequest`、`XxxQueryRequest`
- 从 `app.schemas.response` 导入 `PageQuery` 作为分页查询基类
3. **`backend/app/services/{模块名}_service.py`** — 业务逻辑层
- 类名必须以 `Service` 结尾(如 `ArticleService`),全部使用 `@staticmethod`
- 从 `app.models.{模块名}` 导入模型(不要从 app.models 或 app.models.models 导入)
- 从 `app.schemas.{模块名}` 导入 schema不要从 app.schemas.request 导入)
- 所有方法第一个参数为 `db: AsyncSession`
- 调用方式:`ArticleService.get_list(db, ...)`
4. **`backend/app/api/{模块名}.py`** — API 路由
- 必须导出名为 `router` 的 `APIRouter` 实例
- 示例:`router = APIRouter(prefix="/xxx", tags=["XXX管理"])`
- 所有路由自动加上 `/api` 前缀(由 `api_router = APIRouter(prefix="/api")` 控制)
- 从 `app.core.deps` 导入 `get_current_user`、`require_permission`
- 从 `app.schemas.response` 导入 `success`、`error`、`page_result`
- 路由文件会被 `app/api/__init__.py` 自动扫描注册,**不要修改 __init__.py**
#### 2.3 自动注册机制
| 层 | 扫描规则 | 约定 |
|----|---------|------|
| API 路由 | 扫描 `app/api/` 下所有 `.py`,查找 `router` 变量 | 文件必须导出 `router = APIRouter(...)` |
| Model | 扫描 `app/models/` 下所有 `.py`(跳过 `__init__.py` 和 `mixins.py` | 确保模型被导入到 Base.metadata |
| Service | 扫描 `app/services/` 下所有 `_service.py`,收集以 `Service` 结尾的类 | 可直接 `from app.services import XxxService` |
**因此绝对不需要修改任何 `__init__.py` 文件。**
#### 2.4 已有模型导入路径
```python
from app.models.user import SysUser, sys_user_role # 用户 + 用户角色关联表
from app.models.role import SysRole, sys_role_permission # 角色 + 角色权限关联表
from app.models.permission import SysPermission # 权限
from app.models.dict import SysDictType, SysDictData # 字典类型 + 字典数据
from app.models.log import SysOperationLog, SysLoginLog # 操作日志 + 登录日志
from app.models.tag import SysTag, sys_tag_object # 标签 + 标签对象关联表
from app.models.mixins import TimestampMixin, SoftDeleteMixin # 通用混入
```
#### 2.5 响应格式统一
```python
from app.schemas.response import success, error, page_result
# 成功return success(data=xxx)
# 失败return error(message="xxx", code=400)
# 分页return page_result(items=xxx, total=xxx, page=xxx, page_size=xxx)
```
响应体格式:
```json
{ "code": 200, "message": "success", "data": {...} }
{ "code": 200, "message": "success", "data": { "items": [], "total": 0, "page": 1, "page_size": 10 } }
{ "code": 400, "message": "错误信息", "data": null }
```
#### 2.6 权限校验
- **路由级**`dependencies=[Depends(require_permission("模块:资源:操作"))]`
- **按钮级**:前端使用 `v-permission="'模块:资源:操作'"` 指令
- **权限编码格式**`模块:资源:操作`,如 `content:article:list`
- **超级管理员豁免**:角色为 `admin` 的用户自动拥有全部权限
#### 2.7 认证与安全
- **密码加密**`SHA-256(password + user_salt + global_salt)`,双重加盐
- **Token 体系**Access Token120min+ Refresh Token7天HS256 算法
- **登录安全**连续3次失败强制验证码同IP 10次失败锁定30分钟每IP每分钟限20次登录请求
- **获取客户端IP**:使用 `SecurityMiddleware._get_client_ip(request)`
#### 2.8 数据库与配置
- **数据库**PostgreSQL异步驱动 asyncpg连接由 `app.core.database` 管理
- **迁移**Alembic通过 `alembic revision --autogenerate` 生成
- **配置**:唯一来源 `config.yaml`,环境变量 `UNDER18_<键名>` 可覆盖
- **依赖注入**`get_db()` 提供 AsyncSession`get_current_user()` 提供当前用户
#### 2.9 路由定义注意事项
- 批量操作路由(如 `/batch``/clear/all`)必须定义在通配符路由(如 `/{id}`)之前,否则会被通配符匹配拦截
### 三、前端规范Vue3 + Vite
#### 3.1 新增模块只需创建以下独立文件,不需要修改任何已有文件:
1. **`frontend/src/router/modules/{模块名}.js`** — 路由配置
- 必须 `export default` 一个路由配置对象
- 会被 `router/index.js` 通过 `import.meta.glob` 自动扫描加载
- **不要修改 `router/index.js`**
2. **`frontend/src/views/{模块路径}/{子路由}/index.vue`** — 页面组件
- 视图文件路径必须与路由中的 `component` 导入路径一致
3. **`frontend/src/api/{模块名}.js`** — API 调用函数
-`@/utils/request` 导入 axios 实例
- 函数命名:`getXxxList``createXxx``updateXxx``deleteXxx`
#### 3.2 路由配置模板
```javascript
// frontend/src/router/modules/{模块名}.js
export default {
path: '/{模块路径}',
component: () => import('@/layout/index.vue'),
redirect: '/{模块路径}/{默认子路由}',
meta: { title: '{菜单名称}', icon: '{ElementPlus图标名}' },
children: [
{
path: '{子路由}',
name: '{路由名}',
component: () => import('@/views/{模块路径}/{子路由}/index.vue'),
meta: { title: '{页面标题}', icon: '{图标}', permission: '{权限码}' },
},
],
}
```
#### 3.3 侧边栏与权限
- 侧边栏菜单从 `router/modules/` 下的路由配置自动生成,**不需要修改 Sidebar.vue**
- 路由级权限:`meta.permission` 字段 + `filterRoutes()` 过滤无权限路由
- 按钮级权限:`v-permission="'模块:资源:操作'"` 指令,无权限则隐藏元素
#### 3.4 Store 与工具
- **用户状态**`store/user.js` — token、userInfo、权限列表手动同步 localStorage
- **应用状态**`store/app.js` — 侧边栏折叠、设备类型
- **HTTP 请求**`utils/request.js` — Axios 封装,自动添加 Bearer Token统一错误处理401弹窗重新登录、403无权限、429限流、500服务异常
- **日期格式化**`utils/index.js``formatDate()` 函数
- **防抖**`utils/index.js``debounce()` 函数
#### 3.5 样式约定
- 主题色:`#2d9d5e`(绿色系),通过 CSS 变量覆盖 Element Plus 默认主题
- 布局变量:`--sidebar-width: 220px``--header-height: 56px`
- 新页面样式使用 `<style scoped>`,全局样式放在 `styles/` 目录
### 四、禁止修改的文件清单
以下文件是公共注册文件或核心基础设施,多人同时修改会导致严重合并冲突,**绝对禁止修改**
**后端:**
- `app/api/__init__.py` — 路由自动注册
- `app/models/__init__.py` — 模型自动注册
- `app/services/__init__.py` — 服务自动注册
- `app/schemas/response.py` — 通用响应格式
- `app/core/` 目录下所有文件 — 核心基础设施(数据库、安全、中间件、缓存、依赖注入、配置)
- `app/main.py` — 应用入口
**前端:**
- `src/router/index.js` — 路由自动注册入口 + 守卫
- `src/layout/` 目录下所有文件 — 布局组件(侧边栏、顶栏)
- `src/utils/` 目录下所有文件 — 通用工具
- `src/store/` 目录下所有文件 — 全局状态管理
- `src/styles/` 目录下所有文件 — 全局样式
- `src/main.js` — 应用入口
### 五、命名规范速查
| 层 | 文件名 | 类/变量名 | 数据库表名 |
|----|--------|----------|-----------|
| Model | `{模块名}.py` | `Sys{Entity}` | `sys_{entity}` |
| Schema | `{模块名}.py` | `{Entity}CreateRequest` / `{Entity}UpdateRequest` | — |
| Service | `{模块名}_service.py` | `{Entity}Service` | — |
| API | `{模块名}.py` | `router = APIRouter(prefix="/模块/资源")` | — |
| 权限编码 | — | `模块:资源:操作` | — |
| 前端路由 | `modules/{模块名}.js` | `export default { path: '/模块路径', ... }` | — |
| 前端API | `api/{模块名}.js` | `getXxxList` / `createXxx` / `updateXxx` / `deleteXxx` | — |
```
---
## 使用示例
假设你要开发一个"文章管理"模块,向 AI 提问时这样写:
> 请帮我开发一个"文章管理"功能模块,包含文章的增删改查,文章有标题、内容、分类、状态(草稿/发布)等字段。
>
> [粘贴上面的提示词内容]
AI 就会:
- 创建 `backend/app/models/article.py`(不碰 models/__init__.py
- 创建 `backend/app/schemas/article.py`(独立文件)
- 创建 `backend/app/services/article_service.py`(不碰 services/__init__.py
- 创建 `backend/app/api/article.py`(不碰 api/__init__.py
- 创建 `frontend/src/router/modules/article.js`(不碰 router/index.js
- 创建 `frontend/src/views/article/index.vue`
- 创建 `frontend/src/api/article.js`
每个文件都是独立的,不同人开发不同模块,零冲突!
---
## 六、部署与启动注意事项
### 6.1 前端启动问题:根目录误装 node_modules
**问题描述:** 在项目根目录(`under18/`)下执行 `npm install` 会生成根目录的 `package.json`、`package-lock.json` 和 `node_modules/`,导致 `npx vite` 使用根目录的 Vite版本可能不一致且依赖不完整而非 `frontend/node_modules/` 中完整版本的 Vite表现为 Vite 启动后所有请求返回 404。
**典型场景:** 在根目录安装全局依赖(如 `npm install echarts`)时误装到了根目录而非 `frontend/` 目录。
**正确做法:**
- 前端依赖安装必须在 `frontend/` 目录下执行:`cd frontend && npm install xxx --save`
- 启动前端时使用 frontend 自带的 Vite`cd frontend && npx vite` 或 `cd frontend && node_modules/.bin/vite`
- **禁止在项目根目录下执行 `npm install`**
**如已误装,清理方法:**
```bash
# 删除根目录下误装的文件
rm package.json package-lock.json
rm -rf node_modules/
```
### 6.2 后端启动PYTHONPATH 设置
**问题描述:** 直接在 `backend/` 目录执行 `uvicorn app.main:app` 可能报 `ModuleNotFoundError: No module named 'app'`,因为 Python 找不到 `app` 包。
**正确启动方式:**
```bash
cd backend
set PYTHONPATH=c:\Users\hunter\Desktop\under18\backend # Windows
# export PYTHONPATH=/path/to/under18/backend # Linux/Mac
venv/Scripts/python.exe -m uvicorn app.main:app --host 127.0.0.1 --port 8000 --reload
```
### 6.3 完整启动流程
**前置条件:**
- 数据库使用远程 PostgreSQL`config.yaml` 中配置的 `111.229.199.210:12345`),无需本地启动
- Python 虚拟环境位于项目根目录 `venv/`
- 前端依赖已安装在 `frontend/node_modules/`
**启动步骤:**
```bash
# 1. 启动后端
cd c:\Users\hunter\Desktop\under18\backend
set PYTHONPATH=c:\Users\hunter\Desktop\under18\backend
c:\Users\hunter\Desktop\under18\venv\Scripts\python.exe -m uvicorn app.main:app --host 127.0.0.1 --port 8000 --reload
# 2. 启动前端(新终端)
cd c:\Users\hunter\Desktop\under18\frontend
npx vite --host 0.0.0.0 --port 5173
# 或使用完整路径node_modules\.bin\vite --host 0.0.0.0 --port 5173
# 3. 访问
# 前端http://localhost:5173
# 后端API文档http://127.0.0.1:8000/api/docs
# 后端健康检查http://127.0.0.1:8000/api/health
```
### 6.4 生产构建
```bash
cd frontend
npm run build # 输出到 frontend/dist/
```
构建产物为静态文件,需配合 Nginx 等Web服务器部署并配置 `/api` 反向代理到后端。