pda_react_native_template/src/screens/stockIn/StockInEmpty.tsx

324 lines
8.3 KiB
TypeScript

import React, {useState} from 'react';
import {
View,
Text,
StyleSheet,
TextInput,
TouchableOpacity,
SafeAreaView,
ActivityIndicator,
} from 'react-native';
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';
import LinearGradient from 'react-native-linear-gradient';
import Svg, {Path} from 'react-native-svg';
import axios from 'axios';
import {DialogUtils} from '../../utils';
interface StockInEmptyResponse {
code: number;
message: string;
data: {
code: number;
message: 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()) {
DialogUtils.showWarningMessage('警告', '请先填写载具号', '返回填写');
return;
}
try {
setLoading(true);
const response = await axios.post<StockInEmptyResponse>(
'/api/vehicle/empty-in',
{vehicleNo: vehicleNo.trim()},
);
if (response.status !== 200) {
DialogUtils.showWarningMessage('警告', '服务器请求失败', '我知道了');
return;
}
const responseData = response.data;
if (responseData.code === 200) {
DialogUtils.showSuccessMessage('成功', '空载具入库成功', '我知道了');
setVehicleNo('');
} else {
DialogUtils.showWarningMessage(
'警告',
`服务器返回失败:${responseData.message}`,
'我知道了',
);
}
} catch (error) {
DialogUtils.showErrorMessage(
'请求发生错误',
`请求服务器发生错误:${
error instanceof Error ? error.message : String(error)
}`,
'我知道了',
);
} finally {
setLoading(false);
}
};
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},
]}>
{/* 说明文字 */}
<View
style={[
styles.infoSection,
{backgroundColor: `${theme.colors.aqua}15`},
]}>
<Icon name="info-outline" size={24} color={theme.colors.aqua} />
<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,
backgroundColor: `${theme.colors.background}CC`,
},
]}>
<Icon
name="qr-code-scanner"
size={24}
color={theme.colors.aqua}
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>
{/* 提交按钮 */}
<LinearGradient
colors={theme.colors.gradients.button}
start={{x: 0, y: 0}}
end={{x: 1, y: 0}}
style={[styles.submitButton, loading && styles.submitButtonDisabled]}>
<TouchableOpacity
style={styles.submitButtonContent}
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>
</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',
},
});