This commit is contained in:
fengchuanhn@gmail.com
2026-05-22 16:25:21 +08:00
parent 6f67bf703b
commit a58b0e3bd6
4 changed files with 81 additions and 49 deletions

View File

@@ -1,7 +1,7 @@
from sqlalchemy import func, select
from sqlalchemy.ext.asyncio import AsyncSession
from app.core.roles import ROLE_ADMIN, ROLE_AGENT, ROLE_OEM
from app.core.roles import ROLE_AGENT
from app.core.security import hash_password
from app.models.user import User
from app.schemas.admin_user import AdminUserCreate, AdminUserUpdate
@@ -9,6 +9,9 @@ from app.schemas.admin_user import AdminUserCreate, AdminUserUpdate
DEFAULT_PAGE_SIZE = 20
MAX_PAGE_SIZE = 200
# OEM 创建用户时允许的角色:普通用户、代理
OEM_CREATABLE_ROLE_IDS = frozenset({0, ROLE_AGENT})
class AdminUserError(Exception):
def __init__(self, message: str) -> None:
@@ -66,23 +69,31 @@ async def list_users(
return list(result.all()), total
async def _validate_owner_ids(
async def _validate_agent_under_oem(
db: AsyncSession,
*,
oem_id: int | None,
oem_id: int,
agent_id: int | None,
) -> None:
if oem_id is not None:
oem = await db.get(User, oem_id)
if oem is None or oem.role_id != ROLE_OEM:
raise AdminUserError("所选 OEM 不存在")
if agent_id is not None:
agent = await db.get(User, agent_id)
if agent is None or agent.role_id != ROLE_AGENT:
raise AdminUserError("所选代理不存在")
if agent_id is None:
return
agent = await db.get(User, agent_id)
if agent is None or agent.role_id != ROLE_AGENT:
raise AdminUserError("所选代理不存在")
if agent.oem_id != oem_id:
raise AdminUserError("所选代理不属于当前 OEM")
async def create_user(db: AsyncSession, body: AdminUserCreate) -> User:
def _validate_creatable_role(role_id: int) -> None:
if role_id not in OEM_CREATABLE_ROLE_IDS:
raise AdminUserError("只能创建普通用户或代理")
async def create_user(db: AsyncSession, body: AdminUserCreate, oem: User) -> User:
_validate_creatable_role(body.role_id)
if body.vip_end_time is not None:
raise AdminUserError("创建用户时不能设置 VIP 到期时间")
existing = await db.scalar(select(User).where(User.username == body.username))
if existing is not None:
raise AdminUserError("用户名已存在")
@@ -92,16 +103,19 @@ async def create_user(db: AsyncSession, body: AdminUserCreate) -> User:
if phone_taken is not None:
raise AdminUserError("手机号已被使用")
await _validate_owner_ids(db, oem_id=body.oem_id, agent_id=body.agent_id)
agent_id = body.agent_id
if body.role_id == ROLE_AGENT:
agent_id = None
await _validate_agent_under_oem(db, oem_id=oem.id, agent_id=agent_id)
user = User(
username=body.username,
password_hash=hash_password(body.password),
phone=body.phone,
role_id=body.role_id,
oem_id=body.oem_id,
agent_id=body.agent_id,
vip_end_time=body.vip_end_time,
oem_id=oem.id,
agent_id=agent_id,
vip_end_time=None,
)
db.add(user)
await db.flush()
@@ -109,16 +123,24 @@ async def create_user(db: AsyncSession, body: AdminUserCreate) -> User:
return user
async def _get_user_under_oem(db: AsyncSession, user_id: int, oem: User) -> User:
user = await db.get(User, user_id)
if user is None:
raise AdminUserError("用户不存在")
if user.oem_id != oem.id:
raise AdminUserError("无权限操作该用户")
return user
async def update_user(
db: AsyncSession,
oem: User,
user_id: int,
body: AdminUserUpdate,
*,
actor_id: int,
) -> User:
user = await db.get(User, user_id)
if user is None:
raise AdminUserError("用户不存在")
user = await _get_user_under_oem(db, user_id, oem)
if body.username is not None and body.username != user.username:
taken = await db.scalar(select(User).where(User.username == body.username))
@@ -134,40 +156,34 @@ async def update_user(
user.phone = body.phone
if body.role_id is not None:
if user_id == actor_id and body.role_id != ROLE_ADMIN:
raise AdminUserError("不能修改自己的管理员角色")
if user_id == actor_id:
raise AdminUserError("不能修改自己的角色")
_validate_creatable_role(body.role_id)
user.role_id = body.role_id
if body.oem_id is not None or body.agent_id is not None:
await _validate_owner_ids(
db,
oem_id=body.oem_id if body.oem_id is not None else user.oem_id,
agent_id=body.agent_id if body.agent_id is not None else user.agent_id,
)
if body.oem_id is not None:
user.oem_id = body.oem_id
if body.agent_id is not None:
user.agent_id = body.agent_id
new_agent_id = body.agent_id if body.agent_id is not None else user.agent_id
effective_role = body.role_id if body.role_id is not None else user.role_id
if effective_role == ROLE_AGENT:
new_agent_id = None
elif body.agent_id is not None:
await _validate_agent_under_oem(db, oem_id=oem.id, agent_id=new_agent_id)
if body.agent_id is not None or effective_role == ROLE_AGENT:
user.agent_id = new_agent_id
if body.password:
user.password_hash = hash_password(body.password)
if body.clear_vip_end_time:
user.vip_end_time = None
elif body.vip_end_time is not None:
user.vip_end_time = body.vip_end_time
if body.clear_vip_end_time or body.vip_end_time is not None:
raise AdminUserError("不能设置 VIP 到期时间")
await db.flush()
await db.refresh(user)
return user
async def delete_user(db: AsyncSession, user_id: int, *, actor_id: int) -> None:
async def delete_user(db: AsyncSession, oem: User, user_id: int, *, actor_id: int) -> None:
if user_id == actor_id:
raise AdminUserError("不能删除当前登录账号")
user = await db.get(User, user_id)
if user is None:
raise AdminUserError("用户不存在")
user = await _get_user_under_oem(db, user_id, oem)
await db.delete(user)