Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
There was a problem hiding this comment.
Pull request overview
该 PR 为应用新增 /settings 用户偏好编辑页,通过 Next.js rewrite 代理后端「用户中心」API,实现偏好(theme / language / aiDefaultProvider)的读取与保存,并在保存后同步主题到 ThemeProvider。
Changes:
- 新增
/settings路由:Server Component 页面壳 + Client Component 表单交互 - 新增
/api/user-center/*→ 后端的 rewrite,用于偏好设置等接口同源访问 - 在设置页引入骨架屏与 toast 提示,提供加载/保存反馈
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| next.config.mjs | 增加 /api/user-center/:path* rewrite 到后端,避免浏览器跨域 |
| app/settings/page.tsx | 新增设置页 Server Component 容器(Header/Footer + 表单挂载) |
| app/settings/SettingsForm.tsx | 新增偏好表单:拉取/保存偏好、toast、骨架屏、保存后同步 ThemeProvider |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
app/settings/page.tsx
Outdated
Comment on lines
+2
to
+33
| // 未登录时重定向到 /login?redirect=/settings | ||
| import { cookies } from "next/headers"; | ||
| import { Header } from "@/app/components/Header"; | ||
| import { Footer } from "@/app/components/Footer"; | ||
| import { SettingsForm } from "./SettingsForm"; | ||
|
|
||
| async function getServerUser() { | ||
| const cookieStore = await cookies(); | ||
| const token = cookieStore.get("satoken")?.value; | ||
| if (!token || !process.env.BACKEND_URL) return null; | ||
| try { | ||
| const res = await fetch(`${process.env.BACKEND_URL}/auth/me`, { | ||
| headers: { satoken: token }, | ||
| cache: "no-store", | ||
| }); | ||
| if (!res.ok) return null; | ||
| const body = await res.json(); | ||
| return body?.data ?? null; | ||
| } catch { | ||
| return null; | ||
| } | ||
| } | ||
|
|
||
| export default async function SettingsPage() { | ||
| const user = await getServerUser(); | ||
|
|
||
| // satoken 存在于 localStorage 而非 cookie,服务端无法读取 | ||
| // 因此此处 user 可能为 null;实际登录态由客户端 SettingsForm 内部处理 | ||
| // 仅当能从服务端确认已登出时才重定向,避免误跳转 | ||
| // (大多数情况下 user 为 null 是正常的,由客户端 useAuth 判断) | ||
| void user; | ||
|
|
app/settings/page.tsx
Outdated
| @@ -0,0 +1,53 @@ | |||
| // 用户偏好设置页(Server Component) | |||
| // 未登录时重定向到 /login?redirect=/settings | |||
Comment on lines
+61
to
+65
| useEffect(() => { | ||
| if (status !== "authenticated") return; | ||
| const token = getToken(); | ||
| if (!token) return; | ||
|
|
app/settings/SettingsForm.tsx
Outdated
| }) | ||
| .then((body) => { | ||
| if (body?.success && body?.data) { | ||
| setPrefs({ ...DEFAULT_PREFS, ...body.data }); |
Comment on lines
+84
to
+87
| function showToast(type: "success" | "error", msg: string) { | ||
| setToast({ type, msg }); | ||
| setTimeout(() => setToast(null), 3000); | ||
| } |
app/settings/SettingsForm.tsx
Outdated
|
|
||
| async function handleSave() { | ||
| const token = getToken(); | ||
| if (!token) return; |
longsizhuo
added a commit
that referenced
this pull request
Apr 14, 2026
Copilot CR #278: - page.tsx 删除 getServerUser 死代码:token 存 localStorage 服务端读不到,注释误导 - SettingsForm: token 缺失时 setLoading(false) 结束骨架屏 + 提示 + 跳登录页 - SettingsForm: 加载到偏好后立刻 setTheme,让已保存 theme 与当前主题一致 - SettingsForm: 用 useRef 存 toast timer,新 toast/卸载时 clearTimeout,避免 setState on unmounted - SettingsForm: handleSave 的 token 缺失分支也给 toast + 跳登录,与加载逻辑一致
Sa-Token 后端配置 sa-token.token-name=satoken,从 HTTP header 中读取的是裸 satoken 字段;之前写成 x-satoken 是 Next.js /api/analytics 内部 resolveUserId 的约定,两者不通用。调后端 /api/user-center/* 必须走 Sa-Token 本尊的 header 名。
Copilot CR #278: - page.tsx 删除 getServerUser 死代码:token 存 localStorage 服务端读不到,注释误导 - SettingsForm: token 缺失时 setLoading(false) 结束骨架屏 + 提示 + 跳登录页 - SettingsForm: 加载到偏好后立刻 setTheme,让已保存 theme 与当前主题一致 - SettingsForm: 用 useRef 存 toast timer,新 toast/卸载时 clearTimeout,避免 setState on unmounted - SettingsForm: handleSave 的 token 缺失分支也给 toast + 跳登录,与加载逻辑一致
接前 commit:page.tsx 里 getServerUser 从 cookie 读 satoken,但本项目 token 存 localStorage,服务端拿不到,user 变量被 void 掉也没用。直接删死代码,页面纯 Server Component 壳,登录态由 SettingsForm 的 useAuth 处理。
之前只做了 /settings 页面本身,没任何入口,用户只能手打 URL 才能访问。 在登录用户右上角 Avatar 下拉菜单里加一条「设置」,指向 /settings。 位置:账号信息下方、GitHub 切换/登出之上,符合常见产品 pattern。
之前用 bg-popover / text-foreground / bg-muted 等语义色 token, 在当前主题下 popover 色与 background 几乎同色(白-近白 / 黑-近黑), 面板看起来像透明的悬浮,文字勉强可辨。 改为显式 neutral 色阶: - 容器:bg-white dark:bg-neutral-900 - 边框:border-neutral-200 dark:border-neutral-700 - 账号信息区:bg-neutral-50 dark:bg-neutral-800 做背景分层 - 文字:text-neutral-900 dark:text-neutral-100 - hover:bg-neutral-100 dark:bg-neutral-800 - 登出按钮加 border-t 与上面其它选项分隔 阴影从 shadow-lg 升到 shadow-xl 让浮层从下方内容里跳出来。
SignInButton 之前 fallback 到 http://localhost:8080,在后端跑 8081 的本地 环境就直接打不通。参考 /analytics、/auth、/api/user-center 的 rewrite pattern, 改用同源 /oauth/render/github,next.config.mjs 补一条 /oauth/:path* → BACKEND_URL。 前端不再关心后端端口,换端口时只改 .env 里 BACKEND_URL 即可。 仍然存在的限制(不在本 PR 范围):GitHub OAuth app 注册的 callback URL 是 localhost:3000/api/auth/callback/github,前端换端口跑(如本机 3010)时需要 到 GitHub OAuth app 里补一条 callback URL,否则授权回来依旧 404。
83c6c52 to
766ccbb
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Test plan
依赖
后端 PR: involutionhell-backend#feature/user-preferences