feat(avatar): complete authorization management
This commit is contained in:
@@ -1,41 +1,79 @@
|
||||
"""分身接管配置 API"""
|
||||
from fastapi import APIRouter, Depends, Body
|
||||
"""数字分身单聊接管配置 API。"""
|
||||
|
||||
from fastapi import APIRouter, Body, Depends, Header
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from database import get_db
|
||||
from models import Authorization
|
||||
from responses import ok, fail
|
||||
from responses import fail, ok
|
||||
from routers.authorizations import _require_authorization
|
||||
from routers.avatars import _require_owned_avatar
|
||||
|
||||
router = APIRouter(tags=["分身接管"])
|
||||
|
||||
|
||||
def _has(payload: dict, camel_key: str, snake_key: str) -> bool:
|
||||
return camel_key in payload or snake_key in payload
|
||||
|
||||
|
||||
def _read(payload: dict, camel_key: str, snake_key: str, default=None):
|
||||
if camel_key in payload:
|
||||
return payload[camel_key]
|
||||
if snake_key in payload:
|
||||
return payload[snake_key]
|
||||
return default
|
||||
|
||||
|
||||
@router.put("/avatar/{avatar_id}/authorizations/takeover")
|
||||
def update_takeover_config(
|
||||
avatar_id: str,
|
||||
payload: dict = Body(...),
|
||||
authorization: str = Header(None),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""更新分身接管配置"""
|
||||
auth_id = payload.get("authorizationId") or payload.get("authorization_id")
|
||||
_require_owned_avatar(db, avatar_id, authorization)
|
||||
auth_id = _read(payload, "authorizationId", "authorization_id")
|
||||
if not auth_id:
|
||||
return fail("缺少 authorization_id", 400)
|
||||
|
||||
auth = db.query(Authorization).filter(Authorization.id == auth_id).first()
|
||||
if not auth:
|
||||
return fail("授权不存在", 404)
|
||||
auth = _require_authorization(db, avatar_id, str(auth_id))
|
||||
enabled = bool(auth.takeover_enabled)
|
||||
mode = auth.takeover_mode or "immediate"
|
||||
delay = auth.takeover_delay_seconds or 30
|
||||
|
||||
if "takeover_enabled" in payload:
|
||||
auth.takeover_enabled = payload["takeover_enabled"]
|
||||
if "takeover_mode" in payload:
|
||||
mode = payload["takeover_mode"]
|
||||
if _has(payload, "takeoverEnabled", "takeover_enabled"):
|
||||
raw_enabled = _read(payload, "takeoverEnabled", "takeover_enabled")
|
||||
if not isinstance(raw_enabled, bool):
|
||||
return fail("takeover_enabled 必须是布尔值", 400)
|
||||
enabled = raw_enabled
|
||||
|
||||
if _has(payload, "takeoverMode", "takeover_mode"):
|
||||
mode = _read(payload, "takeoverMode", "takeover_mode")
|
||||
if mode not in ("immediate", "delayed"):
|
||||
return fail("takeover_mode 必须是 immediate 或 delayed", 400)
|
||||
auth.takeover_mode = mode
|
||||
if "takeover_delay_seconds" in payload:
|
||||
delay = payload["takeover_delay_seconds"]
|
||||
if not isinstance(delay, int) or delay < 5:
|
||||
return fail("takeover_delay_seconds 必须 >= 5", 400)
|
||||
auth.takeover_delay_seconds = delay
|
||||
|
||||
if _has(payload, "takeoverDelaySeconds", "takeover_delay_seconds"):
|
||||
delay = _read(payload, "takeoverDelaySeconds", "takeover_delay_seconds")
|
||||
if isinstance(delay, bool) or not isinstance(delay, int) or not 5 <= delay <= 3600:
|
||||
return fail("延迟时间需在 5 到 3600 秒之间", 400)
|
||||
|
||||
if enabled and auth.target_type != "user":
|
||||
return fail("本期仅支持对会会用户开启单聊接管", 400)
|
||||
if enabled and auth.status != "active":
|
||||
return fail("请先启用该授权,再开启聊天接管", 400)
|
||||
|
||||
permissions = list(auth.permissions or [])
|
||||
if enabled:
|
||||
if "chat" not in permissions and "reply" not in permissions:
|
||||
permissions.append("chat")
|
||||
if "takeover" not in permissions:
|
||||
permissions.append("takeover")
|
||||
else:
|
||||
permissions = [permission for permission in permissions if permission != "takeover"]
|
||||
|
||||
auth.permissions = permissions
|
||||
auth.takeover_enabled = enabled
|
||||
auth.takeover_mode = mode
|
||||
auth.takeover_delay_seconds = delay
|
||||
db.commit()
|
||||
return ok(auth.to_dict())
|
||||
db.refresh(auth)
|
||||
return ok(auth.to_dict(), "接管配置已保存")
|
||||
|
||||
Reference in New Issue
Block a user