From aed3c4cc54d586a25c5eb2c3ffc489d5268f57b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=9D=B0?= Date: Fri, 6 Mar 2026 11:10:07 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=8E=92=E6=9F=A5=E7=94=9F=E6=88=90?= =?UTF-8?q?=E6=B5=B7=E6=8A=A5=E5=A4=B1=E8=B4=A5=E7=9A=84=E5=8E=9F=E5=9B=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../detail/components/SharePopup/index.tsx | 61 +++++++++++-------- src/utils/genPoster.ts | 38 ++++++------ 2 files changed, 53 insertions(+), 46 deletions(-) diff --git a/src/game_pages/detail/components/SharePopup/index.tsx b/src/game_pages/detail/components/SharePopup/index.tsx index 8c2a105..a43261b 100644 --- a/src/game_pages/detail/components/SharePopup/index.tsx +++ b/src/game_pages/detail/components/SharePopup/index.tsx @@ -134,35 +134,42 @@ export default forwardRef(({ id, from, detail, userInfo }, ref) => { const endTime = dayjs(end_time); const dayofWeek = DayOfWeekMap.get(startTime.day()); const gameLength = `${endTime.diff(startTime, "hour")}小时`; - // Taro.showLoading({ title: "生成中..." }); - const qrCodeUrlRes = await DetailService.getQrCodeUrl({ - page: "game_pages/detail/index", - scene: `id=${id}`, - }); - // const qrCodeUrl = await base64ToTempFilePath( - // qrCodeUrlRes.data.qr_code_base64 - // ); - const qrCodeUrl = qrCodeUrlRes.data.ossPath; + let qrCodeUrl = ""; + try { + const qrCodeUrlRes = await DetailService.getQrCodeUrl({ + page: "game_pages/detail/index", + scene: `id=${id}`, + }); + qrCodeUrl = qrCodeUrlRes.data.ossPath; + } catch (e) { + Taro.showToast({ title: "获取二维码失败", icon: "error" }); + return; + } await delay(100); - // Taro.showLoading({ title: "生成中..." }); - console.log('url', qrCodeUrl) - const url = await generatePosterImage({ - playType: play_type, - ntrp: `NTRP ${genNTRPRequirementText(skill_level_min, skill_level_max)}`, - mainCoursal: - image_list[0] && image_list[0].startsWith("http") - ? image_list[0] - : `${OSS_BASE}/front/ball/images/0621b8cf-f7d6-43ad-b852-7dc39f29a782.png`, - nickname, - avatarUrl: avatar_url, - title, - locationName: location_name, - date: `${startTime.format("M月D日")} (${dayofWeek})`, - time: `${startTime.format("ah")}点 ${gameLength}`, - qrCodeUrl, - }); + console.log("url", qrCodeUrl); + let url = ""; + try { + url = await generatePosterImage({ + playType: play_type, + ntrp: `NTRP ${genNTRPRequirementText(skill_level_min, skill_level_max)}`, + mainCoursal: + image_list[0] && image_list[0].startsWith("http") + ? image_list[0] + : `${OSS_BASE}/front/ball/images/0621b8cf-f7d6-43ad-b852-7dc39f29a782.png`, + nickname, + avatarUrl: avatar_url, + title, + locationName: location_name, + date: `${startTime.format("M月D日")} (${dayofWeek})`, + time: `${startTime.format("ah")}点 ${gameLength}`, + qrCodeUrl, + }); + } catch (e) { + Taro.showToast({ title: "生成海报失败,请重试", icon: "error" }); + return; + } - console.log('urlend', url) + console.log("urlend", url); // Taro.hideLoading(); Taro.showShareImageMenu({ path: url, diff --git a/src/utils/genPoster.ts b/src/utils/genPoster.ts index 898ee05..8bde940 100644 --- a/src/utils/genPoster.ts +++ b/src/utils/genPoster.ts @@ -55,26 +55,26 @@ function getImageWh(src: string): Promise<{ width: number; height: number }> { } /** 加载图片 */ -function loadImage(canvas: any, src: string): Promise { +function loadImage(canvas: any, src: string, key?: string): Promise { return new Promise((resolve, reject) => { - - let timer: any; + let timer: ReturnType; const img = canvas.createImage(); - img.crossOrigin = "anonymous" + img.crossOrigin = "anonymous"; img.onload = () => { clearTimeout(timer); resolve(img); }; - img.onerror = () => { + img.onerror = (e: Error) => { clearTimeout(timer); - console.log('img error', src) - } - + const errMsg = `Image load failed: ${key}: ${src}` + console.warn(errMsg) + reject(new Error(errMsg)); + }; timer = setTimeout(() => { - reject(new Error(`Image load timeout: ${src}`)); + reject(new Error(`Image load timeout: ${key}: ${src}`)); }, 8000); img.src = src; @@ -327,21 +327,21 @@ export async function generatePosterImage(data: any): Promise { console.log('ctx', ctx) - + // 背景渐变 roundRectGradient(ctx, 0, 0, width, height, 24, "#BFFFEF", "#F2FFFC"); console.log('bgUrl', bgUrl) - const bgImg = await loadImage(canvas, bgUrl); + const bgImg = await loadImage(canvas, bgUrl, 'bgUrl'); ctx.drawImage(bgImg, 0, 0, width, height); - console.log('bgUrlend', ) + console.log('bgUrlend',) roundRotateRect(ctx, 70, 100, width - 140, width - 140, 20, '#fff', deg2rad(-6)); // 顶部图片 - const mainImg = await loadImage(canvas, data.mainCoursal); + const mainImg = await loadImage(canvas, data.mainCoursal, 'mainCoursal'); console.log('mainCoursal', data.mainCoursal) await drawRotateCoverImage( ctx, @@ -375,7 +375,7 @@ export async function generatePosterImage(data: any): Promise { left = 20; // 用户头像 - const avatarImg = await loadImage(canvas, data.avatarUrl); + const avatarImg = await loadImage(canvas, data.avatarUrl, 'avatar'); ctx.save(); ctx.beginPath(); ctx.arc(left + 30, top + 30, 30, 0, Math.PI * 2); @@ -396,7 +396,7 @@ export async function generatePosterImage(data: any): Promise { ctx.fillStyle = "#00B578"; ctx.fillText("球局", left, top); - const ringImg = await loadImage(canvas, ringUrl); + const ringImg = await loadImage(canvas, ringUrl, 'ring'); ctx.drawImage(ringImg, left - 10, top - 30, 80, 36); left = 20; @@ -410,7 +410,7 @@ export async function generatePosterImage(data: any): Promise { top = r.top + 30; left = 20; - const dateImg = await loadImage(canvas, dateIcon); + const dateImg = await loadImage(canvas, dateIcon, 'date'); console.log('dateIcon', dateIcon) await drawCoverImage( @@ -440,7 +440,7 @@ export async function generatePosterImage(data: any): Promise { top += 24; - const mapImg = await loadImage(canvas, mapIcon); + const mapImg = await loadImage(canvas, mapIcon, 'map'); await drawCoverImage(ctx, canvas, mapIcon, mapImg, left, top, 40, 40, 12); left += 40 + 16; @@ -454,7 +454,7 @@ export async function generatePosterImage(data: any): Promise { top = r.top + 60; const logoWh = await getImageWh(logoText); - const logoTextImg = await loadImage(canvas, logoText); + const logoTextImg = await loadImage(canvas, logoText, 'logo'); ctx.drawImage( logoTextImg, left, @@ -464,7 +464,7 @@ export async function generatePosterImage(data: any): Promise { 400 / (logoWh.width / logoWh.height) ); - const qrImg = await loadImage(canvas, data.qrCodeUrl); + const qrImg = await loadImage(canvas, data.qrCodeUrl, 'qrcode'); // roundRectGradient(ctx, width - 12 - 150, height - 22 - 140, 140, 140, 20, "#fff", "#fff") ctx.drawImage(qrImg, width - 22 - 100, height - 22 - 100 - 2, 100, 100);