Skip to content

Commit 79c75d8

Browse files
committed
feat:Improve the study record table
1 parent 2338129 commit 79c75d8

File tree

6 files changed

+156
-106
lines changed

6 files changed

+156
-106
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<script setup lang="ts">
2+
import { getCurrentInstance, type App } from 'vue'
3+
import VxeUITable from 'vxe-table'
4+
import 'vxe-table/lib/style.css'
5+
import dayjs from 'dayjs'
6+
import { State } from 'ts-fsrs'
7+
8+
export interface FsrsRow {
9+
word: string
10+
last_review?: string | Date | null
11+
due?: string | Date | null
12+
state: number
13+
stability?: number
14+
difficulty?: number
15+
elapsed_days?: number
16+
scheduled_days?: number
17+
learning_steps?: number
18+
reps?: number
19+
lapses?: number
20+
[key: string]: unknown
21+
}
22+
23+
defineProps<{
24+
rows: FsrsRow[]
25+
}>()
26+
27+
// 标记挂在 app 上:模块级变量在 HMR/重载时会丢,但 app 不变,避免重复 use() 导致重复注册
28+
const FSRS_VXE_INSTALLED = '__fsrsVxeTableInstalled' as const
29+
30+
const instance = getCurrentInstance()
31+
if (instance) {
32+
const app = instance.appContext.app as App & { [FSRS_VXE_INSTALLED]?: boolean }
33+
if (!app[FSRS_VXE_INSTALLED]) {
34+
app.use(VxeUITable)
35+
app[FSRS_VXE_INSTALLED] = true
36+
}
37+
}
38+
39+
function formatDate(v: string | Date | null | undefined) {
40+
return v ? dayjs(v).format('YYYY-MM-DD HH:mm') : '-'
41+
}
42+
</script>
43+
44+
<template>
45+
<div class="flex-1 overflow-hidden h-full">
46+
<vxe-table
47+
round
48+
border
49+
show-overflow
50+
show-header-overflow
51+
show-footer-overflow
52+
height="auto"
53+
:data="rows"
54+
:row-config="{ keyField: 'word', isHover: true }"
55+
:virtual-y-config="{ enabled: true, gt: 100 }"
56+
:sort-config="{
57+
defaultSort: {
58+
field: 'due',
59+
order: 'desc',
60+
},
61+
}"
62+
>
63+
<vxe-column field="word" title="单词" min-width="120" fixed="left" sortable />
64+
<vxe-column field="last_review" title="最近复习日期" min-width="160" sortable>
65+
<template #default="{ row }">
66+
{{ formatDate(row.last_review as string | Date | null | undefined) }}
67+
</template>
68+
</vxe-column>
69+
<vxe-column field="due" title="下次复习日期" min-width="160" sortable>
70+
<template #default="{ row }">
71+
{{ formatDate(row.due as string | Date | null | undefined) }}
72+
</template>
73+
</vxe-column>
74+
<vxe-column field="state" title="状态" min-width="100">
75+
<template #default="{ row }">
76+
{{ State[row.state as number] }}
77+
</template>
78+
</vxe-column>
79+
<vxe-column field="stability" title="记忆稳定性" min-width="100" sortable />
80+
<vxe-column field="difficulty" title="难度" min-width="80" sortable />
81+
<!-- <vxe-column field="elapsed_days" title="经过天数" min-width="90" sortable/>-->
82+
<vxe-column field="scheduled_days" title="计划间隔" min-width="90" sortable />
83+
<!-- <vxe-column field="learning_steps" title="学习步骤" min-width="90" />-->
84+
<vxe-column field="reps" title="复习次数" min-width="90" sortable />
85+
<vxe-column field="lapses" title="遗忘次数" min-width="90" sortable />
86+
</vxe-table>
87+
</div>
88+
</template>
89+
90+
<style scoped lang="scss">
91+
</style>

apps/nuxt/app/pages/fsrs.vue

Lines changed: 11 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
<script setup lang="ts">
2-
import { useBaseStore } from '@typewords/core/stores/base'
2+
import { useBaseStore } from '@typewords/core/stores/base.ts'
33
import { BaseButton } from '@typewords/base'
44
import dayjs from 'dayjs'
5-
import { State } from 'ts-fsrs'
65
import isToday from 'dayjs/plugin/isToday' // ES 2015
7-
import utc from 'dayjs/plugin/utc' // ES 2015
6+
import utc from 'dayjs/plugin/utc'
7+
import Header from '@typewords/core/components/Header.vue'
8+
89
dayjs.extend(isToday)
910
dayjs.extend(utc)
1011
@@ -21,115 +22,21 @@ const fsrsList = computed(() => {
2122
word,
2223
...card,
2324
}))
25+
// .sort((a, b) => dayjs.utc(b.due).valueOf() - dayjs.utc(a.due).valueOf())
2426
})
25-
26-
const headers = [
27-
{ text: '单词', value: 'word' },
28-
{ text: '最近复习日期', value: 'last_review', sortable: true },
29-
{ text: '下次复习日期', value: 'due' },
30-
{ text: '状态', value: 'state' },
31-
{ text: '记忆稳定性', value: 'stability' },
32-
{ text: '难度', value: 'difficulty' },
33-
{ text: '经过天数', value: 'elapsed_days' },
34-
{ text: '计划间隔', value: 'scheduled_days' },
35-
{ text: '学习步骤', value: 'learning_steps' },
36-
{ text: '复习次数', value: 'reps' },
37-
{ text: '遗忘次数', value: 'lapses' },
38-
]
3927
</script>
4028

