完成新的首页布局
@@ -1,83 +1,106 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
const tabs = [
|
import { ref } from "vue";
|
||||||
{ image: "../static/tab-vip.png" },
|
|
||||||
{ image: "../static/tab-point-book.png" },
|
|
||||||
{ image: "../static/tab-mall.png" },
|
|
||||||
];
|
|
||||||
|
|
||||||
function handleTabClick(index) {
|
const props = defineProps({
|
||||||
if (index === 0) {
|
selected: {
|
||||||
uni.navigateTo({
|
type: Number,
|
||||||
url: "/pages/be-vip",
|
default: 0,
|
||||||
});
|
},
|
||||||
}
|
onChange: {
|
||||||
|
type: Function,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const isIOS = uni.getDeviceInfo().osName === "ios";
|
||||||
|
const tabs = {
|
||||||
|
首页: "home",
|
||||||
|
智能弓: "mall",
|
||||||
|
计分本: "tab-point-book",
|
||||||
|
勋章: "medal",
|
||||||
|
个人中心: "user",
|
||||||
|
};
|
||||||
|
const onTabChange = (index) => {
|
||||||
if (index === 1) {
|
if (index === 1) {
|
||||||
uni.navigateTo({
|
return uni.navigateTo({
|
||||||
url: "/pages/point-book",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (index === 2) {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: "/pages/device-intro",
|
url: "/pages/device-intro",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
if (index === 2) {
|
||||||
|
return uni.navigateTo({
|
||||||
|
url: "/pages/point-book",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (index === 4) {
|
||||||
|
return uni.navigateTo({
|
||||||
|
url: "/pages/user",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// props.onChange(index);
|
||||||
|
};
|
||||||
|
const getTabSrc = (key, index) => {
|
||||||
|
return `../static/tab-${tabs[key]}${props.selected === index ? "" : "-o"}.png`;
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<view class="footer">
|
<view class="footer" :style="{ paddingBottom: isIOS ? '30rpx' : '0' }">
|
||||||
<image class="footer-bg" src="../static/tab-bg.png" mode="widthFix" />
|
<button
|
||||||
<view
|
hover-class="none"
|
||||||
v-for="(tab, index) in tabs"
|
v-for="(key, index) in Object.keys(tabs)"
|
||||||
:key="index"
|
:key="key"
|
||||||
class="tab-item"
|
@click="onTabChange(index)"
|
||||||
@click="handleTabClick(index)"
|
:class="index === 2 ? 'point-book-tab' : ''"
|
||||||
:style="{
|
|
||||||
width: index === 1 ? '36%' : '20%',
|
|
||||||
}"
|
|
||||||
>
|
>
|
||||||
<image :src="tab.image" mode="widthFix" />
|
<image v-if="index !== 2" :src="getTabSrc(key, index)" mode="widthFix" />
|
||||||
</view>
|
<image v-else src="../static/tab-point-book.png" mode="widthFix" />
|
||||||
|
<text
|
||||||
|
v-if="index !== 2"
|
||||||
|
:style="{ color: index === selected ? '#f7cb74' : '#8E7D5C' }"
|
||||||
|
>{{ key }}</text
|
||||||
|
>
|
||||||
|
</button>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.footer {
|
.footer {
|
||||||
height: 120px;
|
height: 140rpx;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-around;
|
justify-content: space-around;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
overflow: hidden;
|
background: linear-gradient(
|
||||||
|
180deg,
|
||||||
|
rgba(70, 55, 34, 0.75) 0%,
|
||||||
|
rgba(5, 11, 25, 0.58) 100%
|
||||||
|
),
|
||||||
|
#000000;
|
||||||
|
box-shadow: 0rpx 0rpx 20rpx 0rpx rgba(0, 0, 0, 0.06);
|
||||||
}
|
}
|
||||||
.footer-bg {
|
.footer > button {
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
position: absolute;
|
|
||||||
z-index: 0;
|
|
||||||
}
|
|
||||||
.tab-item {
|
|
||||||
z-index: 1;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
width: 20%;
|
||||||
}
|
}
|
||||||
.tab-item > image {
|
.footer > button > image {
|
||||||
width: 65rpx;
|
width: 44rpx;
|
||||||
|
height: 44rpx;
|
||||||
}
|
}
|
||||||
.tab-item:last-child > image {
|
.footer > button > text {
|
||||||
width: 85rpx;
|
font-weight: 500;
|
||||||
|
font-size: 20rpx;
|
||||||
|
margin-top: 10rpx;
|
||||||
}
|
}
|
||||||
.tab-item:nth-child(2) {
|
.point-book-tab {
|
||||||
transform: translate(10%, 40%);
|
overflow: unset;
|
||||||
}
|
}
|
||||||
.tab-item:nth-child(3) {
|
.point-book-tab > image {
|
||||||
margin-bottom: 25rpx;
|
width: 144rpx !important;
|
||||||
}
|
height: 144rpx !important;
|
||||||
.tab-item:nth-child(3) > image {
|
transform: translateY(-10rpx);
|
||||||
width: 140rpx;
|
|
||||||
}
|
|
||||||
.tab-item:nth-child(4) {
|
|
||||||
transform: translate(-10%, 44%);
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -25,10 +25,6 @@ const props = defineProps({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
isHome: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
showBackToGame: {
|
showBackToGame: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
@@ -142,12 +138,7 @@ const goCalibration = async () => {
|
|||||||
<template>
|
<template>
|
||||||
<view :style="{ paddingTop: capsuleHeight + 'px' }">
|
<view :style="{ paddingTop: capsuleHeight + 'px' }">
|
||||||
<AppBackground :type="bgType" :bgColor="bgColor" />
|
<AppBackground :type="bgType" :bgColor="bgColor" />
|
||||||
<Header
|
<Header :title="title" :onBack="onBack" :whiteBackArrow="whiteBackArrow" />
|
||||||
v-if="!isHome"
|
|
||||||
:title="title"
|
|
||||||
:onBack="onBack"
|
|
||||||
:whiteBackArrow="whiteBackArrow"
|
|
||||||
/>
|
|
||||||
<BackToGame v-if="showBackToGame" />
|
<BackToGame v-if="showBackToGame" />
|
||||||
<scroll-view
|
<scroll-view
|
||||||
:scroll-y="scroll"
|
:scroll-y="scroll"
|
||||||
@@ -155,7 +146,7 @@ const goCalibration = async () => {
|
|||||||
:bounces="false"
|
:bounces="false"
|
||||||
:show-scrollbar="false"
|
:show-scrollbar="false"
|
||||||
:style="{
|
:style="{
|
||||||
height: `calc(100vh - ${capsuleHeight + (isHome ? 0 : 50)}px - ${
|
height: `calc(100vh - ${capsuleHeight + 50}px - ${
|
||||||
$slots.bottom && showBottom ? (isIOS ? '75px' : '65px') : '0px'
|
$slots.bottom && showBottom ? (isIOS ? '75px' : '65px') : '0px'
|
||||||
})`,
|
})`,
|
||||||
}"
|
}"
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted } from "vue";
|
import { ref, onMounted } from "vue";
|
||||||
import { onShow, onShareAppMessage, onShareTimeline } from "@dcloudio/uni-app";
|
import { onShow, onShareAppMessage, onShareTimeline } from "@dcloudio/uni-app";
|
||||||
import Container from "@/components/Container.vue";
|
|
||||||
import AppFooter from "@/components/AppFooter.vue";
|
import AppFooter from "@/components/AppFooter.vue";
|
||||||
import AppBackground from "@/components/AppBackground.vue";
|
|
||||||
import UserHeader from "@/components/UserHeader.vue";
|
|
||||||
import Signin from "@/components/Signin.vue";
|
import Signin from "@/components/Signin.vue";
|
||||||
import BubbleTip from "@/components/BubbleTip.vue";
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getAppConfig,
|
getAppConfig,
|
||||||
@@ -16,7 +12,7 @@ import {
|
|||||||
getDeviceBatteryAPI,
|
getDeviceBatteryAPI,
|
||||||
} from "@/apis";
|
} from "@/apis";
|
||||||
import { topThreeColors } from "@/constants";
|
import { topThreeColors } from "@/constants";
|
||||||
import { canEenter } from "@/util";
|
import { canEenter, capsuleHeight } from "@/util";
|
||||||
|
|
||||||
import useStore from "@/store";
|
import useStore from "@/store";
|
||||||
import { storeToRefs } from "pinia";
|
import { storeToRefs } from "pinia";
|
||||||
@@ -33,6 +29,7 @@ const { user, device, rankData, online, game } = storeToRefs(store);
|
|||||||
|
|
||||||
const showModal = ref(false);
|
const showModal = ref(false);
|
||||||
const showGuide = ref(false);
|
const showGuide = ref(false);
|
||||||
|
const selected = ref(0);
|
||||||
|
|
||||||
const toPage = async (path) => {
|
const toPage = async (path) => {
|
||||||
if (!user.value.id) {
|
if (!user.value.id) {
|
||||||
@@ -125,15 +122,34 @@ onShareTimeline(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Container :isHome="true" :showBackToGame="true">
|
<view
|
||||||
<view class="container">
|
class="container"
|
||||||
<view class="top-theme">
|
:style="{
|
||||||
|
paddingTop: capsuleHeight + 'px',
|
||||||
|
height: 'calc(100vh - ' + capsuleHeight + 'px)',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<view :style="{ height: '100%' }">
|
||||||
|
<image
|
||||||
|
src="https://static.shelingxingqiu.com/attachment/2026-01-12/dfmg11wd20o1bagd4k.png"
|
||||||
|
mode="widthFix"
|
||||||
|
class="top-bg"
|
||||||
|
/>
|
||||||
|
<view class="header">
|
||||||
|
<image
|
||||||
|
src="https://static.shelingxingqiu.com/attachment/2026-01-12/dfmf4cjlds7oxd0tqd.png"
|
||||||
|
mode="widthFix"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
<view class="body"></view>
|
||||||
|
<Signin :show="showModal" :onClose="() => (showModal = false)" />
|
||||||
|
</view>
|
||||||
|
<!-- <view class="top-theme">
|
||||||
<image
|
<image
|
||||||
src="https://static.shelingxingqiu.com/attachment/2025-12-31/dfc9dxrq4xn7e6y2pp.png"
|
src="https://static.shelingxingqiu.com/attachment/2025-12-31/dfc9dxrq4xn7e6y2pp.png"
|
||||||
mode="widthFix"
|
mode="widthFix"
|
||||||
/>
|
/>
|
||||||
</view>
|
</view>
|
||||||
<UserHeader showRank :onSignin="() => (showModal = true)" />
|
|
||||||
<view :style="{ padding: '12px 10px' }">
|
<view :style="{ padding: '12px 10px' }">
|
||||||
<view class="feature-grid">
|
<view class="feature-grid">
|
||||||
<view class="bow-card">
|
<view class="bow-card">
|
||||||
@@ -242,20 +258,41 @@ onShareTimeline(() => {
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
</view> -->
|
||||||
|
<AppFooter :selected="selected" :onChange="(index) => (selected = index)" />
|
||||||
</view>
|
</view>
|
||||||
<Signin :show="showModal" :onClose="() => (showModal = false)" />
|
|
||||||
</view>
|
|
||||||
<AppFooter />
|
|
||||||
</Container>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.container {
|
.container {
|
||||||
width: 100%;
|
width: 100vw;
|
||||||
height: calc(100% - 120px);
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
background-color: #000;
|
||||||
}
|
}
|
||||||
|
.top-bg {
|
||||||
.feature-grid {
|
width: 100%;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
.header {
|
||||||
|
height: 50px;
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding-left: 30rpx;
|
||||||
|
}
|
||||||
|
.header > image {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 50rpx;
|
||||||
|
}
|
||||||
|
.body {
|
||||||
|
height: calc(100% - 50px);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
/* .feature-grid {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
@@ -442,5 +479,5 @@ onShareTimeline(() => {
|
|||||||
.top-theme > image {
|
.top-theme > image {
|
||||||
width: 300rpx;
|
width: 300rpx;
|
||||||
transform: translate(-4%, -14%);
|
transform: translate(-4%, -14%);
|
||||||
}
|
} */
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 7.3 KiB |
BIN
src/static/tab-home-o.png
Normal file
|
After Width: | Height: | Size: 517 B |
BIN
src/static/tab-home.png
Normal file
|
After Width: | Height: | Size: 665 B |
BIN
src/static/tab-mall-o.png
Normal file
|
After Width: | Height: | Size: 555 B |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 650 B |
BIN
src/static/tab-medal-o.png
Normal file
|
After Width: | Height: | Size: 644 B |
BIN
src/static/tab-medal.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |