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):
return Ad.batch_delete_r(ad_id)
return ad_repo.batch_delete_r(ad_id)
# 设置状态
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):
return AdSort.batch_delete_r(adsort_id)
return adsort_repo.batch_delete_r(adsort_id)
# 查询广告位列表
def get_ad_sort_list():
+1 -1
View File
@@ -129,7 +129,7 @@ def update_item(request, data: ItemForm):
# 删除站点
def delete_item(item_id):
return Item.batch_delete_r(item_id)
return item_repo.batch_delete_r(item_id)
# 获取站点列表
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):
return ItemCate.batch_delete_r(cate_id)
return itemcate_repo.batch_delete_r(cate_id)
# 获取栏目列表
def get_cate_list():
+2 -2
View File
@@ -104,7 +104,7 @@ def update_config(request, data: ConfigForm):
# 删除配置
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):
return ConfigItem.batch_delete_r(config_id)
return configitem_repo.batch_delete_r(config_id)
# 设置状态
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):
return Dict.batch_delete_r(dict_id)
return dict_repo.batch_delete_r(dict_id)
from datetime import datetime, timezone
@@ -205,7 +205,7 @@ def update_dict_item(request, data: DictItemForm):
# 删除字典项
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):
+1 -1
View File
@@ -155,7 +155,7 @@ def delete_job(job_id):
id_list = parse_id_list(job_id)
for jid in id_list:
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):
return Link.batch_delete_r(link_id)
return link_repo.batch_delete_r(link_id)
# 设置状态
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):
return Member.batch_delete_r(member_id)
return member_repo.batch_delete_r(member_id)
# 设置状态
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):
return MemberLevel.batch_delete_r(member_level_id)
return memberlevel_repo.batch_delete_r(member_level_id)
# 获取会员等级列表
def get_member_level_list():
+1 -1
View File
@@ -126,4 +126,4 @@ def update_notice(request, data: NoticeForm):
# 删除通知公告
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):
return City.batch_delete_r(city_id)
return city_repo.batch_delete_r(city_id)
# 根据城市ID获取子级城市
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):
return Dept.batch_delete_r(dept_id)
return dept_repo.batch_delete_r(dept_id)
# 获取部门列表
def get_dept_list():
+1 -1
View File
@@ -152,7 +152,7 @@ def update_level(request, data: LevelForm):
# 删除职级
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):
+1 -1
View File
@@ -101,7 +101,7 @@ def update_position(request, data: PositionForm):
# 删除岗位
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):
+1 -1
View File
@@ -273,7 +273,7 @@ async def add_user_role(user_id, roleIdList):
# 删除用户
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):
+4 -80
View File
@@ -6,20 +6,15 @@
# +======================================================================
# 由 apps/models/base_model.py 迁移而来。
"""数据库模型基类:通用字段、序列化与通用查询方法。"""
"""数据库模型基类:通用字段与序列化方法(数据访问统一走 Repository)。"""
import logging
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, get_db_session
from core.database import Base
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)
@@ -76,74 +71,3 @@ class base_model(Base):
value = value.strftime('%Y-%m-%d')
result[column.name] = value
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.py 继承本类并提供自定义查询,service 通过 repository 访问数据库。
过渡期与 base_model 的 classmethod 双轨并存,全部模块迁移完成后收敛。
"""
from typing import Generic, Optional, TypeVar
from core import R
from core.database import get_db_session
from shared.constants import PAGE_SIZE
from utils.request import parse_id_list
@@ -132,6 +132,29 @@ class BaseRepository(Generic[M]):
setattr(record, self.soft_delete_col, 1)
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:
"""物理删除实例。"""
self.db.delete(obj)