Files
uniapp-tmp/pages/index/index.vue
2026-04-24 10:20:50 +08:00

207 lines
4.5 KiB
Vue

<template>
<view
class="home-container"
:style="{ paddingTop: statusBarHeight + 54 + 'px' }"
>
<!-- 顶部用户信息栏 -->
<view
class="header-section"
:style="{ paddingTop: statusBarHeight + 4 + 'px' }"
>
<view class="user-info">
<image
class="user-avatar"
:src="userInfo.avatarUrl || '/static/images/default-avatar.png'"
mode="aspectFill"
/>
<view class="user-texts">
<text class="greeting-info">{{ greetingText }}</text>
<view class="name-row">
<text class="user-name" @tap="handleLogin">
{{ userInfo.nickName || "点击登录" }}
</text>
</view>
</view>
</view>
</view>
<!-- 登录弹窗 -->
<LoginPopup @logind="handleLoginSuccess" />
</view>
</template>
<script setup>
import { ref, computed } from "vue";
import { getStatusBarHeight } from "@/utils/system";
import {
onShareAppMessage,
onShareTimeline,
onShow,
onPullDownRefresh,
onLoad,
} from "@dcloudio/uni-app";
import { useUserStore } from "@/stores/user";
import {
getShareReward,
} from "@/api/system";
import { getShareToken, saveViewRequest } from "@/utils/common.js";
import LoginPopup from "@/components/LoginPopup/LoginPopup.vue";
import adManager from "@/utils/adManager.js";
const userStore = useUserStore();
const statusBarHeight = ref(getStatusBarHeight());
const userInfo = computed(() => userStore?.userInfo || {});
const isLoggedIn = computed(() => !!userStore.userInfo.nickName);
const greetingText = computed(() => {
const hour = new Date().getHours();
if (hour < 6) return "凌晨好";
if (hour < 9) return "早上好";
if (hour < 12) return "上午好";
if (hour < 14) return "中午好";
if (hour < 17) return "下午好";
if (hour < 19) return "傍晚好";
return "晚上好";
});
const handleLogin = () => {
if (!userInfo.value.nickName) {
uni.$emit("show-login-popup");
}
};
let firstLoad = true;
const initData = () => {
if (adManager.isAdShowing) return; // 防止广告页返回时立即重新渲染引发 insertTextView:fail
};
onLoad((options) => {
uni.$trackRecord({
eventName: "index_page_visit",
eventType: `visit`,
})
if (options.shareToken) {
saveViewRequest(options.shareToken, "index");
}
initData();
});
onShow(() => {
if (firstLoad) {
firstLoad = false;
return;
}
initData();
});
const handleLoginSuccess = () => {
};
onShareAppMessage(async () => {
const shareToken = await getShareToken("index");
getShareReward();
return {
title: "分享",
path: "/pages/index/index?shareToken=" + shareToken,
};
});
onShareTimeline(async () => {
const shareToken = await getShareToken("index");
getShareReward();
return {
title: "分享",
query: `shareToken=${shareToken}`,
};
});
</script>
<style lang="scss" scoped>
.home-container {
min-height: 100vh;
background-color: #fbfbf9; /* 柔和的米色背景 */
padding-left: 32rpx;
padding-right: 32rpx;
padding-bottom: 120rpx;
box-sizing: border-box;
}
/* 顶部用户信息 */
.header-section {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 999;
display: flex;
justify-content: space-between;
align-items: center;
padding-left: 32rpx;
padding-right: 32rpx;
padding-bottom: 24rpx;
background-color: rgba(251, 251, 249, 0.95);
backdrop-filter: blur(20rpx);
.user-info {
display: flex;
align-items: center;
.user-avatar {
width: 64rpx;
height: 64rpx;
border-radius: 50%;
border: 2rpx solid #fff;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
margin-right: 16rpx;
}
.user-texts {
display: flex;
flex-direction: column;
.greeting-info {
font-size: 20rpx;
color: #999;
margin-bottom: 2rpx;
}
.name-row {
display: flex;
align-items: center;
.user-name {
font-size: 26rpx;
font-weight: bold;
color: #333;
margin-right: 12rpx;
}
.user-points {
display: flex;
align-items: center;
background: rgba(255, 152, 0, 0.1);
border: 1rpx solid rgba(255, 152, 0, 0.3);
border-radius: 20rpx;
padding: 2rpx 10rpx;
.points-label {
font-size: 16rpx;
color: #ff9800;
margin-right: 4rpx;
}
.points-value {
font-size: 20rpx;
color: #ff5722;
font-weight: bold;
}
}
}
}
}
}
</style>