pda_react_native_template/src/screens/stockIn/StockInEmpty.tsx

255 lines
6.7 KiB
TypeScript
Raw Normal View History

2025-07-04 10:44:57 +08:00
import React, {useState} from 'react';
import {
View,
Text,
StyleSheet,
TextInput,
TouchableOpacity,
Alert,
SafeAreaView,
ActivityIndicator,
} from 'react-native';
import {httpService} from '../../services/http';
import {NativeStackNavigationProp} from '@react-navigation/native-stack';
import {useNavigation} from '@react-navigation/native';
import {RootStackParamList} from '../../navigation/types';
import {useTheme} from '../../contexts/ThemeContext';
import Icon from 'react-native-vector-icons/MaterialIcons';
interface StockInEmptyResponse {
code: number;
message: string;
data: string;
}
type StockInEmptyScreenNavigationProp = NativeStackNavigationProp<
RootStackParamList,
'StockInEmpty'
>;
export const StockInEmpty: React.FC = () => {
const navigation = useNavigation<StockInEmptyScreenNavigationProp>();
const theme = useTheme();
const [vehicleNo, setVehicleNo] = useState('');
const [loading, setLoading] = useState(false);
// 空托入库方法
const handleEmptyIn = async () => {
if (!vehicleNo.trim()) {
Alert.alert('警告', '请先填写载具号', [
{text: '返回填写', style: 'cancel'},
]);
return;
}
try {
setLoading(true);
const response = await httpService.post<StockInEmptyResponse>(
'/api/vehicle/empty-in',
{vehicleNo: vehicleNo.trim()}
);
if (response.code !== 200) {
Alert.alert('警告', '服务器请求失败', [
{text: '我知道了', style: 'cancel'},
]);
return;
}
// 确保response.data是字符串类型
const responseData = typeof response.data === 'string'
? JSON.parse(response.data)
: response.data;
if (responseData.code === 200) {
Alert.alert('成功', '', [
{text: '我知道了', style: 'default'},
]);
setVehicleNo('');
} else {
Alert.alert('警告', `服务器返回失败:${responseData.message}`, [
{text: '我知道了', style: 'cancel'},
]);
}
} catch (error) {
Alert.alert('请求发生错误', `请求服务器发生错误:${error}`, [
{text: '我知道了', style: 'cancel'},
]);
} finally {
setLoading(false);
}
};
return (
<SafeAreaView style={[styles.container, {backgroundColor: theme.colors.background}]}>
{/* 头部导航栏 */}
<View style={[styles.header, {backgroundColor: theme.colors.primary}]}>
<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} />
</View>
{/* 主体内容 */}
<View style={styles.content}>
{/* 说明文字 */}
<View style={styles.infoSection}>
<Icon name="info-outline" size={24} color={theme.colors.primary} />
<Text style={[styles.infoText, {color: theme.colors.text}]}>
</Text>
</View>
{/* 载具号输入框 */}
<View style={styles.inputContainer}>
<Text style={[styles.inputLabel, {color: theme.colors.text}]}>
<Text style={styles.required}>*</Text>
</Text>
<View style={[styles.inputWrapper, {borderColor: theme.colors.border}]}>
<Icon name="qr-code-scanner" size={24} color={theme.colors.primary} style={styles.inputIcon} />
<TextInput
style={[styles.input, {color: theme.colors.text}]}
value={vehicleNo}
onChangeText={setVehicleNo}
placeholder="请扫描或输入载具号"
placeholderTextColor={theme.colors.textLight}
autoCapitalize="none"
/>
{vehicleNo.length > 0 && (
<TouchableOpacity
onPress={() => setVehicleNo('')}
style={styles.clearButton}>
<Icon name="cancel" size={20} color={theme.colors.textLight} />
</TouchableOpacity>
)}
</View>
</View>
{/* 提交按钮 */}
<TouchableOpacity
style={[
styles.submitButton,
{backgroundColor: theme.colors.primary},
loading && styles.submitButtonDisabled,
]}
onPress={handleEmptyIn}
disabled={loading}>
{loading ? (
<ActivityIndicator color={theme.colors.background} />
) : (
<>
<Icon name="save" size={24} color={theme.colors.background} style={styles.submitIcon} />
<Text style={[styles.submitButtonText, {color: theme.colors.background}]}>
</Text>
</>
)}
</TouchableOpacity>
</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,
},
backButton: {
padding: 8,
},
headerTitle: {
fontSize: 18,
fontWeight: '600',
},
headerRight: {
width: 40,
},
content: {
flex: 1,
padding: 20,
},
infoSection: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: 'rgba(24, 144, 255, 0.1)',
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,
backgroundColor: 'rgba(255, 255, 255, 0.8)',
},
inputIcon: {
marginRight: 8,
},
input: {
flex: 1,
fontSize: 16,
padding: 0,
height: '100%',
},
clearButton: {
padding: 4,
},
submitButton: {
height: 48,
borderRadius: 24,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
marginTop: 32,
elevation: 2,
shadowColor: '#000',
shadowOffset: {width: 0, height: 2},
shadowOpacity: 0.1,
shadowRadius: 2,
},
submitButtonDisabled: {
opacity: 0.6,
},
submitIcon: {
marginRight: 8,
},
submitButtonText: {
fontSize: 16,
fontWeight: '600',
},
});