"""后台操作日志:xiugaijilu 按俱乐部过滤 + admin_audit_log 写入。""" import logging from jituan.constants import DATA_SCOPE_ALL from jituan.models import AdminAuditLog from jituan.services.club_context import resolve_club_id_from_request, resolve_club_scope from jituan.services.club_user import get_user_club_id logger = logging.getLogger(__name__) def club_id_for_yonghuid(yonghuid): from users.business_models import User user = User.query.filter(UserUID=str(yonghuid)).first() return get_user_club_id(user) def filter_admin_audit_by_request(qs, request): """集团 ALL 视图看全部;子公司按 club_id 过滤。""" if resolve_club_scope(request) == DATA_SCOPE_ALL: return qs return qs.filter(club_id=resolve_club_id_from_request(request)) def list_admin_audit_logs(request, page=1, page_size=20, **filters): """分页查询 admin_audit_log。""" qs = AdminAuditLog.query.all().order_by('-CreateTime') qs = filter_admin_audit_by_request(qs, request) operator = (filters.get('operator_yonghuid') or '').strip() target = (filters.get('target_yonghuid') or '').strip() action = (filters.get('action') or '').strip() keyword = (filters.get('keyword') or '').strip() if operator: qs = qs.filter(operator_yonghuid=operator) if target: qs = qs.filter(target_yonghuid=target) if action: qs = qs.filter(action=action) if keyword: qs = qs.filter(remark__icontains=keyword) page = max(1, int(page or 1)) page_size = min(100, max(1, int(page_size or 20))) total = qs.count() start = (page - 1) * page_size rows = qs[start:start + page_size] data_list = [] for r in rows: data_list.append({ 'id': r.id, 'club_id': r.club_id, 'operator_yonghuid': r.operator_yonghuid, 'operator_role_code': r.operator_role_code, 'target_yonghuid': r.target_yonghuid, 'action': r.action, 'resource_type': r.resource_type, 'resource_id': r.resource_id, 'field_name': r.field_name, 'value_before': r.value_before, 'value_after': r.value_after, 'remark': r.remark, 'request_ip': r.request_ip, 'CreateTime': r.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if r.CreateTime else '', }) return { 'list': data_list, 'total': total, 'page': page, 'page_size': page_size, } def filter_xiugaijilu_by_request(qs, request): """集团 ALL 视图看全部;子公司仅看本 club 用户相关记录。""" if resolve_club_scope(request) == DATA_SCOPE_ALL: return qs club_id = resolve_club_id_from_request(request) from users.business_models import User uids = User.query.filter(ClubID=club_id).values_list('UserUID', flat=True) uid_list = [str(u) for u in uids] if not uid_list: return qs.none() return qs.filter(yonghuid__in=uid_list) def resolve_operator_yonghuid(xiugaiid): """ xiugaijilu.xiugaiid 多为客服手机号;admin_audit_log.operator_yonghuid 存 UserUID。 解析失败时回落为原值(列宽已放宽至 16)。 """ s = str(xiugaiid or '').strip() if not s: return '' if len(s) <= 7: return s from users.business_models import User u = User.query.filter(Phone=s).first() if u and getattr(u, 'UserUID', None): return str(u.UserUID) u = User.query.filter(UserUID=s).first() if u and getattr(u, 'UserUID', None): return str(u.UserUID) return s[:16] def log_admin_audit_from_xiugai( *, yonghuid, xiugaiid, leixing, qitashuoming, club_id=None, request_ip='', ): """与 write_xiugai_log 同步写入 admin_audit_log(失败不影响主流程)。""" try: cid = club_id or club_id_for_yonghuid(yonghuid) operator_uid = resolve_operator_yonghuid(xiugaiid) AdminAuditLog.query.create( club_id=cid, operator_yonghuid=operator_uid, target_yonghuid=str(yonghuid), action='xiugaijilu', resource_type='user', resource_id=str(yonghuid), field_name=str(leixing), remark=(qitashuoming or '')[:500], request_ip=(request_ip or '')[:64], ) except Exception as e: logger.warning('写入 admin_audit_log 失败: %s', e)