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.
 
 
 
 
 
 

7.5 KiB

01-APP React Native 项目结构初始化

目标

使用 React Native CLI 创建项目,配置基础依赖和目录结构。


前置要求

  • React Native 环境已搭建
  • Node.js 18+ 已安装
  • Android Studio / Xcode 已配置

实施步骤

步骤 1:创建 React Native 项目

cd I:\apps\demo\healthApps

# 创建项目
npx react-native init app --template react-native-template-typescript

cd app

步骤 2:安装核心依赖

# 导航
npm install @react-navigation/native @react-navigation/native-stack @react-navigation/bottom-tabs
npm install react-native-screens react-native-safe-area-context

# 状态管理
npm install zustand

# 网络请求
npm install axios

# 图表(体质雷达图)
npm install react-native-svg
npm install react-native-gifted-charts

# 存储
npm install @react-native-async-storage/async-storage

# 表单
npm install react-hook-form

# UI 组件
npm install react-native-paper react-native-vector-icons
npm install @types/react-native-vector-icons -D

# 工具
npm install dayjs

步骤 3:配置 iOS 依赖(macOS)

cd ios
pod install
cd ..

步骤 4:创建目录结构

mkdir -p src/api
mkdir -p src/components/common
mkdir -p src/components/survey
mkdir -p src/components/constitution
mkdir -p src/components/chat
mkdir -p src/screens/auth
mkdir -p src/screens/survey
mkdir -p src/screens/constitution
mkdir -p src/screens/chat
mkdir -p src/screens/profile
mkdir -p src/navigation
mkdir -p src/stores
mkdir -p src/hooks
mkdir -p src/utils
mkdir -p src/types
mkdir -p src/assets

步骤 5:创建类型定义

创建 src/types/index.ts

export interface User {
  id: number
  phone: string
  email: string
  nickname: string
  avatar: string
  survey_completed: boolean
}

export interface HealthProfile {
  id: number
  name: string
  birth_date: string
  gender: string
  height: number
  weight: number
  bmi: number
  blood_type: string
}

export interface Question {
  id: number
  constitution_type: string
  question_text: string
  options: string[]
  order_num: number
}

export interface ConstitutionScore {
  type: string
  name: string
  score: number
  description: string
}

export interface ConstitutionResult {
  primary_constitution: ConstitutionScore
  secondary_constitutions: ConstitutionScore[]
  all_scores: ConstitutionScore[]
  recommendations: Record<string, Record<string, string>>
  assessed_at: string
}

export interface Conversation {
  id: number
  title: string
  created_at: string
  updated_at: string
}

export interface Message {
  id: number
  role: 'user' | 'assistant' | 'system'
  content: string
  created_at: string
}

export interface ApiResponse<T = any> {
  code: number
  message: string
  data: T
}

步骤 6:创建 API 请求基础配置

创建 src/api/request.ts

import axios from 'axios'
import AsyncStorage from '@react-native-async-storage/async-storage'
import { Alert } from 'react-native'
import type { ApiResponse } from '../types'

const API_BASE_URL = __DEV__
  ? 'http://10.0.2.2:8080/api'  // Android 模拟器
  : 'https://your-production-url.com/api'

const request = axios.create({
  baseURL: API_BASE_URL,
  timeout: 30000,
})

// 请求拦截器
request.interceptors.request.use(
  async (config) => {
    const token = await AsyncStorage.getItem('token')
    if (token) {
      config.headers.Authorization = `Bearer ${token}`
    }
    return config
  },
  (error) => Promise.reject(error)
)

// 响应拦截器
request.interceptors.response.use(
  (response) => {
    const res = response.data as ApiResponse
    if (res.code !== 0) {
      Alert.alert('提示', res.message || '请求失败')
      return Promise.reject(new Error(res.message))
    }
    return res.data
  },
  (error) => {
    if (error.response?.status === 401) {
      AsyncStorage.removeItem('token')
      // 这里需要导航到登录页,后续在导航配置中处理
    }
    Alert.alert('错误', error.message || '网络错误')
    return Promise.reject(error)
  }
)

export default request

步骤 7:创建用户 Store

创建 src/stores/userStore.ts

import { create } from 'zustand'
import AsyncStorage from '@react-native-async-storage/async-storage'
import type { User } from '../types'

interface UserState {
  token: string
  user: User | null
  isLoggedIn: boolean
  surveyCompleted: boolean
  setToken: (token: string) => void
  setUser: (user: User) => void
  logout: () => void
  loadToken: () => Promise<void>
}

export const useUserStore = create<UserState>((set, get) => ({
  token: '',
  user: null,
  isLoggedIn: false,
  surveyCompleted: false,

  setToken: async (token: string) => {
    await AsyncStorage.setItem('token', token)
    set({ token, isLoggedIn: !!token })
  },

  setUser: (user: User) => {
    set({ user, surveyCompleted: user.survey_completed })
  },

  logout: async () => {
    await AsyncStorage.removeItem('token')
    set({ token: '', user: null, isLoggedIn: false, surveyCompleted: false })
  },

  loadToken: async () => {
    const token = await AsyncStorage.getItem('token')
    if (token) {
      set({ token, isLoggedIn: true })
    }
  },
}))

步骤 8:更新 App.tsx

更新 App.tsx

import React, { useEffect, useState } from 'react'
import { StatusBar } from 'react-native'
import { NavigationContainer } from '@react-navigation/native'
import { Provider as PaperProvider } from 'react-native-paper'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { useUserStore } from './src/stores/userStore'
import RootNavigator from './src/navigation/RootNavigator'

const App = () => {
  const [isReady, setIsReady] = useState(false)
  const loadToken = useUserStore((state) => state.loadToken)

  useEffect(() => {
    const init = async () => {
      await loadToken()
      setIsReady(true)
    }
    init()
  }, [])

  if (!isReady) {
    return null // 或者显示 Splash Screen
  }

  return (
    <SafeAreaProvider>
      <PaperProvider>
        <NavigationContainer>
          <StatusBar barStyle="dark-content" />
          <RootNavigator />
        </NavigationContainer>
      </PaperProvider>
    </SafeAreaProvider>
  )
}

export default App

步骤 9:验证项目

# Android
npm run android

# iOS (macOS)
npm run ios

需要创建的文件清单

文件路径 说明
src/types/index.ts 类型定义
src/api/request.ts 请求封装
src/stores/userStore.ts 用户状态管理
App.tsx 应用入口(更新)

最终目录结构

app/
├── src/
│   ├── api/
│   │   └── request.ts
│   ├── components/
│   │   ├── common/
│   │   ├── survey/
│   │   ├── constitution/
│   │   └── chat/
│   ├── screens/
│   │   ├── auth/
│   │   ├── survey/
│   │   ├── constitution/
│   │   ├── chat/
│   │   └── profile/
│   ├── navigation/
│   ├── stores/
│   │   └── userStore.ts
│   ├── hooks/
│   ├── utils/
│   ├── types/
│   │   └── index.ts
│   └── assets/
├── App.tsx
├── package.json
├── android/
└── ios/

验收标准

  • 项目创建成功
  • 依赖安装完成
  • 目录结构创建完整
  • 模拟器启动正常
  • 无报错

预计耗时

20-30 分钟


下一步

完成后进入 04-APP开发/02-导航和布局设计.md