Files
guoxue-mp/pages/user/index.vue
T
2026-03-25 15:59:24 +08:00

491 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="profile-page">
<image class="profile-bg" src="/static/icon/轮播图 Copy kTtd4FG@1x.png" mode="aspectFill"></image>
<view class="profile-header">
<text class="header-title">我的</text>
</view>
<view class="profile-card">
<view class="profile-info" @click="$jump('/pages/user/profile')">
<image class="avatar" :src="user.avatar" mode="aspectFill"></image>
<view class="info-text">
<view class="user-name">{{ user.nickname }}</view>
<!-- <view class="badge">-->
<!-- <u-icon name="camera-fill" size="20" color="#ffc44d"></u-icon>-->
<!-- <text>小X会员</text>-->
<!-- </view>-->
</view>
</view>
<!-- <text class="profile-desc">为您提供更精准的推荐</text>-->
<view class="profile-stats">
<view class="stat" v-for="stat in stats" :key="stat.label" @click="handleMenu(stat)">
<view class="stat-value">{{ stat.value }}</view>
<view class="stat-label">{{ stat.label }}</view>
</view>
</view>
</view>
<view class="vip-card" v-if="!authing">
<view class="flex justify-start items-center">
<view class="vip-amount">剩余金币:
<text class="highlight">{{ user.coin }}</text>
</view>
<view class="vip-amount">,赠送金币:
<text class="highlight">{{ user.sendCoin }}</text>
</view>
</view>
<view class="vip-btn" @click="openRecharge">
<text>立即续费</text>
</view>
</view>
<view class="menu-section">
<view
class="menu-item"
v-for="item in menuList"
:key="item.label"
@click="handleMenu(item)"
>
<view class="menu-left">
<u-icon :name="item.icon" size="28" color="#8c8fad"></u-icon>
<text class="menu-text">{{ item.label }}</text>
</view>
<u-icon name="arrow-right" color="#a3a7c2" size="18"></u-icon>
<view class="menu-overlay" @click.stop="handleMenu(item)"></view>
</view>
</view>
<view class="logout-card" @click="logout" v-if="user">
<text class="logout-text">退出</text>
<u-icon name="arrow-right" color="#5e5f79" size="18"></u-icon>
</view>
<u-popup :show="showRecharge" mode="center" round="20" @close="showRecharge = false">
<view class="recharge-modal">
<view class="balance-card">
<text class="balance-label">账户余额</text>
<text class="balance-value">¥{{ user.balance.toFixed(2) }}</text>
</view>
<view class="modal-block">
<text class="modal-title">充值金额</text>
<input
class="amount-input"
type="digit"
v-model="rechargeAmount"
placeholder="可输入自定义充值金额"
/>
</view>
<view class="modal-block">
<text class="modal-title">支付方式</text>
<view class="pay-option" @click="paymentMethod = 'wechat'">
<view class="checkbox" :class="{ active: paymentMethod === 'wechat' }"></view>
<text class="pay-text">微信支付</text>
</view>
<text class="agreement">购买协议</text>
</view>
<button class="charge-btn" @click="confirmRecharge">立即充值</button>
<view class="charge-desc">
<text>充值说明</text>
<text>1. 账户充值仅限微信在线方式支付,充值金额实时到账;</text>
<text>2. 账户充值套餐赠送的金额即时到账;</text>
<text>3. 账户余额有效期:自充值日起至用完即止;</text>
<text>4. 若有其它疑问,可拨打客服电话400-000-1234。</text>
</view>
</view>
</u-popup>
<u-popup :show="showPopup" close-on-click-overlay round="10" mode="bottom" :safe-area-inset-bottom="false">
<view class="p-10 flex flex-col justify-center items-center">
<view class="my-10 flex justify-center items-center">
<u-image :src="qr" height="600rpx" width="509rpx" show-menu-by-longpress/>
</view>
<u-button shape="circle" type="primary" @click="closePopup">关闭</u-button>
</view>
</u-popup>
</view>
</template>
<script>
import {userInfoReq} from "@/api/user";
import {clearUserInfo, getUserInfo} from "@/util/user";
import {dictDataReq} from "@/api/common";
export default {
data() {
return {
user: {
nickname: '',
avatar: '',
coin: 0,
sendCoin: 0,
},
stats: [
{label: '收藏', value: 0, path: '/pages/user/collect'},
// {label: '赞过', value: 20},
{label: '评论过', value: 0}
],
menuList: [
{label: '客服入口', icon: 'server-fill', path: ''},
{label: '签到中心', icon: 'calendar', path: '/pages/user/coin'},
// {label: '金币中心', icon: 'red-packet-fill', path: '/pages/user/coin'},
{label: '意见反馈', icon: 'edit-pen', path: '/pages/user/feedback'},
{label: '设置(您还可以选择其他人物进行聊天)', icon: 'setting', path: '/pages/user/setting?noChat=true'},
// {label: '新的聊天', icon: 'chat', path: '/pages/chat/select'}
],
showRecharge: false,
rechargeAmount: '',
paymentMethod: 'wechat',
showPopup: false,
qr: '/static/service.png',
authing: true
}
},
methods: {
backHome() {
uni.switchTab({url: '/pages/index/index'})
},
async getDictList() {
const {data} = await dictDataReq({dictId: '171'})
this.authing = parseInt(data[0].dictDataCode) === 1
},
openRecharge() {
// this.showRecharge = true
uni.navigateTo({url: '/pages/user/coin'})
},
handleMenu(item) {
console.log(item)
if (item.path) {
uni.navigateTo({url: item.path})
} else {
console.log(item.label)
if (item.label === '客服入口')
this.showPopup = true
}
},
logout() {
clearUserInfo()
this.user = null
uni.showToast({title: '已退出', icon: 'success'})
this.$refs.Login.open()
},
confirmRecharge() {
if (!this.rechargeAmount) {
uni.showToast({title: '请输入金额', icon: 'none'})
return
}
uni.showToast({title: '充值成功', icon: 'success'})
this.showRecharge = false
this.rechargeAmount = ''
},
async getUserData(){
const {data} = await userInfoReq()
this.user = data
},
closePopup(){
this.showPopup = false
}
},
onShow() {
this.getDictList()
if (getUserInfo().token)
this.getUserData()
},
}
</script>
<style lang="scss" scoped>
.profile-page {
position: relative;
min-height: 100vh;
padding: 120rpx 30rpx 40rpx;
background: linear-gradient(180deg, #c6d5ff 0%, #eef0ff 45%, #fcfbff 100%);
box-sizing: border-box;
}
.profile-bg {
position: absolute;
inset: 0;
width: 100%;
height: 60%;
z-index: 0;
opacity: 0.35;
filter: blur(6rpx);
}
.profile-header {
position: relative;
z-index: 1;
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 30rpx;
}
.header-title {
font-size: 34rpx;
color: #fff;
font-weight: 600;
}
.profile-card {
position: relative;
z-index: 1;
background: rgba(255, 255, 255, 0.18);
border-radius: 34rpx;
padding: 30rpx;
color: #353750;
text-align: center;
box-shadow: inset 0 0 0 1rpx rgba(255, 255, 255, 0.25);
}
.profile-info {
display: flex;
align-items: center;
justify-content: center;
gap: 24rpx;
}
.avatar {
width: 140rpx;
height: 140rpx;
border-radius: 70rpx;
border: 4rpx solid rgba(255, 255, 255, 0.9);
}
.info-text {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 12rpx;
}
.user-name {
font-size: 34rpx;
font-weight: 600;
}
.badge {
display: inline-flex;
align-items: center;
gap: 8rpx;
background: rgba(255, 255, 255, 0.25);
border-radius: 30rpx;
padding: 6rpx 20rpx;
font-size: 24rpx;
}
.profile-desc {
margin-top: 20rpx;
color: rgba(255, 255, 255, 0.85);
font-size: 26rpx;
}
.profile-stats {
display: flex;
justify-content: space-around;
margin-top: 30rpx;
}
.stat-value {
font-size: 34rpx;
font-weight: 600;
}
.stat-label {
font-size: 24rpx;
margin-top: 8rpx;
opacity: 0.9;
}
.vip-card {
position: relative;
margin-top: 30rpx;
background: rgba(255, 255, 255, 0.8);
border-radius: 24rpx;
padding: 30rpx;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 20rpx 40rpx rgba(86, 107, 255, 0.15);
}
.vip-title {
font-size: 42rpx;
color: #f5a623;
font-weight: 600;
}
.vip-amount {
margin-top: 10rpx;
color: #606585;
font-size: 26rpx;
}
.highlight {
color: #ff4d4f;
font-weight: 600;
}
.vip-btn {
width: 180rpx;
height: 72rpx;
border-radius: 40rpx;
background: linear-gradient(120deg, #0f1f59, #1e31a6);
color: #fff;
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
font-weight: 500;
}
.menu-section {
margin-top: 30rpx;
background: rgba(255, 255, 255, 0.9);
border-radius: 24rpx;
box-shadow: 0 20rpx 40rpx rgba(118, 135, 255, 0.14);
}
.menu-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 30rpx;
border-bottom: 1rpx solid rgba(215, 217, 245, 0.8);
position: relative;
}
.menu-overlay {
position: absolute;
inset: 0;
}
.menu-item:last-child {
border-bottom: none;
}
.menu-left {
display: flex;
align-items: center;
gap: 20rpx;
}
.menu-text {
font-size: 28rpx;
color: #353750;
}
.logout-card {
margin-top: 30rpx;
background: rgba(233, 234, 255, 0.9);
border-radius: 24rpx;
padding: 30rpx;
display: flex;
align-items: center;
justify-content: space-between;
color: #353750;
}
.logout-text {
font-size: 28rpx;
}
.recharge-modal {
width: 600rpx;
background: #fff;
border-radius: 30rpx;
padding: 30rpx;
box-sizing: border-box;
}
.balance-card {
background: linear-gradient(120deg, #a979ff, #7160ff);
border-radius: 26rpx;
padding: 30rpx;
color: #fff;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
}
.balance-label {
font-size: 30rpx;
}
.balance-value {
font-size: 40rpx;
font-weight: 600;
}
.modal-block {
margin-bottom: 20rpx;
}
.modal-title {
font-size: 28rpx;
color: #4d4f6c;
margin-bottom: 10rpx;
display: block;
}
.amount-input {
width: 100%;
height: 80rpx;
border-radius: 20rpx;
background: #f4f5f9;
padding: 0 24rpx;
box-sizing: border-box;
font-size: 28rpx;
}
.pay-option {
display: flex;
align-items: center;
gap: 12rpx;
margin-top: 10rpx;
}
.checkbox {
width: 32rpx;
height: 32rpx;
border-radius: 10rpx;
border: 2rpx solid #b8bbd3;
}
.checkbox.active {
background: #32c26a;
border-color: #32c26a;
}
.pay-text {
font-size: 28rpx;
color: #3a3f62;
}
.agreement {
margin-top: 12rpx;
color: #3752b4;
font-size: 26rpx;
}
.charge-btn {
width: 100%;
height: 90rpx;
border-radius: 45rpx;
background: linear-gradient(120deg, #a979ff, #7160ff);
color: #fff;
font-size: 30rpx;
margin: 20rpx 0;
}
.charge-desc {
display: flex;
flex-direction: column;
gap: 6rpx;
font-size: 24rpx;
color: #8a8fae;
}
</style>