From 3ec854519ef1751942775462278662333c836d23 Mon Sep 17 00:00:00 2001 From: BaboonKing Date: Tue, 14 May 2024 20:13:48 +0800 Subject: [PATCH 01/24] feat: add get User by username of API --- apps/api/src/user/user.controller.ts | 7 ++++++- apps/api/src/user/user.service.ts | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/apps/api/src/user/user.controller.ts b/apps/api/src/user/user.controller.ts index a8d3820c..36772c7b 100644 --- a/apps/api/src/user/user.controller.ts +++ b/apps/api/src/user/user.controller.ts @@ -1,4 +1,4 @@ -import { Body, Controller, Get, Patch, Post, UseGuards } from "@nestjs/common"; +import { Body, Controller, Get, Param, Patch, Post, UseGuards } from "@nestjs/common"; import { AuthGuard } from "../guards/auth.guard"; import { User, UserEntity } from "../user/user.decorators"; @@ -21,6 +21,11 @@ export class UserController { return userInfo; } + @Get(":username") + getUserByUsername(@Param("username") username: string) { + return this.userService.getUserByUsername(username); + } + // 给新用户第一次登录使用 // 目前使用 email 和 github 登录的用户 都不存在 username // 所以这个接口有两个目的 diff --git a/apps/api/src/user/user.service.ts b/apps/api/src/user/user.service.ts index 037b359b..422e38b9 100644 --- a/apps/api/src/user/user.service.ts +++ b/apps/api/src/user/user.service.ts @@ -69,6 +69,25 @@ export class UserService { throw new HttpException(e.response.data.message, e.response.status); } } + async getUserByUsername(username: string) { + const params = new URLSearchParams([ + ["page", "1"], + ["page_size", "1"], + ["search.username", username], + ]).toString(); + + try { + const res = await this.logtoService.logtoApi.get(`/api/users/?${params}`); + if (res.status === 200) { + const user = res.data.at(0); + return user; + } else { + return res.data; + } + } catch (e) { + throw new HttpException(e.response.data.message, e.response.status); + } + } async setupNewUser(user: UserEntity, dto: { username: string; avatar: string }) { if (!dto.avatar) { From 92c98b603cb7d7dbde555f43efc1bf392f4a20ba Mon Sep 17 00:00:00 2001 From: BaboonKing Date: Fri, 24 May 2024 16:52:16 +0800 Subject: [PATCH 02/24] feat: view other people's homepages --- apps/client/api/user.ts | 4 ++ apps/client/pages/User/[username].vue | 79 +++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 apps/client/pages/User/[username].vue diff --git a/apps/client/api/user.ts b/apps/client/api/user.ts index cb3d0f9d..ece9d293 100644 --- a/apps/client/api/user.ts +++ b/apps/client/api/user.ts @@ -18,3 +18,7 @@ export async function fetchCurrentUser() { avatar: logtoUserInfo!.picture || "", // 添加 avatar 字段,默认值为 picture ( picture 这个属性不够清晰 不喜欢) } as User; } +export async function getUserByUsername(username: string) { + // `/user/username/${username}` is better ? + return await http.get(`/user/${username}`); +} diff --git a/apps/client/pages/User/[username].vue b/apps/client/pages/User/[username].vue new file mode 100644 index 00000000..671ef6b0 --- /dev/null +++ b/apps/client/pages/User/[username].vue @@ -0,0 +1,79 @@ + + + + + From d0c93994761da2e278f5de9224033b46c5c398e3 Mon Sep 17 00:00:00 2001 From: BaboonKing Date: Fri, 24 May 2024 17:17:35 +0800 Subject: [PATCH 03/24] feat: recentCoursePacks support UserId --- .../user-course-progress.controller.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/apps/api/src/user-course-progress/user-course-progress.controller.ts b/apps/api/src/user-course-progress/user-course-progress.controller.ts index 743ec4a6..cec3336f 100644 --- a/apps/api/src/user-course-progress/user-course-progress.controller.ts +++ b/apps/api/src/user-course-progress/user-course-progress.controller.ts @@ -22,6 +22,18 @@ export class UserProgressController { return recentCoursePacks; } + @Get("/recent-course-packs-by-user-id") + async getUserRecentCoursePacksByUserId( + @Query("userId") userId?: string, + @Query("limit") limit?: number, + ) { + const recentCoursePacks = await this.userCourseProgressService.getUserRecentCoursePacks( + userId, + limit || 4, + ); + return recentCoursePacks; + } + @UseGuards(AuthGuard) @Put() async upsert(@User() user: UserEntity, @Body() dto: UpsertUserProgressDto) { From 69302b03f02639945d0ff15f79078e750835da8a Mon Sep 17 00:00:00 2001 From: BaboonKing Date: Fri, 24 May 2024 17:19:22 +0800 Subject: [PATCH 04/24] feat: finishCount support UserId --- .../src/user-learn-record/user-learn-record.controller.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/api/src/user-learn-record/user-learn-record.controller.ts b/apps/api/src/user-learn-record/user-learn-record.controller.ts index a809757e..89865d73 100644 --- a/apps/api/src/user-learn-record/user-learn-record.controller.ts +++ b/apps/api/src/user-learn-record/user-learn-record.controller.ts @@ -14,4 +14,9 @@ export class UserLearnRecordController { finishCount(@User() user: UserEntity, @Query() dto?: GetUserLearnRecordDto) { return this.userLearnRecordService.find(user.userId, dto); } + + @Get("finishCountByUserId") + finishCountByUserId(@Query("userId") userId: string, @Query() dto?: GetUserLearnRecordDto) { + return this.userLearnRecordService.find(userId, dto); + } } From 3ce1cb3062e9ee0345396ed0a57d97db1f958726 Mon Sep 17 00:00:00 2001 From: BaboonKing Date: Fri, 24 May 2024 18:53:16 +0800 Subject: [PATCH 05/24] feat: home page redirect to user's HomePage --- apps/client/components/Home/index.vue | 78 ++------------------------- apps/client/pages/index.vue | 4 +- apps/client/services/auth.ts | 7 +++ 3 files changed, 14 insertions(+), 75 deletions(-) diff --git a/apps/client/components/Home/index.vue b/apps/client/components/Home/index.vue index 9ddc76a3..3f8551af 100644 --- a/apps/client/components/Home/index.vue +++ b/apps/client/components/Home/index.vue @@ -1,82 +1,14 @@ - + diff --git a/apps/client/pages/index.vue b/apps/client/pages/index.vue index 447f54da..fe7fe9b7 100644 --- a/apps/client/pages/index.vue +++ b/apps/client/pages/index.vue @@ -1,8 +1,8 @@ diff --git a/apps/client/services/auth.ts b/apps/client/services/auth.ts index 5edc9af3..04b2548e 100644 --- a/apps/client/services/auth.ts +++ b/apps/client/services/auth.ts @@ -1,6 +1,8 @@ import { useLogto } from "@logto/vue"; import { useRuntimeConfig } from "nuxt/app"; +import { useUserStore } from "~/store/user"; + let logto: ReturnType; let runtimeConfig: ReturnType; export async function setupAuth() { @@ -21,6 +23,11 @@ export function isAuthenticated() { return logto.isAuthenticated.value; } +export function isUserLoaded() { + const userStore = useUserStore(); + return Boolean(userStore.userInfo); +} + export async function getToken() { const accessToken = await logto.getAccessToken(runtimeConfig.public.backendEndpoint); From 902ea2fb9012858bc7cb384406203c7b149f7411 Mon Sep 17 00:00:00 2001 From: BaboonKing Date: Fri, 24 May 2024 19:05:06 +0800 Subject: [PATCH 06/24] feat: RecentCoursePack fellow username --- apps/client/api/userCourseProgress.ts | 12 ++++++++++++ .../components/Home/RecentCoursePack.vue | 18 +++++++++++++++--- apps/client/components/Home/helper.ts | 13 ++++++++++--- apps/client/pages/User/[username].vue | 2 +- 4 files changed, 38 insertions(+), 7 deletions(-) diff --git a/apps/client/api/userCourseProgress.ts b/apps/client/api/userCourseProgress.ts index ec7385ac..0422a636 100644 --- a/apps/client/api/userCourseProgress.ts +++ b/apps/client/api/userCourseProgress.ts @@ -31,3 +31,15 @@ export async function fetchUserRecentCoursePacks() { `/user-course-progress/recent-course-packs`, ); } + +export async function fetchUserRecentCoursePacksByUserId(userId: string, limit = 4) { + return await http.get( + `/user-course-progress/recent-course-packs-by-user-id`, + { + params: { + userId, + limit, + }, + }, + ); +} diff --git a/apps/client/components/Home/RecentCoursePack.vue b/apps/client/components/Home/RecentCoursePack.vue index 9f6b7c1b..75b5a227 100644 --- a/apps/client/components/Home/RecentCoursePack.vue +++ b/apps/client/components/Home/RecentCoursePack.vue @@ -29,7 +29,10 @@

