优化更新
This commit is contained in:
@@ -55,10 +55,10 @@
|
||||
┌──────────────────────────────────────────────────────────────────┐
|
||||
│ BaseRepository (src/common/base_repository.py) │
|
||||
│ ─────────────────────────────────────────────────────────────── │
|
||||
│ 查询: get_by_id / get_by_ids / get_one / get_all / count │
|
||||
│ 分页: paginate → (items, total) │
|
||||
│ 查询: get_by_id / get_by_ids / get_all / first_by / count_by │
|
||||
│ 分页: find_page / find_list │
|
||||
│ 写操作: create / update / batch_delete │
|
||||
│ 条件: filter (原始) / filter_by (等值+软删) │
|
||||
│ 条件: exists / exists_by (等值+软删) │
|
||||
│ 软删除: 等值方法自动追加 is_delete=0 │
|
||||
└──────────────────────────┬───────────────────────────────────────┘
|
||||
│
|
||||
@@ -104,29 +104,39 @@
|
||||
### 通用字段
|
||||
|
||||
```python
|
||||
class BaseModel(Base):
|
||||
# src/common/base_model.py
|
||||
from src.core.database import db
|
||||
from sqlalchemy import text, func
|
||||
|
||||
def now():
|
||||
"""返回当前时间(北京时间)"""
|
||||
from datetime import datetime
|
||||
return datetime.now()
|
||||
|
||||
class BaseModel(db.Model):
|
||||
__abstract__ = True # 抽象基类,不会在数据库中创建对应的表
|
||||
# 主键:自增整数,所有业务表的唯一标识
|
||||
id = Column(Integer, primary_key=True, autoincrement=True, comment="主键ID")
|
||||
# 创建人:记录该条记录的创建者用户名,由 Service 层自动填充
|
||||
create_user = Column(String(50), nullable=True, comment="创建人用户名")
|
||||
# 创建时间:记录创建时的 UTC 时间,数据库默认自动生成
|
||||
create_time = Column(DateTime, default=_UTC_NOW, server_default=func.now(), comment="创建时间")
|
||||
# 更新人:记录最后修改该条记录的用户名,由 Service 层自动填充
|
||||
update_user = Column(String(50), nullable=True, comment="最后更新人用户名")
|
||||
# 更新时间:记录最后修改时间,更新时自动刷新,数据库默认自动生成
|
||||
update_time = Column(DateTime, default=_UTC_NOW, onupdate=_UTC_NOW, server_default=func.now(), comment="最后更新时间")
|
||||
# 逻辑删除标记:0 表示正常记录,1 表示已删除,物理删除不使用,保证数据可恢复;添加索引以提升查询性能,Repository 层默认过滤 is_delete=0
|
||||
is_delete = Column(Integer, default=0, server_default=text('0'), index=True, comment="逻辑删除标识:0-正常,1-已删除")
|
||||
|
||||
# 主键:自增整数
|
||||
id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment="主键ID")
|
||||
# 创建人:记录创建者,由业务层通过 get_realname() 设置
|
||||
create_user = db.Column(db.String(64), default='', server_default=text("''"), comment="创建人")
|
||||
# 创建时间:记录创建时间,创建后不再变化
|
||||
create_time = db.Column(db.DateTime, default=now, server_default=func.now(), comment="创建时间")
|
||||
# 更新人:记录最后修改者
|
||||
update_user = db.Column(db.String(64), default='', server_default=text("''"), comment="更新人")
|
||||
# 更新时间:记录最后修改时间,更新时自动刷新
|
||||
update_time = db.Column(db.DateTime, default=now, onupdate=now, server_default=func.now(), comment="最后更新时间")
|
||||
# 逻辑删除标记:0=正常,1=已删除
|
||||
is_delete = db.Column(db.Integer, default=0, server_default=text('0'), index=True, comment="逻辑删除标识:0-正常,1-已删除")
|
||||
```
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|:---|:---|:---|
|
||||
| `id` | Integer, PK, AI | 主键自增 |
|
||||
| `create_user` | String(50) | 创建人(realname) |
|
||||
| `create_time` | DateTime | 创建时间(UTC,server_default) |
|
||||
| `update_user` | String(50) | 更新人(realname) |
|
||||
| `update_time` | DateTime | 更新时间(UTC,onupdate 自动触发) |
|
||||
| `create_user` | String(64) | 创建人(realname),默认空字符串 |
|
||||
| `create_time` | DateTime | 创建时间,server_default=func.now() |
|
||||
| `update_user` | String(64) | 更新人(realname),默认空字符串 |
|
||||
| `update_time` | DateTime | 更新时间,onupdate 自动触发 |
|
||||
| `is_delete` | Integer | 软删除标识:0=正常,1=已删除 |
|
||||
|
||||
### 表注释钩子
|
||||
@@ -203,30 +213,29 @@ class BaseDB:
|
||||
# | 说明: 统一处理前端传入的空字符串 id → None 等通用校验
|
||||
# +======================================================================
|
||||
|
||||
from wtforms import Form, IntegerField
|
||||
from wtforms.validators import Optional
|
||||
from flask_wtf import FlaskForm
|
||||
from src.common.forms.fields import ArrayField
|
||||
|
||||
|
||||
class BaseForm(Form):
|
||||
class BaseForm(FlaskForm):
|
||||
"""
|
||||
表单基类
|
||||
自定义表单基类,增强对 JSON 数组的支持
|
||||
|
||||
所有创建/编辑表单应继承此类,自动获得:
|
||||
1. id 字段:Optional,前端传空字符串时自动转为 None
|
||||
重写 process 方法,确保 ArrayField 能正确处理数组数据。
|
||||
"""
|
||||
|
||||
id = IntegerField('ID', validators=[Optional()])
|
||||
def process(self, formdata=None, obj=None, data=None, **kwargs):
|
||||
"""重写 process 方法,支持 ArrayField 处理数组数据"""
|
||||
# ... 处理逻辑
|
||||
```
|
||||
|
||||
### 代码解析
|
||||
|
||||
**可选 `id` 字段**:
|
||||
**继承 `FlaskForm`**:`BaseForm` 继承自 `flask_wtf.FlaskForm`(而非 `wtforms.Form`),获得 CSRF 保护等 Flask 集成能力。
|
||||
|
||||
```python
|
||||
id = IntegerField('ID', validators=[Optional()])
|
||||
```
|
||||
**ArrayField 支持**:重写 `process` 方法,确保 `ArrayField` 能正确处理前端传入的 JSON 数组数据。
|
||||
|
||||
`id` 默认为 `None`。创建记录时前端不传 `id`,WTForms 自动赋默认值;编辑记录时前端传入 `id`,Service 层据此判断是新增还是更新。
|
||||
**id 字段由子类自行定义**:`BaseForm` 本身不定义 `id` 字段,各业务表单类根据需要自行声明(通常为 `IntegerField` + `Optional()`)。
|
||||
|
||||
### 子类示例
|
||||
|
||||
@@ -301,7 +310,7 @@ class PositionForm(BaseForm):
|
||||
### 软删除约定
|
||||
|
||||
:::warning 重要设计约定
|
||||
- **等值便捷方法**(get_by_id / get_one / get_all / count / filter_by / exists / exists_by_field / paginate)自动追加 `is_delete=0` 过滤,调用方无需关心
|
||||
- **等值便捷方法**(get_by_id / get_by_ids / get_all / first_by / count_by / exists / exists_by / find_page / find_list)自动追加 `is_delete=0` 过滤,调用方无需关心
|
||||
- **原始出口** `filter(*criterion)` **不做**软删过滤,由调用方自行追加 `Model.is_delete == 0`,用于 `in_` / `!=` / `and_` / 区间等复杂条件
|
||||
:::
|
||||
|
||||
@@ -352,13 +361,17 @@ WTForms Schema 可能用 camelCase(如 `parentId`),而模型列是 snake_c
|
||||
|
||||
| 方法 | 说明 | 返回值 |
|
||||
|:---|:---|:---|
|
||||
| `get_page()` | 分页查询 | `R.ok(data=[...], count=total)` |
|
||||
| `get_list()` | 不分页查询 | `R.ok(data=[...])` |
|
||||
| `get_page(params)` | 分页查询 | `dict`(含 records/total 等分页数据) |
|
||||
| `get_list(params)` | 不分页查询 | `list`(记录列表) |
|
||||
| `get_detail(obj_id)` | 详情查询 | `dict` 或 `None` |
|
||||
| `add(data)` | 新增记录 | `R.ok(msg='添加成功')` |
|
||||
| `update(data)` | 编辑记录 | 含表单校验 + 存在性校验 |
|
||||
| `remove(ids)` | 批量软删除 | 逗号分隔 ID 字符串 |
|
||||
| `update_status(data)` | 状态切换 | 含状态表单校验 |
|
||||
| `add(data)` | 新增记录 | `None`(成功无返回,失败 raise BizError) |
|
||||
| `update(data)` | 编辑记录 | `None`(成功无返回,失败 raise BizError) |
|
||||
| `remove(ids)` | 批量软删除 | `int`(删除数量) |
|
||||
| `update_status(data)` | 状态切换 | `None`(成功无返回,失败 raise BizError) |
|
||||
|
||||
:::warning Service 不返回 R 对象
|
||||
Service 层入参为数据字典、出参为纯数据(或 None),业务失败通过 `raise BizError` 表达。Router 层负责封装 `R.ok()` / `R.failed()` 响应。
|
||||
:::
|
||||
|
||||
### 钩子方法
|
||||
|
||||
|
||||
Reference in New Issue
Block a user