92 lines
2.9 KiB
Python
92 lines
2.9 KiB
Python
"""
|
||
云文档快捷入口:持久化在 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)
|