fix: capture and persist target object names for delete, outbound, and borrow operations in audit logs

This commit is contained in:
DXC
2026-03-20 15:47:13 +08:00
parent b08bbba718
commit 032479fe38
15 changed files with 54 additions and 21 deletions

View File

@ -227,8 +227,8 @@ def delete_user(user_id):
claims = get_jwt() claims = get_jwt()
operator_role = claims.get('role') operator_role = claims.get('role')
AuthService.delete_user(user_id, operator_role) username = AuthService.delete_user(user_id, operator_role)
return jsonify({'msg': '删除成功'}), 200 return jsonify({'msg': '删除成功', 'username': username}), 200
except Exception as e: except Exception as e:
current_app.logger.error(f"Delete User Failed: {str(e)}") current_app.logger.error(f"Delete User Failed: {str(e)}")
return jsonify({'msg': str(e)}), 400 return jsonify({'msg': str(e)}), 400

View File

@ -222,7 +222,8 @@ def delete_bom(bom_no):
db.session.commit() db.session.commit()
return jsonify({ return jsonify({
'code': 200, 'code': 200,
'msg': '删除成功' 'msg': '删除成功',
'bom_no': bom_no
}) })
except Exception as e: except Exception as e:
current_app.logger.error(f'删除BOM失败: {str(e)}') current_app.logger.error(f'删除BOM失败: {str(e)}')

View File

@ -330,8 +330,8 @@ def update(id):
) )
def delete(id): def delete(id):
try: try:
MaterialBaseService.delete_material(id) material_name = MaterialBaseService.delete_material(id)
return jsonify({"code": 200, "msg": "删除成功"}) return jsonify({"code": 200, "msg": "删除成功", "material_name": material_name})
except Exception as e: except Exception as e:
traceback.print_exc() traceback.print_exc()
return jsonify({"code": 500, "msg": str(e)}), 500 return jsonify({"code": 500, "msg": str(e)}), 500

View File

@ -307,8 +307,8 @@ def update_buy(id):
) )
def delete_buy(id): def delete_buy(id):
try: try:
BuyInboundService.delete_inbound(id) material_name = BuyInboundService.delete_inbound(id)
return jsonify({"code": 200, "msg": "删除成功"}) return jsonify({"code": 200, "msg": "删除成功", "material_name": material_name})
except Exception as e: except Exception as e:
return jsonify({"code": 500, "msg": str(e)}), 500 return jsonify({"code": 500, "msg": str(e)}), 500

View File

@ -183,8 +183,8 @@ def update(id):
) )
def delete(id): def delete(id):
try: try:
ProductInboundService.delete_inbound(id) material_name = ProductInboundService.delete_inbound(id)
return jsonify({"code": 200, "msg": "删除成功"}) return jsonify({"code": 200, "msg": "删除成功", "material_name": material_name})
except Exception as e: except Exception as e:
traceback.print_exc() traceback.print_exc()
return jsonify({"code": 500, "msg": str(e)}), 500 return jsonify({"code": 500, "msg": str(e)}), 500

View File

@ -178,8 +178,8 @@ def update_semi(id):
) )
def delete_semi(id): def delete_semi(id):
try: try:
SemiInboundService.delete_inbound(id) material_name = SemiInboundService.delete_inbound(id)
return jsonify({"code": 200, "msg": "删除成功"}) return jsonify({"code": 200, "msg": "删除成功", "material_name": material_name})
except Exception as e: except Exception as e:
traceback.print_exc() traceback.print_exc()
return jsonify({"code": 500, "msg": str(e)}), 500 return jsonify({"code": 500, "msg": str(e)}), 500

View File

@ -266,10 +266,11 @@ def update_service(service_id):
def delete_service(service_id): def delete_service(service_id):
"""删除服务权益""" """删除服务权益"""
try: try:
ServiceService.delete_service(service_id) service_name = ServiceService.delete_service(service_id)
return jsonify({ return jsonify({
'code': 200, 'code': 200,
'msg': '删除成功' 'msg': '删除成功',
'service_name': service_name
}) })
except ValueError as e: except ValueError as e:
return jsonify({'code': 404, 'msg': str(e)}), 404 return jsonify({'code': 404, 'msg': str(e)}), 404

View File

@ -190,7 +190,7 @@ def delete_location(location_id):
return jsonify({ return jsonify({
'code': 200, 'code': 200,
'msg': '删除成功', 'msg': '删除成功',
'data': None 'location_code': location.location_code
}) })
except Exception as e: except Exception as e:
db.session.rollback() db.session.rollback()

