| 
					
				 | 
			
			
				@@ -52,26 +52,26 @@ export class CanvasUtils { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	drawPoster(data) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return new Promise(async (resolve, reject) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				// 基础参数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const w = uni.upx2px(690) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const top = uni.upx2px(0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const r = uni.upx2px(24) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				// 基础参数 - 使用2倍分辨率提高清晰度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const w = uni.upx2px(690) * 2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const top = uni.upx2px(0) * 2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const r = uni.upx2px(24) * 2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				// 计算内容布局参数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				// 计算内容布局参数 - 使用2倍分辨率 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				const watermarkArr = data.treeObj.watermarkArr || []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const lineHeight = uni.upx2px(40); // 水印文字行间距 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const startY = uni.upx2px(870); // 水印文字起始Y坐标 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const lineHeight = uni.upx2px(40) * 2; // 水印文字行间距 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const startY = uni.upx2px(870) * 2; // 水印文字起始Y坐标 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				const lastWatermarkY = startY + ((watermarkArr.length - 1) * lineHeight); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const logoHeight = uni.upx2px(80); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const logoSpacing = uni.upx2px(26); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const logoHeight = uni.upx2px(80) * 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const logoSpacing = uni.upx2px(26) * 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				const logoY = lastWatermarkY - logoHeight - logoSpacing; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				const brandTextY = logoY + logoHeight + logoSpacing; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				// 使用固定高度,确保有足够空间显示所有内容 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				// 计算canvas高度(根据内容自适应) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const bottomMargin = uni.upx2px(20); // 底部边距 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const h = brandTextY + uni.upx2px(30) + bottomMargin; // 30rpx是文字高度估算 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const bottomMargin = uni.upx2px(20) * 2; // 底部边距 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const h = brandTextY + uni.upx2px(30) * 2 + bottomMargin; // 30rpx是文字高度估算 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				// 下载所有图片到本地 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -138,54 +138,48 @@ export class CanvasUtils { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				ctx.setFillStyle('#000000') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				ctx.setTextAlign('left')                    // 设置文字对齐方式 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				ctx.setTextBaseline('top')                  // 设置文字基线 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				ctx.font = `bold ${uni.upx2px(36)}px "SweiSpringCJKtc", Arial, sans-serif`  // 设置字体样式:粗体 + 自定义字体 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				ctx.fillText(data.treeObj.year, uni.upx2px(26), uni.upx2px(34)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ctx.font = `bold ${uni.upx2px(36) * 2}px "SweiSpringCJKtc", Arial, sans-serif`  // 设置字体样式:粗体 + 自定义字体 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ctx.fillText(data.treeObj.year, uni.upx2px(26) * 2, uni.upx2px(34) * 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				// 绘制月份 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				ctx.font = `bold ${uni.upx2px(172)}px "SweiSpringCJKtc", Arial, sans-serif`  // 设置字体样式:粗体 + 自定义字体,172rpx大小 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				ctx.fillText(data.treeObj.monthNumber, uni.upx2px(26), uni.upx2px(76)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ctx.font = `bold ${uni.upx2px(172) * 2}px "SweiSpringCJKtc", Arial, sans-serif`  // 设置字体样式:粗体 + 自定义字体,172rpx大小 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ctx.fillText(data.treeObj.monthNumber, uni.upx2px(26) * 2, uni.upx2px(76) * 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				// 绘制斜线 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				ctx.setLineWidth(uni.upx2px(4))  // 设置线条宽度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ctx.setLineWidth(uni.upx2px(4) * 2)  // 设置线条宽度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				ctx.beginPath() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				ctx.moveTo(uni.upx2px(160), uni.upx2px(180))  // 斜线起点(右上角) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				ctx.lineTo(uni.upx2px(140), uni.upx2px(220))  // 斜线终点(左下角) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ctx.moveTo(uni.upx2px(160) * 2, uni.upx2px(180) * 2)  // 斜线起点(右上角) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ctx.lineTo(uni.upx2px(140) * 2, uni.upx2px(220) * 2)  // 斜线终点(左下角) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				ctx.stroke() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				// 绘制日 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				ctx.font = `bold ${uni.upx2px(48)}px "SweiSpringCJKtc", Arial, sans-serif`  // 设置字体样式:粗体 + 自定义字体,172rpx大小 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				ctx.fillText(data.treeObj.day, uni.upx2px(162), uni.upx2px(180)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ctx.font = `bold ${uni.upx2px(48) * 2}px "SweiSpringCJKtc", Arial, sans-serif`  // 设置字体样式:粗体 + 自定义字体,172rpx大小 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ctx.fillText(data.treeObj.day, uni.upx2px(162) * 2, uni.upx2px(180) * 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				// 绘制二维码图片 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				if (downloadedImages.qrCodeUrl) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						ctx.drawImage(downloadedImages.qrCodeUrl, uni.upx2px(w - -190), uni.upx2px(34), uni.upx2px(130), uni.upx2px(142)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						ctx.drawImage(downloadedImages.qrCodeUrl, uni.upx2px(545) * 2, uni.upx2px(34) * 2, uni.upx2px(130) * 2, uni.upx2px(142) * 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					} catch (error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				// 添加品种 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				ctx.setFontSize(uni.upx2px(24)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				ctx.fillText(data.treeObj.pz, uni.upx2px(w - -218), uni.upx2px(190)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				// 绘制树龄 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				ctx.setFontSize(uni.upx2px(24)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				ctx.fillText(`${data.treeObj.age}年 ${data.treeObj.age > 9 ? "老树" : "树龄"}`, uni.upx2px(w - -104), uni.upx2px(190)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				// 绘制气候适宜 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				ctx.setFontSize(uni.upx2px(24)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				ctx.fillText(data.treeObj.phenology, uni.upx2px(w - -32), uni.upx2px(230)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				// 绘制采摘方式 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				ctx.setFontSize(uni.upx2px(24)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				ctx.fillText(`气候适宜-${data.treeObj.howTxt || "果园采摘"}`, uni.upx2px(w - -114), uni.upx2px(230)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				// 添加品种 绘制树龄 - 靠右对齐 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ctx.setFontSize(uni.upx2px(24) * 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ctx.setTextAlign('right') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ctx.fillText(`${data.treeObj.pz} ${data.treeObj.age}年 ${data.treeObj.age > 9 ? "老树" : "树龄"}`, uni.upx2px(665) * 2, uni.upx2px(186) * 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				// 绘制气候适宜 绘制采摘方式 - 靠右对齐 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ctx.setFontSize(uni.upx2px(24) * 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ctx.setTextAlign('right') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ctx.fillText(`${data.treeObj.phenology} 气候适宜-${data.treeObj.howTxt || "果园采摘"}`, uni.upx2px(665) * 2, uni.upx2px(225) * 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				// 绘制树图片(带圆角) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const imgX = uni.upx2px(26); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const imgY = uni.upx2px(280); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const imgW = uni.upx2px(640); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const imgH = uni.upx2px(480); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const radius = uni.upx2px(10); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const imgX = uni.upx2px(26) * 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const imgY = uni.upx2px(280) * 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const imgW = uni.upx2px(640) * 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const imgH = uni.upx2px(480) * 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const radius = uni.upx2px(10) * 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				// 创建圆角路径 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				ctx.beginPath(); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -217,12 +211,12 @@ export class CanvasUtils { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				ctx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				// 绘制图片文字背景和边框(圆角) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const textX = uni.upx2px(w - -104); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const textY = uni.upx2px(316); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const textWidth = uni.upx2px(180); // 背景宽度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const textHeight = uni.upx2px(18);  // 背景高度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const padding = uni.upx2px(16);     // 内边距 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				const textRadius = uni.upx2px(30);  // 圆角半径 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const textX = uni.upx2px(450) * 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const textY = uni.upx2px(316) * 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const textWidth = uni.upx2px(180) * 2; // 背景宽度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const textHeight = uni.upx2px(18) * 2;  // 背景高度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const padding = uni.upx2px(16) * 2;     // 内边距 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				const textRadius = uni.upx2px(25) * 2;  // 圆角半径 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				// 绘制黑色半透明背景(圆角) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				ctx.setFillStyle('rgba(0, 0, 0, 0.6)'); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -241,7 +235,7 @@ export class CanvasUtils { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				// 绘制白色边框(圆角) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				ctx.setStrokeStyle('rgba(255, 255, 255, 0.39)'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				ctx.setLineWidth(uni.upx2px(2)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ctx.setLineWidth(uni.upx2px(2) * 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				ctx.beginPath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				ctx.moveTo(textX - padding + textRadius, textY - padding); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				ctx.lineTo(textX - padding + textWidth + padding * 2 - textRadius, textY - padding); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -260,13 +254,13 @@ export class CanvasUtils { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				ctx.setTextAlign('center'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				ctx.setTextBaseline('middle'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				// 重置字体为默认字体 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				ctx.font = `bold ${uni.upx2px(20)}px Arial, sans-serif`; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ctx.font = `bold ${uni.upx2px(20) * 2}px Arial, sans-serif`; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				ctx.fillText(`${data.treeObj.pz}-${data.treeObj.countyName}`, textX + textWidth / 2, textY + textHeight / 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				// 绘制树牌文字背景 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				if (downloadedImages.treeNameBgUrl) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						ctx.drawImage(downloadedImages.treeNameBgUrl, uni.upx2px(40), uni.upx2px(486), uni.upx2px(276), uni.upx2px(274)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						ctx.drawImage(downloadedImages.treeNameBgUrl, uni.upx2px(40) * 2, uni.upx2px(486) * 2, uni.upx2px(276) * 2, uni.upx2px(274) * 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					} catch (error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						console.error('树牌背景图片绘制失败:', error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					} 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -274,41 +268,41 @@ export class CanvasUtils { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				// 绘制树牌文字 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				ctx.setFillStyle('#ffffff'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				ctx.font = `bold ${uni.upx2px(36)}px "jiangxizhuokai", Arial, sans-serif`  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				ctx.fillText(`【${data.treeName}】`, uni.upx2px(178), uni.upx2px(565)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ctx.font = `bold ${uni.upx2px(36) * 2}px "jiangxizhuokai", Arial, sans-serif`  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ctx.fillText(`【${data.treeName}】`, uni.upx2px(178) * 2, uni.upx2px(565) * 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				ctx.font = `bold ${uni.upx2px(18)}px "jiangxizhuokai", Arial, sans-serif`  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				ctx.fillText(`${data.userInfo.nickname || data.userInfo.name}  ${data.treeObj.year}.${data.treeObj.monthNumber >= 10 ? data.treeObj.monthNumber : "0" + data.treeObj.monthNumber}.${data.treeObj.day}`, uni.upx2px(178), uni.upx2px(610)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ctx.font = `bold ${uni.upx2px(18) * 2}px "jiangxizhuokai", Arial, sans-serif`  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ctx.fillText(`${data.userInfo.nickname || data.userInfo.name}  ${data.treeObj.year}.${data.treeObj.monthNumber >= 10 ? data.treeObj.monthNumber : "0" + data.treeObj.monthNumber}.${data.treeObj.day}`, uni.upx2px(178) * 2, uni.upx2px(610) * 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				// 绘制横线(在水印文字上面) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				ctx.setStrokeStyle('#000000');  // 设置线条颜色为黑色 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				ctx.setLineWidth(uni.upx2px(2)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ctx.setLineWidth(uni.upx2px(2) * 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				// 计算第一行水印文字的长度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				const firstWatermarkText = data.treeObj.watermarkArr[0] || ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				ctx.font = `bold ${uni.upx2px(24)}px "SweiSpringCJKtc", Arial, sans-serif`; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ctx.font = `bold ${uni.upx2px(24) * 2}px "SweiSpringCJKtc", Arial, sans-serif`; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				const textMetrics = ctx.measureText(firstWatermarkText); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				const watermarkTextWidth = textMetrics.width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				ctx.beginPath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				ctx.moveTo(uni.upx2px(36), uni.upx2px(820));  // 横线起点,左边距离36rpx 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				ctx.lineTo(uni.upx2px(36) + watermarkTextWidth, uni.upx2px(820));  // 横线终点,根据文字长度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ctx.moveTo(uni.upx2px(36) * 2, uni.upx2px(820) * 2);  // 横线起点,左边距离36rpx 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ctx.lineTo(uni.upx2px(36) * 2 + watermarkTextWidth, uni.upx2px(820) * 2);  // 横线终点,根据文字长度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				ctx.stroke(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				// 绘制水印文字(根据数组长度动态生成) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				ctx.setFillStyle('#000000'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				ctx.font = `bold ${uni.upx2px(24)}px "SweiSpringCJKtc", Arial, sans-serif`  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ctx.font = `bold ${uni.upx2px(24) * 2}px "SweiSpringCJKtc", Arial, sans-serif`  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				ctx.setTextAlign('left');  // 设置左对齐,确保第一个字在指定位置 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				watermarkArr.forEach((text, index) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					const y = startY + (index * lineHeight); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					ctx.fillText(text, uni.upx2px(36), y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					ctx.fillText(text, uni.upx2px(36) * 2, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				// 绘制logo(与最后一条水印文字对齐) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				if (downloadedImages.logoUrl) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-						ctx.drawImage(downloadedImages.logoUrl, uni.upx2px(w - -230), logoY, uni.upx2px(76), logoHeight); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						ctx.drawImage(downloadedImages.logoUrl, uni.upx2px(590) * 2, logoY, uni.upx2px(76) * 2, logoHeight); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					} catch (error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						console.error('logo图片绘制失败:', error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					} 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -316,8 +310,8 @@ export class CanvasUtils { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				// 绘制飞鸟有味(与logo保持间距) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				ctx.setFillStyle('#000000'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				ctx.font = `bold ${uni.upx2px(22)}px "SweiSpringCJKtc", Arial, sans-serif`  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				ctx.fillText(`飞鸟有味`, uni.upx2px(w - -225), brandTextY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ctx.font = `bold ${uni.upx2px(22) * 2}px "SweiSpringCJKtc", Arial, sans-serif`  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ctx.fillText(`飞鸟有味`, uni.upx2px(580) * 2, brandTextY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				ctx.draw(false, () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					// 等待canvas渲染完成 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -353,12 +347,12 @@ export class CanvasUtils { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	// 保存到相册 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	saveToAlbum() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		return new Promise((resolve, reject) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			uni.showLoading({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				title: '正在生成图片...', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				mask: true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			saveToAlbum() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return new Promise((resolve, reject) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				uni.showLoading({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					title: '正在生成海报...', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					mask: true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			// 先检查canvas是否存在 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			const query = uni.createSelectorQuery(); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -377,10 +371,10 @@ export class CanvasUtils { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				uni.canvasToTempFilePath({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					canvasId: this.canvasId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					width: 690, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					height: 1140, // 固定高度1140rpx 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					destWidth: 690, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-					destHeight: 1140, // 固定高度1140rpx 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					width: 1380, // 2倍分辨率宽度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					height: 2280, // 2倍分辨率高度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					destWidth: 1380, // 2倍分辨率宽度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					destHeight: 2280, // 2倍分辨率高度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					fileType: 'png', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					success: (res) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						uni.hideLoading(); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -390,12 +384,16 @@ export class CanvasUtils { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							mask: true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						// 生成带时间戳的海报文件名 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						const timestamp = new Date().getTime(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						const posterFileName = `海报_${timestamp}.png`; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						uni.saveImageToPhotosAlbum({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							filePath: res.tempFilePath, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 							success: () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 								uni.hideLoading(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 								uni.showToast({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-									title: '保存成功', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+									title: '海报保存成功', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 									icon: 'success', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 									duration: 2000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 								}); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -465,7 +463,7 @@ export class CanvasUtils { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} catch (error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			console.error('海报生成和保存失败:', error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			uni.showToast({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-				title: error.message || '保存失败', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				title: error.message || '海报保存失败', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				icon: 'none' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			return false; 
			 |