重构 AI
This commit is contained in:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user