feat(auth): 账号类型统一为四种(运营方/载体方/OPC/服务方) + 关闭子角色 + 权限逻辑集中

- 新增 app/domain/account_types.py(唯一来源): account_type(role)→operator/carrier/opc/service,
  非运营非OPC一律→service(预留服务商/甲方企业); permission_role(类型)→权限角色码; label()
- _issue_token/_profile_for 统一走账号类型: 权限=permissions_for(permission_role(atype)),
  子角色置None(停用); 资料暴露 account_type/account_type_label
- 端口角色(role)仅保留做内部路由守卫兼容, 对外鉴权用四种账号类型
This commit is contained in:
Pine
2026-08-26 13:03:44 +08:00
parent cabc49eda9
commit af6f01c5a9
2 changed files with 63 additions and 8 deletions
+13 -8
View File
@@ -39,6 +39,7 @@ from ..schemas.auth import (
)
from ...infrastructure.repositories import Database
from ...services import sms, wechat
from ...domain.account_types import account_type, permission_role, label as account_type_label
router = APIRouter(prefix="/auth", tags=["auth"])
@@ -144,17 +145,19 @@ async def _issue_token(
否则回退到 ``users.role``(单角色/中性令牌)。
"""
role = (identity or user).get("role", "opc_member")
sub_role = (identity or user).get("sub_role")
# 账号类型(四种)统一解析;子角色已停用(置 None)
atype = account_type(role)
sub_role = None
org_id = (identity or user).get("org_id")
region_id = (identity or user).get("region_id")
identity_id = identity.get("id") if identity else None
perms = await db.roles.permissions_for(role, sub_role)
perms = await db.roles.permissions_for(permission_role(atype), None)
scope_ids = await db.regions.visible_region_ids(region_id)
scope_level = await db.regions.level(region_id)
token_user = dict(user)
token_user.update(role=role, sub_role=sub_role, org_id=org_id, region_id=region_id)
token_user.update(account_type=atype, role=role, sub_role=None, org_id=org_id, region_id=region_id)
await db.users.mark_login(user["id"]) # 记录最近登录时间(每次签发令牌=一次活动)
return await db.tokens.create(
token_user,
@@ -173,7 +176,8 @@ async def _profile_for(
) -> dict:
"""按身份(或回退用户单角色)构建对外资料字典。"""
role = (identity or user).get("role", "opc_member")
sub_role = (identity or user).get("sub_role")
atype = account_type(role) # 四种账号类型(子角色已停用)
sub_role = None
org_id = (identity or user).get("org_id")
region_id = (identity or user).get("region_id")
profile = {f: user.get(f, "") for f in _PROFILE_FIELDS}
@@ -195,12 +199,13 @@ async def _profile_for(
profile["affiliation"] = user.get("affiliation", "independent")
profile["park_id"] = user.get("park_id", "")
profile["park_name"] = user.get("park_name", "")
profile["account_type"] = user.get("account_type", "opc_default")
profile["role"] = role
profile["sub_role"] = sub_role
profile["account_type"] = atype # 四种账号类型(operator/carrier/opc/service
profile["account_type_label"] = account_type_label(atype)
profile["role"] = role # 端口角色(兼容守卫)
profile["sub_role"] = None # 子角色已停用
profile["org_id"] = org_id
profile["region_id"] = region_id
profile["permissions"] = await db.roles.permissions_for(role, sub_role)
profile["permissions"] = await db.roles.permissions_for(permission_role(atype), None)
profile["scope_region_ids"] = await db.regions.visible_region_ids(region_id)
if identity:
profile["identity_id"] = identity["id"]