feat: 跨域访问从硬编码改为权限码crossDomain动态控制, 新增SQL迁移脚本

This commit is contained in:
yueli
2026-07-15 09:22:58 +08:00
parent d75c301556
commit 9cae1cc44c
2 changed files with 79 additions and 9 deletions

View File

@ -167,14 +167,33 @@ def permission_required(permission_code):
return decorator
return wrapper
def _has_cross_domain_permission(user_role, user_company=''):
"""
检查指定角色是否拥有「全局跨域访问」权限。
复用 AuthService.get_user_permissions 统一查询。
"""
if not user_role:
return False
try:
from app.services.auth_service import AuthService
perm_dict = AuthService.get_user_permissions(user_role, company_name=user_company)
all_perms = perm_dict.get('menus', []) + perm_dict.get('elements', [])
return 'crossDomain' in all_perms
except Exception:
return False
def get_current_company_filter():
"""
多租户数据权限隔离工具函数。
根据当前 JWT 中的 role 和 company_name 决定 SQL 查询应过滤到哪个公司。
权限逻辑(基于权限码 crossDomain支持动态分配:
- SUPER_ADMIN → None全量跨域
- 拥有 crossDomain 权限 → None全量跨域
- 普通用户 → 强制隔离到 JWT 中记录的公司
返回值:
None → 不限制公司(超级管理员全局视角,或显式传了 'ALL'
None → 不限制公司
str → 仅查询该公司数据
使用示例:
@ -194,17 +213,21 @@ def get_current_company_filter():
# 从请求参数获取前端指定的公司(兼容 company_name 和 company 两个参数名)
req_company = request.args.get('company_name', '') or request.args.get('company', '')
# 超级管理员 → 全局跨域
if user_role == 'SUPER_ADMIN':
# 超级管理员:允许通过参数指定公司过滤
if req_company and req_company.strip().upper() != 'ALL':
return req_company.strip()
# 未指定或指定了 ALL → 返回 None全量不限制
return None
else:
# 其他角色SUPERVISOR / FINANCE / WAREHOUSE_MGR 等):
# 强制隔离到 JWT 中记录的公司,无视前端参数
user_company = claims.get('company_name', '')
return user_company if user_company else None
# 动态权限码检查:拥有 crossDomain 权限 → 全局跨域
user_company = claims.get('company_name', '')
if user_role and _has_cross_domain_permission(user_role, user_company):
if req_company and req_company.strip().upper() != 'ALL':
return req_company.strip()
return None
# 普通用户 → 强制隔离到本公司
return user_company if user_company else None
def audit_log(module: str = None, action: str = None, get_target_id_fn=None, get_target_name_fn=None, get_details_fn=None):