签入版本
This commit is contained in:
@@ -0,0 +1,459 @@
|
||||
# 完整代码清单
|
||||
|
||||
本章汇总 Position 岗位模块涉及的全部文件,便于开发时快速查阅和复制。
|
||||
|
||||
## 后端文件清单
|
||||
|
||||
### 1. 数据模型 `src/modules/system/position/models.py`
|
||||
|
||||
```python
|
||||
from sqlalchemy import Column, String, Integer, text
|
||||
|
||||
from core.base_db import base_db
|
||||
from core.base_model import base_model
|
||||
from core.config import DB_PREFIX
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 岗位模型
|
||||
# ============================================================
|
||||
class Position(base_model, base_db):
|
||||
"""岗位模型类"""
|
||||
# ============================================================
|
||||
# 表名配置
|
||||
# ============================================================
|
||||
__tablename__ = DB_PREFIX + "position"
|
||||
__table_comment__ = "岗位表"
|
||||
|
||||
# ============================================================
|
||||
# 字段定义
|
||||
# ============================================================
|
||||
# 岗位名称
|
||||
name = Column(String(255), nullable=False, index=True, comment="岗位名称")
|
||||
# 岗位状态:1-在用 2-停用
|
||||
status = Column(Integer, default=0, server_default=text('0'), index=True, comment="岗位状态:1-在用 2-停用")
|
||||
# 岗位排序
|
||||
sort = Column(Integer, default=0, server_default=text('0'), comment="岗位排序")
|
||||
|
||||
# ============================================================
|
||||
# 内置方法
|
||||
# ============================================================
|
||||
def __repr__(self):
|
||||
"""返回岗位名称作为字符串表示"""
|
||||
return '岗位:{}'.format(self.name)
|
||||
```
|
||||
|
||||
### 2. 表单验证 `src/modules/system/position/schemas.py`
|
||||
|
||||
```python
|
||||
# +======================================================================
|
||||
# | 模块: 岗位表单验证
|
||||
# | 说明: 岗位创建/编辑/状态更新的请求数据校验
|
||||
# +======================================================================
|
||||
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
from core.base_schemas import BaseForm
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 岗位表单类
|
||||
# ============================================================
|
||||
class PositionForm(BaseForm):
|
||||
"""岗位创建/编辑表单"""
|
||||
name: str = Field(..., min_length=1, max_length=150, description="岗位名称")
|
||||
status: int = Field(..., ge=1, le=2, description="岗位状态:1-在用 2-停用")
|
||||
sort: int = Field(..., ge=0, le=99999, description="岗位排序")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 设置状态表单类
|
||||
# ============================================================
|
||||
class PositionStatusForm(BaseModel):
|
||||
"""岗位状态更新表单"""
|
||||
id: int = Field(..., gt=0, description="岗位ID")
|
||||
status: int = Field(..., ge=1, le=2, description="岗位状态:1-在用 2-停用")
|
||||
```
|
||||
|
||||
### 3. 数据访问层 `src/modules/system/position/repository.py`
|
||||
|
||||
```python
|
||||
# +======================================================================
|
||||
# | 模块: 岗位数据访问层
|
||||
# | 说明: 封装岗位模型的数据访问操作
|
||||
# +======================================================================
|
||||
|
||||
from modules.system.position.models import Position
|
||||
from core.base_repository import BaseRepository
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 岗位仓库类
|
||||
# ============================================================
|
||||
class PositionRepository(BaseRepository[Position]):
|
||||
"""岗位数据仓库,继承基础仓库获得通用 CRUD 能力"""
|
||||
pass
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 仓库实例
|
||||
# ============================================================
|
||||
position_repo = PositionRepository(Position)
|
||||
```
|
||||
|
||||
### 4. 业务逻辑层 `src/modules/system/position/service.py`
|
||||
|
||||
```python
|
||||
# +======================================================================
|
||||
# | 模块: 岗位业务逻辑层
|
||||
# | 说明: 岗位的增删改查、唯一性校验、状态管理等业务处理
|
||||
# +======================================================================
|
||||
|
||||
from typing import Optional
|
||||
|
||||
from core.base_service import BaseService
|
||||
from modules.system.position.models import Position
|
||||
from modules.system.position.repository import position_repo
|
||||
from modules.system.user.models import User
|
||||
from modules.system.user.repository import user_repo
|
||||
from utils.request import parse_id_list
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 岗位业务服务类
|
||||
# ============================================================
|
||||
class PositionService(BaseService[Position]):
|
||||
"""岗位业务服务类,继承基础服务获得通用 CRUD 能力"""
|
||||
# 数据访问与模型
|
||||
repo = position_repo
|
||||
model = Position
|
||||
# 分页差异点
|
||||
page_like_fields = ('name',)
|
||||
page_eq_fields = ('status',)
|
||||
page_order_by = (('sort', 'asc'),)
|
||||
# 唯一性校验
|
||||
unique_fields = {'name': '岗位名称不能重复'}
|
||||
|
||||
# ============================================================
|
||||
# 删除前校验
|
||||
# ============================================================
|
||||
def _before_delete(self, ids) -> Optional[str]:
|
||||
"""删除前校验:存在用户引用该岗位时禁止删除,避免用户岗位悬空"""
|
||||
id_list = parse_id_list(str(ids))
|
||||
if id_list and user_repo.filter(User.position_id.in_(id_list), User.is_delete == 0).first():
|
||||
return "存在用户引用该岗位,请先调整用户岗位"
|
||||
return None
|
||||
|
||||
# ============================================================
|
||||
# 获取岗位数据列表
|
||||
# ============================================================
|
||||
def get_position_list(self, request):
|
||||
"""获取岗位数据列表"""
|
||||
# 与 /page 一致的筛选条件:name 模糊、status 精确;保留软删过滤与排序
|
||||
query = self._apply_page_filters(self.repo.filter_by(), request)
|
||||
query = query.order_by(self.model.sort.asc())
|
||||
# 返回结果
|
||||
return [v.to_dict() for v in query.all()]
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 模块级单例
|
||||
# ============================================================
|
||||
position_service = PositionService()
|
||||
```
|
||||
|
||||
### 5. API 端点 `src/api/v1/endpoints/position.py`
|
||||
|
||||
```python
|
||||
# +======================================================================
|
||||
# | 模块: 岗位路由层
|
||||
# | 说明: 提供岗位信息的增删改查、状态管理、列表获取等 API 接口
|
||||
# +======================================================================
|
||||
|
||||
from fastapi import APIRouter, Request
|
||||
|
||||
from modules.system.position.schemas import PositionForm, PositionStatusForm
|
||||
from core.access_decorators import check_demo
|
||||
from core.access_decorators import permission_required
|
||||
from modules.system.position.service import position_service
|
||||
|
||||
from core import R
|
||||
|
||||
# ============================================================
|
||||
# 创建路由实例
|
||||
# ============================================================
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 查询分页数据
|
||||
# ============================================================
|
||||
@router.get('/page', summary='查询分页数据')
|
||||
@permission_required("sys:position:page")
|
||||
def page(request: Request):
|
||||
"""
|
||||
获取岗位分页列表
|
||||
:param request: FastAPI请求对象
|
||||
:return: 分页数据响应
|
||||
"""
|
||||
return position_service.get_page(request)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 查询岗位详情
|
||||
# ============================================================
|
||||
@router.get('/detail/{id}', summary='查询岗位详情')
|
||||
@permission_required("sys:position:detail")
|
||||
def detail(request: Request, id):
|
||||
"""
|
||||
根据岗位ID查询详细信息
|
||||
:param request: FastAPI请求对象
|
||||
:param id: 岗位ID(路径参数)
|
||||
:return: 岗位详情数据
|
||||
"""
|
||||
return R.ok(data=position_service.get_detail(id))
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 获取岗位列表
|
||||
# ============================================================
|
||||
@router.get('/list', summary='获取岗位列表')
|
||||
@permission_required("sys:position:list")
|
||||
def get_position_list(request: Request):
|
||||
"""
|
||||
获取所有岗位列表(无分页,用于下拉选择)
|
||||
:param request: FastAPI请求对象
|
||||
:return: 岗位列表数据
|
||||
"""
|
||||
return R.ok(data=position_service.get_position_list(request))
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 添加岗位
|
||||
# ============================================================
|
||||
@router.post('/add', summary='添加岗位')
|
||||
@permission_required("sys:position:add")
|
||||
@check_demo
|
||||
def add(request: Request, data: PositionForm):
|
||||
"""
|
||||
新增岗位
|
||||
:param request: FastAPI请求对象
|
||||
:param data: 岗位表单数据
|
||||
:return: 添加结果响应
|
||||
"""
|
||||
return position_service.add(request, data)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 更新岗位
|
||||
# ============================================================
|
||||
@router.put('/update', summary='更新岗位')
|
||||
@permission_required("sys:position:update")
|
||||
@check_demo
|
||||
def update(request: Request, data: PositionForm):
|
||||
"""
|
||||
更新岗位信息
|
||||
:param request: FastAPI请求对象
|
||||
:param data: 岗位表单数据(必须包含 id 字段)
|
||||
:return: 更新结果响应
|
||||
"""
|
||||
return position_service.update(request, data)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 删除岗位
|
||||
# ============================================================
|
||||
@router.delete('/delete/{id}', summary='删除岗位')
|
||||
@permission_required("sys:position:delete")
|
||||
@check_demo
|
||||
def delete(request: Request, id):
|
||||
"""
|
||||
根据ID删除单个岗位
|
||||
:param request: FastAPI请求对象
|
||||
:param id: 岗位ID(路径参数)
|
||||
:return: 删除结果响应
|
||||
"""
|
||||
return position_service.delete(id)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 设置岗位状态
|
||||
# ============================================================
|
||||
@router.put('/status', summary='设置岗位状态')
|
||||
@permission_required("sys:position:status")
|
||||
@check_demo
|
||||
def status(request: Request, data: PositionStatusForm):
|
||||
"""
|
||||
修改岗位状态(启用/禁用)
|
||||
:param request: FastAPI请求对象
|
||||
:param data: 状态表单数据
|
||||
:return: 状态更新结果响应
|
||||
"""
|
||||
return position_service.update_status(request, data)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 批量删除岗位
|
||||
# ============================================================
|
||||
@router.delete('/batchDelete', summary='批量删除岗位')
|
||||
@permission_required("sys:position:batchDelete")
|
||||
@check_demo
|
||||
async def batch_delete(request: Request):
|
||||
"""
|
||||
批量删除岗位(请求体需传入 ID 数组)
|
||||
|
||||
Request Body 示例:
|
||||
[1, 2, 3] # 岗位ID数组
|
||||
|
||||
:param request: FastAPI请求对象
|
||||
:return: 批量删除结果响应
|
||||
"""
|
||||
return await position_service.batch_delete(request)
|
||||
```
|
||||
|
||||
### 6. 路由注册(追加到 `src/api/v1/router.py`)
|
||||
|
||||
```python
|
||||
# 导入
|
||||
from api.v1.endpoints.position import router as position_router
|
||||
|
||||
# 注册
|
||||
v1.include_router(position_router, prefix="/position", tags=["岗位管理"])
|
||||
```
|
||||
|
||||
## 前端文件清单
|
||||
|
||||
### 7. API 请求 `ui/src/api/system/position.ts`
|
||||
|
||||
```typescript
|
||||
import { http } from '@/utils/http/axios';
|
||||
|
||||
/**
|
||||
* @description: 岗位列表
|
||||
*/
|
||||
export function getPositionList(params?) {
|
||||
return http.request({
|
||||
url: '/position/page',
|
||||
method: 'GET',
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取全部岗位列表
|
||||
* @param params 参数
|
||||
* @returns 返回结果
|
||||
*/
|
||||
export function getPositionAllList(params?) {
|
||||
return http.request({
|
||||
url: '/position/list',
|
||||
method: 'GET',
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 根据ID获取详情
|
||||
*/
|
||||
export function getPositionDetail(positionId) {
|
||||
return http.request({
|
||||
url: '/position/detail/' + positionId,
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 添加岗位
|
||||
*/
|
||||
export function positionAdd(data: any) {
|
||||
return http.request({
|
||||
url: '/position/add',
|
||||
method: 'POST',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 更新岗位
|
||||
*/
|
||||
export function positionUpdate(data: any) {
|
||||
return http.request({
|
||||
url: '/position/update',
|
||||
method: 'PUT',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 删除岗位
|
||||
*/
|
||||
export function positionDelete(positionId) {
|
||||
return http.request({
|
||||
url: '/position/delete/' + positionId,
|
||||
method: 'DELETE',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 批量删除岗位
|
||||
*/
|
||||
export function positionBatchDelete(data: any) {
|
||||
return http.request({
|
||||
url: '/position/batchDelete',
|
||||
method: 'DELETE',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### 8. 页面视图(4 个文件)
|
||||
|
||||
参考 [3.10 前端页面视图](/zh/volume2/fe-view) 中的完整代码,包含以下文件:
|
||||
|
||||
| 文件 | 说明 |
|
||||
|:----|:----|
|
||||
| `ui/src/views/system/position/index.vue` | 主页面:搜索 + 表格 + 操作 |
|
||||
| `ui/src/views/system/position/edit.vue` | 编辑弹窗:新增/编辑表单 |
|
||||
| `ui/src/views/system/position/columns.ts` | 表格列定义 |
|
||||
| `ui/src/views/system/position/querySchemas.ts` | 搜索表单 Schema |
|
||||
|
||||
### 9. 路由配置(追加到 `ui/src/router/routes/system.ts`)
|
||||
|
||||
```typescript
|
||||
{
|
||||
path: 'position',
|
||||
name: 'Position',
|
||||
component: () => import('/@/views/system/position/index.vue'),
|
||||
meta: { title: '岗位管理' },
|
||||
},
|
||||
```
|
||||
|
||||
## 开发检查清单
|
||||
|
||||
完成后端开发后,按顺序检查:
|
||||
|
||||
- [ ] `models.py` 已定义模型,表名含 `DB_PREFIX` 前缀
|
||||
- [ ] `schemas.py` 已定义表单类,继承 `BaseForm`
|
||||
- [ ] `repository.py` 已定义仓库类 + 模块级单例
|
||||
- [ ] `service.py` 已声明 `repo` / `model` / 分页配置 / 唯一性校验 + 单例
|
||||
- [ ] `endpoint.py` 已定义路由 + 权限装饰器 + 演示模式装饰器
|
||||
- [ ] `router.py` 已导入并注册路由
|
||||
- [ ] 菜单管理中已添加权限节点
|
||||
- [ ] 接口可通过 Swagger 文档正常调用
|
||||
|
||||
完成前端开发后,按顺序检查:
|
||||
|
||||
- [ ] `api/system/position.ts` 已封装所有接口
|
||||
- [ ] `views/system/position/index.vue` 主页面已实现
|
||||
- [ ] `views/system/position/edit.vue` 编辑弹窗已实现
|
||||
- [ ] `views/system/position/columns.ts` 列定义已配置
|
||||
- [ ] `views/system/position/querySchemas.ts` 搜索 Schema 已配置
|
||||
- [ ] 路由配置已追加到 `system.ts`
|
||||
- [ ] 后端菜单已配置组件路径
|
||||
- [ ] 页面可正常访问和操作
|
||||
|
||||
## 总结
|
||||
|
||||
完整模块涉及后端 5 个文件(models/schemas/repository/service/endpoint)+ 路由注册 + 权限配置,前端 4 个文件(index.vue/edit.vue/columns.ts/querySchemas.ts)+ API 文件。代码生成器可根据数据库表自动生成全套代码。
|
||||
Reference in New Issue
Block a user