QRScan.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /**
  2. * 扫描二维码
  3. * @邠心vbe on 2021/03/24
  4. * 升级到 react-native-vision-camera
  5. */
  6. /* eslint-disable no-undef */
  7. import React, { Component, useEffect, useState } from 'react'
  8. import { Pressable, StyleSheet, View } from 'react-native'
  9. import { Camera, useCameraDevice, useCodeScanner } from 'react-native-vision-camera';
  10. import apiCharge from '../../api/apiCharge';
  11. import { PageList } from '../Router';
  12. import Dialog from '../../components/Dialog';
  13. import app from '../../../app.json';
  14. import { Vibration } from 'react-native';
  15. export const QRResult = {
  16. haveResult: () => {
  17. return global.QrCodeResult && global.QrCodeResult.connectorPk;
  18. },
  19. setResult: (info) => {
  20. global.QrCodeResult = info;
  21. },
  22. getResult: () => {
  23. return global.QrCodeResult;
  24. },
  25. clearResult: () => {
  26. global.QrCodeResult = {};
  27. },
  28. applyInputStation: (text, sitePk, back) => {
  29. if (text.indexOf('-') > 0) {
  30. const arr = text.split('-');
  31. if (arr.length >= 2) {
  32. let bid = '', cid = '';
  33. for (let i = 0; i < arr.length; i++) {
  34. let sb = arr[i]?.trim();
  35. if (i == (arr.length-1)) {
  36. cid = sb;
  37. } else {
  38. if (i > 0) {
  39. bid += '-';
  40. }
  41. bid += sb;
  42. }
  43. }
  44. const qr = {
  45. sitePk: sitePk,
  46. chargeBoxId: bid,
  47. connectorId: cid
  48. }
  49. console.log('====================================');
  50. console.log(qr);
  51. console.log('====================================');
  52. Dialog.showProgressDialog();
  53. apiCharge.checkQRStatus(qr).then(res => {
  54. Dialog.dismissLoading();
  55. if (res.data && res.data.chargeBoxId) {
  56. QRResult.setResult(res.data);
  57. back(true)
  58. }
  59. }).catch(({err, code}) => {
  60. Dialog.dismissLoading();
  61. back(false, '')
  62. Dialog.showDialog({
  63. title: 'Error',
  64. message: err,
  65. showCancel: false,
  66. callback: btn => {
  67. if (code == 5194 && btn == Dialog.BUTTON_OK) {
  68. startPage(PageList.myVehicles);
  69. }
  70. }
  71. });
  72. })
  73. } else {
  74. back(false, 'Station ID is incorrect');
  75. }
  76. } else {
  77. back(false, 'Station ID is incorrect');
  78. }
  79. }
  80. }
  81. // 函数组件:QR码扫描器
  82. const QRScanner = ({ onCodeScanned, flashLight, isActive }) => {
  83. const [hasPermission, setHasPermission] = useState(false);
  84. const device = useCameraDevice('back');
  85. useEffect(() => {
  86. (async () => {
  87. const status = await Camera.requestCameraPermission();
  88. setHasPermission(status == 'granted');
  89. })();
  90. }, []);
  91. const codeScanner = useCodeScanner({
  92. codeTypes: ['qr'],
  93. onCodeScanned: (codes) => {
  94. if (codes.length > 0 && isActive) {
  95. const code = codes[0];
  96. onCodeScanned({ data: code.value });
  97. }
  98. },
  99. });
  100. return (
  101. (device && hasPermission) && (<>
  102. <Camera
  103. style={{width: $width, height: $vh(110)}}
  104. device={device}
  105. isActive={isActive}
  106. codeScanner={codeScanner}
  107. enableZoomGesture={true}
  108. photo={false}
  109. video={false}
  110. audio={false}
  111. resizeMode="cover"
  112. torch={flashLight ? 'on' : 'off'}
  113. />
  114. </>)
  115. );
  116. };
  117. export default class QRScan extends Component {
  118. constructor(props) {
  119. super(props);
  120. this.state={
  121. isResult: true,
  122. params: this.props.route.params,
  123. flashLight: false
  124. }
  125. }
  126. componentDidMount() {
  127. this.props.navigation.addListener('focus', () => {
  128. setTimeout(() => {
  129. this.setState({
  130. isResult: false
  131. });
  132. }, 200);
  133. });
  134. this.props.navigation.addListener('beforeRemove', (e) => {
  135. if (!this.state.isResult) {
  136. e.preventDefault();
  137. this.setState({
  138. isResult: true
  139. }, () => {
  140. setTimeout(() => {
  141. goBack();
  142. }, 300);
  143. });
  144. }
  145. });
  146. }
  147. scanResult = (msg) => {
  148. this.setState({
  149. isResult: true
  150. });
  151. Vibration.vibrate(100);
  152. console.log("result2", msg);
  153. if (msg.indexOf('::') > 0) {
  154. const arr = msg.split('::');
  155. if (arr.length == 2) {
  156. const qr = {
  157. chargeBoxId: arr[0],
  158. connectorId: arr[1]
  159. }
  160. if (this.state.params.id) {
  161. qr.sitePk = this.state.params.id
  162. }
  163. this.getChargeDetail(qr);
  164. return;
  165. }
  166. } else {
  167. const qr = {
  168. qrContent: msg
  169. }
  170. if (this.state.params.id) {
  171. qr.sitePk = this.state.params.id
  172. }
  173. this.getChargeDetail(qr);
  174. return;
  175. }
  176. Dialog.showDialog({
  177. title: 'Error',
  178. message: 'It\'s not a legal QR code',
  179. showCancel: false,
  180. callback: (e) => {
  181. this.setState({
  182. isResult: false
  183. });
  184. }});
  185. }
  186. getChargeDetail(qr) {
  187. console.log('===============SCAN QR===============');
  188. console.log(qr);
  189. console.log('===============SCAN QR===============');
  190. apiCharge.checkQRStatus(qr).then(res => {
  191. if (res.data && res.data.chargeBoxId) {
  192. QRResult.setResult(res.data);
  193. if (res.data.sitePk) {
  194. if (this.state.params.actionDetail) {
  195. startPage(PageList.chargeDetailPage, {stationInfo: {id: res.data.sitePk}, action: 'qr', from: PageList.home});
  196. } else {
  197. goBack();
  198. }
  199. //startPage(PageList.chargeDetail, {stationInfo: {id: res.data.sitePk}, action: 'qr'});
  200. }
  201. }
  202. }).catch(({err, code}) => {
  203. Dialog.showDialog({
  204. title: 'Error',
  205. message: err,
  206. showCancel: false,
  207. callback: (btn) => {
  208. this.setState({
  209. isResult: false
  210. });
  211. if (code == 5194 && btn == Dialog.BUTTON_OK && app.vehicle.enable) {
  212. startPage(app.vehicle.newVersionPage ? PageList.vehiclesListV2 : PageList.myVehicles)
  213. }
  214. }
  215. });
  216. })
  217. }
  218. switchFlash() {
  219. this.setState({
  220. flashLight: !this.state.flashLight
  221. })
  222. }
  223. render() {
  224. return (
  225. <View style={styles.container}>
  226. <QRScanner
  227. onCodeScanned={this.scanResult}
  228. flashLight={this.state.flashLight}
  229. isActive={!this.state.isResult}
  230. />
  231. { !this.state.isResult &&
  232. <Pressable
  233. style={styles.flashLight}
  234. onPress={() => this.switchFlash()}>
  235. <MaterialIcons
  236. name={this.state.flashLight ? "flashlight-on" : "flashlight-off"}
  237. size={36}
  238. color="#fff"/>
  239. </Pressable>
  240. }
  241. </View>
  242. );
  243. }
  244. }
  245. const styles = StyleSheet.create({
  246. container: {
  247. alignItems: 'center',
  248. justifyContent: 'center',
  249. backgroundColor: '#000',
  250. ...StyleSheet.absoluteFillObject
  251. },
  252. flashLight: {
  253. bottom: 90,
  254. zIndex: 2,
  255. opacity: 0.7,
  256. padding: 8,
  257. position: 'absolute'
  258. }
  259. })