Files
taimed-international-app/pages/user/index.vue

419 lines
8.7 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="user-page" :style="{ paddingTop: getNotchHeight() + 30 + 'px' }">
<!-- 设置图标 -->
<view class="settings-icon" :style="{ top: getNotchHeight() + 30 + 'px' }" @click="goSettings">
<wd-icon name="setting1" size="24px" color="#666" />
<text>{{ $t('user.settings') }}</text>
</view>
<!-- 用户信息区域 -->
<view class="user-info-section">
<view class="user-info">
<image :src="userInfo.avatar || defaultAvatar" class="avatar" @click="goProfile" />
<view class="user-details">
<text class="nickname">{{ userInfo.nickname || $t('user.notSet') }}</text>
<text v-if="userInfo.email" class="email">{{ userInfo.email }}</text>
</view>
</view>
</view>
<!-- VIP订阅卡片 -->
<view class="vip-card-section">
<view class="vip-card">
<view class="vip-card-title">{{ $t('user.vip') }}</view>
<view class="vip-card-content">
<view class="vip-item-list">
<view v-if="vipInfo?.length > 0" v-for="vip in vipInfo">{{ vipTypeDict[vip.type] }}{{ parseTime(vip.endTime, '{y}-{m}-{d}') }} 截止</view>
<view v-else>办理课程VIP畅享更多权益</view>
</view>
<wd-button v-if="vipInfo?.length > 0" plain type="primary" size="small" @click="goCourseVipSub">{{ $t('vip.renewal') }}</wd-button>
<wd-button v-else plain type="primary" size="small" @click="goCourseVipSub">{{ $t('vip.openVip') }}</wd-button>
</view>
<view class="vip-card-content">
<view class="vip-item-list">
<view v-if="vipInfoEbook?.length > 0" v-for="vip in vipInfoEbook">电子书VIP{{ vipTypeDict[vip.type] }}{{ parseTime(vip.endTime, '{y}-{m}-{d}') }} 截止</view>
<view v-else>办理电子书VIP畅享更多权益</view>
</view>
<wd-button v-if="!vipInfoEbook?.length" plain type="primary" size="small" @click="goSubscribe">{{ $t('vip.openVip') }}</wd-button>
</view>
</view>
</view>
<!-- 我的资产 -->
<view class="assets-card-section wallet-section">
<view class="assets-card wallet_l">
<view class="assets">
<view @click="goVirtualList">
<view class="assets_row">{{ t('global.coin') }}</view>
<view>{{userInfo.peanutCoin ?? 1}}</view>
</view>
<view @click="goPointsList">
<view class="assets_row">积分</view>
<view>{{userInfo.jf ?? 1}}</view>
</view>
<!-- <view>
<view class="assets_row">优惠卷</view>
<view>0</view>
</view> -->
</view>
<view class="chong_btn" @click="goRecharge"> </view>
<!-- <text class="wallet_title">{{$t('my.coin')}}<uni-icons type="help" size="19" color="#666"></uni-icons></text>
<text class="wallet_count">{{userMes.peanutCoin}}</text> -->
</view>
</view>
<!-- 功能菜单列表 -->
<view class="menu-section">
<wd-cell-group border class="menu-list">
<wd-cell v-for="item in menuItems" :key="item.id" :title="item.name" :label="item.desc" is-link @click="handleMenuClick(item)" />
</wd-cell-group>
</view>
</view>
</template>
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { useUserStore } from '@/stores/user'
import { useSysStore } from '@/stores/sys'
import { getUserInfo, getVipInfo } from '@/api/modules/user'
import type { IVipInfo } from '@/types/user'
import { getNotchHeight } from '@/utils/system'
import { parseTime } from '@/utils/index'
import { t } from '@/utils/i18n'
import { onShow } from '@dcloudio/uni-app'
const userStore = useUserStore()
const sysStore = useSysStore()
// 默认头像
const defaultAvatar = '/static/home_icon.png'
// 用户信息
const userInfo = computed(() => userStore.userInfo)
// VIP信息
const vipInfo = computed(() => userStore.userVips)
const vipInfoEbook = computed(() => userStore.userEbookVip)
// VIP类型字典
const vipTypeDict = sysStore.vipTypeDict
// 平台信息
const platform = ref('')
// 菜单项
const menuItems = computed(() => [
{
id: 1,
name: t('user.myOrders'),
url: '/pages/user/order/index',
type: 'pageJump'
},
{
id: 2,
name: t('user.myBooklist'),
url: '/pages/user/myBook/index',
type: 'pageJump'
},
{
id: 3,
name: t('user.profile'),
url: '/pages/user/profile/index',
type: 'pageJump'
},
{
id: 4,
name: t('user.about'),
url: '/pages/user/about/index',
type: 'pageJump'
},
{
id: 5,
name: t('user.feedback'),
url: '/pages/user/feedback/index',
type: 'pageJump'
},
{
id: 6,
name: t('user.dataMigrate'),
url: '/pages/user/migrate/index',
desc: t('user.migrateSubtitle'),
type: 'pageJump'
}
])
/**
* 获取平台信息
*/
const getPlatform = () => {
const systemInfo = uni.getSystemInfoSync()
platform.value = systemInfo.platform === 'android' ? 'android' : 'ios'
}
/**
* 获取数据
*/
const getData = async () => {
// 获取用户信息
const userInfoRes = await getUserInfo()
if (userInfoRes.result) {
userStore.setUserInfo(userInfoRes.result)
}
}
/**
* 跳转到设置页面
*/
const goSettings = () => {
uni.navigateTo({
url: '/pages/user/settings/index'
})
}
/**
* 跳转到个人资料页面
*/
const goProfile = () => {
uni.navigateTo({
url: '/pages/user/profile/index'
})
}
/**
* 跳转到电子书vip订阅页面
*/
const goSubscribe = () => {
uni.navigateTo({
url: '/pages/vip/book'
})
}
/**
* 跳转到课程vip订阅页面
*/
const goCourseVipSub = () => {
uni.navigateTo({
url: '/pages/vip/course'
})
}
/**
* 处理菜单点击
*/
const handleMenuClick = (item : any) => {
switch (item.type) {
case 'pageJump':
uni.navigateTo({
url: item.url
})
break
case 'switchTab':
uni.switchTab({
url: item.url
})
break
}
}
/**
* 跳转充值页面
*/
const goRecharge = () => {
uni.navigateTo({
url: '/pages/user/recharge/index'
})
}
/**
* 跳转虚拟币页面
*/
const goVirtualList = () => {
uni.navigateTo({
url: '/pages/user/virtual/index'
})
}
/**
* 跳转积分列表
*/
const goPointsList = () => {
uni.navigateTo({
url: '/pages/user/points/index'
})
}
onShow(() => {
getData()
})
onMounted(() => {
getPlatform()
})
</script>
<style lang="scss" scoped>
$theme-color: #54a966;
.user-page {
min-height: 100vh;
background-color: #f7faf9;
}
.settings-icon {
position: absolute;
right: 20px;
z-index: 2;
display: flex;
flex-direction: column;
align-items: center;
line-height: 1.2;
text {
display: block;
font-size: 28rpx;
color: #333;
}
}
.user-info-section {
padding: 0 30rpx;
margin-bottom: 50rpx;
}
.user-info {
display: flex;
align-items: center;
.avatar {
width: 100rpx;
height: 100rpx;
border-radius: 100rpx;
margin-right: 30rpx;
}
.user-details {
flex: 1;
.nickname {
display: block;
font-size: 38rpx;
font-weight: bold;
color: #333;
margin-bottom: 10rpx;
}
.email {
display: block;
font-size: 28rpx;
color: #333;
margin-bottom: 10rpx;
}
.vip-time {
display: block;
font-size: 28rpx;
color: #333;
}
}
}
// vip 卡片
.vip-card-section {
padding: 0 20rpx;
margin-bottom: 20rpx;
.vip-card {
background: linear-gradient(135deg, #3E7EF5 0%, #9134EA 100%);
border-radius: 15rpx;
padding: 26rpx 30rpx 10rpx;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
.vip-card-title {
font-size: 32rpx;
color: #fff;
font-weight: bold;
margin-bottom: 20rpx;
}
.vip-card-content {
display: flex;
align-items: center;
justify-content: space-between;
background-color: rgba(255, 255, 255, 0.2);
border-radius: 8px;
padding: 30rpx;
margin-bottom: 20rpx;
}
.vip-item-list {
font-size: 28rpx;
color: #fff;
font-weight: bold;
}
}
}
.assets-card-section {
padding: 0 20rpx;
margin-bottom: 20rpx;
}
.assets-card {
background: #fff;
border-radius: 15rpx;
padding: 40rpx;
display: flex;
align-items: center;
justify-content: space-between;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
.assets-info {
text-align: center;
.label {
display: block;
font-size: 32rpx;
color: #333;
margin-bottom: 10rpx;
}
.value {
display: block;
font-size: 30rpx;
color: $theme-color;
}
}
}
.menu-section {
padding: 20rpx 20rpx;
}
.menu-list {
background: #fff;
border-radius: 15rpx;
overflow: hidden;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
}
.chong_btn {
font-size: 26rpx;
display: block;
border-radius: 50rpx;
color: #fffbf6;
padding: 10rpx 32rpx;
background: #007bff;
}
.assets {
display: flex;
flex: 1;
justify-content: space-around;
text-align: center;
transform: translateX(-20px);
.assets_row {
margin-bottom: 20rpx;
}
}
</style>