| 
									
										
										
										
											2025-07-14 14:32:08 +08:00
										 |  |  |  | <template> | 
					
						
							| 
									
										
										
										
											2025-07-14 17:48:22 +08:00
										 |  |  |  |   <view ref="specialSharePage" class="special-share-page"> | 
					
						
							| 
									
										
										
										
											2025-07-14 14:32:08 +08:00
										 |  |  |  |     <!-- 特殊场景背景图片 --> | 
					
						
							|  |  |  |  |     <image | 
					
						
							|  |  |  |  |       class="share-bg-image" | 
					
						
							|  |  |  |  |       :src="specialBackgroundImage" | 
					
						
							|  |  |  |  |       mode="scaleToFill" | 
					
						
							| 
									
										
										
										
											2025-07-14 17:48:22 +08:00
										 |  |  |  |       crossorigin="anonymous" | 
					
						
							| 
									
										
										
										
											2025-07-14 14:32:08 +08:00
										 |  |  |  |       @load="onBackgroundImageLoad" | 
					
						
							|  |  |  |  |       @error="onBackgroundImageError" | 
					
						
							|  |  |  |  |       v-if="specialBackgroundImage" | 
					
						
							|  |  |  |  |     ></image> | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     <!-- 加载状态 --> | 
					
						
							|  |  |  |  |     <view | 
					
						
							|  |  |  |  |       class="loading-container" | 
					
						
							|  |  |  |  |       v-if="!specialBackgroundImage || isLoadingBackground" | 
					
						
							|  |  |  |  |     > | 
					
						
							|  |  |  |  |       <view class="loader"></view> | 
					
						
							|  |  |  |  |       <text class="loading-text">{{ | 
					
						
							|  |  |  |  |         isLoadingBackground ? '正在获取背景图片...' : '正在加载分享背景...' | 
					
						
							|  |  |  |  |       }}</text> | 
					
						
							|  |  |  |  |     </view> | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     <view | 
					
						
							|  |  |  |  |       class="share-wrapper" | 
					
						
							|  |  |  |  |       v-if="specialBackgroundImage && !isLoadingBackground" | 
					
						
							|  |  |  |  |     > | 
					
						
							|  |  |  |  |       <view class="portal-frame" :class="{ 'is-loaded': isLoaded }"> | 
					
						
							|  |  |  |  |         <view class="qr-code-outer special-qr-style"> | 
					
						
							|  |  |  |  |           <image | 
					
						
							|  |  |  |  |             class="qr-code" | 
					
						
							|  |  |  |  |             :src="qrCodeImage" | 
					
						
							|  |  |  |  |             mode="aspectFit" | 
					
						
							|  |  |  |  |             v-if="qrCodeImage" | 
					
						
							|  |  |  |  |           ></image> | 
					
						
							|  |  |  |  |           <view v-else class="qr-code-placeholder"> | 
					
						
							|  |  |  |  |             <view class="loader"></view> | 
					
						
							|  |  |  |  |           </view> | 
					
						
							|  |  |  |  |         </view> | 
					
						
							| 
									
										
										
										
											2025-07-14 17:48:22 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-14 14:32:08 +08:00
										 |  |  |  |         <text | 
					
						
							|  |  |  |  |           class="member-code-text special-member-code-style" | 
					
						
							|  |  |  |  |           style=" | 
					
						
							|  |  |  |  |             font-size: 30rpx; | 
					
						
							|  |  |  |  |             color: #005bac; | 
					
						
							|  |  |  |  |             font-weight: bold; | 
					
						
							|  |  |  |  |             margin-top: 20rpx; | 
					
						
							|  |  |  |  |           " | 
					
						
							|  |  |  |  |           >{{ desensitization(userInfo.memberCode) }}</text | 
					
						
							|  |  |  |  |         > | 
					
						
							|  |  |  |  |       </view> | 
					
						
							|  |  |  |  |     </view> | 
					
						
							|  |  |  |  |   </view> | 
					
						
							|  |  |  |  | </template> | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | <script> | 
					
						
							| 
									
										
										
										
											2025-07-14 17:48:22 +08:00
										 |  |  |  | import { snapdom } from '@zumer/snapdom' | 
					
						
							| 
									
										
										
										
											2025-07-14 14:32:08 +08:00
										 |  |  |  | import html2canvas from 'html2canvas' | 
					
						
							|  |  |  |  | import { getSharedImg } from '@/config/login' | 
					
						
							|  |  |  |  | export default { | 
					
						
							|  |  |  |  |   name: 'SpecialSharePage', | 
					
						
							|  |  |  |  |   props: { | 
					
						
							|  |  |  |  |     qrCodeImage: { | 
					
						
							|  |  |  |  |       type: String, | 
					
						
							|  |  |  |  |       default: '', | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  |     userInfo: { | 
					
						
							|  |  |  |  |       type: Object, | 
					
						
							|  |  |  |  |       default: () => ({}), | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  |     isWechat: { | 
					
						
							|  |  |  |  |       type: Boolean, | 
					
						
							|  |  |  |  |       default: false, | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  |     isLoaded: { | 
					
						
							|  |  |  |  |       type: Boolean, | 
					
						
							|  |  |  |  |       default: false, | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  |     // 移除specialBackgroundImage prop,改为接口获取
 | 
					
						
							|  |  |  |  |     // 调试用:跳过图片验证
 | 
					
						
							|  |  |  |  |     skipImageVerification: { | 
					
						
							|  |  |  |  |       type: Boolean, | 
					
						
							|  |  |  |  |       default: false, | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  |   }, | 
					
						
							|  |  |  |  |   data() { | 
					
						
							|  |  |  |  |     return { | 
					
						
							|  |  |  |  |       backgroundImageLoaded: false, | 
					
						
							|  |  |  |  |       imageLoadRetryCount: 0, | 
					
						
							|  |  |  |  |       maxRetryCount: 3, | 
					
						
							|  |  |  |  |       specialBackgroundImage: '', // 存储接口返回的背景图
 | 
					
						
							|  |  |  |  |       isLoadingBackground: false, // 是否正在加载背景图
 | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |   }, | 
					
						
							| 
									
										
										
										
											2025-07-14 17:48:22 +08:00
										 |  |  |  |   created() { | 
					
						
							| 
									
										
										
										
											2025-07-14 14:32:08 +08:00
										 |  |  |  |     this.getBackgroundImage() | 
					
						
							|  |  |  |  |   }, | 
					
						
							|  |  |  |  |   methods: { | 
					
						
							|  |  |  |  |     desensitization(str) { | 
					
						
							|  |  |  |  |       if (!str) return '' | 
					
						
							|  |  |  |  |       if (str.length <= 8) return str.slice(0, 4) + '****' | 
					
						
							|  |  |  |  |       const len = str.length - 6 | 
					
						
							|  |  |  |  |       const placeholder = '*'.repeat(len) | 
					
						
							|  |  |  |  |       return str.slice(0, 4) + placeholder + str.slice(-2) | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 背景图片加载成功
 | 
					
						
							|  |  |  |  |     onBackgroundImageLoad() { | 
					
						
							|  |  |  |  |       this.backgroundImageLoaded = true | 
					
						
							|  |  |  |  |       console.log('特殊场景背景图片加载成功') | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 背景图片加载失败
 | 
					
						
							|  |  |  |  |     onBackgroundImageError(e) { | 
					
						
							|  |  |  |  |       console.error('特殊场景背景图片加载失败:', e) | 
					
						
							|  |  |  |  |       this.backgroundImageLoaded = false | 
					
						
							|  |  |  |  |       this.imageLoadRetryCount++ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |       // 如果重试次数未达到上限,可以通知父组件重试
 | 
					
						
							|  |  |  |  |       if (this.imageLoadRetryCount < this.maxRetryCount) { | 
					
						
							|  |  |  |  |         console.log( | 
					
						
							|  |  |  |  |           `图片加载失败,重试中 (${this.imageLoadRetryCount}/${this.maxRetryCount})` | 
					
						
							|  |  |  |  |         ) | 
					
						
							|  |  |  |  |         this.$emit('background-image-retry', this.imageLoadRetryCount) | 
					
						
							|  |  |  |  |       } else { | 
					
						
							|  |  |  |  |         this.$emit('background-image-error', e) | 
					
						
							|  |  |  |  |       } | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 获取特殊场景背景图片
 | 
					
						
							|  |  |  |  |     async getBackgroundImage() { | 
					
						
							|  |  |  |  |       if (this.skipImageVerification) { | 
					
						
							|  |  |  |  |         this.specialBackgroundImage = '' // 跳过验证时清空背景图
 | 
					
						
							|  |  |  |  |         this.backgroundImageLoaded = true | 
					
						
							|  |  |  |  |         return | 
					
						
							|  |  |  |  |       } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |       if (this.specialBackgroundImage) { | 
					
						
							|  |  |  |  |         // 如果背景图已加载,则直接使用
 | 
					
						
							|  |  |  |  |         this.backgroundImageLoaded = true | 
					
						
							|  |  |  |  |         return | 
					
						
							|  |  |  |  |       } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |       this.isLoadingBackground = true | 
					
						
							|  |  |  |  |       try { | 
					
						
							|  |  |  |  |         const result = await getSharedImg() | 
					
						
							|  |  |  |  |         if (result && result.code === 200 && result.data) { | 
					
						
							|  |  |  |  |           this.specialBackgroundImage = | 
					
						
							|  |  |  |  |             'data:image/png;base64,' + result.data.base64 | 
					
						
							|  |  |  |  |           this.backgroundImageLoaded = true | 
					
						
							|  |  |  |  |         } else { | 
					
						
							|  |  |  |  |           this.backgroundImageLoaded = false | 
					
						
							|  |  |  |  |           this.imageLoadRetryCount++ | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |       } catch (error) { | 
					
						
							|  |  |  |  |         this.backgroundImageLoaded = false | 
					
						
							|  |  |  |  |         this.imageLoadRetryCount++ | 
					
						
							|  |  |  |  |         if (this.imageLoadRetryCount < this.maxRetryCount) { | 
					
						
							|  |  |  |  |           this.$emit('background-image-retry', this.imageLoadRetryCount) | 
					
						
							|  |  |  |  |         } else { | 
					
						
							|  |  |  |  |           this.$emit('background-image-error', error) | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |       } finally { | 
					
						
							|  |  |  |  |         this.isLoadingBackground = false | 
					
						
							|  |  |  |  |       } | 
					
						
							|  |  |  |  |       return this.specialBackgroundImage | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     async generateShareImage() { | 
					
						
							| 
									
										
										
										
											2025-07-14 17:48:22 +08:00
										 |  |  |  |       // await this.getBackgroundImage()
 | 
					
						
							| 
									
										
										
										
											2025-07-14 14:32:08 +08:00
										 |  |  |  |       try { | 
					
						
							| 
									
										
										
										
											2025-07-14 17:48:22 +08:00
										 |  |  |  |         this.$nextTick(() => { | 
					
						
							|  |  |  |  |           const info = uni.getSystemInfoSync() | 
					
						
							|  |  |  |  |           console.log(info.platform, '.....info') | 
					
						
							|  |  |  |  |           if (info.platform === 'ios') { | 
					
						
							|  |  |  |  |             console.log('iOS detected, using html2canvas for capturing.') | 
					
						
							|  |  |  |  |             this.capturePageWithHtml2Canvas() | 
					
						
							|  |  |  |  |           } else { | 
					
						
							|  |  |  |  |             console.log('Non-iOS detected, using snapdom for capturing.') | 
					
						
							|  |  |  |  |             this.capturePageWithSnapDom() | 
					
						
							|  |  |  |  |           } | 
					
						
							|  |  |  |  |         }) | 
					
						
							| 
									
										
										
										
											2025-07-14 14:32:08 +08:00
										 |  |  |  |       } catch (error) { | 
					
						
							|  |  |  |  |         uni.hideLoading() | 
					
						
							|  |  |  |  |         uni.showToast({ title: '图片生成失败,请稍后重试', icon: 'none' }) | 
					
						
							|  |  |  |  |       } | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-14 17:48:22 +08:00
										 |  |  |  |     // 新增:使用html2canvas截取整个页面 (For iOS)
 | 
					
						
							| 
									
										
										
										
											2025-07-14 14:32:08 +08:00
										 |  |  |  |     async capturePageWithHtml2Canvas() { | 
					
						
							|  |  |  |  |       return new Promise(async (resolve, reject) => { | 
					
						
							|  |  |  |  |         // 确保所有图片都已加载完成
 | 
					
						
							|  |  |  |  |         const waitForImages = async () => { | 
					
						
							|  |  |  |  |           // 检查是否正在加载背景图片
 | 
					
						
							|  |  |  |  |           if (this.isLoadingBackground) { | 
					
						
							|  |  |  |  |             console.log('等待背景图片接口调用完成...') | 
					
						
							|  |  |  |  |             setTimeout(waitForImages, 100) | 
					
						
							|  |  |  |  |             return | 
					
						
							|  |  |  |  |           } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |           // 检查背景图片是否加载完成
 | 
					
						
							|  |  |  |  |           if (!this.backgroundImageLoaded) { | 
					
						
							|  |  |  |  |             console.log('等待背景图片加载完成...') | 
					
						
							|  |  |  |  |             setTimeout(waitForImages, 100) | 
					
						
							|  |  |  |  |             return | 
					
						
							|  |  |  |  |           } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |           // 检查二维码是否存在
 | 
					
						
							|  |  |  |  |           if (!this.qrCodeImage) { | 
					
						
							|  |  |  |  |             console.log('等待二维码生成...') | 
					
						
							|  |  |  |  |             setTimeout(waitForImages, 100) | 
					
						
							|  |  |  |  |             return | 
					
						
							|  |  |  |  |           } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |           // 检查特殊背景图片参数是否存在
 | 
					
						
							|  |  |  |  |           if (!this.specialBackgroundImage) { | 
					
						
							|  |  |  |  |             console.log('等待特殊背景图片参数...') | 
					
						
							|  |  |  |  |             setTimeout(waitForImages, 100) | 
					
						
							|  |  |  |  |             return | 
					
						
							|  |  |  |  |           } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-14 17:48:22 +08:00
										 |  |  |  |           console.log('所有图片准备就绪,开始使用html2canvas截图...') | 
					
						
							| 
									
										
										
										
											2025-07-14 14:32:08 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |           // 等待确保渲染完成
 | 
					
						
							|  |  |  |  |           setTimeout(() => { | 
					
						
							|  |  |  |  |             const element = this.$el | 
					
						
							|  |  |  |  |             if (!element) { | 
					
						
							| 
									
										
										
										
											2025-07-14 17:48:22 +08:00
										 |  |  |  |               uni.hideLoading() | 
					
						
							| 
									
										
										
										
											2025-07-14 14:32:08 +08:00
										 |  |  |  |               reject(new Error('找不到组件容器')) | 
					
						
							|  |  |  |  |               return | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             html2canvas(element, { | 
					
						
							|  |  |  |  |               useCORS: true, | 
					
						
							| 
									
										
										
										
											2025-07-14 17:48:22 +08:00
										 |  |  |  |               allowTaint: true, | 
					
						
							| 
									
										
										
										
											2025-07-14 14:32:08 +08:00
										 |  |  |  |               backgroundColor: null, | 
					
						
							| 
									
										
										
										
											2025-07-14 17:48:22 +08:00
										 |  |  |  |               scale: 2, // 提高清晰度
 | 
					
						
							|  |  |  |  |               dpi: 300, | 
					
						
							| 
									
										
										
										
											2025-07-14 14:32:08 +08:00
										 |  |  |  |               width: element.offsetWidth, | 
					
						
							|  |  |  |  |               height: element.offsetHeight, | 
					
						
							|  |  |  |  |             }) | 
					
						
							|  |  |  |  |               .then(canvas => { | 
					
						
							| 
									
										
										
										
											2025-07-14 17:48:22 +08:00
										 |  |  |  |                 const dataUrl = canvas.toDataURL('image/jpeg', 1.0) | 
					
						
							| 
									
										
										
										
											2025-07-14 14:32:08 +08:00
										 |  |  |  |                 uni.hideLoading() | 
					
						
							| 
									
										
										
										
											2025-07-15 10:34:28 +08:00
										 |  |  |  |                 // this.handleShareGenerated(dataUrl)
 | 
					
						
							| 
									
										
										
										
											2025-07-14 14:32:08 +08:00
										 |  |  |  |                 this.$emit('share-generated', dataUrl) | 
					
						
							|  |  |  |  |                 resolve() | 
					
						
							|  |  |  |  |               }) | 
					
						
							|  |  |  |  |               .catch(err => { | 
					
						
							|  |  |  |  |                 uni.hideLoading() | 
					
						
							|  |  |  |  |                 console.error('html2canvas截取失败:', err) | 
					
						
							|  |  |  |  |                 uni.showToast({ | 
					
						
							|  |  |  |  |                   title: '图片生成失败,请稍后重试', | 
					
						
							|  |  |  |  |                   icon: 'none', | 
					
						
							|  |  |  |  |                 }) | 
					
						
							|  |  |  |  |                 reject(err) | 
					
						
							|  |  |  |  |               }) | 
					
						
							|  |  |  |  |           }, 1000) | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         // 开始等待图片加载
 | 
					
						
							|  |  |  |  |         waitForImages() | 
					
						
							|  |  |  |  |       }) | 
					
						
							|  |  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2025-07-14 17:48:22 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 使用snapDOM截取整个页面
 | 
					
						
							|  |  |  |  |     async capturePageWithSnapDom() { | 
					
						
							|  |  |  |  |       return new Promise(async (resolve, reject) => { | 
					
						
							|  |  |  |  |         // 确保所有图片都已加载完成
 | 
					
						
							|  |  |  |  |         const waitForImages = async () => { | 
					
						
							|  |  |  |  |           // 检查是否正在加载背景图片
 | 
					
						
							|  |  |  |  |           if (this.isLoadingBackground) { | 
					
						
							|  |  |  |  |             console.log('等待背景图片接口调用完成...') | 
					
						
							|  |  |  |  |             setTimeout(waitForImages, 100) | 
					
						
							|  |  |  |  |             return | 
					
						
							|  |  |  |  |           } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |           // 检查背景图片是否加载完成
 | 
					
						
							|  |  |  |  |           if (!this.backgroundImageLoaded) { | 
					
						
							|  |  |  |  |             console.log('等待背景图片加载完成...') | 
					
						
							|  |  |  |  |             setTimeout(waitForImages, 100) | 
					
						
							|  |  |  |  |             return | 
					
						
							|  |  |  |  |           } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |           // 检查二维码是否存在
 | 
					
						
							|  |  |  |  |           if (!this.qrCodeImage) { | 
					
						
							|  |  |  |  |             console.log('等待二维码生成...') | 
					
						
							|  |  |  |  |             setTimeout(waitForImages, 100) | 
					
						
							|  |  |  |  |             return | 
					
						
							|  |  |  |  |           } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |           // 检查特殊背景图片参数是否存在
 | 
					
						
							|  |  |  |  |           if (!this.specialBackgroundImage) { | 
					
						
							|  |  |  |  |             console.log('等待特殊背景图片参数...') | 
					
						
							|  |  |  |  |             setTimeout(waitForImages, 100) | 
					
						
							|  |  |  |  |             return | 
					
						
							|  |  |  |  |           } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |           console.log('所有图片准备就绪,开始截图...') | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |           // 等待确保渲染完成
 | 
					
						
							|  |  |  |  |           setTimeout(async () => { | 
					
						
							|  |  |  |  |             const element = this.$el | 
					
						
							|  |  |  |  |             if (!element) { | 
					
						
							|  |  |  |  |               reject(new Error('找不到组件容器')) | 
					
						
							|  |  |  |  |               return | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             try { | 
					
						
							|  |  |  |  |               // 获取元素的所有可能尺寸
 | 
					
						
							|  |  |  |  |               const rect = element.getBoundingClientRect() | 
					
						
							|  |  |  |  |               const offsetWidth = element.offsetWidth | 
					
						
							|  |  |  |  |               const offsetHeight = element.offsetHeight | 
					
						
							|  |  |  |  |               const scrollWidth = element.scrollWidth | 
					
						
							|  |  |  |  |               const scrollHeight = element.scrollHeight | 
					
						
							|  |  |  |  |               const clientWidth = element.clientWidth | 
					
						
							|  |  |  |  |               const clientHeight = element.clientHeight | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |               // 计算实际需要的尺寸(取最大值确保完整)
 | 
					
						
							|  |  |  |  |               const elementWidth = Math.max( | 
					
						
							|  |  |  |  |                 offsetWidth, | 
					
						
							|  |  |  |  |                 scrollWidth, | 
					
						
							|  |  |  |  |                 clientWidth, | 
					
						
							|  |  |  |  |                 rect.width | 
					
						
							|  |  |  |  |               ) | 
					
						
							|  |  |  |  |               const elementHeight = Math.max( | 
					
						
							|  |  |  |  |                 offsetHeight, | 
					
						
							|  |  |  |  |                 scrollHeight, | 
					
						
							|  |  |  |  |                 clientHeight, | 
					
						
							|  |  |  |  |                 rect.height | 
					
						
							|  |  |  |  |               ) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |               setTimeout(async () => { | 
					
						
							|  |  |  |  |                 try { | 
					
						
							|  |  |  |  |                   const result = await snapdom(element, { | 
					
						
							|  |  |  |  |                     width: elementWidth, | 
					
						
							|  |  |  |  |                     height: elementHeight, | 
					
						
							|  |  |  |  |                     quality: 1, | 
					
						
							|  |  |  |  |                     compress: false, | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                     // useProxy: true,
 | 
					
						
							|  |  |  |  |                   }) | 
					
						
							|  |  |  |  |                   const canvas = await result.toCanvas() | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                   const dataUrl = canvas.toDataURL('image/jpeg') | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                   uni.hideLoading() | 
					
						
							| 
									
										
										
										
											2025-07-15 10:34:28 +08:00
										 |  |  |  |                   // this.handleShareGenerated(dataUrl)
 | 
					
						
							| 
									
										
										
										
											2025-07-14 17:48:22 +08:00
										 |  |  |  |                   this.$emit('share-generated', dataUrl) | 
					
						
							|  |  |  |  |                   resolve() | 
					
						
							|  |  |  |  |                 } catch (err) { | 
					
						
							|  |  |  |  |                   uni.hideLoading() | 
					
						
							|  |  |  |  |                   console.error('snapDOM截取失败:', err) | 
					
						
							|  |  |  |  |                   uni.showToast({ | 
					
						
							|  |  |  |  |                     title: '图片生成失败,请稍后重试', | 
					
						
							|  |  |  |  |                     icon: 'none', | 
					
						
							|  |  |  |  |                   }) | 
					
						
							|  |  |  |  |                   reject(err) | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |               }, 500) | 
					
						
							|  |  |  |  |             } catch (err) { | 
					
						
							|  |  |  |  |               uni.hideLoading() | 
					
						
							|  |  |  |  |               console.error('snapDOM初始化失败:', err) | 
					
						
							|  |  |  |  |               uni.showToast({ | 
					
						
							|  |  |  |  |                 title: '图片生成失败,请稍后重试', | 
					
						
							|  |  |  |  |                 icon: 'none', | 
					
						
							|  |  |  |  |               }) | 
					
						
							|  |  |  |  |               reject(err) | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |           }, 1000) | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         // 开始等待图片加载
 | 
					
						
							|  |  |  |  |         waitForImages() | 
					
						
							|  |  |  |  |       }) | 
					
						
							|  |  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2025-07-14 14:32:08 +08:00
										 |  |  |  |   }, | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | </script> | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | <style lang="scss" scoped> | 
					
						
							|  |  |  |  | .special-share-page { | 
					
						
							|  |  |  |  |   position: relative; | 
					
						
							|  |  |  |  |   width: 100%; | 
					
						
							|  |  |  |  |   height: 100%; | 
					
						
							|  |  |  |  |   display: flex; | 
					
						
							|  |  |  |  |   flex-direction: column; | 
					
						
							|  |  |  |  |   align-items: center; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /* 背景图片样式 */ | 
					
						
							|  |  |  |  | .share-bg-image { | 
					
						
							|  |  |  |  |   position: absolute; | 
					
						
							|  |  |  |  |   top: 0; | 
					
						
							|  |  |  |  |   left: 0; | 
					
						
							|  |  |  |  |   width: 100%; | 
					
						
							|  |  |  |  |   height: 100%; | 
					
						
							|  |  |  |  |   z-index: 1; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /* 加载状态 */ | 
					
						
							|  |  |  |  | .loading-container { | 
					
						
							|  |  |  |  |   position: absolute; | 
					
						
							|  |  |  |  |   top: 50%; | 
					
						
							|  |  |  |  |   left: 50%; | 
					
						
							|  |  |  |  |   transform: translate(-50%, -50%); | 
					
						
							|  |  |  |  |   display: flex; | 
					
						
							|  |  |  |  |   flex-direction: column; | 
					
						
							|  |  |  |  |   align-items: center; | 
					
						
							|  |  |  |  |   z-index: 2; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | .loading-text { | 
					
						
							|  |  |  |  |   margin-top: 20rpx; | 
					
						
							|  |  |  |  |   font-size: 28rpx; | 
					
						
							|  |  |  |  |   color: #666; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | .share-wrapper { | 
					
						
							|  |  |  |  |   position: absolute; | 
					
						
							|  |  |  |  |   z-index: 2; | 
					
						
							|  |  |  |  |   bottom: 22%; | 
					
						
							|  |  |  |  |   display: flex; | 
					
						
							|  |  |  |  |   flex-direction: column; | 
					
						
							|  |  |  |  |   align-items: center; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | .portal-frame { | 
					
						
							|  |  |  |  |   padding: 32rpx; | 
					
						
							|  |  |  |  |   width: 520rpx; | 
					
						
							|  |  |  |  |   border-radius: 40rpx; | 
					
						
							|  |  |  |  |   display: flex; | 
					
						
							|  |  |  |  |   box-sizing: border-box; | 
					
						
							|  |  |  |  |   flex-direction: column; | 
					
						
							|  |  |  |  |   align-items: center; | 
					
						
							|  |  |  |  |   margin: 0 auto; | 
					
						
							|  |  |  |  |   opacity: 0; | 
					
						
							|  |  |  |  |   transform: translateY(20rpx); | 
					
						
							|  |  |  |  |   transition: all 0.3s ease; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | .portal-frame.is-loaded { | 
					
						
							|  |  |  |  |   opacity: 1; | 
					
						
							|  |  |  |  |   transform: translateY(0); | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /* 特殊场景二维码样式区域 - 用户自定义样式位置 */ | 
					
						
							|  |  |  |  | .qr-code-outer { | 
					
						
							|  |  |  |  |   width: 400rpx; | 
					
						
							|  |  |  |  |   height: 400rpx; | 
					
						
							|  |  |  |  |   border-radius: 20rpx; | 
					
						
							|  |  |  |  |   display: flex; | 
					
						
							|  |  |  |  |   align-items: center; | 
					
						
							|  |  |  |  |   justify-content: center; | 
					
						
							|  |  |  |  |   padding: 12rpx; | 
					
						
							|  |  |  |  |   box-sizing: border-box; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | .qr-code, | 
					
						
							|  |  |  |  | .qr-code-placeholder { | 
					
						
							|  |  |  |  |   width: 100%; | 
					
						
							|  |  |  |  |   height: 100%; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | .qr-code { | 
					
						
							|  |  |  |  |   border-radius: 16rpx; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | .qr-code-placeholder { | 
					
						
							|  |  |  |  |   display: flex; | 
					
						
							|  |  |  |  |   align-items: center; | 
					
						
							|  |  |  |  |   justify-content: center; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | .loader { | 
					
						
							|  |  |  |  |   width: 100rpx; | 
					
						
							|  |  |  |  |   height: 100rpx; | 
					
						
							|  |  |  |  |   border: 8rpx solid rgba(0, 0, 0, 0.1); | 
					
						
							|  |  |  |  |   border-left-color: #0072ff; | 
					
						
							|  |  |  |  |   border-radius: 50%; | 
					
						
							|  |  |  |  |   animation: spin 1s linear infinite; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | @keyframes spin { | 
					
						
							|  |  |  |  |   to { | 
					
						
							|  |  |  |  |     transform: rotate(360deg); | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /* 特殊场景会员编号样式区域 - 用户自定义样式位置 */ | 
					
						
							|  |  |  |  | .member-code-text { | 
					
						
							|  |  |  |  |   /* 用户可以在这里自定义会员编号的样式 */ | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /* 特殊场景下的会员编号样式 */ | 
					
						
							|  |  |  |  | .special-member-code-style { | 
					
						
							|  |  |  |  |   /* 用户可以在这里自定义特殊场景下的会员编号样式 */ | 
					
						
							|  |  |  |  |   /* 例如:不同的位置、颜色、字体等 */ | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | </style> |