scan.vue 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. <template>
  2. <view class="pages">
  3. <view class="scan">
  4. <!-- <view class="loop_line"></view> -->
  5. <u-icon class="close" name="close-circle" color="#fff" size="30" @click="closeScan"></u-icon>
  6. <view class="video-container">
  7. <video class="video" id="video_nav_id" :controls="false"></video>
  8. </view>
  9. <!-- v-if="videoInputDevices.length>1" -->
  10. <view class="camera-container" >
  11. <label>摄像头:</label>
  12. <select v-model="currentVideoInputDevice">
  13. <option
  14. v-for="(videoInputDevice, index) in videoInputDevices"
  15. :key="index"
  16. :value="videoInputDevice"
  17. >
  18. {{ videoInputDevice.label }}
  19. </option>
  20. </select>
  21. </view>
  22. </view>
  23. </view>
  24. </template>
  25. <script>
  26. import {
  27. BrowserMultiFormatReader,
  28. ChecksumException,
  29. FormatException,
  30. } from "@zxing/library";
  31. // import { LOG } from "@zxing/library/esm/core/datamatrix/encoder/constants";
  32. export default {
  33. data() {
  34. return {
  35. exchangeCode:'',
  36. codeReader: null,
  37. videoInputDevices: [],
  38. currentVideoInputDevice: {},
  39. decodeResult: undefined,
  40. }
  41. },
  42. onShow() {
  43. },
  44. beforeDestroy() {
  45. this.codeReader.reset(); //关闭摄像头
  46. // alert('销毁')
  47. },
  48. onHide(){
  49. // alert('销毁')
  50. this.codeReader.reset(); //关闭摄像头
  51. },
  52. mounted() {
  53. var video = document.getElementById('video_nav_id').getElementsByTagName('video')[0]
  54. video.setAttribute('id','video-1')
  55. video.setAttribute('class','video_calss')
  56. this.codeReader = new BrowserMultiFormatReader();
  57. this.openScan();
  58. },
  59. onLoad() {
  60. },
  61. watch: {
  62. currentVideoInputDevice: function () {
  63. this.decodeFromInputVideo();
  64. },
  65. decodeResult: function () {
  66. this.successDecode();
  67. },
  68. },
  69. methods: {
  70. async openScan() {
  71. const _this = this;
  72. // console.log('codeReader', this.codeReader);
  73. // camera.setDisplayOrientation(90);
  74. _this.codeReader
  75. .getVideoInputDevices() //老版本listVideoInputDevices()
  76. .then((videoInputDevices) => {
  77. if (videoInputDevices && videoInputDevices.length) {
  78. if (videoInputDevices.length > 1) {
  79. // videoInputDevices.reverse();
  80. // 把前置摄像头设置默认
  81. let secondElement = videoInputDevices.splice(1, 1)[0]; // 从索引为 1 的位置删除一个元素并返回它
  82. videoInputDevices.splice(0, 0, secondElement); // 在索引为 0 的位置插入第二个元素
  83. } //有多个摄像头的情况
  84. _this.videoInputDevices = videoInputDevices;
  85. _this.currentVideoInputDevice = videoInputDevices[0];
  86. }else{
  87. alert('没有检测到摄像头')
  88. }
  89. })
  90. .catch(() => {});
  91. },
  92. decodeFromInputVideo() {
  93. const _this = this;
  94. _this.codeReader.reset();
  95. // 多次
  96. try {
  97. _this.codeReader.decodeFromVideoDevice(_this.currentVideoInputDevice.deviceId, 'video-1',(res,err) => {
  98. if(res) {
  99. _this.decodeResult = res.text;
  100. }
  101. if (err) {
  102. // alert(err)
  103. if (err instanceof ChecksumException) {
  104. alert("A code was found, but it's read value was not valid.")
  105. console.log(
  106. "A code was found, but it's read value was not valid."
  107. );
  108. }
  109. if (err instanceof FormatException) {
  110. alert("A code was found, but it was in a invalid format.")
  111. console.log("A code was found, but it was in a invalid format.");
  112. }
  113. }
  114. })
  115. }catch(err){
  116. uni.showToast({title: `初始化失败${err}`,icon: 'none'});
  117. }
  118. },
  119. closeScan(){
  120. // this.$router.go(-1)
  121. // uni.navigateBack()
  122. uni.$u.route('/pages/index/index');
  123. },
  124. successDecode() {
  125. const _this = this;
  126. let result = JSON.parse(_this.decodeResult);
  127. this.exchangeCode = result.qrcode;
  128. let pages = getCurrentPages(); //获取所有页面栈实例列表
  129. let nowPage = pages[ pages.length - 1]; //当前页页面实例
  130. let prevPage = pages[ pages.length - 2 ]; //上一页页面实例
  131. prevPage.$vm.exchangeCode= this.exchangeCode; // 修改上一页data里面的数据
  132. this.closeScan();
  133. // this.getCheckGoods();
  134. // alert(_this.decodeResult);
  135. },
  136. }
  137. }
  138. </script>
  139. <style lang="scss" scoped>
  140. #video_nav_id {
  141. height: 80vh;
  142. width: 100%;
  143. }
  144. /deep/.uni-video-cover {
  145. display: none;
  146. }
  147. .scan {
  148. position: fixed;
  149. left: 0;
  150. top: 0;
  151. z-index: 9999;
  152. display: flex;
  153. flex-direction: column;
  154. align-items: center;
  155. color: #ff9900;
  156. width: 100%;
  157. height: 100vh;
  158. background: #000;
  159. .video-container {
  160. margin-top: 20px;
  161. width: 100%;
  162. height: 75vh;
  163. display: flex;
  164. justify-content: center;
  165. /deep/ #video-1{
  166. width: 100%;
  167. height: 100%;
  168. }
  169. @media (min-width: 500px) {
  170. video {
  171. // width: 80vh;
  172. // max-width: 96vw;
  173. height: 80vh;
  174. }
  175. }
  176. }
  177. .camera-container {
  178. position: relative;
  179. margin-top: 10px;
  180. width: 80%;
  181. height: 50px;
  182. line-height: 44px;
  183. border-radius: 10px;
  184. border: 3px solid #ff9900;
  185. display: flex;
  186. justify-content: center;
  187. align-items: center;
  188. padding-left: 8px;
  189. select {
  190. width: calc(100% - 90px);
  191. color: #ff9900;
  192. background: transparent;
  193. border: none;
  194. outline: none;
  195. }
  196. z-index: 100;
  197. }
  198. .close{
  199. position: absolute;
  200. right: 40rpx;
  201. top: 40rpx;
  202. z-index: 100;
  203. }
  204. }
  205. </style>