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

537 行
14 KiB
Vue

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

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

<template>
<view class="user-container">
<!-- 用户头部个人资料卡 -->
<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="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 } from 'vue';
import { USER_PROFILE } from '@/common/mock.js';
import { ICONS } from '@/common/icons.js';
const user = ref(USER_PROFILE);
const currentRole = ref('PLAYER');
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;
}
.row-arrow {
font-size: 24rpx;
color: #64748B;
}
}
}
@keyframes glowSpin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>