feat: 首页更新

This commit is contained in:
2025-11-11 18:48:54 +08:00
parent 230191f181
commit b48cce06f4
43 changed files with 3186 additions and 1029 deletions

View File

@@ -29,42 +29,28 @@ export default function TabLayout() {
<Tabs.Screen
name="index"
options={{
title: 'Tab One',
tabBarIcon: ({ color }) => <TabBarIcon name="code" color={color} />,
headerRight: () => (
<Link href="/modal" asChild>
<Pressable>
{({ pressed }) => (
<FontAwesome
name="info-circle"
size={25}
color={Colors[colorScheme ?? 'light'].text}
style={{ marginRight: 15, opacity: pressed ? 0.5 : 1 }}
/>
)}
</Pressable>
</Link>
),
title: '首页',
tabBarIcon: ({ color }) => <TabBarIcon name="home" color={color} />,
}}
/>
<Tabs.Screen
name="two"
options={{
title: 'Tab Two',
title: '充值',
tabBarIcon: ({ color }) => <TabBarIcon name="code" color={color} />,
}}
/>
<Tabs.Screen
name="demo"
options={{
title: '完整示例',
title: '活动',
tabBarIcon: ({ color }) => <TabBarIcon name="rocket" color={color} />,
}}
/>
<Tabs.Screen
name="paper"
options={{
title: 'Paper UI',
title: '我的',
tabBarIcon: ({ color }) => <TabBarIcon name="paint-brush" color={color} />,
}}
/>

View File

@@ -24,10 +24,8 @@ import { useRouter } from 'expo-router';
// 工具函数
import {
Storage,
storageManager,
STORAGE_KEYS,
SessionStorage,
SESSION_KEYS,
formatDate,
formatRelativeTime,
formatChatTime
@@ -43,17 +41,13 @@ import {
useLanguage,
useHapticsEnabled,
useSettingsActions,
useTenantStates,
useTenantInfo,
} from '@/stores';
import { useTenantLoad, useTenantInfo } from '@/stores/tenantStore';
// 验证规则
import { loginSchema } from '@/schemas';
import type { LoginFormData } from '@/schemas';
// API 服务
import { authService } from '@/services';
// 自定义 Hooks
import { useDebounce, useThrottle, useHaptics } from '@/hooks';
@@ -71,7 +65,7 @@ export default function DemoScreen() {
const login = useUserStore((state) => state.login);
const logout = useUserStore((state) => state.logout);
const { tenantLoad } = useTenantStates();
const tenantLoad = useTenantLoad();
const tenantInfo = useTenantInfo();
// 设置状态
@@ -189,7 +183,7 @@ export default function DemoScreen() {
counter,
};
await Storage.setObject(STORAGE_KEYS.USER_PREFERENCES, testData);
storageManager.session.setItem(STORAGE_KEYS.USER_PREFERENCES, testData);
haptics.success();
Alert.alert('成功', '数据已保存到本地存储');
} catch (error) {
@@ -201,7 +195,7 @@ export default function DemoScreen() {
const handleLoadFromStorage = async () => {
try {
haptics.light();
const data = await Storage.getObject<any>(STORAGE_KEYS.USER_PREFERENCES);
const data = storageManager.session.getItem(STORAGE_KEYS.USER_PREFERENCES);
if (data) {
setStorageValue(JSON.stringify(data, null, 2));
@@ -229,7 +223,7 @@ export default function DemoScreen() {
counter: Math.floor(Math.random() * 100),
};
SessionStorage.setObject(SESSION_KEYS.FORM_DRAFT, testData);
storageManager.session.setItem(STORAGE_KEYS.FORM_DRAFT, testData);
haptics.success();
Alert.alert('成功', '数据已保存到会话存储(应用重启后会丢失)');
} catch (error) {
@@ -241,7 +235,7 @@ export default function DemoScreen() {
const handleLoadFromSession = () => {
try {
haptics.light();
const data = SessionStorage.getObject<any>(SESSION_KEYS.FORM_DRAFT);
const data = storageManager.session.getItem(STORAGE_KEYS.FORM_DRAFT);
if (data) {
setSessionValue(JSON.stringify(data, null, 2));
@@ -259,7 +253,7 @@ export default function DemoScreen() {
const handleClearSession = () => {
try {
haptics.light();
SessionStorage.clear();
storageManager.session.clear();
setSessionValue('');
haptics.success();
Alert.alert('成功', '会话存储已清空');

View File

@@ -1,187 +1,23 @@
import { useState, useEffect } from 'react';
import { StyleSheet, TouchableOpacity, Alert, ActivityIndicator } from 'react-native';
import * as Updates from 'expo-updates';
/**
* 首页 - 游戏大厅
*
* 重构自 xinyong-web 项目的首页
* 支持浅色/深色主题,包含轮播图、分类菜单、游戏大厅等功能
*/
import { Text, View } from '@/components/Themed';
import { Stack } from 'expo-router';
import HomeScreen from '@/pages/HomeScreen';
export default function TabOneScreen() {
const [isChecking, setIsChecking] = useState(false);
const [updateInfo, setUpdateInfo] = useState<string>('');
const checkForUpdates = async () => {
if (__DEV__) {
Alert.alert('提示', '开发模式下无法检查更新,请使用生产构建测试热更新功能');
return;
}
setIsChecking(true);
setUpdateInfo('正在检查更新...');
try {
const update = await Updates.checkForUpdateAsync();
if (update.isAvailable) {
setUpdateInfo('发现新版本,正在下载...');
await Updates.fetchUpdateAsync();
Alert.alert('更新完成', '新版本已下载完成,是否立即重启应用?', [
{
text: '稍后',
style: 'cancel',
onPress: () => setUpdateInfo('更新已下载,稍后重启应用即可应用'),
},
{
text: '立即重启',
onPress: async () => {
await Updates.reloadAsync();
},
},
]);
} else {
setUpdateInfo('当前已是最新版本');
}
} catch (error) {
setUpdateInfo('检查更新失败: ' + (error as Error).message);
Alert.alert('错误', '检查更新失败,请稍后重试');
} finally {
setIsChecking(false);
}
};
const getUpdateInfo = () => {
const { isEmbeddedLaunch, isEmergencyLaunch, updateId, channel, runtimeVersion } =
Updates.useUpdates();
return `
运行模式: ${__DEV__ ? '开发模式' : '生产模式'}
是否为内嵌启动: ${isEmbeddedLaunch ? '是' : '否'}
是否为紧急启动: ${isEmergencyLaunch ? '是' : '否'}
更新 ID: ${updateId || '无'}
更新通道: ${channel || '无'}
运行时版本: ${runtimeVersion || '无'}
`.trim();
};
useEffect(() => {
console.log('=== TabOneScreen 组件已渲染 ===');
}, []);
return (
<View style={styles.container}>
<Text style={styles.title}>🚀 </Text>
<View style={styles.separator} lightColor="#eee" darkColor="rgba(255,255,255,0.1)" />
<View style={styles.infoContainer}>
<Text style={styles.infoTitle}></Text>
<Text style={styles.infoText}>{getUpdateInfo()}</Text>
</View>
<TouchableOpacity
style={[styles.button, isChecking && styles.buttonDisabled]}
onPress={checkForUpdates}
disabled={isChecking}
>
{isChecking ? (
<ActivityIndicator color="#fff" />
) : (
<Text style={styles.buttonText}></Text>
)}
</TouchableOpacity>
{updateInfo ? (
<View style={styles.updateInfoContainer}>
<Text style={styles.updateInfoText}>{updateInfo}</Text>
</View>
) : null}
<View style={styles.instructionsContainer}>
<Text style={styles.instructionsTitle}>📝 使</Text>
<Text style={styles.instructionsText}>
1. 使 EAS Build {'\n'}
2. eas update {'\n'}
3. "检查更新"{'\n'}
4.
</Text>
</View>
</View>
<>
<Stack.Screen
options={{
title: '首页',
headerShown: false,
}}
/>
<HomeScreen />
</>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
padding: 20,
},
title: {
fontSize: 28,
fontWeight: 'bold',
marginBottom: 10,
},
separator: {
marginVertical: 20,
height: 1,
width: '80%',
},
infoContainer: {
backgroundColor: 'rgba(0, 122, 255, 0.1)',
padding: 15,
borderRadius: 10,
marginBottom: 20,
width: '100%',
},
infoTitle: {
fontSize: 16,
fontWeight: 'bold',
marginBottom: 10,
},
infoText: {
fontSize: 12,
fontFamily: 'monospace',
lineHeight: 18,
},
button: {
backgroundColor: '#007AFF',
paddingHorizontal: 30,
paddingVertical: 15,
borderRadius: 10,
marginBottom: 20,
minWidth: 200,
alignItems: 'center',
},
buttonDisabled: {
backgroundColor: '#999',
},
buttonText: {
color: '#fff',
fontSize: 16,
fontWeight: 'bold',
},
updateInfoContainer: {
backgroundColor: 'rgba(52, 199, 89, 0.1)',
padding: 15,
borderRadius: 10,
marginBottom: 20,
width: '100%',
},
updateInfoText: {
fontSize: 14,
textAlign: 'center',
},
instructionsContainer: {
backgroundColor: 'rgba(255, 149, 0, 0.1)',
padding: 15,
borderRadius: 10,
width: '100%',
},
instructionsTitle: {
fontSize: 16,
fontWeight: 'bold',
marginBottom: 10,
},
instructionsText: {
fontSize: 13,
lineHeight: 20,
},
});

View File

@@ -12,7 +12,8 @@ import { PaperProvider, MD3DarkTheme, MD3LightTheme } from 'react-native-paper';
// ✅ 从 hooks 目录导入
import { useColorScheme } from '@/hooks';
// ✅ 从 stores 目录导入
import { restoreUserState, restoreSettingsState, useTenantActions } from '@/stores';
import { restoreUserState, restoreSettingsState } from '@/stores';
import { requestTenantInfo } from '@/stores/tenantStore';
export {
// Catch any errors thrown by the Layout component.
@@ -32,7 +33,6 @@ export default function RootLayout() {
SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),
...FontAwesome.font,
});
const { requestTenantInfo } = useTenantActions();
// Expo Router uses Error Boundaries to catch errors in the navigation tree.
useEffect(() => {