# 前端真实 API 对接实施计划 > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. **Goal:** 将 react-shadcn/pc 前端项目中的 mock 数据替换为真实后端 API 调用,优先完成用户管理和个人设置页面的数据对接。 **Architecture:** 采用渐进式对接策略:1) 优先对接现有后端已支持的 API(用户管理、个人资料)2) 为 Dashboard 创建聚合查询 API 或模拟数据增强 3) 添加 API 错误处理和加载状态 4) 使用 React Query 或 SWR 进行状态管理优化。 **Tech Stack:** React 19 + TypeScript, fetch API, go-zero backend API, localStorage for auth token --- ## 现状分析 ### Mock 数据使用情况 | 页面 | 当前状态 | 需要对接的 API | |------|----------|----------------| | DashboardPage | 完全 mock 数据 (stats, recentActivity, chart) | 需要新增 Dashboard 统计 API | | UserManagementPage | 部分对接,有 fallback mock | 完善现有 API 调用,移除 mock fallback | | SettingsPage | 完全静态表单,无 API | 对接 /profile/me GET/PUT 和 /profile/password | | LoginPage | 已对接 /login | - | ### 后端已有 API 端点 ``` POST /api/v1/login - 登录 POST /api/v1/register - 注册 POST /api/v1/refresh - 刷新 Token GET /api/v1/profile/me - 获取个人资料 PUT /api/v1/profile/me - 更新个人资料 POST /api/v1/profile/password - 修改密码 GET /api/v1/users - 获取用户列表 GET /api/v1/user/:id - 获取用户详情 POST /api/v1/user - 创建用户 PUT /api/v1/user/:id - 更新用户 DELETE /api/v1/user/:id - 删除用户 ``` ### 需要新增的后端 API - `GET /api/v1/dashboard/stats` - 仪表板统计数据 - `GET /api/v1/dashboard/activities` - 最近活动列表 --- ## Task 1: 完善 api.ts 添加缺失的 API 方法 **Files:** - Modify: `frontend/react-shadcn/pc/src/services/api.ts` **Step 1: 添加 Profile 相关 API 方法** ```typescript // src/services/api.ts // 在 apiClient 类中添加以下方法 // Profile APIs async getProfile(): Promise> { return this.request>('/profile/me') } async updateProfile(data: UpdateProfileRequest): Promise> { return this.request>('/profile/me', { method: 'PUT', body: JSON.stringify(data), }) } async changePassword(data: ChangePasswordRequest): Promise> { return this.request>('/profile/password', { method: 'POST', body: JSON.stringify(data), }) } // Dashboard APIs (需要后端实现) async getDashboardStats(): Promise> { return this.request>('/dashboard/stats') } async getRecentActivities(limit: number = 10): Promise> { return this.request>(`/dashboard/activities?limit=${limit}`) } ``` **Step 2: 添加缺失的类型定义** ```typescript // src/types/index.ts 添加以下类型 export interface DashboardStats { totalUsers: number activeUsers: number systemLoad: number dbStatus: '正常' | '异常' userGrowth: number[] // 12个月的数据 } export interface Activity { id: number user: string action: string time: string status: 'success' | 'error' } export interface ChangePasswordRequest { oldPassword: string newPassword: string } export interface UpdateProfileRequest { username?: string phone?: string avatar?: string bio?: string } ``` **Step 3: Commit** ```bash git add frontend/react-shadcn/pc/src/services/api.ts frontend/react-shadcn/pc/src/types/index.ts git commit -m "feat: add profile and dashboard API methods with types" ``` --- ## Task 2: 重构 SettingsPage 对接真实 API **Files:** - Modify: `frontend/react-shadcn/pc/src/pages/SettingsPage.tsx` **Step 1: 添加状态管理和 API 调用** ```typescript // src/pages/SettingsPage.tsx import { useState, useEffect } from 'react' import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/Card' import { Input } from '@/components/ui/Input' import { Button } from '@/components/ui/Button' import { Settings, Save, Bell, Lock, Palette, Loader2 } from 'lucide-react' import { apiClient } from '@/services/api' import type { Profile, UpdateProfileRequest, ChangePasswordRequest } from '@/types' export function SettingsPage() { // 加载状态 const [isLoading, setIsLoading] = useState(true) const [isSaving, setIsSaving] = useState(false) const [isChangingPassword, setIsChangingPassword] = useState(false) const [message, setMessage] = useState<{ type: 'success' | 'error'; text: string } | null>(null) // 个人资料状态 const [profile, setProfile] = useState>({ username: '', email: '', phone: '', bio: '', avatar: '', }) // 密码修改状态 const [passwordData, setPasswordData] = useState({ oldPassword: '', newPassword: '', }) const [confirmPassword, setConfirmPassword] = useState('') // 通知设置状态 const [notifications, setNotifications] = useState({ email: true, system: true, }) // 加载个人资料 useEffect(() => { loadProfile() }, []) const loadProfile = async () => { try { setIsLoading(true) const response = await apiClient.getProfile() if (response.success && response.data) { setProfile(response.data) } } catch (error) { setMessage({ type: 'error', text: '加载个人资料失败' }) } finally { setIsLoading(false) } } // 保存个人资料 const handleSaveProfile = async () => { try { setIsSaving(true) setMessage(null) const updateData: UpdateProfileRequest = { username: profile.username, phone: profile.phone, avatar: profile.avatar, bio: profile.bio, } const response = await apiClient.updateProfile(updateData) if (response.success) { setMessage({ type: 'success', text: '个人资料保存成功' }) } else { setMessage({ type: 'error', text: response.message || '保存失败' }) } } catch (error) { setMessage({ type: 'error', text: '保存个人资料失败' }) } finally { setIsSaving(false) } } // 修改密码 const handleChangePassword = async () => { // 验证密码 if (passwordData.newPassword !== confirmPassword) { setMessage({ type: 'error', text: '新密码与确认密码不一致' }) return } if (passwordData.newPassword.length < 6) { setMessage({ type: 'error', text: '新密码长度至少6位' }) return } try { setIsChangingPassword(true) setMessage(null) const response = await apiClient.changePassword(passwordData) if (response.success) { setMessage({ type: 'success', text: '密码修改成功' }) // 清空密码输入 setPasswordData({ oldPassword: '', newPassword: '' }) setConfirmPassword('') } else { setMessage({ type: 'error', text: response.message || '修改失败' }) } } catch (error) { setMessage({ type: 'error', text: '修改密码失败,请检查当前密码是否正确' }) } finally { setIsChangingPassword(false) } } if (isLoading) { return (
) } return (
{/* 消息提示 */} {message && (
{message.text}
)} {/* Profile Settings */} 个人设置 setProfile({ ...profile, username: e.target.value })} /> setProfile({ ...profile, phone: e.target.value })} />
{/* Notification Settings */} 通知设置

邮件通知

接收重要操作邮件通知