""" 云文档快捷入口:持久化在 data/cloud_docs.json,支持增删改查。 """ import json import uuid from pathlib import Path from typing import Any, Dict, List from fastapi import APIRouter, HTTPException, status from pydantic import BaseModel, Field router = APIRouter(prefix="/settings/cloud-docs", tags=["cloud-docs"]) CONFIG_PATH = Path("data/cloud_docs.json") class CloudDocLinkCreate(BaseModel): name: str = Field(..., min_length=1, max_length=64, description="显示名称") url: str = Field(..., min_length=1, max_length=512, description="登录/入口 URL") class CloudDocLinkRead(BaseModel): id: str name: str url: str class CloudDocLinkUpdate(BaseModel): name: str | None = Field(None, min_length=1, max_length=64) url: str | None = Field(None, min_length=1, max_length=512) def _load_links() -> List[Dict[str, Any]]: if not CONFIG_PATH.exists(): return [] try: data = json.loads(CONFIG_PATH.read_text(encoding="utf-8")) return data if isinstance(data, list) else [] except Exception: return [] def _save_links(links: List[Dict[str, Any]]) -> None: CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True) CONFIG_PATH.write_text( json.dumps(links, ensure_ascii=False, indent=2), encoding="utf-8", ) @router.get("", response_model=List[CloudDocLinkRead]) async def list_cloud_docs(): """获取所有云文档快捷入口。""" links = _load_links() return [CloudDocLinkRead(**x) for x in links] @router.post("", response_model=CloudDocLinkRead, status_code=status.HTTP_201_CREATED) async def create_cloud_doc(payload: CloudDocLinkCreate): """新增一条云文档入口。""" links = _load_links() new_id = str(uuid.uuid4())[:8] new_item = {"id": new_id, "name": payload.name.strip(), "url": payload.url.strip()} links.append(new_item) _save_links(links) return CloudDocLinkRead(**new_item) @router.put("/{link_id}", response_model=CloudDocLinkRead) async def update_cloud_doc(link_id: str, payload: CloudDocLinkUpdate): """更新名称或 URL。""" links = _load_links() for item in links: if item.get("id") == link_id: if payload.name is not None: item["name"] = payload.name.strip() if payload.url is not None: item["url"] = payload.url.strip() _save_links(links) return CloudDocLinkRead(**item) raise HTTPException(status_code=404, detail="云文档入口不存在") @router.delete("/{link_id}", status_code=status.HTTP_204_NO_CONTENT) async def delete_cloud_doc(link_id: str): """删除一条云文档入口。""" links = _load_links() new_list = [x for x in links if x.get("id") != link_id] if len(new_list) == len(links): raise HTTPException(status_code=404, detail="云文档入口不存在") _save_links(new_list)