fix(backend): resolve DetachedInstanceError in audit_log, add pessimistic locks for stock adjustments, and eliminate N+1 queries with eager loading

This commit is contained in:
DXC
2026-04-02 18:44:12 +08:00
parent edf09508f6
commit a52ced0375
3 changed files with 39 additions and 13 deletions

View File

@ -205,18 +205,18 @@ def audit_log(module: str, action: str = None, get_target_id_fn=None, get_target
username = claims.get('username', '')
display_name = claims.get('display_name', '')
# 兜底:如果 display_name 为空,查询数据库获取
# ★ 修复 DetachedInstanceError在 fn() 执行前预先获取用户完整信息
# 这样可以避免在 fn() 提交 session 后再访问 User 对象导致游离
if not display_name and user_id:
try:
from app.models.system import SysUser
user = SysUser.query.get(user_id)
if user:
user_info = user.to_dict()
display_name = user_info.get('display_name', username)
display_name = user.display_name or username
except Exception:
pass
# 获取IP
# 预先获取 IP(避免后续访问 request 对象异常)
ip_address = request.headers.get('X-Forwarded-For') or request.remote_addr or ''
if ip_address and ',' in ip_address:
ip_address = ip_address.split(',')[0].strip()
@ -235,7 +235,7 @@ def audit_log(module: str, action: str = None, get_target_id_fn=None, get_target
raw_payload = _get_payload()
filtered_payload = _filter_payload(raw_payload) if raw_payload else None
# 执行原函数
# 执行原函数(此时 Session 可能被提交或回滚)
response = fn(*args, **kwargs)
# 只记录成功的请求(响应状态码 200/201
@ -249,6 +249,9 @@ def audit_log(module: str, action: str = None, get_target_id_fn=None, get_target
from app.extensions import db
from flask import current_app
# ★ 已在上方预先获取 display_name此处无需再查询 User 对象
# 使用预先获取的字符串数据,避免 DetachedInstanceError
# 获取 target_id
target_id = None
if get_target_id_fn: