feat: 前端对接 Profile/Messages/Settings 页面 API

- 3 消息页 + 2 资料编辑页 + 3 设置页 + 2 资料展示页
- api.ts 新增 Profile/Messages/ChangePassword 等类型和方法
- SSEContext 事件映射修复 + 断线重连修复
- 剩余页面加 USE_MOCK 双模式,52/55 页面已完成

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Your Name
2026-02-10 10:27:59 +08:00
co-authored by Claude Opus 4.6
parent a76c302d7a
commit f02b3f4098
14 changed files with 473 additions and 41 deletions
+40 -6
View File
@@ -1,6 +1,6 @@
'use client'
import React, { useState } from 'react'
import React, { useState, useEffect, useCallback } from 'react'
import { useRouter } from 'next/navigation'
import { ArrowLeft, Camera, Check, Copy } from 'lucide-react'
import { ResponsiveLayout } from '@/components/layout/ResponsiveLayout'
@@ -8,6 +8,8 @@ import { Button } from '@/components/ui/Button'
import { Input } from '@/components/ui/Input'
import { cn } from '@/lib/utils'
import { useToast } from '@/components/ui/Toast'
import { USE_MOCK } from '@/contexts/AuthContext'
import { api } from '@/lib/api'
// 模拟用户数据
const mockUser = {
@@ -32,11 +34,29 @@ export default function ProfileEditPage() {
douyinAccount: mockUser.douyinAccount,
bio: mockUser.bio,
})
const [creatorId, setCreatorId] = useState(mockUser.creatorId)
const loadData = useCallback(async () => {
if (USE_MOCK) return
try {
const profile = await api.getProfile()
setFormData({
name: profile.name || '',
phone: profile.phone || '',
email: profile.email || '',
douyinAccount: profile.creator?.douyin_account || '',
bio: profile.creator?.bio || '',
})
if (profile.creator?.id) setCreatorId(profile.creator.id)
} catch {}
}, [])
useEffect(() => { loadData() }, [loadData])
// 复制达人ID
const handleCopyId = async () => {
try {
await navigator.clipboard.writeText(mockUser.creatorId)
await navigator.clipboard.writeText(creatorId)
setIdCopied(true)
setTimeout(() => setIdCopied(false), 2000)
} catch {
@@ -52,8 +72,22 @@ export default function ProfileEditPage() {
// 保存
const handleSave = async () => {
setIsSaving(true)
// 模拟保存
await new Promise(resolve => setTimeout(resolve, 1000))
if (USE_MOCK) {
await new Promise(resolve => setTimeout(resolve, 1000))
} else {
try {
await api.updateProfile({
name: formData.name,
phone: formData.phone,
bio: formData.bio,
douyin_account: formData.douyinAccount,
})
} catch (err: any) {
toast.error(err.message || '保存失败')
setIsSaving(false)
return
}
}
setIsSaving(false)
router.back()
}
@@ -89,7 +123,7 @@ export default function ProfileEditPage() {
background: 'linear-gradient(135deg, #6366F1 0%, #4F46E5 100%)',
}}
>
<span className="text-[40px] font-bold text-white">{mockUser.initial}</span>
<span className="text-[40px] font-bold text-white">{formData.name?.[0] || '?'}</span>
</div>
{/* 相机按钮 */}
<button
@@ -118,7 +152,7 @@ export default function ProfileEditPage() {
<label className="text-sm font-medium text-text-primary">ID</label>
<div className="flex gap-3">
<div className="flex-1 px-4 py-3 rounded-xl border border-border-default bg-bg-elevated/50 flex items-center justify-between">
<span className="font-mono font-medium text-accent-indigo">{mockUser.creatorId}</span>
<span className="font-mono font-medium text-accent-indigo">{creatorId}</span>
<button
type="button"
onClick={handleCopyId}