refactor(repo): 收敛 base_model 双轨,删除函数统一走 repo.batch_delete_r

- shared/base_repository.py 新增 batch_delete_r(返回 R,等价原 base_model 语义)
- 20 个模块删除函数从 Model.batch_delete_r 改为 x_repo.batch_delete_r
- shared/base_model.py 移除 classmethod(get_by_id/get_by_ids/get_all_active/exists/batch_delete_r),只留字段 + to_dict
- 清理 base_model 多余 imports
- 实测 dept 删除、批量删除及多模块读接口正常

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Claude
2026-08-07 11:28:25 +08:00
co-authored by Claude
parent 2cb71cc50d
commit ae2e141713
17 changed files with 46 additions and 99 deletions
+1 -1
View File
@@ -150,7 +150,7 @@ def update_ad(request, data: AdForm):
# 删除广告 # 删除广告
def delete_ad(ad_id): def delete_ad(ad_id):
return Ad.batch_delete_r(ad_id) return ad_repo.batch_delete_r(ad_id)
# 设置状态 # 设置状态
def update_ad_status(request, data: AdStatusForm): def update_ad_status(request, data: AdStatusForm):
+1 -1
View File
@@ -115,7 +115,7 @@ def update_ad_sort(request, data: AdSortForm):
# 删除广告位 # 删除广告位
def delete_ad_sort(adsort_id): def delete_ad_sort(adsort_id):
return AdSort.batch_delete_r(adsort_id) return adsort_repo.batch_delete_r(adsort_id)
# 查询广告位列表 # 查询广告位列表
def get_ad_sort_list(): def get_ad_sort_list():
+1 -1
View File
@@ -129,7 +129,7 @@ def update_item(request, data: ItemForm):
# 删除站点 # 删除站点
def delete_item(item_id): def delete_item(item_id):
return Item.batch_delete_r(item_id) return item_repo.batch_delete_r(item_id)
# 获取站点列表 # 获取站点列表
def get_item_list(): def get_item_list():
+1 -1
View File
@@ -145,7 +145,7 @@ def update_item_cate(request, data: ItemCateForm):
# 删除栏目 # 删除栏目
def delete_item_cate(cate_id): def delete_item_cate(cate_id):
return ItemCate.batch_delete_r(cate_id) return itemcate_repo.batch_delete_r(cate_id)
# 获取栏目列表 # 获取栏目列表
def get_cate_list(): def get_cate_list():
+2 -2
View File
@@ -104,7 +104,7 @@ def update_config(request, data: ConfigForm):
# 删除配置 # 删除配置
def delete_config(config_id): def delete_config(config_id):
return Config.batch_delete_r(config_id) return config_repo.batch_delete_r(config_id)
# 解析配置项选项字符串为字典 # 解析配置项选项字符串为字典
@@ -320,7 +320,7 @@ def update_config_item(request, data: ConfigItemForm):
# 删除配置项 # 删除配置项
def delete_config_item(config_id): def delete_config_item(config_id):
return ConfigItem.batch_delete_r(config_id) return configitem_repo.batch_delete_r(config_id)
# 设置状态 # 设置状态
def update_config_item_status(request, data: ConfigItemStatusForm): def update_config_item_status(request, data: ConfigItemStatusForm):
+2 -2
View File
@@ -99,7 +99,7 @@ def update_dict(request, data: DictForm):
# 删除字典 # 删除字典
def delete_dict(dict_id): def delete_dict(dict_id):
return Dict.batch_delete_r(dict_id) return dict_repo.batch_delete_r(dict_id)
from datetime import datetime, timezone from datetime import datetime, timezone
@@ -205,7 +205,7 @@ def update_dict_item(request, data: DictItemForm):
# 删除字典项 # 删除字典项
def delete_dict_item(dict_id): def delete_dict_item(dict_id):
return DictItem.batch_delete_r(dict_id) return dictitem_repo.batch_delete_r(dict_id)
# 设置状态 # 设置状态
def update_dict_item_status(request, data: DictItemStatusForm): def update_dict_item_status(request, data: DictItemStatusForm):
+1 -1
View File
@@ -155,7 +155,7 @@ def delete_job(job_id):
id_list = parse_id_list(job_id) id_list = parse_id_list(job_id)
for jid in id_list: for jid in id_list:
remove_job_from_scheduler(jid) remove_job_from_scheduler(jid)
return Job.batch_delete_r(job_id) return job_repo.batch_delete_r(job_id)
# 设置任务状态 # 设置任务状态
+1 -1
View File
@@ -135,7 +135,7 @@ def update_link(request, data: LinkForm):
# 删除友链 # 删除友链
def delete_link(link_id): def delete_link(link_id):
return Link.batch_delete_r(link_id) return link_repo.batch_delete_r(link_id)
# 设置状态 # 设置状态
def update_link_status(request, data: LinkStatusForm): def update_link_status(request, data: LinkStatusForm):
+2 -2
View File
@@ -200,7 +200,7 @@ def update_member(request, data: MemberForm):
# 删除会员 # 删除会员
def delete_member(member_id): def delete_member(member_id):
return Member.batch_delete_r(member_id) return member_repo.batch_delete_r(member_id)
# 设置状态 # 设置状态
def update_member_status(request, data: MemberStatusForm): def update_member_status(request, data: MemberStatusForm):
@@ -323,7 +323,7 @@ def update_member_level(request, data: MemberLevelForm):
# 删除会员等级 # 删除会员等级
def delete_member_level(member_level_id): def delete_member_level(member_level_id):
return MemberLevel.batch_delete_r(member_level_id) return memberlevel_repo.batch_delete_r(member_level_id)
# 获取会员等级列表 # 获取会员等级列表
def get_member_level_list(): def get_member_level_list():
+1 -1
View File
@@ -126,4 +126,4 @@ def update_notice(request, data: NoticeForm):
# 删除通知公告 # 删除通知公告
def delete_notice(notice_id): def delete_notice(notice_id):
return Notice.batch_delete_r(notice_id) return notice_repo.batch_delete_r(notice_id)
+1 -1
View File
@@ -130,7 +130,7 @@ def update_city(request, data: CityForm):
# 删除城市 # 删除城市
def delete_city(city_id): def delete_city(city_id):
return City.batch_delete_r(city_id) return city_repo.batch_delete_r(city_id)
# 根据城市ID获取子级城市 # 根据城市ID获取子级城市
def get_child_list(city_code): def get_child_list(city_code):
+1 -1
View File
@@ -85,7 +85,7 @@ def update_dept(request, data: DeptForm):
# 删除部门 # 删除部门
def delete_dept(dept_id): def delete_dept(dept_id):
return Dept.batch_delete_r(dept_id) return dept_repo.batch_delete_r(dept_id)
# 获取部门列表 # 获取部门列表
def get_dept_list(): def get_dept_list():
+1 -1
View File
@@ -152,7 +152,7 @@ def update_level(request, data: LevelForm):
# 删除职级 # 删除职级
def delete_level(level_id): def delete_level(level_id):
return Level.batch_delete_r(level_id) return level_repo.batch_delete_r(level_id)
# 设置状态 # 设置状态
def update_level_status(request, data: LevelStatusForm): def update_level_status(request, data: LevelStatusForm):
+1 -1
View File
@@ -101,7 +101,7 @@ def update_position(request, data: PositionForm):
# 删除岗位 # 删除岗位
def delete_position(position_id): def delete_position(position_id):
return Position.batch_delete_r(position_id) return position_repo.batch_delete_r(position_id)
# 设置状态 # 设置状态
def update_position_status(request, data: PositionStatusForm): def update_position_status(request, data: PositionStatusForm):
+1 -1
View File
@@ -273,7 +273,7 @@ async def add_user_role(user_id, roleIdList):
# 删除用户 # 删除用户
def delete_user(user_id): def delete_user(user_id):
return User.batch_delete_r(user_id) return user_repo.batch_delete_r(user_id)
# 设置状态 # 设置状态
def update_user_status(request, data: UserStatusForm): def update_user_status(request, data: UserStatusForm):
+4 -80
View File
@@ -6,20 +6,15 @@
# +====================================================================== # +======================================================================
# 由 apps/models/base_model.py 迁移而来。 # 由 apps/models/base_model.py 迁移而来。
"""数据库模型基类:通用字段、序列化与通用查询方法。""" """数据库模型基类:通用字段与序列化方法(数据访问统一走 Repository)。"""
import logging
from datetime import date, datetime, timezone from datetime import date, datetime, timezone
from typing import Optional, List, Dict, Any from typing import Dict, Any
from sqlalchemy import Column, Integer, DATETIME, and_ from sqlalchemy import Column, Integer, DATETIME
from core import R from core.database import Base
from core.database import Base, get_db_session
from shared.constants import SERIALIZE_EXCLUDE_FIELDS from shared.constants import SERIALIZE_EXCLUDE_FIELDS
from utils.request import parse_id_list
logger = logging.getLogger(__name__)
_UTC_NOW = lambda: datetime.now(tz=timezone.utc) _UTC_NOW = lambda: datetime.now(tz=timezone.utc)
@@ -76,74 +71,3 @@ class base_model(Base):
value = value.strftime('%Y-%m-%d') value = value.strftime('%Y-%m-%d')
result[column.name] = value result[column.name] = value
return result return result
# ============================================================
# 通用查询方法
# ============================================================
@classmethod
def get_by_id(cls, id: Optional[int]) -> Optional['base_model']:
"""根据ID获取未删除的记录,不存在返回 None"""
if id is None or id <= 0:
return None
db = get_db_session()
return db.query(cls).filter(cls.id == id, cls.is_delete == 0).first()
@classmethod
def get_by_ids(cls, ids: List[int]) -> List['base_model']:
"""根据ID列表批量获取未删除的记录"""
if not ids:
return []
valid_ids = [i for i in ids if i and i > 0]
if not valid_ids:
return []
db = get_db_session()
return db.query(cls).filter(cls.id.in_(valid_ids), cls.is_delete == 0).all()
@classmethod
def get_all_active(cls) -> List['base_model']:
"""获取所有未删除的记录"""
db = get_db_session()
return db.query(cls).filter(cls.is_delete == 0).all()
@classmethod
def exists(cls, id: Optional[int]) -> bool:
"""检查未删除记录是否存在"""
if id is None or id <= 0:
return False
db = get_db_session()
return db.query(cls).filter(cls.id == id, cls.is_delete == 0).count() > 0
# ============================================================
# 删除方法
# ============================================================
@classmethod
def batch_delete_r(cls, ids_str: Optional[str]):
"""
批量软删除并返回R对象
封装ID校验、解析、软删除的完整流程。
Args:
ids_str: 逗号分隔的ID字符串,如 "1,2,3"
Returns:
R: 操作结果
"""
if not ids_str:
return R.failed("记录ID不存在")
id_list = parse_id_list(ids_str)
if not id_list:
return R.failed("记录ID不存在")
db = get_db_session()
records = db.query(cls).filter(and_(cls.id.in_(id_list), cls.is_delete == 0)).all()
if len(records) != len(id_list):
return R.failed("记录不存在")
for record in records:
record.is_delete = 1
return R.ok(msg="本次共删除{0}条数据".format(len(records)))
+24 -1
View File
@@ -8,11 +8,11 @@
"""通用 Repository 基类:封装各模型的数据访问层公共操作。 """通用 Repository 基类:封装各模型的数据访问层公共操作。
各模块 repository.py 继承本类并提供自定义查询,service 通过 repository 访问数据库。 各模块 repository.py 继承本类并提供自定义查询,service 通过 repository 访问数据库。
过渡期与 base_model 的 classmethod 双轨并存,全部模块迁移完成后收敛。
""" """
from typing import Generic, Optional, TypeVar from typing import Generic, Optional, TypeVar
from core import R
from core.database import get_db_session from core.database import get_db_session
from shared.constants import PAGE_SIZE from shared.constants import PAGE_SIZE
from utils.request import parse_id_list from utils.request import parse_id_list
@@ -132,6 +132,29 @@ class BaseRepository(Generic[M]):
setattr(record, self.soft_delete_col, 1) setattr(record, self.soft_delete_col, 1)
return True return True
def batch_delete_r(self, ids_str) -> R:
"""
批量软删除并返回 R 对象(等价原 base_model.batch_delete_r)。
Args:
ids_str: 逗号分隔的ID字符串,如 "1,2,3"
Returns:
R: 操作结果(成功 code=0,失败 code=1)
"""
if not ids_str:
return R.failed("记录ID不存在")
id_list = parse_id_list(ids_str)
if not id_list:
return R.failed("记录ID不存在")
records = self.db.query(self.model).filter(
self.model.id.in_(id_list), self._soft_col() == 0).all()
if len(records) != len(id_list):
return R.failed("记录不存在")
for record in records:
setattr(record, self.soft_delete_col, 1)
return R.ok(msg="本次共删除{0}条数据".format(len(records)))
def hard_delete(self, obj) -> bool: def hard_delete(self, obj) -> bool:
"""物理删除实例。""" """物理删除实例。"""
self.db.delete(obj) self.db.delete(obj)