scan.js 5.9 KB

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