feat:fix dict list

This commit is contained in:
zyronon
2025-07-19 23:41:52 +08:00
parent 246f9f6dec
commit b10c861302
29 changed files with 1218 additions and 3603 deletions

View File

@@ -26,8 +26,8 @@ Netlify: <https://typing-words.netlify.app/>(需要翻墙)
### 背文章
内置经典教材书籍,可以练习和背诵文章,逐句输入,自动发音。也可以自行添加、导入文章,提供一键翻译、译文对照功能
### 生词本、错词本、简单词
默写单词时输入错误会自动添加到错词本,以便后续复习。也可以添加到简单词,之后再遇到这个词便会自动跳过,同时也可以将其添加到生词本中,以便巩固复习
### 生词本、错词本、已掌握
默写单词时输入错误会自动添加到错词本,以便后续复习。也可以添加到已掌握,之后再遇到这个词便会自动跳过,同时也可以将其添加到生词本中,以便巩固复习
### 默写模式
在用户完成一个章节的练习后,如果有错误词,那么会重复练习错误词,直到没有错误词为止。完成之后弹出选项可选择默写本章、重复本章、下一章
@@ -72,7 +72,7 @@ API 等词库。 尽可能满足大部分用户对背单词的需求,也非常
### 灵感来源
[qwerty-learner](https://github.com/RealKai42/qwerty-learner/) 很喜欢作者的这个项目,但是它没有背单词所必备的 **生词本、错词本、简单词** 的功能,可能是作者反复强调和提醒这个项目是“**为键盘工作者设计的单词记忆与英语肌肉记忆锻炼软件**”而不是一个“**背单词**”的软件吧,尽管绝大多数用户都是用它来背单词😂😂😂。
[qwerty-learner](https://github.com/RealKai42/qwerty-learner/) 很喜欢作者的这个项目,但是它没有背单词所必备的 **生词本、错词本、已掌握** 的功能,可能是作者反复强调和提醒这个项目是“**为键盘工作者设计的单词记忆与英语肌肉记忆锻炼软件**”而不是一个“**背单词**”的软件吧,尽管绝大多数用户都是用它来背单词😂😂😂。
本项目参考其思路使用 Vue 重写了,并添加了 **生词本、错词本、简单词****文章练习** 等功能
本项目参考其思路使用 Vue 重写了,并添加了 **生词本、错词本、已掌握****文章练习** 等功能

View File

@@ -43,6 +43,7 @@
--anim-time: 0.5s;
--color-input-bg: white;
--color-input-border: #bfbfbf;
--color-input-icon: #d3d4d7;
--color-textarea-bg: white;
@@ -148,7 +149,7 @@ html.dark {
}
.anim {
transition: background var(--anim-time), color var(--anim-time), border var(--anim-time);
transition: background var(--anim-time), color var(--anim-time), border var(--anim-time), opacity var(--anim-time);
}
.en-article-family {
@@ -475,7 +476,7 @@ footer {
}
.book {
@apply p-4 rounded-md bg-slate-200 relative cursor-pointer h-40 hover:bg-red anim;
@apply p-4 rounded-md bg-slate-200 relative cursor-pointer h-40 hover:bg-red anim flex flex-col justify-between;
}
.line {

View File

@@ -1,5 +1,857 @@
import {DictResource, DictType} from "@/types.ts"
import {newDicts} from "@/assets/newDicts.ts";
// 国际考试
const internationalExam: DictResource[] = [
{
id: 'BEC_2',
name: '商务英语词汇',
description: '商务英语词汇',
url: 'BEC_2.7z',
length: 2753,
category: '国际考试',
tags: ['所有', 'BEC'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'BEC_3',
name: '新东方 BEC 词汇',
description: '新东方 BEC 词汇',
url: 'BEC_3.7z',
length: 2825,
category: '国际考试',
tags: ['所有', 'BEC', '新东方'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'TOEFL_2',
name: 'TOEFL 词汇',
description: 'TOEFL 词汇',
url: 'TOEFL_2.json',
length: 9213,
category: '国际考试',
tags: ['所有', 'TOEFL'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'GRE_2',
name: 'GRE 词汇',
description: 'GRE 词汇',
url: 'GRE_2.json',
length: 7199,
category: '国际考试',
tags: ['所有', 'GRE'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'SAT_2',
name: 'SAT 词汇',
description: 'SAT 词汇',
url: 'SAT_2.json',
length: 4423,
category: '国际考试',
tags: ['所有', 'SAT'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'GMAT_2',
name: 'GMAT 词汇',
description: 'GMAT 词汇',
url: 'GMAT_2.json',
length: 3254,
category: '国际考试',
tags: ['所有', 'GMAT'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'IELTS_3',
name: '新东方雅思词汇',
description: '新东方雅思词汇',
url: 'IELTS_3.json',
length: 3575,
category: '国际考试',
tags: ['所有', 'IELTS', '新东方'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'TOEFL_3',
name: '新东方 TOEFL 词汇',
description: '新东方 TOEFL 词汇',
url: 'TOEFL_3.json',
length: 4264,
category: '国际考试',
tags: ['所有', 'TOEFL', '新东方'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'GRE_3',
name: '新东方 GRE 词汇',
description: '新东方 GRE 词汇',
url: 'GRE_3.json',
length: 6515,
category: '国际考试',
tags: ['所有', '新东方', 'GRE'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'SAT_3',
name: '新东方 SAT 词汇',
description: '新东方 SAT 词汇',
url: 'SAT_3.json',
length: 4464,
category: '国际考试',
tags: ['所有', '新东方', 'SAT'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'GMAT_3',
name: '新东方 GMAT 词汇',
description: '新东方 GMAT 词汇',
url: 'GMAT_3.json',
length: 3047,
category: '国际考试',
tags: ['所有', '新东方', 'GMAT'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'IELTS_2',
name: '雅思词汇',
description: '雅思词汇',
url: 'IELTS_2.json',
length: 3427,
category: '国际考试',
tags: ['所有', 'IELTS'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
]
// 中国考试
const chinaExam: DictResource[] = [
{
id: 'CET4_1',
name: '四级真题核心词',
description: '四级真题核心词',
url: 'CET4_1.json',
length: 1162,
category: '中国考试',
tags: ['所有', '大学英语', '四级',],
translateLanguage: 'common',
language: 'en',
type: DictType.word
},
{
id: 'CET6_1',
name: '六级真题核心词',
description: '六级真题核心词',
url: 'CET6_1.json',
length: 1228,
category: '中国考试',
tags: ['所有', '大学英语', '六级'],
translateLanguage: 'common',
language: 'en',
type: DictType.word
},
{
id: 'Level4_1',
name: '专四真题高频词',
description: '专四真题高频词',
url: 'Level4_1.json',
length: 595,
category: '中国考试',
tags: ['所有', '大学英语'],
translateLanguage: 'common',
language: 'en',
type: DictType.word
},
{
id: 'Level8_1',
name: '专八真题高频词',
description: '专八真题高频词',
url: 'Level8_1.json',
length: 684,
category: '中国考试',
tags: ['所有', '大学英语'],
translateLanguage: 'common',
language: 'en',
type: DictType.word
},
{
id: 'CET4_2',
name: '四级英语词汇',
description: '四级英语词汇',
url: 'CET4_2.json',
length: 3739,
category: '中国考试',
tags: ['所有', '大学英语', '四级'],
translateLanguage: 'common',
language: 'en',
type: DictType.word
},
{
id: 'CET6_2',
name: '六级英语词汇',
description: '六级英语词汇',
url: 'CET6_2.json',
length: 2078,
category: '中国考试',
tags: ['所有', '大学英语', '六级'],
translateLanguage: 'common',
language: 'en',
type: DictType.word
},
{
id: 'Level4_2',
name: '专四核心词汇',
description: '专四核心词汇',
url: 'Level4_2.json',
length: 4025,
category: '中国考试',
tags: ['所有', '大学英语'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'Level8_2',
name: '专八核心词汇',
description: '专八核心词汇',
url: 'Level8_2.json',
length: 12197,
category: '中国考试',
tags: ['所有', '大学英语'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'CET4_3',
name: '新东方四级词汇',
url: 'CET4_3.json',
length: 2607,
category: '中国考试',
tags: ['所有', '大学英语', '四级', '新东方'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
description: ''
},
{
id: 'CET6_3',
name: '新东方六级词汇',
description: '新东方六级词汇',
url: 'CET6_3.json',
length: 2345,
category: '中国考试',
tags: ['所有', '大学英语', '六级', '新东方'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'KaoYan_2',
name: '考研英语词汇',
description: '考研英语词汇',
url: 'KaoYan_2.json',
length: 4533,
category: '中国考试',
tags: ['所有', '考研'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'KaoYan_1',
name: '考研必考词汇',
description: '考研必考词汇',
url: 'KaoYan_1.json',
length: 1341,
category: '中国考试',
tags: ['所有', '考研'],
translateLanguage: 'common',
language: 'en',
type: DictType.word
},
{
id: 'KaoYan_3',
name: '新东方考研词汇',
description: '新东方考研词汇',
url: 'KaoYan_3.json',
length: 3728,
category: '中国考试',
tags: ['所有', '考研', '新东方'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
]
// 青少儿英语
const childrenEnglish: DictResource[] = [
{
id: 'ChuZhong_2',
name: '初中英语词汇',
description: '初中英语词汇',
url: 'ChuZhong_2.json',
length: 1420,
category: '青少年英语',
tags: ['所有', '通用', '初中'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'GaoZhong_2',
name: '高中英语词汇',
description: '高中英语词汇',
url: 'GaoZhong_2.json',
length: 3668,
category: '青少年英语',
tags: ['所有', '通用', '高中'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'ChuZhong_3',
name: '新东方初中词汇',
description: '新东方初中词汇',
url: 'ChuZhong_3.json',
length: 1803,
category: '青少年英语',
tags: ['所有', '通用', '初中'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'GaoZhong_3',
name: '新东方高中词汇',
description: '新东方高中词汇',
url: 'GaoZhong_3.json',
length: 2340,
category: '青少年英语',
tags: ['所有', '通用', '高中'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPXiaoXue3_1',
name: '人教版小学英语-三年级上册',
description: '人教版小学英语-三年级上册',
url: 'PEPXiaoXue3_1.json',
length: 64,
category: '青少年英语',
tags: ['所有', '小学', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPXiaoXue3_2',
name: '人教版小学英语-三年级下册',
description: '人教版小学英语-三年级下册',
url: 'PEPXiaoXue3_2.json',
length: 72,
category: '青少年英语',
tags: ['所有', '小学', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPXiaoXue4_1',
name: '人教版小学英语-四年级上册',
description: '人教版小学英语-四年级上册',
url: 'PEPXiaoXue4_1.json',
length: 84,
category: '青少年英语',
tags: ['所有', '小学', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPXiaoXue4_2',
name: '人教版小学英语-四年级下册',
description: '人教版小学英语-四年级下册',
url: 'PEPXiaoXue4_2.json',
length: 104,
category: '青少年英语',
tags: ['所有', '小学', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPXiaoXue5_1',
name: '人教版小学英语-五年级上册',
description: '人教版小学英语-五年级上册',
url: 'PEPXiaoXue5_1.json',
length: 131,
category: '青少年英语',
tags: ['所有', '小学', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPXiaoXue5_2',
name: '人教版小学英语-五年级下册',
description: '人教版小学英语-五年级下册',
url: 'PEPXiaoXue5_2.json',
length: 156,
category: '青少年英语',
tags: ['所有', '小学', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPXiaoXue6_1',
name: '人教版小学英语-六年级上册',
description: '人教版小学英语-六年级上册',
url: 'PEPXiaoXue6_1.json',
length: 130,
category: '青少年英语',
tags: ['所有', '小学', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPXiaoXue6_2',
name: '人教版小学英语-六年级下册',
description: '人教版小学英语-六年级下册',
url: 'PEPXiaoXue6_2.json',
length: 108,
category: '青少年英语',
tags: ['所有', '小学', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPChuZhong7_1',
name: '七年级上册',
description: '人教版初中英语-七年级上册',
url: 'PEPChuZhong7_1.json',
length: 392,
category: '青少年英语',
tags: ['所有', '初中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPChuZhong7_2',
name: '七年级下册',
description: '人教版初中英语-七年级下册',
url: 'PEPChuZhong7_2.json',
length: 492,
category: '青少年英语',
tags: ['所有', '初中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPChuZhong8_1',
name: '八年级上册',
description: '人教版初中英语-八年级上册',
url: 'PEPChuZhong8_1.json',
length: 419,
category: '青少年英语',
tags: ['所有', '初中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPChuZhong8_2',
name: '八年级下册',
description: '人教版初中英语-八年级下册',
url: 'PEPChuZhong8_2.json',
length: 466,
category: '青少年英语',
tags: ['所有', '初中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPChuZhong9_1',
name: '九年级全册',
description: '人教版初中英语-九年级全册',
url: 'PEPChuZhong9_1.json',
length: 551,
category: '青少年英语',
tags: ['所有', '初中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'WaiYanSheChuZhong_1',
name: '七年级上册',
description: '外研社版初中英语-七年级上册',
url: 'WaiYanSheChuZhong_1.json',
length: 629,
category: '青少年英语',
tags: ['所有', '初中', '外研社'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'WaiYanSheChuZhong_2',
name: '七年级下册',
description: '外研社版初中英语-七年级下册',
url: 'WaiYanSheChuZhong_2.json',
length: 438,
category: '青少年英语',
tags: ['所有', '初中', '外研社'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'WaiYanSheChuZhong_3',
name: '八年级上册',
description: '外研社版初中英语-八年级上册',
url: 'WaiYanSheChuZhong_3.json',
length: 320,
category: '青少年英语',
tags: ['所有', '初中', '外研社'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'WaiYanSheChuZhong_4',
name: '八年级下册',
description: '外研社版初中英语-八年级下册',
url: 'WaiYanSheChuZhong_4.json',
length: 266,
category: '青少年英语',
tags: ['所有', '初中', '外研社'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'WaiYanSheChuZhong_5',
name: '九年级上册',
description: '外研社版初中英语-九年级上册',
url: 'WaiYanSheChuZhong_5.json',
length: 381,
category: '青少年英语',
tags: ['所有', '初中', '外研社'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'WaiYanSheChuZhong_6',
name: '九年级下册',
description: '外研社版初中英语-九年级下册',
url: 'WaiYanSheChuZhong_6.json',
length: 128,
category: '青少年英语',
tags: ['所有', '初中', '外研社'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPGaoZhong_1',
name: '高中必修1',
description: '人教版高中英语-必修 1',
url: 'PEPGaoZhong_1.json',
length: 311,
category: '青少年英语',
tags: ['所有', '高中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPGaoZhong_2',
name: '高中必修2',
description: '人教版高中英语-必修 2',
url: 'PEPGaoZhong_2.json',
length: 319,
category: '青少年英语',
tags: ['所有', '高中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPGaoZhong_3',
name: '高中必修3',
description: '人教版高中英语-必修 3',
url: 'PEPGaoZhong_3.json',
length: 366,
category: '青少年英语',
tags: ['所有', '高中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPGaoZhong_4',
name: '高中必修4',
description: '人教版高中英语-必修 4',
url: 'PEPGaoZhong_4.json',
length: 307,
category: '青少年英语',
tags: ['所有', '高中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPGaoZhong_5',
name: '高中必修5',
description: '人教版高中英语-必修 5',
url: 'PEPGaoZhong_5.json',
length: 357,
category: '青少年英语',
tags: ['所有', '高中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPGaoZhong_6',
name: '高中必修6',
description: '人教版高中英语-必修 6',
url: 'PEPGaoZhong_6.json',
length: 391,
category: '青少年英语',
tags: ['所有', '高中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPGaoZhong_7',
name: '高中必修7',
description: '人教版高中英语-必修 7',
url: 'PEPGaoZhong_7.json',
length: 384,
category: '青少年英语',
tags: ['所有', '高中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPGaoZhong_8',
name: '高中必修8',
description: '人教版高中英语-必修 8',
url: 'PEPGaoZhong_8.json',
length: 420,
category: '青少年英语',
tags: ['所有', '高中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPGaoZhong_9',
name: '高中必修9',
description: '人教版高中英语-必修 9',
url: 'PEPGaoZhong_9.json',
length: 352,
category: '青少年英语',
tags: ['所有', '高中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPGaoZhong_10',
name: '高中必修10',
description: '人教版高中英语-必修 10',
url: 'PEPGaoZhong_10.json',
length: 361,
category: '青少年英语',
tags: ['所有', '高中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPGaoZhong_11',
name: '高中必修11',
description: '人教版高中英语-必修 11',
url: 'PEPGaoZhong_11.json',
length: 309,
category: '青少年英语',
tags: ['所有', '高中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'BeiShiGaoZhong_1',
name: '高中必修1',
description: '北师大版高中必修1',
url: 'BeiShiGaoZhong_1.json',
length: 226,
category: '青少年英语',
tags: ['所有', '高中', '北师大'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'BeiShiGaoZhong_2',
name: '高中必修2',
description: '北师大版高中必修2',
url: 'BeiShiGaoZhong_2.json',
length: 244,
category: '青少年英语',
tags: ['所有', '高中', '北师大'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'BeiShiGaoZhong_3',
name: '高中必修3',
description: '北师大版高中必修3',
url: 'BeiShiGaoZhong_3.json',
length: 295,
category: '青少年英语',
tags: ['所有', '高中', '北师大'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'BeiShiGaoZhong_4',
name: '高中必修4',
description: '北师大版高中必修4',
url: 'BeiShiGaoZhong_4.json',
length: 336,
category: '青少年英语',
tags: ['所有', '高中', '北师大'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'BeiShiGaoZhong_5',
name: '高中必修5',
description: '北师大版高中必修5',
url: 'BeiShiGaoZhong_5.json',
length: 327,
category: '青少年英语',
tags: ['所有', '高中', '北师大'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'BeiShiGaoZhong_6',
name: '高中必修6',
description: '北师大版高中必修6',
url: 'BeiShiGaoZhong_6.json',
length: 271,
category: '青少年英语',
tags: ['所有', '高中', '北师大'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'BeiShiGaoZhong_7',
name: '高中必修7',
description: '北师大版高中必修7',
url: 'BeiShiGaoZhong_7.json',
length: 334,
category: '青少年英语',
tags: ['所有', '高中', '北师大'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'BeiShiGaoZhong_8',
name: '高中必修8',
description: '北师大版高中必修8',
url: 'BeiShiGaoZhong_8.json',
length: 364,
category: '青少年英语',
tags: ['所有', '高中', '北师大'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'BeiShiGaoZhong_9',
name: '高中必修9',
description: '北师大版高中必修9',
url: 'BeiShiGaoZhong_9.json',
length: 299,
category: '青少年英语',
tags: ['所有', '高中', '北师大'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'BeiShiGaoZhong_10',
name: '高中必修10',
description: '北师大版高中必修10',
url: 'BeiShiGaoZhong_10.json',
length: 267,
category: '青少年英语',
tags: ['所有', '高中', '北师大'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'BeiShiGaoZhong_11',
name: '高中必修11',
description: '北师大版高中必修11',
url: 'BeiShiGaoZhong_11.json',
length: 330,
category: '青少年英语',
tags: ['所有', '高中', '北师大'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
]
// 英语文章
export const enArticle: DictResource[] = [
@@ -42,9 +894,7 @@ export const enArticle: DictResource[] = [
]
export const dictionaryResources: DictResource[] = [
// ...chinaExam,
// ...internationalExam,
// ...childrenEnglish,
...newDicts,
// ...enArticle,
...chinaExam,
...internationalExam,
...childrenEnglish,
]

File diff suppressed because it is too large Load Diff

View File

@@ -1,860 +0,0 @@
import {DictResource, DictType} from "@/types.ts";
// 国际考试
const internationalExam: DictResource[] = [
{
id: 'BEC_2',
name: '商务英语词汇',
description: '商务英语词汇',
url: 'BEC_2.7z',
length: 2753,
category: '国际考试',
tags: ['所有', 'BEC'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'BEC_3',
name: '新东方 BEC 词汇',
description: '新东方 BEC 词汇',
url: 'BEC_3.7z',
length: 2825,
category: '国际考试',
tags: ['所有', 'BEC', '新东方'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'TOEFL_2',
name: 'TOEFL 词汇',
description: 'TOEFL 词汇',
url: 'TOEFL_2.json',
length: 9213,
category: '国际考试',
tags: ['所有', 'TOEFL'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'GRE_2',
name: 'GRE 词汇',
description: 'GRE 词汇',
url: 'GRE_2.json',
length: 7199,
category: '国际考试',
tags: ['所有', 'GRE'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'SAT_2',
name: 'SAT 词汇',
description: 'SAT 词汇',
url: 'SAT_2.json',
length: 4423,
category: '国际考试',
tags: ['所有', 'SAT'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'GMAT_2',
name: 'GMAT 词汇',
description: 'GMAT 词汇',
url: 'GMAT_2.json',
length: 3254,
category: '国际考试',
tags: ['所有', 'GMAT'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'IELTS_3',
name: '新东方雅思词汇',
description: '新东方雅思词汇',
url: 'IELTS_3.json',
length: 3575,
category: '国际考试',
tags: ['所有', 'IELTS', '新东方'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'TOEFL_3',
name: '新东方 TOEFL 词汇',
description: '新东方 TOEFL 词汇',
url: 'TOEFL_3.json',
length: 4264,
category: '国际考试',
tags: ['所有', 'TOEFL', '新东方'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'GRE_3',
name: '新东方 GRE 词汇',
description: '新东方 GRE 词汇',
url: 'GRE_3.json',
length: 6515,
category: '国际考试',
tags: ['所有', '新东方', 'GRE'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'SAT_3',
name: '新东方 SAT 词汇',
description: '新东方 SAT 词汇',
url: 'SAT_3.json',
length: 4464,
category: '国际考试',
tags: ['所有', '新东方', 'SAT'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'GMAT_3',
name: '新东方 GMAT 词汇',
description: '新东方 GMAT 词汇',
url: 'GMAT_3.json',
length: 3047,
category: '国际考试',
tags: ['所有', '新东方', 'GMAT'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'IELTS_2',
name: '雅思词汇',
description: '雅思词汇',
url: 'IELTS_2.json',
length: 3427,
category: '国际考试',
tags: ['所有', 'IELTS'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
]
// 中国考试
const chinaExam: DictResource[] = [
{
id: 'CET4_1',
name: '四级真题核心词',
description: '四级真题核心词',
url: 'CET4_1.json',
length: 1162,
category: '中国考试',
tags: ['所有', '大学英语', '四级',],
translateLanguage: 'common',
language: 'en',
type: DictType.word
},
{
id: 'CET6_1',
name: '六级真题核心词',
description: '六级真题核心词',
url: 'CET6_1.json',
length: 1228,
category: '中国考试',
tags: ['所有', '大学英语', '六级'],
translateLanguage: 'common',
language: 'en',
type: DictType.word
},
{
id: 'Level4_1',
name: '专四真题高频词',
description: '专四真题高频词',
url: 'Level4_1.json',
length: 595,
category: '中国考试',
tags: ['所有', '大学英语'],
translateLanguage: 'common',
language: 'en',
type: DictType.word
},
{
id: 'Level8_1',
name: '专八真题高频词',
description: '专八真题高频词',
url: 'Level8_1.json',
length: 684,
category: '中国考试',
tags: ['所有', '大学英语'],
translateLanguage: 'common',
language: 'en',
type: DictType.word
},
{
id: 'CET4_2',
name: '四级英语词汇',
description: '四级英语词汇',
url: 'CET4_2.json',
length: 3739,
category: '中国考试',
tags: ['所有', '大学英语', '四级'],
translateLanguage: 'common',
language: 'en',
type: DictType.word
},
{
id: 'CET6_2',
name: '六级英语词汇',
description: '六级英语词汇',
url: 'CET6_2.json',
length: 2078,
category: '中国考试',
tags: ['所有', '大学英语', '六级'],
translateLanguage: 'common',
language: 'en',
type: DictType.word
},
{
id: 'Level4_2',
name: '专四核心词汇',
description: '专四核心词汇',
url: 'Level4_2.json',
length: 4025,
category: '中国考试',
tags: ['所有', '大学英语'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'Level8_2',
name: '专八核心词汇',
description: '专八核心词汇',
url: 'Level8_2.json',
length: 12197,
category: '中国考试',
tags: ['所有', '大学英语'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'CET4_3',
name: '新东方四级词汇',
url: 'CET4_3.json',
length: 2607,
category: '中国考试',
tags: ['所有', '大学英语', '四级', '新东方'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
description: ''
},
{
id: 'CET6_3',
name: '新东方六级词汇',
description: '新东方六级词汇',
url: 'CET6_3.json',
length: 2345,
category: '中国考试',
tags: ['所有', '大学英语', '六级', '新东方'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'KaoYan_2',
name: '考研英语词汇',
description: '考研英语词汇',
url: 'KaoYan_2.json',
length: 4533,
category: '中国考试',
tags: ['所有', '考研'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'KaoYan_1',
name: '考研必考词汇',
description: '考研必考词汇',
url: 'KaoYan_1.json',
length: 1341,
category: '中国考试',
tags: ['所有', '考研'],
translateLanguage: 'common',
language: 'en',
type: DictType.word
},
{
id: 'KaoYan_3',
name: '新东方考研词汇',
description: '新东方考研词汇',
url: 'KaoYan_3.json',
length: 3728,
category: '中国考试',
tags: ['所有', '考研', '新东方'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
]
// 青少儿英语
const childrenEnglish: DictResource[] = [
{
id: 'ChuZhong_2',
name: '初中英语词汇',
description: '初中英语词汇',
url: 'ChuZhong_2.json',
length: 1420,
category: '青少年英语',
tags: ['所有', '通用', '初中'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'GaoZhong_2',
name: '高中英语词汇',
description: '高中英语词汇',
url: 'GaoZhong_2.json',
length: 3668,
category: '青少年英语',
tags: ['所有', '通用', '高中'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'ChuZhong_3',
name: '新东方初中词汇',
description: '新东方初中词汇',
url: 'ChuZhong_3.json',
length: 1803,
category: '青少年英语',
tags: ['所有', '通用', '初中'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'GaoZhong_3',
name: '新东方高中词汇',
description: '新东方高中词汇',
url: 'GaoZhong_3.json',
length: 2340,
category: '青少年英语',
tags: ['所有', '通用', '高中'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPXiaoXue3_1',
name: '人教版小学英语-三年级上册',
description: '人教版小学英语-三年级上册',
url: 'PEPXiaoXue3_1.json',
length: 64,
category: '青少年英语',
tags: ['所有', '小学', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPXiaoXue3_2',
name: '人教版小学英语-三年级下册',
description: '人教版小学英语-三年级下册',
url: 'PEPXiaoXue3_2.json',
length: 72,
category: '青少年英语',
tags: ['所有', '小学', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPXiaoXue4_1',
name: '人教版小学英语-四年级上册',
description: '人教版小学英语-四年级上册',
url: 'PEPXiaoXue4_1.json',
length: 84,
category: '青少年英语',
tags: ['所有', '小学', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPXiaoXue4_2',
name: '人教版小学英语-四年级下册',
description: '人教版小学英语-四年级下册',
url: 'PEPXiaoXue4_2.json',
length: 104,
category: '青少年英语',
tags: ['所有', '小学', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPXiaoXue5_1',
name: '人教版小学英语-五年级上册',
description: '人教版小学英语-五年级上册',
url: 'PEPXiaoXue5_1.json',
length: 131,
category: '青少年英语',
tags: ['所有', '小学', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPXiaoXue5_2',
name: '人教版小学英语-五年级下册',
description: '人教版小学英语-五年级下册',
url: 'PEPXiaoXue5_2.json',
length: 156,
category: '青少年英语',
tags: ['所有', '小学', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPXiaoXue6_1',
name: '人教版小学英语-六年级上册',
description: '人教版小学英语-六年级上册',
url: 'PEPXiaoXue6_1.json',
length: 130,
category: '青少年英语',
tags: ['所有', '小学', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPXiaoXue6_2',
name: '人教版小学英语-六年级下册',
description: '人教版小学英语-六年级下册',
url: 'PEPXiaoXue6_2.json',
length: 108,
category: '青少年英语',
tags: ['所有', '小学', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPChuZhong7_1',
name: '七年级上册',
description: '人教版初中英语-七年级上册',
url: 'PEPChuZhong7_1.json',
length: 392,
category: '青少年英语',
tags: ['所有', '初中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPChuZhong7_2',
name: '七年级下册',
description: '人教版初中英语-七年级下册',
url: 'PEPChuZhong7_2.json',
length: 492,
category: '青少年英语',
tags: ['所有', '初中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPChuZhong8_1',
name: '八年级上册',
description: '人教版初中英语-八年级上册',
url: 'PEPChuZhong8_1.json',
length: 419,
category: '青少年英语',
tags: ['所有', '初中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPChuZhong8_2',
name: '八年级下册',
description: '人教版初中英语-八年级下册',
url: 'PEPChuZhong8_2.json',
length: 466,
category: '青少年英语',
tags: ['所有', '初中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPChuZhong9_1',
name: '九年级全册',
description: '人教版初中英语-九年级全册',
url: 'PEPChuZhong9_1.json',
length: 551,
category: '青少年英语',
tags: ['所有', '初中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'WaiYanSheChuZhong_1',
name: '七年级上册',
description: '外研社版初中英语-七年级上册',
url: 'WaiYanSheChuZhong_1.json',
length: 629,
category: '青少年英语',
tags: ['所有', '初中', '外研社'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'WaiYanSheChuZhong_2',
name: '七年级下册',
description: '外研社版初中英语-七年级下册',
url: 'WaiYanSheChuZhong_2.json',
length: 438,
category: '青少年英语',
tags: ['所有', '初中', '外研社'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'WaiYanSheChuZhong_3',
name: '八年级上册',
description: '外研社版初中英语-八年级上册',
url: 'WaiYanSheChuZhong_3.json',
length: 320,
category: '青少年英语',
tags: ['所有', '初中', '外研社'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'WaiYanSheChuZhong_4',
name: '八年级下册',
description: '外研社版初中英语-八年级下册',
url: 'WaiYanSheChuZhong_4.json',
length: 266,
category: '青少年英语',
tags: ['所有', '初中', '外研社'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'WaiYanSheChuZhong_5',
name: '九年级上册',
description: '外研社版初中英语-九年级上册',
url: 'WaiYanSheChuZhong_5.json',
length: 381,
category: '青少年英语',
tags: ['所有', '初中', '外研社'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'WaiYanSheChuZhong_6',
name: '九年级下册',
description: '外研社版初中英语-九年级下册',
url: 'WaiYanSheChuZhong_6.json',
length: 128,
category: '青少年英语',
tags: ['所有', '初中', '外研社'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPGaoZhong_1',
name: '高中必修1',
description: '人教版高中英语-必修 1',
url: 'PEPGaoZhong_1.json',
length: 311,
category: '青少年英语',
tags: ['所有', '高中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPGaoZhong_2',
name: '高中必修2',
description: '人教版高中英语-必修 2',
url: 'PEPGaoZhong_2.json',
length: 319,
category: '青少年英语',
tags: ['所有', '高中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPGaoZhong_3',
name: '高中必修3',
description: '人教版高中英语-必修 3',
url: 'PEPGaoZhong_3.json',
length: 366,
category: '青少年英语',
tags: ['所有', '高中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPGaoZhong_4',
name: '高中必修4',
description: '人教版高中英语-必修 4',
url: 'PEPGaoZhong_4.json',
length: 307,
category: '青少年英语',
tags: ['所有', '高中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPGaoZhong_5',
name: '高中必修5',
description: '人教版高中英语-必修 5',
url: 'PEPGaoZhong_5.json',
length: 357,
category: '青少年英语',
tags: ['所有', '高中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPGaoZhong_6',
name: '高中必修6',
description: '人教版高中英语-必修 6',
url: 'PEPGaoZhong_6.json',
length: 391,
category: '青少年英语',
tags: ['所有', '高中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPGaoZhong_7',
name: '高中必修7',
description: '人教版高中英语-必修 7',
url: 'PEPGaoZhong_7.json',
length: 384,
category: '青少年英语',
tags: ['所有', '高中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPGaoZhong_8',
name: '高中必修8',
description: '人教版高中英语-必修 8',
url: 'PEPGaoZhong_8.json',
length: 420,
category: '青少年英语',
tags: ['所有', '高中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPGaoZhong_9',
name: '高中必修9',
description: '人教版高中英语-必修 9',
url: 'PEPGaoZhong_9.json',
length: 352,
category: '青少年英语',
tags: ['所有', '高中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPGaoZhong_10',
name: '高中必修10',
description: '人教版高中英语-必修 10',
url: 'PEPGaoZhong_10.json',
length: 361,
category: '青少年英语',
tags: ['所有', '高中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'PEPGaoZhong_11',
name: '高中必修11',
description: '人教版高中英语-必修 11',
url: 'PEPGaoZhong_11.json',
length: 309,
category: '青少年英语',
tags: ['所有', '高中', '人教版'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'BeiShiGaoZhong_1',
name: '高中必修1',
description: '北师大版高中必修1',
url: 'BeiShiGaoZhong_1.json',
length: 226,
category: '青少年英语',
tags: ['所有', '高中', '北师大'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'BeiShiGaoZhong_2',
name: '高中必修2',
description: '北师大版高中必修2',
url: 'BeiShiGaoZhong_2.json',
length: 244,
category: '青少年英语',
tags: ['所有', '高中', '北师大'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'BeiShiGaoZhong_3',
name: '高中必修3',
description: '北师大版高中必修3',
url: 'BeiShiGaoZhong_3.json',
length: 295,
category: '青少年英语',
tags: ['所有', '高中', '北师大'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'BeiShiGaoZhong_4',
name: '高中必修4',
description: '北师大版高中必修4',
url: 'BeiShiGaoZhong_4.json',
length: 336,
category: '青少年英语',
tags: ['所有', '高中', '北师大'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'BeiShiGaoZhong_5',
name: '高中必修5',
description: '北师大版高中必修5',
url: 'BeiShiGaoZhong_5.json',
length: 327,
category: '青少年英语',
tags: ['所有', '高中', '北师大'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'BeiShiGaoZhong_6',
name: '高中必修6',
description: '北师大版高中必修6',
url: 'BeiShiGaoZhong_6.json',
length: 271,
category: '青少年英语',
tags: ['所有', '高中', '北师大'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'BeiShiGaoZhong_7',
name: '高中必修7',
description: '北师大版高中必修7',
url: 'BeiShiGaoZhong_7.json',
length: 334,
category: '青少年英语',
tags: ['所有', '高中', '北师大'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'BeiShiGaoZhong_8',
name: '高中必修8',
description: '北师大版高中必修8',
url: 'BeiShiGaoZhong_8.json',
length: 364,
category: '青少年英语',
tags: ['所有', '高中', '北师大'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'BeiShiGaoZhong_9',
name: '高中必修9',
description: '北师大版高中必修9',
url: 'BeiShiGaoZhong_9.json',
length: 299,
category: '青少年英语',
tags: ['所有', '高中', '北师大'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'BeiShiGaoZhong_10',
name: '高中必修10',
description: '北师大版高中必修10',
url: 'BeiShiGaoZhong_10.json',
length: 267,
category: '青少年英语',
tags: ['所有', '高中', '北师大'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
{
id: 'BeiShiGaoZhong_11',
name: '高中必修11',
description: '北师大版高中必修11',
url: 'BeiShiGaoZhong_11.json',
length: 330,
category: '青少年英语',
tags: ['所有', '高中', '北师大'],
translateLanguage: 'common',
language: 'en',
type: DictType.word,
},
]
export const newDicts = [
...chinaExam,
...internationalExam,
...childrenEnglish,
]

View File

@@ -65,7 +65,7 @@
},
"ToggleSimple": {
"en": "",
"zh": "标记/取消简单词",
"zh": "标记/取消已掌握",
"id": "",
"tw": "",
"th": "",
@@ -351,4 +351,4 @@
"de": "",
"fr": ""
}
}
}

View File

@@ -29,4 +29,8 @@ app.use(pinia)
app.use(i18n)
app.use(router)
app.mount('#app')
app.directive('opacity', (el, binding) => {
el.style.opacity = binding.value ? 1 : 0
})
app.mount('#app')

View File

@@ -79,7 +79,7 @@
<!-- <div class="tab" :class="index === 0 && 'active'" @click="index = 0">当前</div>-->
<!-- <div class="tab" :class="index === 1 && 'active'" @click="index = 1">收藏</div>-->
<!-- <div class="tab" :class="index === 2 && 'active'" @click="index = 2">错词本</div>-->
<!-- <div class="tab" :class="index === 3 && 'active'" @click="index = 3">简单词</div>-->
<!-- <div class="tab" :class="index === 3 && 'active'" @click="index = 3">已掌握</div>-->
<!-- </div>-->
<!-- <div class="indicator" :style="{left:index * 25 + '%'}"></div>-->
<!-- </div>-->
@@ -255,4 +255,4 @@
<!-- }-->
<!-- }-->
<!--}-->
<!--</style>-->
<!--</style>-->

View File

@@ -26,9 +26,9 @@ import {APP_NAME} from "../../../utils/const.ts";
</div>
</li>
<li>
<div class="title">生词本错词本简单词</div>
<div class="title">生词本错词本已掌握</div>
<div class="txt">
默写单词时输入错误会自动添加到错词本以便后续复习也可以添加到简单词之后再遇到这个词便会自动跳过同时也可以将其添加到生词本中以便巩固复习
默写单词时输入错误会自动添加到错词本以便后续复习也可以添加到已掌握之后再遇到这个词便会自动跳过同时也可以将其添加到生词本中以便巩固复习
</div>
</li>
<li>
@@ -78,4 +78,4 @@ import {APP_NAME} from "../../../utils/const.ts";
}
}
</style>
</style>

View File

@@ -74,7 +74,7 @@ function $no() {
</div>
<div class="item" @click="router.push('/mobile/simple')">
<img src="../../../assets/img/complete.png" alt="">
<span>简单词</span>
<span>已掌握</span>
</div>
</div>
<div class="setting-list">

View File

@@ -7,11 +7,11 @@ import SimpleList from "@/pages/mobile/components/SimpleList.vue";
<template>
<div class="mobile-page">
<NavBar title="简单词"/>
<NavBar title="已掌握"/>
<SimpleList/>
</div>
</template>
<style scoped lang="scss">
</style>
</style>

View File

@@ -373,13 +373,13 @@ onMounted(() => {
v-if="!isWordSimple(item)"
class="easy"
@click="toggleWordSimple(item)"
title="标记为简单词"
title="标记为已掌握"
icon="material-symbols:check-circle-outline-rounded"/>
<BaseIcon
v-else
class="fill"
@click="toggleWordSimple(item)"
title="取消标记简单词"
title="取消标记已掌握"
icon="material-symbols:check-circle-rounded"/>
</template>
</WordList>

View File

@@ -61,7 +61,7 @@ function startStudy() {
showSearchDialog = true
return
}
router.push('/learn-article')
router.push('/study-article')
}
</script>

View File

@@ -1,14 +1,12 @@
<script setup lang="ts">
import {onMounted, onUnmounted, watch} from "vue";
import {usePracticeStore} from "@/stores/practice.ts";
import {onMounted, onUnmounted} from "vue";
import {useBaseStore} from "@/stores/base.ts";
import Statistics from "@/pages/pc/word/Statistics.vue";
import {emitter, EventKey} from "@/utils/eventBus.ts";
import {useSettingStore} from "@/stores/setting.ts";
import {useRuntimeStore} from "@/stores/runtime.ts";
import {MessageBox} from "@/utils/MessageBox.tsx";
import PracticeArticle from "@/pages/pc/article/practice-article/index.vue";
import {ShortcutKey} from "@/types.ts";
import {useStartKeyboardEventListener} from "@/hooks/event.ts";

View File

@@ -35,7 +35,6 @@ const emit = defineEmits<{
}],
}>()
const settingStore = useSettingStore()
let listRef: any = $ref()
function scrollToBottom() {
@@ -73,11 +72,11 @@ let selectAll = $computed(() => {
})
function toggleSelect(item) {
let rIndex = selectIds.findIndex(v => v === item.id)
let rIndex = selectIds.findIndex(v => v === item.word)
if (rIndex > -1) {
selectIds.splice(rIndex, 1)
} else {
selectIds.push(item.id)
selectIds.push(item.word)
}
}
@@ -85,7 +84,7 @@ function toggleSelectAll() {
if (selectAll) {
selectIds = []
} else {
selectIds = currentList.map(v => v.id)
selectIds = currentList.map(v => v.word)
}
}
@@ -119,7 +118,7 @@ const s = useSlots()
defineRender(
() => {
const d = (item) => <el-checkbox
modelValue={selectIds.includes(item.id)}
modelValue={selectIds.includes(item.word)}
onChange={() => toggleSelect(item)}
size="large"/>
@@ -211,7 +210,7 @@ defineRender(
{currentList.map((item) => {
return (
<div class="list-item-wrapper"
key={item.id}
key={item.word}
>
{s.default({checkbox: d, item})}
</div>
@@ -238,4 +237,4 @@ defineRender(
</script>
<style scoped lang="scss">
</style>
</style>

View File

@@ -5,6 +5,12 @@ import {dictionaryResources} from "@/assets/dictionary.ts";
import {groupBy} from "lodash-es";
import {useBaseStore} from "@/stores/base.ts";
import DictGroup from "@/pages/pc/components/list/DictGroup.vue";
import BaseIcon from "@/components/BaseIcon.vue";
import Input from "@/pages/pc/components/Input.vue";
import BaseButton from "@/components/BaseButton.vue";
import {computed} from "vue";
import DictList from "@/pages/pc/components/list/DictList.vue";
import Empty from "@/components/Empty.vue";
const emit = defineEmits<{
add: [],
@@ -12,14 +18,11 @@ const emit = defineEmits<{
}>()
const store = useBaseStore()
let currentLanguage = $ref('en')
let currentTranslateLanguage = $ref('common')
let groupByLanguage = groupBy(dictionaryResources, 'language')
function groupByDictTags(dictList: DictResource[]) {
return dictList.reduce<Record<string, DictResource[]>>((result, dict) => {
dict.tags.forEach((tag) => {
if (Object.prototype.hasOwnProperty.call(result, tag)) {
if (result[tag]) {
result[tag].push(dict)
} else {
result[tag] = [dict]
@@ -29,34 +32,64 @@ function groupByDictTags(dictList: DictResource[]) {
}, {})
}
const groupByTranslateLanguage = $computed(() => {
return groupBy(groupByLanguage[currentLanguage], 'translateLanguage')
})
const groupedByCategoryAndTag = $computed(() => {
const currentTranslateLanguageDictList = groupByTranslateLanguage[currentTranslateLanguage]
const groupByCategory = groupBy(currentTranslateLanguageDictList, 'category')
const groupByCategory = groupBy(dictionaryResources, 'category')
let data = []
for (const [key, value] of Object.entries(groupByCategory)) {
data.push([key, groupByDictTags(value)])
}
// console.log('groupedByCategoryAndTag', data)
return data
})
let showSearchInput = $ref(false)
let searchKey = $ref('')
const searchList = computed(() => {
if (searchKey) {
let s = searchKey.toLowerCase()
return dictionaryResources.filter((item) => {
return item.name.toLowerCase().includes(s)
|| item.category.toLowerCase().includes(s)
|| item.tags.join('').replace('所有', '').toLowerCase().includes(s)
|| item?.url?.toLowerCase?.().includes?.(s)
})
}
return []
})
defineExpose({startSearch: () => showSearchInput = true})
</script>
<template>
<div class="w-full">
<DictGroup
v-for="item in groupedByCategoryAndTag"
:select-id="store.currentStudyWordDict.id"
@selectDict="e => emit('selectDict',e)"
:groupByTag="item[1]"
:category="item[0]"
/>
<div class="card">
<div class="flex gap-4" v-if="showSearchInput">
<Input placeholder="请输入词典名称/缩写/类别" v-model="searchKey" class="flex-1" autofocus/>
<BaseButton @click="showSearchInput = false, searchKey = ''">取消</BaseButton>
</div>
<div class="title flex justify-between" v-else>
<span>词典列表</span>
<BaseIcon @click="showSearchInput = true" icon="fluent:search-24-regular"/>
</div>
<div class="mt-4" v-if="searchKey">
<DictList
v-if="searchList.length "
@selectDict="e => emit('selectDict',e)"
:list="searchList"
:select-id="'-1'"/>
<Empty v-else text="没有相关词典"/>
</div>
<div class="w-full" v-else>
<DictGroup
v-for="item in groupedByCategoryAndTag"
:select-id="store.currentStudyWordDict.id"
@selectDict="e => emit('selectDict',e)"
:groupByTag="item[1]"
:category="item[0]"
/>
</div>
</div>
</template>
<style scoped lang="scss">

View File

@@ -6,6 +6,7 @@ import {useDisableEventListener, useWindowClick} from "@/hooks/event.ts";
defineProps<{
modelValue: string
placeholder: string
autofocus?: boolean
}>()
@@ -40,6 +41,7 @@ const vFocus = {
<input type="text"
:value="modelValue"
v-focus="autofocus"
:placeholder="placeholder"
@input="e=>$emit('update:modelValue',e.target.value)"
>
<transition name="fade">
@@ -52,7 +54,7 @@ const vFocus = {
.base-input {
border: 1px solid var(--color-second-bg);
border: 1px solid var(--color-input-border);
border-radius: .4rem;
overflow: hidden;
padding: .2rem .3rem;

View File

@@ -158,10 +158,12 @@ let tab = $ref(2)
<div class="flex gap-1 mt-26">
<div class="phonetic" v-if="settingStore.wordSoundType === 'us' && word.phonetic0">[{{
(settingStore.dictation && !showFullWord) ? '_'.repeat(word.phonetic0.length) : word.phonetic0
}}]</div>
}}]
</div>
<div class="phonetic" v-if="settingStore.wordSoundType === 'uk' && word.phonetic1">[{{
(settingStore.dictation && !showFullWord) ? '_'.repeat(word.phonetic1.length) : word.phonetic1
}}]</div>
}}]
</div>
<Tooltip
:title="`发音(${settingStore.shortcutKeyMap[ShortcutKey.PlayWordPronunciation]})`"
@@ -186,10 +188,10 @@ let tab = $ref(2)
<span class="letter" v-else>{{ displayWord }}</span>
</div>
<div class="translate"
<div class="translate anim"
v-opacity="settingStore.translate"
:style="{
fontSize: settingStore.fontSize.wordTranslateFontSize +'px',
opacity: settingStore.translate ? 1 : 0
}"
>
<div class="my-2 flex" v-for="(v,i) in word.trans">
@@ -199,13 +201,17 @@ let tab = $ref(2)
</div>
</div>
<div class="other">
<div class="line-white my-4"></div>
<div class="sentences" v-if="word.sentences && word.sentences.length">
<div class="sentence my-2" v-for="item in word.sentences">
<SentenceHightLightWord class="text-lg" :text="item.c" :word="word.word" :dictation="settingStore.dictation"/>
<div class="text-md">{{ item.cn }}</div>
<template v-if="word.sentences && word.sentences.length">
<div class="line-white my-4"></div>
<div class="sentences">
<div class="sentence my-2" v-for="item in word.sentences">
<SentenceHightLightWord class="text-lg" :text="item.c" :word="word.word"
:dictation="settingStore.dictation"/>
<div class="text-md anim" v-opacity="settingStore.translate">{{ item.cn }}</div>
</div>
</div>
</div>
</template>
<div class="line-white my-4"></div>
<div class="tabs">
<div @click="tab = 0" class="tab" :class="tab === 0 && 'active'">短语</div>
@@ -215,8 +221,9 @@ let tab = $ref(2)
</div>
<template v-if="tab === 0">
<div class="my-2" v-for="item in word.phrases">
<SentenceHightLightWord class="text-lg" :text="item.c" :word="word.word" :high-light="false" :dictation="settingStore.dictation"/>
<div class="text-md">{{ item.cn }}</div>
<SentenceHightLightWord class="text-lg" :text="item.c" :word="word.word" :high-light="false"
:dictation="settingStore.dictation"/>
<div class="text-md anim" v-opacity="settingStore.translate">{{ item.cn }}</div>
</div>
</template>
<template v-if="tab === 1">
@@ -230,7 +237,7 @@ let tab = $ref(2)
</template>
<template v-if="tab === 2">
<div class="mt-2">
<div>
<div v-if="word.relWords.root">
词根{{ word.relWords.root }}
</div>
<div class="flex my-2" v-for="item in word.relWords.rels">
@@ -264,7 +271,6 @@ let tab = $ref(2)
.phonetic, .translate {
font-size: 1.2rem;
transition: all .3s;
}
.phonetic {

View File

@@ -4,7 +4,6 @@ import {Word} from "@/types.ts";
import VolumeIcon from "@/components/icon/VolumeIcon.vue";
import {usePlayWordAudio} from "@/hooks/sound.ts";
const props = withDefaults(defineProps<{
item: Word,
showTranslate?: boolean
@@ -32,8 +31,20 @@ const playWordAudio = usePlayWordAudio()
<span class="phonetic">{{ item.phonetic0 }}</span>
<VolumeIcon class="volume" @click="playWordAudio(item.word)"></VolumeIcon>
</div>
<div class="item-sub-title" v-if="item.trans.length && showTranslate">
<div v-for="v in item.trans">{{ (v.pos ? v.pos + '.' : '') + (v.tran ) }}</div>
<div class="item-sub-title flex flex-col gap-2" v-if="item.trans.length && showTranslate">
<div v-for="v in item.trans">
<el-popover
v-if="v.cn.length > 30"
width="300"
:content="v.pos + ' ' + v.cn"
placement="top"
>
<template #reference>
<span>{{ v.pos + ' ' + v.cn.slice(0, 30) + '...' }}</span>
</template>
</el-popover>
<span v-else>{{ v.pos + ' ' + v.cn }}</span>
</div>
</div>
</div>
</div>

View File

@@ -1,11 +1,11 @@
<script setup lang="ts">
import {Dict, DictType} from "@/types.ts";
import {DictResource} from "@/types.ts";
import {Icon} from "@iconify/vue";
import BaseIcon from "@/components/BaseIcon.vue";
const props = defineProps<{
dict?: Dict,
dict?: DictResource,
active?: boolean
showDel?: boolean
}>()
@@ -28,7 +28,7 @@ const emit = defineEmits<{
<div class="desc" :style="{opacity:dict.name !== dict.description?1:0}">{{ dict.description }}</div>
</div>
<div class="bottom">
<div class="num">{{ dict.length + '词' }}</div>
<div class="num text-align-right">{{ dict.length + '词' }}</div>
</div>
<div class="del" v-if="dict.showDel && !active">
<BaseIcon icon="solar:trash-bin-minimalistic-linear" @click="emit('del')"/>

View File

@@ -1,10 +1,10 @@
<script setup lang="ts">
import {Dict} from "@/types.ts";
import {Dict, DictResource} from "@/types.ts";
import {Icon} from "@iconify/vue";
import DictItem from "@/pages/pc/components/list/DictItem.vue";
defineProps<{
list?: Dict[],
list?: DictResource[],
selectId?: string
}>()

View File

@@ -2,13 +2,11 @@
import BasePage from "@/pages/pc/components/BasePage.vue";
import {onMounted, reactive} from "vue";
import {useRoute} from "vue-router";
import {useRuntimeStore} from "@/stores/runtime.ts";
import {useBaseStore} from "@/stores/base.ts";
import {assign, cloneDeep} from "lodash-es";
import {nanoid} from "nanoid";
import BaseIcon from "@/components/BaseIcon.vue";
import {_checkDictWords, useNav} from "@/utils";
import {useNav} from "@/utils";
import BaseTable from "@/pages/pc/components/BaseTable.vue";
import WordItem from "@/pages/pc/components/WordItem.vue";
import type {Word} from "@/types.ts";
@@ -16,8 +14,6 @@ import type {FormInstance, FormRules} from "element-plus";
import PopConfirm from "@/pages/pc/components/PopConfirm.vue";
const runtimeStore = useRuntimeStore()
const store = useBaseStore()
const route = useRoute()
let loading = $ref(false)
let list = $computed({
@@ -30,31 +26,13 @@ let list = $computed({
})
onMounted(async () => {
switch (Number(route.query.type)) {
case -1:
if (runtimeStore.routeData) {
loading = true
runtimeStore.editDict = cloneDeep(runtimeStore.routeData)
await _checkDictWords(runtimeStore.editDict)
setTimeout(() => {
loading = false
}, 300)
}
break
case 0:
runtimeStore.editDict = cloneDeep(store.collectWord)
break
case 1:
runtimeStore.editDict = cloneDeep(store.wrong)
break
case 2:
runtimeStore.editDict = cloneDeep(store.simple)
break
case 3:
runtimeStore.editDict = cloneDeep(store.master)
break
default:
break
if (runtimeStore.routeData) {
loading = true
runtimeStore.editDict = cloneDeep(runtimeStore.routeData)
// await _checkDictWords(runtimeStore.editDict)
setTimeout(() => {
loading = false
}, 300)
}
})
const {back} = useNav()
@@ -161,109 +139,111 @@ function s(ss) {
defineRender(() => {
return (
<BasePage>
<header class="flex gap-4 mb-2 items-center">
<BaseIcon onClick={back} icon="octicon:arrow-left-24" width={20}/>
<div class="left">
<div class="top">
<div class="text-xl">
{runtimeStore.editDict.name}
<div className="card">
<header class="flex gap-4 mb-2 items-center">
<BaseIcon onClick={back} icon="octicon:arrow-left-24" width={20}/>
<div class="left">
<div class="top">
<div class="text-xl">
{runtimeStore.editDict.name}
</div>
</div>
</div>
{
runtimeStore.editDict.description ?
<div class="desc">{runtimeStore.editDict.description}</div> : null
}
</div>
</header>
<div class="flex" style="height:calc(100vh - 8rem)">
<div class="w-1/2">
<BaseTable
class="h-full"
list={list}
loading={loading}
onUpdate:list={e => list = e}
del={delWord}
batchDel={batchDel}
add={addWord}
>
{
(val) =>
<WordItem
item={val.item}>
{{
prefix: () => val.checkbox(val.item),
suffix: () => (
<div class='flex flex-col'>
<BaseIcon
class="option-icon"
onClick={() => editWord(val.item)}
title="编辑"
icon="tabler:edit"/>
<PopConfirm title="确认删除?"
onConfirm={() => delWord(val.item.id)}
>
runtimeStore.editDict.description ?
<div class="desc">{runtimeStore.editDict.description}</div> : null
}
</div>
</header>
<div class="flex" style="height:calc(100vh - 8rem)">
<div class="w-1/2">
<BaseTable
class="h-full"
list={list}
loading={loading}
onUpdate:list={e => list = e}
del={delWord}
batchDel={batchDel}
add={addWord}
>
{
(val) =>
<WordItem
item={val.item}>
{{
prefix: () => val.checkbox(val.item),
suffix: () => (
<div class='flex flex-col'>
<BaseIcon
class="option-icon"
title="删除"
icon="solar:trash-bin-minimalistic-linear"/>
</PopConfirm>
onClick={() => editWord(val.item)}
title="编辑"
icon="tabler:edit"/>
<PopConfirm title="确认删除?"
onConfirm={() => delWord(val.item.id)}
>
<BaseIcon
class="option-icon"
title="删除"
icon="solar:trash-bin-minimalistic-linear"/>
</PopConfirm>
</div>
)
}}
</WordItem>
}
</BaseTable>
</div>
{
wordFormData.type ? (
<div class="flex-1 ml-4">
<div class="common-title">
{wordFormData.type === FormMode.Add ? '添加' : '修改'}单词
</div>
<el-form
className="form"
ref="wordFormRef"
rules={wordRules}
model={wordForm}
label-width="7rem">
<el-form-item label="单词" prop="word">
<el-input
modelValue={wordForm.word}
onUpdate:model-value={e => wordForm.word = e}
/>
</el-form-item>
<el-form-item label="翻译">
<el-input
modelValue={wordForm.trans}
onUpdate:model-value={e => wordForm.trans = e}
placeholder="多个翻译请换行"
autosize={{minRows: 6, maxRows: 10}}
type="textarea"/>
</el-form-item>
<el-form-item label="音标/发音①">
<el-input
modelValue={wordForm.phonetic0}
onUpdate:model-value={e => wordForm.phonetic0 = e}
/>
</el-form-item>
<el-form-item label="音标/发音②">
<el-input
modelValue={wordForm.phonetic1}
onUpdate:model-value={e => wordForm.phonetic1 = e}/>
</el-form-item>
<div class="center">
<el-button
onClick={closeWordForm}>关闭
</el-button>
<el-button type="primary"
onClick={onSubmitWord}>保存
</el-button>
</div>
)
}}
</WordItem>
}
</BaseTable>
</div>
{
wordFormData.type ? (
<div class="flex-1 ml-4">
<div class="common-title">
{wordFormData.type === FormMode.Add ? '添加' : '修改'}单词
</div>
</el-form>
</div>
) : null
}
<el-form
className="form"
ref="wordFormRef"
rules={wordRules}
model={wordForm}
label-width="7rem">
<el-form-item label="单词" prop="word">
<el-input
modelValue={wordForm.word}
onUpdate:model-value={e => wordForm.word = e}
/>
</el-form-item>
<el-form-item label="翻译">
<el-input
modelValue={wordForm.trans}
onUpdate:model-value={e => wordForm.trans = e}
placeholder="多个翻译请换行"
autosize={{minRows: 6, maxRows: 10}}
type="textarea"/>
</el-form-item>
<el-form-item label="音标/发音①">
<el-input
modelValue={wordForm.phonetic0}
onUpdate:model-value={e => wordForm.phonetic0 = e}
/>
</el-form-item>
<el-form-item label="音标/发音②">
<el-input
modelValue={wordForm.phonetic1}
onUpdate:model-value={e => wordForm.phonetic1 = e}/>
</el-form-item>
<div class="center">
<el-button
onClick={closeWordForm}>关闭
</el-button>
<el-button type="primary"
onClick={onSubmitWord}>保存
</el-button>
</div>
</el-form>
</div>
) : null
}
</div>
</div>
</BasePage>
)

View File

@@ -1,9 +1,9 @@
<script setup lang="ts">
import {onMounted, onUnmounted} from "vue"
import {inject, onMounted, onUnmounted, provide} from "vue"
import {usePracticeStore} from "@/stores/practice.ts";
import {useSettingStore} from "@/stores/setting.ts";
import {ShortcutKey} from "@/types.ts";
import {ShortcutKey, StudyData} from "@/types.ts";
import BaseIcon from "@/components/BaseIcon.vue";
import {Icon} from "@iconify/vue";
import IconWrapper from "@/pages/pc/components/IconWrapper.vue";
@@ -32,12 +32,6 @@ function format(val: number, suffix: string = '', check: number = -1) {
return val === check ? '-' : (val + suffix)
}
const progress = $computed(() => {
if (!statisticsStore.total) return 0
if (statisticsStore.index > statisticsStore.total) return 100
return ((statisticsStore.index / statisticsStore.total) * 100)
})
let speedMinute = $ref(0)
let timer = $ref(0)
onMounted(() => {
@@ -50,6 +44,30 @@ onUnmounted(() => {
timer && clearInterval(timer)
})
const statStore = usePracticeStore()
let studyData = inject<StudyData>('studyData')
const status = $computed(() => {
let str = '正在'
switch (statStore.step) {
case 0:
str += `学习新词`
break
case 1:
str += `复习`
break
case 2:
str += '默写'
break
}
return str
})
const progress = $computed(() => {
if (!studyData.words.length) return 0
return ((studyData.index / studyData.words.length) * 100)
})
</script>
<template>
@@ -71,9 +89,9 @@ onUnmounted(() => {
<div class="flex justify-between items-center">
<div class="stat gap-6">
<div class="row">
<div class="num">{{ speedMinute }}分钟</div>
<div class="num">{{ `${studyData.index}/${studyData.words.length}` }}</div>
<div class="line"></div>
<div class="name">时间</div>
<div class="name">{{ status }}</div>
</div>
<div class="row">
<div class="num">{{ statisticsStore.total }}</div>
@@ -96,13 +114,13 @@ onUnmounted(() => {
v-if="!isSimple"
class="collect"
@click="$emit('toggleSimple')"
:title="`标记为简单词(${settingStore.shortcutKeyMap[ShortcutKey.ToggleSimple]})`"
:title="`标记为已掌握(${settingStore.shortcutKeyMap[ShortcutKey.ToggleSimple]})`"
icon="material-symbols:check-circle-outline-rounded"/>
<BaseIcon
v-else
class="fill"
@click="$emit('toggleSimple')"
:title="`取消标记简单词(${settingStore.shortcutKeyMap[ShortcutKey.ToggleSimple]})`"
:title="`取消标记已掌握(${settingStore.shortcutKeyMap[ShortcutKey.ToggleSimple]})`"
icon="material-symbols:check-circle-rounded"/>
<BaseIcon
@@ -202,7 +220,7 @@ onUnmounted(() => {
flex-direction: column;
align-items: center;
gap: .3rem;
width: 5rem;
width: 6rem;
color: gray;
.line {

View File

@@ -8,28 +8,26 @@ import BaseIcon from "@/components/BaseIcon.vue";
import Dialog from "@/pages/pc/components/dialog/Dialog.vue";
import {_getAccomplishDate, _getAccomplishDays, useNav} from "@/utils";
import BasePage from "@/pages/pc/components/BasePage.vue";
import {getDefaultDict} from "@/types.ts";
import {Dict, DictResource, getDefaultDict} from "@/types.ts";
import {onMounted} from "vue";
import {getCurrentStudyWord} from "@/hooks/dict.ts";
import {usePracticeStore} from "@/stores/practice.ts";
import {EventKey, useEvent} from "@/utils/eventBus.ts";
import DictListPanel from "@/pages/pc/components/DictListPanel.vue";
import DictGroup from "@/pages/pc/components/list/DictGroup.vue";
import {cloneDeep} from "lodash-es";
import {useRuntimeStore} from "@/stores/runtime.ts";
import {getArticleBookDataByUrl} from "@/utils/article.ts";
const store = useBaseStore()
const router = useRouter()
const {nav} = useNav()
const runtimeStore = useRuntimeStore()
function clickEvent(e) {
console.log('e', e)
}
let showMore = $ref(false)
const otherWordDictList = $computed(() => {
if (showMore) return store.otherWordDictList
else return store.otherWordDictList.slice(0, 4)
})
let currentStudy = $ref({
new: [],
review: [],
@@ -61,6 +59,30 @@ function changePerDayStudyNumber() {
function selectDict(e) {
console.log(e)
}
async function goDictDetail2(val: Dict) {
runtimeStore.editDict = cloneDeep(val)
nav('edit-word-dict')
}
async function getBookDetail(val: DictResource) {
let r = await getArticleBookDataByUrl(val)
runtimeStore.editDict = cloneDeep(r)
nav('book-detail')
}
let showAddChooseDialog = $ref(false)
let dictListRef = $ref<any>()
function goChooseDict() {
showAddChooseDialog = false
dictListRef.startSearch()
}
function addDict() {
}
</script>
<template>
@@ -131,55 +153,29 @@ function selectDict(e) {
</div>
</div>
<div class="card" v-if="otherWordDictList.length">
<div class="flex justify-between">
<div class="title">
其他学习词典
</div>
<BaseIcon icon="ic:round-add"
title="切换词典"
@click="router.push('/dict')"/>
</div>
<div class="grid grid-cols-2 gap-6 mt-5 ">
<div class=" p-4 rounded-md justify-between items-center bg-slate-200 " v-for="i in otherWordDictList">
<div class="flex justify-between w-full">
<span>{{ i.name }}</span>
<div class="text-2xl ml-2 flex gap-4">
<BaseIcon title="删除" icon="hugeicons:delete-02" @click="store.delWordDict(i)"/>
<BaseIcon title="学习" icon="nonicons:go-16" @click="store.changeWordDict(getDefaultDict(i))"/>
<BaseIcon title="修改" icon="nonicons:go-16" @click="nav('edit-word-dict',{type:-1},i)"/>
</div>
</div>
<div class="mt-5 text-sm">已学习5555个单词的1%</div>
<el-progress class="mt-1" :percentage="80" color="white" :show-text="false"></el-progress>
</div>
</div>
<div class="flex justify-center mt-2 text-2xl" v-if="store.otherWordDictList.length > 4">
<BaseIcon @click="showMore = !showMore" v-if="showMore" icon="mingcute:up-line"/>
<BaseIcon @click="showMore = !showMore" v-else icon="mingcute:down-line"/>
</div>
</div>
<div class="card flex flex-col">
<div class="title">
我的词典
</div>
<div class="grid grid-cols-6 gap-4 mt-4">
<div class="book" v-for="item in store.word.bookList" @click="nav('edit-word-dict',{type:item.type})">
<div class="book" v-for="item in store.word.bookList" @click="goDictDetail2(item)">
<span>{{ item.name }}</span>
<div class="absolute bottom-4 right-4">{{ item.words.length }}个词</div>
</div>
<div class="book" @click="showAddChooseDialog = true">
<div class="center h-full">
<Icon
width="40px"
icon="fluent:add-20-filled"/>
</div>
</div>
</div>
</div>
<div class="card">
<div class="title">
所有词典
</div>
<DictListPanel
@selectDict="selectDict"
/>
</div>
<DictListPanel
ref="dictListRef"
@selectDict="selectDict"
/>
<div class="card">
<div class="title">
@@ -234,6 +230,16 @@ function selectDict(e) {
</div>
</div>
</Dialog>
<Dialog v-model="showAddChooseDialog" title="选项">
<div class="color-black px-6 w-100">
<div class="cursor-pointer hover:bg-black/10 p-2 rounded"
@click="goChooseDict">选择一本词典
</div>
<p class="cursor-pointer hover:bg-black/10 p-2 rounded" @click="addDict">创建自己的词典</p>
</div>
</Dialog>
</BasePage>
</template>

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import {watch} from "vue"
import {provide, watch} from "vue"
import {useBaseStore} from "@/stores/base.ts"
import {getDefaultWord, ShortcutKey, Word} from "@/types.ts";
import {getDefaultWord, ShortcutKey, StudyData, Word} from "@/types.ts";
import {emitter, EventKey, useEvents} from "@/utils/eventBus.ts"
import {cloneDeep, shuffle} from "lodash-es"
import {usePracticeStore} from "@/stores/practice.ts"
@@ -11,7 +11,6 @@ import {Icon} from "@iconify/vue";
import Tooltip from "@/pages/pc/components/Tooltip.vue";
import Typing from "@/pages/pc/components/Typing.vue";
import Panel from "@/pages/pc/components/Panel.vue";
import {useRuntimeStore} from "@/stores/runtime.ts";
import {useWordOptions} from "@/hooks/dict.ts";
import BaseIcon from "@/components/BaseIcon.vue";
import WordList from "@/pages/pc/components/list/WordList.vue";
@@ -42,7 +41,6 @@ const emit = defineEmits<{
const typingRef: any = $ref()
const store = useBaseStore()
const runtimeStore = useRuntimeStore()
const statStore = usePracticeStore()
const settingStore = useSettingStore()
@@ -54,16 +52,19 @@ const {
} = useWordOptions()
let allWrongWords = []
let current = $ref({
let data = $ref<StudyData>({
index: 0,
words: [],
wrongWords: [],
})
provide('studyData', data)
watch(() => props.data, () => {
current.words = props.data.new
current.index = 0
current.wrongWords = []
data.words = props.data.new
data.index = 0
data.wrongWords = []
allWrongWords = []
statStore.step = 0
@@ -76,26 +77,26 @@ watch(() => props.data, () => {
}, {immediate: true, deep: true})
const word = $computed(() => {
return current.words[current.index] ?? getDefaultWord()
return data.words[data.index] ?? getDefaultWord()
})
const prevWord: Word = $computed(() => {
return current.words?.[current.index - 1] ?? undefined
return data.words?.[data.index - 1] ?? undefined
})
const nextWord: Word = $computed(() => {
return current.words?.[current.index + 1] ?? undefined
return data.words?.[data.index + 1] ?? undefined
})
function next(isTyping: boolean = true) {
if (current.index === current.words.length - 1) {
if (current.wrongWords.length) {
if (data.index === data.words.length - 1) {
if (data.wrongWords.length) {
console.log('学完了,但还有错词')
current.words = shuffle(cloneDeep(current.wrongWords))
current.index = 0
current.wrongWords = []
data.words = shuffle(cloneDeep(data.wrongWords))
data.index = 0
data.wrongWords = []
} else {
console.log('学完了,没错词', statStore.total, statStore.step, current.index)
console.log('学完了,没错词', statStore.total, statStore.step, data.index)
isTyping && statStore.inputWordNumber++
statStore.speed = Date.now() - statStore.startDate
@@ -107,24 +108,24 @@ function next(isTyping: boolean = true) {
if (statStore.step === 1) {
settingStore.dictation = true
current.words = shuffle(props.data.write.concat(props.data.new).concat(props.data.review))
data.words = shuffle(props.data.write.concat(props.data.new).concat(props.data.review))
statStore.step++
current.index = 0
data.index = 0
}
if (statStore.step === 0) {
statStore.step++
if (props.data.review.length) {
current.words = shuffle(props.data.review)
data.words = shuffle(props.data.review)
settingStore.dictation = false
current.index = 0
data.index = 0
} else {
next()
}
}
}
} else {
current.index++
data.index++
isTyping && statStore.inputWordNumber++
// console.log('这个词完了')
}
@@ -134,8 +135,8 @@ function wordWrong() {
if (!store.wrong.words.find((v: Word) => v.word.toLowerCase() === word.word.toLowerCase())) {
store.wrong.words.push(word)
}
if (!current.wrongWords.find((v: Word) => v.word.toLowerCase() === word.word.toLowerCase())) {
current.wrongWords.push(word)
if (!data.wrongWords.find((v: Word) => v.word.toLowerCase() === word.word.toLowerCase())) {
data.wrongWords.push(word)
}
if (!allWrongWords.find((v: Word) => v.word.toLowerCase() === word.word.toLowerCase())) {
allWrongWords.push(word)
@@ -160,10 +161,10 @@ useOnKeyboardEventListener(onKeyDown, onKeyUp)
//TODO 略过忽略的单词上
function prev() {
if (current.index === 0) {
if (data.index === 0) {
ElMessage.warning('已经是第一个了~')
} else {
current.index--
data.index--
}
}
@@ -203,28 +204,13 @@ useEvents([
[ShortcutKey.PlayWordPronunciation, play],
])
const status = $computed(() => {
let str = '正在'
switch (statStore.step) {
case 0:
str += `学习新单词`
break
case 1:
str += '复习'
break
case 2:
str += '默写'
break
}
return str
})
</script>
<template>
<div class="practice-wrapper">
<div class="practice-word">
<div class="near-word" v-if="settingStore.showNearWord">
<div class="prev"
<div class="absolute z-1 top-4 w-full" v-if="settingStore.showNearWord">
<div class="center gap-2 cursor-pointer float-left"
@click="prev"
v-if="prevWord">
<Icon class="arrow" icon="bi:arrow-left" width="22"/>
@@ -234,7 +220,7 @@ const status = $computed(() => {
<div class="word">{{ prevWord.word }}</div>
</Tooltip>
</div>
<div class="next"
<div class="center gap-2 cursor-pointer float-right "
@click="next(false)"
v-if="nextWord">
<Tooltip
@@ -267,24 +253,15 @@ const status = $computed(() => {
<div class="panel-page-item pl-4"
v-loading="!store.load"
>
<div class="list-header">
<div class="flex items-center gap-1">
<Icon icon="material-symbols:hourglass-empty-rounded"/>
<span class="text-sm"> {{ status }}</span>
</div>
<div class="flex items-center gap-2">
<span> {{ current.index }} / {{ current.words.length }}</span>
</div>
</div>
<WordList
v-if="current.words.length"
v-if="data.words.length"
:is-active="active"
:static="false"
:show-word="!settingStore.dictation"
:show-translate="settingStore.translate"
:list="current.words"
:activeIndex="current.index"
@click="(val:any) => current.index = val.index"
:list="data.words"
:activeIndex="data.index"
@click="(val:any) => data.index = val.index"
>
<template v-slot:suffix="{item,index}">
<BaseIcon
@@ -301,13 +278,13 @@ const status = $computed(() => {
v-if="!isWordSimple(item)"
class="easy"
@click="toggleWordSimple(item)"
title="标记为简单词"
title="标记为已掌握"
icon="material-symbols:check-circle-outline-rounded"/>
<BaseIcon
v-else
class="fill"
@click="toggleWordSimple(item)"
title="取消标记简单词"
title="取消标记已掌握"
icon="material-symbols:check-circle-rounded"/>
</template>
</WordList>
@@ -342,48 +319,6 @@ const status = $computed(() => {
gap: .4rem;
position: relative;
width: var(--toolbar-width);
.near-word {
position: absolute;
top: 1rem;
width: 100%;
z-index: 1;
& > div {
width: 45%;
align-items: center;
.arrow {
font-size: .5rem;
}
}
.word {
font-size: 1.2rem;
margin-bottom: .2rem;
font-family: var(--word-font-family);
}
.prev {
cursor: pointer;
display: flex;
float: left;
gap: .8rem;
}
.next {
cursor: pointer;
display: flex;
justify-content: flex-end;
gap: .8rem;
float: right;
}
}
.options-wrapper {
position: absolute;
margin-top: 8rem;
}
}
.word-panel-wrapper {

View File

@@ -325,7 +325,7 @@
},
{
"id": "skip",
"name": "简单词",
"name": "已掌握",
"description": "",
"sort": 0,
"originWords": [],
@@ -115323,4 +115323,4 @@
"load": true
},
"version": 3
}
}

View File

@@ -6,7 +6,7 @@ import WordHomePage from "@/pages/pc/word/WordHomePage.vue";
import PC from "@/pages/pc/index.vue";
import ArticleHomePage from "@/pages/pc/article/ArticleHomePage.vue";
import HomeIndex from "@/pages/pc/home/HomeIndex.vue";
import LearnArticle from "@/pages/pc/article/LearnArticle.vue";
import StudyArticle from "@/pages/pc/article/StudyArticle.vue";
import EditWordDict from "@/pages/pc/word/EditWordDict.vue";
import StudyWord from "@/pages/pc/word/StudyWord.vue";
import EditArticlePage from "@/pages/pc/article/EditArticlePage.vue";
@@ -23,9 +23,9 @@ export const routes: RouteRecordRaw[] = [
{path: 'study-word', component: StudyWord},
{path: 'edit-word-dict', component: EditWordDict},
{path: 'article', component: ArticleHomePage},
{path: 'study-article', component: StudyArticle},
{path: 'edit-article', component: EditArticlePage},
{path: 'batch-edit-article', component: BatchEditArticlePage},
{path: 'learn-article', component: LearnArticle},
{path: 'book-detail', component: BookDetail},
]
},

View File

@@ -207,16 +207,12 @@ export const useBaseStore = defineStore('base', {
if (!this.sdict.words?.length) return 0
return _getStudyProgress(this.sdict.lastLearnIndex, this.sdict.words?.length)
},
otherWordDictList(): Dict[] {
return this.word.bookList.filter(v => this.sdict.id !== v.id)
},
currentArticleCollectDict(): Dict {
return this.article.bookList[0]
},
chapter(state: BaseState): Word[] {
return this.currentDict.chapterWords[this.currentDict.chapterIndex] ?? []
},
currentBook(): Dict {
return this.article.bookList[this.article.studyIndex] ?? {}
},

View File

@@ -339,3 +339,9 @@ export const SlideType = {
HORIZONTAL: 0,
VERTICAL: 1,
}
export interface StudyData {
index: number,
words: any[],
wrongWords: any[],
}