添加测试页面

This commit is contained in:
李宇奇 2025-09-10 22:55:40 +08:00
parent 484b9c332b
commit c12750ee9a
8 changed files with 289 additions and 35 deletions

View File

@ -1,6 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application <application
android:name=".MainApplication" android:name=".MainApplication"

View File

@ -4,6 +4,17 @@ import type {ApiResponse} from '../types';
export class WmsApiClient { export class WmsApiClient {
private static http = HttpClient.getInstance(); private static http = HttpClient.getInstance();
static async test(timeOut: number = 5000) : Promise<ApiResponse<any>> {
const response = await this.http.get(
'/wms/test/hello',
{
timeout: timeOut,
}
);
console.log("yuqili {}", JSON.stringify(response));
return response.data.data;
}
/** /**
* *
*/ */

View File

@ -1,5 +1,5 @@
export const ENV = { export const ENV = {
API_URL: __DEV__ ? 'http://dev-api.example.com' : 'https://api.example.com', API_URL: 'http://10.0.2.2:12315',
APP_NAME: 'PdaRnTemplate', APP_NAME: 'PdaRnTemplate',
VERSION: '1.0.0', VERSION: '1.0.0',
}; };

View File

@ -1,13 +1,14 @@
import React from 'react'; import React from 'react';
import {NavigationContainer} from '@react-navigation/native'; import { NavigationContainer } from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack'; import { createNativeStackNavigator } from '@react-navigation/native-stack';
import {LoginScreen} from '../screens/auth/LoginScreen'; import { LoginScreen } from '../screens/auth/LoginScreen';
import {HomeScreen} from '../screens/home/HomeScreen'; import { HomeScreen } from '../screens/home/HomeScreen';
import {StockInEmpty} from '../screens/stockIn/StockInEmpty'; import { StockInEmpty } from '../screens/stockIn/StockInEmpty';
import {StockInManual} from '../screens/stockIn/StockInManual'; import { StockInManual } from '../screens/stockIn/StockInManual';
import {RootStackParamList} from './types'; import {Test} from '../screens/test/TestPage';
import {Platform} from 'react-native'; import { RootStackParamList } from './types';
import {screensEnabled, enableScreens} from 'react-native-screens'; import { Platform } from 'react-native';
import { screensEnabled, enableScreens } from 'react-native-screens';
// 确保 react-native-screens 在导航之前初始化 // 确保 react-native-screens 在导航之前初始化
if (Platform.OS === 'android' && !screensEnabled()) { if (Platform.OS === 'android' && !screensEnabled()) {
@ -35,6 +36,13 @@ const Navigation = () => {
animation: 'none', animation: 'none',
}} }}
/> />
<Stack.Screen
name="Test"
component={Test}
options={{
animation: 'none',
}}
/>
<Stack.Screen <Stack.Screen
name="Home" name="Home"
component={HomeScreen} component={HomeScreen}

View File

@ -1,6 +1,7 @@
import {NativeStackScreenProps} from '@react-navigation/native-stack'; import {NativeStackScreenProps} from '@react-navigation/native-stack';
export type RootStackParamList = { export type RootStackParamList = {
Test: undefined;
Login: undefined; Login: undefined;
Home: undefined; Home: undefined;
StockInEmpty: undefined; StockInEmpty: undefined;

View File

@ -48,6 +48,7 @@ export const HomeScreen: React.FC = () => {
}, []); }, []);
const menuItems: MenuItem[] = [ const menuItems: MenuItem[] = [
{title: 'test', icon: 'local-shipping', route: 'Test'},
{title: '空载具入库', icon: 'local-shipping', route: 'StockInEmpty'}, {title: '空载具入库', icon: 'local-shipping', route: 'StockInEmpty'},
{title: '手动码盘入库', icon: 'inventory', route: 'StockInManual'}, {title: '手动码盘入库', icon: 'inventory', route: 'StockInManual'},
]; ];

View File

