# AI 开发提示词 — 项目架构与模块开发规范 > 在向 AI 提出开发需求时,将以下提示词附加在需求描述之后,AI 即可按照项目架构规范生成代码,避免多人协作时的合并冲突。 --- ## 提示词内容(复制到你的需求后面) ``` ## 项目架构与模块开发规范 ### 一、项目概述 Under18 是一个前后端分离的 RBAC 权限管理脚手架,提供用户、角色、权限、字典、标签、日志等通用功能模块。采用模块化自动注册架构,新增功能模块时**严禁修改任何共享/公共文件**,所有新代码必须放在独立模块文件中。 **技术栈:** - 后端:FastAPI + SQLAlchemy(异步)+ PostgreSQL + Alembic - 前端:Vue 3 + Vite 5 + Element Plus + Pinia + Vue Router 4 - 缓存:cachetools.TTLCache(进程内,替代 Redis) - 认证:JWT(HS256),Access 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 Token(120min)+ Refresh Token(7天),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` - 新页面样式使用 `