Files
shoot-miniprograms/src/pages/point-book-detail.vue
2025-08-07 11:04:12 +08:00

249 lines
6.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup>
import { ref, onMounted, onUnmounted } from "vue";
import { onLoad } from "@dcloudio/uni-app";
import Container from "@/components/Container.vue";
import BowTargetEdit from "@/components/BowTargetEdit.vue";
import ScreenHint2 from "@/components/ScreenHint2.vue";
import SButton from "@/components/SButton.vue";
import { getPointBookDetailAPI } from "@/apis";
const selectedIndex = ref(0);
const showTip = ref(false);
const showTip2 = ref(false);
const groups = ref([]);
const data = ref({});
const targetSrc = ref("");
const arrows = ref([]);
const openTip = (index) => {
if (index === 1) showTip.value = true;
else if (index === 2) showTip2.value = true;
};
const closeTip = () => {
showTip.value = false;
showTip2.value = false;
};
const onSelect = (index) => {
selectedIndex.value = index;
data.value = groups.value[index];
arrows.value = groups.value[index].list.filter((item) => item.x && item.y);
};
const goBack = () => {
uni.navigateBack();
};
onLoad(async (options) => {
if (options.id) {
const result = await getPointBookDetailAPI(options.id);
const config = uni.getStorageSync("point-book-config");
config.targetOption.some((item) => {
if (item.id === result.targetType) {
targetSrc.value = item.icon;
}
});
if (result.groups) {
groups.value = result.groups;
data.value = result.groups[0];
arrows.value = result.groups[0].list.filter((item) => item.x && item.y);
}
}
});
</script>
<template>
<Container :bgType="2" bgColor="#F5F5F5" :whiteBackArrow="false" title="分析">
<view class="container">
<view class="tab-bar">
<view
v-for="(_, index) in groups"
:key="index"
@click="onSelect(index)"
:style="{ borderColor: selectedIndex === index ? '#FED847' : '#fff' }"
>
<text
:style="{
color: selectedIndex === index ? '#000' : '#333',
fontSize: selectedIndex === index ? '15px' : '13px',
letterSpacing: index !== 0 ? '2px' : '0',
}"
>{{ index === 0 ? "全部" : `${index}` }}</text
>
<!-- <image
src="../static/s-triangle.png"
mode="widthFix"
:style="{ bottom: selectedIndex !== index ? '0' : '-5px' }"
/> -->
</view>
</view>
<view class="detail-data">
<view>
<view
:style="{ display: 'flex', alignItems: 'center' }"
@click="() => openTip(1)"
>
<text>落点稳定性</text>
<image
src="../static/s-question-mark.png"
mode="widthFix"
class="question-mark"
/>
</view>
<text>{{ Number((data.stability || 0).toFixed(2)) }}</text>
</view>
<view>
<view>黄心率</view>
<text>{{ Number((data.yellowRate * 100).toFixed(2)) }}%</text>
</view>
<view>
<view>10环数</view>
<text>{{ data.tenRings }}</text>
</view>
<view>
<view>平均环数</view>
<text>{{ Number((data.averageRing || 0).toFixed(2)) }}</text>
</view>
<view>
<view>总环数</view>
<text>{{ data.userTotalRing }}/{{ data.totalRing }}</text>
</view>
</view>
<view class="title-bar">
<view />
<text>落点分布</text>
<button hover-class="none" @click="() => openTip(2)">
<image
src="../static/s-question-mark.png"
mode="widthFix"
class="question-mark"
/>
</button>
</view>
<BowTargetEdit :src="targetSrc" :arrows="arrows" />
<view :style="{ marginTop: '20px' }">
<SButton :onClick="goBack" :rounded="50">关闭</SButton>
</view>
<ScreenHint2 :show="showTip || showTip2" :onClose="closeTip">
<view class="tip-content">
<block v-if="showTip">
<text>落点稳定性说明</text>
<text
>通过计算每支箭与其他箭的平均距离衡一量射击的稳定性数字越小则说明射击越稳定该数据只能在用户标记落点的情况下生成</text
>
</block>
<block v-if="showTip2">
<text>落点分布说明</text>
<text>展示用户某次练习中射击的点位</text>
</block>
</view>
</ScreenHint2>
</view>
</Container>
</template>
<style scoped>
.container {
width: 100%;
}
.tab-bar {
display: flex;
width: clac(100% - 20px);
overflow-x: auto;
padding: 0 10px;
margin-top: 10px;
}
.tab-bar::-webkit-scrollbar {
width: 0;
height: 0;
color: transparent;
}
.tab-bar > view {
box-sizing: border-box;
border: 2px solid #fff;
border-radius: 10px;
background-color: #fff;
width: 24vw;
height: 13vw;
line-height: 13vw;
text-align: center;
margin: 5px;
margin-top: 0;
font-size: 14px;
flex: 0 0 auto;
position: relative;
}
.tab-bar > view > text {
transition: all 0.2s ease;
}
.tab-bar > view > image {
position: absolute;
width: 14px;
height: 4px;
left: calc(50% - 7px);
transition: all 0.3s ease;
}
.detail-data {
display: grid;
grid-template-columns: repeat(3, 1fr);
column-gap: 3vw;
margin: 10px 15px;
}
.detail-data > view {
border-radius: 10px;
background-color: #fff;
margin-bottom: 10px;
padding: 12px;
}
.detail-data > view > view {
font-size: 13px;
color: #999;
margin-bottom: 8px;
}
.detail-data > view > text {
font-weight: 500;
}
.question-mark {
width: 15px;
height: 15px;
margin-left: 3px;
}
.title-bar {
width: 100%;
display: flex;
align-items: center;
font-size: 13px;
color: #999;
}
.title-bar > view:first-child {
width: 5px;
height: 15px;
border-radius: 10px;
background-color: #fed847;
margin-right: 7px;
margin-left: 15px;
}
.title-bar > text {
margin-bottom: 2px;
}
.tip-content {
width: 100%;
padding: 25px;
display: flex;
flex-direction: column;
}
.tip-content > text {
width: 100%;
}
.tip-content > text:first-child {
text-align: center;
}
.tip-content > text:last-child {
font-size: 13px;
margin-top: 20px;
opacity: 0.8;
}
</style>