healthapp
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

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