@ -1,4 +1,4 @@
import React, {useState} from 'react'; import React, { useState } from 'react';
import { import {
View, View,
Text, Text,
@ -8,15 +8,15 @@ import {
SafeAreaView, SafeAreaView,
ActivityIndicator, ActivityIndicator,
} from 'react-native'; } from 'react-native';
import {NativeStackNavigationProp} from '@react-navigation/native-stack'; import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import {useNavigation} from '@react-navigation/native'; import { useNavigation } from '@react-navigation/native';
import {RootStackParamList} from '../../navigation/types'; import { RootStackParamList } from '../../navigation/types';
import {useTheme} from '../../contexts/ThemeContext'; import { useTheme } from '../../contexts/ThemeContext';
import Icon from 'react-native-vector-icons/MaterialIcons'; import Icon from 'react-native-vector-icons/MaterialIcons';
import LinearGradient from 'react-native-linear-gradient'; import LinearGradient from 'react-native-linear-gradient';
import Svg, {Path} from 'react-native-svg'; import Svg, { Path } from 'react-native-svg';
import axios from 'axios'; import axios from 'axios';
import {DialogUtils} from '../../utils'; import { DialogUtils } from '../../utils';
interface StockInEmptyResponse { interface StockInEmptyResponse {
code: number; code: number;
@ -49,7 +49,7 @@ export const StockInEmpty: React.FC = () => {
setLoading(true); setLoading(true);
const response = await axios.post<StockInEmptyResponse>( const response = await axios.post<StockInEmptyResponse>(
'/api/vehicle/empty-in', '/api/vehicle/empty-in',
{vehicleNo: vehicleNo.trim()}, { vehicleNo: vehicleNo.trim() },
); );
if (response.status !== 200) { if (response.status !== 200) {
@ -72,8 +72,7 @@ export const StockInEmpty: React.FC = () => {
} catch (error) { } catch (error) {
DialogUtils.showErrorMessage( DialogUtils.showErrorMessage(
'请求发生错误', '请求发生错误',
`请求服务器发生错误:${ `请求服务器发生错误:${error instanceof Error ? error.message : String(error)
error instanceof Error ? error.message : String(error)
}`, }`,
'我知道了', '我知道了',
); );
@ -84,19 +83,19 @@ export const StockInEmpty: React.FC = () => {
return ( return (
<SafeAreaView <SafeAreaView
style={[styles.container, {backgroundColor: theme.colors.background}]}> style={[styles.container, { backgroundColor: theme.colors.background }]}>
{/* 头部导航栏 */} {/* 头部导航栏 */}
<LinearGradient <LinearGradient
colors={theme.colors.gradients.primary} colors={theme.colors.gradients.primary}
start={{x: 0, y: 0}} start={{ x: 0, y: 0 }}
end={{x: 1, y: 0}} end={{ x: 1, y: 0 }}
style={styles.header}> style={styles.header}>
<TouchableOpacity <TouchableOpacity
onPress={() => navigation.goBack()} onPress={() => navigation.goBack()}
style={styles.backButton}> style={styles.backButton}>
<Icon name="arrow-back" size={24} color={theme.colors.background} /> <Icon name="arrow-back" size={24} color={theme.colors.background} />
</TouchableOpacity> </TouchableOpacity>
<Text style={[styles.headerTitle, {color: theme.colors.background}]}> <Text style={[styles.headerTitle, { color: theme.colors.background }]}>
</Text> </Text>
<View style={styles.headerRight} /> <View style={styles.headerRight} />
@ -121,23 +120,23 @@ export const StockInEmpty: React.FC = () => {
<View <View
style={[ style={[
styles.content, styles.content,
{backgroundColor: theme.colors.backgroundGray}, { backgroundColor: theme.colors.backgroundGray },
]}> ]}>
{/* 说明文字 */} {/* 说明文字 */}
<View <View
style={[ style={[
styles.infoSection, styles.infoSection,
{backgroundColor: `${theme.colors.aqua}15`}, { backgroundColor: `${theme.colors.aqua}15` },
]}> ]}>
<Icon name="info-outline" size={24} color={theme.colors.aqua} /> <Icon name="info-outline" size={24} color={theme.colors.aqua} />
<Text style={[styles.infoText, {color: theme.colors.text}]}> <Text style={[styles.infoText, { color: theme.colors.text }]}>
</Text> </Text>
</View> </View>
{/* 载具号输入框 */} {/* 载具号输入框 */}
<View style={styles.inputContainer}> <View style={styles.inputContainer}>
<Text style={[styles.inputLabel, {color: theme.colors.text}]}> <Text style={[styles.inputLabel, { color: theme.colors.text }]}>
<Text style={styles.required}>*</Text> <Text style={styles.required}>*</Text>
</Text> </Text>
<View <View
@ -155,7 +154,7 @@ export const StockInEmpty: React.FC = () => {
style={styles.inputIcon} style={styles.inputIcon}
/> />
<TextInput <TextInput
style={[styles.input, {color: theme.colors.text}]} style={[styles.input, { color: theme.colors.text }]}
value={vehicleNo} value={vehicleNo}
onChangeText={setVehicleNo} onChangeText={setVehicleNo}
placeholder="请扫描或输入载具号" placeholder="请扫描或输入载具号"
@ -175,8 +174,8 @@ export const StockInEmpty: React.FC = () => {
{/* 提交按钮 */} {/* 提交按钮 */}
<LinearGradient <LinearGradient
colors={theme.colors.gradients.button} colors={theme.colors.gradients.button}
start={{x: 0, y: 0}} start={{ x: 0, y: 0 }}
end={{x: 1, y: 0}} end={{ x: 1, y: 0 }}
style={[styles.submitButton, loading && styles.submitButtonDisabled]}> style={[styles.submitButton, loading && styles.submitButtonDisabled]}>
<TouchableOpacity <TouchableOpacity
style={styles.submitButtonContent} style={styles.submitButtonContent}
@ -195,7 +194,7 @@ export const StockInEmpty: React.FC = () => {
<Text <Text
style={[ style={[
styles.submitButtonText, styles.submitButtonText,
{color: theme.colors.background}, { color: theme.colors.background },
]}> ]}>
</Text> </Text>
@ -220,7 +219,7 @@ const styles = StyleSheet.create({
paddingHorizontal: 16, paddingHorizontal: 16,
elevation: 4, elevation: 4,
shadowColor: '#000', shadowColor: '#000',
shadowOffset: {width: 0, height: 2}, shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.2, shadowOpacity: 0.2,
shadowRadius: 2, shadowRadius: 2,
}, },
@ -300,7 +299,7 @@ const styles = StyleSheet.create({
marginTop: 32, marginTop: 32,
elevation: 2, elevation: 2,
shadowColor: '#000', shadowColor: '#000',
shadowOffset: {width: 0, height: 2}, shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1, shadowOpacity: 0.1,
shadowRadius: 2, shadowRadius: 2,
}, },

View File

@ -0,0 +1,233 @@
import { WmsApiClient } from '../../api/wmsApi'
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { useNavigation } from '@react-navigation/native';
import { RootStackParamList } from '../../navigation/types';
import { useState } from 'react';
import { DialogUtils } from '../../utils';
import {
View,
Text,
StyleSheet,
TextInput,
TouchableOpacity,
SafeAreaView,
ActivityIndicator,
} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import Icon from 'react-native-vector-icons/MaterialIcons';
import { useTheme } from '../../contexts/ThemeContext';
import Svg, { Path } from 'react-native-svg';
type TestScreenNavigationProp = NativeStackNavigationProp<
RootStackParamList,
'Test'
>;
export const Test: React.FC = () => {
const navigation = useNavigation<TestScreenNavigationProp>();
const theme = useTheme();
const [showStr, setStr] = useState('');
const test = async () => {
try {
const response = await WmsApiClient.test();
DialogUtils.showSuccessMessage('成功', "success", "我知道了",);
setStr(response.data);
return;
} catch (error) {
DialogUtils.showErrorMessage(
'请求发生错误',
`请求服务器发生错误:${JSON.stringify(error)
}`,
'我知道了',
);
}
}
return (
<SafeAreaView
style={[styles.container, { backgroundColor: theme.colors.background }]} >
<LinearGradient
colors={theme.colors.gradients.primary}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 0 }}
style={styles.header}>
<TouchableOpacity
onPress={() => navigation.goBack()}
style={styles.backButton}>
<Icon name="arrow-back" size={24} color={theme.colors.background} />
</TouchableOpacity>
<Text style={[styles.headerTitle, { color: theme.colors.background }]}>
</Text>
<View style={styles.headerRight} />
</LinearGradient>
<View style={styles.waveContainer}>
<Svg
height="100%"
width="100%"
viewBox="0 0 1440 320"
style={styles.waveSvg}
preserveAspectRatio="none">
<Path
fill={`${theme.colors.aqua}30`}
d="M0,96L48,112C96,128,192,160,288,186.7C384,213,480,235,576,213.3C672,192,768,128,864,128C960,128,1056,192,1152,213.3C1248,235,1344,213,1392,202.7L1440,192L1440,0L1392,0C1344,0,1248,0,1152,0C1056,0,960,0,864,0C768,0,672,0,576,0C480,0,384,0,288,0C192,0,96,0,48,0L0,0Z"
/>
</Svg>
</View>
<View
style={[
styles.content,
{ backgroundColor: theme.colors.backgroundGray },
]}>
<Text>
{showStr}
</Text>
<LinearGradient
colors={theme.colors.gradients.button}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 0 }}
style={styles.submitButton}>
<TouchableOpacity
style={styles.submitButtonContent}
onPress={test}>
{
<>
<Icon
name="save"
size={24}
color={theme.colors.background}
style={styles.submitIcon}
/>
<Text
style={[
styles.submitButtonText,
{ color: theme.colors.background },
]}>
Click Me
</Text>
</>
}
</TouchableOpacity>
</LinearGradient>
</View>
</SafeAreaView>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
header: {
height: 56,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingHorizontal: 16,
elevation: 4,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.2,
shadowRadius: 2,
},
waveContainer: {
height: 100,
backgroundColor: 'transparent',
position: 'absolute',
top: 56,
left: 0,
right: 0,
zIndex: -1,
},
waveSvg: {
position: 'absolute',
top: 0,
},
backButton: {
padding: 8,
},
headerTitle: {
fontSize: 18,
fontWeight: '600',
},
headerRight: {
width: 40,
},
content: {
flex: 1,
padding: 20,
},
infoSection: {
flexDirection: 'row',
alignItems: 'center',
padding: 16,
borderRadius: 8,
marginBottom: 24,
},
infoText: {
marginLeft: 12,
fontSize: 14,
flex: 1,
},
inputContainer: {
marginBottom: 24,
},
inputLabel: {
fontSize: 16,
marginBottom: 8,
fontWeight: '500',
},
required: {
color: '#ff4d4f',
},
inputWrapper: {
flexDirection: 'row',
alignItems: 'center',
borderWidth: 1,
borderRadius: 8,
height: 48,
paddingHorizontal: 12,
},
inputIcon: {
marginRight: 8,
},
input: {
flex: 1,
fontSize: 16,
padding: 0,
height: '100%',
},
clearButton: {
padding: 4,
},
submitButton: {
height: 48,
borderRadius: 24,
marginTop: 32,
elevation: 2,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 2,
},
submitButtonContent: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
},
submitButtonDisabled: {
opacity: 0.6,
},
submitIcon: {
marginRight: 8,
},
submitButtonText: {
fontSize: 16,
fontWeight: '600',
},
});