2025-09-24 21:05:06 +08:00
|
|
|
|
<script setup>
|
2025-09-25 17:07:37 +08:00
|
|
|
|
import { ref, computed, onMounted, onBeforeUnmount, watch } from "vue";
|
2025-09-24 21:05:06 +08:00
|
|
|
|
import { onShow, onShareAppMessage, onShareTimeline } from "@dcloudio/uni-app";
|
|
|
|
|
|
import Container from "@/components/Container.vue";
|
|
|
|
|
|
import PointRecord from "@/components/PointRecord.vue";
|
2025-09-25 10:16:23 +08:00
|
|
|
|
import RingBarChart from "@/components/RingBarChart.vue";
|
2025-09-24 21:05:06 +08:00
|
|
|
|
import SModal from "@/components/SModal.vue";
|
|
|
|
|
|
import Signin from "@/components/Signin.vue";
|
2025-09-25 15:18:24 +08:00
|
|
|
|
import ScreenHint2 from "@/components/ScreenHint2.vue";
|
|
|
|
|
|
import RewardUs from "@/components/RewardUs.vue";
|
2025-09-24 21:05:06 +08:00
|
|
|
|
|
|
|
|
|
|
import {
|
|
|
|
|
|
getHomeData,
|
|
|
|
|
|
getPointBookConfigAPI,
|
|
|
|
|
|
getPointBookListAPI,
|
|
|
|
|
|
getPointBookStatisticsAPI,
|
|
|
|
|
|
} from "@/apis";
|
|
|
|
|
|
|
2025-09-28 18:28:49 +08:00
|
|
|
|
import { getElementRect } from "@/util";
|
2025-09-29 11:05:42 +08:00
|
|
|
|
|
|
|
|
|
|
import { generateKDEHeatmapImage } from "@/kde-heatmap";
|
2025-09-25 11:53:47 +08:00
|
|
|
|
|
2025-09-24 21:05:06 +08:00
|
|
|
|
import useStore from "@/store";
|
|
|
|
|
|
import { storeToRefs } from "pinia";
|
|
|
|
|
|
const store = useStore();
|
|
|
|
|
|
const { updateUser } = store;
|
|
|
|
|
|
const { user } = storeToRefs(store);
|
|
|
|
|
|
|
|
|
|
|
|
const isIOS = computed(() => {
|
|
|
|
|
|
const systemInfo = uni.getDeviceInfo();
|
|
|
|
|
|
return systemInfo.osName === "ios";
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2025-09-30 10:53:06 +08:00
|
|
|
|
const loadImage = ref(true);
|
2025-09-24 21:05:06 +08:00
|
|
|
|
const showModal = ref(false);
|
2025-09-25 15:18:24 +08:00
|
|
|
|
const showTip = ref(false);
|
2025-09-24 21:05:06 +08:00
|
|
|
|
const data = ref({
|
|
|
|
|
|
weeksCheckIn: [],
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const list = ref([]);
|
2025-09-25 10:59:49 +08:00
|
|
|
|
const bowTargetSrc = ref("");
|
2025-09-27 10:09:02 +08:00
|
|
|
|
const heatMapImageSrc = ref(""); // 存储热力图图片地址
|
2025-09-28 18:28:49 +08:00
|
|
|
|
const canvasVisible = ref(false); // 控制canvas显示状态
|
2025-09-24 21:05:06 +08:00
|
|
|
|
|
|
|
|
|
|
const toListPage = () => {
|
|
|
|
|
|
uni.navigateTo({
|
|
|
|
|
|
url: "/pages/point-book-list",
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-09-25 17:07:37 +08:00
|
|
|
|
const onSignin = () => {
|
|
|
|
|
|
showModal.value = true;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const startScoring = () => {
|
|
|
|
|
|
if (user.value.id) {
|
|
|
|
|
|
uni.navigateTo({
|
|
|
|
|
|
url: "/pages/point-book-create",
|
|
|
|
|
|
});
|
|
|
|
|
|
} else {
|
|
|
|
|
|
showModal.value = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const loadData = async () => {
|
2025-09-24 21:05:06 +08:00
|
|
|
|
const result = await getPointBookListAPI(1);
|
2025-09-25 11:53:47 +08:00
|
|
|
|
list.value = result.slice(0, 3);
|
2025-09-24 21:05:06 +08:00
|
|
|
|
const result2 = await getPointBookStatisticsAPI();
|
2025-09-29 11:05:42 +08:00
|
|
|
|
data.value = result2;
|
2025-09-28 18:28:49 +08:00
|
|
|
|
|
|
|
|
|
|
const rect = await getElementRect(".heat-map");
|
2025-09-25 14:22:03 +08:00
|
|
|
|
let hot = 0;
|
|
|
|
|
|
if (result2.checkInCount > -3 && result2.checkInCount < 3) hot = 1;
|
|
|
|
|
|
else if (result2.checkInCount >= 3) hot = 2;
|
|
|
|
|
|
else if (result2.checkInCount >= 5) hot = 3;
|
|
|
|
|
|
else if (result2.checkInCount === 7) hot = 4;
|
|
|
|
|
|
uni.$emit("update-hot", hot);
|
2025-09-30 16:47:00 +08:00
|
|
|
|
// 异步生成热力图,不阻塞UI
|
|
|
|
|
|
const generateHeatmapAsync = async () => {
|
|
|
|
|
|
const weekArrows = result2.weekArrows
|
|
|
|
|
|
.filter((item) => item.x && item.y)
|
|
|
|
|
|
.map((item) => [item.x, item.y]);
|
|
|
|
|
|
|
2025-09-30 10:53:06 +08:00
|
|
|
|
try {
|
2025-09-30 16:47:00 +08:00
|
|
|
|
// 渐进式渲染:数据量大时先快速渲染粗略版本
|
|
|
|
|
|
if (weekArrows.length > 1000) {
|
|
|
|
|
|
const quickPath = await generateKDEHeatmapImage(
|
|
|
|
|
|
"heatMapCanvas",
|
|
|
|
|
|
rect.width,
|
|
|
|
|
|
rect.height,
|
|
|
|
|
|
weekArrows,
|
|
|
|
|
|
{
|
|
|
|
|
|
range: [0, 1],
|
|
|
|
|
|
gridSize: 80, // 先使用较小的gridSize快速显示
|
|
|
|
|
|
bandwidth: 0.2,
|
|
|
|
|
|
showPoints: false,
|
|
|
|
|
|
}
|
|
|
|
|
|
);
|
|
|
|
|
|
heatMapImageSrc.value = quickPath;
|
|
|
|
|
|
// 延迟后再渲染精细版本
|
|
|
|
|
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 渲染最终精细版本
|
|
|
|
|
|
const finalPath = await generateKDEHeatmapImage(
|
2025-09-30 10:53:06 +08:00
|
|
|
|
"heatMapCanvas",
|
|
|
|
|
|
rect.width,
|
|
|
|
|
|
rect.height,
|
2025-09-30 16:47:00 +08:00
|
|
|
|
weekArrows,
|
2025-09-30 10:53:06 +08:00
|
|
|
|
{
|
2025-09-30 16:47:00 +08:00
|
|
|
|
range: [0, 1],
|
2025-09-30 10:53:06 +08:00
|
|
|
|
gridSize: 120, // 更高的网格密度,减少锯齿
|
|
|
|
|
|
bandwidth: 0.15, // 稍小的带宽,让热力图更细腻
|
2025-09-30 16:47:00 +08:00
|
|
|
|
showPoints: false,
|
2025-09-30 10:53:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
);
|
2025-09-30 16:47:00 +08:00
|
|
|
|
heatMapImageSrc.value = finalPath;
|
2025-09-30 10:53:06 +08:00
|
|
|
|
loadImage.value = false;
|
2025-09-30 16:47:00 +08:00
|
|
|
|
console.log("热力图图片地址:", finalPath);
|
2025-09-30 10:53:06 +08:00
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("生成热力图图片失败:", error);
|
2025-09-30 16:47:00 +08:00
|
|
|
|
loadImage.value = false;
|
2025-09-30 10:53:06 +08:00
|
|
|
|
}
|
2025-09-30 16:47:00 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 异步生成热力图,不阻塞UI
|
|
|
|
|
|
generateHeatmapAsync();
|
2025-09-24 21:05:06 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
2025-09-25 17:07:37 +08:00
|
|
|
|
watch(
|
|
|
|
|
|
() => user.value.id,
|
|
|
|
|
|
(id) => {
|
|
|
|
|
|
if (id) loadData();
|
2025-09-24 21:05:06 +08:00
|
|
|
|
}
|
2025-09-25 17:07:37 +08:00
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
onShow(async () => {
|
|
|
|
|
|
if (user.value.id) loadData();
|
|
|
|
|
|
});
|
2025-09-24 21:05:06 +08:00
|
|
|
|
|
|
|
|
|
|
onMounted(async () => {
|
|
|
|
|
|
uni.$on("point-book-signin", onSignin);
|
|
|
|
|
|
const token = uni.getStorageSync(
|
|
|
|
|
|
`${uni.getAccountInfoSync().miniProgram.envVersion}_token`
|
|
|
|
|
|
);
|
|
|
|
|
|
if (!user.value.id && token) {
|
|
|
|
|
|
const data = await getHomeData();
|
|
|
|
|
|
if (data.user) updateUser(data.user);
|
|
|
|
|
|
}
|
|
|
|
|
|
const config = await getPointBookConfigAPI();
|
|
|
|
|
|
uni.setStorageSync("point-book-config", config);
|
2025-09-25 10:59:49 +08:00
|
|
|
|
if (config.targetOption && config.targetOption[0]) {
|
|
|
|
|
|
bowTargetSrc.value = config.targetOption[0].icon;
|
|
|
|
|
|
}
|
2025-09-24 21:05:06 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
onBeforeUnmount(() => {
|
|
|
|
|
|
uni.$off("point-book-signin", onSignin);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
onShareAppMessage(() => {
|
|
|
|
|
|
return {
|
|
|
|
|
|
title: "高效记录每一次射箭,深度分析助你提升!",
|
|
|
|
|
|
path: "pages/point-book-create",
|
|
|
|
|
|
imageUrl:
|
|
|
|
|
|
"https://static.shelingxingqiu.com/attachment/2025-09-22/dcz4m4nbgycqqwknrv.png",
|
|
|
|
|
|
};
|
|
|
|
|
|
});
|
|
|
|
|
|
onShareTimeline(() => {
|
|
|
|
|
|
return {
|
|
|
|
|
|
title: "高效记录每一次射箭,深度分析助你提升!",
|
|
|
|
|
|
query: "from=timeline",
|
|
|
|
|
|
imageUrl:
|
|
|
|
|
|
"https://static.shelingxingqiu.com/attachment/2025-09-22/dcz4m4nbgycqqwknrv.png",
|
|
|
|
|
|
};
|
|
|
|
|
|
});
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<template>
|
2025-09-25 10:16:23 +08:00
|
|
|
|
<Container :bgType="4" bgColor="#F5F5F5" :whiteBackArrow="false" title="">
|
2025-09-24 21:05:06 +08:00
|
|
|
|
<view class="container">
|
|
|
|
|
|
<view class="daily-signin">
|
|
|
|
|
|
<view>
|
2025-09-30 18:29:08 +08:00
|
|
|
|
<image src="../static/week-check.png" />
|
2025-09-24 21:05:06 +08:00
|
|
|
|
</view>
|
2025-09-30 10:53:06 +08:00
|
|
|
|
<view :class="data.weeksCheckIn[0] ? 'checked' : ''">
|
2025-09-24 21:05:06 +08:00
|
|
|
|
<image
|
|
|
|
|
|
v-if="data.weeksCheckIn[0]"
|
|
|
|
|
|
src="../static/checked-green2.png"
|
|
|
|
|
|
mode="widthFix"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<view v-else></view>
|
|
|
|
|
|
<text>周一</text>
|
|
|
|
|
|
</view>
|
2025-09-30 10:53:06 +08:00
|
|
|
|
<view :class="data.weeksCheckIn[1] ? 'checked' : ''">
|
2025-09-24 21:05:06 +08:00
|
|
|
|
<image
|
|
|
|
|
|
v-if="data.weeksCheckIn[1]"
|
|
|
|
|
|
src="../static/checked-green2.png"
|
|
|
|
|
|
mode="widthFix"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<view v-else></view>
|
|
|
|
|
|
<text>周二</text>
|
|
|
|
|
|
</view>
|
2025-09-30 10:53:06 +08:00
|
|
|
|
<view :class="data.weeksCheckIn[2] ? 'checked' : ''">
|
2025-09-24 21:05:06 +08:00
|
|
|
|
<image
|
|
|
|
|
|
v-if="data.weeksCheckIn[2]"
|
|
|
|
|
|
src="../static/checked-green2.png"
|
|
|
|
|
|
mode="widthFix"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<view v-else></view>
|
|
|
|
|
|
<text>周三</text>
|
|
|
|
|
|
</view>
|
2025-09-30 10:53:06 +08:00
|
|
|
|
<view :class="data.weeksCheckIn[3] ? 'checked' : ''">
|
2025-09-24 21:05:06 +08:00
|
|
|
|
<image
|
|
|
|
|
|
v-if="data.weeksCheckIn[3]"
|
|
|
|
|
|
src="../static/checked-green2.png"
|
|
|
|
|
|
mode="widthFix"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<view v-else></view>
|
|
|
|
|
|
<text>周四</text>
|
|
|
|
|
|
</view>
|
2025-09-30 10:53:06 +08:00
|
|
|
|
<view :class="data.weeksCheckIn[4] ? 'checked' : ''">
|
2025-09-24 21:05:06 +08:00
|
|
|
|
<image
|
|
|
|
|
|
v-if="data.weeksCheckIn[4]"
|
|
|
|
|
|
src="../static/checked-green2.png"
|
|
|
|
|
|
mode="widthFix"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<view v-else></view>
|
|
|
|
|
|
<text>周五</text>
|
|
|
|
|
|
</view>
|
2025-09-30 10:53:06 +08:00
|
|
|
|
<view :class="data.weeksCheckIn[5] ? 'checked' : ''">
|
2025-09-24 21:05:06 +08:00
|
|
|
|
<image
|
|
|
|
|
|
v-if="data.weeksCheckIn[5]"
|
|
|
|
|
|
src="../static/checked-green2.png"
|
|
|
|
|
|
mode="widthFix"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<view v-else></view>
|
|
|
|
|
|
<text>周六</text>
|
|
|
|
|
|
</view>
|
2025-09-30 10:53:06 +08:00
|
|
|
|
<view :class="data.weeksCheckIn[6] ? 'checked' : ''">
|
2025-09-24 21:05:06 +08:00
|
|
|
|
<image
|
|
|
|
|
|
v-if="data.weeksCheckIn[6]"
|
|
|
|
|
|
src="../static/checked-green2.png"
|
|
|
|
|
|
mode="widthFix"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<view v-else></view>
|
|
|
|
|
|
<text>周日</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="statistics">
|
|
|
|
|
|
<view>
|
2025-09-25 17:07:37 +08:00
|
|
|
|
<text>{{ data.todayTotalArrow || "-" }}</text>
|
2025-09-30 16:47:00 +08:00
|
|
|
|
<text>今日射箭(箭)</text>
|
2025-09-24 21:05:06 +08:00
|
|
|
|
</view>
|
|
|
|
|
|
<view>
|
2025-09-25 17:07:37 +08:00
|
|
|
|
<text>{{ data.totalArrow || "-" }}</text>
|
2025-09-30 16:47:00 +08:00
|
|
|
|
<text>累计射箭(箭)</text>
|
2025-09-24 21:05:06 +08:00
|
|
|
|
</view>
|
|
|
|
|
|
<view>
|
2025-09-25 17:07:37 +08:00
|
|
|
|
<text>{{ data.totalDay || "-" }}</text>
|
2025-09-30 16:47:00 +08:00
|
|
|
|
<text>已训练天数(天)</text>
|
2025-09-24 21:05:06 +08:00
|
|
|
|
</view>
|
|
|
|
|
|
<view>
|
2025-09-25 17:07:37 +08:00
|
|
|
|
<text>{{ data.averageRing || "-" }}</text>
|
2025-09-30 16:47:00 +08:00
|
|
|
|
<text>平均环数(箭)</text>
|
2025-09-24 21:05:06 +08:00
|
|
|
|
</view>
|
|
|
|
|
|
<view>
|
2025-09-25 17:07:37 +08:00
|
|
|
|
<text>{{
|
|
|
|
|
|
data.yellowRate !== undefined
|
|
|
|
|
|
? Number(data.yellowRate * 100).toFixed(2)
|
|
|
|
|
|
: "-"
|
|
|
|
|
|
}}</text>
|
2025-09-30 16:47:00 +08:00
|
|
|
|
<text>黄心率(%)</text>
|
2025-09-24 21:05:06 +08:00
|
|
|
|
</view>
|
|
|
|
|
|
<view>
|
|
|
|
|
|
<button hover-class="none" @click="startScoring">
|
|
|
|
|
|
<image src="../static/start-scoring.png" mode="widthFix" />
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="title">
|
|
|
|
|
|
<image src="../static/point-book-title1.png" mode="widthFix" />
|
|
|
|
|
|
</view>
|
2025-09-25 10:59:49 +08:00
|
|
|
|
<view class="heat-map">
|
|
|
|
|
|
<image
|
|
|
|
|
|
:src="bowTargetSrc || '../static/bow-target.png'"
|
|
|
|
|
|
mode="widthFix"
|
|
|
|
|
|
/>
|
2025-09-27 10:09:02 +08:00
|
|
|
|
<image v-if="heatMapImageSrc" :src="heatMapImageSrc" mode="widthFix" />
|
2025-09-30 10:53:06 +08:00
|
|
|
|
<view v-if="loadImage" class="load-image">
|
|
|
|
|
|
<text>生成中...</text>
|
|
|
|
|
|
</view>
|
2025-09-28 18:28:49 +08:00
|
|
|
|
<canvas
|
|
|
|
|
|
canvas-id="heatMapCanvas"
|
|
|
|
|
|
style="
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
position: absolute;
|
2025-09-29 11:14:49 +08:00
|
|
|
|
top: -1000px;
|
2025-09-28 18:28:49 +08:00
|
|
|
|
left: 0;
|
|
|
|
|
|
z-index: 2;
|
|
|
|
|
|
"
|
|
|
|
|
|
/>
|
2025-09-25 10:59:49 +08:00
|
|
|
|
</view>
|
2025-09-30 16:47:00 +08:00
|
|
|
|
<view class="reward" v-if="data.totalArrow">
|
2025-09-25 15:18:24 +08:00
|
|
|
|
<button hover-class="none" @click="showTip = true">
|
2025-09-25 14:22:03 +08:00
|
|
|
|
<image src="../static/reward-us.png" mode="widthFix" />
|
|
|
|
|
|
</button>
|
2025-09-25 15:18:24 +08:00
|
|
|
|
</view>
|
2025-09-25 10:16:23 +08:00
|
|
|
|
<RingBarChart :data="data.ringRate" />
|
2025-09-25 17:07:37 +08:00
|
|
|
|
<view class="title" v-if="user.id">
|
2025-09-24 21:05:06 +08:00
|
|
|
|
<image src="../static/point-book-title2.png" mode="widthFix" />
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<block v-for="(item, index) in list" :key="index">
|
|
|
|
|
|
<PointRecord :data="item" />
|
|
|
|
|
|
</block>
|
|
|
|
|
|
<view
|
|
|
|
|
|
class="see-more"
|
|
|
|
|
|
@click="toListPage"
|
|
|
|
|
|
v-if="list.length"
|
|
|
|
|
|
:style="{ marginBottom: isIOS ? '10rpx' : 0 }"
|
|
|
|
|
|
>
|
|
|
|
|
|
<text>查看所有记录</text>
|
|
|
|
|
|
<image src="../static/enter-arrow-blue.png" mode="widthFix" />
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<SModal :show="showModal" :onClose="() => (showModal = false)" :noBg="true">
|
|
|
|
|
|
<Signin :onClose="() => (showModal = false)" :noBg="true" />
|
|
|
|
|
|
</SModal>
|
2025-09-25 15:18:24 +08:00
|
|
|
|
<ScreenHint2 :show="showTip" :onClose="() => (showTip = false)">
|
2025-09-25 17:07:37 +08:00
|
|
|
|
<RewardUs :show="showTip" :onClose="() => (showTip = false)" />
|
2025-09-25 15:18:24 +08:00
|
|
|
|
</ScreenHint2>
|
2025-09-24 21:05:06 +08:00
|
|
|
|
</Container>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
|
.container {
|
|
|
|
|
|
width: calc(100% - 50rpx);
|
|
|
|
|
|
padding: 25rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.statistics {
|
|
|
|
|
|
border-radius: 25rpx;
|
|
|
|
|
|
border-bottom-left-radius: 50rpx;
|
|
|
|
|
|
border-bottom-right-radius: 50rpx;
|
2025-09-30 18:29:08 +08:00
|
|
|
|
border: 4rpx solid #fed848;
|
2025-09-24 21:05:06 +08:00
|
|
|
|
background: #fff;
|
|
|
|
|
|
font-size: 22rpx;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-wrap: wrap;
|
2025-09-25 14:22:03 +08:00
|
|
|
|
padding: 25rpx 0;
|
2025-09-25 10:59:49 +08:00
|
|
|
|
margin-bottom: 10rpx;
|
2025-09-24 21:05:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
.statistics > view {
|
|
|
|
|
|
width: 33.33%;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
.statistics > view:nth-child(-n + 3) {
|
|
|
|
|
|
margin-bottom: 25rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.statistics > view:nth-child(2),
|
|
|
|
|
|
.statistics > view:nth-child(5) {
|
|
|
|
|
|
border-left: 1rpx solid #eeeeee;
|
|
|
|
|
|
border-right: 1rpx solid #eeeeee;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
}
|
|
|
|
|
|
.statistics > view > text {
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
font-size: 22rpx;
|
|
|
|
|
|
color: #333333;
|
|
|
|
|
|
}
|
|
|
|
|
|
.statistics > view > text:first-child {
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
font-size: 40rpx;
|
|
|
|
|
|
margin-bottom: 10rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.statistics > view:last-child > button > image {
|
|
|
|
|
|
width: 164rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.daily-signin {
|
|
|
|
|
|
display: grid;
|
|
|
|
|
|
grid-template-columns: repeat(8, 1fr);
|
2025-09-30 18:29:08 +08:00
|
|
|
|
gap: 10rpx;
|
2025-09-24 21:05:06 +08:00
|
|
|
|
border-radius: 20rpx;
|
|
|
|
|
|
margin-bottom: 25rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.daily-signin > view {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
border-radius: 12rpx;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
}
|
|
|
|
|
|
.daily-signin > view:not(:first-child) {
|
|
|
|
|
|
background: #f8f8f8;
|
2025-09-30 10:53:06 +08:00
|
|
|
|
box-sizing: border-box;
|
2025-09-30 18:29:08 +08:00
|
|
|
|
width: 78rpx;
|
|
|
|
|
|
height: 94rpx;
|
|
|
|
|
|
padding-top: 10rpx;
|
2025-09-24 21:05:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
.daily-signin > view:not(:first-child) > image {
|
|
|
|
|
|
width: 32rpx;
|
|
|
|
|
|
height: 32rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.daily-signin > view:not(:first-child) > view {
|
|
|
|
|
|
width: 32rpx;
|
|
|
|
|
|
height: 32rpx;
|
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
|
box-sizing: border-box;
|
2025-09-30 18:29:08 +08:00
|
|
|
|
border: 2rpx solid #333;
|
2025-09-24 21:05:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
.daily-signin > view > text {
|
2025-09-30 18:29:08 +08:00
|
|
|
|
font-size: 20rpx;
|
2025-09-24 21:05:06 +08:00
|
|
|
|
color: #999999;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
text-align: center;
|
2025-09-30 18:29:08 +08:00
|
|
|
|
margin-top: 10rpx;
|
2025-09-24 21:05:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
.daily-signin > view:first-child > image {
|
2025-09-30 18:29:08 +08:00
|
|
|
|
width: 72rpx;
|
|
|
|
|
|
height: 94rpx;
|
2025-09-24 21:05:06 +08:00
|
|
|
|
}
|
2025-09-30 10:53:06 +08:00
|
|
|
|
.checked {
|
2025-09-30 18:29:08 +08:00
|
|
|
|
border: 2rpx solid #000;
|
2025-09-30 10:53:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
.checked > text {
|
|
|
|
|
|
color: #333 !important;
|
|
|
|
|
|
}
|
2025-09-24 21:05:06 +08:00
|
|
|
|
.title {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: center;
|
2025-09-25 10:59:49 +08:00
|
|
|
|
margin: 25rpx 0;
|
2025-09-24 21:05:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
.title > image {
|
|
|
|
|
|
width: 566rpx;
|
|
|
|
|
|
}
|
2025-09-25 10:59:49 +08:00
|
|
|
|
.heat-map {
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
margin: 10rpx;
|
|
|
|
|
|
width: calc(100vw - 70rpx);
|
|
|
|
|
|
height: calc(100vw - 70rpx);
|
|
|
|
|
|
}
|
|
|
|
|
|
.heat-map > image {
|
|
|
|
|
|
width: 100%;
|
2025-09-30 10:53:06 +08:00
|
|
|
|
height: 100%;
|
2025-09-27 10:09:02 +08:00
|
|
|
|
position: absolute;
|
|
|
|
|
|
top: 0;
|
|
|
|
|
|
left: 0;
|
2025-09-25 10:59:49 +08:00
|
|
|
|
}
|
2025-09-30 10:53:06 +08:00
|
|
|
|
.load-image {
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
width: 160rpx;
|
|
|
|
|
|
top: calc(50% - 65rpx);
|
|
|
|
|
|
left: calc(50% - 75rpx);
|
|
|
|
|
|
/* background: rgb(0 0 0 / 0.4); */
|
|
|
|
|
|
/* padding: 20rpx; */
|
|
|
|
|
|
color: #525252;
|
|
|
|
|
|
font-size: 20rpx;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
}
|
2025-09-25 14:22:03 +08:00
|
|
|
|
.reward {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: flex-end;
|
|
|
|
|
|
margin-top: -100rpx;
|
2025-09-25 15:18:24 +08:00
|
|
|
|
position: relative;
|
|
|
|
|
|
z-index: 10;
|
2025-09-25 14:22:03 +08:00
|
|
|
|
}
|
|
|
|
|
|
.reward > button {
|
|
|
|
|
|
width: 100rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.reward > button > image {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
}
|
2025-09-24 21:05:06 +08:00
|
|
|
|
</style>
|