Files
lexgo/learner/src/components/TermFormFields.vue
T
ila 3ebec5b11b feat: 词汇库搜索、筛选与编辑 (#12)
- GET /api/v1/terms 列表:查询键白名单、page/limit 边界(默认 20、上限 100)、
  排序 updated_at DESC;搜索同时匹配身份键、显示原文与个人释义,转小写后比较(term 为
  二进制排序规则),%/_/\ 按字面值转义;status 与 kind 可组合
- PATCH /api/v1/terms/:id 编辑:复用释义/例句与状态/等级校验,身份不可编辑;
  只有状态或等级变化才重排复习时间,历史作答记录与计数保留
- 学习端新增 /vocab 路由与导航、stores/vocabulary.ts、VocabView.vue(搜索、筛选、
  分页、空态与无结果清除、编辑对话框含 1~7 等级选择器、筛选与页码写入 URL)
- 释义/例句/状态/等级抽成 TermFormFields.vue,与阅读器面板共用,避免规则漂移
- Wiki 记录 Architecture、Business-Rules、Local-Development 与需求更新
2026-09-14 23:46:42 +08:00

35 lines
2.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import { computed } from 'vue'
import { ElInput, ElOption, ElRadio, ElRadioGroup, ElSelect } from 'element-plus'
import { TERM_STATUSES, type TermStatus } from '../composables/useReaderLookup'
// The reader panel and the vocabulary dialog edit the same fields, so they share this form
// instead of keeping two copies of the same rules.
const props = defineProps<{ disabled?: boolean; showLevel?: boolean; hint?: string }>()
const definition = defineModel<string>('definition', { required: true })
const examples = defineModel<string>('examples', { required: true })
const status = defineModel<TermStatus>('status', { required: true })
const level = defineModel<number>('level', { required: true })
const levelVisible = computed(() => props.showLevel === true && status.value === 'learning')
</script>
<template>
<div class="term-fields">
<p class="lookup-term-title">学习状态</p>
<ElRadioGroup v-model="status" :disabled="disabled" aria-label="学习状态">
<ElRadio v-for="item in TERM_STATUSES" :key="item.value" :value="item.value">{{ item.label }}</ElRadio>
</ElRadioGroup>
<p v-if="levelVisible" class="term-level">
<label for="term-level">学习等级</label>
<ElSelect id="term-level" v-model="level" :disabled="disabled" class="term-level-select" data-testid="term-level">
<ElOption v-for="value in 7" :key="value" :label="`${value} 级`" :value="value" />
</ElSelect>
</p>
<p v-else-if="status === 'learning'" class="subtle">学习中按 1~7 级记录,等级由复习推进。</p>
<label for="term-definition">我的释义 <span v-if="hint">{{ hint }}</span></label>
<ElInput id="term-definition" v-model="definition" type="textarea" :rows="3" :disabled="disabled" placeholder="记下当前词的释义" />
<label for="term-examples">例句 <span>每行一条,最多 5 条</span></label>
<ElInput id="term-examples" v-model="examples" type="textarea" :rows="2" :disabled="disabled" placeholder="可选,每行一条" />
</div>
</template>