Browse Source

优化:修复微信电脑版优惠券分享二维码显示空白问题

haiyang 7 months ago
parent
commit
892a773511

+ 2 - 1
src/api/receiveCoupon.ts

@@ -1,5 +1,6 @@
 import { http } from '@/http/alova'
 import { ContentTypeEnum } from '@/http/tools/enum'
+import { getEnvField } from '@/utils/envField'
 
 export function getReceiveCouponDetail(couponId: string) {
     return http.Get('/couponCenter/APP/shareRecord/queryTemplateBySendUserId', {
@@ -23,7 +24,7 @@ export function getCouponShareLink(params) {
 export function getWxQcCode(params) {
     return http.Post('/couponCenter/APP/shareRecord/createQRCode', {
         ...params,
-        env_version: import.meta.env.VITE_WEIXIN_MINIAPP_VERSION
+        env_version: getEnvField(),
     }, {
         responseType: 'arraybuffer',
         cacheFor: null,

+ 68 - 47
src/pages-A/shareFriend/index.vue

@@ -77,7 +77,7 @@ import { nextTick, ref } from 'vue'
 import { markSuccess } from '@/api/receiveCoupon'
 import CustomNavigationBar from '@/components/CustomNavigationBar.vue'
 import { useInviteCodeStore } from '@/store/inviteQCCode'
-import { safeAreaInsets } from '@/utils'
+import { safeAreaInsets, isPcWeixinMp } from '@/utils'
 import { getImageUrl } from '@/utils/imageUtil'
 
 definePage({
@@ -250,26 +250,36 @@ async function loadRemoteImage(canvas, imageUrl) {
             reject(new Error('图片加载超时'))
         }, 10000) // 10秒超时
 
-        image.onload = () => {
-            clearTimeout(timeout)
-            const imageWidth = image.naturalWidth || image.width
-            const imageHeight = image.naturalHeight || image.height
+        uni.getImageInfo({
+            src: imageUrl,
+            success: (res) => {
+                image.onload = () => {
+                    clearTimeout(timeout)
+                    const imageWidth = image.naturalWidth || image.width || res.width
+                    const imageHeight = image.naturalHeight || image.height || res.height
 
-            if (image.complete && imageWidth > 0 && imageHeight > 0) {
-                resolve(image)
-            }
-            else {
-                reject(new Error('图片加载事件触发但尺寸无效'))
-            }
-        }
+                    if ((isPcWeixinMp() || image.complete) && imageWidth > 0 && imageHeight > 0) {
+                        resolve(image)
+                    }
+                    else {
+                        reject(new Error('图片加载事件触发但尺寸无效'))
+                    }
+                }
 
-        image.onerror = (err) => {
-            clearTimeout(timeout)
-            console.error('加载远程图片失败:', err)
-            reject(err)
-        }
+                image.onerror = (err) => {
+                    clearTimeout(timeout)
+                    console.error('加载远程图片失败:', err)
+                    reject(err)
+                }
+
+                image.src = res.path
+
+            },
+            fail: (fail) => {
+                reject(new Error('获取图片信息失败'))
+            },
+        })
 
-        image.src = imageUrl
     })
 }
 
@@ -337,7 +347,11 @@ function drawRulesDescription(ctx, width, height, scale) {
 // 绘制二维码区域
 async function drawQRCodeArea(ctx, canvas, qrCodeImg, width, height, scale) {
     const qrSize = 125 * scale
-    const qrX = ((width - qrSize) / 3) - 130
+    // const qrX = (width / 2) - qrSize - 100
+    let qrX = (width / 2) - qrSize - 80
+    if (isPcWeixinMp()) {
+        qrX = (width / 2) - qrSize - 35
+    }
     const qrY = 660 * scale
 
     // 使用柔和的白色背景,增加卡片层次感
@@ -417,35 +431,42 @@ async function drawQRCodeArea(ctx, canvas, qrCodeImg, width, height, scale) {
                 const timeout = setTimeout(() => {
                     reject(new Error('图片加载超时'))
                 }, 10000) // 10秒超时
+                uni.getImageInfo({
+                    src: tempFilePath || imgSrc,
+                    success: (res) => {
+                        qrImage.onload = () => {
+                            console.log('图片加载成功:', res)
+                            clearTimeout(timeout)
+                            console.log('二维码图片加载成功', {
+                                complete: qrImage.complete,
+                                naturalWidth: qrImage.naturalWidth || qrCodeImg.width || res.width,
+                                naturalHeight: qrImage.naturalHeight || qrCodeImg.height || res.height,
+                            }, qrImage)
+
+                            // 获取图片尺寸,兼容微信小程序环境
+                            const imageWidth = qrImage.naturalWidth || qrImage.width || res.width
+                            const imageHeight = qrImage.naturalHeight || qrImage.height || res.height
+                            // 再次检查图片是否真正加载完成
+                            if ((isPcWeixinMp() || qrImage.complete) && imageWidth > 0 && imageHeight > 0) {
+                                resolve()
+                            }
+                            else {
+                                reject(new Error('图片加载事件触发但尺寸无效'))
+                            }
+                        }
+                        qrImage.onerror = (err) => {
+                            clearTimeout(timeout)
+                            console.error('加载二维码图片失败:', err)
+                            reject(err)
+                        }
 
-                qrImage.onload = () => {
-                    clearTimeout(timeout)
-                    console.log('二维码图片加载成功', {
-                        complete: qrImage.complete,
-                        naturalWidth: qrImage.naturalWidth || qrCodeImg.width,
-                        naturalHeight: qrImage.naturalHeight || qrCodeImg.height,
-                    }, qrImage)
-
-                    // 获取图片尺寸,兼容微信小程序环境
-                    const imageWidth = qrImage.naturalWidth || qrImage.width
-                    const imageHeight = qrImage.naturalHeight || qrImage.height
-
-                    // 再次检查图片是否真正加载完成
-                    if (qrImage.complete && imageWidth > 0 && imageHeight > 0) {
-                        resolve()
-                    }
-                    else {
-                        reject(new Error('图片加载事件触发但尺寸无效'))
-                    }
-                }
-                qrImage.onerror = (err) => {
-                    clearTimeout(timeout)
-                    console.error('加载二维码图片失败:', err)
-                    reject(err)
-                }
-
-                // 优先使用临时文件路径,否则使用base64数据
-                qrImage.src = tempFilePath || imgSrc
+                        // 优先使用临时文件路径,否则使用base64数据
+                        qrImage.src = res.path
+                    },
+                    fail: (fail) => {
+                        reject(new Error('获取图片信息失败'))
+                    },
+                })
             })
 
             const finalWidth = qrImage.naturalWidth || qrImage.width

+ 56 - 54
src/pages-A/sharePage/index.vue

@@ -188,7 +188,6 @@ async function getWxacodeBase64() {
         const base64 = uni.arrayBufferToBase64(arrayBuffer)
         const imageUrl = `data:image/jpeg;base64,${base64}`
         const params = parseUrlParams(contentData)
-        console.log(params, '获取到的参数')
         shareRecordId.value = params[inviteCode.value.shareKey]
         return imageUrl
     }
@@ -636,70 +635,72 @@ async function drawQRCodeArea(ctx, canvas, qrCodeImg, width, height, scale) {
                     }
                 }
 
-                if (!isPcWeixinMp()) {
-                    // 尝试使用临时文件方式
-                    try {
-                        // #ifdef MP-WEIXIN
-                        const fs = uni.getFileSystemManager()
-                        const tempFileName = `temp_qr_${Date.now()}.png`
-                        tempFilePath = `${uni.env.USER_DATA_PATH}/${tempFileName}`
-
-                        // 提取base64数据部分
-                        let base64Data = imgSrc
-                        if (imgSrc.includes('base64,')) {
-                            base64Data = imgSrc.split('base64,')[1]
-                        }
-
-                        fs.writeFileSync(tempFilePath, base64Data, 'base64')
-                        console.log('Base64已转换为临时文件:', tempFilePath)
-                        // #endif
-                    }
-                    catch (fileError) {
-                        console.warn('转换base64为临时文件失败,尝试直接使用base64:', fileError)
-                        // 清除临时文件路径,确保使用base64
-                        tempFilePath = ''
+                // 尝试使用临时文件方式
+                try {
+                    // #ifdef MP-WEIXIN
+                    const fs = uni.getFileSystemManager()
+                    const tempFileName = `temp_qr_${Date.now()}.png`
+                    tempFilePath = `${uni.env.USER_DATA_PATH}/${tempFileName}`
+
+                    // 提取base64数据部分
+                    let base64Data = imgSrc
+                    if (imgSrc.includes('base64,')) {
+                        base64Data = imgSrc.split('base64,')[1]
                     }
-                } else {
-                    console.log('电脑版微信小程序,直接使用base64数据')
+
+                    fs.writeFileSync(tempFilePath, base64Data, 'base64')
+                    console.log('Base64已转换为临时文件:', tempFilePath)
+                    // #endif
+                }
+                catch (fileError) {
+                    console.warn('转换base64为临时文件失败,尝试直接使用base64:', fileError)
+                    // 清除临时文件路径,确保使用base64
+                    tempFilePath = ''
                 }
             }
 
             const qrImage = canvas.createImage()
-
             // 使用Promise确保图片加载完成
             await new Promise((resolve, reject) => {
                 const timeout = setTimeout(() => {
                     reject(new Error('图片加载超时'))
                 }, 10000) // 10秒超时
+                uni.getImageInfo({
+                    src: tempFilePath || imgSrc,
+                    success: (res) => {
+                        qrImage.onload = () => {
+                            console.log('图片加载成功:', res)
+                            clearTimeout(timeout)
+                            console.log('二维码图片加载成功', {
+                                complete: qrImage.complete,
+                                naturalWidth: qrImage.naturalWidth || qrCodeImg.width || res.width,
+                                naturalHeight: qrImage.naturalHeight || qrCodeImg.height || res.height,
+                            }, qrImage)
+
+                            // 获取图片尺寸,兼容微信小程序环境
+                            const imageWidth = qrImage.naturalWidth || qrImage.width || res.width
+                            const imageHeight = qrImage.naturalHeight || qrImage.height || res.height
+                            // 再次检查图片是否真正加载完成
+                            if ((isPcWeixinMp() || qrImage.complete) && imageWidth > 0 && imageHeight > 0) {
+                                resolve()
+                            }
+                            else {
+                                reject(new Error('图片加载事件触发但尺寸无效'))
+                            }
+                        }
+                        qrImage.onerror = (err) => {
+                            clearTimeout(timeout)
+                            console.error('加载二维码图片失败:', err)
+                            reject(err)
+                        }
 
-                qrImage.onload = () => {
-                    clearTimeout(timeout)
-                    console.log('二维码图片加载成功', {
-                        complete: qrImage.complete,
-                        naturalWidth: qrImage.naturalWidth || qrCodeImg.width,
-                        naturalHeight: qrImage.naturalHeight || qrCodeImg.height,
-                    }, qrImage)
-
-                    // 获取图片尺寸,兼容微信小程序环境
-                    const imageWidth = qrImage.naturalWidth || qrImage.width
-                    const imageHeight = qrImage.naturalHeight || qrImage.height
-
-                    // 再次检查图片是否真正加载完成
-                    if (qrImage.complete && imageWidth > 0 && imageHeight > 0) {
-                        resolve()
-                    }
-                    else {
-                        reject(new Error('图片加载事件触发但尺寸无效'))
-                    }
-                }
-                qrImage.onerror = (err) => {
-                    clearTimeout(timeout)
-                    console.error('加载二维码图片失败:', err)
-                    reject(err)
-                }
-
-                // 优先使用临时文件路径,否则使用base64数据
-                qrImage.src = tempFilePath || imgSrc
+                        // 优先使用临时文件路径,否则使用base64数据
+                        qrImage.src = res.path
+                    },
+                    fail: (fail) => {
+                        reject(new Error('获取图片信息失败'))
+                    },
+                })
             })
 
             const finalWidth = qrImage.naturalWidth || qrImage.width
@@ -717,6 +718,7 @@ async function drawQRCodeArea(ctx, canvas, qrCodeImg, width, height, scale) {
             ctx.clip()
             ctx.drawImage(qrImage, qrX, qrY, qrSize, qrSize)
 
+
             // 图片绘制成功后,添加一个精致的内边框
             ctx.restore()
             ctx.beginPath()

+ 34 - 0
src/utils/envField.ts

@@ -0,0 +1,34 @@
+/**
+ * 根据当前小程序环境返回对应字段
+ * 开发版和体验版返回"体验版"
+ * 正式版返回"正式版"
+ */
+export function getEnvField(): string {
+    // 默认返回体验版
+    let envField = 'trial'
+
+    // 微信小程序端环境区分
+    try {
+        const accountInfo = uni.getAccountInfoSync()
+        const envVersion = accountInfo.miniProgram.envVersion
+
+        switch (envVersion) {
+            case 'develop':
+            case 'trial':
+                // 开发版和体验版返回"体验版"
+                envField = 'trial'
+                break
+            case 'release':
+                // 正式版返回"正式版"
+                envField = 'release'
+                break
+            default:
+                envField = 'trial'
+        }
+    } catch (error) {
+        console.error('获取小程序环境信息失败:', error)
+        envField = 'release'
+    }
+
+    return envField
+}

+ 2 - 2
src/utils/index.ts

@@ -12,8 +12,8 @@ export const isPcWeixinMp = (): boolean => {
 
     try {
         // 电脑版微信小程序的userAgent包含Windows或Macintosh
-        const userAgent = navigator.userAgent || ''
-        return /Windows|Macintosh/i.test(userAgent)
+        const systemInfo = uni.getSystemInfoSync()
+        return /Windows|Macintosh/i.test(systemInfo.platform)
     } catch (e) {
         return false
     }