# api/departments.py from typing import List from django.shortcuts import get_object_or_404 from ninja import Router from ninja.errors import HttpError from users.models import Department from users.permission import has_permission from users.schema import DepartmentOut, DepartmentCreate, DepartmentUpdate router = Router(tags=['depts']) @router.post("/", response=DepartmentOut, summary="创建部门") def create_department(request, payload: DepartmentCreate): if not has_permission(request.auth.id, "dept:create"): raise HttpError(403, "权限不足") data = payload.dict() parent_id = data.pop('parent_id', None) if parent_id: data['parent_id'] = parent_id dept = Department.objects.create(**data) return dept @router.get("/", response=List[DepartmentOut], summary="获取部门列表(扁平)") def list_departments(request): if not has_permission(request.auth.id, "dept:list"): raise HttpError(403, "权限不足") return Department.objects.all() @router.get("/tree/", response=List[dict], summary="获取部门树形结构") def get_department_tree(request): if not has_permission(request.auth.id, "dept:list"): raise HttpError(403, "权限不足") depts = Department.objects.all().order_by('order') return build_dept_tree(list(depts)) @router.get("/{dept_id}/", response=DepartmentOut, summary="获取部门详情") def get_department(request, dept_id: int): if not has_permission(request.auth.id, "dept:view"): raise HttpError(403, "权限不足") dept = get_object_or_404(Department, id=dept_id) return dept @router.put("/{dept_id}/", response=DepartmentOut, summary="更新部门") def update_department(request, dept_id: int, payload: DepartmentUpdate): if not has_permission(request.auth.id, "dept:update"): raise HttpError(403, "权限不足") dept = get_object_or_404(Department, id=dept_id) data = payload.dict() parent_id = data.pop('parent_id', None) if parent_id: data['parent_id'] = parent_id else: data['parent'] = None for attr, value in data.items(): setattr(dept, attr, value) dept.save() return dept @router.delete("/{dept_id}/", summary="删除部门") def delete_department(request, dept_id: int): if not has_permission(request.auth.id, "dept:delete"): raise HttpError(403, "权限不足") dept = get_object_or_404(Department, id=dept_id) # 可选:检查是否有子部门或用户 if dept.user_set.exists() or Department.objects.filter(parent=dept).exists(): return 400, {"detail": "部门包含用户或子部门,无法删除"} dept.delete() return {"success": True} # 工具函数:构建部门树 def build_dept_tree(depts, parent_id=None): tree = [] for dept in depts: if dept.parent_id == parent_id: node = { 'id': dept.id, 'name': dept.name, 'parent_id': dept.parent_id, 'order': dept.order, 'children': build_dept_tree(depts, dept.id) or None } tree.append(node) return tree