美化页面
This commit is contained in:
parent
342dba7ba0
commit
c0a0eed3c0
11
package-lock.json
generated
11
package-lock.json
generated
|
|
@ -19,6 +19,7 @@
|
|||
"react": "18.3.1",
|
||||
"react-native": "0.75.5",
|
||||
"react-native-chart-kit": "^6.12.0",
|
||||
"react-native-linear-gradient": "^2.8.3",
|
||||
"react-native-safe-area-context": "^5.5.1",
|
||||
"react-native-screens": "^4.5.0",
|
||||
"react-native-svg": "^15.12.0",
|
||||
|
|
@ -13357,6 +13358,16 @@
|
|||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-linear-gradient": {
|
||||
"version": "2.8.3",
|
||||
"resolved": "https://registry.npmjs.org/react-native-linear-gradient/-/react-native-linear-gradient-2.8.3.tgz",
|
||||
"integrity": "sha512-KflAXZcEg54PXkLyflaSZQ3PJp4uC4whM7nT/Uot9m0e/qxFV3p6uor1983D1YOBJbJN7rrWdqIjq0T42jOJyA==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-safe-area-context": {
|
||||
"version": "5.5.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-5.5.1.tgz",
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
"react": "18.3.1",
|
||||
"react-native": "0.75.5",
|
||||
"react-native-chart-kit": "^6.12.0",
|
||||
"react-native-linear-gradient": "^2.8.3",
|
||||
"react-native-safe-area-context": "^5.5.1",
|
||||
"react-native-screens": "^4.5.0",
|
||||
"react-native-svg": "^15.12.0",
|
||||
|
|
@ -47,4 +48,4 @@
|
|||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
73
src/components/common/WaveBackground.tsx
Normal file
73
src/components/common/WaveBackground.tsx
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
import React from 'react';
|
||||
import {View, StyleSheet, Dimensions} from 'react-native';
|
||||
import LinearGradient from 'react-native-linear-gradient';
|
||||
import Svg, {Path} from 'react-native-svg';
|
||||
|
||||
const {width} = Dimensions.get('window');
|
||||
|
||||
interface WaveBackgroundProps {
|
||||
height: number;
|
||||
gradientColors: string[];
|
||||
}
|
||||
|
||||
export const WaveBackground: React.FC<WaveBackgroundProps> = ({
|
||||
height,
|
||||
gradientColors,
|
||||
}) => {
|
||||
return (
|
||||
<View style={[styles.container, {height}]}>
|
||||
<LinearGradient colors={gradientColors} style={StyleSheet.absoluteFill}>
|
||||
<View style={styles.waveContainer}>
|
||||
<Svg height={60} width={width} style={styles.wave}>
|
||||
<Path
|
||||
d={`M0,20
|
||||
C${width * 0.25},35
|
||||
${width * 0.5},5
|
||||
${width * 0.75},25
|
||||
C${width * 0.875},35
|
||||
${width},15
|
||||
${width},20
|
||||
L${width},0
|
||||
L0,0 Z`}
|
||||
fill="rgba(255, 255, 255, 0.3)"
|
||||
/>
|
||||
</Svg>
|
||||
<Svg height={60} width={width} style={[styles.wave, styles.wave2]}>
|
||||
<Path
|
||||
d={`M0,15
|
||||
C${width * 0.125},5
|
||||
${width * 0.25},25
|
||||
${width * 0.5},15
|
||||
C${width * 0.75},5
|
||||
${width},25
|
||||
${width},15
|
||||
L${width},0
|
||||
L0,0 Z`}
|
||||
fill="rgba(255, 255, 255, 0.2)"
|
||||
/>
|
||||
</Svg>
|
||||
</View>
|
||||
</LinearGradient>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
width: '100%',
|
||||
overflow: 'hidden',
|
||||
},
|
||||
waveContainer: {
|
||||
position: 'absolute',
|
||||
bottom: -1,
|
||||
left: 0,
|
||||
right: 0,
|
||||
},
|
||||
wave: {
|
||||
backgroundColor: 'transparent',
|
||||
},
|
||||
wave2: {
|
||||
position: 'absolute',
|
||||
bottom: 15,
|
||||
},
|
||||
});
|
||||
|
|
@ -3,19 +3,41 @@
|
|||
|
||||
export const theme = {
|
||||
colors: {
|
||||
primary: '#05dcef', // 主题色 (0xff05dcef)
|
||||
background: '#ffffff', // 背景色 (0xffffffff)
|
||||
text: '#333333', // 文本颜色 (0xff333333)
|
||||
accent: '#03a9f4', // 强调色 (0xff03a9f4)
|
||||
|
||||
// 派生的颜色
|
||||
primaryLight: '#66e5f3', // 主题色亮色版
|
||||
primaryDark: '#04b0be', // 主题色暗色版
|
||||
textLight: '#666666', // 次要文本颜色
|
||||
border: '#dddddd', // 边框颜色
|
||||
error: '#ff3b30', // 错误颜色
|
||||
success: '#4cd964', // 成功颜色
|
||||
warning: '#ff9500', // 警告颜色
|
||||
// 基础颜色
|
||||
primary: '#4158D0', // 主色调
|
||||
secondary: '#C850C0', // 次要色调
|
||||
tertiary: '#FFCC70', // 第三色调
|
||||
background: '#ffffff', // 背景色
|
||||
text: '#333333', // 文本颜色
|
||||
textLight: '#666666', // 次要文本颜色
|
||||
border: '#dddddd', // 边框颜色
|
||||
error: '#ff3b30', // 错误颜色
|
||||
success: '#4cd964', // 成功颜色
|
||||
warning: '#ff9500', // 警告颜色
|
||||
cyan: '#00FFFF', // 青色背景
|
||||
|
||||
// 渐变色配置
|
||||
gradients: {
|
||||
primary: ['#4158D0', '#C850C0', '#FFCC70'], // 主要渐变(蓝紫金)
|
||||
contrast: ['#00F5A0', '#00D9F5'], // 对比渐变(绿青)
|
||||
card: ['#9795F0', '#E3C3F1'], // 卡片渐变(柔和紫色)
|
||||
login: ['#4158D0', '#C850C0', '#FFCC70'], // 登录页面专用渐变
|
||||
loginWave: ['rgba(255, 255, 255, 0.3)', 'rgba(255, 255, 255, 0.2)'], // 登录页面波浪渐变
|
||||
header: ['#4158D0', '#C850C0'], // 头部渐变
|
||||
button: ['#4158D0', '#C850C0'], // 按钮渐变
|
||||
// 波浪背景渐变
|
||||
wave: {
|
||||
start: 'rgba(255, 255, 255, 0.3)',
|
||||
middle: 'rgba(255, 255, 255, 0.2)',
|
||||
end: 'rgba(255, 255, 255, 0.1)'
|
||||
}
|
||||
},
|
||||
|
||||
// 图表颜色
|
||||
chart: {
|
||||
blue: '#0077B6', // 深蓝色
|
||||
orange: '#FB8500', // 明亮的橙色
|
||||
},
|
||||
},
|
||||
|
||||
// 字体大小
|
||||
|
|
@ -25,6 +47,8 @@ export const theme = {
|
|||
medium: 16,
|
||||
large: 18,
|
||||
xlarge: 20,
|
||||
xxlarge: 24,
|
||||
title: 32,
|
||||
},
|
||||
|
||||
// 间距
|
||||
|
|
@ -41,7 +65,8 @@ export const theme = {
|
|||
small: 4,
|
||||
medium: 8,
|
||||
large: 12,
|
||||
round: 999,
|
||||
xl: 16,
|
||||
circle: 999,
|
||||
},
|
||||
|
||||
// 阴影
|
||||
|
|
@ -77,6 +102,12 @@ export const theme = {
|
|||
elevation: 6,
|
||||
},
|
||||
},
|
||||
|
||||
// 波浪效果配置
|
||||
wave: {
|
||||
height: 60,
|
||||
opacity: 1,
|
||||
},
|
||||
};
|
||||
|
||||
// 类型定义
|
||||
|
|
|
|||
|
|
@ -5,11 +5,19 @@ import {
|
|||
StyleSheet,
|
||||
TouchableOpacity,
|
||||
InteractionManager,
|
||||
Image,
|
||||
Dimensions,
|
||||
} from 'react-native';
|
||||
import {useNavigation, useIsFocused} from '@react-navigation/native';
|
||||
import {NativeStackNavigationProp} from '@react-navigation/native-stack';
|
||||
import {RootStackParamList} from '../../navigation/types';
|
||||
import {Screen} from '../../components/common/Screen';
|
||||
import {WaveBackground} from '../../components/common/WaveBackground';
|
||||
import LinearGradient from 'react-native-linear-gradient';
|
||||
import Svg, {Path, Defs, LinearGradient as SvgLinearGradient, Stop} from 'react-native-svg';
|
||||
import {useTheme} from '../../contexts/ThemeContext';
|
||||
|
||||
const {width} = Dimensions.get('window');
|
||||
|
||||
type LoginScreenNavigationProp = NativeStackNavigationProp<
|
||||
RootStackParamList,
|
||||
|
|
@ -19,6 +27,7 @@ type LoginScreenNavigationProp = NativeStackNavigationProp<
|
|||
export const LoginScreen: React.FC = () => {
|
||||
const navigation = useNavigation<LoginScreenNavigationProp>();
|
||||
const isFocused = useIsFocused();
|
||||
const theme = useTheme();
|
||||
|
||||
const handleLogin = useCallback(() => {
|
||||
if (!isFocused) return;
|
||||
|
|
@ -32,53 +41,219 @@ export const LoginScreen: React.FC = () => {
|
|||
}, [navigation, isFocused]);
|
||||
|
||||
return (
|
||||
<Screen>
|
||||
{/* 头部导航栏 */}
|
||||
<View style={styles.header}>
|
||||
<Text style={styles.headerTitle}>请登录(景旺冷冻仓)</Text>
|
||||
<Screen style={[styles.screen, {backgroundColor: theme.colors.background}]}>
|
||||
{/* 头部背景 */}
|
||||
<View style={styles.headerContainer}>
|
||||
<LinearGradient
|
||||
colors={theme.colors.gradients.primary}
|
||||
style={[StyleSheet.absoluteFill, styles.gradientBackground]}
|
||||
start={{ x: 0, y: 0 }}
|
||||
end={{ x: 1, y: 1 }}
|
||||
>
|
||||
{/* 半透明波浪效果 */}
|
||||
<View style={styles.waveOverlay}>
|
||||
<Svg height="100%" width={width} style={styles.waveSvg}>
|
||||
<Path
|
||||
d={`M0,50
|
||||
C${width * 0.2},30
|
||||
${width * 0.4},70
|
||||
${width * 0.6},50
|
||||
C${width * 0.8},30
|
||||
${width},60
|
||||
${width},50`}
|
||||
fill="none"
|
||||
stroke="rgba(255, 255, 255, 0.2)"
|
||||
strokeWidth="2"
|
||||
/>
|
||||
<Path
|
||||
d={`M0,70
|
||||
C${width * 0.2},50
|
||||
${width * 0.4},90
|
||||
${width * 0.6},70
|
||||
C${width * 0.8},50
|
||||
${width},80
|
||||
${width},70`}
|
||||
fill="none"
|
||||
stroke="rgba(255, 255, 255, 0.15)"
|
||||
strokeWidth="2"
|
||||
/>
|
||||
</Svg>
|
||||
</View>
|
||||
</LinearGradient>
|
||||
<View style={styles.headerContent}>
|
||||
<Text style={[styles.headerTitle, { color: theme.colors.background }]}>
|
||||
景旺冷冻仓
|
||||
</Text>
|
||||
<Text style={[styles.headerSubtitle, { color: theme.colors.background }]}>
|
||||
智能仓储管理系统
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 不规则曲线背景 */}
|
||||
<View style={styles.curveContainer}>
|
||||
<Svg height="120" width={width} style={styles.curve}>
|
||||
<Defs>
|
||||
<SvgLinearGradient id="contrastGradient" x1="0" y1="0" x2="1" y2="0">
|
||||
<Stop offset="0" stopColor={theme.colors.gradients.contrast[0]} />
|
||||
<Stop offset="1" stopColor={theme.colors.gradients.contrast[1]} />
|
||||
</SvgLinearGradient>
|
||||
</Defs>
|
||||
<Path
|
||||
d={`M0,120
|
||||
L0,50
|
||||
C${width * 0.3},20 ${width * 0.7},80 ${width},30
|
||||
L${width},120
|
||||
Z`}
|
||||
fill="url(#contrastGradient)"
|
||||
/>
|
||||
</Svg>
|
||||
</View>
|
||||
|
||||
{/* 主体内容 */}
|
||||
<View style={styles.content}>
|
||||
{/* 登录按钮 */}
|
||||
<TouchableOpacity
|
||||
style={styles.loginButton}
|
||||
onPress={handleLogin}>
|
||||
<Text style={styles.loginButtonText}>进入系统</Text>
|
||||
</TouchableOpacity>
|
||||
<View style={[styles.contentWrapper]}>
|
||||
<LinearGradient
|
||||
colors={theme.colors.gradients.contrast}
|
||||
style={StyleSheet.absoluteFill}
|
||||
start={{x: 0, y: 0}}
|
||||
end={{x: 1, y: 0}}
|
||||
/>
|
||||
<View style={styles.content}>
|
||||
{/* Logo占位 */}
|
||||
<View style={styles.logoContainer}>
|
||||
<LinearGradient
|
||||
colors={theme.colors.gradients.contrast}
|
||||
style={[styles.logoCircle, theme.shadow.medium]}>
|
||||
<Text style={[styles.logoText, {color: theme.colors.primary}]}>
|
||||
JW
|
||||
</Text>
|
||||
</LinearGradient>
|
||||
</View>
|
||||
|
||||
{/* 登录按钮 */}
|
||||
<TouchableOpacity
|
||||
style={[styles.loginButtonContainer, theme.shadow.medium]}
|
||||
onPress={handleLogin}>
|
||||
<LinearGradient
|
||||
colors={theme.colors.gradients.primary}
|
||||
start={{x: 0, y: 0}}
|
||||
end={{x: 1, y: 0}}
|
||||
style={styles.loginButton}>
|
||||
<Text style={[styles.loginButtonText, {color: theme.colors.background}]}>
|
||||
进入系统
|
||||
</Text>
|
||||
</LinearGradient>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{/* 底部版权信息 */}
|
||||
<View style={styles.footer}>
|
||||
<Text style={[styles.footerText, {color: theme.colors.textLight}]}>
|
||||
© 2024 景旺电子
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</Screen>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
header: {
|
||||
height: 56,
|
||||
justifyContent: 'center',
|
||||
screen: {
|
||||
flex: 1,
|
||||
},
|
||||
headerContainer: {
|
||||
height: 280,
|
||||
position: 'relative',
|
||||
overflow: 'hidden',
|
||||
},
|
||||
headerContent: {
|
||||
position: 'absolute',
|
||||
top: 60,
|
||||
left: 0,
|
||||
right: 0,
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#1890ff',
|
||||
},
|
||||
headerTitle: {
|
||||
color: '#fff',
|
||||
fontSize: 32,
|
||||
fontWeight: 'bold',
|
||||
textShadowColor: 'rgba(0, 0, 0, 0.2)',
|
||||
textShadowOffset: {width: 1, height: 1},
|
||||
textShadowRadius: 3,
|
||||
},
|
||||
headerSubtitle: {
|
||||
fontSize: 18,
|
||||
fontWeight: '600',
|
||||
marginTop: 8,
|
||||
opacity: 0.9,
|
||||
},
|
||||
curveContainer: {
|
||||
position: 'absolute',
|
||||
top: 200,
|
||||
left: 0,
|
||||
right: 0,
|
||||
zIndex: 1,
|
||||
},
|
||||
curve: {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
},
|
||||
contentWrapper: {
|
||||
flex: 1,
|
||||
marginTop: 160,
|
||||
},
|
||||
content: {
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
paddingTop: 15,
|
||||
paddingTop: 40,
|
||||
},
|
||||
logoContainer: {
|
||||
marginBottom: 40,
|
||||
},
|
||||
logoCircle: {
|
||||
width: 120,
|
||||
height: 120,
|
||||
borderRadius: 60,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
logoText: {
|
||||
fontSize: 40,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
loginButtonContainer: {
|
||||
width: width * 0.8,
|
||||
maxWidth: 300,
|
||||
height: 50,
|
||||
borderRadius: 25,
|
||||
overflow: 'hidden',
|
||||
},
|
||||
loginButton: {
|
||||
backgroundColor: '#1890ff',
|
||||
width: 250,
|
||||
height: 44,
|
||||
borderRadius: 4,
|
||||
alignItems: 'center',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
loginButtonText: {
|
||||
color: '#fff',
|
||||
fontSize: 16,
|
||||
fontSize: 18,
|
||||
fontWeight: '600',
|
||||
},
|
||||
footer: {
|
||||
padding: 20,
|
||||
alignItems: 'center',
|
||||
},
|
||||
footerText: {
|
||||
fontSize: 12,
|
||||
},
|
||||
gradientBackground: {
|
||||
opacity: 0.95,
|
||||
},
|
||||
waveOverlay: {
|
||||
position: 'absolute',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
opacity: 0.6,
|
||||
},
|
||||
waveSvg: {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
},
|
||||
});
|
||||
|
|
@ -14,6 +14,10 @@ import { RootStackParamList } from '../../navigation/types';
|
|||
import { PieChart } from 'react-native-chart-kit';
|
||||
import Icon from 'react-native-vector-icons/MaterialIcons';
|
||||
import { useTheme } from '../../contexts/ThemeContext';
|
||||
import LinearGradient from 'react-native-linear-gradient';
|
||||
import Svg, { Path } from 'react-native-svg';
|
||||
|
||||
const { width } = Dimensions.get('window');
|
||||
|
||||
type HomeScreenNavigationProp = NativeStackNavigationProp<
|
||||
RootStackParamList,
|
||||
|
|
@ -33,12 +37,14 @@ export const HomeScreen: React.FC = () => {
|
|||
const [fontLoaded, setFontLoaded] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
Icon.loadFont().then(() => {
|
||||
console.log('Icon fonts loaded');
|
||||
setFontLoaded(true);
|
||||
}).catch(error => {
|
||||
console.error('Failed to load icon fonts:', error);
|
||||
});
|
||||
Icon.loadFont()
|
||||
.then(() => {
|
||||
console.log('Icon fonts loaded');
|
||||
setFontLoaded(true);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Failed to load icon fonts:', error);
|
||||
});
|
||||
}, []);
|
||||
|
||||
const menuItems: MenuItem[] = [
|
||||
|
|
@ -50,16 +56,16 @@ export const HomeScreen: React.FC = () => {
|
|||
{
|
||||
name: '空闲',
|
||||
population: 40,
|
||||
color: theme.colors.success || '#4CAF50',
|
||||
color: theme.colors.chart.blue,
|
||||
legendFontColor: theme.colors.textLight,
|
||||
legendFontSize: 15,
|
||||
legendFontSize: theme.fontSize.regular,
|
||||
},
|
||||
{
|
||||
name: '占用',
|
||||
population: 60,
|
||||
color: theme.colors.warning || '#FF9800',
|
||||
color: theme.colors.chart.orange,
|
||||
legendFontColor: theme.colors.textLight,
|
||||
legendFontSize: 15,
|
||||
legendFontSize: theme.fontSize.regular,
|
||||
},
|
||||
];
|
||||
|
||||
|
|
@ -69,94 +75,162 @@ export const HomeScreen: React.FC = () => {
|
|||
color: (opacity = 1) => `rgba(0, 0, 0, ${opacity})`,
|
||||
};
|
||||
|
||||
const screenWidth = Dimensions.get('window').width;
|
||||
|
||||
if (!fontLoaded) {
|
||||
return (
|
||||
<View style={[styles.loadingContainer, {backgroundColor: theme.colors.background}]}>
|
||||
<Text style={{color: theme.colors.text}}>加载图标中...</Text>
|
||||
<View style={[styles.loadingContainer, { backgroundColor: theme.colors.background }]}>
|
||||
<Text style={{ color: theme.colors.text }}>加载图标中...</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<SafeAreaView style={[styles.container, {backgroundColor: theme.colors.background}]}>
|
||||
{/* 头部导航栏 */}
|
||||
<View style={[styles.header, {backgroundColor: theme.colors.primary}]}>
|
||||
<TouchableOpacity
|
||||
onPress={() => setIsDrawerOpen(!isDrawerOpen)}
|
||||
style={styles.menuButton}>
|
||||
<Icon name="menu" size={24} color={theme.colors.background} />
|
||||
</TouchableOpacity>
|
||||
<Text style={[styles.headerTitle, {color: theme.colors.background}]}>
|
||||
景旺WMS移动终端(冷冻)
|
||||
</Text>
|
||||
<View style={styles.headerRight}>
|
||||
<SafeAreaView style={[styles.container, { backgroundColor: theme.colors.background }]}>
|
||||
{/* 头部区域 */}
|
||||
<View style={styles.headerSection}>
|
||||
{/* 渐变背景 */}
|
||||
<LinearGradient
|
||||
colors={theme.colors.gradients.primary}
|
||||
style={StyleSheet.absoluteFill}
|
||||
start={{ x: 0, y: 0 }}
|
||||
end={{ x: 1, y: 1 }}
|
||||
>
|
||||
{/* 半透明波浪效果 */}
|
||||
<View style={styles.waveOverlay}>
|
||||
<Svg height="100%" width={width} style={styles.waveSvg}>
|
||||
<Path
|
||||
d={`M0,50
|
||||
C${width * 0.2},30
|
||||
${width * 0.4},70
|
||||
${width * 0.6},50
|
||||
C${width * 0.8},30
|
||||
${width},60
|
||||
${width},50`}
|
||||
fill="none"
|
||||
stroke="rgba(255, 255, 255, 0.2)"
|
||||
strokeWidth="2"
|
||||
/>
|
||||
<Path
|
||||
d={`M0,70
|
||||
C${width * 0.2},50
|
||||
${width * 0.4},90
|
||||
${width * 0.6},70
|
||||
C${width * 0.8},50
|
||||
${width},80
|
||||
${width},70`}
|
||||
fill="none"
|
||||
stroke="rgba(255, 255, 255, 0.15)"
|
||||
strokeWidth="2"
|
||||
/>
|
||||
</Svg>
|
||||
</View>
|
||||
</LinearGradient>
|
||||
{/* 头部内容 */}
|
||||
<View style={styles.headerContent}>
|
||||
<TouchableOpacity
|
||||
onPress={() => setIsDrawerOpen(!isDrawerOpen)}
|
||||
style={styles.menuButton}>
|
||||
<Icon name="menu" size={24} color={theme.colors.background} />
|
||||
</TouchableOpacity>
|
||||
<Text style={[styles.headerTitle, { color: theme.colors.background }]}>
|
||||
景旺WMS移动终端(冷冻)
|
||||
</Text>
|
||||
<TouchableOpacity style={styles.iconButton}>
|
||||
<Icon name="notifications" size={24} color={theme.colors.background} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 主体内容 */}
|
||||
<View style={styles.mainContent}>
|
||||
<LinearGradient
|
||||
colors={theme.colors.gradients.contrast}
|
||||
style={StyleSheet.absoluteFill}
|
||||
start={{x: 0, y: 0}}
|
||||
end={{x: 1, y: 0}}
|
||||
/>
|
||||
<ScrollView contentContainerStyle={styles.scrollContent}>
|
||||
{/* 快捷操作区 */}
|
||||
<View style={styles.quickActions}>
|
||||
{menuItems.map((item, index) => (
|
||||
<TouchableOpacity
|
||||
key={index}
|
||||
style={[styles.actionCard]}
|
||||
onPress={() => navigation.navigate(item.route)}>
|
||||
<LinearGradient
|
||||
colors={theme.colors.gradients.card}
|
||||
style={[StyleSheet.absoluteFill, {borderRadius: 12}]}
|
||||
start={{x: 0, y: 0}}
|
||||
end={{x: 1, y: 1}}
|
||||
/>
|
||||
<LinearGradient
|
||||
colors={theme.colors.gradients.primary}
|
||||
style={styles.iconGradient}>
|
||||
<Icon name={item.icon} size={32} color={theme.colors.background} />
|
||||
</LinearGradient>
|
||||
<Text style={[styles.actionTitle, {color: theme.colors.background}]}>
|
||||
{item.title}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</View>
|
||||
|
||||
{/* 图表区域 */}
|
||||
<View style={styles.chartSection}>
|
||||
<Text style={[styles.chartTitle, {color: theme.colors.background}]}>
|
||||
库存占用情况
|
||||
</Text>
|
||||
<View style={styles.chartContainer}>
|
||||
<PieChart
|
||||
data={stockData}
|
||||
width={width - 48}
|
||||
height={220}
|
||||
chartConfig={chartConfig}
|
||||
accessor="population"
|
||||
backgroundColor="transparent"
|
||||
paddingLeft="15"
|
||||
absolute
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</ScrollView>
|
||||
</View>
|
||||
|
||||
{/* 侧边菜单 */}
|
||||
{isDrawerOpen && (
|
||||
<View style={[styles.drawer, {backgroundColor: theme.colors.background}]}>
|
||||
<View style={[styles.drawerHeader, {backgroundColor: theme.colors.primary}]}>
|
||||
<Text style={[styles.drawerTitle, {color: theme.colors.background}]}>
|
||||
景旺电子
|
||||
</Text>
|
||||
<Text style={[styles.drawerSubtitle, {color: theme.colors.background}]}>
|
||||
欢迎使用WMS移动终端
|
||||
</Text>
|
||||
</View>
|
||||
{menuItems.map((item, index) => (
|
||||
<TouchableOpacity
|
||||
key={index}
|
||||
style={[styles.drawerItem, {borderBottomColor: theme.colors.border}]}
|
||||
onPress={() => {
|
||||
setIsDrawerOpen(false);
|
||||
navigation.navigate(item.route);
|
||||
}}>
|
||||
<View style={styles.iconContainer}>
|
||||
<Icon
|
||||
name={item.icon}
|
||||
size={28}
|
||||
color={theme.colors.primary}
|
||||
/>
|
||||
</View>
|
||||
<Text style={[styles.drawerItemText, {color: theme.colors.text}]}>
|
||||
{item.title}
|
||||
<>
|
||||
<View style={[styles.drawer, { backgroundColor: theme.colors.background }]}>
|
||||
<LinearGradient
|
||||
colors={theme.colors.gradients.primary}
|
||||
style={styles.drawerHeader}>
|
||||
<Text style={[styles.drawerTitle, { color: theme.colors.background }]}>
|
||||
景旺电子
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</View>
|
||||
)}
|
||||
|
||||
{/* 主体内容 */}
|
||||
<ScrollView style={[styles.content, {backgroundColor: theme.colors.background}]}>
|
||||
<Text style={[styles.chartTitle, {color: theme.colors.text}]}>
|
||||
库存占用情况:
|
||||
</Text>
|
||||
<View style={styles.chartContainer}>
|
||||
<PieChart
|
||||
data={stockData}
|
||||
width={screenWidth - 40}
|
||||
height={220}
|
||||
chartConfig={chartConfig}
|
||||
accessor="population"
|
||||
backgroundColor="transparent"
|
||||
paddingLeft="15"
|
||||
absolute
|
||||
<Text style={[styles.drawerSubtitle, { color: theme.colors.background }]}>
|
||||
欢迎使用WMS移动终端
|
||||
</Text>
|
||||
</LinearGradient>
|
||||
{menuItems.map((item, index) => (
|
||||
<TouchableOpacity
|
||||
key={index}
|
||||
style={[styles.drawerItem, { borderBottomColor: theme.colors.border }]}
|
||||
onPress={() => {
|
||||
setIsDrawerOpen(false);
|
||||
navigation.navigate(item.route);
|
||||
}}>
|
||||
<View style={styles.drawerIconContainer}>
|
||||
<Icon name={item.icon} size={28} color={theme.colors.primary} />
|
||||
</View>
|
||||
<Text style={[styles.drawerItemText, { color: theme.colors.text }]}>
|
||||
{item.title}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</View>
|
||||
<TouchableOpacity
|
||||
style={styles.overlay}
|
||||
onPress={() => setIsDrawerOpen(false)}
|
||||
/>
|
||||
</View>
|
||||
</ScrollView>
|
||||
|
||||
{/* 遮罩层 */}
|
||||
{isDrawerOpen && (
|
||||
<TouchableOpacity
|
||||
style={styles.overlay}
|
||||
onPress={() => setIsDrawerOpen(false)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</SafeAreaView>
|
||||
);
|
||||
|
|
@ -166,45 +240,96 @@ const styles = StyleSheet.create({
|
|||
container: {
|
||||
flex: 1,
|
||||
},
|
||||
mainContent: {
|
||||
flex: 1,
|
||||
position: 'relative',
|
||||
},
|
||||
scrollContent: {
|
||||
flexGrow: 1,
|
||||
paddingVertical: 20,
|
||||
},
|
||||
loadingContainer: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
header: {
|
||||
height: 56,
|
||||
headerSection: {
|
||||
height: 160,
|
||||
position: 'relative',
|
||||
overflow: 'hidden',
|
||||
},
|
||||
waveOverlay: {
|
||||
position: 'absolute',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
opacity: 0.6,
|
||||
},
|
||||
waveSvg: {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
},
|
||||
headerContent: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
paddingHorizontal: 16,
|
||||
paddingTop: 16,
|
||||
justifyContent: 'space-between',
|
||||
height: 160,
|
||||
},
|
||||
menuButton: {
|
||||
padding: 8,
|
||||
},
|
||||
headerTitle: {
|
||||
flex: 1,
|
||||
fontSize: 18,
|
||||
fontWeight: '600',
|
||||
textAlign: 'center',
|
||||
},
|
||||
headerRight: {
|
||||
width: 40,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-end',
|
||||
},
|
||||
iconButton: {
|
||||
padding: 8,
|
||||
},
|
||||
content: {
|
||||
flex: 1,
|
||||
marginTop: -20,
|
||||
},
|
||||
quickActions: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-around',
|
||||
paddingHorizontal: 16,
|
||||
marginTop: 20,
|
||||
},
|
||||
actionCard: {
|
||||
width: width / 2 - 24,
|
||||
borderRadius: 12,
|
||||
padding: 20,
|
||||
alignItems: 'center',
|
||||
overflow: 'hidden',
|
||||
},
|
||||
iconGradient: {
|
||||
width: 64,
|
||||
height: 64,
|
||||
borderRadius: 32,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
marginBottom: 12,
|
||||
},
|
||||
actionTitle: {
|
||||
fontSize: 16,
|
||||
textAlign: 'center',
|
||||
},
|
||||
chartSection: {
|
||||
borderRadius: 12,
|
||||
margin: 16,
|
||||
padding: 16,
|
||||
overflow: 'hidden',
|
||||
},
|
||||
chartTitle: {
|
||||
fontSize: 16,
|
||||
marginBottom: 10,
|
||||
fontSize: 18,
|
||||
fontWeight: '600',
|
||||
marginBottom: 16,
|
||||
},
|
||||
chartContainer: {
|
||||
alignItems: 'center',
|
||||
marginTop: 20,
|
||||
},
|
||||
drawer: {
|
||||
position: 'absolute',
|
||||
|
|
@ -227,6 +352,7 @@ const styles = StyleSheet.create({
|
|||
},
|
||||
drawerSubtitle: {
|
||||
fontSize: 14,
|
||||
opacity: 0.9,
|
||||
},
|
||||
drawerItem: {
|
||||
flexDirection: 'row',
|
||||
|
|
@ -234,7 +360,7 @@ const styles = StyleSheet.create({
|
|||
padding: 16,
|
||||
borderBottomWidth: 1,
|
||||
},
|
||||
iconContainer: {
|
||||
drawerIconContainer: {
|
||||
width: 32,
|
||||
height: 32,
|
||||
justifyContent: 'center',
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ 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';
|
||||
|
||||
interface StockInEmptyResponse {
|
||||
code: number;
|
||||
|
|
@ -83,7 +85,11 @@ export const StockInEmpty: React.FC = () => {
|
|||
return (
|
||||
<SafeAreaView style={[styles.container, {backgroundColor: theme.colors.background}]}>
|
||||
{/* 头部导航栏 */}
|
||||
<View style={[styles.header, {backgroundColor: theme.colors.primary}]}>
|
||||
<LinearGradient
|
||||
colors={[theme.colors.primary, theme.colors.secondary, theme.colors.tertiary]}
|
||||
start={{x: 0, y: 0}}
|
||||
end={{x: 1, y: 0}}
|
||||
style={styles.header}>
|
||||
<TouchableOpacity
|
||||
onPress={() => navigation.goBack()}
|
||||
style={styles.backButton}>
|
||||
|
|
@ -91,12 +97,33 @@ export const StockInEmpty: React.FC = () => {
|
|||
</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.tertiary}40`}
|
||||
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}>
|
||||
<LinearGradient
|
||||
colors={theme.colors.gradients.contrast}
|
||||
style={StyleSheet.absoluteFill}
|
||||
start={{x: 0, y: 0}}
|
||||
end={{x: 1, y: 0}}
|
||||
/>
|
||||
{/* 说明文字 */}
|
||||
<View style={styles.infoSection}>
|
||||
<View style={[styles.infoSection, {backgroundColor: `${theme.colors.primary}15`}]}>
|
||||
<Icon name="info-outline" size={24} color={theme.colors.primary} />
|
||||
<Text style={[styles.infoText, {color: theme.colors.text}]}>
|
||||
请扫描或输入载具号进行空载具入库操作
|
||||
|
|
@ -108,7 +135,10 @@ export const StockInEmpty: React.FC = () => {
|
|||
<Text style={[styles.inputLabel, {color: theme.colors.text}]}>
|
||||
载具号 <Text style={styles.required}>*</Text>
|
||||
</Text>
|
||||
<View style={[styles.inputWrapper, {borderColor: theme.colors.border}]}>
|
||||
<View style={[styles.inputWrapper, {
|
||||
borderColor: theme.colors.border,
|
||||
backgroundColor: `${theme.colors.background}CC`,
|
||||
}]}>
|
||||
<Icon name="qr-code-scanner" size={24} color={theme.colors.primary} style={styles.inputIcon} />
|
||||
<TextInput
|
||||
style={[styles.input, {color: theme.colors.text}]}
|
||||
|
|
@ -129,25 +159,27 @@ export const StockInEmpty: React.FC = () => {
|
|||
</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>
|
||||
<LinearGradient
|
||||
colors={[theme.colors.primary, theme.colors.secondary]}
|
||||
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>
|
||||
);
|
||||
|
|
@ -169,6 +201,19 @@ const styles = StyleSheet.create({
|
|||
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,
|
||||
},
|
||||
|
|
@ -186,7 +231,6 @@ const styles = StyleSheet.create({
|
|||
infoSection: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
backgroundColor: 'rgba(24, 144, 255, 0.1)',
|
||||
padding: 16,
|
||||
borderRadius: 8,
|
||||
marginBottom: 24,
|
||||
|
|
@ -214,7 +258,6 @@ const styles = StyleSheet.create({
|
|||
borderRadius: 8,
|
||||
height: 48,
|
||||
paddingHorizontal: 12,
|
||||
backgroundColor: 'rgba(255, 255, 255, 0.8)',
|
||||
},
|
||||
inputIcon: {
|
||||
marginRight: 8,
|
||||
|
|
@ -231,9 +274,6 @@ const styles = StyleSheet.create({
|
|||
submitButton: {
|
||||
height: 48,
|
||||
borderRadius: 24,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginTop: 32,
|
||||
elevation: 2,
|
||||
shadowColor: '#000',
|
||||
|
|
@ -241,6 +281,12 @@ const styles = StyleSheet.create({
|
|||
shadowOpacity: 0.1,
|
||||
shadowRadius: 2,
|
||||
},
|
||||
submitButtonContent: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
submitButtonDisabled: {
|
||||
opacity: 0.6,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ import {
|
|||
import {useNavigation} from '@react-navigation/native';
|
||||
import Icon from 'react-native-vector-icons/MaterialIcons';
|
||||
import {useTheme} from '../../contexts/ThemeContext';
|
||||
import LinearGradient from 'react-native-linear-gradient';
|
||||
import Svg, {Path} from 'react-native-svg';
|
||||
|
||||
interface PackageDataItem {
|
||||
id: string;
|
||||
|
|
@ -236,7 +238,11 @@ const StockInWheelManual: React.FC = () => {
|
|||
return (
|
||||
<View style={[styles.container, {backgroundColor: theme.colors.background}]}>
|
||||
{/* 头部导航栏 */}
|
||||
<View style={[styles.header, {backgroundColor: theme.colors.primary}]}>
|
||||
<LinearGradient
|
||||
colors={[theme.colors.primary, theme.colors.secondary, theme.colors.tertiary]}
|
||||
start={{x: 0, y: 0}}
|
||||
end={{x: 1, y: 0}}
|
||||
style={styles.header}>
|
||||
<TouchableOpacity
|
||||
style={styles.backButton}
|
||||
onPress={() => navigation.goBack()}>
|
||||
|
|
@ -246,285 +252,326 @@ const StockInWheelManual: React.FC = () => {
|
|||
手动码盘入库
|
||||
</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.tertiary}40`}
|
||||
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>
|
||||
|
||||
<ScrollView style={[styles.content, {backgroundColor: theme.colors.background}]}>
|
||||
{/* 信息提示区 */}
|
||||
<View style={[styles.infoSection, {backgroundColor: `${theme.colors.primary}15`}]}>
|
||||
<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.label, {color: theme.colors.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
|
||||
ref={vehicleInputRef}
|
||||
style={[styles.input, {color: theme.colors.text}]}
|
||||
value={vehicleCode}
|
||||
onChangeText={setVehicleCode}
|
||||
placeholder="请扫描或输入载具号"
|
||||
placeholderTextColor={theme.colors.textLight}
|
||||
/>
|
||||
{vehicleCode.length > 0 && (
|
||||
<TouchableOpacity
|
||||
onPress={() => setVehicleCode('')}
|
||||
style={styles.clearButton}>
|
||||
<Icon name="cancel" size={20} color={theme.colors.textLight} />
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
<View style={styles.mainContent}>
|
||||
<LinearGradient
|
||||
colors={theme.colors.gradients.contrast}
|
||||
style={StyleSheet.absoluteFill}
|
||||
start={{x: 0, y: 0}}
|
||||
end={{x: 1, y: 0}}
|
||||
/>
|
||||
<ScrollView contentContainerStyle={styles.scrollContent}>
|
||||
{/* 信息提示区 */}
|
||||
<View style={[styles.infoSection, {backgroundColor: `${theme.colors.primary}15`}]}>
|
||||
<Icon name="info-outline" size={24} color={theme.colors.primary} />
|
||||
<Text style={[styles.infoText, {color: theme.colors.text}]}>
|
||||
请先扫描载具号,然后添加物料信息进行码盘入库
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 条码输入区 */}
|
||||
<View style={styles.inputContainer}>
|
||||
<Text style={[styles.label, {color: theme.colors.text}]}>物料条码</Text>
|
||||
<View style={[styles.inputWrapper, {borderColor: theme.colors.border}]}>
|
||||
<Icon name="qr-code-2" size={24} color={theme.colors.primary} style={styles.inputIcon} />
|
||||
<TextInput
|
||||
ref={goodsInputRef}
|
||||
style={[styles.input, {color: theme.colors.text}]}
|
||||
value={goodsCode}
|
||||
onChangeText={setGoodsCode}
|
||||
placeholder="请扫描物料二维码"
|
||||
placeholderTextColor={theme.colors.textLight}
|
||||
/>
|
||||
{goodsCode.length > 0 && (
|
||||
<TouchableOpacity
|
||||
onPress={() => setGoodsCode('')}
|
||||
style={styles.clearButton}>
|
||||
<Icon name="cancel" size={20} color={theme.colors.textLight} />
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 选项区域 */}
|
||||
<View style={styles.optionsContainer}>
|
||||
{/* 区域选择 */}
|
||||
<View style={styles.optionGroup}>
|
||||
<Text style={[styles.optionLabel, {color: theme.colors.text}]}>区域</Text>
|
||||
<View style={styles.radioGroup}>
|
||||
<TouchableOpacity
|
||||
style={[
|
||||
styles.radioButton,
|
||||
{borderColor: theme.colors.border},
|
||||
areaID === '有卤' && styles.radioButtonActive,
|
||||
areaID === '有卤' && {backgroundColor: theme.colors.primary},
|
||||
]}
|
||||
onPress={() => setAreaID('有卤')}>
|
||||
<Text
|
||||
style={[
|
||||
styles.radioText,
|
||||
{color: theme.colors.text},
|
||||
areaID === '有卤' && {color: theme.colors.background},
|
||||
]}>
|
||||
有卤
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
style={[
|
||||
styles.radioButton,
|
||||
{borderColor: theme.colors.border},
|
||||
areaID === '无卤' && styles.radioButtonActive,
|
||||
areaID === '无卤' && {backgroundColor: theme.colors.primary},
|
||||
]}
|
||||
onPress={() => setAreaID('无卤')}>
|
||||
<Text
|
||||
style={[
|
||||
styles.radioText,
|
||||
{color: theme.colors.text},
|
||||
areaID === '无卤' && {color: theme.colors.background},
|
||||
]}>
|
||||
无卤
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
{/* 载具号输入区 */}
|
||||
<View style={styles.inputContainer}>
|
||||
<Text style={[styles.label, {color: theme.colors.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.primary} style={styles.inputIcon} />
|
||||
<TextInput
|
||||
ref={vehicleInputRef}
|
||||
style={[styles.input, {color: theme.colors.text}]}
|
||||
value={vehicleCode}
|
||||
onChangeText={setVehicleCode}
|
||||
placeholder="请扫描或输入载具号"
|
||||
placeholderTextColor={theme.colors.textLight}
|
||||
/>
|
||||
{vehicleCode.length > 0 && (
|
||||
<TouchableOpacity
|
||||
onPress={() => setVehicleCode('')}
|
||||
style={styles.clearButton}>
|
||||
<Icon name="cancel" size={20} color={theme.colors.textLight} />
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 工厂选择 */}
|
||||
<View style={styles.optionGroup}>
|
||||
<Text style={[styles.optionLabel, {color: theme.colors.text}]}>工厂</Text>
|
||||
<View style={styles.radioGroup}>
|
||||
<TouchableOpacity
|
||||
style={[
|
||||
styles.radioButton,
|
||||
{borderColor: theme.colors.border},
|
||||
factory === '二厂' && styles.radioButtonActive,
|
||||
factory === '二厂' && {backgroundColor: theme.colors.primary},
|
||||
]}
|
||||
onPress={() => setFactory('二厂')}>
|
||||
<Text
|
||||
style={[
|
||||
styles.radioText,
|
||||
{color: theme.colors.text},
|
||||
factory === '二厂' && {color: theme.colors.background},
|
||||
]}>
|
||||
二厂
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
style={[
|
||||
styles.radioButton,
|
||||
{borderColor: theme.colors.border},
|
||||
factory === '三厂' && styles.radioButtonActive,
|
||||
factory === '三厂' && {backgroundColor: theme.colors.primary},
|
||||
]}
|
||||
onPress={() => setFactory('三厂')}>
|
||||
<Text
|
||||
style={[
|
||||
styles.radioText,
|
||||
{color: theme.colors.text},
|
||||
factory === '三厂' && {color: theme.colors.background},
|
||||
]}>
|
||||
三厂
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
{/* 条码输入区 */}
|
||||
<View style={styles.inputContainer}>
|
||||
<Text style={[styles.label, {color: theme.colors.text}]}>物料条码</Text>
|
||||
<View style={[styles.inputWrapper, {
|
||||
borderColor: theme.colors.border,
|
||||
backgroundColor: `${theme.colors.background}CC`,
|
||||
}]}>
|
||||
<Icon name="qr-code-2" size={24} color={theme.colors.primary} style={styles.inputIcon} />
|
||||
<TextInput
|
||||
ref={goodsInputRef}
|
||||
style={[styles.input, {color: theme.colors.text}]}
|
||||
value={goodsCode}
|
||||
onChangeText={setGoodsCode}
|
||||
placeholder="请扫描物料二维码"
|
||||
placeholderTextColor={theme.colors.textLight}
|
||||
/>
|
||||
{goodsCode.length > 0 && (
|
||||
<TouchableOpacity
|
||||
onPress={() => setGoodsCode('')}
|
||||
style={styles.clearButton}>
|
||||
<Icon name="cancel" size={20} color={theme.colors.textLight} />
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 状态选择 - 改为与区域、工厂相同的样式 */}
|
||||
<View style={styles.optionGroup}>
|
||||
<Text style={[styles.optionLabel, {color: theme.colors.text}]}>状态</Text>
|
||||
<View style={styles.radioGroup}>
|
||||
<ScrollView horizontal showsHorizontalScrollIndicator={false}>
|
||||
<View style={styles.radioGroup}>
|
||||
{['合格', '不合格', '封存', '待检', '进口物料'].map((item) => (
|
||||
<TouchableOpacity
|
||||
key={item}
|
||||
style={[
|
||||
styles.radioButton,
|
||||
{borderColor: theme.colors.border},
|
||||
status === item && styles.radioButtonActive,
|
||||
status === item && {backgroundColor: theme.colors.primary},
|
||||
]}
|
||||
onPress={() => setStatus(item)}>
|
||||
<Text
|
||||
{/* 选项区域 */}
|
||||
<View style={styles.optionsContainer}>
|
||||
{/* 区域选择 */}
|
||||
<View style={styles.optionGroup}>
|
||||
<Text style={[styles.optionLabel, {color: theme.colors.text}]}>区域</Text>
|
||||
<View style={styles.radioGroup}>
|
||||
<TouchableOpacity
|
||||
style={[
|
||||
styles.radioButton,
|
||||
{borderColor: theme.colors.border},
|
||||
areaID === '有卤' && styles.radioButtonActive,
|
||||
areaID === '有卤' && {backgroundColor: theme.colors.primary},
|
||||
]}
|
||||
onPress={() => setAreaID('有卤')}>
|
||||
<Text
|
||||
style={[
|
||||
styles.radioText,
|
||||
{color: theme.colors.text},
|
||||
areaID === '有卤' && {color: theme.colors.background},
|
||||
]}>
|
||||
有卤
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
style={[
|
||||
styles.radioButton,
|
||||
{borderColor: theme.colors.border},
|
||||
areaID === '无卤' && styles.radioButtonActive,
|
||||
areaID === '无卤' && {backgroundColor: theme.colors.primary},
|
||||
]}
|
||||
onPress={() => setAreaID('无卤')}>
|
||||
<Text
|
||||
style={[
|
||||
styles.radioText,
|
||||
{color: theme.colors.text},
|
||||
areaID === '无卤' && {color: theme.colors.background},
|
||||
]}>
|
||||
无卤
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 工厂选择 */}
|
||||
<View style={styles.optionGroup}>
|
||||
<Text style={[styles.optionLabel, {color: theme.colors.text}]}>工厂</Text>
|
||||
<View style={styles.radioGroup}>
|
||||
<TouchableOpacity
|
||||
style={[
|
||||
styles.radioButton,
|
||||
{borderColor: theme.colors.border},
|
||||
factory === '二厂' && styles.radioButtonActive,
|
||||
factory === '二厂' && {backgroundColor: theme.colors.primary},
|
||||
]}
|
||||
onPress={() => setFactory('二厂')}>
|
||||
<Text
|
||||
style={[
|
||||
styles.radioText,
|
||||
{color: theme.colors.text},
|
||||
factory === '二厂' && {color: theme.colors.background},
|
||||
]}>
|
||||
二厂
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
style={[
|
||||
styles.radioButton,
|
||||
{borderColor: theme.colors.border},
|
||||
factory === '三厂' && styles.radioButtonActive,
|
||||
factory === '三厂' && {backgroundColor: theme.colors.primary},
|
||||
]}
|
||||
onPress={() => setFactory('三厂')}>
|
||||
<Text
|
||||
style={[
|
||||
styles.radioText,
|
||||
{color: theme.colors.text},
|
||||
factory === '三厂' && {color: theme.colors.background},
|
||||
]}>
|
||||
三厂
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 状态选择 - 改为与区域、工厂相同的样式 */}
|
||||
<View style={styles.optionGroup}>
|
||||
<Text style={[styles.optionLabel, {color: theme.colors.text}]}>状态</Text>
|
||||
<View style={styles.radioGroup}>
|
||||
<ScrollView horizontal showsHorizontalScrollIndicator={false}>
|
||||
<View style={styles.radioGroup}>
|
||||
{['合格', '不合格', '封存', '待检', '进口物料'].map((item) => (
|
||||
<TouchableOpacity
|
||||
key={item}
|
||||
style={[
|
||||
styles.radioText,
|
||||
{color: theme.colors.text},
|
||||
status === item && {color: theme.colors.background},
|
||||
]}>
|
||||
{item}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</View>
|
||||
</ScrollView>
|
||||
styles.radioButton,
|
||||
{borderColor: theme.colors.border},
|
||||
status === item && styles.radioButtonActive,
|
||||
status === item && {backgroundColor: theme.colors.primary},
|
||||
]}
|
||||
onPress={() => setStatus(item)}>
|
||||
<Text
|
||||
style={[
|
||||
styles.radioText,
|
||||
{color: theme.colors.text},
|
||||
status === item && {color: theme.colors.background},
|
||||
]}>
|
||||
{item}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</View>
|
||||
</ScrollView>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 操作按钮区 */}
|
||||
<View style={styles.buttonGroup}>
|
||||
<TouchableOpacity
|
||||
style={[styles.button, styles.addButton, {backgroundColor: theme.colors.primary}]}
|
||||
onPress={resolveCode}>
|
||||
<Icon name="add-circle-outline" size={24} color={theme.colors.background} style={styles.buttonIcon} />
|
||||
<Text style={[styles.buttonText, {color: theme.colors.background}]}>
|
||||
添加物料
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
{/* 操作按钮区 */}
|
||||
<View style={styles.buttonGroup}>
|
||||
<LinearGradient
|
||||
colors={[theme.colors.primary, theme.colors.secondary]}
|
||||
start={{x: 0, y: 0}}
|
||||
end={{x: 1, y: 0}}
|
||||
style={styles.button}>
|
||||
<TouchableOpacity
|
||||
style={styles.buttonContent}
|
||||
onPress={resolveCode}>
|
||||
<Icon name="add-circle-outline" size={24} color={theme.colors.background} style={styles.buttonIcon} />
|
||||
<Text style={[styles.buttonText, {color: theme.colors.background}]}>
|
||||
添加物料
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</LinearGradient>
|
||||
|
||||
<TouchableOpacity
|
||||
style={[styles.button, styles.completeButton, {backgroundColor: theme.colors.success}]}
|
||||
onPress={wheelComplete}>
|
||||
<Icon name="check-circle-outline" size={24} color={theme.colors.background} style={styles.buttonIcon} />
|
||||
<Text style={[styles.buttonText, {color: theme.colors.background}]}>
|
||||
码盘完成
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{/* 物料列表 */}
|
||||
<View style={styles.tableContainer}>
|
||||
<View style={styles.tableHeader}>
|
||||
<Icon name="list-alt" size={24} color={theme.colors.primary} />
|
||||
<Text style={[styles.tableTitle, {color: theme.colors.text}]}>
|
||||
已添加物料 ({packageData.length})
|
||||
</Text>
|
||||
<LinearGradient
|
||||
colors={[theme.colors.success, theme.colors.secondary]}
|
||||
start={{x: 0, y: 0}}
|
||||
end={{x: 1, y: 0}}
|
||||
style={styles.button}>
|
||||
<TouchableOpacity
|
||||
style={styles.buttonContent}
|
||||
onPress={wheelComplete}>
|
||||
<Icon name="check-circle-outline" size={24} color={theme.colors.background} style={styles.buttonIcon} />
|
||||
<Text style={[styles.buttonText, {color: theme.colors.background}]}>
|
||||
码盘完成
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</LinearGradient>
|
||||
</View>
|
||||
|
||||
{packageData.map((item, index) => (
|
||||
<View
|
||||
key={item.id}
|
||||
style={[
|
||||
styles.card,
|
||||
{
|
||||
backgroundColor: theme.colors.background,
|
||||
borderColor: theme.colors.border,
|
||||
},
|
||||
]}>
|
||||
{/* 卡片头部 */}
|
||||
<View style={styles.cardHeader}>
|
||||
<View style={styles.cardHeaderLeft}>
|
||||
<Text style={[styles.cardHeaderText, {color: theme.colors.text}]}>
|
||||
序号:{item.id}
|
||||
</Text>
|
||||
<Text style={[styles.cardHeaderText, {color: theme.colors.textLight}]}>
|
||||
采购单号:{item.segment1}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.cardActions}>
|
||||
<TouchableOpacity
|
||||
style={[styles.cardActionButton, {backgroundColor: `${theme.colors.primary}15`}]}
|
||||
onPress={() => showDetails(item)}>
|
||||
<Icon name="info-outline" size={20} color={theme.colors.primary} />
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
style={[styles.cardActionButton, {backgroundColor: `${theme.colors.error}15`}]}
|
||||
onPress={() => deleteItem(item.id)}>
|
||||
<Icon name="delete-outline" size={20} color={theme.colors.error} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
{/* 物料列表 */}
|
||||
<View style={styles.tableContainer}>
|
||||
<View style={styles.tableHeader}>
|
||||
<Icon name="list-alt" size={24} color={theme.colors.primary} />
|
||||
<Text style={[styles.tableTitle, {color: theme.colors.text}]}>
|
||||
已添加物料 ({packageData.length})
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
{/* 卡片内容 */}
|
||||
<View style={styles.cardContent}>
|
||||
<View style={styles.cardRow}>
|
||||
<View style={styles.cardField}>
|
||||
<Text style={[styles.cardLabel, {color: theme.colors.textLight}]}>物料号</Text>
|
||||
<Text style={[styles.cardValue, {color: theme.colors.text}]}>{item.itemId}</Text>
|
||||
{packageData.map((item, index) => (
|
||||
<View
|
||||
key={item.id}
|
||||
style={[styles.card]}>
|
||||
<LinearGradient
|
||||
colors={theme.colors.gradients.contrast}
|
||||
style={[StyleSheet.absoluteFill, {borderRadius: 12}]}
|
||||
start={{x: 0, y: 0}}
|
||||
end={{x: 1, y: 0}}
|
||||
/>
|
||||
{/* 卡片头部 */}
|
||||
<View style={styles.cardHeader}>
|
||||
<View style={styles.cardHeaderLeft}>
|
||||
<Text style={[styles.cardHeaderText, {color: theme.colors.background}]}>
|
||||
序号:{item.id}
|
||||
</Text>
|
||||
<Text style={[styles.cardHeaderText, {color: theme.colors.background}]}>
|
||||
采购单号:{item.segment1}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.cardField}>
|
||||
<Text style={[styles.cardLabel, {color: theme.colors.textLight}]}>批次号</Text>
|
||||
<Text style={[styles.cardValue, {color: theme.colors.text}]}>{item.batch}</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={styles.cardRow}>
|
||||
<View style={styles.cardField}>
|
||||
<Text style={[styles.cardLabel, {color: theme.colors.textLight}]}>数量</Text>
|
||||
<View style={styles.cardActions}>
|
||||
<TouchableOpacity
|
||||
style={styles.editableValue}
|
||||
onPress={() => modifyNumber(item.id)}>
|
||||
<Text style={[styles.cardValue, {color: theme.colors.primary}]}>
|
||||
{item.quantity}
|
||||
</Text>
|
||||
<Icon name="edit" size={16} color={theme.colors.primary} />
|
||||
style={[styles.cardActionButton, {backgroundColor: `${theme.colors.primary}15`}]}
|
||||
onPress={() => showDetails(item)}>
|
||||
<Icon name="info-outline" size={20} color={theme.colors.primary} />
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
style={[styles.cardActionButton, {backgroundColor: `${theme.colors.error}15`}]}
|
||||
onPress={() => deleteItem(item.id)}>
|
||||
<Icon name="delete-outline" size={20} color={theme.colors.error} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View style={styles.cardField}>
|
||||
<Text style={[styles.cardLabel, {color: theme.colors.textLight}]}>重量</Text>
|
||||
<Text style={[styles.cardValue, {color: theme.colors.text}]}>{item.weight}</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={styles.cardRow}>
|
||||
<View style={styles.cardField}>
|
||||
<Text style={[styles.cardLabel, {color: theme.colors.textLight}]}>生产日期</Text>
|
||||
<Text style={[styles.cardValue, {color: theme.colors.text}]}>{item.productData}</Text>
|
||||
{/* 卡片内容 */}
|
||||
<View style={styles.cardContent}>
|
||||
<View style={styles.cardRow}>
|
||||
<View style={styles.cardField}>
|
||||
<Text style={[styles.cardLabel, {color: theme.colors.background}]}>物料号</Text>
|
||||
<Text style={[styles.cardValue, {color: theme.colors.background}]}>{item.itemId}</Text>
|
||||
</View>
|
||||
<View style={styles.cardField}>
|
||||
<Text style={[styles.cardLabel, {color: theme.colors.background}]}>批次号</Text>
|
||||
<Text style={[styles.cardValue, {color: theme.colors.background}]}>{item.batch}</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={styles.cardRow}>
|
||||
<View style={styles.cardField}>
|
||||
<Text style={[styles.cardLabel, {color: theme.colors.background}]}>数量</Text>
|
||||
<TouchableOpacity
|
||||
style={styles.editableValue}
|
||||
onPress={() => modifyNumber(item.id)}>
|
||||
<Text style={[styles.cardValue, {color: theme.colors.background}]}>
|
||||
{item.quantity}
|
||||
</Text>
|
||||
<Icon name="edit" size={16} color={theme.colors.background} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View style={styles.cardField}>
|
||||
<Text style={[styles.cardLabel, {color: theme.colors.background}]}>重量</Text>
|
||||
<Text style={[styles.cardValue, {color: theme.colors.background}]}>{item.weight}</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={styles.cardRow}>
|
||||
<View style={styles.cardField}>
|
||||
<Text style={[styles.cardLabel, {color: theme.colors.background}]}>生产日期</Text>
|
||||
<Text style={[styles.cardValue, {color: theme.colors.background}]}>{item.productData}</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
</ScrollView>
|
||||
))}
|
||||
</View>
|
||||
</ScrollView>
|
||||
</View>
|
||||
|
||||
{loading && (
|
||||
<View style={[styles.loadingOverlay, {backgroundColor: 'rgba(0, 0, 0, 0.7)'}]}>
|
||||
|
|
@ -544,6 +591,14 @@ const styles = StyleSheet.create({
|
|||
container: {
|
||||
flex: 1,
|
||||
},
|
||||
mainContent: {
|
||||
flex: 1,
|
||||
position: 'relative',
|
||||
},
|
||||
scrollContent: {
|
||||
flexGrow: 1,
|
||||
padding: 16,
|
||||
},
|
||||
header: {
|
||||
height: 56,
|
||||
flexDirection: 'row',
|
||||
|
|
@ -556,6 +611,19 @@ const styles = StyleSheet.create({
|
|||
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,
|
||||
},
|
||||
|
|
@ -566,10 +634,6 @@ const styles = StyleSheet.create({
|
|||
headerRight: {
|
||||
width: 40,
|
||||
},
|
||||
content: {
|
||||
flex: 1,
|
||||
padding: 16,
|
||||
},
|
||||
infoSection: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
|
|
@ -650,15 +714,18 @@ const styles = StyleSheet.create({
|
|||
flex: 1,
|
||||
height: 48,
|
||||
borderRadius: 24,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
elevation: 2,
|
||||
shadowColor: '#000',
|
||||
shadowOffset: {width: 0, height: 2},
|
||||
shadowOpacity: 0.1,
|
||||
shadowRadius: 2,
|
||||
},
|
||||
buttonContent: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
buttonIcon: {
|
||||
marginRight: 8,
|
||||
},
|
||||
|
|
@ -683,13 +750,8 @@ const styles = StyleSheet.create({
|
|||
},
|
||||
card: {
|
||||
borderRadius: 12,
|
||||
borderWidth: 1,
|
||||
marginBottom: 12,
|
||||
elevation: 2,
|
||||
shadowColor: '#000',
|
||||
shadowOffset: {width: 0, height: 2},
|
||||
shadowOpacity: 0.1,
|
||||
shadowRadius: 2,
|
||||
overflow: 'hidden',
|
||||
},
|
||||
cardHeader: {
|
||||
flexDirection: 'row',
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user