template_store.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. from __future__ import annotations
  2. import json
  3. from pathlib import Path
  4. from typing import Dict, List, Optional
  5. from fastapi import HTTPException
  6. from ..schemas import TemplateCreate, TemplateRecord, TemplateUpdate
  7. class TemplateStore:
  8. """Simple JSON-file based store for template definitions."""
  9. def __init__(self, data_path: Path):
  10. self.data_path = data_path
  11. self.data_path.parent.mkdir(parents=True, exist_ok=True)
  12. if not self.data_path.exists():
  13. self.data_path.write_text(json.dumps([], ensure_ascii=False, indent=2))
  14. self._cache: Dict[str, TemplateRecord] = {}
  15. self._load()
  16. def _load(self) -> None:
  17. raw = json.loads(self.data_path.read_text())
  18. self._cache = {item["id"]: TemplateRecord(**item) for item in raw}
  19. def _persist(self) -> None:
  20. # Use JSON mode so datetime fields are converted to ISO strings.
  21. serializable = [record.model_dump(mode="json") for record in self._cache.values()]
  22. self.data_path.write_text(
  23. json.dumps(serializable, ensure_ascii=False, indent=2)
  24. )
  25. def list_templates(self) -> List[TemplateRecord]:
  26. return list(self._cache.values())
  27. def get_template(self, template_id: str) -> TemplateRecord:
  28. try:
  29. return self._cache[template_id]
  30. except KeyError as exc:
  31. raise HTTPException(status_code=404, detail="模板不存在") from exc
  32. def create_template(self, payload: TemplateCreate) -> TemplateRecord:
  33. record = TemplateRecord(**payload.model_dump())
  34. self._cache[record.id] = record
  35. self._persist()
  36. return record
  37. def update_template(self, template_id: str, payload: TemplateUpdate) -> TemplateRecord:
  38. record = self.get_template(template_id)
  39. update_data = payload.model_dump(exclude_none=True)
  40. updated = record.model_copy(update=update_data)
  41. from datetime import datetime
  42. updated.updated_at = datetime.utcnow()
  43. self._cache[template_id] = updated
  44. self._persist()
  45. return updated
  46. def delete_template(self, template_id: str) -> None:
  47. if template_id not in self._cache:
  48. raise HTTPException(status_code=404, detail="模板不存在")
  49. del self._cache[template_id]
  50. self._persist()
  51. def list_categories(self) -> List[str]:
  52. categories = {record.category for record in self._cache.values()}
  53. return sorted(categories)
  54. def load_store(base_dir: Path) -> TemplateStore:
  55. data_path = base_dir / "data" / "templates.json"
  56. return TemplateStore(data_path)