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.
 
 
 
 
 
 

5.4 KiB

04-健康调查页面

目标

实现 APP 端新用户健康调查功能,包括多步骤表单。


实现要点

APP 端健康调查与 Web 端功能相同,主要差异:

  1. 步骤指示器:使用自定义组件或 react-native-paper 的 ProgressBar
  2. 表单输入:使用 TextInputRadioButtonSwitch 等 RN 组件
  3. 日期选择:使用 @react-native-community/datetimepicker
  4. 滑动选择:使用 @react-native-community/slider

关键代码示例

步骤指示器组件

// src/components/common/StepIndicator.tsx
import React from 'react'
import { View, Text, StyleSheet } from 'react-native'

interface Props {
  steps: string[]
  currentStep: number
}

const StepIndicator: React.FC<Props> = ({ steps, currentStep }) => {
  return (
    <View style={styles.container}>
      {steps.map((step, index) => (
        <View key={index} style={styles.stepWrapper}>
          <View
            style={[
              styles.circle,
              index <= currentStep && styles.activeCircle,
            ]}
          >
            <Text style={[styles.number, index <= currentStep && styles.activeNumber]}>
              {index + 1}
            </Text>
          </View>
          <Text style={styles.label}>{step}</Text>
          {index < steps.length - 1 && (
            <View
              style={[styles.line, index < currentStep && styles.activeLine]}
            />
          )}
        </View>
      ))}
    </View>
  )
}

const styles = StyleSheet.create({
  container: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    paddingHorizontal: 20,
    paddingVertical: 16,
  },
  stepWrapper: {
    alignItems: 'center',
    flex: 1,
  },
  circle: {
    width: 32,
    height: 32,
    borderRadius: 16,
    backgroundColor: '#e0e0e0',
    justifyContent: 'center',
    alignItems: 'center',
  },
  activeCircle: {
    backgroundColor: '#667eea',
  },
  number: {
    color: '#999',
    fontWeight: 'bold',
  },
  activeNumber: {
    color: '#fff',
  },
  label: {
    fontSize: 12,
    color: '#666',
    marginTop: 4,
  },
  line: {
    position: 'absolute',
    top: 16,
    left: '60%',
    right: '-40%',
    height: 2,
    backgroundColor: '#e0e0e0',
  },
  activeLine: {
    backgroundColor: '#667eea',
  },
})

export default StepIndicator

调查主页面

// src/screens/survey/SurveyScreen.tsx
import React, { useState } from 'react'
import { View, ScrollView, StyleSheet, Alert } from 'react-native'
import { Button } from 'react-native-paper'
import StepIndicator from '../../components/common/StepIndicator'
import BasicInfoForm from '../../components/survey/BasicInfoForm'
import LifestyleForm from '../../components/survey/LifestyleForm'
import HealthStatusForm from '../../components/survey/HealthStatusForm'
import { useUserStore } from '../../stores/userStore'

const steps = ['基础信息', '生活习惯', '健康状况', '完成']

const SurveyScreen = () => {
  const [currentStep, setCurrentStep] = useState(0)
  const { setUser, user } = useUserStore()

  const handleNext = () => {
    if (currentStep < steps.length - 1) {
      setCurrentStep(currentStep + 1)
    }
  }

  const handlePrev = () => {
    if (currentStep > 0) {
      setCurrentStep(currentStep - 1)
    }
  }

  const handleComplete = () => {
    if (user) {
      setUser({ ...user, survey_completed: true })
    }
  }

  return (
    <View style={styles.container}>
      <StepIndicator steps={steps} currentStep={currentStep} />

      <ScrollView style={styles.content}>
        {currentStep === 0 && <BasicInfoForm onNext={handleNext} />}
        {currentStep === 1 && (
          <LifestyleForm onPrev={handlePrev} onNext={handleNext} />
        )}
        {currentStep === 2 && (
          <HealthStatusForm onPrev={handlePrev} onNext={handleNext} />
        )}
        {currentStep === 3 && (
          <View style={styles.completeContainer}>
            <Text style={styles.completeTitle}>健康调查完成!</Text>
            <Text style={styles.completeSubtitle}>
              接下来进行体质测评
            </Text>
            <Button mode="contained" onPress={handleComplete}>
              开始体质测评
            </Button>
          </View>
        )}
      </ScrollView>
    </View>
  )
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#f5f5f5',
  },
  content: {
    flex: 1,
    padding: 16,
  },
  completeContainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    padding: 40,
  },
  completeTitle: {
    fontSize: 24,
    fontWeight: 'bold',
    marginBottom: 8,
  },
  completeSubtitle: {
    fontSize: 16,
    color: '#666',
    marginBottom: 24,
  },
})

export default SurveyScreen

需要创建的文件

文件路径 说明
src/api/survey.ts 调查 API(同 Web 端)
src/screens/survey/SurveyScreen.tsx 调查主页面
src/components/survey/BasicInfoForm.tsx 基础信息表单
src/components/survey/LifestyleForm.tsx 生活习惯表单
src/components/survey/HealthStatusForm.tsx 健康状况表单
src/components/common/StepIndicator.tsx 步骤指示器

验收标准

  • 步骤指示器显示正确
  • 各表单可正常填写
  • 数据提交成功
  • 完成后自动跳转

预计耗时

35-45 分钟


下一步

完成后进入 04-APP开发/05-体质辨识页面.md