scan.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. let Qrcode = require('@/components/reqrcode.js')
  2. export function toScanCode(options) {
  3. let resultData = ''
  4. // #ifdef APP-PLUS
  5. let platform = uni.getSystemInfoSync().platform
  6. if (platform == 'ios') {
  7. resultData = scanCodeIos(options)
  8. } else {
  9. return new Promise((resolve, reject) => {
  10. uni.scanCode({
  11. onlyFromCamera: options.onlyFromCamera, // 只允许通过相机扫码
  12. scanType: ['barCode','qrCode'], //扫码类型 barCode一维码 qrCode二维码
  13. autoZoom:true,//是否启用自动放大,默认启用
  14. success: function(res) {
  15. resolve(res.result);
  16. }
  17. });
  18. })
  19. }
  20. // #endif
  21. // #ifdef H5
  22. var ua = navigator.userAgent;
  23. var isWeixin = !!/MicroMessenger/i.test(ua);
  24. if (isWeixin) {
  25. getJsApiConfig();
  26. resultData = scanCodeWxH5(options)
  27. } else {
  28. resultData = scanCodeH5(options)
  29. }
  30. // #endif
  31. return Promise.resolve(resultData);
  32. }
  33. //处理扫码内容
  34. export function scanContent(result) {
  35. var obj = null;
  36. try {
  37. obj = JSON.parse(result)
  38. } catch (err) {
  39. this.$tip.error("无法识别二维码");
  40. return
  41. }
  42. return obj;
  43. }
  44. //微信扫码 参考地址:https://mp.weixin.qq.com/s/ulq_cs-gGwkpmdt5zsU4aA
  45. export function scanCodeWxH5(options) {
  46. let fromCamera = options.onlyFromCamera
  47. return new Promise((resolve, reject) => {
  48. wx.scanQRCode({
  49. needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
  50. scanType: ['barCode','qrCode'], // 可以指定扫二维码还是一维码,默认二者都有 barCode一维码 qrCode二维码
  51. success: function(res) {
  52. resolve(res.resultStr)
  53. }
  54. });
  55. })
  56. }
  57. //ios 扫码 uniapp nvue自带的Barcode
  58. export function scanCodeIos(options) {
  59. let fromCamera = options.onlyFromCamera
  60. return new Promise((resolve, reject) => {
  61. //开始扫码
  62. toHsScanCode({
  63. evalName: "hs-scancode", //扫码回调监听事件
  64. msg: '扫码', //提示文本
  65. fil: '0,1,2', //条码类型 0-qr二维码 1-EAN条形码标准版 2-EAN条形码简版
  66. onlyFromCamera: fromCamera // 只允许通过相机扫码
  67. }, res => {
  68. //扫码成功后 这里自己判断,如果要自己处理结果就返回 true
  69. resolve(res.result)
  70. return true
  71. })
  72. })
  73. }
  74. //这里可以写成一个通用方法
  75. export function toHsScanCode(options, results) {
  76. const q = Object.entries(options).map(([key, value]) => `${key}=${value}`).join('&')
  77. uni.$on(options.evalName || "hs-scancode", ([error, res]) => {
  78. if (res) {
  79. //扫码结果
  80. uni.navigateBack({
  81. delta: 1,
  82. animationType: "fade-out", //用 fade-out 关闭页面,减少扫码成功后跳转页面的闪动
  83. animationDuration: 300,
  84. })
  85. if (results && results(res) === true) return;
  86. }
  87. })
  88. uni.navigateTo({
  89. url: `/pages/component/hs-scancode?${q}`
  90. })
  91. }
  92. // 调用接口获取config信息
  93. export function getJsApiConfig() {
  94. //获取到的url是当前页面的域名,而不是完整url
  95. const apiUrl = location.href.split('#')[0];
  96. let param = {
  97. url: apiUrl
  98. }
  99. this.$http.get('/sys/wx/getJsApiConfig', {
  100. params: param
  101. }).then(res => {
  102. if (res.data.success) {
  103. getConfig(res.data.result);
  104. } else {
  105. this.$tip.error(res.data.message);
  106. }
  107. }).catch((err) => {
  108. console.log("请求返回err", err)
  109. })
  110. }
  111. export function getConfig(res) {
  112. // 配置config信息
  113. wx.config({
  114. debug: false,
  115. appId: res.appId, // 必填,公众号的唯一标识
  116. timestamp: res.timestamp, // 必填,生成签名的时间戳
  117. nonceStr: res.nonceStr, // 必填,生成签名的随机串
  118. signature: res.signature, // 必填,签名
  119. jsApiList: ['scanQRCode'] // 必填,需要使用的JS接口列表
  120. });
  121. // 通过ready接口处理成功验证
  122. wx.ready(function() {
  123. wx.checkJsApi({
  124. jsApiList: ['scanQRCode'],
  125. success: function(res) {
  126. console.log('检验成功');
  127. }
  128. });
  129. });
  130. // 通过error接口处理失败验证
  131. wx.error(function(res) {
  132. console.log('校验失败');
  133. });
  134. }
  135. // H5通过拉起相机拍照来识别二维码
  136. export function scanCodeH5(options) {
  137. let fromCamera = options.onlyFromCamera
  138. let sourceType = ['camera','album']
  139. if(fromCamera){
  140. sourceType = ['camera']
  141. }
  142. return new Promise((resolve, reject) => {
  143. uni.chooseImage({
  144. count: 1,
  145. sourceType: sourceType, //来源类型
  146. success: imgRes => {
  147. Qrcode.qrcode.decode(getObjectURL(imgRes.tempFiles[0]))
  148. Qrcode.qrcode.callback = (codeRes) => {
  149. if (codeRes.indexOf('error') >= 0) {
  150. // 识别失败
  151. reject("二维码识别失败");
  152. } else {
  153. // 识别成功
  154. let content = decodeStr(codeRes)
  155. let formatContent = scanContent(content)
  156. resolve(formatContent);
  157. }
  158. }
  159. }
  160. })
  161. })
  162. }
  163. // 获取文件地址函数
  164. export function getObjectURL(file) {
  165. var url = null
  166. if (window.createObjectURL !== undefined) { // basic
  167. url = window.createObjectURL(file)
  168. } else if (window.URL !== undefined) { // mozilla(firefox)
  169. url = window.URL.createObjectURL(file)
  170. } else if (window.webkitURL !== undefined) { // webkit or chrome
  171. url = window.webkitURL.createObjectURL(file)
  172. }
  173. return url
  174. }
  175. // 解码,输出:中文
  176. export function decodeStr(str) {
  177. var out, i, len, c;
  178. var char2, char3;
  179. out = "";
  180. len = str.length;
  181. i = 0;
  182. while (i < len) {
  183. c = str.charCodeAt(i++);
  184. switch (c >> 4) {
  185. case 0:
  186. case 1:
  187. case 2:
  188. case 3:
  189. case 4:
  190. case 5:
  191. case 6:
  192. case 7:
  193. // 0xxxxxxx
  194. out += str.charAt(i - 1);
  195. break;
  196. case 12:
  197. case 13:
  198. // 110x xxxx 10xx xxxx
  199. char2 = str.charCodeAt(i++);
  200. out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
  201. break;
  202. case 14:
  203. // 1110 xxxx 10xx xxxx 10xx xxxx
  204. char2 = str.charCodeAt(i++);
  205. char3 = str.charCodeAt(i++);
  206. out += String.fromCharCode(((c & 0x0F) << 12) |
  207. ((char2 & 0x3F) << 6) |
  208. ((char3 & 0x3F) << 0));
  209. break;
  210. }
  211. }
  212. return out;
  213. }