View File

@ -317,9 +317,11 @@ class AuthService:
if not user: if not user:
raise Exception("用户不存在") raise Exception("用户不存在")
# 提前获取用户名用于审计日志
username = user.username
db.session.delete(user) db.session.delete(user)
db.session.commit() db.session.commit()
return True return username
@staticmethod @staticmethod
def get_user_permissions(role_code): def get_user_permissions(role_code):

View File

@ -568,6 +568,9 @@ class MaterialBaseService:
if not material: if not material:
raise ValueError("数据不存在") raise ValueError("数据不存在")
# 提前获取物料名称用于审计日志
material_name = material.name
buy_usage_count = StockBuy.query.filter_by(base_id=m_id).count() buy_usage_count = StockBuy.query.filter_by(base_id=m_id).count()
semi_usage_count = StockSemi.query.filter_by(base_id=m_id).count() semi_usage_count = StockSemi.query.filter_by(base_id=m_id).count()
prod_usage_count = StockProduct.query.filter_by(base_id=m_id).count() prod_usage_count = StockProduct.query.filter_by(base_id=m_id).count()
@ -585,7 +588,7 @@ class MaterialBaseService:
db.session.delete(material) db.session.delete(material)
db.session.commit() db.session.commit()
return True return material_name
except Exception as e: except Exception as e:
db.session.rollback() db.session.rollback()

View File

@ -280,9 +280,11 @@ class BuyInboundService:
try: try:
stock = StockBuy.query.get(stock_id) stock = StockBuy.query.get(stock_id)
if not stock: raise ValueError("记录不存在") if not stock: raise ValueError("记录不存在")
# 提前获取物料名称用于审计日志
material_name = stock.material_name
db.session.delete(stock) db.session.delete(stock)
db.session.commit() db.session.commit()
return True return material_name
except Exception as e: except Exception as e:
db.session.rollback() db.session.rollback()
raise e raise e

View File

@ -252,9 +252,12 @@ class ProductInboundService:
try: try:
stock = StockProduct.query.get(stock_id) stock = StockProduct.query.get(stock_id)
if stock: if stock:
# 提前获取物料名称用于审计日志
material_name = stock.material_name
db.session.delete(stock) db.session.delete(stock)
db.session.commit() db.session.commit()
return True return material_name
return None
except Exception as e: except Exception as e:
db.session.rollback() db.session.rollback()
raise e raise e

View File

@ -341,9 +341,11 @@ class SemiInboundService:
stock = StockSemi.query.get(stock_id) stock = StockSemi.query.get(stock_id)
if not stock: if not stock:
raise ValueError("记录不存在") raise ValueError("记录不存在")
# 提前获取物料名称用于审计日志
material_name = stock.material_name
db.session.delete(stock) db.session.delete(stock)
db.session.commit() db.session.commit()
return True return material_name
except Exception as e: except Exception as e:
db.session.rollback() db.session.rollback()
raise e raise e

View File

@ -144,10 +144,12 @@ class ServiceService:
def delete_service(cls, service_id): def delete_service(cls, service_id):
"""软删除""" """软删除"""
service = cls.get_service(service_id) service = cls.get_service(service_id)
# 提前获取服务名称用于审计日志
service_name = service.service_name
service.is_deleted = True service.is_deleted = True
service.updated_at = datetime.now() service.updated_at = datetime.now()
db.session.commit() db.session.commit()
return True return service_name
@classmethod @classmethod
def get_service_list(cls, page=1, per_page=20, keyword=None, def get_service_list(cls, page=1, per_page=20, keyword=None,

View File

@ -257,6 +257,23 @@ def audit_log(module: str, action: str = None, get_target_id_fn=None, get_target
target_name = get_target_name_fn() target_name = get_target_name_fn()
except Exception: except Exception:
pass pass
# 如果仍未获取到目标名称,尝试从响应 JSON 中常见字段获取
if not target_name and hasattr(response, 'json'):
resp_data = response.get_json()
if resp_data and isinstance(resp_data, dict):
# 优先从顶层获取
for field in ['order_no', 'outbound_no', 'borrow_no', 'adjustment_no', 'material_name']:
if field in resp_data:
target_name = resp_data[field]
break
# 再尝试从 data 字段获取(部分 API 返回格式)
if not target_name and 'data' in resp_data:
data = resp_data['data']
if isinstance(data, dict):
for field in ['order_no', 'outbound_no', 'borrow_no', 'adjustment_no', 'material_name']:
if field in data:
target_name = data[field]
break
# 获取 details # 获取 details
details = None details = None