2025-07-29 10:46:37 +08:00
|
|
|
<script setup>
|
|
|
|
|
import { ref, onMounted, onUnmounted } from "vue";
|
|
|
|
|
const props = defineProps({
|
|
|
|
|
itemIndex: {
|
|
|
|
|
type: Number,
|
|
|
|
|
default: 0,
|
|
|
|
|
},
|
|
|
|
|
expand: {
|
|
|
|
|
type: Boolean,
|
|
|
|
|
default: false,
|
|
|
|
|
},
|
|
|
|
|
onExpand: {
|
|
|
|
|
type: Function,
|
2025-07-30 09:55:15 +08:00
|
|
|
default: () => {},
|
2025-07-29 10:46:37 +08:00
|
|
|
},
|
|
|
|
|
onSelect: {
|
|
|
|
|
type: Function,
|
|
|
|
|
default: () => {},
|
|
|
|
|
},
|
2025-07-30 09:55:15 +08:00
|
|
|
noArrow: {
|
|
|
|
|
type: Boolean,
|
|
|
|
|
default: false,
|
|
|
|
|
},
|
2025-07-29 10:46:37 +08:00
|
|
|
});
|
|
|
|
|
const bowTypes = [
|
|
|
|
|
{
|
|
|
|
|
name: "反曲弓",
|
|
|
|
|
image:
|
|
|
|
|
"https://api.shelingxingqiu.com/attachment/2025-07-28/dbnincayxdzicpeidq.png",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "复合弓",
|
|
|
|
|
image:
|
|
|
|
|
"https://api.shelingxingqiu.com/attachment/2025-07-28/dbnincawegb0dhs0sw.png",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "美洲猎弓",
|
|
|
|
|
image:
|
|
|
|
|
"https://api.shelingxingqiu.com/attachment/2025-07-28/dbnincaxxeqlufc3nl.png",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "传统弓",
|
|
|
|
|
image:
|
|
|
|
|
"https://api.shelingxingqiu.com/attachment/2025-07-28/dbnincastq3c3xkzdu.png",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "光弓",
|
|
|
|
|
image:
|
|
|
|
|
"https://api.shelingxingqiu.com/attachment/2025-07-28/dbnincaur573p7lxh7.png",
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
const itemTexts = ["选择弓种", "选择练习距离", "选择靶纸", "选择组/箭数"];
|
|
|
|
|
const distances = [5, 8, 10, 18, 25, 30, 50, 60, 70];
|
|
|
|
|
const bowtargetTypes = [
|
|
|
|
|
"40全环靶",
|
|
|
|
|
"80全环靶",
|
|
|
|
|
"122全环靶",
|
|
|
|
|
"40半环靶",
|
|
|
|
|
"60半环靶",
|
|
|
|
|
"80半环靶",
|
|
|
|
|
"三连靶",
|
|
|
|
|
"品字靶",
|
|
|
|
|
"复合三连靶",
|
|
|
|
|
"复合品字靶",
|
|
|
|
|
];
|
|
|
|
|
const groupArrows = [3, 6, 12, 18];
|
|
|
|
|
|
|
|
|
|
const selectedIndex = ref(-1);
|
|
|
|
|
const secondSelectIndex = ref(-1);
|
|
|
|
|
const onSelectItem = (index) => {
|
|
|
|
|
selectedIndex.value = index;
|
|
|
|
|
if (props.itemIndex === 0) {
|
|
|
|
|
props.onSelect(props.itemIndex, bowTypes[index].name);
|
|
|
|
|
} else if (props.itemIndex === 1) {
|
|
|
|
|
props.onSelect(props.itemIndex, distances[index]);
|
|
|
|
|
} else if (props.itemIndex === 2) {
|
|
|
|
|
props.onSelect(props.itemIndex, bowtargetTypes[index]);
|
|
|
|
|
} else if (props.itemIndex === 3 && secondSelectIndex.value !== -1) {
|
|
|
|
|
props.onSelect(
|
|
|
|
|
props.itemIndex,
|
|
|
|
|
`${selectedIndex.value + 1}组/${groupArrows[secondSelectIndex.value]}箭`
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
const onSelectSecondItem = (index) => {
|
|
|
|
|
secondSelectIndex.value = index;
|
|
|
|
|
if (selectedIndex.value !== -1) {
|
|
|
|
|
props.onSelect(
|
|
|
|
|
props.itemIndex,
|
|
|
|
|
`${selectedIndex.value + 1}组/${groupArrows[secondSelectIndex.value]}箭`
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
const meter = ref("");
|
|
|
|
|
const onMeterChange = (e) => {
|
|
|
|
|
meter.value = e.detail.value;
|
|
|
|
|
props.onSelect(props.itemIndex, e.detail.value);
|
|
|
|
|
};
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<template>
|
2025-07-30 09:55:15 +08:00
|
|
|
<view
|
|
|
|
|
class="container"
|
|
|
|
|
:style="{
|
|
|
|
|
maxHeight: expand ? '500px' : '50px',
|
|
|
|
|
marginTop: noArrow ? '0' : '10px',
|
|
|
|
|
}"
|
|
|
|
|
>
|
2025-07-29 10:46:37 +08:00
|
|
|
<view @click="() => onExpand(itemIndex, !expand)">
|
|
|
|
|
<text :style="{ opacity: expand ? 1 : 0 }">{{
|
|
|
|
|
itemIndex !== 3 ? itemTexts[itemIndex] : "选择组"
|
|
|
|
|
}}</text>
|
|
|
|
|
<block>
|
|
|
|
|
<text :style="{ opacity: expand ? 0 : 1 }" v-if="itemIndex === 0">{{
|
|
|
|
|
bowTypes[selectedIndex]
|
|
|
|
|
? bowTypes[selectedIndex].name
|
|
|
|
|
: itemTexts[itemIndex]
|
|
|
|
|
}}</text>
|
|
|
|
|
<text :style="{ opacity: expand ? 0 : 1 }" v-if="itemIndex === 1">{{
|
|
|
|
|
distances[selectedIndex]
|
|
|
|
|
? distances[selectedIndex] + " 米"
|
|
|
|
|
: selectedIndex === 9
|
|
|
|
|
? meter + " 米"
|
|
|
|
|
: itemTexts[itemIndex]
|
|
|
|
|
}}</text>
|
|
|
|
|
<text :style="{ opacity: expand ? 0 : 1 }" v-if="itemIndex === 2">{{
|
|
|
|
|
bowtargetTypes[selectedIndex]
|
|
|
|
|
? bowtargetTypes[selectedIndex]
|
|
|
|
|
: itemTexts[itemIndex]
|
|
|
|
|
}}</text>
|
|
|
|
|
<text :style="{ opacity: expand ? 0 : 1 }" v-if="itemIndex === 3">{{
|
|
|
|
|
selectedIndex !== -1 && secondSelectIndex !== -1
|
|
|
|
|
? `${selectedIndex + 1}组/${groupArrows[secondSelectIndex]}箭`
|
|
|
|
|
: itemTexts[itemIndex]
|
|
|
|
|
}}</text>
|
|
|
|
|
</block>
|
|
|
|
|
<button hover-class="none">
|
|
|
|
|
<image
|
2025-07-30 09:55:15 +08:00
|
|
|
v-if="!noArrow"
|
2025-07-29 10:46:37 +08:00
|
|
|
src="../static/arrow-grey.png"
|
|
|
|
|
mode="widthFix"
|
|
|
|
|
:style="{ transform: expand ? 'rotateX(180deg)' : 'rotateX(0deg)' }"
|
|
|
|
|
/>
|
|
|
|
|
</button>
|
|
|
|
|
</view>
|
|
|
|
|
<view v-if="itemIndex === 0" class="bow-items">
|
|
|
|
|
<view
|
|
|
|
|
v-for="(item, index) in bowTypes"
|
|
|
|
|
:key="index"
|
|
|
|
|
:style="{
|
|
|
|
|
borderColor: selectedIndex === index ? '#fed847' : '#eeeeee',
|
|
|
|
|
}"
|
|
|
|
|
@click="onSelectItem(index)"
|
|
|
|
|
>
|
|
|
|
|
<image :src="item.image" mode="widthFix" />
|
|
|
|
|
<text>{{ item.name }}</text>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
<view v-if="itemIndex === 1" class="distance-items">
|
|
|
|
|
<view
|
|
|
|
|
v-for="(item, index) in distances"
|
|
|
|
|
:key="index"
|
|
|
|
|
:style="{
|
|
|
|
|
borderColor: selectedIndex === index ? '#fed847' : '#eeeeee',
|
|
|
|
|
}"
|
|
|
|
|
@click="onSelectItem(index)"
|
|
|
|
|
>
|
|
|
|
|
<text>{{ item }}</text>
|
|
|
|
|
<text>米</text>
|
|
|
|
|
</view>
|
|
|
|
|
<view
|
|
|
|
|
:style="{
|
|
|
|
|
borderColor: selectedIndex === 9 ? '#fed847' : '#eeeeee',
|
|
|
|
|
}"
|
|
|
|
|
>
|
|
|
|
|
<input
|
|
|
|
|
placeholder="自定义"
|
|
|
|
|
placeholder-style="color: #DDDDDD"
|
|
|
|
|
@focus="() => (selectedIndex = 9)"
|
|
|
|
|
@change="onMeterChange"
|
|
|
|
|
/>
|
|
|
|
|
<text>米</text>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
<view v-if="itemIndex === 2" class="bowtarget-items">
|
|
|
|
|
<view
|
|
|
|
|
v-for="(item, index) in bowtargetTypes"
|
|
|
|
|
:key="index"
|
|
|
|
|
:style="{
|
|
|
|
|
borderColor: selectedIndex === index ? '#fed847' : '#eeeeee',
|
|
|
|
|
}"
|
|
|
|
|
@click="onSelectItem(index)"
|
|
|
|
|
>
|
|
|
|
|
<text>{{ item.substring(0, item.length - 3) }}</text>
|
|
|
|
|
<text>{{ item.substring(item.length - 3) }}</text>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
<view v-if="itemIndex === 3">
|
|
|
|
|
<view class="amount-items">
|
|
|
|
|
<view
|
|
|
|
|
v-for="i in 12"
|
|
|
|
|
:key="i"
|
|
|
|
|
:style="{
|
|
|
|
|
borderColor: selectedIndex === i ? '#fed847' : '#eeeeee',
|
|
|
|
|
}"
|
|
|
|
|
@click="onSelectItem(i)"
|
|
|
|
|
>
|
|
|
|
|
<text>{{ i }}</text>
|
|
|
|
|
<text>组</text>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
<view>选择每组的箭数</view>
|
|
|
|
|
<view class="amount-items">
|
|
|
|
|
<view
|
|
|
|
|
v-for="(item, index) in groupArrows"
|
|
|
|
|
:key="index"
|
|
|
|
|
:style="{
|
|
|
|
|
borderColor: secondSelectIndex === index ? '#fed847' : '#eeeeee',
|
|
|
|
|
}"
|
|
|
|
|
@click="onSelectSecondItem(index)"
|
|
|
|
|
>
|
|
|
|
|
<text>{{ item }}</text>
|
|
|
|
|
<text>箭</text>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</view>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
.container {
|
2025-07-30 09:55:15 +08:00
|
|
|
width: calc(100% - 20px);
|
2025-07-29 10:46:37 +08:00
|
|
|
background-color: #fff;
|
|
|
|
|
border-radius: 10px;
|
|
|
|
|
padding: 0 10px;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
transition: all 0.3s ease;
|
|
|
|
|
color: #333;
|
|
|
|
|
}
|
|
|
|
|
.container > view:first-child {
|
|
|
|
|
width: 100%;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
height: 50px;
|
|
|
|
|
}
|
|
|
|
|
.container > view:first-child > text:first-child {
|
|
|
|
|
width: 85px;
|
|
|
|
|
color: #999999;
|
|
|
|
|
}
|
|
|
|
|
.container > view:first-child > button {
|
|
|
|
|
width: 85px;
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: flex-end;
|
|
|
|
|
}
|
|
|
|
|
.container > view:first-child > button > image {
|
|
|
|
|
transition: all 0.5s ease;
|
|
|
|
|
width: 20px;
|
|
|
|
|
height: 20px;
|
|
|
|
|
}
|
|
|
|
|
.bow-items {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: repeat(3, 1fr);
|
|
|
|
|
column-gap: 2vw;
|
|
|
|
|
}
|
|
|
|
|
.bow-items > view {
|
|
|
|
|
width: 27vw;
|
|
|
|
|
height: 27vw;
|
|
|
|
|
border-radius: 10px;
|
|
|
|
|
border: 2px solid #eeeeee;
|
|
|
|
|
margin-bottom: 2vw;
|
|
|
|
|
}
|
|
|
|
|
.bow-items > view > image {
|
|
|
|
|
width: 100%;
|
|
|
|
|
}
|
|
|
|
|
.bow-items > view > text {
|
|
|
|
|
width: 100%;
|
|
|
|
|
display: block;
|
|
|
|
|
text-align: center;
|
|
|
|
|
transform: translateY(-30px);
|
|
|
|
|
}
|
|
|
|
|
.distance-items,
|
|
|
|
|
.bowtarget-items,
|
|
|
|
|
.amount-items {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: repeat(4, 1fr);
|
|
|
|
|
column-gap: 2vw;
|
|
|
|
|
position: relative;
|
|
|
|
|
}
|
|
|
|
|
.distance-items > view,
|
|
|
|
|
.bowtarget-items > view,
|
|
|
|
|
.amount-items > view {
|
|
|
|
|
width: 20vw;
|
|
|
|
|
height: 14vw;
|
|
|
|
|
border-radius: 10px;
|
|
|
|
|
border: 2px solid #eeeeee;
|
|
|
|
|
margin-bottom: 2vw;
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
align-items: center;
|
|
|
|
|
}
|
|
|
|
|
.distance-items > view > text:first-child,
|
|
|
|
|
.amount-items > view > text:first-child {
|
|
|
|
|
width: 25px;
|
|
|
|
|
display: block;
|
|
|
|
|
text-align: center;
|
|
|
|
|
}
|
|
|
|
|
.distance-items > view:last-child {
|
|
|
|
|
width: 65.5vw;
|
|
|
|
|
position: absolute;
|
|
|
|
|
bottom: 0;
|
|
|
|
|
right: 0;
|
|
|
|
|
}
|
|
|
|
|
.distance-items > view:last-child > input {
|
|
|
|
|
width: 80%;
|
|
|
|
|
text-align: center;
|
|
|
|
|
}
|
|
|
|
|
.bowtarget-items > view {
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
height: 16vw;
|
|
|
|
|
}
|
|
|
|
|
.bowtarget-items > view > text {
|
|
|
|
|
width: 100%;
|
|
|
|
|
text-align: center;
|
|
|
|
|
}
|
|
|
|
|
</style>
|