diff --git a/src/app/profile/page.tsx b/src/app/profile/page.tsx index 64faf15..2c211ed 100644 --- a/src/app/profile/page.tsx +++ b/src/app/profile/page.tsx @@ -17,7 +17,7 @@ import { useCustomApiKeys } from '@/lib/custom-api-store'; import { useCreationHistory, type CreationRecord, isPlaceholder } from '@/lib/creation-history-store'; import { useCreditRecords, formatRecordTime } from '@/lib/credit-records-store'; import { useUserOrders, formatOrderTime } from '@/lib/order-store'; -import { useAuth } from '@/lib/auth-store'; +import { readStoredAuth, useAuth } from '@/lib/auth-store'; import { useSiteConfig } from '@/lib/site-config'; import { CreationDetailDialog } from '@/components/creation-detail-dialog'; import { @@ -232,7 +232,11 @@ export default function ProfilePage() { }; const handleAccountSave = async () => { - if (!user || !accessToken) { + const currentAuth = readStoredAuth(); + const authUser = user || currentAuth.user; + const authToken = accessToken || currentAuth.accessToken; + + if (!authUser || !authToken) { setAccountMessage({ type: 'error', text: '请先登录后再修改资料' }); return; } @@ -268,7 +272,7 @@ export default function ProfilePage() { method: 'PUT', headers: { 'Content-Type': 'application/json', - Authorization: `Bearer ${accessToken}`, + Authorization: `Bearer ${authToken}`, }, body: JSON.stringify(payload), }); @@ -283,12 +287,12 @@ export default function ProfilePage() { email: data.profile.email, nickname: data.profile.nickname, phone: data.profile.phone || null, - membershipTier: data.profile.membership_tier || user.membershipTier, - creditsBalance: data.profile.credits_balance ?? user.creditsBalance, - dailyQuotaUsed: data.profile.daily_quota_used ?? user.dailyQuotaUsed, - dailyQuotaLimit: data.profile.daily_quota_limit ?? user.dailyQuotaLimit, - avatarUrl: data.profile.avatar_url ?? user.avatarUrl, - createdAt: data.profile.created_at ?? user.createdAt, + membershipTier: data.profile.membership_tier || authUser.membershipTier, + creditsBalance: data.profile.credits_balance ?? authUser.creditsBalance, + dailyQuotaUsed: data.profile.daily_quota_used ?? authUser.dailyQuotaUsed, + dailyQuotaLimit: data.profile.daily_quota_limit ?? authUser.dailyQuotaLimit, + avatarUrl: data.profile.avatar_url ?? authUser.avatarUrl, + createdAt: data.profile.created_at ?? authUser.createdAt, emailVerified: data.profile.email_verified === true, emailVerifiedAt: data.profile.email_verified_at ?? null, }); @@ -305,7 +309,8 @@ export default function ProfilePage() { }; const handleSendProfileEmailCode = async () => { - if (!accessToken) { + const authToken = accessToken || readStoredAuth().accessToken; + if (!authToken) { setAccountMessage({ type: 'error', text: '请先登录后再验证邮箱' }); return; } @@ -320,7 +325,7 @@ export default function ProfilePage() { method: 'POST', headers: { 'Content-Type': 'application/json', - Authorization: `Bearer ${accessToken}`, + Authorization: `Bearer ${authToken}`, }, body: JSON.stringify({ email: accountForm.email }), }); @@ -337,7 +342,8 @@ export default function ProfilePage() { }; const handleVerifyProfileEmail = async () => { - if (!accessToken) return; + const authToken = accessToken || readStoredAuth().accessToken; + if (!authToken) return; if (!isEmail(accountForm.email) || !emailVerifyCode) { setAccountMessage({ type: 'error', text: '请填写邮箱和验证码' }); return; @@ -348,7 +354,7 @@ export default function ProfilePage() { method: 'POST', headers: { 'Content-Type': 'application/json', - Authorization: `Bearer ${accessToken}`, + Authorization: `Bearer ${authToken}`, }, body: JSON.stringify({ email: accountForm.email, code: emailVerifyCode }), }); diff --git a/src/lib/auth-store.ts b/src/lib/auth-store.ts index 8b3950a..fa6c6ac 100644 --- a/src/lib/auth-store.ts +++ b/src/lib/auth-store.ts @@ -26,20 +26,36 @@ export interface AuthState { const STORAGE_KEY = 'miaojing_auth'; const EVENT_KEY = 'miaojing_auth_updated'; -function getStoredAuth(): AuthState { +export function readStoredAuth(): AuthState { if (typeof window === 'undefined') { return { user: null, accessToken: null, isLoggedIn: false }; } try { const raw = localStorage.getItem(STORAGE_KEY); if (!raw) return { user: null, accessToken: null, isLoggedIn: false }; - const parsed = JSON.parse(raw) as AuthState; - return parsed; + const parsed = JSON.parse(raw) as Partial & { session?: { access_token?: unknown } }; + const accessToken = typeof parsed.accessToken === 'string' && parsed.accessToken + ? parsed.accessToken + : typeof parsed.session?.access_token === 'string' + ? parsed.session.access_token + : null; + if (!parsed.user || !accessToken) { + return { user: null, accessToken: null, isLoggedIn: false }; + } + return { + user: parsed.user, + accessToken, + isLoggedIn: true, + }; } catch { return { user: null, accessToken: null, isLoggedIn: false }; } } +function getStoredAuth(): AuthState { + return readStoredAuth(); +} + function setStoredAuth(state: AuthState): void { if (typeof window === 'undefined') return; localStorage.setItem(STORAGE_KEY, JSON.stringify(state));