refactor(orm): 将所有的批量 delete/update 重构为对象级操作,以确保触发 SQLAlchemy 审计事件
This commit is contained in:
@ -218,8 +218,8 @@ def delete_bom(bom_no):
|
|||||||
if not exist:
|
if not exist:
|
||||||
return jsonify({'code': 404, 'msg': 'BOM 不存在'}), 404
|
return jsonify({'code': 404, 'msg': 'BOM 不存在'}), 404
|
||||||
|
|
||||||
# 删除
|
# 删除(改为对象级删除以触发审计事件)
|
||||||
query.delete()
|
db.session.delete(exist)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return jsonify({
|
return jsonify({
|
||||||
'code': 200,
|
'code': 200,
|
||||||
|
|||||||
@ -444,7 +444,11 @@ def clear_draft():
|
|||||||
# 清除指定会话
|
# 清除指定会话
|
||||||
query = query.filter_by(session_id=session_id)
|
query = query.filter_by(session_id=session_id)
|
||||||
|
|
||||||
count = query.delete()
|
# 改为对象级删除以触发审计事件
|
||||||
|
records = query.all()
|
||||||
|
count = len(records)
|
||||||
|
for rec in records:
|
||||||
|
db.session.delete(rec)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
return jsonify({"message": f"已清除 {count} 条记录", "count": count}), 200
|
return jsonify({"message": f"已清除 {count} 条记录", "count": count}), 200
|
||||||
@ -461,8 +465,11 @@ def start_new_session():
|
|||||||
清空整张草稿表,返回新的 session_id
|
清空整张草稿表,返回新的 session_id
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# 清空整张草稿表
|
# 清空整张草稿表(改为对象级删除以触发审计事件)
|
||||||
deleted_count = StocktakeDraft.query.delete()
|
all_records = StocktakeDraft.query.all()
|
||||||
|
deleted_count = len(all_records)
|
||||||
|
for rec in all_records:
|
||||||
|
db.session.delete(rec)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
# 生成新的 session_id
|
# 生成新的 session_id
|
||||||
@ -1148,10 +1155,14 @@ def generate_missing_stocktake():
|
|||||||
|
|
||||||
# ★ 幂等性保护:先删除当前 session 下系统自动生成的漏盘记录
|
# ★ 幂等性保护:先删除当前 session 下系统自动生成的漏盘记录
|
||||||
# 特征:user_id == 'system' (表示由系统自动生成)
|
# 特征:user_id == 'system' (表示由系统自动生成)
|
||||||
deleted_count = StocktakeDraft.query.filter(
|
# 改为对象级删除以触发审计事件
|
||||||
|
system_records = StocktakeDraft.query.filter(
|
||||||
StocktakeDraft.session_id == session_id,
|
StocktakeDraft.session_id == session_id,
|
||||||
StocktakeDraft.user_id == 'system'
|
StocktakeDraft.user_id == 'system'
|
||||||
).delete()
|
).all()
|
||||||
|
deleted_count = len(system_records)
|
||||||
|
for rec in system_records:
|
||||||
|
db.session.delete(rec)
|
||||||
if deleted_count > 0:
|
if deleted_count > 0:
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
print(f"[generate_missing] 已清理 {deleted_count} 条历史漏盘记录")
|
print(f"[generate_missing] 已清理 {deleted_count} 条历史漏盘记录")
|
||||||
|
|||||||
@ -189,8 +189,10 @@ class BomService:
|
|||||||
raise ValueError(f'保存失败!当前子件配置与已有版本 {ver} 完全一致,请勿重复保存')
|
raise ValueError(f'保存失败!当前子件配置与已有版本 {ver} 完全一致,请勿重复保存')
|
||||||
|
|
||||||
# ===== 执行保存 =====
|
# ===== 执行保存 =====
|
||||||
# 仅删除当前版本的旧记录
|
# 仅删除当前版本的旧记录(改为对象级删除以触发审计事件)
|
||||||
BomTable.query.filter_by(bom_no=bom_no, version=version).delete()
|
old_records = BomTable.query.filter_by(bom_no=bom_no, version=version).all()
|
||||||
|
for rec in old_records:
|
||||||
|
db.session.delete(rec)
|
||||||
|
|
||||||
for child in children:
|
for child in children:
|
||||||
bom = BomTable(
|
bom = BomTable(
|
||||||
@ -260,7 +262,11 @@ class BomService:
|
|||||||
existing = BomTable.query.filter_by(parent_id=parent_id).first()
|
existing = BomTable.query.filter_by(parent_id=parent_id).first()
|
||||||
bom_no = existing.bom_no if existing else BomService.generate_bom_no()
|
bom_no = existing.bom_no if existing else BomService.generate_bom_no()
|
||||||
|
|
||||||
BomTable.query.filter_by(bom_no=bom_no, version=version).delete()
|
# 改为对象级删除以触发审计事件
|
||||||
|
old_records = BomTable.query.filter_by(bom_no=bom_no, version=version).all()
|
||||||
|
for rec in old_records:
|
||||||
|
db.session.delete(rec)
|
||||||
|
|
||||||
for item in child_list:
|
for item in child_list:
|
||||||
bom = BomTable(
|
bom = BomTable(
|
||||||
bom_no=bom_no, version=version, parent_id=parent_id,
|
bom_no=bom_no, version=version, parent_id=parent_id,
|
||||||
|
|||||||
@ -109,8 +109,10 @@ class PermissionService:
|
|||||||
try:
|
try:
|
||||||
# 1. 开启事务 (Flask-SQLAlchemy 自动管理,但明确逻辑更好)
|
# 1. 开启事务 (Flask-SQLAlchemy 自动管理,但明确逻辑更好)
|
||||||
|
|
||||||
# 2. 删除该角色旧的所有权限
|
# 2. 删除该角色旧的所有权限(改为对象级删除以触发审计事件)
|
||||||
SysRolePermission.query.filter_by(role_code=role_code).delete()
|
old_perms = SysRolePermission.query.filter_by(role_code=role_code).all()
|
||||||
|
for p in old_perms:
|
||||||
|
db.session.delete(p)
|
||||||
|
|
||||||
# 3. 准备新数据
|
# 3. 准备新数据
|
||||||
if permissions:
|
if permissions:
|
||||||
@ -374,10 +376,14 @@ class PermissionService:
|
|||||||
).all()
|
).all()
|
||||||
|
|
||||||
for menu in legacy_menus:
|
for menu in legacy_menus:
|
||||||
# 删除关联的权限
|
# 删除关联的权限(改为对象级删除以触发审计事件)
|
||||||
SysRolePermission.query.filter_by(target_code=menu.code).delete()
|
old_perms = SysRolePermission.query.filter_by(target_code=menu.code).all()
|
||||||
# 删除关联的元素
|
for p in old_perms:
|
||||||
SysElement.query.filter_by(menu_code=menu.code).delete()
|
db.session.delete(p)
|
||||||
|
# 删除关联的元素(改为对象级删除以触发审计事件)
|
||||||
|
old_elements = SysElement.query.filter_by(menu_code=menu.code).all()
|
||||||
|
for e in old_elements:
|
||||||
|
db.session.delete(e)
|
||||||
# 删除菜单
|
# 删除菜单
|
||||||
db.session.delete(menu)
|
db.session.delete(menu)
|
||||||
print(f"🗑️ 已清理旧版库存盘点菜单: {menu.code} ({menu.name})")
|
print(f"🗑️ 已清理旧版库存盘点菜单: {menu.code} ({menu.name})")
|
||||||
@ -456,8 +462,10 @@ class PermissionService:
|
|||||||
).all()
|
).all()
|
||||||
for menu in orphaned_menus:
|
for menu in orphaned_menus:
|
||||||
print(f"🗑️ 清理根级别冗余菜单: {menu.code} ({menu.name})")
|
print(f"🗑️ 清理根级别冗余菜单: {menu.code} ({menu.name})")
|
||||||
# 删除关联的权限
|
# 删除关联的权限(改为对象级删除以触发审计事件)
|
||||||
SysRolePermission.query.filter_by(target_code=menu.code).delete()
|
old_perms = SysRolePermission.query.filter_by(target_code=menu.code).all()
|
||||||
|
for p in old_perms:
|
||||||
|
db.session.delete(p)
|
||||||
db.session.delete(menu)
|
db.session.delete(menu)
|
||||||
|
|
||||||
# 第二步:清理重复菜单(同一个 code 存在多条记录,保留 ID 最小的)
|
# 第二步:清理重复菜单(同一个 code 存在多条记录,保留 ID 最小的)
|
||||||
@ -473,13 +481,20 @@ class PermissionService:
|
|||||||
# 保留第一条,删除其他
|
# 保留第一条,删除其他
|
||||||
for dup in duplicates[1:]:
|
for dup in duplicates[1:]:
|
||||||
print(f"🗑️ 清理重复菜单: {dup.code} (id={dup.id}, name={dup.name})")
|
print(f"🗑️ 清理重复菜单: {dup.code} (id={dup.id}, name={dup.name})")
|
||||||
SysRolePermission.query.filter_by(target_code=dup.code).delete()
|
# 改为对象级删除以触发审计事件
|
||||||
SysElement.query.filter_by(menu_code=dup.code).delete()
|
old_perms = SysRolePermission.query.filter_by(target_code=dup.code).all()
|
||||||
|
for p in old_perms:
|
||||||
|
db.session.delete(p)
|
||||||
|
old_elements = SysElement.query.filter_by(menu_code=dup.code).all()
|
||||||
|
for e in old_elements:
|
||||||
|
db.session.delete(e)
|
||||||
db.session.delete(dup)
|
db.session.delete(dup)
|
||||||
|
|
||||||
# 第三步:强制重新设置所有子菜单的 parent_id,确保没有遗漏
|
# 第三步:强制重新设置所有子菜单的 parent_id,确保没有遗漏
|
||||||
# 先将所有子菜单的 parent_id 设为 None,然后重新设置
|
# 改为对象级更新以触发审计事件
|
||||||
SysMenu.query.filter(SysMenu.code.in_(child_codes)).update({SysMenu.parent_id: None})
|
child_menus = SysMenu.query.filter(SysMenu.code.in_(child_codes)).all()
|
||||||
|
for m in child_menus:
|
||||||
|
m.parent_id = None
|
||||||
|
|
||||||
# 创建或更新菜单
|
# 创建或更新菜单
|
||||||
menu_map = {} # code -> menu obj
|
menu_map = {} # code -> menu obj
|
||||||
|
|||||||
Reference in New Issue
Block a user