aiCoursewareDraft.ts 1.6 KB

12345678910111213141516171819202122232425262728293031
  1. import Dexie from "dexie"
  2. import { getToken } from "@/libs/auth"
  3. import type { AiCoursewareOutline, AiCoursewarePreferences, AiCoursewareResourceBinding, AiCoursewarePage } from "@/api/aiCourseware"
  4. import type { Slide, SlideTheme } from "@/types/slides"
  5. export type ProtectedPageContent = Pick<AiCoursewarePage, "title" | "subtitle" | "bullets" | "studentContent" | "learningEvidence" | "interaction"> & { studentTask?: string }
  6. export interface AiDraftRecord {
  7. key: string
  8. updatedAt: number
  9. outline?: AiCoursewareOutline
  10. converted?: { title: string; theme: Partial<SlideTheme>; slides: Slide[] }
  11. preferences: AiCoursewarePreferences
  12. extraPrompt: string
  13. taskId?: string
  14. resources?: AiCoursewareResourceBinding[]
  15. protectedContent?: Array<[number, ProtectedPageContent]>
  16. backup?: { title: string; theme: SlideTheme; slides: Slide[]; width: number; ratio: number }
  17. }
  18. const database = new Dexie("AI_COURSEWARE_DRAFTS")
  19. database.version(1).stores({ drafts: "key,updatedAt" })
  20. const drafts = database.table<AiDraftRecord, string>("drafts")
  21. export async function draftKey(id: string, source: string): Promise<string> {
  22. const token = getToken()
  23. if (!token) throw new Error("登录状态不可用,无法保存个人草稿")
  24. const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(token))
  25. const owner = Array.from(new Uint8Array(digest), byte => byte.toString(16).padStart(2, "0")).join("")
  26. return `${owner}:${source}:${id}`
  27. }
  28. export const loadAiDraft = (key: string) => drafts.get(key)
  29. export const saveAiDraft = (record: AiDraftRecord) => drafts.put(JSON.parse(JSON.stringify(record)))