Complete admin operations management

This commit is contained in:
2026-07-07 13:55:10 +08:00
parent da262f4596
commit 7be9847d65
10 changed files with 510 additions and 27 deletions

View File

@@ -8,7 +8,7 @@ from app.core.database import get_db
from app.core.dependencies import get_current_admin
from app.core.responses import api_success
from app.models.admin import Admin
from app.models.knowledge import Knowledge
from app.models.knowledge import Knowledge, UserKnowledgePermission
from app.schemas.admin import KnowledgeSaveRequest
from app.services.admin_service import OperationLogService
@@ -69,6 +69,11 @@ def delete_knowledge(
current_admin: Admin = Depends(get_current_admin),
) -> dict:
knowledge = _get_knowledge(db, knowledge_id)
permissions = db.scalars(
select(UserKnowledgePermission).where(UserKnowledgePermission.knowledge_id == knowledge.id)
).all()
for permission in permissions:
db.delete(permission)
db.delete(knowledge)
OperationLogService.write(db, admin_id=current_admin.id, module="knowledge", action="delete", target_id=knowledge.id)
db.commit()

View File

@@ -1,6 +1,8 @@
from __future__ import annotations
from fastapi import APIRouter, Depends, Query
from datetime import datetime
from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy import select
from sqlalchemy.orm import Session
@@ -8,8 +10,9 @@ from app.core.database import get_db
from app.core.dependencies import get_current_admin
from app.core.responses import api_success
from app.models.admin import Admin
from app.models.knowledge import Knowledge, UserKnowledgePermission
from app.models.user import User
from app.schemas.admin import AdminUserUpdateRequest
from app.schemas.admin import AdminUserKnowledgePermissionSaveRequest, AdminUserUpdateRequest
from app.services.admin_service import OperationLogService
router = APIRouter()
@@ -60,6 +63,72 @@ def update_user(
return api_success(_user_dict(user))
@router.get("/user/{user_id}/knowledge-permissions")
def user_knowledge_permissions(
user_id: int,
db: Session = Depends(get_db),
current_admin: Admin = Depends(get_current_admin),
) -> dict:
user = _get_user(db, user_id)
permissions = db.scalars(
select(UserKnowledgePermission)
.where(UserKnowledgePermission.user_id == user.id)
.order_by(UserKnowledgePermission.knowledge_id.asc())
).all()
return api_success(
{
"user": _user_dict(user),
"permissions": [_permission_dict(permission) for permission in permissions],
}
)
@router.put("/user/{user_id}/knowledge-permissions")
def save_user_knowledge_permissions(
user_id: int,
payload: AdminUserKnowledgePermissionSaveRequest,
db: Session = Depends(get_db),
current_admin: Admin = Depends(get_current_admin),
) -> dict:
user = _get_user(db, user_id)
normalized = {item.knowledgeId: item for item in payload.permissions}
if normalized:
existing_ids = set(db.scalars(select(Knowledge.id).where(Knowledge.id.in_(normalized.keys()))).all())
missing_ids = sorted(set(normalized.keys()) - existing_ids)
if missing_ids:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=f"知识库不存在: {','.join(str(item) for item in missing_ids)}",
)
old_permissions = db.scalars(
select(UserKnowledgePermission).where(UserKnowledgePermission.user_id == user.id)
).all()
for permission in old_permissions:
db.delete(permission)
db.flush()
for item in normalized.values():
db.add(
UserKnowledgePermission(
user_id=user.id,
knowledge_id=item.knowledgeId,
effective_at=_without_timezone(item.effectiveAt),
expired_at=_without_timezone(item.expiredAt),
created_by=current_admin.id,
)
)
OperationLogService.write(
db,
admin_id=current_admin.id,
module="user",
action="knowledge_permission",
target_id=user.id,
)
db.commit()
return user_knowledge_permissions(user.id, db, current_admin)
@router.delete("/user/{user_id}")
def delete_user(
user_id: int,
@@ -96,3 +165,17 @@ def _user_dict(user: User) -> dict:
"lastLoginAt": user.last_login_at,
"createdAt": user.created_at,
}
def _permission_dict(permission: UserKnowledgePermission) -> dict:
return {
"knowledgeId": permission.knowledge_id,
"effectiveAt": permission.effective_at,
"expiredAt": permission.expired_at,
}
def _without_timezone(value: datetime | None) -> datetime | None:
if value is None:
return None
return value.replace(tzinfo=None)

View File

@@ -39,6 +39,16 @@ class AdminUserUpdateRequest(BaseModel):
expiredAt: datetime | None = None
class AdminUserKnowledgePermissionItem(BaseModel):
knowledgeId: int = Field(gt=0)
effectiveAt: datetime | None = None
expiredAt: datetime | None = None
class AdminUserKnowledgePermissionSaveRequest(BaseModel):
permissions: list[AdminUserKnowledgePermissionItem] = Field(default_factory=list)
class KnowledgeSaveRequest(BaseModel):
name: str = Field(min_length=1, max_length=100)
feishuSpaceId: str = Field(min_length=1, max_length=100)