Skip to content

Commit

Permalink
Merge pull request #90 from tolerious/feat/the-guardian-support
Browse files Browse the repository at this point in the history
Feat/the guardian support
  • Loading branch information
tolerious authored Feb 15, 2025
2 parents 4c87da2 + a5dc5af commit 9b2ce1b
Show file tree
Hide file tree
Showing 8 changed files with 241 additions and 34 deletions.
11 changes: 10 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
{
"files.autoSave": "afterDelay",
"editor.bracketPairColorization.independentColorPoolPerBracketType": true
"editor.bracketPairColorization.independentColorPoolPerBracketType": true,
"cSpell.words": [
"dsense",
"FUIYOH",
"HIYAA",
"thisweek",
"usersetting",
"wordgroup",
"wordlist"
]
}
11 changes: 0 additions & 11 deletions components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,18 @@ declare module 'vue' {
export interface GlobalComponents {
ElAffix: typeof import('element-plus/es')['ElAffix']
ElBacktop: typeof import('element-plus/es')['ElBacktop']
ElButton: typeof import('element-plus/es')['ElButton']
ElCard: typeof import('element-plus/es')['ElCard']
ElCarousel: typeof import('element-plus/es')['ElCarousel']
ElCarouselItem: typeof import('element-plus/es')['ElCarouselItem']
ElCol: typeof import('element-plus/es')['ElCol']
ElCollapse: typeof import('element-plus/es')['ElCollapse']
ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
ElDescriptions: typeof import('element-plus/es')['ElDescriptions']
ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem']
ElDialog: typeof import('element-plus/es')['ElDialog']
ElDivider: typeof import('element-plus/es')['ElDivider']
ElEmpty: typeof import('element-plus/es')['ElEmpty']
ElForm: typeof import('element-plus/es')['ElForm']
ElFormItem: typeof import('element-plus/es')['ElFormItem']
ElIcon: typeof import('element-plus/es')['ElIcon']
ElInput: typeof import('element-plus/es')['ElInput']
ElOption: typeof import('element-plus/es')['ElOption']
ElRadio: typeof import('element-plus/es')['ElRadio']
ElRow: typeof import('element-plus/es')['ElRow']
ElSelect: typeof import('element-plus/es')['ElSelect']
ElSkeleton: typeof import('element-plus/es')['ElSkeleton']
ElSkeletonItem: typeof import('element-plus/es')['ElSkeletonItem']
ElSwitch: typeof import('element-plus/es')['ElSwitch']
Header: typeof import('./src/components/Header.vue')['default']
IconCommunity: typeof import('./src/components/icons/IconCommunity.vue')['default']
IconDocumentation: typeof import('./src/components/icons/IconDocumentation.vue')['default']
Expand Down
10 changes: 10 additions & 0 deletions src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ const router = createRouter({
name: 'register',
component: () => import('@/views/UserRegister.vue'),
},
{
path: '/reading',
name: 'reading',
component: () => import('@/views/ReadingArticle.vue'),
},
{
path: '/reading/:articleID',
name: 'readingDetail',
component: () => import('@/views/ReadingArticleDetail.vue'),
},
{
path: '/review/word/:groupID',
name: 'reviewWord',
Expand Down
2 changes: 1 addition & 1 deletion src/utils/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ function createRequest(service: AxiosInstance) {
Authorization: token ? `Bearer ${token}` : '',
'Content-Type': 'application/json',
},
timeout: 10000,
timeout: 100000,
baseURL: import.meta.env.VITE_BASE_API,
data: {},
};
Expand Down
39 changes: 33 additions & 6 deletions src/views/HomePage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,20 @@

<el-row justify="space-around">
<el-col :span="11">
<el-card class="cursor-pointer text-center" shadow-sm="always" @click="redirect('group-manage')"
<el-card
class="cursor-pointer text-center hover:bg-pink-500 hover:text-white"
shadow="always"
@click="redirect('group-manage')"
>我的词组</el-card
>
</el-col>
<el-col :span="11">
<el-card class="cursor-pointer text-center" shadow-sm="always" @click="redirect('today')">
今日收藏
<el-card
class="cursor-pointer text-center hover:bg-pink-500 hover:text-white"
shadow="always"
@click="redirect('recite')"
>
单词背诵
</el-card>
</el-col>
</el-row>
Expand All @@ -61,12 +68,31 @@
</el-row> -->
<el-row justify="space-around" style="margin-top: 15px">
<el-col :span="11">
<el-card class="cursor-pointer text-center" shadow-sm="always" @click="redirect('feedback')"
<el-card
class="cursor-pointer text-center hover:bg-pink-500 hover:text-white"
shadow="always"
@click="redirect('reading')"
>阅读理解</el-card
>
</el-col>
<el-col :span="11">
<el-card class="cursor-not-allowed text-center" shadow="always">即将开放 </el-card>
</el-col>
</el-row>
<el-row justify="space-around" style="margin-top: 15px">
<el-col :span="11">
<el-card
class="hover:bg-pink-500 hover:text-white cursor-pointer text-center"
shadow="always"
@click="redirect('feedback')"
>反馈建议</el-card
>
</el-col>
<el-col :span="11">
<el-card class="cursor-pointer text-center" shadow-sm="always" @click="redirect('settings')"
<el-card
class="hover:bg-pink-500 hover:text-white cursor-pointer text-center"
shadow="always"
@click="redirect('settings')"
>用户设置</el-card
>
</el-col>
Expand Down Expand Up @@ -135,7 +161,7 @@ function createCollectionChart() {
const dom = document.getElementById('collection');
if (dom) {
const chart = new Chart('collection', {
new Chart('collection', {
type: 'bar',
data: {
labels: everyDayWordCount.value.map(row => row.year),
Expand Down Expand Up @@ -176,6 +202,7 @@ function redirect(condition: string) {
if (condition === 'settings') router.push('/settings');
if (condition === 'help') router.push('/help');
if (condition === 'square') router.push('/square');
if (condition === 'reading') router.push('/reading');
if (condition === 'today') router.push('/today');
}
Expand Down
77 changes: 77 additions & 0 deletions src/views/ReadingArticle.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<template>
<Header :title="'Reading Article'" @go-back="handleGoBack" />
<div class="px-3 py-2" v-if="articleList.length > 0">
<span
@click="handleGenerateAllQuestionsAnswers"
class="px-2 py-1 bg-cyan-400 select-none cursor-pointer active:shadow-sm active:shadow-cyan-600 rounded"
>一键生成</span
>
<div v-for="article in articleList" :key="article._id">
<div class="my-3 font-bold text-lg">{{ article._id }}</div>
<div
@click="handleGoToArticleDetail(i._id)"
class="px-1 py-2 bg-slate-50 mb-2 cursor-pointer"
v-for="i in article.documents"
:key="i"
>
<div @click.stop class="cursor-auto">{{ i.title }}</div>
<div class="flex items-center" v-if="i.questions">
<div class="h-2 w-5 bg-green-300"></div>
<div class="ml-1"><span>问题已生成</span></div>
</div>
<div class="flex items-center" v-else>
<div class="h-2 w-5 bg-red-500"></div>
<div class="ml-1"><span>问题未生成</span></div>
</div>
</div>
</div>
</div>
<el-empty description="暂无数据,请访问The Guardian网站,阅读新闻,系统会自动添加。" v-else />
</template>

<script setup lang="ts">
import Header from '@/components/Header.vue';
import { request } from '@/utils/service';
import { onMounted, ref } from 'vue';
import { useRouter } from 'vue-router';
const router = useRouter();
const articleList = ref([]);
async function handleGenerateAllQuestionsAnswers() {
let availableList = [];
articleList.value.forEach(article => {
article.documents.forEach(doc => {
if (!doc.questions) {
availableList.push(doc._id);
}
});
});
console.log(availableList);
for (let i = 0; i < availableList.length; i++) {
const r = await request({ url: '/deepseek', method: 'post', data: { articleId: availableList[i] } });
console.log(r);
}
}
function handleGoToArticleDetail(id) {
router.push(`/reading/${id}`);
}
async function getGuardianArticles() {
const r = await request({ url: '/article/guardian' });
console.log(r);
articleList.value = r.data;
}
function handleGoBack() {
router.go(-1);
}
onMounted(() => {
getGuardianArticles();
});
</script>
95 changes: 95 additions & 0 deletions src/views/ReadingArticleDetail.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<template>
<Header :title="'Reading Article Detail'" @go-back="handleGoBack" />
<div class="px-3 py-3 bg-slate-50">
<h1 class="text-center text-xl font-bold">{{ articleDetail.title }}</h1>
<div class="mx-2 flex gap-2 my-5 text-slate-500">
<div class="bg-cyan-500 h-full w-1">&nbsp;</div>
<div>{{ articleDetail.summary }}</div>
</div>
<div>
<p class="text-lg mx-2 my-4" v-for="pp in articleDetail.content" :key="pp">{{ pp }}</p>
</div>
<div class="flex gap-2 items-center">
<a class="px-2 py-1 bg-cyan-500 cursor-pointer round rounded text-white" @click="handleOriginalUrl"
>原文链接</a
>
<div
@click="generateQuestions"
class="cursor-pointer active:shadow active:shadow-slate-400 px-2 py-1 bg-pink-500 rounded text-white"
>
生成问题
</div>
<div
@click="displayAnswers"
class="cursor-pointer active:shadow active:shadow-slate-400 px-2 py-1 bg-pink-500 rounded text-white"
>
查看答案
</div>
<div
@click="refreshPage"
class="cursor-pointer active:shadow active:shadow-slate-400 px-2 py-1 bg-pink-500 rounded text-white"
>
刷新页面
</div>
</div>
<div class="mt-16">
<div class="font-bold">Questions:</div>
<p class="whitespace-pre-wrap">{{ articleDetail.questions }}</p>
</div>
<div class="mt-16" v-if="isAnswersVisible">
<div class="font-bold">Answers:</div>
<p class="whitespace-pre-wrap">{{ articleDetail.answers }}</p>
</div>
</div>
</template>
<script setup lang="ts">
import Header from '@/components/Header.vue';
import { request } from '@/utils/service';
import { ElNotification } from 'element-plus';
import { onMounted, ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';
const router = useRouter();
const route = useRoute();
const articleDetail = ref({});
const isAnswersVisible = ref(false);
function refreshPage(){
window.location.reload();
}
function displayAnswers() {
isAnswersVisible.value = !isAnswersVisible.value;
}
function handleOriginalUrl() {
window.open(articleDetail.value.originalUrl);
}
function handleGoBack() {
router.go(-1);
}
async function getArticleDetail(id) {
const r = await request({ url: '/article/guardian/' + id });
console.log(r);
return r;
}
async function generateQuestions() {
const r = await request({ url: '/deepseek', method: 'post', data: { articleId: articleDetail.value._id } });
console.log(r);
if (r.code === 200) {
ElNotification({ type: 'success', title: '问题已生成' });
} else {
ElNotification({ type: 'error', title: '问题生成失败,请重试' });
}
}
onMounted(async () => {
const id = route.params.articleID;
console.log(id);
const t = await getArticleDetail(id);
articleDetail.value = t.data;
});
</script>
30 changes: 15 additions & 15 deletions src/views/RecordWord.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@
<div>
<el-select style="width: 180px" v-model="defaultGroup">
<el-option value="" label=""></el-option>
<el-option v-for="group in groupList" :value="group._id" :label="group.name"></el-option>
<el-option
v-for="group in groupList"
:value="group._id"
:label="group.name"
:key="group.name"
></el-option>
</el-select>
</div>
<div><el-button type="warning" @click="playAudio(form.englishName)">&nbsp;Audio&nbsp;</el-button></div>
Expand All @@ -34,27 +39,32 @@
:title="`${card.name} - ${card.property} - ${card.phonetic}`"
:name="index"
v-for="(card, index) in cardList"
:key="index"
>
<div class="collapse-header">{{ card.property }} {{ card.phonetic }}</div>
<template v-for="dsenseObj in card.dsenseObjList">
<el-card style="margin-bottom: 15px" v-for="dsense in dsenseObj.defBlockObjList">
<el-card style="margin-bottom: 15px" v-for="dsense in dsenseObj.defBlockObjList" :key="dsense.en">
<template #header>
<div class="dsense-title-container">{{ dsense.en }}</div>
<div class="dsense-title-container">{{ dsense.zh }}</div>
</template>
<div>
<div v-for="sentence in dsense.sentence">
<div v-for="sentence in dsense.sentence" :key="sentence">
{{ sentence }}
</div>
</div>
</el-card>
<el-card style="margin-bottom: 15px" v-for="dsense in dsenseObj.phraseBlockObjList">
<el-card
style="margin-bottom: 15px"
v-for="dsense in dsenseObj.phraseBlockObjList"
:key="dsense.en"
>
<template #header>
<div class="dsense-title-container">{{ dsense.en }}</div>
<div class="dsense-title-container">{{ dsense.zh }}</div>
</template>
<div>
<div v-for="sentence in dsense.sentence">
<div v-for="sentence in dsense.sentence" :key="sentence">
{{ sentence }}
</div>
</div>
Expand Down Expand Up @@ -98,10 +108,8 @@ interface WDL {
// #region variable
let timer = ref(null);
const grabWordInput = ref(null);
let groupID = ref('');
const router = useRouter();
let activeNames = ref([]);
let wordDescription: Ref<WD>;
let audioUrl = ref('https://dict.youdao.com/dictvoice?type=1&audio=');
let originUrl = ref('https://dict.youdao.com/dictvoice?type=1&audio=');
const form: Ref<WDL> = ref({
Expand Down Expand Up @@ -134,14 +142,6 @@ onMounted(() => {
}
}, 1200);
});
wordDescription = ref({
englishDescription: '',
partOfSpeech: '',
level: '',
chineseDescription: '',
sentence: '',
group: '',
});
getDefaultGroup();
getGroupList();
});
Expand Down

0 comments on commit 9b2ce1b

Please sign in to comment.