QCode.vue 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. <script setup lang="ts">
  2. // eslint-disable-next-line ts/ban-ts-comment
  3. // @ts-expect-error
  4. import UQRCode from 'uqrcodejs'
  5. const props = defineProps<{ text: string, qwidth: number, qrKey: string }>()
  6. const _this = getCurrentInstance()
  7. function createQRCode() {
  8. const qr = new UQRCode()
  9. qr.data = props.text
  10. qr.size = props.qwidth || 100 // 这里是px,和下面的不匹配
  11. qr.make()
  12. const canvasContext = uni.createCanvasContext(props.qrKey, _this)
  13. qr.canvasContext = canvasContext
  14. qr.drawCanvas()
  15. }
  16. createQRCode()
  17. async function downloadQrcode() {
  18. try {
  19. // 1. 先确保二维码已绘制完成(短暂延迟,兼容绘制异步性)
  20. await new Promise(resolve => setTimeout(resolve, 300))
  21. // 2. 将Canvas转为临时文件路径(复用原有canvas-id)
  22. const tempRes: any = await uni.canvasToTempFilePath({
  23. canvasId: props.qrKey, // 与原有Canvas的canvas-id保持一致
  24. width: props.qwidth,
  25. height: props.qwidth,
  26. destWidth: props.qwidth * 2, // 生成高清图
  27. destHeight: props.qwidth * 2,
  28. fileType: 'png',
  29. }, _this)
  30. // 3. 分端处理下载/保存逻辑
  31. const systemInfo = uni.getSystemInfoSync()
  32. if (systemInfo.platform === 'h5') {
  33. // H5端:浏览器下载
  34. const link = document.createElement('a')
  35. link.href = tempRes.tempFilePath
  36. link.download = `二维码_${Date.now()}.png`
  37. link.click()
  38. uni.showToast({ title: '二维码下载成功' })
  39. }
  40. else {
  41. // 小程序/APP端:保存到相册(处理授权)
  42. // 检查授权状态
  43. const settingRes = await uni.getSetting({})
  44. if (!settingRes.authSetting['scope.writePhotosAlbum']) {
  45. // 未授权则请求授权
  46. try {
  47. await uni.authorize({ scope: 'scope.writePhotosAlbum' })
  48. }
  49. catch {
  50. uni.showToast({ title: '需授权保存相册才能下载', icon: 'none' })
  51. return
  52. }
  53. }
  54. // 保存到系统相册
  55. await uni.saveImageToPhotosAlbum({
  56. filePath: tempRes.tempFilePath,
  57. })
  58. uni.showToast({ title: '二维码已保存到相册' })
  59. }
  60. }
  61. catch (err) {
  62. // const errMsg = (err as any).errMsg
  63. uni.showToast({ title: `下载失败`, icon: 'none' })
  64. console.error('二维码下载失败:', err)
  65. }
  66. }
  67. defineExpose({
  68. downloadQrcode,
  69. })
  70. </script>
  71. <template>
  72. <canvas :id="qrKey" :canvas-id="qrKey" :style="{ width: `${props.qwidth}px`, height: `${props.qwidth}px` }" />
  73. </template>
  74. <style scoped>
  75. </style>