feat(i18n): 实现应用国际化支持,添加中英文翻译

- 为所有UI组件添加国际化支持,替换硬编码文本
- 新增useI18n钩子函数统一管理翻译
- 完善中英文翻译资源,覆盖统计、用药、通知设置等模块
- 优化Tab布局使用翻译键值替代静态文本
- 更新药品管理、个人资料编辑等页面的多语言支持
This commit is contained in:
richarjiang
2025-11-13 11:09:55 +08:00
parent 416d144387
commit 2dca3253e6
21 changed files with 1669 additions and 366 deletions

View File

@@ -6,6 +6,7 @@ import dayjs from 'dayjs';
import { Image } from 'expo-image';
import { router } from 'expo-router';
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
interface BasalMetabolismCardProps {
@@ -14,6 +15,7 @@ interface BasalMetabolismCardProps {
}
export function BasalMetabolismCard({ selectedDate, style }: BasalMetabolismCardProps) {
const { t } = useTranslation();
const [basalMetabolism, setBasalMetabolism] = useState<number | null>(null);
const [loading, setLoading] = useState(false);
@@ -90,7 +92,7 @@ export function BasalMetabolismCard({ selectedDate, style }: BasalMetabolismCard
return result;
} catch (error) {
console.error('BasalMetabolismCard: 获取基础代谢数据失败:', error);
console.error('BasalMetabolismCard: Failed to get basal metabolism data:', error);
return null;
} finally {
// 清理请求记录
@@ -134,20 +136,20 @@ export function BasalMetabolismCard({ selectedDate, style }: BasalMetabolismCard
// 使用 useMemo 优化状态描述计算
const status = useMemo(() => {
if (basalMetabolism === null || basalMetabolism === 0) {
return { text: '未知', color: '#9AA3AE' };
return { text: t('statistics.components.metabolism.status.unknown'), color: '#9AA3AE' };
}
// 基于常见的基础代谢范围来判断状态
if (basalMetabolism >= 1800) {
return { text: '高代谢', color: '#10B981' };
return { text: t('statistics.components.metabolism.status.high'), color: '#10B981' };
} else if (basalMetabolism >= 1400) {
return { text: '正常', color: '#3B82F6' };
return { text: t('statistics.components.metabolism.status.normal'), color: '#3B82F6' };
} else if (basalMetabolism >= 1000) {
return { text: '偏低', color: '#F59E0B' };
return { text: t('statistics.components.metabolism.status.low'), color: '#F59E0B' };
} else {
return { text: '较低', color: '#EF4444' };
return { text: t('statistics.components.metabolism.status.veryLow'), color: '#EF4444' };
}
}, [basalMetabolism]);
}, [basalMetabolism, t]);
return (
<>
@@ -163,7 +165,7 @@ export function BasalMetabolismCard({ selectedDate, style }: BasalMetabolismCard
source={require('@/assets/images/icons/icon-fire.png')}
style={styles.titleIcon}
/>
<Text style={styles.title}></Text>
<Text style={styles.title}>{t('statistics.components.metabolism.title')}</Text>
</View>
<View style={[styles.statusBadge, { backgroundColor: status.color + '20' }]}>
<Text style={[styles.statusText, { color: status.color }]}>{status.text}</Text>
@@ -173,9 +175,9 @@ export function BasalMetabolismCard({ selectedDate, style }: BasalMetabolismCard
{/* 数值显示区域 */}
<View style={styles.valueSection}>
<Text style={styles.value}>
{loading ? '加载中...' : (basalMetabolism != null && basalMetabolism > 0 ? Math.round(basalMetabolism).toString() : '--')}
{loading ? t('statistics.components.metabolism.loading') : (basalMetabolism != null && basalMetabolism > 0 ? Math.round(basalMetabolism).toString() : '--')}
</Text>
<Text style={styles.unit}>/</Text>
<Text style={styles.unit}>{t('statistics.components.metabolism.unit')}</Text>
</View>
</TouchableOpacity>
</>