| 
					
				 | 
			
			
				@@ -0,0 +1,178 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import html2canvas from "html2canvas"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import { uploadBase64 } from "./uploadImg"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import wx from "weixin-js-sdk"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function detectRuntimeEnvironment() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Node.js环境 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (typeof process !== "undefined" && process.versions && process.versions.node) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return "nodejs"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 微信小程序环境 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (typeof wx !== "undefined" && wx && wx.getSystemInfo) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return "wechat-miniprogram"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // WebView环境 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (typeof window !== "undefined" && typeof document !== "undefined") { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 检查是否在微信内置浏览器中 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const ua = navigator.userAgent.toLowerCase(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (ua.match(/micromessenger/i)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return "wechat-webview"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return "browser"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // React Native环境 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (typeof navigator !== "undefined" && navigator.product === "ReactNative") { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return "react-native"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 未知环境 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return "unknown"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 深拷贝 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function deepClone(obj) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (typeof obj !== "object" || obj === null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return obj; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const target = obj.constructor === Array ? [] : {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (var key in obj) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (Object.prototype.hasOwnProperty.call(obj, key)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (typeof obj[key] === "object") { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                target[key] = deepClone(obj[key]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                target[key] = obj[key]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return target; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function extractCoordinates(input) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 使用正则表达式匹配括号内的内容 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const match = input.match(/\(([^)]+)\)/); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (match) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 如果找到了匹配项,match[1] 将包含括号内的内容 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 然后我们按照空格分割这个字符串来获取坐标 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const coordinates = match[1].split(" ").map(Number); // 将每个坐标转换为数字 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return coordinates; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 如果没有找到匹配项,返回null或其他合适的值 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 节流 => 一定时间内只调用一次函数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function throttle(func, wait) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let timeout = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let lastRun = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return function (...args) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const now = new Date().getTime(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!lastRun) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 如果 lastRun 没有被设置,表示这是第一次调用 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            func.apply(this, args); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            lastRun = now; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            clearTimeout(timeout); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 设置一个新的超时,在 wait 时间后再次运行函数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            timeout = setTimeout(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (now - lastRun >= wait) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    func.apply(this, args); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    lastRun = now; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }, wait - (now - lastRun)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// 下载图片的函数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+async function downloadImage(downDom) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (downDom) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const canvas = await html2canvas(downDom, { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            useCORS: true, // 支持跨域图片 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // scale: 2, // 提高生成图片分辨率 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 2. 创建最终合成的 Canvas 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const finalCanvas = document.createElement("canvas"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const ctx = finalCanvas.getContext("2d"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 设置最终图片大小 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        finalCanvas.width = canvas.width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        finalCanvas.height = canvas.height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 绘制 DOM 转换的内容 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.drawImage(canvas, 0, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 3. 加载本地二维码图片 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const qrImage = new Image(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // qrImage.src = require("@/assets/img/weather_index/code.png"); // 本地二维码路径 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 等待二维码图片加载完成后绘制到 Canvas 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        qrImage.onload = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const qrWidth = 48 * 3; // 二维码宽度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const qrHeight = 74 * 3; // 二维码高度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const padding = 8 * 3; // 边距 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 绘制二维码到最终 Canvas 的右上角 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ctx.drawImage( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                qrImage, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                canvas.width - qrWidth - padding, // 右边距 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                padding, // 上边距 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                qrWidth, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                qrHeight 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const image = finalCanvas.toDataURL("image/png"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                uploadBase64(image); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } catch (error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                console.error("上传失败:", error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // // 创建下载链接 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // const link = document.createElement("a"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // link.href = image; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // link.download = "每日三问.png"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // link.click(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function convertImage(imgUrl) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return new Promise((resolve, reject) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fetch(imgUrl) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .then((response) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (!response.ok) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    throw new Error(`HTTP 错误:${response.status}`); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return response.blob(); // 获取图片的二进制数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .then((blob) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                const reader = new FileReader(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                reader.onload = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    // 转换成功后返回 Base64 数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    resolve(reader.result); // 通过 resolve 返回 Base64 数据 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                reader.onerror = (error) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    console.error("文件读取失败:", error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    reject(error); // 出现错误时通过 reject 抛出错误 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                reader.readAsDataURL(blob); // 将 Blob 数据转换为 Base64 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .catch((error) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                console.error("图片转换失败:", error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                reject(error); // 捕获错误并通过 reject 抛出 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+export { deepClone, extractCoordinates, throttle, downloadImage, convertImage, detectRuntimeEnvironment }; 
			 |