{{ coursePack.description }}

-
+
- + Date: Fri, 24 May 2024 19:05:36 +0800 Subject: [PATCH 07/24] chore: merge code --- apps/client/pages/User/[username].vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/client/pages/User/[username].vue b/apps/client/pages/User/[username].vue index e5afde8d..4a332492 100644 --- a/apps/client/pages/User/[username].vue +++ b/apps/client/pages/User/[username].vue @@ -11,7 +11,7 @@
{{ user?.username }}
- {{ user?.name || "未设置" }} + {{ user?.name }}

From 818ef53865a558e23e5006f6f12ffb9054acc0f8 Mon Sep 17 00:00:00 2001 From: BaboonKing Date: Fri, 24 May 2024 19:41:17 +0800 Subject: [PATCH 08/24] feat: CalendarGraph data follow username --- apps/client/api/userLearnRecord.ts | 9 +++++ apps/client/composables/learnRecord.ts | 56 +++++++++++++------------- apps/client/pages/User/[username].vue | 25 +++--------- 3 files changed, 41 insertions(+), 49 deletions(-) diff --git a/apps/client/api/userLearnRecord.ts b/apps/client/api/userLearnRecord.ts index 6aba035e..c82c8912 100644 --- a/apps/client/api/userLearnRecord.ts +++ b/apps/client/api/userLearnRecord.ts @@ -18,3 +18,12 @@ export async function fetchLearnRecord(params: UserLearnRecord) { }, ); } + +export async function fetchLearnRecordByUserId(params: UserLearnRecord & { userId: string }) { + return await http.get( + `/user-learn-record/finishCountByUserId`, + { + params, + }, + ); +} diff --git a/apps/client/composables/learnRecord.ts b/apps/client/composables/learnRecord.ts index c4491abe..32fcc80a 100644 --- a/apps/client/composables/learnRecord.ts +++ b/apps/client/composables/learnRecord.ts @@ -1,46 +1,44 @@ -import { ref } from "vue"; +import type { MaybeRef } from "vue"; + +import { ref, toValue, watchEffect } from "vue"; import type { UserLearnRecordResponse } from "~/api/userLearnRecord"; -import { fetchLearnRecord } from "~/api/userLearnRecord"; - -let year: number | undefined = 0; -const learnRecord = ref({ - list: [], - totalCount: 0, -}); -let isSetup = false; - -export function useLearnRecord() { - function setQueryYear(val?: number) { - if (year !== val) { - year = val; - isSetup = false; - } - } +import { fetchLearnRecordByUserId } from "~/api/userLearnRecord"; + +interface UseLearnRecordOptions { + year?: MaybeRef; + userId: string; +} + +export function useLearnRecord(options: UseLearnRecordOptions) { + const { userId } = options || {}; + const learnRecord = ref({ + list: [], + totalCount: 0, + }); + + const year = ref(options.year || new Date().getFullYear()); function getQuery() { + const yearStr = toValue(year); return { - startDate: year ? `${year}-01-01` : undefined, - endDate: year ? `${year}-12-31` : undefined, + userId, + startDate: yearStr ? `${yearStr}-01-01` : undefined, + endDate: yearStr ? `${yearStr}-12-31` : undefined, }; } async function updateLearnRecord() { - const res = await fetchLearnRecord(getQuery()); - learnRecord.value = res; - } - - async function setupLearnRecord() { - if (isSetup) return; - isSetup = true; - const res = await fetchLearnRecord(getQuery()); + const res = await fetchLearnRecordByUserId(getQuery()); learnRecord.value = res; } + watchEffect(() => { + updateLearnRecord(); + }); return { + year, learnRecord, updateLearnRecord, - setQueryYear, - setupLearnRecord, }; } diff --git a/apps/client/pages/User/[username].vue b/apps/client/pages/User/[username].vue index 4a332492..32b884e9 100644 --- a/apps/client/pages/User/[username].vue +++ b/apps/client/pages/User/[username].vue @@ -40,7 +40,7 @@ class="mt-10" :data="learnRecord.list" :totalCount="learnRecord.totalCount" - @toggleYear="toggleYear" + @toggleYear="onToggleYear" />
@@ -48,32 +48,17 @@ From b757165b852f56be5f87492f1e34ef2d8d86fcfc Mon Sep 17 00:00:00 2001 From: BaboonKing Date: Fri, 24 May 2024 20:02:09 +0800 Subject: [PATCH 09/24] chore: RankingList to homepage of user --- apps/client/components/rank/RankingItem.vue | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/apps/client/components/rank/RankingItem.vue b/apps/client/components/rank/RankingItem.vue index 1749a46c..6f202608 100644 --- a/apps/client/components/rank/RankingItem.vue +++ b/apps/client/components/rank/RankingItem.vue @@ -6,15 +6,30 @@ class="w-16" :rank="rank" /> -
{{ username || "匿名" }}
+
+ {{ username || "匿名" }} +
{{ count }} 课
From 70acc897a7cd9a6325f9ab28ab6fd0399a205a96 Mon Sep 17 00:00:00 2001 From: BaboonKing Date: Sat, 25 May 2024 23:58:27 +0800 Subject: [PATCH 10/24] refactor: /user/:username to /:username --- apps/client/components/Home/index.vue | 2 +- apps/client/components/rank/RankingItem.vue | 4 ++-- apps/client/pages/{User => }/[username].vue | 0 3 files changed, 3 insertions(+), 3 deletions(-) rename apps/client/pages/{User => }/[username].vue (100%) diff --git a/apps/client/components/Home/index.vue b/apps/client/components/Home/index.vue index 3f8551af..ecd5bea4 100644 --- a/apps/client/components/Home/index.vue +++ b/apps/client/components/Home/index.vue @@ -8,7 +8,7 @@ const userStore = useUserStore(); const username = userStore.userInfo?.username; const router = useRouter(); -router.replace(`/user/${username}`); +router.replace(`/${username}`); diff --git a/apps/client/components/rank/RankingItem.vue b/apps/client/components/rank/RankingItem.vue index 6f202608..ad5276e1 100644 --- a/apps/client/components/rank/RankingItem.vue +++ b/apps/client/components/rank/RankingItem.vue @@ -26,10 +26,10 @@ const props = defineProps({ }); const router = useRouter(); const toUserHomePage = () => { - const { href } = router.resolve(`/user/${props.username}`); + const { href } = router.resolve(`/${props.username}`); window.location.href = href; //TODO: use route - // router.push(`/user/${props.username}`); + // router.push(`/${props.username}`); }; diff --git a/apps/client/pages/User/[username].vue b/apps/client/pages/[username].vue similarity index 100% rename from apps/client/pages/User/[username].vue rename to apps/client/pages/[username].vue From 009b87c572b6b75a9fe2e559c8a8728fba7cad37 Mon Sep 17 00:00:00 2001 From: BaboonKing Date: Sun, 26 May 2024 00:10:49 +0800 Subject: [PATCH 11/24] chore: remove /recent-course-packs-by-user-id API --- .../user-course-progress.controller.ts | 17 ++--------------- apps/client/api/userCourseProgress.ts | 10 ++-------- apps/client/components/Home/helper.ts | 4 ++-- 3 files changed, 6 insertions(+), 25 deletions(-) diff --git a/apps/api/src/user-course-progress/user-course-progress.controller.ts b/apps/api/src/user-course-progress/user-course-progress.controller.ts index cec3336f..f0868829 100644 --- a/apps/api/src/user-course-progress/user-course-progress.controller.ts +++ b/apps/api/src/user-course-progress/user-course-progress.controller.ts @@ -12,24 +12,11 @@ import { UserCourseProgressService } from "./user-course-progress.service"; export class UserProgressController { constructor(private readonly userCourseProgressService: UserCourseProgressService) {} - @UseGuards(AuthGuard) @Get("/recent-course-packs") - async getUserRecentCoursePacks(@User() user: UserEntity, @Query("limit") limit: number) { - const recentCoursePacks = await this.userCourseProgressService.getUserRecentCoursePacks( - user.userId, - limit || 3, - ); - return recentCoursePacks; - } - - @Get("/recent-course-packs-by-user-id") - async getUserRecentCoursePacksByUserId( - @Query("userId") userId?: string, - @Query("limit") limit?: number, - ) { + async getUserRecentCoursePacks(@Query("userId") userId?: string, @Query("limit") limit?: number) { const recentCoursePacks = await this.userCourseProgressService.getUserRecentCoursePacks( userId, - limit || 4, + limit || 3, ); return recentCoursePacks; } diff --git a/apps/client/api/userCourseProgress.ts b/apps/client/api/userCourseProgress.ts index 0422a636..0ce5f156 100644 --- a/apps/client/api/userCourseProgress.ts +++ b/apps/client/api/userCourseProgress.ts @@ -26,15 +26,9 @@ export async function fetchUpdateCourseProgress(userProgressUpdate: UserProgress ); } -export async function fetchUserRecentCoursePacks() { - return await http.get( - `/user-course-progress/recent-course-packs`, - ); -} - -export async function fetchUserRecentCoursePacksByUserId(userId: string, limit = 4) { +export async function fetchUserRecentCoursePacks(userId: string, limit = 4) { return await http.get( - `/user-course-progress/recent-course-packs-by-user-id`, + `/user-course-progress/recent-course-packs`, { params: { userId, diff --git a/apps/client/components/Home/helper.ts b/apps/client/components/Home/helper.ts index c5b4a327..0a1c6e42 100644 --- a/apps/client/components/Home/helper.ts +++ b/apps/client/components/Home/helper.ts @@ -1,7 +1,7 @@ import { ref } from "vue"; import type { UserRecentCoursePackResponse } from "~/api/userCourseProgress"; -import { fetchUserRecentCoursePacksByUserId } from "~/api/userCourseProgress"; +import { fetchUserRecentCoursePacks } from "~/api/userCourseProgress"; const coursePacks = ref([]); @@ -14,7 +14,7 @@ export function useRecentCoursePack(options: UseRecentCoursePackOptions) { const { userId, limit = 4 } = options || {}; async function fetchCoursePacks() { - coursePacks.value = await fetchUserRecentCoursePacksByUserId(userId, limit); + coursePacks.value = await fetchUserRecentCoursePacks(userId, limit); } return { From 7d3944baa30ce92f7a92d85a54ca2d4b967973d4 Mon Sep 17 00:00:00 2001 From: BaboonKing Date: Sun, 26 May 2024 00:15:43 +0800 Subject: [PATCH 12/24] chore: remove finishCountByUserId API --- .../user-learn-record.controller.ts | 8 +------- apps/client/api/userLearnRecord.ts | 20 ++++--------------- apps/client/composables/learnRecord.ts | 4 ++-- 3 files changed, 7 insertions(+), 25 deletions(-) diff --git a/apps/api/src/user-learn-record/user-learn-record.controller.ts b/apps/api/src/user-learn-record/user-learn-record.controller.ts index 89865d73..06e47819 100644 --- a/apps/api/src/user-learn-record/user-learn-record.controller.ts +++ b/apps/api/src/user-learn-record/user-learn-record.controller.ts @@ -9,14 +9,8 @@ import { UserLearnRecordService } from "./user-learn-record.service"; export class UserLearnRecordController { constructor(private userLearnRecordService: UserLearnRecordService) {} - @UseGuards(AuthGuard) @Get("finishCount") - finishCount(@User() user: UserEntity, @Query() dto?: GetUserLearnRecordDto) { - return this.userLearnRecordService.find(user.userId, dto); - } - - @Get("finishCountByUserId") - finishCountByUserId(@Query("userId") userId: string, @Query() dto?: GetUserLearnRecordDto) { + finishCount(@Query("userId") userId: string, @Query() dto?: GetUserLearnRecordDto) { return this.userLearnRecordService.find(userId, dto); } } diff --git a/apps/client/api/userLearnRecord.ts b/apps/client/api/userLearnRecord.ts index c82c8912..36c3d5c5 100644 --- a/apps/client/api/userLearnRecord.ts +++ b/apps/client/api/userLearnRecord.ts @@ -10,20 +10,8 @@ export interface UserLearnRecordResponse { list: Array<{ day: string; count: number }>; } -export async function fetchLearnRecord(params: UserLearnRecord) { - return await http.get( - `/user-learn-record/finishCount`, - { - params, - }, - ); -} - -export async function fetchLearnRecordByUserId(params: UserLearnRecord & { userId: string }) { - return await http.get( - `/user-learn-record/finishCountByUserId`, - { - params, - }, - ); +export async function fetchLearnRecord(params: UserLearnRecord & { userId: string }) { + return await http.get(`/user-learn-record/finishCount`, { + params, + }); } diff --git a/apps/client/composables/learnRecord.ts b/apps/client/composables/learnRecord.ts index 32fcc80a..952a35c7 100644 --- a/apps/client/composables/learnRecord.ts +++ b/apps/client/composables/learnRecord.ts @@ -3,7 +3,7 @@ import type { MaybeRef } from "vue"; import { ref, toValue, watchEffect } from "vue"; import type { UserLearnRecordResponse } from "~/api/userLearnRecord"; -import { fetchLearnRecordByUserId } from "~/api/userLearnRecord"; +import { fetchLearnRecord } from "~/api/userLearnRecord"; interface UseLearnRecordOptions { year?: MaybeRef; @@ -29,7 +29,7 @@ export function useLearnRecord(options: UseLearnRecordOptions) { } async function updateLearnRecord() { - const res = await fetchLearnRecordByUserId(getQuery()); + const res = await fetchLearnRecord(getQuery()); learnRecord.value = res; } watchEffect(() => { From 642247e4d52c22596c5aebd8629a7eb11b1ab579 Mon Sep 17 00:00:00 2001 From: BaboonKing Date: Sun, 26 May 2024 00:24:43 +0800 Subject: [PATCH 13/24] chore: optimize code of isSelf --- apps/client/components/Home/RecentCoursePack.vue | 2 +- apps/client/store/user.ts | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/apps/client/components/Home/RecentCoursePack.vue b/apps/client/components/Home/RecentCoursePack.vue index 75b5a227..6544e996 100644 --- a/apps/client/components/Home/RecentCoursePack.vue +++ b/apps/client/components/Home/RecentCoursePack.vue @@ -77,7 +77,7 @@ const { coursePacks, fetchCoursePacks } = useRecentCoursePack({ userId: props.us const userStore = useUserStore(); -const isSelf = computed(() => userStore.userInfo?.sub === props.userId); +const isSelf = userStore.isSelf(props.userId); const isLoading = ref(false); diff --git a/apps/client/store/user.ts b/apps/client/store/user.ts index b0f45bcf..160c7a8a 100644 --- a/apps/client/store/user.ts +++ b/apps/client/store/user.ts @@ -1,5 +1,7 @@ +import type { MaybeRefOrGetter } from "vue"; + import { defineStore } from "pinia"; -import { ref } from "vue"; +import { computed, ref, toValue } from "vue"; import type { User } from "~/types"; import { fetchSetupNewUser } from "~/api/user"; @@ -12,6 +14,12 @@ export const useUserStore = defineStore("user", () => { user.value = val; } + function isSelf(userId: MaybeRefOrGetter) { + return computed(() => { + return user.value?.sub === toValue(userId); + }); + } + function isNewUser() { return !user.value?.username || !user.value?.avatar; } @@ -38,5 +46,6 @@ export const useUserStore = defineStore("user", () => { initUser, setupNewUser, isFounderMembership, + isSelf, }; }); From 600dd080d1d37040f1d3d662de973b365770d2ac Mon Sep 17 00:00:00 2001 From: BaboonKing Date: Sun, 26 May 2024 00:34:22 +0800 Subject: [PATCH 14/24] feat: open new tab for other users --- apps/client/components/rank/RankingItem.vue | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/apps/client/components/rank/RankingItem.vue b/apps/client/components/rank/RankingItem.vue index ad5276e1..13e044dc 100644 --- a/apps/client/components/rank/RankingItem.vue +++ b/apps/client/components/rank/RankingItem.vue @@ -27,9 +27,6 @@ const props = defineProps({ const router = useRouter(); const toUserHomePage = () => { const { href } = router.resolve(`/${props.username}`); - window.location.href = href; - - //TODO: use route - // router.push(`/${props.username}`); + window.open(href, "_blank"); }; From eaa246307e06aaa2af0fd4cac07ffa35529e5831 Mon Sep 17 00:00:00 2001 From: BaboonKing Date: Sun, 26 May 2024 00:43:12 +0800 Subject: [PATCH 15/24] feat: add tips for username on ranking list --- apps/client/components/rank/RankingItem.vue | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/client/components/rank/RankingItem.vue b/apps/client/components/rank/RankingItem.vue index 13e044dc..7a0c518b 100644 --- a/apps/client/components/rank/RankingItem.vue +++ b/apps/client/components/rank/RankingItem.vue @@ -7,8 +7,10 @@ :rank="rank" />
{{ username || "匿名" }}
From 0b5803306c0f90b81cb21846df8d2ddc8ed20c00 Mon Sep 17 00:00:00 2001 From: BaboonKing Date: Sun, 26 May 2024 00:47:33 +0800 Subject: [PATCH 16/24] fix: error --- apps/client/composables/learnRecord.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/client/composables/learnRecord.ts b/apps/client/composables/learnRecord.ts index 952a35c7..0ca35663 100644 --- a/apps/client/composables/learnRecord.ts +++ b/apps/client/composables/learnRecord.ts @@ -17,7 +17,7 @@ export function useLearnRecord(options: UseLearnRecordOptions) { totalCount: 0, }); - const year = ref(options.year || new Date().getFullYear()); + const year = ref(options?.year || new Date().getFullYear()); function getQuery() { const yearStr = toValue(year); From d52574e45be40ffd637cb1e3ba3c56f494a293e0 Mon Sep 17 00:00:00 2001 From: BaboonKing Date: Sun, 26 May 2024 00:52:47 +0800 Subject: [PATCH 17/24] chore: remove Invalid code --- apps/api/src/user/user.service.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/apps/api/src/user/user.service.ts b/apps/api/src/user/user.service.ts index 422e38b9..2a12eccb 100644 --- a/apps/api/src/user/user.service.ts +++ b/apps/api/src/user/user.service.ts @@ -70,11 +70,7 @@ export class UserService { } } async getUserByUsername(username: string) { - const params = new URLSearchParams([ - ["page", "1"], - ["page_size", "1"], - ["search.username", username], - ]).toString(); + const params = new URLSearchParams([["search.username", username]]).toString(); try { const res = await this.logtoService.logtoApi.get(`/api/users/?${params}`); From 1d7afd36081457a66d9d2cd17e6f1095df076750 Mon Sep 17 00:00:00 2001 From: BaboonKing Date: Sun, 26 May 2024 01:07:14 +0800 Subject: [PATCH 18/24] =?UTF-8?q?feat:=20hide=20=E6=9B=B4=E5=A4=9A?= =?UTF-8?q?=E8=AF=BE=E7=A8=8B=E5=8C=85=20on=20not=20self?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/client/pages/[username].vue | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/client/pages/[username].vue b/apps/client/pages/[username].vue index 32b884e9..f5dfd688 100644 --- a/apps/client/pages/[username].vue +++ b/apps/client/pages/[username].vue @@ -30,9 +30,11 @@
最近使用的课程包
更多课程包 + > + 更多课程包
@@ -51,9 +53,11 @@ import { useRoute } from "#app"; import { getUserByUsername } from "~/api/user"; import { useLearnRecord } from "~/composables/learnRecord"; +import { useUserStore } from "~/store/user"; const route = useRoute(); const user = await getUserByUsername(route.params.username as string); +const isSelf = useUserStore().isSelf(() => user?.id); const { learnRecord, year } = useLearnRecord({ userId: user?.id }); const onToggleYear = (value?: number) => { From 1e5f5638692326b1f99d61e402a8badfe0e6b496 Mon Sep 17 00:00:00 2001 From: BaboonKing Date: Sun, 26 May 2024 01:41:36 +0800 Subject: [PATCH 19/24] feat: current user homepage on root path --- apps/client/components/Home/index.vue | 14 ---- .../{Home => user-home}/CalendarGraph.vue | 0 .../{Home => user-home}/RecentCoursePack.vue | 0 .../components/{Home => user-home}/helper.ts | 0 apps/client/components/user-home/index.vue | 73 +++++++++++++++++++ apps/client/pages/[username].vue | 60 +-------------- apps/client/pages/index.vue | 8 +- 7 files changed, 82 insertions(+), 73 deletions(-) delete mode 100644 apps/client/components/Home/index.vue rename apps/client/components/{Home => user-home}/CalendarGraph.vue (100%) rename apps/client/components/{Home => user-home}/RecentCoursePack.vue (100%) rename apps/client/components/{Home => user-home}/helper.ts (100%) create mode 100644 apps/client/components/user-home/index.vue diff --git a/apps/client/components/Home/index.vue b/apps/client/components/Home/index.vue deleted file mode 100644 index ecd5bea4..00000000 --- a/apps/client/components/Home/index.vue +++ /dev/null @@ -1,14 +0,0 @@ - - - - diff --git a/apps/client/components/Home/CalendarGraph.vue b/apps/client/components/user-home/CalendarGraph.vue similarity index 100% rename from apps/client/components/Home/CalendarGraph.vue rename to apps/client/components/user-home/CalendarGraph.vue diff --git a/apps/client/components/Home/RecentCoursePack.vue b/apps/client/components/user-home/RecentCoursePack.vue similarity index 100% rename from apps/client/components/Home/RecentCoursePack.vue rename to apps/client/components/user-home/RecentCoursePack.vue diff --git a/apps/client/components/Home/helper.ts b/apps/client/components/user-home/helper.ts similarity index 100% rename from apps/client/components/Home/helper.ts rename to apps/client/components/user-home/helper.ts diff --git a/apps/client/components/user-home/index.vue b/apps/client/components/user-home/index.vue new file mode 100644 index 00000000..fb0d7ce5 --- /dev/null +++ b/apps/client/components/user-home/index.vue @@ -0,0 +1,73 @@ + + + + + diff --git a/apps/client/pages/[username].vue b/apps/client/pages/[username].vue index f5dfd688..add65434 100644 --- a/apps/client/pages/[username].vue +++ b/apps/client/pages/[username].vue @@ -1,68 +1,12 @@ diff --git a/apps/client/pages/index.vue b/apps/client/pages/index.vue index fe7fe9b7..2f5ebf9c 100644 --- a/apps/client/pages/index.vue +++ b/apps/client/pages/index.vue @@ -1,8 +1,14 @@ From 82af7a3170b0350793bc1934634531768d82b760 Mon Sep 17 00:00:00 2001 From: BaboonKing Date: Sun, 26 May 2024 02:09:57 +0800 Subject: [PATCH 20/24] fix: test error of recent-course-packs --- .../tests/user-course-progress.e2e-spec.ts | 6 ++++-- apps/api/test/fixture/db.ts | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/api/src/user-course-progress/tests/user-course-progress.e2e-spec.ts b/apps/api/src/user-course-progress/tests/user-course-progress.e2e-spec.ts index fb831edd..e90b6a72 100644 --- a/apps/api/src/user-course-progress/tests/user-course-progress.e2e-spec.ts +++ b/apps/api/src/user-course-progress/tests/user-course-progress.e2e-spec.ts @@ -43,12 +43,14 @@ describe("user-progress e2e", () => { const courseIdFirst = createId(); const coursePackIdSecond = createId(); const courseIdSecond = createId(); - await insertUserCourseProgress(db, coursePackIdFirst, courseIdFirst, 0); - await insertUserCourseProgress(db, coursePackIdSecond, courseIdSecond, 10); + const userId = createId(); + await insertUserCourseProgress(db, coursePackIdFirst, courseIdFirst, 0, userId); + await insertUserCourseProgress(db, coursePackIdSecond, courseIdSecond, 10, userId); await request(app.getHttpServer()) .get("/user-course-progress/recent-course-packs") .set("Authorization", `Bearer ${token}`) + .query({ userId }) .expect(200) .expect(({ body }) => { expect(body.length).toBe(2); diff --git a/apps/api/test/fixture/db.ts b/apps/api/test/fixture/db.ts index 212b83b3..b5331965 100644 --- a/apps/api/test/fixture/db.ts +++ b/apps/api/test/fixture/db.ts @@ -80,11 +80,12 @@ export async function insertUserCourseProgress( coursePackId: string, courseId: string, statementIndex: number, + userId?: string, ) { const [entity] = await db .insert(userCourseProgress) .values({ - userId: getTokenOwner(), + userId: userId || getTokenOwner(), coursePackId, courseId, statementIndex, From 550affb7f4e2a580e631b7c4d9e643201395aa95 Mon Sep 17 00:00:00 2001 From: BaboonKing Date: Sun, 26 May 2024 02:18:15 +0800 Subject: [PATCH 21/24] chore: remove log --- apps/client/components/user-home/index.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/client/components/user-home/index.vue b/apps/client/components/user-home/index.vue index fb0d7ce5..860256a2 100644 --- a/apps/client/components/user-home/index.vue +++ b/apps/client/components/user-home/index.vue @@ -60,7 +60,6 @@ const props = defineProps<{ }>(); const user = await getUserByUsername(props.username); -console.log(user); const isSelf = useUserStore().isSelf(() => user?.id); const { learnRecord, year } = useLearnRecord({ userId: user?.id }); From 19d574a9d00825e63c3db2b62567e86971a55850 Mon Sep 17 00:00:00 2001 From: BaboonKing Date: Sun, 26 May 2024 02:32:17 +0800 Subject: [PATCH 22/24] fix: unexpected refetch of learn records --- apps/client/components/user-home/index.vue | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/client/components/user-home/index.vue b/apps/client/components/user-home/index.vue index 860256a2..c759fb37 100644 --- a/apps/client/components/user-home/index.vue +++ b/apps/client/components/user-home/index.vue @@ -65,6 +65,9 @@ const isSelf = useUserStore().isSelf(() => user?.id); const { learnRecord, year } = useLearnRecord({ userId: user?.id }); const onToggleYear = (value?: number) => { + if (!value) { + return; + } year.value = value!; }; From b39d96d14a4fb8ad682233ab29c1717aae101eae Mon Sep 17 00:00:00 2001 From: BaboonKing Date: Sun, 26 May 2024 03:41:57 +0800 Subject: [PATCH 23/24] feat: debounced of LearnRecord --- apps/client/composables/learnRecord.ts | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/apps/client/composables/learnRecord.ts b/apps/client/composables/learnRecord.ts index 0ca35663..89d92204 100644 --- a/apps/client/composables/learnRecord.ts +++ b/apps/client/composables/learnRecord.ts @@ -1,23 +1,31 @@ import type { MaybeRef } from "vue"; -import { ref, toValue, watchEffect } from "vue"; +import { refDebounced } from "@vueuse/core"; +import { ref, toValue, watch } from "vue"; import type { UserLearnRecordResponse } from "~/api/userLearnRecord"; import { fetchLearnRecord } from "~/api/userLearnRecord"; +import { useUserStore } from "~/store/user"; interface UseLearnRecordOptions { year?: MaybeRef; - userId: string; + /** + * @default string current user + */ + userId?: string; } export function useLearnRecord(options: UseLearnRecordOptions) { - const { userId } = options || {}; + const userStore = useUserStore(); + const { userId = userStore.userInfo?.sub! } = options || {}; + const learnRecord = ref({ list: [], totalCount: 0, }); const year = ref(options?.year || new Date().getFullYear()); + const debouncedYear = refDebounced(year, 1500); function getQuery() { const yearStr = toValue(year); @@ -32,9 +40,15 @@ export function useLearnRecord(options: UseLearnRecordOptions) { const res = await fetchLearnRecord(getQuery()); learnRecord.value = res; } - watchEffect(() => { - updateLearnRecord(); - }); + watch( + debouncedYear, + () => { + updateLearnRecord(); + }, + { + immediate: true, + }, + ); return { year, From a0660bb0b0729ea7a3a2ef7247758727d52c0629 Mon Sep 17 00:00:00 2001 From: BaboonKing Date: Thu, 30 May 2024 16:31:22 +0800 Subject: [PATCH 24/24] feat: merge code of Avatar --- apps/client/components/user-home/index.vue | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/client/components/user-home/index.vue b/apps/client/components/user-home/index.vue index c759fb37..d2d0de4c 100644 --- a/apps/client/components/user-home/index.vue +++ b/apps/client/components/user-home/index.vue @@ -2,9 +2,12 @@