4129
<template>
42-
<div class="fsrs-page">
43-
<h2>学习记录</h2>
44-
<div class="flex gap-space items-center">
45-
<p>共 {{ fsrsList.length }} 条记录</p>
30+
<div class="p-4 box-border h-screen flex flex-col">
31+
<Header title="学习记录" />
32+
<div class="flex justify-end items-center mb-4">
33+
<span class="mr-4">共 {{ fsrsList.length }} 条记录</span>
4634
<BaseButton :type="type === 'today' ? 'primary' : 'info'" @click="type = 'today'">今日学习</BaseButton>
4735
<BaseButton :type="type === 'all' ? 'primary' : 'info'" @click="type = 'all'">所有记录</BaseButton>
4836
</div>
4937

50-
<div class="table-container">
51-
<table v-if="fsrsList.length > 0">
52-
<thead>
53-
<tr>
54-
<th>单词</th>
55-
<th>最近复习日期</th>
56-
<th>下次复习日期</th>
57-
<th>状态</th>
58-
<th>记忆稳定性</th>
59-
<th>难度</th>
60-
<th>经过天数</th>
61-
<th>计划间隔</th>
62-
<th>学习步骤</th>
63-
<th>复习次数</th>
64-
<th>遗忘次数</th>
65-
</tr>
66-
</thead>
67-
<tbody>
68-
<tr v-for="item in fsrsList" :key="item.word">
69-
<td>{{ item.word }}</td>
70-
<td>{{ item.last_review ? dayjs(item.last_review).format('YYYY-MM-DD HH:mm') : '-' }}</td>
71-
<td>{{ item.due ? dayjs(item.due).format('YYYY-MM-DD HH:mm') : '-' }}</td>
72-
<td>{{ State[item.state] }}</td>
73-
<td>{{ item.stability }}</td>
74-
<td>{{ item.difficulty }}</td>
75-
<td>{{ item.elapsed_days }}</td>
76-
<td>{{ item.scheduled_days }}</td>
77-
<td>{{ item.learning_steps }}</td>
78-
<td>{{ item.reps }}</td>
79-
<td>{{ item.lapses }}</td>
80-
</tr>
81-
</tbody>
82-
</table>
83-
<div v-else class="empty">暂无数据</div>
84-
</div>
38+
<FsrsRecordsTable v-if="fsrsList.length > 0" :rows="fsrsList" />
8539
</div>
8640
</template>
8741

88-
<style scoped lang="scss">
89-
.fsrs-page {
90-
padding: 20px;
91-
92-
h2 {
93-
margin-bottom: 10px;
94-
}
95-
96-
p {
97-
margin-bottom: 20px;
98-
color: #666;
99-
}
100-
}
101-
102-
.table-container {
103-
height: 80vh;
104-
overflow-x: auto;
105-
106-
table {
107-
width: 100%;
108-
border-collapse: collapse;
109-
110-
th,
111-
td {
112-
border: 1px solid #ddd;
113-
padding: 8px;
114-
text-align: left;
115-
white-space: nowrap;
116-
background-color: var(--color-second);
117-
}
118-
119-
th {
120-
background-color: var(--color-bg);
121-
font-weight: bold;
122-
}
123-
124-
td:hover {
125-
background-color: var(--color-third);
126-
}
127-
}
128-
}
129-
130-
.empty {
131-
text-align: center;
132-
padding: 40px;
133-
color: #999;
134-
}
135-
</style>
42+
<style scoped lang="scss"></style>

apps/nuxt/nuxt.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ export default defineNuxtConfig({
159159
},
160160
// 构建配置
161161
build: {
162-
transpile: ['vue-virtual-scroller'],
162+
transpile: ['vue-virtual-scroller', 'vxe-table'],
163163
},
164164
// 实验性功能
165165
experimental: {

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@
3737
"vue": "^3.5.25",
3838
"vue-i18n": "^11.2.8",
3939
"vue-router": "^4.6.3",
40-
"vue-virtual-scroller": "2.0.0-beta.8"
40+
"vue-virtual-scroller": "2.0.0-beta.8",
41+
"vxe-table": "^4.18.10"
4142
},
4243
"devDependencies": {
4344
"@alicloud/pop-core": "^1.8.0",

packages/core/src/stores/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export * from './base'
2+
export * from './user'
3+
export * from './runtime'
4+
export * from './setting'
5+
export * from './practice'

pnpm-lock.yaml

Lines changed: 46 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)