You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
6.6 KiB
6.6 KiB
01-API 服务对接
目标
将前端原型从模拟数据切换到真实后端 API。
前置要求
- APP/Web 原型开发完成
- 后端 API 服务运行中
对接步骤概览
1. 配置 API 基础地址
APP (React Native):
创建 app/src/config/api.ts:
// 开发环境配置
export const API_BASE_URL = __DEV__
? 'http://localhost:8080/api'
: 'https://api.yourservice.com/api';
export const TIMEOUT = 30000;
Web (Vue):
创建 web/src/config/api.ts:
export const API_BASE_URL = import.meta.env.DEV
? 'http://localhost:8080/api'
: 'https://api.yourservice.com/api';
2. 创建 HTTP 请求封装
APP (React Native):
创建 app/src/api/client.ts:
import AsyncStorage from '@react-native-async-storage/async-storage';
import { API_BASE_URL, TIMEOUT } from '../config/api';
interface RequestOptions {
method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
body?: any;
headers?: Record<string, string>;
}
export async function apiRequest<T>(
endpoint: string,
options: RequestOptions = {}
): Promise<T> {
const token = await AsyncStorage.getItem('token');
const headers: Record<string, string> = {
'Content-Type': 'application/json',
...options.headers,
};
if (token) {
headers['Authorization'] = `Bearer ${token}`;
}
const response = await fetch(`${API_BASE_URL}${endpoint}`, {
method: options.method || 'GET',
headers,
body: options.body ? JSON.stringify(options.body) : undefined,
});
const data = await response.json();
if (data.code !== 0) {
throw new Error(data.message || '请求失败');
}
return data.data;
}
Web (Vue):
创建 web/src/api/client.ts:
import axios from 'axios';
import { ElMessage } from 'element-plus';
import { API_BASE_URL } from '../config/api';
import { useAuthStore } from '../stores/auth';
import router from '../router';
const client = axios.create({
baseURL: API_BASE_URL,
timeout: 30000,
});
// 请求拦截器
client.interceptors.request.use(config => {
const authStore = useAuthStore();
if (authStore.token) {
config.headers.Authorization = `Bearer ${authStore.token}`;
}
return config;
});
// 响应拦截器
client.interceptors.response.use(
response => {
const { code, message, data } = response.data;
if (code !== 0) {
ElMessage.error(message || '请求失败');
return Promise.reject(new Error(message));
}
return data;
},
error => {
if (error.response?.status === 401) {
const authStore = useAuthStore();
authStore.logout();
router.push('/login');
}
ElMessage.error(error.message || '网络错误');
return Promise.reject(error);
}
);
export default client;
3. 创建 API 模块
创建各模块 API 文件:
认证 API (api/auth.ts):
import client from './client';
export const authApi = {
login: (phone: string, password: string) =>
client.post('/auth/login', { phone, password }),
register: (phone: string, password: string, nickname?: string) =>
client.post('/auth/register', { phone, password, nickname }),
};
体质 API (api/constitution.ts):
import client from './client';
export const constitutionApi = {
getQuestions: () =>
client.get('/constitution/questions'),
submit: (answers: { question_id: number; score: number }[]) =>
client.post('/constitution/submit', { answers }),
getResult: () =>
client.get('/constitution/result'),
getHistory: () =>
client.get('/constitution/history'),
};
对话 API (api/conversation.ts):
import client from './client';
export const conversationApi = {
getList: () =>
client.get('/conversations'),
create: (title?: string) =>
client.post('/conversations', { title }),
getDetail: (id: string) =>
client.get(`/conversations/${id}`),
delete: (id: string) =>
client.delete(`/conversations/${id}`),
sendMessage: (id: string, content: string) =>
client.post(`/conversations/${id}/messages`, { content }),
};
用户 API (api/user.ts):
import client from './client';
export const userApi = {
getProfile: () =>
client.get('/user/profile'),
updateProfile: (data: { nickname?: string; avatar?: string }) =>
client.put('/user/profile', data),
getHealthProfile: () =>
client.get('/user/health-profile'),
};
产品 API (api/product.ts):
import client from './client';
export const productApi = {
getList: (category?: string) =>
client.get('/products', { params: { category } }),
getDetail: (id: number) =>
client.get(`/products/${id}`),
getRecommend: () =>
client.get('/products/recommend'),
search: (keyword: string) =>
client.get('/products/search', { params: { keyword } }),
};
4. 修改 Store 使用真实 API
示例:修改认证 Store:
// stores/auth.ts (修改前 - 使用模拟数据)
function login(userData: User) {
user.value = userData;
token.value = 'mock-token-' + userData.id;
}
// stores/auth.ts (修改后 - 使用真实 API)
import { authApi } from '@/api/auth';
async function login(phone: string, password: string) {
const result = await authApi.login(phone, password);
user.value = {
id: result.user_id,
nickname: result.nickname,
phone,
surveyCompleted: result.survey_completed,
};
token.value = result.token;
localStorage.setItem('token', result.token);
}
5. 对接清单
| 功能模块 | 模拟数据 | 真实 API | 说明 |
|---|---|---|---|
| 用户登录 | mockLogin() |
POST /auth/login |
验证码改密码登录 |
| 用户注册 | - | POST /auth/register |
新增功能 |
| 体质问卷 | constitutionQuestions |
GET /constitution/questions |
- |
| 体质提交 | calculateConstitution() |
POST /constitution/submit |
后端计算 |
| 体质结果 | useConstitutionStore |
GET /constitution/result |
- |
| 对话列表 | useChatStore |
GET /conversations |
- |
| 发送消息 | mockAIReply() |
POST /conversations/:id/messages |
AI 真实回复 |
| 产品推荐 | mockProducts |
GET /products/recommend |
- |
| 用户信息 | useAuthStore |
GET /user/profile |
- |
| 健康档案 | mockProfile |
GET /user/health-profile |
- |
验收标准
- 登录接口对接成功
- 体质问卷从后端获取
- 体质结果由后端计算
- AI 对话调用真实接口
- Token 认证正常工作
- 错误处理正常
预计耗时
60-90 分钟
下一步
完成后进入 05-前后端对接/02-联调测试.md