Files
rating/pages/mine/mine.vue
2026-05-07 11:05:30 +08:00

511 lines
11 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="mine-page">
<!-- Custom Navbar -->
<view
class="nav-bar"
:style="{ paddingTop: navBarTop + 'px', height: navBarHeight + 'px' }"
>
<!-- <text class="nav-title">我的</text> -->
</view>
<scroll-view
scroll-y
class="content-scroll"
:style="{ paddingTop: navBarTop + navBarHeight + 'px' }"
>
<view class="content-wrap">
<!-- User Card -->
<view class="user-card" @tap="handleUserClick">
<view class="avatar-box">
<image :src="userInfo.avatarUrl" class="avatar" mode="aspectFill" />
<!-- <view class="red-badge"><text class="fire">🔥</text></view> -->
</view>
<view class="user-info">
<view class="row-1">
<text class="nickname">{{ userInfo.nickName }}</text>
<view class="vip-tag" v-if="isLoggedIn && userInfo.isVip">
<text class="vip-text">VIP 祥瑞会员</text>
</view>
</view>
<view class="row-2" v-if="isLoggedIn">
<!-- <text class="arrow-icon"></text> -->
<!-- <text class="stats-text"
>已发送 <text class="num">3</text> 条新春祝福</text
> -->
</view>
<view class="row-2" v-else>
<text class="stats-text">点击登录解锁更多功能</text>
</view>
</view>
<view class="card-arrow"></view>
</view>
<!-- VIP Banner -->
<view v-if="!isIos" class="vip-banner" @tap="navTo('vip')">
<view class="vip-left">
<view class="vip-icon-box">
<uni-icons type="vip-filled" size="32" color="#5d4037" />
</view>
<view class="vip-content">
<view class="vip-title-row">
<text class="vip-title">祥瑞会员中心</text>
<view class="diamond-tag">DIAMOND</view>
</view>
<text class="vip-subtitle">开通会员解锁全部特权</text>
</view>
</view>
<view class="vip-right">
<text class="open-text">立即开通</text>
<text class="arrow"></text>
</view>
</view>
<!-- My Creations -->
<view class="section-title">我的xx</view>
<view class="menu-group">
<view class="menu-item" @tap="navTo('avatar')">
<view class="icon-box pink-bg"><text></text></view>
<text class="menu-text">我的专属头像</text>
<text class="arrow"></text>
</view>
</view>
<!-- Other Actions -->
<view class="menu-group mt-30">
<button class="menu-item share-btn" open-type="share">
<view class="icon-left"><text class="share-icon">🔗</text></view>
<text class="menu-text">分享给好友</text>
<text class="arrow"></text>
</button>
<view class="menu-item" @tap="navTo('feedback')">
<view class="icon-left"><text class="feedback-icon">📝</text></view>
<text class="menu-text">意见反馈</text>
<text class="arrow"></text>
</view>
<view class="menu-item" @tap="navTo('help')">
<view class="icon-left"><text class="help-icon"></text></view>
<text class="menu-text">使用说明 / 帮助</text>
<text class="arrow"></text>
</view>
</view>
<!-- Footer -->
<!-- <view class="version-info">2026 丙午马年 · 精美助手 v1.0.2</view> -->
<view style="height: 120rpx"></view>
</view>
</scroll-view>
<!-- Login Popup -->
<LoginPopup ref="loginPopupRef" @logind="handleLogind" />
</view>
</template>
<script setup>
import { ref, computed } from "vue";
import { useUserStore } from "@/stores/user";
import { onShareAppMessage, onLoad } from "@dcloudio/uni-app";
import { getShareToken } from "@/utils/common";
import { getShareReward } from "@/api/system";
import LoginPopup from "@/components/LoginPopup/LoginPopup.vue";
const userStore = useUserStore();
const loginPopupRef = ref(null);
// Navigation Bar
const navBarTop = ref(20);
const navBarHeight = ref(44);
// User Info
const defaultAvatarUrl =
"https://file.lihailezzc.com/resource/d9b329082b32f8305101f708593a4882.png";
const userInfo = computed(() => ({
nickName: userStore.userInfo.nickName || "点击登录",
avatarUrl: userStore.userInfo.avatarUrl || defaultAvatarUrl,
isVip: userStore.userInfo.isVip || false,
}));
const isLoggedIn = computed(() => !!userStore.userInfo.nickName);
const isIos = computed(() => uni.getSystemInfoSync().osName === "ios");
onLoad((options) => {
const sysInfo = uni.getSystemInfoSync();
navBarTop.value = sysInfo.statusBarHeight;
navBarHeight.value = 44;
});
onShareAppMessage(async () => {
const shareToken = await getShareToken("mine");
getShareReward({ scene: "mine" });
return {
title: "分享",
path: "/pages/index/index?shareToken=" + shareToken,
imageUrl:
"https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png",
};
});
const handleUserClick = () => {
if (!isLoggedIn.value) {
loginPopupRef.value.open();
} else {
// Navigate to profile details
uni.navigateTo({
url: "/pages/mine/profile",
});
}
};
const handleLogind = async () => {
// Logic after successful login if needed
};
const navTo = (page) => {
if (!isLoggedIn.value) {
loginPopupRef.value.open();
uni.showToast({ title: "请先登录", icon: "none" });
return;
}
if (page === "avatar") {
uni.navigateTo({
url: "/pages/mine/avatar",
});
return;
}
if (page === "feedback") {
uni.navigateTo({
url: "/pages/feedback/index",
});
return;
}
if (page === "help") {
uni.navigateTo({
url: "/pages/mine/help",
});
return;
}
if (page === "vip") {
uni.navigateTo({
url: "/pages/mine/vip",
});
return;
}
uni.showToast({ title: "功能开发中", icon: "none" });
};
</script>
<style lang="scss" scoped>
.mine-page {
min-height: 100vh;
background: #f9f9f9;
box-sizing: border-box;
}
.nav-bar {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 100;
display: flex;
align-items: center;
justify-content: center;
background: #f9f9f9;
}
.nav-title {
font-size: 32rpx;
font-weight: bold;
color: #000;
}
.content-scroll {
height: 100vh;
}
.content-wrap {
padding: 20rpx 30rpx 40rpx;
}
/* User Card */
.user-card {
background: #fff;
border-radius: 30rpx;
padding: 40rpx;
display: flex;
align-items: center;
margin-bottom: 40rpx;
position: relative;
box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.03);
}
.avatar-box {
position: relative;
margin-right: 30rpx;
}
.avatar {
width: 120rpx;
height: 120rpx;
border-radius: 50%;
border: 4rpx solid #fff;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
}
.red-badge {
position: absolute;
top: 0;
right: -10rpx;
width: 40rpx;
height: 40rpx;
background: #ff3b30;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
border: 2rpx solid #fff;
}
.fire {
font-size: 24rpx;
color: #fff;
}
.user-info {
flex: 1;
}
.row-1 {
display: flex;
align-items: center;
margin-bottom: 12rpx;
}
.nickname {
font-size: 36rpx;
font-weight: bold;
color: #333;
margin-right: 16rpx;
}
.vip-tag {
background: #ffecec;
padding: 4rpx 16rpx;
border-radius: 999rpx;
}
.vip-text {
color: #ff3b30;
font-size: 20rpx;
font-weight: bold;
}
.row-2 {
display: flex;
align-items: center;
}
.arrow-icon {
color: #ff3b30;
font-size: 20rpx;
margin-right: 8rpx;
}
.stats-text {
font-size: 24rpx;
color: #666;
}
.num {
font-weight: bold;
color: #333;
margin: 0 4rpx;
}
.card-arrow {
font-size: 40rpx;
color: #ccc;
margin-left: 10rpx;
}
/* VIP Banner */
.vip-banner {
background: linear-gradient(135deg, #2e2424 0%, #1a1616 100%);
border-radius: 30rpx;
padding: 30rpx 40rpx;
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 40rpx;
box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.1);
}
.vip-left {
display: flex;
align-items: center;
}
.vip-icon-box {
width: 80rpx;
height: 80rpx;
background: #fceea9;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-right: 24rpx;
border: 4rpx solid #bfa46f;
}
.vip-content {
display: flex;
flex-direction: column;
}
.vip-title-row {
display: flex;
align-items: center;
margin-bottom: 8rpx;
}
.vip-title {
font-size: 32rpx;
font-weight: bold;
color: #fceea9;
margin-right: 12rpx;
}
.diamond-tag {
background: rgba(252, 238, 169, 0.15);
color: #fceea9;
font-size: 18rpx;
padding: 2rpx 8rpx;
border-radius: 6rpx;
border: 1px solid rgba(252, 238, 169, 0.4);
}
.vip-subtitle {
font-size: 22rpx;
color: rgba(252, 238, 169, 0.6);
}
.vip-right {
display: flex;
align-items: center;
}
.open-text {
font-size: 26rpx;
color: #fceea9;
margin-right: 4rpx;
font-weight: 500;
}
.vip-banner .arrow {
color: #fceea9;
font-size: 32rpx;
}
/* Section Title */
.section-title {
font-size: 26rpx;
font-weight: bold;
color: #999;
margin-bottom: 20rpx;
padding-left: 10rpx;
}
/* Menu Group */
.menu-group {
background: #fff;
border-radius: 24rpx;
overflow: hidden;
margin-bottom: 40rpx;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.02);
}
.menu-group.mt-30 {
margin-top: 30rpx;
}
.menu-item {
display: flex;
align-items: center;
padding: 30rpx;
background: #fff;
position: relative;
}
.menu-item:active {
background: #f9f9f9;
}
/* For button reset */
.menu-item.share-btn {
width: 100%;
text-align: left;
line-height: normal;
border-radius: 0;
}
.menu-item.share-btn::after {
border: none;
}
.icon-box {
width: 72rpx;
height: 72rpx;
border-radius: 16rpx;
display: flex;
align-items: center;
justify-content: center;
margin-right: 24rpx;
font-size: 36rpx;
}
.red-bg {
background: #fff0f0;
color: #ff3b30;
}
.orange-bg {
background: #fff8e6;
color: #ff9500;
}
.pink-bg {
background: #fff0f5;
color: #ff2d55;
}
.yellow-bg {
background: #fffae0;
color: #ffcc00;
}
.gray-bg {
background: #f5f5f5;
color: #666;
}
.icon-left {
width: 40rpx;
display: flex;
justify-content: center;
margin-right: 24rpx;
margin-left: 16rpx;
}
.share-icon,
.help-icon,
.feedback-icon {
font-size: 36rpx;
color: #666;
}
.menu-text {
flex: 1;
font-size: 28rpx;
color: #333;
font-weight: 500;
}
.new-badge {
background: #ff3b30;
color: #fff;
font-size: 20rpx;
padding: 2rpx 10rpx;
border-radius: 8rpx;
margin-right: 16rpx;
}
.arrow {
color: #ccc;
font-size: 32rpx;
}
/* Version Info */
.version-info {
text-align: center;
color: #ccc;
font-size: 22rpx;
margin-top: 60rpx;
}
</style>