stream returns
Some checks failed
Deploy / deploy (push) Has been cancelled

This commit is contained in:
2025-09-24 18:28:42 +08:00
parent 0a9d49b526
commit 0b652aa301
6 changed files with 197 additions and 29 deletions

View File

@@ -1,5 +1,7 @@
import { DetailsData, WeeklyData } from "~/utils/types"
import { getAIAnalysis, getAIDetailData, getAIWeeklyData } from "../api"
import { consumeJSONEventStream } from "~/utils/stream"
import { getAIDetailData, getAIWeeklyData } from "../api"
import { getCSRFToken } from "~/utils/functions"
export const useAIStore = defineStore("ai", () => {
const duration = ref("months:6")
@@ -22,6 +24,8 @@ export const useAIStore = defineStore("ai", () => {
ai: false,
})
const mdContent = ref("")
const theFirstPerson = computed(() => {
return !!username.value ? username.value : "你"
})
@@ -55,13 +59,85 @@ export const useAIStore = defineStore("ai", () => {
loading.weekly = false
}
let aiController: AbortController | null = null
async function fetchAIAnalysis() {
if (aiController) {
aiController.abort()
}
const controller = new AbortController()
aiController = controller
loading.ai = true
const res = await getAIAnalysis(detailsData, weeklyData.value)
console.log(res.data)
loading.ai = false
mdContent.value = ""
const headers: Record<string, string> = {
"Content-Type": "application/json",
}
const csrfToken = getCSRFToken()
if (csrfToken) {
headers["X-CSRFToken"] = csrfToken
}
try {
const response = await fetch("/api/ai/analysis", {
method: "POST",
headers,
body: JSON.stringify({
details: detailsData,
weekly: weeklyData.value,
}),
signal: controller.signal,
})
if (!response.ok) {
throw new Error("AI 分析生成失败")
}
let hasStarted = false
await consumeJSONEventStream(response, {
signal: controller.signal,
onEvent(event) {
if (event === "end" && !hasStarted) {
loading.ai = false
}
},
onMessage(payload) {
const parsed = payload as {
type?: string
content?: string
message?: string
}
if (parsed.type === "delta" && parsed.content) {
if (!hasStarted) {
hasStarted = true
loading.ai = false
}
mdContent.value += parsed.content
} else if (parsed.type === "error") {
throw new Error(parsed.message || "AI 服务异常")
} else if (parsed.type === "done" && !hasStarted) {
loading.ai = false
}
},
})
} catch (error: any) {
if (controller.signal.aborted) {
return
}
console.error("生成 AI 分析失败", error)
const message = error?.message || "生成失败,请稍后再试"
mdContent.value = `生成失败:${message}`
} finally {
if (aiController === controller) {
aiController = null
loading.ai = false
}
}
}
return {
fetchWeeklyData,
fetchDetailsData,
@@ -72,5 +148,6 @@ export const useAIStore = defineStore("ai", () => {
username,
theFirstPerson,
loading,
mdContent,
}
})