diff --git a/apps/api/src/routes/account.ts b/apps/api/src/routes/account.ts index df0360d..fb98c85 100644 --- a/apps/api/src/routes/account.ts +++ b/apps/api/src/routes/account.ts @@ -84,15 +84,10 @@ accountRoutes.post("/users", async (c) => { userId: created.id, acmProblemsStatus: {}, avatar: `${config.avatarUriPrefix}/default.png`, - blog: null, mood: null, acceptedNumber: 0, submissionNumber: 0, - github: null, - school: null, - major: null, realName: null, - language: null, }) }) return success(c, { ok: true }, 201) diff --git a/apps/api/src/routes/admin/account.ts b/apps/api/src/routes/admin/account.ts index 0228932..db31310 100644 --- a/apps/api/src/routes/admin/account.ts +++ b/apps/api/src/routes/admin/account.ts @@ -227,7 +227,6 @@ adminAccountRoutes.post("/users", requireSuperAdmin, async (c) => { acmProblemsStatus: {}, submissionNumber: 0, acceptedNumber: 0, - totalScore: 0, }))) return users.length }) diff --git a/apps/api/src/routes/auth.ts b/apps/api/src/routes/auth.ts index 2b3477c..18aa090 100644 --- a/apps/api/src/routes/auth.ts +++ b/apps/api/src/routes/auth.ts @@ -1,9 +1,5 @@ -import { - loginRequestSchema, - sessionUserSchema, - userProfileSchema, -} from "@oj2/contract" -import { and, eq, sql } from "drizzle-orm" +import { loginRequestSchema } from "@oj2/contract" +import { eq, sql } from "drizzle-orm" import { Hono } from "hono" import { optionalAuth, type AppEnv } from "../auth/middleware" @@ -17,21 +13,31 @@ import { getUserProfileById } from "../services/profile" export const authRoutes = new Hono() authRoutes.post("/auth/login", async (c) => { - const parsed = loginRequestSchema.safeParse(await c.req.json().catch(() => null)) + const parsed = loginRequestSchema.safeParse( + await c.req.json().catch(() => null), + ) if (!parsed.success) { - return failure(c, 400, "invalid-request", "Username and password are required") + return failure( + c, + 400, + "invalid-request", + "Username and password are required", + ) } const [user] = await db .select() .from(schema.user) - .where( - sql`lower(${schema.user.username}) = lower(${parsed.data.username})`, - ) + .where(sql`lower(${schema.user.username}) = lower(${parsed.data.username})`) .limit(1) if (!user) { - return failure(c, 401, "invalid-credentials", "Invalid username or password") + return failure( + c, + 401, + "invalid-credentials", + "Invalid username or password", + ) } if (user.isDisabled) { return failure(c, 403, "account-disabled", "Your account has been disabled") @@ -39,7 +45,12 @@ authRoutes.post("/auth/login", async (c) => { const password = await verifyPassword(parsed.data.password, user.password) if (!password.valid) { - return failure(c, 401, "invalid-credentials", "Invalid username or password") + return failure( + c, + 401, + "invalid-credentials", + "Invalid username or password", + ) } const now = new Date().toISOString() @@ -67,6 +78,7 @@ authRoutes.get("/me", optionalAuth, async (c) => { if (!authUser) return success(c, null) const data = await getUserProfileById(authUser.id, true) - if (!data) return failure(c, 404, "profile-not-found", "User profile does not exist") + if (!data) + return failure(c, 404, "profile-not-found", "User profile does not exist") return success(c, data) }) diff --git a/apps/api/src/services/profile.ts b/apps/api/src/services/profile.ts index 718a5d7..7b1f6e5 100644 --- a/apps/api/src/services/profile.ts +++ b/apps/api/src/services/profile.ts @@ -29,12 +29,7 @@ export async function getUserProfileById(userId: number, showRealName: boolean) realName: showRealName ? row.profile.realName : null, acmProblemsStatus: row.profile.acmProblemsStatus, avatar: row.profile.avatar, - blog: row.profile.blog, mood: row.profile.mood, - github: row.profile.github, - school: row.profile.school, - major: row.profile.major, - language: row.profile.language, acceptedNumber: row.profile.acceptedNumber, submissionNumber: row.profile.submissionNumber, }) diff --git a/apps/web/src/admin/achievement/components/AchievementModal.vue b/apps/web/src/admin/achievement/components/AchievementModal.vue index 676ba19..d6481fb 100644 --- a/apps/web/src/admin/achievement/components/AchievementModal.vue +++ b/apps/web/src/admin/achievement/components/AchievementModal.vue @@ -1,4 +1,5 @@ - 仅 {{ achievement.unlock_rate }}% 的人获得 + 仅 {{ achievement.unlockRate }}% 的人获得 diff --git a/apps/web/src/oj/achievement/index.vue b/apps/web/src/oj/achievement/index.vue index 4b54628..f11d5e1 100644 --- a/apps/web/src/oj/achievement/index.vue +++ b/apps/web/src/oj/achievement/index.vue @@ -7,25 +7,10 @@ import type { Achievement, AchievementRarity, AchievementSummary, + UserBadge, } from "utils/types" import AchievementCard from "./components/AchievementCard.vue" -interface UserBadge { - id: number - earned_time: string - badge: { - id: number - name: string - description: string - icon: string - } - // 奖章来自哪个题单,接口在 UserBadgeSerializer 里带出来 - problemset: { - id: number - title: string - } | null -} - const route = useRoute() const name = computed(() => (route.query.name as string) || undefined) @@ -72,7 +57,7 @@ async function load() { // http 客户端返回 ApiResponse,真实载荷在 .data 里 achievements.value = list.data.achievements summary.value = sum.data - badges.value = (badgeRes.data ?? []) as UserBadge[] + badges.value = badgeRes.data ?? [] } finally { loading.value = false } diff --git a/apps/web/src/oj/ai/components/DifficultyGradeChart.vue b/apps/web/src/oj/ai/components/DifficultyGradeChart.vue index 6add8be..b21aa4b 100644 --- a/apps/web/src/oj/ai/components/DifficultyGradeChart.vue +++ b/apps/web/src/oj/ai/components/DifficultyGradeChart.vue @@ -83,6 +83,7 @@ const data = computed(() => { // 根据等级返回对应的颜色 function getGradeColor(grade: Grade): string { const colors: { [key in Grade]: string } = { + "": "#C9CDD4", // 无评级:后端在没有可用数据时下发空串 S: "#FF6384", A: "#FFCE56", B: "#36A2EB", diff --git a/apps/web/src/oj/ai/components/DurationChart.vue b/apps/web/src/oj/ai/components/DurationChart.vue index 502d7ca..7331939 100644 --- a/apps/web/src/oj/ai/components/DurationChart.vue +++ b/apps/web/src/oj/ai/components/DurationChart.vue @@ -73,14 +73,14 @@ const data = computed>(() => { { type: "bar", label: "完成题目数", - data: aiStore.durationData.map((duration) => duration.problem_count), + data: aiStore.durationData.map((duration) => duration.problemCount), yAxisID: "y", order: 2, }, { type: "bar", label: "总提交次数", - data: aiStore.durationData.map((duration) => duration.submission_count), + data: aiStore.durationData.map((duration) => duration.submissionCount), yAxisID: "y", order: 2, }, diff --git a/apps/web/src/oj/ai/components/EfficiencyChart.vue b/apps/web/src/oj/ai/components/EfficiencyChart.vue index 8b74bf4..1659a98 100644 --- a/apps/web/src/oj/ai/components/EfficiencyChart.vue +++ b/apps/web/src/oj/ai/components/EfficiencyChart.vue @@ -59,8 +59,8 @@ const show = computed(() => { // 计算提交效率数据 const efficiencyData = computed(() => { return aiStore.durationData.map((duration) => { - const problemCount = duration.problem_count || 0 - const submissionCount = duration.submission_count || 0 + const problemCount = duration.problemCount || 0 + const submissionCount = duration.submissionCount || 0 // 计算效率:提交次数/完成题目数 // 值越接近1,说明一次AC率越高 diff --git a/apps/web/src/oj/ai/components/Grade.vue b/apps/web/src/oj/ai/components/Grade.vue index b5096d1..19ee246 100644 --- a/apps/web/src/oj/ai/components/Grade.vue +++ b/apps/web/src/oj/ai/components/Grade.vue @@ -28,8 +28,10 @@