This commit is contained in:
kron
2025-07-30 17:38:48 +08:00
parent f414b34f44
commit 0ebe34cc1e
30 changed files with 211 additions and 81 deletions

View File

@@ -13,7 +13,7 @@ const props = defineProps({
const tabs = [ const tabs = [
{ image: "../static/tab-vip.png" }, { image: "../static/tab-vip.png" },
{ image: "../static/tab-grow.png" }, { image: "../static/tab-point-book.png" },
{ image: "../static/tab-mall.png" }, { image: "../static/tab-mall.png" },
]; ];
@@ -26,7 +26,7 @@ function handleTabClick(index) {
} }
if (index === 1) { if (index === 1) {
uni.navigateTo({ uni.navigateTo({
url: "/pages/my-growth", url: "/pages/point-book-create",
}); });
} }
if (index === 2) { if (index === 2) {
@@ -45,14 +45,11 @@ function handleTabClick(index) {
:key="index" :key="index"
class="tab-item" class="tab-item"
@click="handleTabClick(index)" @click="handleTabClick(index)"
:style="{
width: index === 1 ? '32%' : '10%',
}"
> >
<image <image :src="tab.image" mode="widthFix" />
:src="tab.image"
:style="{
width: index === 1 ? '100px' : '40px',
}"
mode="widthFix"
/>
</view> </view>
</view> </view>
</template> </template>
@@ -76,10 +73,16 @@ function handleTabClick(index) {
.tab-item { .tab-item {
z-index: 1; z-index: 1;
} }
.tab-item > image {
width: 88%;
}
.tab-item:nth-child(2) { .tab-item:nth-child(2) {
transform: translateY(10px); transform: translateY(20%) translateX(25%);
}
.tab-item:nth-child(3) {
transform: translateY(-10%) translateX(5%);
} }
.tab-item:nth-child(4) { .tab-item:nth-child(4) {
transform: translateY(10px) translateX(-10px); transform: translateY(20%) translateX(-25%);
} }
</style> </style>

View File

@@ -0,0 +1,17 @@
<script setup></script>
<template>
<view class="container">
<image src="../static/bow-target.png" mode="widthFix" />
</view>
</template>
<style scoped>
.container {
width: 90%;
margin: 10px auto;
}
.container > image {
width: 100%;
}
</style>

View File

@@ -1,5 +1,5 @@
<script setup> <script setup>
import { ref, onMounted, onUnmounted } from "vue"; import { ref, watch, onMounted, onUnmounted } from "vue";
const props = defineProps({ const props = defineProps({
itemIndex: { itemIndex: {
type: Number, type: Number,
@@ -21,6 +21,10 @@ const props = defineProps({
type: Boolean, type: Boolean,
default: false, default: false,
}, },
value: {
type: String,
default: "",
},
}); });
const bowTypes = [ const bowTypes = [
{ {
@@ -96,6 +100,36 @@ const onMeterChange = (e) => {
meter.value = e.detail.value; meter.value = e.detail.value;
props.onSelect(props.itemIndex, e.detail.value); props.onSelect(props.itemIndex, e.detail.value);
}; };
watch(
() => props.value,
(newValue) => {
if (!newValue) return;
if (props.itemIndex === 0) {
bowTypes.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;
}
});
}
if (props.itemIndex === 2) {
bowtargetTypes.forEach((item, index) => {
if (item === newValue) {
selectedIndex.value = index;
}
});
}
}
);
</script> </script>
<template> <template>
@@ -112,21 +146,13 @@ const onMeterChange = (e) => {
}}</text> }}</text>
<block> <block>
<text :style="{ opacity: expand ? 0 : 1 }" v-if="itemIndex === 0">{{ <text :style="{ opacity: expand ? 0 : 1 }" v-if="itemIndex === 0">{{
bowTypes[selectedIndex] value || itemTexts[itemIndex]
? bowTypes[selectedIndex].name
: itemTexts[itemIndex]
}}</text> }}</text>
<text :style="{ opacity: expand ? 0 : 1 }" v-if="itemIndex === 1">{{ <text :style="{ opacity: expand ? 0 : 1 }" v-if="itemIndex === 1">{{
distances[selectedIndex] value ? value + "" : itemTexts[itemIndex]
? distances[selectedIndex] + " "
: selectedIndex === 9
? meter + " "
: itemTexts[itemIndex]
}}</text> }}</text>
<text :style="{ opacity: expand ? 0 : 1 }" v-if="itemIndex === 2">{{ <text :style="{ opacity: expand ? 0 : 1 }" v-if="itemIndex === 2">{{
bowtargetTypes[selectedIndex] value || itemTexts[itemIndex]
? bowtargetTypes[selectedIndex]
: itemTexts[itemIndex]
}}</text> }}</text>
<text :style="{ opacity: expand ? 0 : 1 }" v-if="itemIndex === 3">{{ <text :style="{ opacity: expand ? 0 : 1 }" v-if="itemIndex === 3">{{
selectedIndex !== -1 && secondSelectIndex !== -1 selectedIndex !== -1 && secondSelectIndex !== -1
@@ -174,6 +200,7 @@ const onMeterChange = (e) => {
}" }"
> >
<input <input
v-model="meter"
placeholder="自定义" placeholder="自定义"
placeholder-style="color: #DDDDDD" placeholder-style="color: #DDDDDD"
@focus="() => (selectedIndex = 9)" @focus="() => (selectedIndex = 9)"

View File

@@ -1,13 +1,13 @@
{ {
"pages": [ "pages": [
{ {
"path": "pages/point-book-create" "path": "pages/index"
}, },
{ {
"path": "pages/point-book-edit" "path": "pages/point-book-edit"
}, },
{ {
"path": "pages/index" "path": "pages/point-book-create"
}, },
{ {
"path": "pages/point-book-list" "path": "pages/point-book-list"

View File

@@ -18,7 +18,8 @@ import { topThreeColors } from "@/constants";
import useStore from "@/store"; import useStore from "@/store";
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
const store = useStore(); const store = useStore();
const { updateConfig, updateUser, updateDevice, updateRank } = store; const { updateConfig, updateUser, updateDevice, updateRank, getLvlName } =
store;
// 使用storeToRefs用于UI里显示保持响应性 // 使用storeToRefs用于UI里显示保持响应性
const { user, device, rankData } = storeToRefs(store); const { user, device, rankData } = storeToRefs(store);
const showModal = ref(false); const showModal = ref(false);
@@ -109,11 +110,10 @@ const comingSoon = () => {
<view class="feature-grid"> <view class="feature-grid">
<view class="bow-card"> <view class="bow-card">
<image <image
src="https://api.shelingxingqiu.com/attachment/2025-07-15/dbciq9qhkpd3pqxawo.webp" src="../static/my-bow.png"
mode="widthFix" mode="widthFix"
@click="() => toPage('/pages/my-device')" @click="() => toPage('/pages/my-device')"
/> />
<text v-if="!user.id">我的弓箭</text> <text v-if="!user.id">我的弓箭</text>
<text v-if="user.id && !device.deviceId">请绑定设备</text> <text v-if="user.id && !device.deviceId">请绑定设备</text>
<text <text
@@ -123,7 +123,7 @@ const comingSoon = () => {
>{{ device.deviceName }}</text >{{ device.deviceName }}</text
> >
<image <image
src="../static/a2@2x.png" src="../static/first-try.png"
mode="widthFix" mode="widthFix"
@click="() => toPage('/pages/first-try')" @click="() => toPage('/pages/first-try')"
/> />
@@ -135,20 +135,17 @@ const comingSoon = () => {
<text>快来报到吧~</text> <text>快来报到吧~</text>
</BubbleTip> </BubbleTip>
</view> </view>
<view class="play-card">
<view class="practice-card" @click="() => toPage('/pages/practise')"> <view @click="() => toPage('/pages/practise')">
<image src="../static/a2@2x(1).png" mode="widthFix" /> <image src="../static/my-practise.png" mode="widthFix" />
</view> </view>
<view @click="() => toPage('/pages/friend-battle')">
<view <image src="../static/friend-battle.png" mode="widthFix" />
class="friend-card" </view>
@click="() => toPage('/pages/friend-battle')"
>
<image src="../static/a3@2x.png" mode="widthFix" />
</view> </view>
</view> </view>
<view class="ranking-section"> <view class="ranking-section">
<image src="../static/a4@2x.png" mode="widthFix" /> <image src="../static/rank-bg.png" mode="widthFix" />
<button <button
class="into-btn" class="into-btn"
@click="() => toPage('/pages/ranking')" @click="() => toPage('/pages/ranking')"
@@ -185,7 +182,30 @@ const comingSoon = () => {
</view> </view>
</view> </view>
</view> </view>
<view class="region-stats"> <view class="my-data">
<view @click="() => toPage('/pages/my-growth')">
<image src="../static/my-growth.png" mode="widthFix" />
</view>
<view>
<view>
<text>段位</text>
<text>{{ user.scores ? getLvlName(user.scores) : "-" }}</text>
</view>
<view>
<text>赛季平均环数</text>
<text>{{ user.avg_ring ? user.avg_ring + "环" : "-" }}</text>
</view>
<view>
<text>赛季胜率</text>
<text>{{
user.avg_win
? Number((user.avg_win * 100).toFixed(2)) + "%"
: "-"
}}</text>
</view>
</view>
</view>
<!-- <view class="region-stats">
<view <view
v-for="(region, index) in [ v-for="(region, index) in [
{ name: '广东', score: 4291 }, { name: '广东', score: 4291 },
@@ -237,7 +257,7 @@ const comingSoon = () => {
<text>...</text> <text>...</text>
<text>更多</text> <text>更多</text>
</view> </view>
</view> </view> -->
</view> </view>
</view> </view>
<SModal :show="showModal" :onClose="() => (showModal = false)"> <SModal :show="showModal" :onClose="() => (showModal = false)">
@@ -254,17 +274,19 @@ const comingSoon = () => {
} }
.feature-grid { .feature-grid {
display: grid; width: 100%;
grid-template-columns: 1fr 1fr; display: flex;
grid-template-areas: "bow practice" "bow friend"; margin-bottom: 5px;
row-gap: 5px; }
column-gap: 10px;
margin-bottom: 10px; .feature-grid > view {
position: relative;
display: flex;
flex-direction: column;
} }
.bow-card { .bow-card {
grid-area: bow; width: 50%;
position: relative;
} }
.feature-grid > view > image { .feature-grid > view > image {
@@ -281,21 +303,16 @@ const comingSoon = () => {
color: #b3b3b3; color: #b3b3b3;
} }
.bow-card > image:first-child {
transform: scaleY(1.08) translateY(9px);
}
.bow-card > image:nth-child(3) { .bow-card > image:nth-child(3) {
transform: translateY(-1px); transform: translateY(-1px);
} }
.practice-card { .play-card {
grid-area: practice; width: 48%;
width: 100%; margin-left: 2%;
} }
.friend-card { .play-card > view > image {
grid-area: friend;
width: 100%; width: 100%;
} }
@@ -382,7 +399,7 @@ const comingSoon = () => {
} }
.more-players { .more-players {
background: rgba(255, 255, 255, 0.2); background: #3C445A;
font-size: 9px; font-size: 9px;
line-height: 80rpx; line-height: 80rpx;
text-align: center; text-align: center;
@@ -447,4 +464,39 @@ const comingSoon = () => {
line-height: 20px; line-height: 20px;
margin-bottom: 5px; margin-bottom: 5px;
} }
.my-data {
display: flex;
margin-top: 20px;
justify-content: space-between;
}
.my-data > view:first-child {
width: 28%;
}
.my-data > view:first-child > image {
width: 100%;
transform: translateX(-8px);
}
.my-data > view:nth-child(2) {
width: 68%;
font-size: 12px;
color: #fff6;
display: flex;
justify-content: space-between;
}
.my-data > view:nth-child(2) > view:nth-child(2) {
width: 38%;
}
.my-data > view:nth-child(2) > view {
width: 28%;
border-radius: 10px;
background: linear-gradient(180deg, #303b4c 30%, #2c384a 100%);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.my-data > view:nth-child(2) > view > text:last-child {
color: #fff;
line-height: 25px;
}
</style> </style>

View File

@@ -24,6 +24,7 @@ const onSelect = (itemIndex, value) => {
else if (itemIndex === 1) distance.value = value; else if (itemIndex === 1) distance.value = value;
else if (itemIndex === 2) bowtargetType.value = value; else if (itemIndex === 2) bowtargetType.value = value;
else if (itemIndex === 3) amountGroup.value = value; else if (itemIndex === 3) amountGroup.value = value;
if (itemIndex < 3) expandIndex.value += 1;
if ( if (
bowType.value && bowType.value &&
distance.value && distance.value &&
@@ -44,6 +45,14 @@ const toEditPage = () => {
url: "/pages/point-book-edit", url: "/pages/point-book-edit",
}); });
}; };
onMounted(() => {
const pointBook = uni.getStorageSync("point-book");
if (pointBook) {
bowType.value = pointBook.bowType;
distance.value = pointBook.distance;
bowtargetType.value = pointBook.bowtargetType;
}
});
</script> </script>
<template> <template>
@@ -54,25 +63,31 @@ const toEditPage = () => {
title="计分本" title="计分本"
> >
<view class="container"> <view class="container">
<image src="../static/point-book-banner.png" mode="widthFix" /> <image
src="https://api.shelingxingqiu.com/attachment/2025-07-30/dbp9r4762kiaqykbpn.png"
mode="widthFix"
/>
<view> <view>
<EditOption <EditOption
:itemIndex="0" :itemIndex="0"
:expand="expandIndex === 0" :expand="expandIndex === 0"
:onExpand="onExpandChange" :onExpand="onExpandChange"
:onSelect="onSelect" :onSelect="onSelect"
:value="bowType"
/> />
<EditOption <EditOption
:itemIndex="1" :itemIndex="1"
:expand="expandIndex === 1" :expand="expandIndex === 1"
:onExpand="onExpandChange" :onExpand="onExpandChange"
:onSelect="onSelect" :onSelect="onSelect"
:value="distance + ''"
/> />
<EditOption <EditOption
:itemIndex="2" :itemIndex="2"
:expand="expandIndex === 2" :expand="expandIndex === 2"
:onExpand="onExpandChange" :onExpand="onExpandChange"
:onSelect="onSelect" :onSelect="onSelect"
:value="bowtargetType"
/> />
<EditOption <EditOption
:itemIndex="3" :itemIndex="3"

View File

@@ -3,6 +3,7 @@ import { ref, onMounted } from "vue";
import Container from "@/components/Container.vue"; import Container from "@/components/Container.vue";
import ScreenHint2 from "@/components/ScreenHint2.vue"; import ScreenHint2 from "@/components/ScreenHint2.vue";
import SButton from "@/components/SButton.vue"; import SButton from "@/components/SButton.vue";
import BowTargetEdit from "@/components/BowTargetEdit.vue";
const clickable = ref(false); const clickable = ref(false);
const showTip = ref(false); const showTip = ref(false);
@@ -39,13 +40,16 @@ const onClickRing = (ring) => {
if (arrowGroups.value[currentGroup.value]) { if (arrowGroups.value[currentGroup.value]) {
arrowGroups.value[currentGroup.value][currentArrow.value] = ring; arrowGroups.value[currentGroup.value][currentArrow.value] = ring;
clickable.value = arrowGroups.value[currentGroup.value].every( clickable.value = arrowGroups.value[currentGroup.value].every(
(item) => item !== null (item) => !!item
); );
if (currentArrow.value < amount.value - 1) { if (currentArrow.value < amount.value - 1) {
currentArrow.value++; currentArrow.value++;
} }
} }
}; };
const deleteArrow = () => {
arrowGroups.value[currentGroup.value][currentArrow.value] = "";
};
onMounted(() => { onMounted(() => {
const pointBook = uni.getStorageSync("point-book"); const pointBook = uni.getStorageSync("point-book");
@@ -53,7 +57,7 @@ onMounted(() => {
groups.value = Number(pointBook.amountGroup.split("/")[0]); groups.value = Number(pointBook.amountGroup.split("/")[0]);
amount.value = Number(pointBook.amountGroup.split("/")[1]); amount.value = Number(pointBook.amountGroup.split("/")[1]);
for (let i = 1; i <= groups.value; i++) { for (let i = 1; i <= groups.value; i++) {
arrowGroups.value[i] = new Array(amount.value).fill(null); arrowGroups.value[i] = new Array(amount.value).fill("");
} }
} }
}); });
@@ -67,12 +71,16 @@ onMounted(() => {
:onBack="() => (showTip = true)" :onBack="() => (showTip = true)"
> >
<view class="container"> <view class="container">
<view class="bow-target"> <BowTargetEdit />
<image src="../static/bow-target.png" mode="widthFix" />
</view>
<view class="title-bar"> <view class="title-bar">
<view /> <view>
<text> {{ currentGroup }} </text> <view />
<text> {{ currentGroup }} </text>
</view>
<view @click="deleteArrow">
<image src="../static/delete.png" />
<text>删除</text>
</view>
</view> </view>
<view class="bow-arrows"> <view class="bow-arrows">
<view <view
@@ -84,12 +92,12 @@ onMounted(() => {
borderColor: currentArrow === index ? '#FED847' : '#eeeeee', borderColor: currentArrow === index ? '#FED847' : '#eeeeee',
borderWidth: currentArrow === index ? '2px' : '1px', borderWidth: currentArrow === index ? '2px' : '1px',
}" }"
>{{ arrow === null ? "" : arrow + " 环" }}</view >{{ isNaN(arrow) ? arrow : arrow ? arrow + " 环" : "" }}</view
> >
</view> </view>
<text>输入分值的情况下系统不提供落点稳定性分</text> <text>输入分值的情况下系统不提供落点稳定性分</text>
<view class="bow-rings"> <view class="bow-rings">
<view @click="() => onClickRing(11)">X</view> <view @click="() => onClickRing('X')">X</view>
<view <view
v-for="i in 10" v-for="i in 10"
:key="i" :key="i"
@@ -97,7 +105,7 @@ onMounted(() => {
:style="{ backgroundColor: ringColors[i] || '#d8d8d8' }" :style="{ backgroundColor: ringColors[i] || '#d8d8d8' }"
>{{ 11 - i }}</view >{{ 11 - i }}</view
> >
<view @click="() => onClickRing(0)">M</view> <view @click="() => onClickRing('M')">M</view>
</view> </view>
<ScreenHint2 :show="showTip"> <ScreenHint2 :show="showTip">
<view class="tip-content"> <view class="tip-content">
@@ -194,27 +202,35 @@ onMounted(() => {
.tip-content > view > button:last-child { .tip-content > view > button:last-child {
background: #fed847; background: #fed847;
} }
.bow-target {
width: 90%;
margin: 10px auto;
}
.bow-target > image {
width: 100%;
}
.title-bar { .title-bar {
width: 100%; width: calc(100% - 30px);
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between;
font-size: 13px; font-size: 13px;
margin: 0 15px;
}
.title-bar > view:first-child {
display: flex;
align-items: center;
color: #333; color: #333;
font-weight: 500; font-weight: 500;
} }
.title-bar > view:first-child { .title-bar > view:first-child > view:first-child {
width: 5px; width: 5px;
height: 15px; height: 15px;
border-radius: 10px; border-radius: 10px;
background-color: #fed847; background-color: #fed847;
margin-right: 7px; margin-right: 7px;
margin-left: 15px; }
.title-bar > view:nth-child(2) {
color: #287fff;
display: flex;
align-items: center;
}
.title-bar > view:nth-child(2) image {
width: 14px;
height: 14px;
margin-right: 5px;
} }
</style> </style>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

BIN
src/static/delete.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 B

BIN
src/static/first-try.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
src/static/my-bow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

BIN
src/static/my-growth.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
src/static/my-practise.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

BIN
src/static/rank-bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 465 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 630 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 724 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 579 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 706 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB