From a17f3e825cea8762d4b6a87d2cfe5135f9077149 Mon Sep 17 00:00:00 2001 From: cuixiaorui Date: Wed, 24 Jan 2024 17:49:02 +0800 Subject: [PATCH] feat: implementation summary and refactor code --- apps/api/src/course/course.controller.ts | 12 +- apps/api/src/course/course.service.ts | 64 +- apps/client/README.md | 9 + apps/client/api/courses.ts | 11 +- apps/client/components/main/Answer.vue | 71 +- apps/client/components/main/Game.vue | 21 +- apps/client/components/main/Question.vue | 24 +- apps/client/components/main/Summary.vue | 50 + apps/client/components/main/Tips.vue | 27 +- apps/client/components/main/game.ts | 18 + apps/client/components/main/summary.ts | 16 + apps/client/composables/useEnglishSound.ts | 20 +- apps/client/nuxt.config.ts | 1 + apps/client/package.json | 7 +- apps/client/pages/Main/[id].vue | 5 +- apps/client/pages/index.vue | 82 +- apps/client/store/courses.ts | 25 +- apps/client/tests/helper/fireEvent.ts | 5 + apps/client/utils/keyboardShortcuts.ts | 78 + .../utils/tests/keyboardShortcuts.spec.ts | 69 + apps/client/vitest.config.ts | 7 + pnpm-lock.yaml | 11418 ++++++---------- 22 files changed, 4448 insertions(+), 7592 deletions(-) create mode 100644 apps/client/components/main/Summary.vue create mode 100644 apps/client/components/main/game.ts create mode 100644 apps/client/components/main/summary.ts create mode 100644 apps/client/tests/helper/fireEvent.ts create mode 100644 apps/client/utils/keyboardShortcuts.ts create mode 100644 apps/client/utils/tests/keyboardShortcuts.spec.ts create mode 100644 apps/client/vitest.config.ts diff --git a/apps/api/src/course/course.controller.ts b/apps/api/src/course/course.controller.ts index 9d1cba0ba..0e4e6a3f9 100644 --- a/apps/api/src/course/course.controller.ts +++ b/apps/api/src/course/course.controller.ts @@ -6,7 +6,17 @@ export class CourseController { constructor(private courseService: CourseService) {} @Get(':courseId') - getStatements(@Param('courseId') courseId: number) { + findOne(@Param('courseId') courseId: number) { return this.courseService.find(courseId); } + + @Get('') + findAll() { + return this.courseService.findAll(); + } + + @Get(':courseId/next') + findNext(@Param('courseId') courseId: number) { + return this.courseService.findNext(courseId); + } } diff --git a/apps/api/src/course/course.service.ts b/apps/api/src/course/course.service.ts index 79981e922..046897f71 100644 --- a/apps/api/src/course/course.service.ts +++ b/apps/api/src/course/course.service.ts @@ -1,12 +1,50 @@ import { DB, DbType } from '../global/providers/db.provider'; -import { eq, asc } from 'drizzle-orm'; +import { eq, asc, gt } from 'drizzle-orm'; import { statement, course } from '@earthwrom/shared'; -import { Injectable, Inject } from '@nestjs/common'; +import { Injectable, Inject, HttpException, HttpStatus } from '@nestjs/common'; @Injectable() export class CourseService { constructor(@Inject(DB) private db: DbType) {} + async findNext(courseId: number) { + const result = await this.db + .select({ id: course.id, title: course.title }) + .from(course) + .where(gt(course.id, courseId)) + .orderBy(asc(course.id)); + + if (result.length < 0) { + throw new HttpException( + 'There is no next course', + HttpStatus.BAD_REQUEST, + ); + } + + const nextCourse = result[0]; + + const statementsResult = await this.findStatements(nextCourse.id); + + const finalResult = { + id: nextCourse.id, + title: nextCourse.title, + statements: statementsResult, + }; + + return finalResult; + } + + async findAll() { + const courseResult = await this.db + .select({ + id: course.id, + title: course.title, + }) + .from(course); + + return courseResult; + } + async find(courseId: number) { const courseResult = await this.db .select({ @@ -16,7 +54,19 @@ export class CourseService { .from(course) .where(eq(course.id, courseId)); - const statementsResult = await this.db + const statementsResult = await this.findStatements(courseId); + + const finalResult = { + id: courseResult[0].id, + title: courseResult[0].title, + statements: statementsResult, + }; + + return finalResult; + } + + private async findStatements(courseId) { + return await this.db .select({ id: statement.id, chinese: statement.chinese, @@ -26,13 +76,5 @@ export class CourseService { .from(statement) .where(eq(statement.courseId, courseId)) .orderBy(asc(statement.order)); - - const finalResult = { - id: courseResult[0].id, - title: courseResult[0].title, - statements: statementsResult, - }; - - return finalResult; } } diff --git a/apps/client/README.md b/apps/client/README.md index f5db2a2db..fa1343a95 100644 --- a/apps/client/README.md +++ b/apps/client/README.md @@ -73,3 +73,12 @@ bun run preview ``` Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information. + + + + +## 开发规范 + +1. 不要解构 pinia 的 store + - 解构会导致响应式丢失问题(ref 类型也会变成普通类型) + - 带上 store 的话 代码可读性也更好一点 一眼就能知道数据的来源是哪里 \ No newline at end of file diff --git a/apps/client/api/courses.ts b/apps/client/api/courses.ts index a0fbd86a2..f788e41a7 100644 --- a/apps/client/api/courses.ts +++ b/apps/client/api/courses.ts @@ -3,11 +3,18 @@ import { useFetchPlus } from "~/composables/useFetch"; interface Course { title: string; id: number; + statements: Array; } export async function fetchCourse(courseId: number) { - const { data: courses } = await useFetchPlus( - `/courses/${courseId}` + const { data: courses } = await useFetchPlus(`/courses/${courseId}`); + + return courses; +} + +export async function fetchNextCourse(courseId: number) { + const { data: courses } = await useFetchPlus( + `/courses/${courseId}/next` ); return courses; diff --git a/apps/client/components/main/Answer.vue b/apps/client/components/main/Answer.vue index acd2dafe4..fcbde10ea 100644 --- a/apps/client/components/main/Answer.vue +++ b/apps/client/components/main/Answer.vue @@ -27,51 +27,64 @@ diff --git a/apps/client/components/main/Game.vue b/apps/client/components/main/Game.vue index 2542c1f09..c62c5a351 100644 --- a/apps/client/components/main/Game.vue +++ b/apps/client/components/main/Game.vue @@ -2,16 +2,17 @@
- +
+
@@ -19,17 +20,13 @@ import Question from "./Question.vue"; import Answer from "./Answer.vue"; import CourseProgress from "./CourseProgress.vue"; -import Tips from './Tips.vue'; +import Summary from "./Summary.vue"; +import Tips from "./Tips.vue"; +import { useMode } from "./game"; -const mode = ref<"question" | "answer">("question"); +const { mode } = useMode(); -function handleBingo() { - mode.value = "answer"; -} - -function handleNextQuestion() { - mode.value = "question"; -} +const showModal = ref(false); diff --git a/apps/client/components/main/Question.vue b/apps/client/components/main/Question.vue index 3ba7a6349..5315f5ba9 100644 --- a/apps/client/components/main/Question.vue +++ b/apps/client/components/main/Question.vue @@ -1,7 +1,9 @@ diff --git a/apps/client/pages/index.vue b/apps/client/pages/index.vue index cb88fa121..52f8b22fa 100644 --- a/apps/client/pages/index.vue +++ b/apps/client/pages/index.vue @@ -1,55 +1,85 @@