make page
This commit is contained in:
@@ -1,70 +1,102 @@
|
||||
<template>
|
||||
<view class="mine-content">
|
||||
<!-- 顶部区域 -->
|
||||
<view class="mine-top-panel" :style="{ paddingTop: getBavBarHeight() + 'px' }">
|
||||
<view class="user-info">
|
||||
<!-- 根据登录状态显示不同内容 -->
|
||||
<view v-if="isLoggedIn" class="user-logged-in">
|
||||
<image :src="userInfo.avatarUrl" class="avatar" mode="aspectFill" />
|
||||
<view class="user-logged-in-info">
|
||||
<text class="nickname">{{ userInfo.nickName }}</text>
|
||||
<text class="phone">19969024553</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-else class="user-not-logged-in">
|
||||
<image :src="defaultAvatarUrl" class="avatar" mode="aspectFill" />
|
||||
<button class="login-button" @tap="openPopup">点击登录</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="mine-middle-panel">
|
||||
<view class="mine-info-panel">
|
||||
<view>0.00</view>
|
||||
<view>我的余额</view>
|
||||
</view>
|
||||
|
||||
<view class="mine-info-panel">
|
||||
<view>0</view>
|
||||
<view>优惠卷</view>
|
||||
</view>
|
||||
|
||||
<view class="mine-info-panel">
|
||||
<view>0</view>
|
||||
<view>积分</view>
|
||||
</view>
|
||||
|
||||
<view class="mine-info-panel">
|
||||
<view>0</view>
|
||||
<view>我的收藏</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 登录弹窗 -->
|
||||
<uni-popup ref="popupRef" type="bottom" :safe-area="false">
|
||||
<view class="popup-container">
|
||||
<view class="popup-header">
|
||||
<text class="popup-title">登录授权</text>
|
||||
</view>
|
||||
|
||||
<view class="avatar-nickname">
|
||||
<button open-type="chooseAvatar" @chooseavatar="onChooseAvatar" class="avatar-selector">
|
||||
<image v-if="avatarUrl" :src="avatarUrl" class="avatar-preview" />
|
||||
<text v-else>获取头像</text>
|
||||
</button>
|
||||
<input
|
||||
class="nickname-input"
|
||||
type="nickname"
|
||||
v-model="nickname"
|
||||
placeholder="请输入昵称"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<button class="confirm-btn" @tap="confirmLogin">确认登录</button>
|
||||
</view>
|
||||
</uni-popup>
|
||||
</view>
|
||||
<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">
|
||||
<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>
|
||||
|
||||
<!-- My Creations -->
|
||||
<view class="section-title">我的创作</view>
|
||||
<view class="menu-group">
|
||||
<view class="menu-item" @tap="navTo('greetings')">
|
||||
<view class="icon-box red-bg"><text>🧧</text></view>
|
||||
<text class="menu-text">我的新春祝福</text>
|
||||
<text class="arrow">›</text>
|
||||
</view>
|
||||
<view class="menu-item" @tap="navTo('videos')">
|
||||
<view class="icon-box orange-bg"><text>📹</text></view>
|
||||
<text class="menu-text">我的拜年视频</text>
|
||||
<text class="arrow">›</text>
|
||||
</view>
|
||||
<view class="menu-item" @tap="navTo('decorations')">
|
||||
<view class="icon-box pink-bg"><text>☺</text></view>
|
||||
<text class="menu-text">我的头像挂饰</text>
|
||||
<text class="arrow">›</text>
|
||||
</view>
|
||||
<view class="menu-item" @tap="navTo('frames')">
|
||||
<view class="icon-box yellow-bg"><text>🖼</text></view>
|
||||
<text class="menu-text">我的马年头像框</text>
|
||||
<view class="new-badge">NEW</view>
|
||||
<text class="arrow">›</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- History -->
|
||||
<view class="section-title">历史记录</view>
|
||||
<view class="menu-group">
|
||||
<view class="menu-item" @tap="navTo('history')">
|
||||
<view class="icon-box gray-bg"><text>🕒</text></view>
|
||||
<text class="menu-text">新春祝福记录</text>
|
||||
<text class="arrow">›</text>
|
||||
</view>
|
||||
<view class="menu-item" @tap="navTo('archive')">
|
||||
<view class="icon-box gray-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('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>
|
||||
|
||||
<!-- Bottom Spacer for TabBar -->
|
||||
<view style="height: 120rpx;"></view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<!-- Login Popup -->
|
||||
<LoginPopup ref="loginPopupRef" @logind="handleLogind"/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@@ -74,230 +106,261 @@ import { getPlatformProvider, getBavBarHeight } from '@/utils/system'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
import { apiLogin } from '@/api/auth.js'
|
||||
|
||||
import LoginPopup from '@/components/LoginPopup/LoginPopup.vue'
|
||||
|
||||
const userStore = useUserStore()
|
||||
const popupRef = ref(null)
|
||||
const loginPopupRef = ref(null)
|
||||
|
||||
// 用户输入的临时信息
|
||||
const avatarUrl = ref('')
|
||||
const nickname = ref('')
|
||||
// Navigation Bar
|
||||
const navBarTop = ref(20)
|
||||
const navBarHeight = ref(44)
|
||||
|
||||
// User Info
|
||||
const defaultAvatarUrl = 'https://file.lihailezzc.com/resource/d9b329082b32f8305101f708593a4882.png'
|
||||
|
||||
// 从store获取用户信息(改为计算属性)
|
||||
const userInfo = computed(() => ({
|
||||
nickName: userStore.userInfo.nickName || '未登录',
|
||||
nickName: userStore.userInfo.nickName || '点击登录',
|
||||
avatarUrl: userStore.userInfo.avatarUrl || defaultAvatarUrl
|
||||
}))
|
||||
|
||||
// 判断用户是否已登录
|
||||
const isLoggedIn = computed(() => !!userStore.userInfo.nickName)
|
||||
|
||||
// 默认头像
|
||||
const defaultAvatarUrl = 'https://file.lihailezzc.com/resource/d9b329082b32f8305101f708593a4882.png'
|
||||
|
||||
// 获取状态栏高度
|
||||
const bavBarHeight = ref(0)
|
||||
|
||||
onMounted(() => {
|
||||
// 确保高度值在组件挂载后获取
|
||||
bavBarHeight.value = getBavBarHeight()
|
||||
const sysInfo = uni.getSystemInfoSync()
|
||||
navBarTop.value = sysInfo.statusBarHeight
|
||||
// Assuming standard nav bar height
|
||||
navBarHeight.value = 44
|
||||
})
|
||||
|
||||
const openPopup = () => {
|
||||
popupRef.value.open()
|
||||
const handleUserClick = () => {
|
||||
if (!isLoggedIn.value) {
|
||||
loginPopupRef.value.open()
|
||||
} else {
|
||||
// Navigate to profile details or do nothing
|
||||
}
|
||||
}
|
||||
|
||||
const onChooseAvatar = (e) => {
|
||||
avatarUrl.value = e.detail.avatarUrl
|
||||
const handleLogind = async () => {
|
||||
// Logic after successful login if needed
|
||||
}
|
||||
|
||||
const confirmLogin = async () => {
|
||||
if (!nickname.value || !avatarUrl.value) {
|
||||
return uni.showToast({ title: '请填写完整信息', icon: 'none' })
|
||||
}
|
||||
|
||||
try {
|
||||
const platform = getPlatformProvider()
|
||||
if (platform === 'mp-weixin') {
|
||||
const code = await wxLogin()
|
||||
console.log('准备登录:', { code, nickname: nickname.value, avatarUrl: avatarUrl.value })
|
||||
// console.log('准备登录:', { code, nickname: nickname.value, avatarUrl: 'http://tmp/HXhtcEwQ5A3B58476c91ba545ab67c6bf9c67d9c2559.jpeg' })
|
||||
|
||||
const fileKeyRes = await uni.uploadFile({
|
||||
url: 'https://apis.lihailezzc.com/api/common/upload',
|
||||
filePath: avatarUrl.value,
|
||||
name: 'file', // 和后端接收文件字段名一致
|
||||
header: {
|
||||
'x-app-id': '6846f093fdf841f6189ef0b5',
|
||||
},
|
||||
})
|
||||
if(fileKeyRes.statusCode < 400) {
|
||||
const keyJson = JSON.parse(fileKeyRes.data)
|
||||
const url = `https://file.lihailezzc.com/${keyJson?.data.key}`
|
||||
const loginRes = await apiLogin({ code, nickname: nickname.value, avatarUrl: url })
|
||||
// 保存用户信息到store
|
||||
userStore.setUserInfo({
|
||||
nickName: nickname.value,
|
||||
avatarUrl: avatarUrl.value,
|
||||
})
|
||||
|
||||
userStore.setToken(loginRes.token)
|
||||
|
||||
uni.showToast({ title: '登录成功', icon: 'success' })
|
||||
popupRef.value.close()
|
||||
|
||||
// 重置临时变量
|
||||
avatarUrl.value = ''
|
||||
nickname.value = ''
|
||||
} else {
|
||||
throw Error('获取失败')
|
||||
}
|
||||
|
||||
}
|
||||
} catch (err) {
|
||||
uni.showToast({ title: '登录失败', icon: 'none' })
|
||||
console.error(err)
|
||||
}
|
||||
const navTo = (page) => {
|
||||
uni.showToast({ title: '功能开发中', icon: 'none' })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.mine-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
background: #F9F6F2;
|
||||
|
||||
button {
|
||||
border: none;
|
||||
outline: none;
|
||||
background-color: transparent;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
line-height: normal;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
button::after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.mine-top-panel{
|
||||
width: 100vw;
|
||||
height: 500rpx;
|
||||
background-color: #beecd8;
|
||||
border-bottom-left-radius: 50% 50rpx;
|
||||
border-bottom-right-radius: 50% 50rpx;
|
||||
overflow: hidden;
|
||||
.user-info{
|
||||
padding-left: 40rpx;
|
||||
image {
|
||||
width: 150rpx;
|
||||
height: 150rpx;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.user-logged-in{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.user-logged-in-info{
|
||||
padding-left: 20rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.nickname{
|
||||
color: #1a1a1a;
|
||||
font-weight: 800;
|
||||
}
|
||||
.phone{
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
}
|
||||
.user-not-logged-in{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.login-button{
|
||||
padding-left: 20rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.mine-middle-panel{
|
||||
width: 90vw;
|
||||
height: 200rpx;
|
||||
background-color: #fff;
|
||||
margin-top: -100rpx;
|
||||
border-radius: 20rpx; /* 四角小圆角 */
|
||||
box-shadow: 0 8rpx 16rpx rgba(0, 0, 0, 0.05); /* 柔和阴影 */
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding-left: 20rpx;
|
||||
padding-right: 20rpx;
|
||||
.mine-info-panel{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 23%;
|
||||
}
|
||||
}
|
||||
<style lang="scss" scoped>
|
||||
.mine-page {
|
||||
min-height: 100vh;
|
||||
background: #f9f9f9;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
/* 弹窗样式 */
|
||||
.popup-container {
|
||||
background-color: #fff;
|
||||
padding: 40rpx 30rpx 60rpx;
|
||||
border-top-left-radius: 30rpx;
|
||||
border-top-right-radius: 30rpx;
|
||||
|
||||
.popup-header {
|
||||
text-align: center;
|
||||
margin-bottom: 30rpx;
|
||||
.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;
|
||||
}
|
||||
|
||||
.popup-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
.content-scroll {
|
||||
height: 100vh;
|
||||
}
|
||||
.content-wrap {
|
||||
padding: 20rpx 30rpx 40rpx;
|
||||
}
|
||||
|
||||
.avatar-nickname {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-bottom: 30rpx;
|
||||
/* 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;
|
||||
}
|
||||
|
||||
.avatar-selector {
|
||||
width: 145rpx;
|
||||
height: 145rpx;
|
||||
border-radius: 50%;
|
||||
font-size: 26rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 20rpx;
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
.avatar-preview {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.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;
|
||||
}
|
||||
|
||||
.nickname-input {
|
||||
width: 80%;
|
||||
border: 1rpx solid #ccc;
|
||||
border-radius: 20rpx;
|
||||
padding: 20rpx;
|
||||
font-size: 26rpx;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
/* Section Title */
|
||||
.section-title {
|
||||
font-size: 26rpx;
|
||||
font-weight: bold;
|
||||
color: #999;
|
||||
margin-bottom: 20rpx;
|
||||
padding-left: 10rpx;
|
||||
}
|
||||
|
||||
.confirm-btn {
|
||||
background-color: #07c160;
|
||||
color: white;
|
||||
font-size: 30rpx;
|
||||
border-radius: 50rpx;
|
||||
padding: 20rpx 0;
|
||||
width: 100%;
|
||||
}
|
||||
/* 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 {
|
||||
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>
|
||||
Reference in New Issue
Block a user