from fastapi import APIRouter, Query
from fastapi.params import Depends
from tortoise.expressions import Q
from app.api.v1.utils import refresh_api_list, insert_log, generate_tags_recursive_list
from app.controllers import user_controller
from app.controllers.api import api_controller
from app.core.ctx import CTX_USER_ID
from app.models.system import Api, Role
from app.models.system import LogType, LogDetailType
from app.schemas.apis import ApiCreate, ApiUpdate, ApiSearch
from app.schemas.base import Success, SuccessExtra
导入了FastAPI、Tortoise ORM等必要的模块和自定义的工具函数、控制器、模型、模式等。
router = APIRouter()
创建了一个APIRouter实例,用于定义API路由。
查看API列表
@router.post("/apis/all/", summary="查看API列表")
async def _(obj_in: ApiSearch):
# 构建查询条件
q = Q()
if obj_in.api_path:
q &= Q(api_path__contains=obj_in.api_path)
if obj_in.summary:
q &= Q(summary=obj_in.summary)
if obj_in.tags:
for tag in obj_in.tags:
q &= Q(tags__contains=[tag])
if obj_in.status_type:
q &= Q(status_type=obj_in.status_type)
# 获取当前用户及其角色
user_id = CTX_USER_ID.get()
user_obj = await user_controller.get(id=user_id)
await user_obj.fetch_related("by_user_roles")
user_role_objs: list[Role] = await user_obj.by_user_roles
user_role_codes = [role_obj.role_code for role_obj in user_role_objs]
# 根据用户角色获取API列表
if "R_SUPER" in user_role_codes:
total, api_objs = await api_controller.list(page=obj_in.current, page_size=obj_in.size, search=q, order=["tags", "id"])
else:
api_objs: list[Api] = []
for role_obj in user_role_objs:
await role_obj.fetch_related("by_role_apis")
api_objs.extend([api_obj for api_obj in await role_obj.by_role_apis.filter(q)])
unique_apis = list(set(api_objs))
sorted_menus = sorted(unique_apis, key=lambda x: x.id)
# 实现分页
start = (obj_in.current - 1) * obj_in.size
end = start + obj_in.size
api_objs = sorted_menus[start:end]
total = len(sorted_menus)
# 转换API对象为字典并返回
records = []
for obj in api_objs:
data = await obj.to_dict(exclude_fields=["create_time", "update_time"])
records.append(data)
data = {"records": records}
await insert_log(log_type=LogType.UserLog, log_detail_type=LogDetailType.ApiGetList, by_user_id=user_obj.id)
return SuccessExtra(data=data, total=total, current=obj_in.current, size=obj_in.size)
接收一个ApiSearch
对象作为输入,用于指定查询条件。
根据输入条件构建查询条件q
。
获取当前用户及其角色,根据用户角色获取API列表。超级用户可以直接获取所有符合条件的API,普通用户只能获取其角色关联的API。
对API对象进行分页处理,并转换为字典格式返回。
记录用户操作日志。
查看单个API
@router.get("/apis/{api_id}", summary="查看API")
async def _(api_id: int):
api_obj = await api_controller.get(id=api_id)
data = await api_obj.to_dict(exclude_fields=["id", "create_time", "update_time"])
await insert_log(log_type=LogType.UserLog, log_detail_type=LogDetailType.ApiGetOne, by_user_id=0)
return Success(data=data)
根据API ID获取对应的API对象,并转换为字典格式返回。
记录用户操作日志。
构建API树
def build_api_tree(apis: list[Api]):
parent_map = {"root": {"id": "root", "children": []}}
# 遍历输入数据
for api in apis:
tags = api.tags
parent_id = "root"
for tag in tags:
node_id = f"parent${tag}"
# 如果当前节点不存在,则创建一个新的节点
if node_id not in parent_map:
node = {"id": node_id, "summary": tag, "children": []}
parent_map[node_id] = node
parent_map[parent_id]["children"].append(node)
parent_id = node_id
parent_map[parent_id]["children"].append({
"id": api.id,
"summary": api.summary,
})
return parent_map["root"]["children"]
@router.get("/apis/tree/", summary="查看API树")
async def _():
api_objs = await Api.all()
data = []
if api_objs:
data = build_api_tree(api_objs)
await insert_log(log_type=LogType.UserLog, log_detail_type=LogDetailType.ApiGetTree, by_user_id=0)
return Success(data=data)
build_api_tree
函数:根据API对象的标签构建树形结构。
获取所有API对象,并调用build_api_tree
函数构建树形结构返回。
记录用户操作日志。
创建API
@router.post("/apis", summary="创建API")
async def _(api_in: ApiCreate):
if isinstance(api_in.tags, str):
api_in.tags = api_in.tags.split("|")
new_api = await api_controller.create(obj_in=api_in)
await insert_log(log_type=LogType.UserLog, log_detail_type=LogDetailType.ApiCreateOne, by_user_id=0)
return Success(msg="Created Successfully", data={"created_id": new_api.id})
接收一个ApiCreate
对象作为输入,创建新的API对象。
如果标签是字符串格式,则将其分割为列表。
记录用户操作日志。
更新API
@router.patch("/apis/{api_id}", summary="更新API")
async def _(api_id: int, api_in: ApiUpdate):
if isinstance(api_in.tags, str):
api_in.tags = api_in.tags.split("|")
await api_controller.update(id=api_id, obj_in=api_in)
await insert_log(log_type=LogType.UserLog, log_detail_type=LogDetailType.ApiUpdateOne, by_user_id=0)
return Success(msg="Update Successfully", data={"updated_id": api_id})
根据API ID更新对应的API对象。
如果标签是字符串格式,则将其分割为列表。
记录用户操作日志。
删除API
@router.delete("/apis/{api_id}", summary="删除API")
async def _(api_id: int):
await api_controller.remove(id=api_id)
await insert_log(log_type=LogType.UserLog, log_detail_type=LogDetailType.ApiDeleteOne, by_user_id=0)
return Success(msg="Deleted Successfully", data={"deleted_id": api_id})
根据API ID删除对应的API对象。
记录用户操作日志。
批量删除API
@router.delete("/apis", summary="批量删除API")
async def _(ids: str = Query(..., description="API ID列表, 用逗号隔开")):
api_ids = ids.split(",")
deleted_ids = []
for api_id in api_ids:
api_obj = await Api.get(id=int(api_id))
await api_obj.delete()
deleted_ids.append(int(api_id))
await insert_log(log_type=LogType.UserLog, log_detail_type=LogDetailType.ApiBatchDelete, by_user_id=0)
return Success(msg="Deleted Successfully", data={"deleted_ids": deleted_ids})
接收一个包含API ID列表的字符串,批量删除对应的API对象。
记录用户操作日志。
刷新API列表
@router.post("/apis/refresh/", summary="刷新API列表")
async def _():
await refresh_api_list()
await insert_log(log_type=LogType.UserLog, log_detail_type=LogDetailType.ApiRefresh, by_user_id=0)
return Success()
调用refresh_api_list
函数刷新API列表。
记录用户操作日志。
查看API tags
@router.post("/apis/tags/all/", summary="查看API tags")
async def _():
data = await generate_tags_recursive_list()
# await insert_log(log_type=LogType.UserLog, log_detail_type=LogDetailType.ApiRefresh, by_user_id=0)
return Success(data=data)
调用generate_tags_recursive_list
函数生成递归的标签列表并返回。
注释掉了日志记录代码。
查看API列表:支持根据路径、摘要、标签、状态等条件筛选API,并根据用户角色返回相应的API列表。超级用户可以查看所有API,普通用户只能查看其角色关联的API。
查看单个API:根据API ID获取对应的API详细信息。
构建API树:根据API的标签构建树形结构,方便用户查看和管理API。
创建API:允许用户创建新的API,支持指定API的路径、摘要、标签、状态等信息。
更新API:支持对现有API的信息进行更新,如路径、摘要、标签、状态等。
删除API:可以删除单个API或批量删除多个API。
刷新API列表:提供刷新API列表的功能,可能用于更新缓存或重新加载API配置。
根据用户角色(超级用户或普通用户)控制用户可以访问的API列表。超级用户可以访问所有API,普通用户只能访问其角色关联的API。
每个API操作(查看列表、查看单个、创建、更新、删除、刷新等)都会记录相应的用户操作日志,方便后续审计和追踪。
使用Tortoise ORM进行数据查询和操作,支持复杂的查询条件和分页处理。
在返回API数据时,会排除一些字段(如创建时间和更新时间),以简化响应数据。
通过build_api_tree
函数根据API的标签构建树形结构,便于用户以层次化的方式查看和管理API。
这段代码实现了一个完整的API管理模块,支持对API的增删改查操作,并提供了API树形结构查看、批量操作、权限控制和日志记录等功能。代码结构清晰,功能完善,适合在需要对API进行集中管理和操作的场景中使用。