添加创建积分本页面

This commit is contained in:
kron
2025-07-29 10:46:37 +08:00
parent 9d6bcde9ba
commit e073f3eb0f
17 changed files with 515 additions and 10 deletions

View File

@@ -203,4 +203,19 @@ button::after {
margin-top: 20px; margin-top: 20px;
color: #fff9; color: #fff9;
} }
.see-more {
display: flex;
align-items: center;
justify-content: center;
margin-top: 5px;
}
.see-more > text {
color: #39a8ff;
margin-top: 2px;
font-size: 13px;
}
.see-more > image {
width: 15px;
margin-top: 2px;
}
</style> </style>

View File

@@ -5,11 +5,15 @@ const props = defineProps({
type: Number, type: Number,
default: 0, default: 0,
}, },
bgColor: {
type: String,
default: "#050b19",
},
}); });
</script> </script>
<template> <template>
<view class="background"> <view class="background" :style="{ backgroundColor: bgColor }">
<image <image
class="bg-image" class="bg-image"
v-if="type === 0" v-if="type === 0"
@@ -22,6 +26,12 @@ const props = defineProps({
src="../static/app-bg2.png" src="../static/app-bg2.png"
mode="widthFix" mode="widthFix"
/> />
<image
class="bg-image"
v-if="type === 2"
src="../static/app-bg3.png"
mode="widthFix"
/>
<view class="bg-overlay" v-if="type === 0"></view> <view class="bg-overlay" v-if="type === 0"></view>
</view> </view>
</template> </template>
@@ -34,7 +44,6 @@ const props = defineProps({
left: 0; left: 0;
top: 0; top: 0;
z-index: -1; z-index: -1;
background-color: #050b19;
} }
.bg-image { .bg-image {

View File

@@ -32,6 +32,14 @@ defineProps({
type: Boolean, type: Boolean,
default: false, default: false,
}, },
bgColor: {
type: String,
default: "#050b19",
},
whiteBackArrow: {
type: Boolean,
default: true,
},
}); });
const isIos = ref(true); const isIos = ref(true);
const showHint = ref(false); const showHint = ref(false);
@@ -67,8 +75,13 @@ const goBack = () => {
<template> <template>
<view> <view>
<AppBackground :type="bgType" /> <AppBackground :type="bgType" :bgColor="bgColor" />
<Header v-if="!isHome" :title="title" :onBack="onBack" /> <Header
v-if="!isHome"
:title="title"
:onBack="onBack"
:whiteBackArrow="whiteBackArrow"
/>
<BackToGame v-if="showBackToGame" /> <BackToGame v-if="showBackToGame" />
<view <view
class="content" class="content"

View File

@@ -0,0 +1,317 @@
<script setup>
import { ref, onMounted, onUnmounted } from "vue";
const props = defineProps({
itemIndex: {
type: Number,
default: 0,
},
expand: {
type: Boolean,
default: false,
},
onExpand: {
type: Function,
default: null,
},
onSelect: {
type: Function,
default: () => {},
},
});
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>
<view class="container" :style="{ maxHeight: expand ? '500px' : '50px' }">
<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
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 {
width: calc(100vw - 40px);
background-color: #fff;
margin-top: 10px;
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>

View File

@@ -11,6 +11,10 @@ const props = defineProps({
type: Function, type: Function,
default: null, default: null,
}, },
whiteBackArrow: {
type: Boolean,
default: true,
},
}); });
const onClick = () => { const onClick = () => {
@@ -46,9 +50,14 @@ onUnmounted(() => {
<template> <template>
<view class="container" :style="{ paddingTop: isIos ? '80rpx' : '50rpx' }"> <view class="container" :style="{ paddingTop: isIos ? '80rpx' : '50rpx' }">
<view class="back-btn" @click="onClick"> <view class="back-btn" @click="onClick">
<image src="../static/back.png" mode="widthFix" /> <image v-if="whiteBackArrow" src="../static/back.png" mode="widthFix" />
<image
v-if="!whiteBackArrow"
src="../static/back-black.png"
mode="widthFix"
/>
</view> </view>
<view> <view :style="{ color: whiteBackArrow ? '#fff' : '#000' }">
<block <block
v-if=" v-if="
'-凹造型-感知距离-小试牛刀'.indexOf(title) === -1 || '-凹造型-感知距离-小试牛刀'.indexOf(title) === -1 ||
@@ -95,7 +104,6 @@ onUnmounted(() => {
height: 100rpx; height: 100rpx;
/* margin-top: var(--status-bar-height); */ /* margin-top: var(--status-bar-height); */
padding-left: 15px; padding-left: 15px;
color: #fff;
font-size: 16px; font-size: 16px;
font-weight: bold; font-weight: bold;
} }
@@ -104,8 +112,8 @@ onUnmounted(() => {
align-items: center; align-items: center;
} }
.back-btn > image { .back-btn > image {
width: 18px; width: 22px;
height: 18px; height: 22px;
margin-right: 10px; margin-right: 10px;
} }
.first-try-steps { .first-try-steps {

View File

@@ -26,6 +26,10 @@ const props = defineProps({
type: String, type: String,
default: "#000", default: "#000",
}, },
disabledColor:{
type: String,
default: "#757575",
}
}); });
const loading = ref(false); const loading = ref(false);
@@ -55,7 +59,7 @@ const onBtnClick = debounce(async () => {
:style="{ :style="{
width: width, width: width,
borderRadius: rounded + 'px', borderRadius: rounded + 'px',
backgroundColor: disabled ? '#757575' : backgroundColor, backgroundColor: disabled ? disabledColor : backgroundColor,
color, color,
}" }"
open-type="getUserInfo" open-type="getUserInfo"

View File

@@ -1,8 +1,17 @@
{ {
"pages": [ "pages": [
{
"path": "pages/point-book-create"
},
{ {
"path": "pages/index" "path": "pages/index"
}, },
{
"path": "pages/point-book-list"
},
{
"path": "pages/point-book-detail"
},
{ {
"path": "pages/match-page" "path": "pages/match-page"
}, },

View File

@@ -0,0 +1,105 @@
<script setup>
import { ref, onMounted, onUnmounted } from "vue";
import Container from "@/components/Container.vue";
import EditOption from "@/components/EditOption.vue";
import SButton from "@/components/SButton.vue";
const clickable = ref(false);
const expandIndex = ref(-1);
const bowType = ref("");
const distance = ref(0);
const bowtargetType = ref("");
const amountGroup = ref("");
const onExpandChange = (index, expand) => {
expandIndex.value = !expand ? -1 : index;
};
const onClick = () => {};
const toListPage = () => {
uni.navigateTo({
url: "/pages/point-book-list",
});
};
const onSelect = (itemIndex, value) => {
if (itemIndex === 0) bowType.value = value;
else if (itemIndex === 1) distance.value = value;
else if (itemIndex === 2) bowtargetType.value = value;
else if (itemIndex === 3) amountGroup.value = value;
if (
bowType.value &&
distance.value &&
bowtargetType.value &&
amountGroup.value
) {
clickable.value = true;
}
};
</script>
<template>
<Container
:bgType="2"
bgColor="#F5F5F5"
:whiteBackArrow="false"
title="计分本"
>
<view class="container">
<image src="../static/point-book-banner.png" mode="widthFix" />
<EditOption
:itemIndex="0"
:expand="expandIndex === 0"
:onExpand="onExpandChange"
:onSelect="onSelect"
/>
<EditOption
:itemIndex="1"
:expand="expandIndex === 1"
:onExpand="onExpandChange"
:onSelect="onSelect"
/>
<EditOption
:itemIndex="2"
:expand="expandIndex === 2"
:onExpand="onExpandChange"
:onSelect="onSelect"
/>
<EditOption
:itemIndex="3"
:expand="expandIndex === 3"
:onExpand="onExpandChange"
:onSelect="onSelect"
/>
</view>
<view :style="{ marginBottom: '20px' }">
<SButton
:disabled="!clickable"
:onClick="onClick"
disabledColor="#DDDDDD"
:color="clickable ? '#000' : '#fff'"
>
开始计分
</SButton>
<view class="see-more" @click="toListPage">
<text>历史计分记录</text>
<image src="../static/enter-arrow-blue.png" mode="widthFix" />
</view>
</view>
</Container>
</template>
<style scoped>
.container {
width: calc(100% - 20px);
padding: 0 15px;
display: flex;
flex-direction: column;
align-items: center;
}
.container > image {
width: 100%;
border: 2px solid #fff;
box-sizing: border-box;
border-radius: 10px;
}
</style>

View File

@@ -0,0 +1,9 @@
<script setup>
import { ref, onMounted, onUnmounted } from "vue";
</script>
<template>
<Container> </Container>
</template>
<style scoped></style>

View File

@@ -0,0 +1,16 @@
<script setup>
import { ref, onMounted, onUnmounted } from "vue";
import Container from "@/components/Container.vue";
</script>
<template>
<Container
:bgType="2"
bgColor="#F5F5F5"
:whiteBackArrow="false"
title="计分记录"
>
</Container>
</template>
<style scoped></style>

BIN
src/static/app-bg3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

BIN
src/static/arrow-grey.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 B

BIN
src/static/back-black.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 636 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 204 B

After

Width:  |  Height:  |  Size: 471 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB