代码优化
This commit is contained in:
@@ -46,7 +46,7 @@ onMounted(() => {
|
|||||||
<text>{{ data.createAt }}</text>
|
<text>{{ data.createAt }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view>
|
<view>
|
||||||
<text>黄心率:{{ Number(data.yellowRate.toFixed(2)) * 100 }}%</text>
|
<text>黄心率:{{ data.yellowRate * 100 }}%</text>
|
||||||
<text>10环数:{{ data.tenRings }}</text>
|
<text>10环数:{{ data.tenRings }}</text>
|
||||||
<text>平均:{{ data.averageRing }}</text>
|
<text>平均:{{ data.averageRing }}</text>
|
||||||
</view>
|
</view>
|
||||||
@@ -131,7 +131,7 @@ onMounted(() => {
|
|||||||
width: 60px;
|
width: 60px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
top: calc(50% - 11px);
|
top: calc(50% - 13px);
|
||||||
left: calc(50% - 30px);
|
left: calc(50% - 30px);
|
||||||
}
|
}
|
||||||
.arrow-amount > text:nth-child(2) {
|
.arrow-amount > text:nth-child(2) {
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ function getHeatColor(density) {
|
|||||||
const red = Math.round(50 * (intensity - 0.5) * 2);
|
const red = Math.round(50 * (intensity - 0.5) * 2);
|
||||||
const green = Math.round(180 + 75 * (1 - intensity));
|
const green = Math.round(180 + 75 * (1 - intensity));
|
||||||
const blue = Math.round(30 * (1 - intensity));
|
const blue = Math.round(30 * (1 - intensity));
|
||||||
return `rgba(${red}, ${green}, ${blue}, ${alpha * 0.7})`;
|
return `rgba(${red}, ${green}, ${blue}, ${alpha * 0.8})`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,8 +167,16 @@ const heatmapCache = new Map();
|
|||||||
* @returns {Promise} 绘制完成的Promise
|
* @returns {Promise} 绘制完成的Promise
|
||||||
*/
|
*/
|
||||||
export function drawKDEHeatmap(canvasId, width, height, points, options = {}) {
|
export function drawKDEHeatmap(canvasId, width, height, points, options = {}) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
|
// iOS兼容性:限制canvas尺寸,避免内存问题
|
||||||
|
const maxCanvasSize = 1500; // iOS设备最大建议尺寸
|
||||||
|
if (width > maxCanvasSize || height > maxCanvasSize) {
|
||||||
|
const scale = Math.min(maxCanvasSize / width, maxCanvasSize / height);
|
||||||
|
width = Math.floor(width * scale);
|
||||||
|
height = Math.floor(height * scale);
|
||||||
|
console.log(`iOS兼容性:限制canvas尺寸为 ${width}x${height}`);
|
||||||
|
}
|
||||||
const {
|
const {
|
||||||
bandwidth = 0.8,
|
bandwidth = 0.8,
|
||||||
gridSize = 100,
|
gridSize = 100,
|
||||||
@@ -177,18 +185,126 @@ export function drawKDEHeatmap(canvasId, width, height, points, options = {}) {
|
|||||||
pointColor = "rgba(255, 255, 255, 0.9)",
|
pointColor = "rgba(255, 255, 255, 0.9)",
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
// 创建绘图上下文
|
// 创建绘图上下文 - iOS兼容性检查
|
||||||
const ctx = uni.createCanvasContext(canvasId);
|
let ctx;
|
||||||
|
try {
|
||||||
|
ctx = uni.createCanvasContext(canvasId);
|
||||||
|
if (!ctx) {
|
||||||
|
throw new Error("无法创建canvas上下文");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("创建canvas上下文失败:", error);
|
||||||
|
reject(new Error("iOS兼容性:Canvas上下文创建失败"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 清空画布
|
// 清空画布
|
||||||
ctx.clearRect(0, 0, width, height);
|
ctx.clearRect(0, 0, width, height);
|
||||||
|
|
||||||
|
// iOS兼容性:设置全局合成操作,让颜色叠加更自然
|
||||||
|
try {
|
||||||
|
ctx.globalCompositeOperation = 'screen';
|
||||||
|
} catch (error) {
|
||||||
|
console.warn("设置全局合成操作失败,使用默认设置:", error);
|
||||||
|
}
|
||||||
|
|
||||||
// 如果没有数据,直接绘制
|
// 如果没有数据,直接绘制
|
||||||
if (!points || points.length === 0) {
|
if (!points || points.length === 0) {
|
||||||
ctx.draw(false, () => resolve());
|
ctx.draw(false, () => resolve());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 使用分片处理,避免长时间阻塞主线程
|
||||||
|
const processInChunks = (data, chunkSize = 1000) => {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
let index = 0;
|
||||||
|
let frameCount = 0;
|
||||||
|
|
||||||
|
const processChunk = () => {
|
||||||
|
// iOS兼容性:使用Date.now()作为performance.now的回退
|
||||||
|
const startTime = typeof performance !== 'undefined' && performance.now ? performance.now() : Date.now();
|
||||||
|
const endIndex = Math.min(index + chunkSize, data.length);
|
||||||
|
|
||||||
|
// 批量处理多个点,减少函数调用开销
|
||||||
|
ctx.save(); // 保存当前状态
|
||||||
|
|
||||||
|
for (let i = index; i < endIndex; i++) {
|
||||||
|
const point = data[i];
|
||||||
|
// 处理单个点的绘制逻辑
|
||||||
|
processPoint(point);
|
||||||
|
|
||||||
|
// 每处理50个点检查一次时间,避免超时
|
||||||
|
const currentTime = typeof performance !== 'undefined' && performance.now ? performance.now() : Date.now();
|
||||||
|
if (i % 50 === 0 && currentTime - startTime > 8) {
|
||||||
|
// 如果处理时间超过8ms,保存状态并中断
|
||||||
|
index = i + 1;
|
||||||
|
ctx.restore();
|
||||||
|
// iOS兼容性:更安全的requestAnimationFrame检测
|
||||||
|
if (typeof requestAnimationFrame === 'function') {
|
||||||
|
try {
|
||||||
|
requestAnimationFrame(processChunk);
|
||||||
|
} catch (e) {
|
||||||
|
// 如果requestAnimationFrame失败,使用setTimeout
|
||||||
|
setTimeout(processChunk, 2);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setTimeout(processChunk, 2); // 小延迟后继续
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.restore(); // 恢复状态
|
||||||
|
index = endIndex;
|
||||||
|
frameCount++;
|
||||||
|
|
||||||
|
if (index < data.length) {
|
||||||
|
// 动态调整延迟:如果处理时间超过16ms(一帧),使用更大延迟
|
||||||
|
const currentTime = typeof performance !== 'undefined' && performance.now ? performance.now() : Date.now();
|
||||||
|
const processingTime = currentTime - startTime;
|
||||||
|
const delay = processingTime > 16 ? 8 : 1; // 根据处理时间动态调整
|
||||||
|
|
||||||
|
// iOS兼容性:更安全的requestAnimationFrame检测
|
||||||
|
if (typeof requestAnimationFrame === 'function') {
|
||||||
|
try {
|
||||||
|
requestAnimationFrame(processChunk);
|
||||||
|
} catch (e) {
|
||||||
|
// 如果requestAnimationFrame失败,使用setTimeout
|
||||||
|
setTimeout(processChunk, delay);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setTimeout(processChunk, delay);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
processChunk();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理单个点的函数 - iOS兼容性优化
|
||||||
|
const processPoint = (point) => {
|
||||||
|
const [x, y, density] = point;
|
||||||
|
const normalizedX = (x - range[0]) / (range[1] - range[0]);
|
||||||
|
const normalizedY = (y - range[0]) / (range[1] - range[0]);
|
||||||
|
const canvasX = normalizedX * width;
|
||||||
|
const canvasY = normalizedY * height;
|
||||||
|
const color = getHeatColor(density);
|
||||||
|
|
||||||
|
// iOS兼容性:确保数值有效
|
||||||
|
if (isNaN(canvasX) || isNaN(canvasY) || !isFinite(canvasX) || !isFinite(canvasY)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.setFillStyle(color);
|
||||||
|
ctx.beginPath();
|
||||||
|
const radius = Math.max(1, Math.min(width / gridSize, height / gridSize) * 0.6); // 确保半径至少为1
|
||||||
|
ctx.arc(canvasX, canvasY, radius, 0, 2 * Math.PI);
|
||||||
|
ctx.fill();
|
||||||
|
};
|
||||||
|
|
||||||
// 生成缓存key(基于参数和数据点的哈希)
|
// 生成缓存key(基于参数和数据点的哈希)
|
||||||
const cacheKey = `${bandwidth}-${gridSize}-${range.join(',')}-${points.length}-${JSON.stringify(points.slice(0, 10))}`;
|
const cacheKey = `${bandwidth}-${gridSize}-${range.join(',')}-${points.length}-${JSON.stringify(points.slice(0, 10))}`;
|
||||||
|
|
||||||
@@ -197,29 +313,17 @@ export function drawKDEHeatmap(canvasId, width, height, points, options = {}) {
|
|||||||
console.log('使用缓存的热力图数据');
|
console.log('使用缓存的热力图数据');
|
||||||
const cachedDensityData = heatmapCache.get(cacheKey);
|
const cachedDensityData = heatmapCache.get(cacheKey);
|
||||||
|
|
||||||
// 直接使用缓存数据绘制
|
// 使用分片处理绘制缓存数据
|
||||||
const cellWidth = width / gridSize;
|
await processInChunks(cachedDensityData, 200); // 每批处理200个点,减少单次处理量
|
||||||
const cellHeight = height / gridSize;
|
|
||||||
const xRange = range[1] - range[0];
|
|
||||||
const yRange = range[1] - range[0];
|
|
||||||
|
|
||||||
cachedDensityData.forEach((point) => {
|
// 绘制原始数据点 - iOS兼容性优化
|
||||||
const [x, y, density] = point;
|
|
||||||
const normalizedX = (x - range[0]) / xRange;
|
|
||||||
const normalizedY = (y - range[0]) / yRange;
|
|
||||||
const canvasX = normalizedX * width;
|
|
||||||
const canvasY = normalizedY * height;
|
|
||||||
const color = getHeatColor(density);
|
|
||||||
|
|
||||||
ctx.setFillStyle(color);
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.arc(canvasX, canvasY, Math.min(cellWidth, cellHeight) * 0.6, 0, 2 * Math.PI);
|
|
||||||
ctx.fill();
|
|
||||||
});
|
|
||||||
|
|
||||||
// 绘制原始数据点
|
|
||||||
if (showPoints) {
|
if (showPoints) {
|
||||||
ctx.setFillStyle(pointColor);
|
ctx.setFillStyle(pointColor);
|
||||||
|
ctx.beginPath(); // 开始批量路径
|
||||||
|
const xRange = range[1] - range[0];
|
||||||
|
const yRange = range[1] - range[0];
|
||||||
|
let validPoints = 0;
|
||||||
|
|
||||||
points.forEach((point) => {
|
points.forEach((point) => {
|
||||||
const [x, y] = point;
|
const [x, y] = point;
|
||||||
const normalizedX = (x - range[0]) / xRange;
|
const normalizedX = (x - range[0]) / xRange;
|
||||||
@@ -227,15 +331,25 @@ export function drawKDEHeatmap(canvasId, width, height, points, options = {}) {
|
|||||||
const canvasX = normalizedX * width;
|
const canvasX = normalizedX * width;
|
||||||
const canvasY = normalizedY * height;
|
const canvasY = normalizedY * height;
|
||||||
|
|
||||||
ctx.beginPath();
|
// iOS兼容性:确保坐标有效
|
||||||
|
if (!isNaN(canvasX) && !isNaN(canvasY) && isFinite(canvasX) && isFinite(canvasY)) {
|
||||||
ctx.arc(canvasX, canvasY, 2.5, 0, 2 * Math.PI);
|
ctx.arc(canvasX, canvasY, 2.5, 0, 2 * Math.PI);
|
||||||
ctx.fill();
|
validPoints++;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 只有在有有效点的情况下才执行填充
|
||||||
|
if (validPoints > 0) {
|
||||||
|
ctx.fill(); // 一次性填充所有圆点
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.draw(false, () => {
|
ctx.draw(false, () => {
|
||||||
console.log("KDE热力图绘制完成(缓存)");
|
console.log("KDE热力图绘制完成(缓存)");
|
||||||
resolve();
|
resolve();
|
||||||
|
}, (error) => {
|
||||||
|
console.error("KDE热力图绘制失败(缓存):", error);
|
||||||
|
reject(new Error("Canvas绘制失败(缓存): " + error));
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -258,40 +372,15 @@ export function drawKDEHeatmap(canvasId, width, height, points, options = {}) {
|
|||||||
const xRange = range[1] - range[0];
|
const xRange = range[1] - range[0];
|
||||||
const yRange = range[1] - range[0];
|
const yRange = range[1] - range[0];
|
||||||
|
|
||||||
// 绘制热力图网格 - 批量绘制优化
|
// 使用分片处理绘制热力图网格
|
||||||
const colorGroups = new Map();
|
await processInChunks(densityData, 200); // 每批处理200个点,减少单次处理量
|
||||||
|
|
||||||
// 按颜色分组,减少setFillStyle调用
|
// 绘制原始数据点 - iOS兼容性优化
|
||||||
densityData.forEach((point) => {
|
|
||||||
const [x, y, density] = point;
|
|
||||||
const color = getHeatColor(density);
|
|
||||||
|
|
||||||
if (!colorGroups.has(color)) {
|
|
||||||
colorGroups.set(color, []);
|
|
||||||
}
|
|
||||||
colorGroups.get(color).push(point);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 批量绘制相同颜色的点
|
|
||||||
colorGroups.forEach((points, color) => {
|
|
||||||
ctx.setFillStyle(color);
|
|
||||||
points.forEach((point) => {
|
|
||||||
const [x, y, density] = point;
|
|
||||||
const normalizedX = (x - range[0]) / xRange;
|
|
||||||
const normalizedY = (y - range[0]) / yRange;
|
|
||||||
const canvasX = normalizedX * width;
|
|
||||||
const canvasY = normalizedY * height;
|
|
||||||
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.arc(canvasX, canvasY, Math.min(cellWidth, cellHeight) * 0.6, 0, 2 * Math.PI);
|
|
||||||
ctx.fill();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// 绘制原始数据点 - 批量绘制优化
|
|
||||||
if (showPoints) {
|
if (showPoints) {
|
||||||
ctx.setFillStyle(pointColor);
|
ctx.setFillStyle(pointColor);
|
||||||
ctx.beginPath(); // 开始批量路径
|
ctx.beginPath(); // 开始批量路径
|
||||||
|
let validPoints = 0;
|
||||||
|
|
||||||
points.forEach((point) => {
|
points.forEach((point) => {
|
||||||
const [x, y] = point;
|
const [x, y] = point;
|
||||||
const normalizedX = (x - range[0]) / xRange;
|
const normalizedX = (x - range[0]) / xRange;
|
||||||
@@ -299,15 +388,26 @@ export function drawKDEHeatmap(canvasId, width, height, points, options = {}) {
|
|||||||
const canvasX = normalizedX * width;
|
const canvasX = normalizedX * width;
|
||||||
const canvasY = normalizedY * height;
|
const canvasY = normalizedY * height;
|
||||||
|
|
||||||
|
// iOS兼容性:确保坐标有效
|
||||||
|
if (!isNaN(canvasX) && !isNaN(canvasY) && isFinite(canvasX) && isFinite(canvasY)) {
|
||||||
ctx.arc(canvasX, canvasY, 2.5, 0, 2 * Math.PI);
|
ctx.arc(canvasX, canvasY, 2.5, 0, 2 * Math.PI);
|
||||||
|
validPoints++;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 只有在有有效点的情况下才执行填充
|
||||||
|
if (validPoints > 0) {
|
||||||
ctx.fill(); // 一次性填充所有圆点
|
ctx.fill(); // 一次性填充所有圆点
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 执行绘制
|
// 执行绘制 - iOS兼容性优化
|
||||||
ctx.draw(false, () => {
|
ctx.draw(false, () => {
|
||||||
console.log("KDE热力图绘制完成");
|
console.log("KDE热力图绘制完成");
|
||||||
resolve();
|
resolve();
|
||||||
|
}, (error) => {
|
||||||
|
console.error("KDE热力图绘制失败:", error);
|
||||||
|
reject(new Error("Canvas绘制失败: " + error));
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("KDE热力图绘制失败:", error);
|
console.error("KDE热力图绘制失败:", error);
|
||||||
@@ -330,13 +430,15 @@ export function generateKDEHeatmapImage(
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
drawKDEHeatmap(canvasId, width, height, points, options)
|
drawKDEHeatmap(canvasId, width, height, points, options)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
// 生成图片
|
// 生成图片 - iOS兼容性优化
|
||||||
uni.canvasToTempFilePath({
|
uni.canvasToTempFilePath({
|
||||||
canvasId: canvasId,
|
canvasId: canvasId,
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
destWidth: width * 3, // 提高输出分辨率,让图像更细腻
|
destWidth: width * 2, // iOS兼容性:降低分辨率避免内存问题
|
||||||
destHeight: height * 3,
|
destHeight: height * 2,
|
||||||
|
fileType: "png", // iOS兼容性:明确指定png格式
|
||||||
|
quality: 1, // iOS兼容性:最高质量
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
console.log("KDE热力图图片生成成功:", res.tempFilePath);
|
console.log("KDE热力图图片生成成功:", res.tempFilePath);
|
||||||
resolve(res.tempFilePath);
|
resolve(res.tempFilePath);
|
||||||
|
|||||||
@@ -76,29 +76,56 @@ const loadData = async () => {
|
|||||||
else if (result2.checkInCount >= 5) hot = 3;
|
else if (result2.checkInCount >= 5) hot = 3;
|
||||||
else if (result2.checkInCount === 7) hot = 4;
|
else if (result2.checkInCount === 7) hot = 4;
|
||||||
uni.$emit("update-hot", hot);
|
uni.$emit("update-hot", hot);
|
||||||
setTimeout(async () => {
|
// 异步生成热力图,不阻塞UI
|
||||||
|
const generateHeatmapAsync = async () => {
|
||||||
|
const weekArrows = result2.weekArrows
|
||||||
|
.filter((item) => item.x && item.y)
|
||||||
|
.map((item) => [item.x, item.y]);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const imagePath = await generateKDEHeatmapImage(
|
// 渐进式渲染:数据量大时先快速渲染粗略版本
|
||||||
|
if (weekArrows.length > 1000) {
|
||||||
|
const quickPath = await generateKDEHeatmapImage(
|
||||||
"heatMapCanvas",
|
"heatMapCanvas",
|
||||||
rect.width,
|
rect.width,
|
||||||
rect.height,
|
rect.height,
|
||||||
result2.weekArrows
|
weekArrows,
|
||||||
.filter((item) => item.x && item.y)
|
|
||||||
.map((item) => [item.x, item.y]),
|
|
||||||
{
|
{
|
||||||
range: [0, 1], // 适配0-1坐标范围
|
range: [0, 1],
|
||||||
gridSize: 120, // 更高的网格密度,减少锯齿
|
gridSize: 80, // 先使用较小的gridSize快速显示
|
||||||
bandwidth: 0.15, // 稍小的带宽,让热力图更细腻
|
bandwidth: 0.2,
|
||||||
showPoints: false, // 显示白色原始数据点
|
showPoints: false,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
heatMapImageSrc.value = imagePath; // 存储生成的图片地址
|
heatMapImageSrc.value = quickPath;
|
||||||
|
// 延迟后再渲染精细版本
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 渲染最终精细版本
|
||||||
|
const finalPath = await generateKDEHeatmapImage(
|
||||||
|
"heatMapCanvas",
|
||||||
|
rect.width,
|
||||||
|
rect.height,
|
||||||
|
weekArrows,
|
||||||
|
{
|
||||||
|
range: [0, 1],
|
||||||
|
gridSize: 120, // 更高的网格密度,减少锯齿
|
||||||
|
bandwidth: 0.15, // 稍小的带宽,让热力图更细腻
|
||||||
|
showPoints: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
heatMapImageSrc.value = finalPath;
|
||||||
loadImage.value = false;
|
loadImage.value = false;
|
||||||
console.log("热力图图片地址:", imagePath);
|
console.log("热力图图片地址:", finalPath);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("生成热力图图片失败:", error);
|
console.error("生成热力图图片失败:", error);
|
||||||
|
loadImage.value = false;
|
||||||
}
|
}
|
||||||
}, 300);
|
};
|
||||||
|
|
||||||
|
// 异步生成热力图,不阻塞UI
|
||||||
|
generateHeatmapAsync();
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@@ -224,19 +251,19 @@ onShareTimeline(() => {
|
|||||||
<view class="statistics">
|
<view class="statistics">
|
||||||
<view>
|
<view>
|
||||||
<text>{{ data.todayTotalArrow || "-" }}</text>
|
<text>{{ data.todayTotalArrow || "-" }}</text>
|
||||||
<text>今日射箭(箭)</text>
|
<text>今日射箭(箭)</text>
|
||||||
</view>
|
</view>
|
||||||
<view>
|
<view>
|
||||||
<text>{{ data.totalArrow || "-" }}</text>
|
<text>{{ data.totalArrow || "-" }}</text>
|
||||||
<text>累计射箭(箭)</text>
|
<text>累计射箭(箭)</text>
|
||||||
</view>
|
</view>
|
||||||
<view>
|
<view>
|
||||||
<text>{{ data.totalDay || "-" }}</text>
|
<text>{{ data.totalDay || "-" }}</text>
|
||||||
<text>已训练天数(天)</text>
|
<text>已训练天数(天)</text>
|
||||||
</view>
|
</view>
|
||||||
<view>
|
<view>
|
||||||
<text>{{ data.averageRing || "-" }}</text>
|
<text>{{ data.averageRing || "-" }}</text>
|
||||||
<text>平均环数(箭)</text>
|
<text>平均环数(箭)</text>
|
||||||
</view>
|
</view>
|
||||||
<view>
|
<view>
|
||||||
<text>{{
|
<text>{{
|
||||||
@@ -244,7 +271,7 @@ onShareTimeline(() => {
|
|||||||
? Number(data.yellowRate * 100).toFixed(2)
|
? Number(data.yellowRate * 100).toFixed(2)
|
||||||
: "-"
|
: "-"
|
||||||
}}</text>
|
}}</text>
|
||||||
<text>黄心率(%)</text>
|
<text>黄心率(%)</text>
|
||||||
</view>
|
</view>
|
||||||
<view>
|
<view>
|
||||||
<button hover-class="none" @click="startScoring">
|
<button hover-class="none" @click="startScoring">
|
||||||
@@ -276,7 +303,7 @@ onShareTimeline(() => {
|
|||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
</view>
|
</view>
|
||||||
<view class="reward" v-if="data.totalArrow && !loadImage">
|
<view class="reward" v-if="data.totalArrow">
|
||||||
<button hover-class="none" @click="showTip = true">
|
<button hover-class="none" @click="showTip = true">
|
||||||
<image src="../static/reward-us.png" mode="widthFix" />
|
<image src="../static/reward-us.png" mode="widthFix" />
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
Reference in New Issue
Block a user