|
|
@@ -0,0 +1,270 @@
|
|
|
+/**
|
|
|
+ * 扫描二维码
|
|
|
+ * @邠心vbe on 2021/03/24
|
|
|
+ * 升级到 react-native-vision-camera
|
|
|
+ */
|
|
|
+/* eslint-disable no-undef */
|
|
|
+import React, { Component, useEffect, useState } from 'react'
|
|
|
+import { Pressable, StyleSheet, View } from 'react-native'
|
|
|
+import { Camera, useCameraDevice, useCodeScanner } from 'react-native-vision-camera';
|
|
|
+import apiCharge from '../../api/apiCharge';
|
|
|
+import { PageList } from '../Router';
|
|
|
+import Dialog from '../../components/Dialog';
|
|
|
+import app from '../../../app.json';
|
|
|
+import { Vibration } from 'react-native';
|
|
|
+
|
|
|
+export const QRResult = {
|
|
|
+ haveResult: () => {
|
|
|
+ return global.QrCodeResult && global.QrCodeResult.connectorPk;
|
|
|
+ },
|
|
|
+ setResult: (info) => {
|
|
|
+ global.QrCodeResult = info;
|
|
|
+ },
|
|
|
+ getResult: () => {
|
|
|
+ return global.QrCodeResult;
|
|
|
+ },
|
|
|
+ clearResult: () => {
|
|
|
+ global.QrCodeResult = {};
|
|
|
+ },
|
|
|
+ applyInputStation: (text, sitePk, back) => {
|
|
|
+ if (text.indexOf('-') > 0) {
|
|
|
+ const arr = text.split('-');
|
|
|
+ if (arr.length >= 2) {
|
|
|
+ let bid = '', cid = '';
|
|
|
+ for (let i = 0; i < arr.length; i++) {
|
|
|
+ let sb = arr[i]?.trim();
|
|
|
+ if (i == (arr.length-1)) {
|
|
|
+ cid = sb;
|
|
|
+ } else {
|
|
|
+ if (i > 0) {
|
|
|
+ bid += '-';
|
|
|
+ }
|
|
|
+ bid += sb;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const qr = {
|
|
|
+ sitePk: sitePk,
|
|
|
+ chargeBoxId: bid,
|
|
|
+ connectorId: cid
|
|
|
+ }
|
|
|
+ console.log('====================================');
|
|
|
+ console.log(qr);
|
|
|
+ console.log('====================================');
|
|
|
+ Dialog.showProgressDialog();
|
|
|
+ apiCharge.checkQRStatus(qr).then(res => {
|
|
|
+ Dialog.dismissLoading();
|
|
|
+ if (res.data && res.data.chargeBoxId) {
|
|
|
+ QRResult.setResult(res.data);
|
|
|
+ back(true)
|
|
|
+ }
|
|
|
+ }).catch(({err, code}) => {
|
|
|
+ Dialog.dismissLoading();
|
|
|
+ back(false, '')
|
|
|
+ Dialog.showDialog({
|
|
|
+ title: 'Error',
|
|
|
+ message: err,
|
|
|
+ showCancel: false,
|
|
|
+ callback: btn => {
|
|
|
+ if (code == 5194 && btn == Dialog.BUTTON_OK) {
|
|
|
+ startPage(PageList.myVehicles);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ back(false, 'Station ID is incorrect');
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ back(false, 'Station ID is incorrect');
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 函数组件:QR码扫描器
|
|
|
+const QRScanner = ({ onCodeScanned, flashLight, isActive }) => {
|
|
|
+ const [hasPermission, setHasPermission] = useState(false);
|
|
|
+ const device = useCameraDevice('back');
|
|
|
+ useEffect(() => {
|
|
|
+ (async () => {
|
|
|
+ const status = await Camera.requestCameraPermission();
|
|
|
+ setHasPermission(status == 'granted');
|
|
|
+ })();
|
|
|
+ }, []);
|
|
|
+ const codeScanner = useCodeScanner({
|
|
|
+ codeTypes: ['qr'],
|
|
|
+ onCodeScanned: (codes) => {
|
|
|
+ if (codes.length > 0 && isActive) {
|
|
|
+ const code = codes[0];
|
|
|
+ onCodeScanned({ data: code.value });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ });
|
|
|
+
|
|
|
+ return (
|
|
|
+ (device && hasPermission) && (<>
|
|
|
+ <Camera
|
|
|
+ style={{width: $width, height: $vh(110)}}
|
|
|
+ device={device}
|
|
|
+ isActive={isActive}
|
|
|
+ codeScanner={codeScanner}
|
|
|
+ enableZoomGesture={true}
|
|
|
+ photo={false}
|
|
|
+ video={false}
|
|
|
+ audio={false}
|
|
|
+ resizeMode="cover"
|
|
|
+ torch={flashLight ? 'on' : 'off'}
|
|
|
+ />
|
|
|
+ </>)
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+export default class QRScan extends Component {
|
|
|
+
|
|
|
+ constructor(props) {
|
|
|
+ super(props);
|
|
|
+ this.state={
|
|
|
+ isResult: true,
|
|
|
+ params: this.props.route.params,
|
|
|
+ flashLight: false
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ componentDidMount() {
|
|
|
+ this.props.navigation.addListener('focus', () => {
|
|
|
+ setTimeout(() => {
|
|
|
+ this.setState({
|
|
|
+ isResult: false
|
|
|
+ });
|
|
|
+ }, 200);
|
|
|
+ });
|
|
|
+ this.props.navigation.addListener('beforeRemove', (e) => {
|
|
|
+ if (!this.state.isResult) {
|
|
|
+ e.preventDefault();
|
|
|
+ this.setState({
|
|
|
+ isResult: true
|
|
|
+ }, () => {
|
|
|
+ setTimeout(() => {
|
|
|
+ goBack();
|
|
|
+ }, 300);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ scanResult = (msg) => {
|
|
|
+ this.setState({
|
|
|
+ isResult: true
|
|
|
+ });
|
|
|
+ Vibration.vibrate(100);
|
|
|
+ console.log("result2", msg);
|
|
|
+ if (msg.indexOf('::') > 0) {
|
|
|
+ const arr = msg.split('::');
|
|
|
+ if (arr.length == 2) {
|
|
|
+ const qr = {
|
|
|
+ chargeBoxId: arr[0],
|
|
|
+ connectorId: arr[1]
|
|
|
+ }
|
|
|
+ if (this.state.params.id) {
|
|
|
+ qr.sitePk = this.state.params.id
|
|
|
+ }
|
|
|
+ this.getChargeDetail(qr);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ const qr = {
|
|
|
+ qrContent: msg
|
|
|
+ }
|
|
|
+ if (this.state.params.id) {
|
|
|
+ qr.sitePk = this.state.params.id
|
|
|
+ }
|
|
|
+ this.getChargeDetail(qr);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Dialog.showDialog({
|
|
|
+ title: 'Error',
|
|
|
+ message: 'It\'s not a legal QR code',
|
|
|
+ showCancel: false,
|
|
|
+ callback: (e) => {
|
|
|
+ this.setState({
|
|
|
+ isResult: false
|
|
|
+ });
|
|
|
+ }});
|
|
|
+ }
|
|
|
+
|
|
|
+ getChargeDetail(qr) {
|
|
|
+ console.log('===============SCAN QR===============');
|
|
|
+ console.log(qr);
|
|
|
+ console.log('===============SCAN QR===============');
|
|
|
+ apiCharge.checkQRStatus(qr).then(res => {
|
|
|
+ if (res.data && res.data.chargeBoxId) {
|
|
|
+ QRResult.setResult(res.data);
|
|
|
+ if (res.data.sitePk) {
|
|
|
+ if (this.state.params.actionDetail) {
|
|
|
+ startPage(PageList.chargeDetailPage, {stationInfo: {id: res.data.sitePk}, action: 'qr', from: PageList.home});
|
|
|
+ } else {
|
|
|
+ goBack();
|
|
|
+ }
|
|
|
+ //startPage(PageList.chargeDetail, {stationInfo: {id: res.data.sitePk}, action: 'qr'});
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }).catch(({err, code}) => {
|
|
|
+ Dialog.showDialog({
|
|
|
+ title: 'Error',
|
|
|
+ message: err,
|
|
|
+ showCancel: false,
|
|
|
+ callback: (btn) => {
|
|
|
+ this.setState({
|
|
|
+ isResult: false
|
|
|
+ });
|
|
|
+ if (code == 5194 && btn == Dialog.BUTTON_OK && app.vehicle.enable) {
|
|
|
+ startPage(app.vehicle.newVersionPage ? PageList.vehiclesListV2 : PageList.myVehicles)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ switchFlash() {
|
|
|
+ this.setState({
|
|
|
+ flashLight: !this.state.flashLight
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ render() {
|
|
|
+ return (
|
|
|
+ <View style={styles.container}>
|
|
|
+ <QRScanner
|
|
|
+ onCodeScanned={this.scanResult}
|
|
|
+ flashLight={this.state.flashLight}
|
|
|
+ isActive={!this.state.isResult}
|
|
|
+ />
|
|
|
+ { !this.state.isResult &&
|
|
|
+ <Pressable
|
|
|
+ style={styles.flashLight}
|
|
|
+ onPress={() => this.switchFlash()}>
|
|
|
+ <MaterialIcons
|
|
|
+ name={this.state.flashLight ? "flashlight-on" : "flashlight-off"}
|
|
|
+ size={36}
|
|
|
+ color="#fff"/>
|
|
|
+ </Pressable>
|
|
|
+ }
|
|
|
+ </View>
|
|
|
+ );
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const styles = StyleSheet.create({
|
|
|
+ container: {
|
|
|
+ alignItems: 'center',
|
|
|
+ justifyContent: 'center',
|
|
|
+ backgroundColor: '#000',
|
|
|
+ ...StyleSheet.absoluteFillObject
|
|
|
+ },
|
|
|
+ flashLight: {
|
|
|
+ bottom: 90,
|
|
|
+ zIndex: 2,
|
|
|
+ opacity: 0.7,
|
|
|
+ padding: 8,
|
|
|
+ position: 'absolute'
|
|
|
+ }
|
|
|
+})
|