164 lines
4.1 KiB
Vue
164 lines
4.1 KiB
Vue
<script setup>
|
||
import { computed, ref } from "vue";
|
||
import { onLoad } from "@dcloudio/uni-app";
|
||
import Container from "@/components/Container.vue";
|
||
import Avatar from "@/components/Avatar.vue";
|
||
import BowTarget from "@/components/BowTarget.vue";
|
||
import ScorePanel2 from "@/components/TrainingScorePanel.vue";
|
||
import { getPractiseDetailAPI } from "@/apis";
|
||
import useStore from "@/store";
|
||
import { storeToRefs } from "pinia";
|
||
const store = useStore();
|
||
const { user } = storeToRefs(store);
|
||
const arrows = ref([]);
|
||
const isSvip = ref(false);
|
||
const practiseDetail = ref({});
|
||
|
||
const trainingType = computed(() =>
|
||
String(practiseDetail.value.trainingType || "").trim().toLowerCase()
|
||
);
|
||
const targetTypeText = computed(() => {
|
||
const targetType = Number(practiseDetail.value.targetType);
|
||
return targetType > 0 ? `${targetType}CM靶` : "";
|
||
});
|
||
const difficultyText = computed(() => {
|
||
const difficultyLevel = Number(practiseDetail.value.difficultyLevel);
|
||
return Number.isInteger(difficultyLevel) && difficultyLevel > 0
|
||
? `LV${difficultyLevel}`
|
||
: "";
|
||
});
|
||
const totalRings = computed(() => {
|
||
const interpretationTotal = Number(
|
||
practiseDetail.value.interpretation?.totalRings
|
||
);
|
||
if (Number.isFinite(interpretationTotal)) return interpretationTotal;
|
||
return arrows.value.reduce(
|
||
(total, arrow) => total + (Number(arrow.ring) || 0),
|
||
0
|
||
);
|
||
});
|
||
|
||
const normalizeArrow = (arrow = {}) => ({
|
||
...arrow,
|
||
ring: Number(arrow.ring) || 0,
|
||
ringX:
|
||
arrow.ringX === true ||
|
||
Number(arrow.ringX) === 1 ||
|
||
Number(arrow.ifX) === 1,
|
||
ok: arrow.ok === true || Number(arrow.ok) === 1,
|
||
});
|
||
|
||
onLoad(async (options) => {
|
||
if (!options.id) return;
|
||
const result = (await getPractiseDetailAPI(options.id)) || {};
|
||
practiseDetail.value = result;
|
||
arrows.value = Array.isArray(result.details)
|
||
? result.details.map(normalizeArrow)
|
||
: [];
|
||
isSvip.value = result.sVip === true || user.value?.sVip === true;
|
||
});
|
||
</script>
|
||
|
||
<template>
|
||
<Container title="靶纸">
|
||
<view class="container">
|
||
<!-- <view class="header">
|
||
<view>
|
||
<Avatar :src="user.avatar" frame />
|
||
<view>
|
||
<text>{{ user.nickName }}</text>
|
||
<text>{{ user.lvlName }}</text>
|
||
</view>
|
||
</view>
|
||
</view> -->
|
||
<view v-if="practiseDetail.id" class="practice-meta">
|
||
<text v-if="targetTypeText">{{ targetTypeText }}</text>
|
||
<text>{{ practiseDetail.trainingTypeText }}</text>
|
||
<text v-if="difficultyText">{{ difficultyText }}</text>
|
||
</view>
|
||
<view :style="{ marginBottom: '20px' }">
|
||
<BowTarget
|
||
:scores="arrows"
|
||
:isSvip="isSvip"
|
||
:enableShotEffect="false"
|
||
/>
|
||
</view>
|
||
<view class="desc">
|
||
<text>{{ arrows.length }}</text>
|
||
<text>支箭,共</text>
|
||
<text>{{ totalRings }}</text>
|
||
<text>环</text>
|
||
</view>
|
||
<ScorePanel2
|
||
:arrows="arrows"
|
||
:total="arrows.length"
|
||
:trainingType="trainingType"
|
||
recordMode
|
||
/>
|
||
</view>
|
||
</Container>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.container {
|
||
width: 100%;
|
||
flex-direction: column;
|
||
justify-content: center;
|
||
align-items: center;
|
||
}
|
||
.practice-meta {
|
||
width: 100%;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
color: #fff;
|
||
font-size: 26rpx;
|
||
font-weight: 600;
|
||
line-height: 40rpx;
|
||
padding: 16rpx 0;
|
||
}
|
||
.practice-meta > text + text {
|
||
margin-left: 24rpx;
|
||
}
|
||
.header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
width: calc(100% - 20px);
|
||
padding: 10px;
|
||
}
|
||
.header > view:first-child {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-left: 10px;
|
||
}
|
||
.header > view:first-child > view:last-child {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: flex-start;
|
||
margin-left: 10px;
|
||
color: #fff;
|
||
}
|
||
.header > view:first-child > view:last-child > text:last-child {
|
||
font-size: 10px;
|
||
color: #fff9;
|
||
background-color: #5f51ff;
|
||
padding: 2px 5px;
|
||
border-radius: 10px;
|
||
margin-top: 5px;
|
||
}
|
||
.header > view:last-child > image {
|
||
width: 40px;
|
||
}
|
||
.desc {
|
||
color: #fff;
|
||
margin-bottom: 40px;
|
||
width: 100%;
|
||
text-align: center;
|
||
}
|
||
.desc > text:nth-child(1),
|
||
.desc > text:nth-child(3) {
|
||
color: #fed847;
|
||
}
|
||
</style>
|