diff --git a/src/components/Header.vue b/src/components/Header.vue index df20b3d..923fab8 100644 --- a/src/components/Header.vue +++ b/src/components/Header.vue @@ -115,7 +115,7 @@ onBeforeUnmount(() => { :size="40" borderColor="#333" /> - {{ user.nickName }} + {{ user.nickName }} { font-size: 30rpx; color: #333333; margin: 0 20rpx; + max-width: 200rpx; } diff --git a/src/components/PointRecord.vue b/src/components/PointRecord.vue index c170ebf..05ad7c6 100644 --- a/src/components/PointRecord.vue +++ b/src/components/PointRecord.vue @@ -113,6 +113,7 @@ onMounted(() => { font-size: 26rpx; margin-right: 10px; position: relative; + color: #333; } .container > view:last-child { margin-right: 1vw; diff --git a/src/components/RewardUs.vue b/src/components/RewardUs.vue index 772ba09..319e9e6 100644 --- a/src/components/RewardUs.vue +++ b/src/components/RewardUs.vue @@ -15,6 +15,7 @@ const props = defineProps({ }); const amounts = [5, 20, 50, 80, 100, 200]; const selected = ref(null); +const checked = ref(false); const formData = reactive({ name: "", @@ -63,6 +64,10 @@ watch( () => props.show, () => { selected.value = null; + formData.name = ""; + formData.account = ""; + formData.organization = ""; + formData.suggestion = ""; } ); @@ -84,11 +89,15 @@ watch( {{ item }} - - + + + 我想给建议(选填) - + 您的姓名 @@ -114,6 +123,7 @@ watch( display: flex; flex-direction: column; align-items: center; + transition: all 0.3s ease-in-out; } .container > text:first-child { font-weight: 500; @@ -153,6 +163,13 @@ watch( justify-content: flex-start; margin-top: 20rpx; } +.container > view:nth-child(3) > view { + width: 32rpx; + height: 32rpx; + margin: 0 10rpx; + border: 1rpx solid #e3e3e3; + border-radius: 50%; +} .container > view:nth-child(3) > image { width: 32rpx; height: 32rpx; diff --git a/src/components/RingBarChart.vue b/src/components/RingBarChart.vue index deb9bf3..02919cc 100644 --- a/src/components/RingBarChart.vue +++ b/src/components/RingBarChart.vue @@ -43,11 +43,13 @@ const ringText = (ring) => { - {{ Number(b.rate.toFixed(1)) }}% + + {{ Number((b.rate * 100).toFixed(1)) }}% + diff --git a/src/pages/point-book-create.vue b/src/pages/point-book-create.vue index 8e0a573..ae37807 100644 --- a/src/pages/point-book-create.vue +++ b/src/pages/point-book-create.vue @@ -59,13 +59,13 @@ const toEditPage = () => { }); } }; -onShow(async () => { - const result = await getPointBookDataAPI(); - if (result) { - days.value = result.total_day || 0; - arrows.value = result.total_arrow || 0; - } -}); +// onShow(async () => { +// const result = await getPointBookDataAPI(); +// if (result) { +// days.value = result.total_day || 0; +// arrows.value = result.total_arrow || 0; +// } +// }); onMounted(async () => { const pointBook = uni.getStorageSync("point-book"); if (pointBook) { @@ -82,10 +82,10 @@ onMounted(async () => { :bgType="2" bgColor="#F5F5F5" :whiteBackArrow="false" - title="计分与技术分析" + title="选择参数" > - + { - 开始计分 + 下一步 历史计分记录 diff --git a/src/pages/point-book-detail.vue b/src/pages/point-book-detail.vue index 6b23d94..0564a9a 100644 --- a/src/pages/point-book-detail.vue +++ b/src/pages/point-book-detail.vue @@ -34,8 +34,10 @@ const onSelect = (index) => { }; const goBack = () => { + const pages = getCurrentPages(); + const currentPage = pages[pages.length - 2]; uni.navigateBack({ - delta: 2, + delta: currentPage.route === "pages/point-book" ? 1 : 2, }); }; diff --git a/src/pages/point-book.vue b/src/pages/point-book.vue index 0865481..745c875 100644 --- a/src/pages/point-book.vue +++ b/src/pages/point-book.vue @@ -37,6 +37,7 @@ const data = ref({ const list = ref([]); const bowTargetSrc = ref(""); +const heatMapImageSrc = ref(""); // 存储热力图图片地址 const toListPage = () => { uni.navigateTo({ @@ -71,8 +72,18 @@ const loadData = async () => { uni.$emit("update-hot", hot); const rect = await getElementRect(".heat-map"); // 延迟绘制热力图确保Canvas准备就绪 - setTimeout(() => { - drawHeatMap(rect.width, rect.height, result2.weekArrows); + setTimeout(async () => { + try { + const imagePath = await drawHeatMap( + rect.width, + rect.height, + result2.weekArrows + ); + heatMapImageSrc.value = imagePath; // 存储生成的图片地址 + console.log("热力图图片地址:", imagePath); + } catch (error) { + console.error("生成热力图图片失败:", error); + } }, 500); }; @@ -235,6 +246,7 @@ onShareTimeline(() => { :src="bowTargetSrc || '../static/bow-target.png'" mode="widthFix" /> + @@ -373,12 +385,15 @@ onShareTimeline(() => { .heat-map > image { width: 100%; + position: absolute; + top: 0; + left: 0; } .heat-map > canvas { position: absolute; top: 0; - left: 0; + left: -1000px; width: 100%; height: 100%; z-index: 2; diff --git a/src/util.js b/src/util.js index 7571d6d..58ec581 100644 --- a/src/util.js +++ b/src/util.js @@ -446,51 +446,74 @@ export const calcRing = (bowtargetId, x, y, diameter) => { return 0; }; -// 绘制热力图 +// 绘制热力图并生成图片 export const drawHeatMap = (width, height, arrows) => { - try { - const ctx = uni.createCanvasContext("heatMapCanvas"); + return new Promise((resolve, reject) => { + try { + const ctx = uni.createCanvasContext("heatMapCanvas"); - let minCount = 0; - let maxCount = 0; - // 计算最大和最小频次 - arrows.forEach((point) => { - if (point.count > maxCount) { - maxCount = point.count; - } - if (point.count < minCount) { - minCount = point.count; - } - }); - // 绘制热力点 - arrows.forEach((point) => { - if (point.x === 0 && point.y === 0) return; - // 数量越多,半径越小(反比关系) - const radius = 20; + // ctx.setFillStyle("rgba(255, 255, 255, 0.4)"); + // ctx.fillRect(0, 0, width, height); - // 根据频次设置同一种颜色的5个深浅度 - let color = "rgba(255, 232, 143, 0.2)"; - // if (point.count >= maxCount * 0.5) { - // color = "rgba(255, 232, 143, 0.7)"; // 最深 - 频次5次及以上 - // } else if (point.count >= maxCount * 0.4) { - // color = "rgba(255, 232, 143, 0.5)"; // 较深 - 频次4次 - // } else if (point.count >= maxCount * 0.3) { - // color = "rgba(255, 232, 143, 0.3)"; // 中等 - 频次3次 - // } else if (point.count >= maxCount * 0.2) { - // color = "rgba(255, 232, 143, 0.2)"; // 较浅 - 频次2次 - // } else { - // color = "rgba(255, 232, 143, 0.1)"; // 最浅 - 频次1次 - // } + let minCount = 0; + let maxCount = 0; + // 计算最大和最小频次 + arrows.forEach((point) => { + if (point.count > maxCount) { + maxCount = point.count; + } + if (point.count < minCount) { + minCount = point.count; + } + }); + // 绘制热力点 + arrows.forEach((point) => { + if (point.x === 0 && point.y === 0) return; + // 数量越多,半径越小(反比关系) + const radius = 20; - // 绘制圆形热力点 - ctx.setFillStyle(color); - ctx.beginPath(); - ctx.arc(point.x * width, point.y * height, radius, 0, 2 * Math.PI); - ctx.fill(); - }); + // 根据频次设置同一种颜色的5个深浅度 + let color = "rgba(71, 254, 102, 0.2)"; + // if (point.count >= maxCount * 0.5) { + // color = "rgba(255, 232, 143, 0.7)"; // 最深 - 频次5次及以上 + // } else if (point.count >= maxCount * 0.4) { + // color = "rgba(255, 232, 143, 0.5)"; // 较深 - 频次4次 + // } else if (point.count >= maxCount * 0.3) { + // color = "rgba(255, 232, 143, 0.3)"; // 中等 - 频次3次 + // } else if (point.count >= maxCount * 0.2) { + // color = "rgba(255, 232, 143, 0.2)"; // 较浅 - 频次2次 + // } else { + // color = "rgba(255, 232, 143, 0.1)"; // 最浅 - 频次1次 + // } - ctx.draw(); - } catch (error) { - console.error("绘制热力图失败:", error); - } + // 绘制圆形热力点 + ctx.setFillStyle(color); + ctx.beginPath(); + ctx.arc(point.x * width, point.y * height, radius, 0, 2 * Math.PI); + ctx.fill(); + }); + + ctx.draw(false, () => { + // Canvas绘制完成后生成图片 + uni.canvasToTempFilePath({ + canvasId: "heatMapCanvas", + width: width, + height: height, + destWidth: width * 2, // 提高图片质量 + destHeight: height * 2, + success: (res) => { + console.log("热力图图片生成成功:", res.tempFilePath); + resolve(res.tempFilePath); + }, + fail: (error) => { + console.error("热力图图片生成失败:", error); + reject(error); + }, + }); + }); + } catch (error) { + console.error("绘制热力图失败:", error); + reject(error); + } + }); };