图片选择
This commit is contained in:
parent
c56e54df01
commit
0fd914b3aa
36
package-lock.json
generated
36
package-lock.json
generated
|
@ -30,8 +30,10 @@
|
|||
"react-native-contacts": "^8.0.4",
|
||||
"react-native-fs": "^2.20.0",
|
||||
"react-native-gesture-handler": "^2.20.2",
|
||||
"react-native-image-picker": "^7.2.3",
|
||||
"react-native-linear-gradient": "^2.8.3",
|
||||
"react-native-permissions": "^5.2.1",
|
||||
"react-native-qrcode": "^0.2.7",
|
||||
"react-native-qrcode-scanner": "^1.5.5",
|
||||
"react-native-qrcode-svg": "^6.3.12",
|
||||
"react-native-reanimated": "^3.16.1",
|
||||
|
@ -7535,6 +7537,15 @@
|
|||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/create-react-class": {
|
||||
"version": "15.7.0",
|
||||
"resolved": "https://registry.npmmirror.com/create-react-class/-/create-react-class-15.7.0.tgz",
|
||||
"integrity": "sha512-QZv4sFWG9S5RUvkTYWbflxeZX+JG7Cz0Tn33rQBJ+WFQTqTfUTjMjiv9tnfXazjsO5r0KhPs+AqCjyrQX6h2ng==",
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.3.1",
|
||||
"object-assign": "^4.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-fetch": {
|
||||
"version": "3.1.8",
|
||||
"resolved": "https://registry.npmmirror.com/cross-fetch/-/cross-fetch-3.1.8.tgz",
|
||||
|
@ -13964,6 +13975,11 @@
|
|||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/qr.js": {
|
||||
"version": "0.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/qr.js/-/qr.js-0.0.0.tgz",
|
||||
"integrity": "sha512-c4iYnWb+k2E+vYpRimHqSu575b1/wKl4XFeJGpFmrJQz5I88v9aY2czh7s0w36srfCM1sXgC/xpoJz5dJfq+OQ=="
|
||||
},
|
||||
"node_modules/qrcode": {
|
||||
"version": "1.5.4",
|
||||
"resolved": "https://registry.npmmirror.com/qrcode/-/qrcode-1.5.4.tgz",
|
||||
|
@ -14377,7 +14393,6 @@
|
|||
"version": "2.20.0",
|
||||
"resolved": "https://registry.npmmirror.com/react-native-fs/-/react-native-fs-2.20.0.tgz",
|
||||
"integrity": "sha512-VkTBzs7fIDUiy/XajOSNk0XazFE9l+QlMAce7lGuebZcag5CnjszB+u4BdqzwaQOdcYb5wsJIsqq4kxInIRpJQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"base-64": "^0.1.0",
|
||||
"utf8": "^3.0.0"
|
||||
|
@ -14413,6 +14428,15 @@
|
|||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-image-picker": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmmirror.com/react-native-image-picker/-/react-native-image-picker-7.2.3.tgz",
|
||||
"integrity": "sha512-zKIZUlQNU3EtqizsXSH92zPeve4vpUrsqHu2kkpCxWE9TZhJFZBb+irDsBOY8J21k0+Edgt06TMQGJ+iPUIXyA==",
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-linear-gradient": {
|
||||
"version": "2.8.3",
|
||||
"resolved": "https://registry.npmmirror.com/react-native-linear-gradient/-/react-native-linear-gradient-2.8.3.tgz",
|
||||
|
@ -14439,6 +14463,16 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-qrcode": {
|
||||
"version": "0.2.7",
|
||||
"resolved": "https://registry.npmmirror.com/react-native-qrcode/-/react-native-qrcode-0.2.7.tgz",
|
||||
"integrity": "sha512-Xvc3T1h95zA9tbRxiMkKethDYpPwKcqDPIHe9Cxt7pM+lma9dSzd6yXGGLGeZmFU/SmHMK+4bTnDltUv1s4Jnw==",
|
||||
"dependencies": {
|
||||
"create-react-class": "^15.6.0",
|
||||
"prop-types": "^15.5.10",
|
||||
"qr.js": "0.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-qrcode-scanner": {
|
||||
"version": "1.5.5",
|
||||
"resolved": "https://registry.npmmirror.com/react-native-qrcode-scanner/-/react-native-qrcode-scanner-1.5.5.tgz",
|
||||
|
|
|
@ -32,8 +32,10 @@
|
|||
"react-native-contacts": "^8.0.4",
|
||||
"react-native-fs": "^2.20.0",
|
||||
"react-native-gesture-handler": "^2.20.2",
|
||||
"react-native-image-picker": "^7.2.3",
|
||||
"react-native-linear-gradient": "^2.8.3",
|
||||
"react-native-permissions": "^5.2.1",
|
||||
"react-native-qrcode": "^0.2.7",
|
||||
"react-native-qrcode-scanner": "^1.5.5",
|
||||
"react-native-qrcode-svg": "^6.3.12",
|
||||
"react-native-reanimated": "^3.16.1",
|
||||
|
|
|
@ -7,16 +7,28 @@ import {
|
|||
Keyboard,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
Modal,
|
||||
Image
|
||||
Image,
|
||||
Modal
|
||||
} from 'react-native';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import { StackNavigationProp } from '@react-navigation/stack';
|
||||
import { rpx } from '../../utils/rpx';
|
||||
import QRCodeScanner from 'react-native-qrcode-scanner';
|
||||
import { RNCamera } from 'react-native-camera';
|
||||
import { TopNavigation, TopNavigationAction, Icon } from '@ui-kitten/components';
|
||||
import { TopNavigation, TopNavigationAction, Icon, Popover, Button } from '@ui-kitten/components';
|
||||
import Toast from 'react-native-toast-message';
|
||||
import { launchImageLibrary } from 'react-native-image-picker';
|
||||
|
||||
// 假设你有一个函数 checkIfImageContainsQRCode 和 decodeQRCodeFromImage
|
||||
const checkIfImageContainsQRCode = async (imageUri: string): Promise<boolean> => {
|
||||
// 实现判断图片是否包含二维码的逻辑
|
||||
return true; // 示例返回值
|
||||
};
|
||||
|
||||
const decodeQRCodeFromImage = async (imageUri: string): Promise<string> => {
|
||||
// 实现二维码解析的逻辑
|
||||
return 'example_sn=123456'; // 示例返回值
|
||||
};
|
||||
|
||||
type RootStackParamList = {
|
||||
Home: undefined;
|
||||
|
@ -34,10 +46,15 @@ const BackIcon = (props: any) => (
|
|||
<Icon {...props} name='arrow-back-outline'/>
|
||||
);
|
||||
|
||||
const MoreIcon = (props: any) => (
|
||||
<Icon {...props} name='more-vertical'/>
|
||||
);
|
||||
|
||||
const SnBind = () => {
|
||||
const navigation = useNavigation<NavigationProp>();
|
||||
const [sn, setSn] = useState('');
|
||||
const [isScanning, setIsScanning] = useState(false);
|
||||
const [popoverVisible, setPopoverVisible] = useState(false);
|
||||
|
||||
const navigateBack = () => {
|
||||
navigation.goBack();
|
||||
|
@ -47,6 +64,10 @@ const SnBind = () => {
|
|||
<TopNavigationAction icon={BackIcon} onPress={navigateBack}/>
|
||||
);
|
||||
|
||||
const togglePopover = () => {
|
||||
setPopoverVisible(!popoverVisible);
|
||||
};
|
||||
|
||||
const handlePress = () => {
|
||||
if (!sn.trim()) {
|
||||
Toast.show({
|
||||
|
@ -58,8 +79,59 @@ const SnBind = () => {
|
|||
navigation.navigate('ConfirmBind', { sn: sn.trim() });
|
||||
};
|
||||
|
||||
const handleScan = () => {
|
||||
setIsScanning(true);
|
||||
const handleImagePicker = () => {
|
||||
setPopoverVisible(false);
|
||||
launchImageLibrary({ mediaType: 'photo' }, (response) => {
|
||||
if (response.didCancel) {
|
||||
console.log('User cancelled image picker');
|
||||
} else if (response.errorCode) {
|
||||
console.log('ImagePicker Error: ', response.errorMessage);
|
||||
} else if (response.assets && response.assets.length > 0) {
|
||||
const imageUri = response.assets[0].uri;
|
||||
// 判断图片是否包含二维码
|
||||
checkIfImageContainsQRCode(imageUri)
|
||||
.then((containsQRCode) => {
|
||||
if (!containsQRCode) {
|
||||
Toast.show({
|
||||
type: 'error',
|
||||
text1: '图片不包含二维码',
|
||||
});
|
||||
return;
|
||||
}
|
||||
// 使用二维码解析库解析图片
|
||||
decodeQRCodeFromImage(imageUri)
|
||||
.then((data) => {
|
||||
console.log('二维码内容:', data);
|
||||
// 处理解析结果
|
||||
const snMatch = data.match(/[?&]sn=([^&]+)/);
|
||||
if (snMatch && snMatch[1]) {
|
||||
setSn(snMatch[1]);
|
||||
Toast.show({
|
||||
type: 'success',
|
||||
text1: '图片解析成功',
|
||||
});
|
||||
} else {
|
||||
Toast.show({
|
||||
type: 'error',
|
||||
text1: '未找到有效的SN码',
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
Toast.show({
|
||||
type: 'error',
|
||||
text1: '图片解析失败或不包含二维码',
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
Toast.show({
|
||||
type: 'error',
|
||||
text1: '无法判断图片内容',
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const onSuccess = (e: { data: string }) => {
|
||||
|
@ -113,12 +185,26 @@ const SnBind = () => {
|
|||
value={sn}
|
||||
onChangeText={setSn}
|
||||
/>
|
||||
<TouchableOpacity onPress={handleScan} style={styles.scanButton}>
|
||||
<Image
|
||||
source={{ uri: 'https://lxnapi.ccttiot.com/bike/img/static/uSPtEFPtKlWIAKNrDtiQ' }}
|
||||
style={styles.scanIcon}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
<Popover
|
||||
anchor={() => (
|
||||
<TouchableOpacity onPress={togglePopover} style={styles.scanButton}>
|
||||
<Image
|
||||
source={{ uri: 'https://lxnapi.ccttiot.com/bike/img/static/uSPtEFPtKlWIAKNrDtiQ' }}
|
||||
style={styles.scanIcon}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
visible={popoverVisible}
|
||||
onBackdropPress={togglePopover}
|
||||
>
|
||||
<View>
|
||||
<Button onPress={handleImagePicker}>从相册选择</Button>
|
||||
<Button onPress={() => {
|
||||
setPopoverVisible(false);
|
||||
setIsScanning(true);
|
||||
}}>扫描二维码</Button>
|
||||
</View>
|
||||
</Popover>
|
||||
</View>
|
||||
|
||||
{/* 提示文本 */}
|
||||
|
@ -245,11 +331,17 @@ const styles = StyleSheet.create({
|
|||
backgroundColor: '#4297F3',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: 2 },
|
||||
shadowOpacity: 0.3,
|
||||
shadowRadius: 4,
|
||||
elevation: 5,
|
||||
},
|
||||
scanIcon: {
|
||||
width: rpx(88),
|
||||
height: rpx(88),
|
||||
resizeMode: 'contain',
|
||||
tintColor: '#fff',
|
||||
},
|
||||
tip: {
|
||||
marginTop: rpx(40),
|
||||
|
|
29
yarn.lock
29
yarn.lock
|
@ -3834,6 +3834,14 @@ create-jest@^29.7.0:
|
|||
jest-util "^29.7.0"
|
||||
prompts "^2.0.1"
|
||||
|
||||
create-react-class@^15.6.0:
|
||||
version "15.7.0"
|
||||
resolved "https://registry.npmmirror.com/create-react-class/-/create-react-class-15.7.0.tgz"
|
||||
integrity sha512-QZv4sFWG9S5RUvkTYWbflxeZX+JG7Cz0Tn33rQBJ+WFQTqTfUTjMjiv9tnfXazjsO5r0KhPs+AqCjyrQX6h2ng==
|
||||
dependencies:
|
||||
loose-envify "^1.3.1"
|
||||
object-assign "^4.1.1"
|
||||
|
||||
cross-fetch@^3.1.5:
|
||||
version "3.1.8"
|
||||
resolved "https://registry.npmmirror.com/cross-fetch/-/cross-fetch-3.1.8.tgz"
|
||||
|
@ -6521,7 +6529,7 @@ logkitty@^0.7.1:
|
|||
dayjs "^1.8.15"
|
||||
yargs "^15.1.0"
|
||||
|
||||
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
|
||||
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1, loose-envify@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.npmmirror.com/loose-envify/-/loose-envify-1.4.0.tgz"
|
||||
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
|
||||
|
@ -7671,6 +7679,11 @@ pure-rand@^6.0.0:
|
|||
resolved "https://registry.npmmirror.com/pure-rand/-/pure-rand-6.1.0.tgz"
|
||||
integrity sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==
|
||||
|
||||
qr.js@0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.npmmirror.com/qr.js/-/qr.js-0.0.0.tgz"
|
||||
integrity sha512-c4iYnWb+k2E+vYpRimHqSu575b1/wKl4XFeJGpFmrJQz5I88v9aY2czh7s0w36srfCM1sXgC/xpoJz5dJfq+OQ==
|
||||
|
||||
qrcode-terminal@0.11.0:
|
||||
version "0.11.0"
|
||||
resolved "https://registry.npmmirror.com/qrcode-terminal/-/qrcode-terminal-0.11.0.tgz"
|
||||
|
@ -7810,6 +7823,11 @@ react-native-gesture-handler@^2.20.2, "react-native-gesture-handler@>= 1.0.0":
|
|||
invariant "^2.2.4"
|
||||
prop-types "^15.7.2"
|
||||
|
||||
react-native-image-picker@^7.2.3:
|
||||
version "7.2.3"
|
||||
resolved "https://registry.npmmirror.com/react-native-image-picker/-/react-native-image-picker-7.2.3.tgz"
|
||||
integrity sha512-zKIZUlQNU3EtqizsXSH92zPeve4vpUrsqHu2kkpCxWE9TZhJFZBb+irDsBOY8J21k0+Edgt06TMQGJ+iPUIXyA==
|
||||
|
||||
react-native-linear-gradient@^2.8.3:
|
||||
version "2.8.3"
|
||||
resolved "https://registry.npmmirror.com/react-native-linear-gradient/-/react-native-linear-gradient-2.8.3.tgz"
|
||||
|
@ -7843,6 +7861,15 @@ react-native-qrcode-svg@^6.3.12:
|
|||
qrcode "^1.5.1"
|
||||
text-encoding "^0.7.0"
|
||||
|
||||
react-native-qrcode@^0.2.7:
|
||||
version "0.2.7"
|
||||
resolved "https://registry.npmmirror.com/react-native-qrcode/-/react-native-qrcode-0.2.7.tgz"
|
||||
integrity sha512-Xvc3T1h95zA9tbRxiMkKethDYpPwKcqDPIHe9Cxt7pM+lma9dSzd6yXGGLGeZmFU/SmHMK+4bTnDltUv1s4Jnw==
|
||||
dependencies:
|
||||
create-react-class "^15.6.0"
|
||||
prop-types "^15.5.10"
|
||||
qr.js "0.0.0"
|
||||
|
||||
react-native-reanimated@^3.16.1:
|
||||
version "3.16.3"
|
||||
resolved "https://registry.npmmirror.com/react-native-reanimated/-/react-native-reanimated-3.16.3.tgz"
|
||||
|
|
Loading…
Reference in New Issue
Block a user