重构 AI

This commit is contained in:
2025-10-07 00:26:22 +08:00
parent 0c8e32aad4
commit c1d5119a0a
16 changed files with 966 additions and 322 deletions

View File

@@ -1,39 +1,60 @@
<template>
<n-grid :cols="isDesktop ? 5 : 1" :x-gap="20">
<n-gi :span="2">
<n-flex vertical size="large">
<n-flex align="center" justify="space-between">
<n-h3 style="margin: 0">请选择时间范围智能分析学习情况</n-h3>
<n-select
style="width: 140px"
:options="options"
v-model:value="aiStore.duration"
/>
<n-spin :show="aiStore.loading.fetching">
<n-grid :cols="isDesktop ? 5 : 1" :x-gap="20" :y-gap="20">
<n-gi :span="2">
<n-flex vertical size="large">
<n-flex align="center" justify="space-between">
<n-h3 style="margin: 0">请选择时间范围智能分析学习情况</n-h3>
<n-select
style="width: 140px"
:options="options"
v-model:value="aiStore.duration"
/>
</n-flex>
<Overview />
<n-grid :cols="2" :x-gap="20">
<n-gi :span="1">
<TagsChart />
</n-gi>
<n-gi :span="1">
<n-flex vertical :size="20">
<DifficultyChart />
<GradeChart />
</n-flex>
</n-gi>
</n-grid>
<SolvedTable />
</n-flex>
<Details :start="start" :end="end" />
</n-flex>
</n-gi>
<n-gi :span="3">
<n-flex vertical size="large">
<Heatmap />
<WeeklyChart :end="end" />
<AI v-if="aiStore.detailsData.solved.length" />
</n-flex>
</n-gi>
</n-grid>
</n-gi>
<n-gi :span="3">
<n-flex vertical size="large">
<Heatmap />
<ProgressChart />
<DurationChart />
<AI v-if="aiStore.detailsData.solved.length >= 10" />
</n-flex>
</n-gi>
<n-gi :span="5">
<AI v-if="aiStore.detailsData.solved.length > 0 && aiStore.detailsData.solved.length < 10" />
</n-gi>
</n-grid>
</n-spin>
</template>
<script setup lang="ts">
import { isDesktop } from "shared/composables/breakpoints"
import { formatISO, sub, type Duration } from "date-fns"
import WeeklyChart from "./components/WeeklyChart.vue"
import Details from "./components/Details.vue"
import TagsChart from "./components/TagsChart.vue"
import DifficultyChart from "./components/DifficultyChart.vue"
import GradeChart from "./components/GradeChart.vue"
import Overview from "./components/Overview.vue"
import Heatmap from "./components/Heatmap.vue"
import ProgressChart from "./components/ProgressChart.vue"
import DurationChart from "./components/DurationChart.vue"
import AI from "./components/AI.vue"
import SolvedTable from "./components/SolvedTable.vue"
import { useAIStore } from "../store/ai"
const aiStore = useAIStore()
const start = ref("")
const end = ref("")
const aiStore = useAIStore()
const options: SelectOption[] = [
{ label: "一节课内", value: "hours:1" },
@@ -54,11 +75,25 @@ const subOptions = computed<Duration>(() => {
return { [unit]: parseInt(n) } as Duration
})
function updateRange() {
const start = computed(() => {
const current = new Date()
end.value = formatISO(current)
start.value = formatISO(sub(current, subOptions.value))
}
return formatISO(sub(current, subOptions.value))
})
watch(() => aiStore.duration, updateRange, { immediate: true })
const end = computed(() => {
return formatISO(new Date())
})
// 获取热力图数据(仅一次)
onMounted(() => {
aiStore.fetchHeatmapData()
})
watch(
() => aiStore.duration,
() => {
aiStore.fetchAnalysisData(start.value, end.value, aiStore.duration)
},
{ immediate: true },
)
</script>