feat(auth): 账号类型收敛为四种 + 对外下发中文标签(文本)

- account_type(role)→operator/carrier/opc_member/service; 非运营非OPC一律service; sub_role置None
- 登录/me/资料统一返回 account_type + account_type_label(运营方/载体方/OPC/服务方); 前端直接渲染文本
- 权限按账号类型解析(service→provider基座), 逻辑集中在 app/domain/account_types.py
This commit is contained in:
Pine
2026-08-26 13:09:02 +08:00
parent af6f01c5a9
commit 00f43976b3
3 changed files with 19 additions and 7 deletions
+3
View File
@@ -84,6 +84,9 @@ class UserProfile(BaseModel):
# RBAC(登录/me 返回;update-profile 不重签时不返回权限明细)
role: str = "opc_member"
sub_role: str | None = None
# 账号类型(四种)与中文标签 —— 前端直接渲染文本,不做代码映射
account_type: str = "service"
account_type_label: str = "服务方"
org_id: str | None = None
region_id: str | None = None
permissions: list[str] = Field(default_factory=list)
+11 -6
View File
@@ -14,7 +14,7 @@
"""
from __future__ import annotations
ACCOUNT_TYPES = ("operator", "carrier", "opc", "service")
ACCOUNT_TYPES = ("operator", "carrier", "opc_member", "service")
def account_type(role: str | None) -> str:
@@ -25,17 +25,22 @@ def account_type(role: str | None) -> str:
if r in ("carrier", "park", "park_staff", "carrier_staff"):
return "carrier"
if r in ("opc_member", "opc", "opc_certified", "opc_independent"):
return "opc"
# provider / enterprise / government / investor / ... 全部归 服务方
return "opc_member"
# provider / enterprise / government / investor / developer / ... 全部归 服务方
return "service"
def permission_role(atype: str) -> str:
"""账号类型 → 用于查权限表( roles/<code> )的角色码。service 用 provider 基座。"""
"""账号类型 → 用于查权限表( roles/<code> )的角色码。
四种类型各自对应一个已种子的权限角色:
operator→operator, carrier→carrier, opc_member→opc_member,
service→provider(服务方基座权限, 后期扩 服务商/甲方企业 可在其上叠加)。
"""
return {
"operator": "operator",
"carrier": "carrier",
"opc": "opc_member",
"opc_member": "opc_member",
"service": "provider",
}.get(atype, "provider")
@@ -45,6 +50,6 @@ def label(atype: str) -> str:
return {
"operator": "运营方",
"carrier": "载体方",
"opc": "OPC",
"opc_member": "OPC",
"service": "服务方",
}.get(atype, "服务方")
+5 -1
View File
@@ -14,6 +14,7 @@ from sqlalchemy import delete, func, select, update
from sqlalchemy.ext.asyncio import AsyncSession
from .. import config
from ..domain.account_types import account_type as _acct_type, label as _acct_label
from .models import (
Agent,
AuditLog,
@@ -583,7 +584,10 @@ class UserRepository:
profile["status"] = user.get("opc_status", "")
profile["topics"] = _parse_topics(user.get("topics", ""))
profile["role"] = user.get("role", "opc_member")
profile["sub_role"] = user.get("sub_role")
profile["sub_role"] = None # 子角色已停用
atype = user.get("account_type") or _acct_type(user.get("role"))
profile["account_type"] = atype
profile["account_type_label"] = user.get("account_type_label") or _acct_label(atype)
profile["org_id"] = user.get("org_id")
profile["region_id"] = user.get("region_id")
profile["permissions"] = user.get("permissions", [])