Files
shoot-miniprograms/src/components/EditOption.vue
2025-08-06 18:36:30 +08:00

340 lines
8.4 KiB
Vue

<script setup>
import { ref, watch, onMounted, onUnmounted } from "vue";
import { getPointBookConfigAPI } from "@/apis";
const props = defineProps({
itemIndex: {
type: Number,
default: 0,
},
expand: {
type: Boolean,
default: false,
},
onExpand: {
type: Function,
default: () => {},
},
onSelect: {
type: Function,
default: () => {},
},
noArrow: {
type: Boolean,
default: false,
},
value: {
type: String,
default: "",
},
});
const itemTexts = ["选择弓种", "选择练习距离", "选择靶纸", "选择组/箭数"];
const distances = [5, 8, 10, 18, 25, 30, 50, 60, 70];
const groupArrows = [3, 6, 12, 18];
const data = ref([]);
const selectedIndex = ref(-1);
const secondSelectIndex = ref(-1);
const onSelectItem = (index) => {
selectedIndex.value = index;
if (props.itemIndex === 0) {
props.onSelect(props.itemIndex, data.value[index]);
} else if (props.itemIndex === 1) {
props.onSelect(props.itemIndex, distances[index]);
} else if (props.itemIndex === 2) {
props.onSelect(props.itemIndex, data.value[index]);
} else if (props.itemIndex === 3 && secondSelectIndex.value !== -1) {
props.onSelect(
props.itemIndex,
`${selectedIndex.value}/${groupArrows[secondSelectIndex.value]}`
);
}
};
const onSelectSecondItem = (index) => {
secondSelectIndex.value = index;
if (selectedIndex.value !== -1) {
props.onSelect(
props.itemIndex,
`${selectedIndex.value}/${groupArrows[secondSelectIndex.value]}`
);
}
};
const meter = ref("");
const onMeterChange = (e) => {
meter.value = e.detail.value;
props.onSelect(props.itemIndex, e.detail.value);
};
watch(
() => props.value,
(newValue) => {
if (!newValue) {
selectedIndex.value = -1;
return;
}
if (props.itemIndex === 0 || props.itemIndex === 2) {
data.value.forEach((item, index) => {
if (item.name === newValue) {
selectedIndex.value = index;
}
});
}
if (props.itemIndex === 1) {
distances.forEach((item, index) => {
if (item == newValue) {
selectedIndex.value = index;
}
if (selectedIndex.value === -1) {
meter.value = newValue;
}
});
}
}
);
const loadConfig = () => {
const config = uni.getStorageSync("point-book-config");
if (config) {
if (props.itemIndex === 0) {
data.value = config.bowOption;
} else if (props.itemIndex === 2) {
data.value = config.targetOption;
}
}
};
onMounted(async () => {
const config = uni.getStorageSync("point-book-config");
if (config) {
loadConfig();
} else {
const config = await getPointBookConfigAPI();
uni.setStorageSync("point-book-config", config);
loadConfig();
}
});
</script>
<template>
<view
class="container"
:style="{
maxHeight: expand ? '500px' : '50px',
marginTop: noArrow ? '0' : '10px',
}"
>
<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">{{
value || itemTexts[itemIndex]
}}</text>
<text :style="{ opacity: expand ? 0 : 1 }" v-if="itemIndex === 1">{{
value && value > 0 ? value + "米" : itemTexts[itemIndex]
}}</text>
<text :style="{ opacity: expand ? 0 : 1 }" v-if="itemIndex === 2">{{
value || 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
v-if="!noArrow"
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 data"
:key="index"
:style="{
borderColor: selectedIndex === index ? '#fed847' : '#eeeeee',
}"
@click="onSelectItem(index)"
>
<image :src="item.icon" 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
v-model="meter"
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 data"
:key="index"
:style="{
borderColor: selectedIndex === index ? '#fed847' : '#eeeeee',
}"
@click="onSelectItem(index)"
>
<text>{{ item.name.substring(0, item.name.length - 3) }}</text>
<text>{{ item.name.substring(item.name.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
:style="{ marginTop: '5px', marginBottom: '10px', color: '#999999' }"
>选择每组的箭数</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 {
width: calc(100% - 20px);
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 > text:nth-child(2) {
font-weight: 500;
}
.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: 12vw;
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>