签入版本

This commit is contained in:
2026-09-16 13:28:20 +08:00
parent 6cd5e80de0
commit c97d87847f
410 changed files with 68726 additions and 0 deletions
@@ -0,0 +1,276 @@
:::tip 参数管理
参数管理模块用于管理动态系统参数,与系统配置模块类似但更侧重于业务参数的灵活配置。支持按参数键查询、修改,无需重启服务即可生效。本模块是典型的「BaseService 简单模块」,通过声明差异点即可获得完整 CRUD 能力。
:::
## 模块结构
```
src/modules/param/
├── models.py # 参数模型
├── schemas.py # 表单验证
├── repository.py # 数据访问层
└── service.py # 业务逻辑层(继承 BaseService)
```
## 参数模型
```python
# src/modules/param/models.py
class Param(BaseModel):
"""参数模型类"""
__tablename__ = DB_PREFIX + "param"
__table_comment__ = "系统参数表"
# 参数名称
name = Column(String(100), nullable=False, index=True, comment="参数名称")
# 参数编码(唯一标识,用于业务代码中按编码取值)
code = Column(String(100), nullable=False, index=True, comment="参数编码")
# 参数值
value = Column(String(255), nullable=False, comment="参数值")
# 参数类型:0-系统 1-业务
type = Column(Integer, nullable=False, comment="参数类型:0-系统 1-业务")
# 参数状态:1-正常 2-禁用
status = Column(Integer, nullable=False, index=True, comment="参数状态:1-正常 2-禁用")
# 参数排序
sort = Column(Integer, nullable=False, comment="参数排序")
# 参数备注
note = Column(String(255), nullable=True, comment="参数备注")
```
其中 `id`、`create_user`、`create_time`、`update_user`、`update_time`、`is_delete` 由基类 `base_model` 自动提供。
## 表单验证
```python
class ParamForm(BaseSchema):
name: str = Field(..., min_length=1, max_length=100, description="参数名称")
code: str = Field(..., min_length=1, max_length=100, description="参数编码")
value: str = Field(..., min_length=1, max_length=255, description="参数值")
type: int = Field(..., ge=0, le=1, description="参数类型:0-系统 1-业务")
status: int = Field(..., ge=1, le=2, description="参数状态:1-正常 2-禁用")
sort: int = Field(..., ge=0, le=99999, description="参数排序")
note: Optional[str] = Field(None, max_length=255, description="参数备注")
```
| 字段 | 必填 | 约束 | 说明 |
|:----|:----|:----|:----|
| `name` | 是 | `1~100 字符` | 参数名称,唯一 |
| `code` | 是 | `1~100 字符` | 参数编码,唯一,业务代码中按此取值 |
| `value` | 是 | `1~255 字符` | 参数值,字符串类型 |
| `type` | 是 | `0~1` | 0=系统参数,1=业务参数 |
| `status` | 是 | `1~2` | 1=正常,2=禁用(注意:非 0/1) |
| `sort` | 是 | `0~99999` | 排序号,值越大越靠前 |
| `note` | 否 | `max_length=255` | 备注说明 |
:::warning status 字段的取值范围
参数模块的 `status` 使用 `1=正常, 2=禁用`,与文章模块的 `0=正常, 1=下架` 不同。这是历史约定,开发时需注意区分。
:::
## Service 层设计
### 继承 BaseService
参数模块是典型的 BaseService 简单模块,只需声明差异点即可获得完整 CRUD 能力:
```python
class ParamService(BaseService(Param]):
"""参数业务服务类,继承基础服务获得通用 CRUD 能力"""
# ============ 必须声明 ============
repo = param_repo # 数据访问层实例
model = Param # 模型类
# ============ 分页差异点 ============
page_like_fields = ('name', 'code') # 模糊搜索字段
page_eq_fields = ('type', 'status') # 等值搜索字段
page_order_by = (('sort', 'asc'), ('id', 'desc')) # 排序规则
# ============ 唯一性校验 ============
unique_fields = {
'name': '参数名称不能重复',
'code': '参数编码不能重复'
}
# ============ 枚举显示名映射 ============
serialize_maps = {
'type': 'param_type', # 参数类型 → 数据字典
'status': 'param_status' # 参数状态 → 数据字典
}
# ============ 自定义方法 ============
def get_value_by_code(self, code: str, default: Optional[str] = None) -> Optional[str]:
"""根据参数编码获取参数值"""
param = self.repo.get_one(code=code, status=1)
return param.value if param else default
```
### 差异点详解
#### page_like_fields(模糊搜索)
声明后,BaseService 自动从 `request.query_params` 中取同名参数做 `LIKE %值%` 查询:
```python
# 声明 page_like_fields = ('name', 'code') 后
# 请求 GET /api/v1/param/page?name=默认&code=PASSWORD
# 自动生成:WHERE name LIKE '%默认%' AND code LIKE '%PASSWORD%'
```
#### page_eq_fields(等值搜索)
声明后,自动取同名参数做精确匹配:
```python
# 声明 page_eq_fields = ('type', 'status') 后
# 请求 GET /api/v1/param/page?type=0&status=1
# 自动生成:WHERE type = 0 AND status = 1
```
#### page_order_by(排序规则)
```python
# 声明 page_order_by = (('sort', 'asc'), ('id', 'desc'))
# 生成:ORDER BY sort ASC, id DESC
# 即排序号越小越靠前,同排序号时新记录在前
```
#### unique_fields(唯一性校验)
```python
# 声明 unique_fields = {'name': '参数名称不能重复', 'code': '参数编码不能重复'}
# 新增时:查询是否存在同名/同编码记录
# 编辑时:查询是否存在同名/同编码记录(排除自身 ID)
# 若重复:返回 R.failed('参数名称不能重复')
```
BaseService 内部自动调用 `repo.exists_by_field(field, value, exclude_id)` 实现,无需手写校验逻辑。
#### serialize_maps(枚举显示名映射)
```python
# 声明 serialize_maps = {'type': 'param_type', 'status': 'param_status'}
# 序列化时自动调用 get_dict_map('param_type') 获取字典映射
# 输出时自动补 data['type_name'] = '系统参数' / '业务参数'
# 输出时自动补 data['status_name'] = '正常' / '禁用'
```
分页列表和详情接口均自动输出枚举名称,前端可直接展示中文。
## 按编码取值
这是参数模块的核心自定义方法,供其他业务模块调用:
```python
param_service = ParamService()
# 获取参数值(存在且状态=正常时返回值,否则返回默认值)
default_pwd = param_service.get_value_by_code("USER_DEFAULT_PASSWORD", "123456")
upload_limit = param_service.get_value_by_code("UPLOAD_MAX_SIZE", "10")
maintenance = param_service.get_value_by_code("MAINTENANCE_MODE", "0")
```
### 实现原理
```python
def get_value_by_code(self, code: str, default: Optional[str] = None) -> Optional[str]:
param = self.repo.get_one(code=code, status=1) # 按编码查询,状态必须为正常
return param.value if param else default
```
- `repo.get_one(code=code, status=1)` 自动过滤软删除记录(`is_delete=0`)
- `status=1` 确保禁用的参数不会被读取
- 未找到时返回 `default` 值,避免调用方判空
:::tip 典型用法
在其他 service 中注入参数值,实现运行时可调的业务配置:
```python
from modules.param.service import param_service
def reset_password(user_id):
# 从参数表读取默认密码,无需硬编码
default_pwd = param_service.get_value_by_code("USER_DEFAULT_PASSWORD", "123456")
# ... 重置密码逻辑
```
:::
## Repository 层
```python
class ParamRepository(BaseRepository(Param]):
"""参数数据仓库,继承基础仓库获得通用 CRUD 能力"""
pass
param_repo = ParamRepository(Param)
```
参数模块无需自定义查询方法,BaseRepository 的通用方法已满足需求。
## API 接口
| 接口 | 方法 | 权限节点 | 说明 |
|:----|:----|:----|:----|
| `/api/v1/param/page` | GET | `sys:param:page` | 分页查询(支持 name/code 模糊搜索 + type/status 精确匹配) |
| `/api/v1/param/detail/{id}` | GET | `sys:param:detail` | 详情查询 |
| `/api/v1/param/add` | POST | `sys:param:add` | 新增参数(自动校验 name/code 唯一性) |
| `/api/v1/param/update` | PUT | `sys:param:update` | 编辑参数(自动校验 name/code 唯一性,排除自身) |
| `/api/v1/param/delete/{id}` | DELETE | `sys:param:delete` | 单条删除 |
| `/api/v1/param/batchDelete` | DELETE | `sys:param:batchDelete` | 批量删除 |
### 查询参数
分页接口支持以下查询参数(BaseService 自动处理):
| 参数 | 类型 | 说明 |
|:----|:----|:----|
| `pageNo` | int | 页码,默认 1 |
| `pageSize` | int | 每页条数,默认 10 |
| `name` | string | 参数名称,模糊搜索 |
| `code` | string | 参数编码,模糊搜索 |
| `type` | int | 参数类型,精确匹配(0=系统 1=业务) |
| `status` | int | 参数状态,精确匹配(1=正常 2=禁用) |
## 数据字典
参数模块使用以下数据字典(需在字典管理中配置):
| 字典编码 | 用途 | 字典项示例 |
|:----|:----|:----|
| `param_type` | 参数类型名称 | 0=系统参数, 1=业务参数 |
| `param_status` | 参数状态名称 | 1=正常, 2=禁用 |
BaseService 的 `serialize_maps` 声明后,分页列表和详情接口自动输出 `type_name` 和 `status_name` 字段。
## 与系统配置的区别
| 特性 | 参数管理(Param) | 系统配置(Config) |
|:----|:----|:----|
| 用途 | 单个系统参数 | 配置分组 + 配置项 |
| 结构 | 扁平(name+code+value) | 两级(config + config_item) |
| 典型场景 | 默认密码、功能开关、上传限制 | SMTP 配置、站点信息、第三方服务 |
| 取值方式 | `param_service.get_value_by_code()` | `config_service.get_value_by_key()` |
| Service 模式 | BaseService 子类 | BaseService 子类 |
## 开发要点
```
1. BaseService 子类:声明差异点即可,无需手写 CRUD 逻辑
2. 唯一性校验:unique_fields 声明后自动校验 name 和 code 唯一性
3. 枚举映射:serialize_maps 声明后自动输出 type_name 和 status_name
4. 按编码取值:get_value_by_code() 是核心方法,供其他模块调用
5. 状态值注意:status 使用 1=正常 2=禁用(非 0/1),与文章模块不同
6. 排序规则:page_order_by = (('sort', 'asc'), ('id', 'desc')),排序号越小越靠前
```
## 总结
参数管理模块是项目中典型的 BaseService 简单模块,核心特点:
```
1. 继承 BaseService:声明 repo/model/page_like_fields/page_eq_fields/unique_fields/serialize_maps 即可
2. 模糊 + 等值搜索:name/code 模糊搜索,type/status 等值搜索,BaseService 自动处理
3. 唯一性校验:name 和 code 双重唯一性,BaseService 自动校验
4. 枚举映射:type 和 status 自动映射为中文名称
5. 按编码取值:get_value_by_code() 供其他业务模块调用,实现运行时可调配置
6. 软删除 + 状态过滤:get_one 自动过滤已删除和已禁用的参数
```