文件
shanghaipeiwan/pwuniapp/pages/user/index.vue

612 行
16 KiB
Vue

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

<template>
<view class="user-container" :class="{ 'theme-warm': currentThemeKey === 'warm' }">
<!-- 用户头部个人资料卡 -->
<view class="profile-card">
<image class="user-avatar" :src="user.avatar" mode="aspectFill" />
<view class="user-info">
<view class="name-row">
<text class="user-name">{{ user.nickname }}</text>
<text class="vip-badge">VIP 黄金玩家</text>
</view>
<text class="user-uid">UID: {{ user.id }}</text>
</view>
<view class="edit-btn btn-active" @click="editProfile">
<image class="edit-svg" :src="ICONS.settings" mode="aspectFit" />
</view>
</view>
<!-- 核心亮点:双身份流光切换卡 (纯矢量与流光动效) -->
<view class="role-switch-card card-active" @click="toggleRole">
<view class="role-glow-border"></view>
<view class="role-content">
<view class="role-left">
<view class="role-title-row">
<view class="role-dot" :class="{ expert: currentRole === 'EXPERT' }"></view>
<text class="current-role-tag">
{{ currentRole === 'PLAYER' ? '当前身份:普通玩家' : '当前身份:接单大神' }}
</text>
</view>
<text class="role-sub">
{{ currentRole === 'PLAYER' ? '一键切换至大神接单工作台,开启派单收益' : '一键切换回玩家大厅,自由寻找开黑车队' }}
</text>
</view>
<button class="btn-switch-role btn-active">
{{ currentRole === 'PLAYER' ? '切换为大神' : '切回玩家端' }}
</button>
</view>
</view>
<!-- 钱包与资产看板 -->
<view class="wallet-card">
<view class="wallet-head">
<text class="wallet-title">我的资产</text>
<text class="wallet-detail" @click="viewWalletLog">账单明细 ></text>
</view>
<view class="asset-grid">
<view class="asset-col">
<text class="asset-label">可用余额 (元)</text>
<text class="asset-val green-val">¥{{ user.balance }}</text>
<button class="asset-btn recharge btn-active" @click="handleRecharge">充值</button>
</view>
<view class="asset-divider"></view>
<view class="asset-col">
<text class="asset-label">分销佣金收益 (元)</text>
<text class="asset-val gold-val">¥{{ user.commission }}</text>
<button class="asset-btn withdraw btn-active" @click="handleWithdraw">提现</button>
</view>
</view>
</view>
<!-- 核心功能金刚区 (纯矢量SVG图标) -->
<view class="menu-grid-card">
<view class="menu-item btn-active" @click="navTo('/pages/activity/my-ticket')">
<view class="menu-icon bg-green">
<image class="menu-svg" :src="ICONS.ticket" mode="aspectFit" />
</view>
<text class="menu-title">我的门票</text>
<text class="menu-desc">4位核销码</text>
</view>
<view class="menu-item btn-active" @click="showInvitePoster">
<view class="menu-icon bg-purple">
<image class="menu-svg" :src="ICONS.share" mode="aspectFit" />
</view>
<text class="menu-title">推广赚钱</text>
<text class="menu-desc">二级返佣</text>
</view>
<view class="menu-item btn-active" @click="navTo('/pages/order/list')">
<view class="menu-icon bg-blue">
<image class="menu-svg" :src="ICONS.orderList" mode="aspectFit" />
</view>
<text class="menu-title">所有订单</text>
<text class="menu-desc">对局与退款</text>
</view>
<view class="menu-item btn-active" @click="applyExpert">
<view class="menu-icon bg-orange">
<image class="menu-svg" :src="ICONS.expertBadge" mode="aspectFit" />
</view>
<text class="menu-title">大神认证</text>
<text class="menu-desc">入驻接单</text>
</view>
</view>
<!-- 列表式功能菜单 (纯矢量SVG图标) -->
<view class="list-menu-card">
<view class="list-row btn-active" @click="handleSwitchTheme">
<image class="row-svg" :src="ICONS.palette" mode="aspectFit" />
<text class="row-label">界面主题风格</text>
<view class="theme-pill" :class="{ warm: currentThemeKey === 'warm' }">
<text>{{ currentThemeKey === 'warm' ? '暖阳赤焰' : '冷光暗夜' }}</text>
</view>
<text class="row-arrow">></text>
</view>
<view class="list-row btn-active" @click="contactService">
<image class="row-svg" :src="ICONS.headphones" mode="aspectFit" />
<text class="row-label">官方在线客服</text>
<text class="row-arrow">></text>
</view>
<view class="list-row btn-active" @click="openNotice">
<image class="row-svg" :src="ICONS.bell" mode="aspectFit" />
<text class="row-label">平台消息与通知</text>
<text class="row-arrow">></text>
</view>
<view class="list-row btn-active" @click="openAbout">
<image class="row-svg" :src="ICONS.shield" mode="aspectFit" />
<text class="row-label">平台规范与服务协议</text>
<text class="row-arrow">></text>
</view>
</view>
</view>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import { USER_PROFILE } from '@/common/mock.js';
import { ICONS } from '@/common/icons.js';
import { getCurrentThemeKey, setTheme, THEME_KEYS } from '@/common/theme.js';
const user = ref(USER_PROFILE);
const currentRole = ref('PLAYER');
const currentThemeKey = ref(getCurrentThemeKey());
const onThemeChanged = (key) => {
currentThemeKey.value = key;
};
onMounted(() => {
currentThemeKey.value = getCurrentThemeKey();
uni.$on('theme-change', onThemeChanged);
});
onUnmounted(() => {
uni.$off('theme-change', onThemeChanged);
});
const handleSwitchTheme = () => {
uni.showActionSheet({
itemList: ['冷光暗夜 (经典暗夜蓝紫)', '暖阳赤焰 (热情暖橙金流光)'],
success: (res) => {
const selectedKey = res.tapIndex === 1 ? THEME_KEYS.WARM : THEME_KEYS.COOL;
currentThemeKey.value = selectedKey;
setTheme(selectedKey);
uni.showToast({
title: selectedKey === THEME_KEYS.WARM ? '已切换至【暖阳赤焰】暖色系' : '已切换至【冷光暗夜】经典款',
icon: 'none',
duration: 1500
});
}
});
};
const toggleRole = () => {
if (currentRole.value === 'PLAYER') {
currentRole.value = 'EXPERT';
uni.showToast({
title: '正在进入【大神接单工作台】...',
icon: 'success',
duration: 1200
});
setTimeout(() => {
uni.navigateTo({
url: '/pages/expert/workspace'
});
}, 600);
} else {
currentRole.value = 'PLAYER';
uni.showToast({
title: '已切回【玩家端】',
icon: 'none'
});
}
};
const editProfile = () => {
uni.showToast({ title: '个人信息设置已就绪', icon: 'none' });
};
const viewWalletLog = () => {
uni.showToast({ title: '已加载近期收支明细', icon: 'none' });
};
const handleRecharge = () => {
uni.showToast({ title: '微信充值通道已拉起', icon: 'none' });
};
const handleWithdraw = () => {
uni.showModal({
title: '佣金提现申请',
content: `当前可提现佣金为 ¥${user.value.commission},提现将自动发起微信企业付款打款到微信零钱。`,
confirmText: '确认提现',
confirmColor: '#10B981',
success: (res) => {
if (res.confirm) {
uni.showToast({ title: '提现申请已提交,将在1个工作日内到账', icon: 'success' });
}
}
});
};
const showInvitePoster = () => {
uni.showModal({
title: '二级分销推广',
content: `您的专属邀请码为:PW${user.value.id}\n已成功邀请 ${user.value.invitedCount} 位好友!\n好友下单您将实时享受最高 15% 自动分润提成。`,
showCancel: false,
confirmText: '保存太阳码'
});
};
const applyExpert = () => {
uni.navigateTo({
url: '/pages/expert/workspace'
});
};
const contactService = () => {
uni.showToast({ title: '正在连接 7x24h 官方电竞客服', icon: 'none' });
};
const openNotice = () => {
uni.showToast({ title: '暂无未读系统公告', icon: 'none' });
};
const openAbout = () => {
uni.showModal({
title: '平台服务协议',
content: '严禁发布任何违规言论及作弊挂机行为,平台全面保障用户资金安全与绿色电竞环境。',
showCancel: false
});
};
const navTo = (url) => {
if (url === '/pages/order/list' || url === '/pages/activity/list') {
uni.switchTab({ url });
} else {
uni.navigateTo({ url });
}
};
</script>
<style lang="scss" scoped>
.user-container {
min-height: 100vh;
background-color: #0A0F1D;
padding: 24rpx 32rpx calc(160rpx + env(safe-area-inset-bottom));
}
.profile-card {
display: flex;
align-items: center;
margin-bottom: 28rpx;
.user-avatar {
width: 120rpx;
height: 120rpx;
border-radius: 60rpx;
border: 4rpx solid #6366F1;
margin-right: 24rpx;
}
.user-info {
flex: 1;
.name-row {
display: flex;
align-items: center;
gap: 12rpx;
margin-bottom: 8rpx;
.user-name {
font-size: 32rpx;
font-weight: 700;
color: #F8FAFC;
}
.vip-badge {
font-size: 18rpx;
background: linear-gradient(135deg, #F59E0B, #D97706);
color: #FFF;
padding: 2rpx 10rpx;
border-radius: 8rpx;
font-weight: 600;
}
}
.user-uid {
font-size: 22rpx;
color: #64748B;
font-family: monospace;
}
}
.edit-btn {
width: 68rpx;
height: 68rpx;
background: #151D30;
border-radius: 34rpx;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid rgba(255, 255, 255, 0.08);
.edit-svg {
width: 32rpx;
height: 32rpx;
opacity: 0.8;
}
}
}
.role-switch-card {
position: relative;
border-radius: 24rpx;
padding: 28rpx;
margin-bottom: 28rpx;
overflow: hidden;
box-shadow: 0 8rpx 28rpx rgba(99, 102, 241, 0.35);
&::before {
content: '';
position: absolute;
inset: -50%;
background: conic-gradient(from 0deg, transparent 0%, #6366F1 25%, #10B981 50%, #6366F1 75%, transparent 100%);
animation: glowSpin 5s linear infinite;
z-index: 0;
}
&::after {
content: '';
position: absolute;
inset: 2rpx;
background: linear-gradient(135deg, #1E1B4B 0%, #0F172A 100%);
border-radius: 22rpx;
z-index: 1;
}
.role-content {
position: relative;
z-index: 2;
display: flex;
justify-content: space-between;
align-items: center;
.role-left {
flex: 1;
margin-right: 20rpx;
.role-title-row {
display: flex;
align-items: center;
gap: 10rpx;
margin-bottom: 6rpx;
.role-dot {
width: 12rpx;
height: 12rpx;
border-radius: 50%;
background: #6366F1;
box-shadow: 0 0 8rpx #6366F1;
&.expert {
background: #10B981;
box-shadow: 0 0 8rpx #10B981;
}
}
.current-role-tag {
font-size: 28rpx;
font-weight: 700;
color: #FFFFFF;
}
}
.role-sub {
font-size: 20rpx;
color: #94A3B8;
line-height: 1.4;
}
}
.btn-switch-role {
background: linear-gradient(135deg, #6366F1 0%, #8B5CF6 100%);
color: #FFF;
font-size: 22rpx;
font-weight: 700;
border-radius: 32rpx;
padding: 0 24rpx;
height: 64rpx;
line-height: 64rpx;
margin: 0;
box-shadow: 0 4rpx 16rpx rgba(99, 102, 241, 0.4);
}
}
}
.wallet-card {
background-color: #151D30;
border-radius: 24rpx;
padding: 28rpx;
margin-bottom: 24rpx;
border: 1px solid rgba(255, 255, 255, 0.06);
.wallet-head {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24rpx;
.wallet-title {
font-size: 28rpx;
font-weight: 700;
color: #F8FAFC;
}
.wallet-detail {
font-size: 22rpx;
color: #64748B;
}
}
.asset-grid {
display: flex;
align-items: center;
justify-content: space-around;
.asset-col {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
.asset-label {
font-size: 22rpx;
color: #94A3B8;
margin-bottom: 8rpx;
}
.asset-val {
font-size: 36rpx;
font-weight: 700;
margin-bottom: 14rpx;
font-variant-numeric: tabular-nums;
&.green-val {
color: #10B981;
}
&.gold-val {
color: #F59E0B;
}
}
.asset-btn {
font-size: 20rpx;
padding: 0 24rpx;
height: 48rpx;
line-height: 46rpx;
border-radius: 24rpx;
margin: 0;
&.recharge {
background: rgba(16, 185, 129, 0.15);
color: #10B981;
border: 1px solid rgba(16, 185, 129, 0.3);
}
&.withdraw {
background: rgba(245, 158, 11, 0.15);
color: #F59E0B;
border: 1px solid rgba(245, 158, 11, 0.3);
}
}
}
.asset-divider {
width: 1px;
height: 80rpx;
background: rgba(255, 255, 255, 0.08);
}
}
}
.menu-grid-card {
display: flex;
justify-content: space-between;
background-color: #151D30;
border-radius: 24rpx;
padding: 24rpx 16rpx;
margin-bottom: 24rpx;
border: 1px solid rgba(255, 255, 255, 0.06);
.menu-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
.menu-icon {
width: 76rpx;
height: 76rpx;
border-radius: 22rpx;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 10rpx;
.menu-svg {
width: 38rpx;
height: 38rpx;
}
&.bg-green { background: rgba(16, 185, 129, 0.15); border: 1px solid rgba(16, 185, 129, 0.3); }
&.bg-purple { background: rgba(139, 92, 246, 0.15); border: 1px solid rgba(139, 92, 246, 0.3); }
&.bg-blue { background: rgba(99, 102, 241, 0.15); border: 1px solid rgba(99, 102, 241, 0.3); }
&.bg-orange { background: rgba(245, 158, 11, 0.15); border: 1px solid rgba(245, 158, 11, 0.3); }
}
.menu-title {
font-size: 24rpx;
color: #F8FAFC;
font-weight: 600;
margin-bottom: 4rpx;
}
.menu-desc {
font-size: 18rpx;
color: #64748B;
}
}
}
.list-menu-card {
background-color: #151D30;
border-radius: 24rpx;
padding: 8rpx 28rpx;
border: 1px solid rgba(255, 255, 255, 0.06);
.list-row {
display: flex;
align-items: center;
padding: 26rpx 0;
border-bottom: 1px solid rgba(255, 255, 255, 0.04);
&:last-child {
border-bottom: none;
}
.row-svg {
width: 32rpx;
height: 32rpx;
margin-right: 20rpx;
opacity: 0.85;
}
.row-label {
flex: 1;
font-size: 26rpx;
color: #E2E8F0;
}
.theme-pill {
margin-right: 16rpx;
font-size: 22rpx;
color: #818CF8;
background: rgba(99, 102, 241, 0.15);
border: 1px solid rgba(99, 102, 241, 0.3);
padding: 4rpx 16rpx;
border-radius: 20rpx;
font-weight: 500;
&.warm {
color: #FB923C;
background: rgba(249, 115, 22, 0.15);
border-color: rgba(249, 115, 22, 0.3);
}
}
.row-arrow {
font-size: 24rpx;
color: #64748B;
}
}
}
.user-container.theme-warm {
background-color: #140E0A;
.profile-card .user-avatar {
border-color: #F97316;
}
.role-switch-card .role-glow-border {
background: conic-gradient(from 0deg, #F97316, #F59E0B, #EA580C, #F97316);
}
.role-switch-card .btn-switch-role {
background: linear-gradient(135deg, #F97316, #EA580C);
box-shadow: 0 4rpx 16rpx rgba(249, 115, 22, 0.4);
}
.wallet-card, .menu-grid-card, .list-menu-card {
background-color: #221711;
border-color: rgba(249, 115, 22, 0.12);
}
}
@keyframes glowSpin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>