Build lightweight AI agent admin
This commit is contained in:
@@ -0,0 +1,199 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
应用管理API
|
||||
"""
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.database import get_db
|
||||
from app.config import settings
|
||||
from app.base_schema import PaginatedResponse, ResponseModel
|
||||
from core.application.schema import (
|
||||
ApplicationCreate,
|
||||
ApplicationUpdate,
|
||||
ApplicationResponse,
|
||||
ApplicationListResponse,
|
||||
)
|
||||
from core.application.service import ApplicationService
|
||||
|
||||
router = APIRouter(prefix="/applications", tags=["应用管理"])
|
||||
|
||||
|
||||
@router.post("/", response_model=ApplicationResponse, summary="创建应用")
|
||||
async def create_application(
|
||||
data: ApplicationCreate,
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""
|
||||
创建新应用
|
||||
- **name**: 应用名称
|
||||
- **code**: 应用编码(唯一标识,用于URL路由,只能包含字母、数字、下划线和短横线)
|
||||
- **description**: 应用描述(可选)
|
||||
- **icon**: 应用图标(可选)
|
||||
- **app_type**: 应用类型(可选,默认mixed)
|
||||
"""
|
||||
# 检查编码唯一性
|
||||
if not await ApplicationService.check_unique(db, field="code", value=data.code):
|
||||
raise HTTPException(status_code=400, detail="应用编码已存在")
|
||||
|
||||
# 检查名称唯一性
|
||||
if not await ApplicationService.check_unique(db, field="name", value=data.name):
|
||||
raise HTTPException(status_code=400, detail="应用名称已存在")
|
||||
|
||||
return await ApplicationService.create(db=db, data=data)
|
||||
|
||||
|
||||
@router.get("/", response_model=PaginatedResponse[ApplicationListResponse], summary="获取应用列表")
|
||||
async def get_applications(
|
||||
page: int = Query(default=1, ge=1, description="页码"),
|
||||
page_size: int = Query(default=settings.PAGE_SIZE, ge=1, le=settings.PAGE_MAX_SIZE, alias="pageSize", description="每页数量"),
|
||||
keyword: str = Query(default=None, description="搜索关键词"),
|
||||
app_type: str = Query(default=None, alias="appType", description="应用类型"),
|
||||
status: str = Query(default=None, description="状态"),
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""
|
||||
获取应用列表(分页)
|
||||
支持按关键词、类型、状态筛选
|
||||
"""
|
||||
items, total = await ApplicationService.search(
|
||||
db,
|
||||
keyword=keyword,
|
||||
app_type=app_type,
|
||||
status=status,
|
||||
page=page,
|
||||
page_size=page_size
|
||||
)
|
||||
return PaginatedResponse(items=items, total=total)
|
||||
|
||||
|
||||
@router.get("/stats", response_model=ResponseModel, summary="获取应用统计")
|
||||
async def get_stats(db: AsyncSession = Depends(get_db)):
|
||||
"""
|
||||
获取应用统计信息
|
||||
"""
|
||||
stats = await ApplicationService.get_stats(db)
|
||||
return ResponseModel(message="获取成功", data=stats)
|
||||
|
||||
|
||||
@router.get("/check/unique", response_model=ResponseModel, summary="检查字段唯一性")
|
||||
async def check_unique(
|
||||
field: str = Query(..., description="字段名:code 或 name"),
|
||||
value: str = Query(..., description="字段值"),
|
||||
exclude_id: str = Query(default=None, alias="excludeId", description="排除的记录ID"),
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""
|
||||
检查字段值是否唯一
|
||||
"""
|
||||
allowed_fields = ["code", "name"]
|
||||
if field not in allowed_fields:
|
||||
raise HTTPException(status_code=400, detail=f"不支持检查字段: {field}")
|
||||
|
||||
is_unique = await ApplicationService.check_unique(db, field=field, value=value, exclude_id=exclude_id)
|
||||
return ResponseModel(
|
||||
message="可用" if is_unique else "已存在",
|
||||
data={"unique": is_unique}
|
||||
)
|
||||
|
||||
|
||||
@router.get("/code/{code}", response_model=ApplicationResponse, summary="根据编码获取应用")
|
||||
async def get_application_by_code(
|
||||
code: str,
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""
|
||||
根据应用编码获取应用详情
|
||||
"""
|
||||
db_obj = await ApplicationService.get_by_code(db, code=code)
|
||||
if db_obj is None:
|
||||
raise HTTPException(status_code=404, detail="应用不存在")
|
||||
return db_obj
|
||||
|
||||
|
||||
@router.get("/{record_id}", response_model=ApplicationResponse, summary="获取应用详情")
|
||||
async def get_application(
|
||||
record_id: str,
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""
|
||||
根据ID获取应用详情
|
||||
"""
|
||||
db_obj = await ApplicationService.get_by_id(db, record_id=record_id)
|
||||
if db_obj is None:
|
||||
raise HTTPException(status_code=404, detail="应用不存在")
|
||||
return db_obj
|
||||
|
||||
|
||||
@router.put("/{record_id}", response_model=ApplicationResponse, summary="更新应用")
|
||||
async def update_application(
|
||||
record_id: str,
|
||||
data: ApplicationUpdate,
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""
|
||||
更新应用信息
|
||||
"""
|
||||
# 检查编码唯一性(排除自身)
|
||||
if data.code and not await ApplicationService.check_unique(db, field="code", value=data.code, exclude_id=record_id):
|
||||
raise HTTPException(status_code=400, detail="应用编码已存在")
|
||||
|
||||
# 检查名称唯一性(排除自身)
|
||||
if data.name and not await ApplicationService.check_unique(db, field="name", value=data.name, exclude_id=record_id):
|
||||
raise HTTPException(status_code=400, detail="应用名称已存在")
|
||||
|
||||
db_obj = await ApplicationService.update(db, record_id=record_id, data=data)
|
||||
if db_obj is None:
|
||||
raise HTTPException(status_code=404, detail="应用不存在")
|
||||
|
||||
# 清除该应用相关的菜单缓存
|
||||
from core.menu.service import MenuService
|
||||
await MenuService.invalidate_app_menu_cache(db_obj.code)
|
||||
|
||||
return db_obj
|
||||
|
||||
|
||||
@router.post("/{record_id}/publish", response_model=ApplicationResponse, summary="发布应用")
|
||||
async def publish_application(
|
||||
record_id: str,
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""
|
||||
发布应用;已停用状态也可调用本接口重新启用(状态变为已发布)
|
||||
"""
|
||||
db_obj = await ApplicationService.publish(db, record_id=record_id)
|
||||
if db_obj is None:
|
||||
raise HTTPException(status_code=404, detail="应用不存在")
|
||||
return db_obj
|
||||
|
||||
|
||||
@router.post("/{record_id}/disable", response_model=ApplicationResponse, summary="停用应用")
|
||||
async def disable_application(
|
||||
record_id: str,
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""
|
||||
停用应用
|
||||
"""
|
||||
db_obj = await ApplicationService.disable(db, record_id=record_id)
|
||||
if db_obj is None:
|
||||
raise HTTPException(status_code=404, detail="应用不存在")
|
||||
return db_obj
|
||||
|
||||
|
||||
@router.delete("/{record_id}", response_model=ResponseModel, summary="删除应用")
|
||||
async def delete_application(
|
||||
record_id: str,
|
||||
hard: bool = Query(default=False, description="是否物理删除"),
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""
|
||||
删除应用
|
||||
- **hard=false**: 逻辑删除(默认)
|
||||
- **hard=true**: 物理删除
|
||||
"""
|
||||
success = await ApplicationService.delete(db, record_id=record_id, hard=hard)
|
||||
if not success:
|
||||
raise HTTPException(status_code=404, detail="应用不存在")
|
||||
return ResponseModel(message="删除成功")
|
||||
Reference in New Issue
Block a user