image:替换图片

This commit is contained in:
zheng020 2026-05-15 21:39:21 +08:00
parent e4ce006de3
commit 6252be4d75
7 changed files with 373 additions and 302 deletions

View File

@ -114,6 +114,19 @@
</view> -->
<!-- </view> -->
<!-- 完整链上哈希显示遮罩层 -->
<view v-if="showTxHash" class="txhash-mask" @tap="showTxHash = false">
<view class="txhash-popup" @tap.stop>
<view class="txhash-popup-header">
<text class="txhash-popup-title">链上哈希</text>
<view class="txhash-popup-close" @tap="showTxHash = false">
<image class="close-icon" src="/static/icon/hide.png" mode="aspectFit"></image>
</view>
</view>
<text class="txhash-popup-content" selectable @longpress="copyHash">{{ displayTxHash }}</text>
</view>
</view>
<!-- 链上数据 -->
<view class="chain-section">
<image class="chain-logo" src="/static/logo/APPLOGO.png" mode="aspectFit"></image>
@ -143,8 +156,7 @@
<view class="chain-row">
<text class="chain-label">链上哈希</text>
<view class="chain-value-wrap">
<text class="chain-value chain-hash" @longpress="copyHash">{{ showTxHash ? displayTxHash
: hiddenTxHash }}</text>
<text class="chain-value chain-hash" @longpress="copyHash">{{ hiddenTxHash }}</text>
<view class="toggle-btn" @tap="showTxHash = !showTxHash">
<image class="toggle-icon" :src="showTxHash ? '/static/icon/show.png' : '/static/icon/hide.png'" mode="aspectFit"></image>
</view>
@ -1026,6 +1038,62 @@ onUnmounted(() => {
color: rgba(255, 255, 255, 0.75);
}
/* 链上哈希遮罩层 */
.txhash-mask {
position: fixed;
left: 0;
right: 0;
bottom: 24rpx;
z-index: 999;
display: flex;
align-items: center;
justify-content: center;
padding: 0 64rpx;
}
.txhash-popup {
border-radius: 24rpx;
padding: 32rpx;
background: url('/static/rank/activity-support-icon/beijingkuang.png') no-repeat center center;
background-size: 105% 120%;
}
.txhash-popup-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24rpx;
}
.txhash-popup-title {
font-size: 32rpx;
font-weight: bold;
color: #fff;
font-family: 'yt', sans-serif;
}
.txhash-popup-close {
padding: 8rpx;
}
.close-icon {
width: 40rpx;
height: 40rpx;
}
.txhash-popup-content {
display: block;
font-size: 26rpx;
color: #fff;
font-family: 'yt', sans-serif;
word-break: break-all;
line-height: 1.6;
background-color: rgba(0, 0, 0, 0.2);
padding: 20rpx;
border-radius: 12rpx;
}
/* 点赞用户列表 */
.like-users-list {
display: flex;

View File

@ -56,7 +56,8 @@ const navItems = [
name: '铸爱',
icon: '/static/icon/castlove.png',
angle: 90.01, //
path: '/pages/castlove/mall'
path: '/pages/castlove/mall',
rotate: '8deg'
},
{
name: '星城',
@ -107,7 +108,8 @@ const getNavIconStyle = (index) => {
return {
'--x': `${x}rpx`,
'--y': `${y}rpx`,
'--delay': `${delay}s`
'--delay': `${delay}s`,
'--rotate': item.rotate || '0deg'
};
};
@ -237,6 +239,7 @@ const handleNavClick = (index) => {
transition: transform 0.3s ease, filter 0.3s ease;
filter: drop-shadow(0 6rpx 16rpx rgba(0, 0, 0, 0.4)) drop-shadow(0 2rpx 8rpx rgba(0, 0, 0, 0.2));
position: relative;
transform: rotate(var(--rotate));
}
/* 底部倒影效果 */

View File

@ -7,251 +7,268 @@
<!-- 上半部分用户信息卡片 -->
<view class="top-section">
<!-- 蒙层 -->
<view class="background-overlay"></view>
<!-- 蒙层 -->
<view class="background-overlay"></view>
<!-- Header组件 -->
<image class="close-icon-img" src="/static/starbookcontent/tuichu.png" mode="aspectFit" @tap="goBack"></image>
<!-- Header组件 -->
<image class="close-icon-img" src="/static/starbookcontent/tuichu.png" mode="aspectFit" @tap="goBack">
</image>
<!-- 用户信息卡片 -->
<view class="user-info-card">
<!-- 上半部分头像和用户信息左右布局 -->
<view class="user-main-info">
<view @tap="handleAvatarClick" class="avatar-container">
<Avatar :key="avatarKey" :userId="uid" :size="260" :borderWidth="6" :showLevel="true"
:level="fanLevel" :avatarUrl="userAvatarUrl" />
</view>
<view class="user-text-info">
<!-- 昵称 -->
<view class="info-row">
<text style="font-size: 48rpx;text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.3);" class="info-value">{{ nickname }}</text>
<!-- 用户信息卡片 -->
<view class="user-info-card">
<!-- 上半部分头像和用户信息左右布局 -->
<view class="user-main-info">
<view @tap="handleAvatarClick" class="avatar-container">
<Avatar :key="avatarKey" :userId="uid" :size="260" :borderWidth="6" :showLevel="true"
:level="fanLevel" :avatarUrl="userAvatarUrl" />
</view>
<!-- DID -->
<view class="info-row">
<text class="info-label">DID</text>
<text class="info-value uid-value">{{ uid }}</text>
<view class="info-btn" @tap="copyUid">查看</view>
</view>
<!-- 链上地址 -->
<view class="info-row">
<text class="info-label">链上地址</text>
<text class="info-value address-value">{{ displayAddress }}</text>
<view class="info-btn" @tap="copyAddress">查看</view>
</view>
<!-- 手机号 -->
<view class="info-row">
<text class="info-label">注册手机</text>
<text class="info-value" v-if="displayMobile">{{ displayMobile }}</text>
<text class="info-value" v-else>未绑定</text>
<view class="info-btn" @tap="handleViewMobile">查看</view>
<view class="user-text-info">
<!-- 昵称 -->
<view class="info-row">
<text style="font-size: 48rpx;text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.3);"
class="info-value">{{ nickname }}</text>
</view>
<!-- DID -->
<view class="info-row">
<text class="info-label">DID</text>
<view class="address-row">
<text class="info-value uid-value">{{ uid }}</text>
<!-- <image class="toggle-icon"
:src="showBlockNumber ? '/static/icon/show.png' : '/static/icon/hide.png'"
mode="aspectFit" @tap="copyUid"></image> -->
</view>
</view>
<!-- 链上地址 -->
<view class="info-row">
<text class="info-label">链上地址</text>
<view class="address-row">
<text class="info-value address-value" @longpress="copyAddress">{{ displayAddress }}</text>
<view class="toggle-btn" @tap="showBlockNumber = !showBlockNumber">
<image class="toggle-icon" :src="showBlockNumber ? '/static/icon/show.png' : '/static/icon/hide.png'" mode="aspectFit"></image>
</view>
</view>
</view>
<!-- 手机号 -->
<view class="info-row">
<text class="info-label">注册手机</text>
<view class="address-row">
<text class="info-value" v-if="mobile">{{ displayMobile }}</text>
<view class="toggle-btn" @tap="toggleMobileDisplay">
<image class="toggle-icon" :src="showMobile ? '/static/icon/show.png' : '/static/icon/hide.png'" mode="aspectFit"></image>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 下半部分白色背景区域 -->
<view class="bottom-section">
<view class="content-area">
<!-- 我的资产 -->
<view class="section-bg" style="padding-top: 0;">
<view class="section-title">我的资产</view>
<view class="assets-grid">
<view class="asset-card" @tap="handleAssetClick('myWorks')">
<image class="asset-icon" src="/static/icon/dazi.png" mode="aspectFit"></image>
<text class="asset-text">个人中心</text>
<!-- <text class="arrow"></text> -->
</view>
<view class="asset-card" @tap="handleAssetClick('starbook')">
<image class="asset-icon" src="/static/icon/starbook.png" mode="aspectFit"></image>
<text class="asset-text">我的星册</text>
<!-- <text class="arrow"></text> -->
<!-- 下半部分白色背景区域 -->
<view class="bottom-section">
<view class="content-area">
<!-- 我的资产 -->
<view class="section-bg" style="padding-top: 0;">
<view class="section-title">我的资产</view>
<view class="assets-grid">
<view class="asset-card" @tap="handleAssetClick('myWorks')">
<image class="asset-icon" src="/static/icon/dazi.png" mode="aspectFit"></image>
<text class="asset-text">个人中心</text>
<!-- <text class="arrow"></text> -->
</view>
<view class="asset-card" @tap="handleAssetClick('starbook')">
<image class="asset-icon" src="/static/icon/starbook.png" mode="aspectFit"></image>
<text class="asset-text">我的星册</text>
<!-- <text class="arrow"></text> -->
</view>
</view>
</view>
</view>
<!-- 服务与工具 -->
<view class="section-bg">
<view class="section-title">服务与工具</view>
<view class="service-buttons-container">
<!-- 新手指引入口 -->
<view class="service-button" @tap="handleGuideClick">
<image class="service-icon" src="/static/icon/onboarding.png" mode="aspectFit"></image>
<text class="service-text">新手指引</text>
<text v-if="guideClaimableCount > 0" class="guide-badge">{{ guideClaimableCount }}</text>
</view>
<view class="service-button" @tap="handleChangeNickname">
<image class="service-icon" src="/static/icon/edit-nickname.png" mode="aspectFit"></image>
<text class="service-text">修改昵称</text>
</view>
<view class="service-button" @tap="handleChangePassword">
<image class="service-icon" src="/static/icon/edit-password.png" mode="aspectFit"></image>
<text class="service-text">修改密码</text>
</view>
<!-- <view class="service-button" @tap="handleSwitchRole">
<!-- 服务与工具 -->
<view class="section-bg">
<view class="section-title">服务与工具</view>
<view class="service-buttons-container">
<!-- 新手指引入口 -->
<view class="service-button" @tap="handleGuideClick">
<image class="service-icon" src="/static/icon/onboarding.png" mode="aspectFit"></image>
<text class="service-text">新手指引</text>
<text v-if="guideClaimableCount > 0" class="guide-badge">{{ guideClaimableCount
}}</text>
</view>
<view class="service-button" @tap="handleChangeNickname">
<image class="service-icon" src="/static/icon/edit-nickname.png" mode="aspectFit">
</image>
<text class="service-text">修改昵称</text>
</view>
<view class="service-button" @tap="handleChangePassword">
<image class="service-icon" src="/static/icon/edit-password.png" mode="aspectFit">
</image>
<text class="service-text">修改密码</text>
</view>
<!-- <view class="service-button" @tap="handleSwitchRole">
<image class="service-icon" src="/static/icon/switch-account.png" mode="aspectFit"></image>
<text class="service-text">添加身份</text>
</view> -->
<view class="service-button" @tap="handleDeleteAccount">
<image class="service-icon" src="/static/icon/logout.png" mode="aspectFit"></image>
<text class="service-text">注销账号</text>
</view>
</view>
</view>
</view>
<!-- 修改昵称弹窗 -->
<view class="nickname-modal" v-if="showNicknameModal" @tap="closeNicknameModal">
<view class="modal-content" @tap.stop>
<view class="modal-title">修改昵称</view>
<input class="modal-input" v-model="newNickname" placeholder="请输入新昵称" maxlength="20" />
<view class="modal-buttons">
<button class="modal-btn-cancel" @tap="closeNicknameModal">取消</button>
<button class="modal-btn-confirm" @tap="confirmChangeNickname">确认</button>
</view>
</view>
</view>
<!-- 修改密码弹窗 -->
<view class="password-modal" v-if="showPasswordModal" @tap="closePasswordModal">
<view class="modal-content" @tap.stop>
<view class="modal-title">修改密码</view>
<!-- 旧密码输入框 -->
<view class="modal-password-wrapper">
<input class="modal-password-input" :type="showOldPassword ? 'text' : 'password'"
v-model="oldPassword" placeholder="请输入旧密码" placeholder-class="input-placeholder" />
<view class="modal-eye-icon" @click="showOldPassword = !showOldPassword">
<text class="eye-text">{{ showOldPassword ? '👁️' : '👁️‍🗨️' }}</text>
</view>
</view>
<!-- 新密码输入框 -->
<view class="modal-password-wrapper">
<input class="modal-password-input" :type="showNewPassword ? 'text' : 'password'"
v-model="newPassword" placeholder="请输入新密码" placeholder-class="input-placeholder" />
<view class="modal-eye-icon" @click="showNewPassword = !showNewPassword">
<text class="eye-text">{{ showNewPassword ? '👁️' : '👁️‍🗨️' }}</text>
</view>
</view>
<view class="modal-buttons">
<button class="modal-btn-cancel" @tap="closePasswordModal">取消</button>
<button class="modal-btn-confirm" @tap="confirmChangePassword">确认</button>
</view>
</view>
</view>
<!-- 添加身份弹窗 -->
<view class="add-identity-modal" v-if="showAddIdentityModal" @tap="closeAddIdentityModal">
<view class="modal-content" @tap.stop>
<view class="modal-title">添加身份</view>
<view class="modal-subtitle">选择您喜欢的明星成为TA的粉丝</view>
<!-- 明星选择列表 -->
<view class="star-list">
<view v-for="star in fanIdentitiesList" :key="star.star_id" class="star-item"
:class="{ 'star-item-selected': selectedStarId === star.star_id }"
@tap="selectStar(star.star_id)">
<view class="star-info">
<text class="star-name">{{ star.name }}</text>
<text class="star-tag" v-if="star.tag">{{ star.tag }}</text>
</view>
<view class="star-radio">
<view v-if="selectedStarId === star.star_id" class="star-radio-checked"></view>
<view class="service-button" @tap="handleDeleteAccount">
<image class="service-icon" src="/static/icon/logout.png" mode="aspectFit"></image>
<text class="service-text">注销账号</text>
</view>
</view>
</view>
</view>
<!-- 昵称输入框 -->
<input class="modal-input" v-model="newIdentityNickname" placeholder="请输入您的新昵称" maxlength="20" />
<view class="modal-buttons">
<button class="modal-btn-cancel" @tap="closeAddIdentityModal">取消</button>
<button class="modal-btn-confirm" @tap="confirmAddIdentity">确认</button>
<!-- 修改昵称弹窗 -->
<view class="nickname-modal" v-if="showNicknameModal" @tap="closeNicknameModal">
<view class="modal-content" @tap.stop>
<view class="modal-title">修改昵称</view>
<input class="modal-input" v-model="newNickname" placeholder="请输入新昵称" maxlength="20" />
<view class="modal-buttons">
<button class="modal-btn-cancel" @tap="closeNicknameModal">取消</button>
<button class="modal-btn-confirm" @tap="confirmChangeNickname">确认</button>
</view>
</view>
</view>
</view>
<!-- 身份切换下拉列表 -->
<view class="identity-dropdown-modal" v-if="showIdentityDropdown" @tap="closeIdentityDropdown">
<view class="identity-dropdown-content" @tap.stop>
<view class="identity-dropdown-title">切换粉丝身份</view>
<view class="identity-list">
<view v-for="identity in myFanIdentities" :key="identity.star_id" class="identity-item" :class="{
'identity-item-active': identity.star_id === currentStarId,
'identity-item-disabled': identity.star_id === currentStarId
}" @tap="handleSwitchIdentity(identity.star_id)">
<view class="identity-info">
<view class="identity-main">
<text class="identity-star-name">{{ identity.star_name }}</text>
<text class="identity-star-tag">{{ identity.star_tag }}</text>
<!-- 修改密码弹窗 -->
<view class="password-modal" v-if="showPasswordModal" @tap="closePasswordModal">
<view class="modal-content" @tap.stop>
<view class="modal-title">修改密码</view>
<!-- 旧密码输入框 -->
<view class="modal-password-wrapper">
<input class="modal-password-input" :type="showOldPassword ? 'text' : 'password'"
v-model="oldPassword" placeholder="请输入旧密码" placeholder-class="input-placeholder" />
<view class="modal-eye-icon" @click="showOldPassword = !showOldPassword">
<text class="eye-text">{{ showOldPassword ? '👁️' : '👁️‍🗨️' }}</text>
</view>
</view>
<!-- 新密码输入框 -->
<view class="modal-password-wrapper">
<input class="modal-password-input" :type="showNewPassword ? 'text' : 'password'"
v-model="newPassword" placeholder="请输入新密码" placeholder-class="input-placeholder" />
<view class="modal-eye-icon" @click="showNewPassword = !showNewPassword">
<text class="eye-text">{{ showNewPassword ? '👁️' : '👁️‍🗨️' }}</text>
</view>
</view>
<view class="modal-buttons">
<button class="modal-btn-cancel" @tap="closePasswordModal">取消</button>
<button class="modal-btn-confirm" @tap="confirmChangePassword">确认</button>
</view>
</view>
</view>
<!-- 添加身份弹窗 -->
<view class="add-identity-modal" v-if="showAddIdentityModal" @tap="closeAddIdentityModal">
<view class="modal-content" @tap.stop>
<view class="modal-title">添加身份</view>
<view class="modal-subtitle">选择您喜欢的明星成为TA的粉丝</view>
<!-- 明星选择列表 -->
<view class="star-list">
<view v-for="star in fanIdentitiesList" :key="star.star_id" class="star-item"
:class="{ 'star-item-selected': selectedStarId === star.star_id }"
@tap="selectStar(star.star_id)">
<view class="star-info">
<text class="star-name">{{ star.name }}</text>
<text class="star-tag" v-if="star.tag">{{ star.tag }}</text>
</view>
<view class="star-radio">
<view v-if="selectedStarId === star.star_id" class="star-radio-checked"></view>
</view>
<text class="identity-nickname">昵称: {{ identity.nickname }}</text>
</view>
<view v-if="identity.star_id === currentStarId" class="identity-current-badge">
<text class="identity-current-text">当前身份</text>
</view>
<!-- 昵称输入框 -->
<input class="modal-input" v-model="newIdentityNickname" placeholder="请输入您的新昵称"
maxlength="20" />
<view class="modal-buttons">
<button class="modal-btn-cancel" @tap="closeAddIdentityModal">取消</button>
<button class="modal-btn-confirm" @tap="confirmAddIdentity">确认</button>
</view>
</view>
</view>
<!-- 身份切换下拉列表 -->
<view class="identity-dropdown-modal" v-if="showIdentityDropdown" @tap="closeIdentityDropdown">
<view class="identity-dropdown-content" @tap.stop>
<view class="identity-dropdown-title">切换粉丝身份</view>
<view class="identity-list">
<view v-for="identity in myFanIdentities" :key="identity.star_id" class="identity-item"
:class="{
'identity-item-active': identity.star_id === currentStarId,
'identity-item-disabled': identity.star_id === currentStarId
}" @tap="handleSwitchIdentity(identity.star_id)">
<view class="identity-info">
<view class="identity-main">
<text class="identity-star-name">{{ identity.star_name }}</text>
<text class="identity-star-tag">{{ identity.star_tag }}</text>
</view>
<text class="identity-nickname">昵称: {{ identity.nickname }}</text>
</view>
<view v-if="identity.star_id === currentStarId" class="identity-current-badge">
<text class="identity-current-text">当前身份</text>
</view>
</view>
</view>
</view>
</view>
<!-- 注销账号确认弹窗 -->
<view class="confirm-modal" v-if="showDeleteAccountModal" @tap="closeDeleteAccountModal">
<view class="modal-content" @tap.stop>
<view class="modal-title">注销账号</view>
<view class="modal-message">注销账号后您的所有数据将被永久删除且无法恢复确定要注销账号吗</view>
<view class="modal-buttons">
<button class="modal-btn-cancel" @tap="closeDeleteAccountModal">取消</button>
<button class="modal-btn-confirm danger" @tap="confirmDeleteAccount">确定注销</button>
</view>
</view>
</view>
<!-- 退出登录确认弹窗 -->
<view class="confirm-modal" v-if="showLogoutModal" @tap="closeLogoutModal">
<view class="modal-content" @tap.stop>
<view class="modal-title">退出登录</view>
<view class="modal-message">确定要退出登录吗</view>
<view class="modal-buttons">
<button class="modal-btn-cancel" @tap="closeLogoutModal">取消</button>
<button class="modal-btn-confirm" @tap="confirmLogout">确定</button>
</view>
</view>
</view>
<!-- 修改头像弹窗 -->
<view class="avatar-modal" v-if="showAvatarModal" @tap="closeAvatarModal">
<view class="modal-content" @tap.stop>
<view class="modal-title">修改头像</view>
<!-- 头像预览 -->
<view class="avatar-preview">
<Avatar :key="avatarKey" :userId="uid" :size="200" :borderWidth="6"
:avatarUrl="userAvatarUrl" />
</view>
<!-- 上传按钮 -->
<button class="upload-avatar-btn" @tap="handleUploadAvatar" :disabled="uploadingAvatar">
{{ uploadingAvatar ? '上传中...' : '上传新头像' }}
</button>
<view class="upload-hint">支持JPGPNG格式大小不超过10MB</view>
<view class="modal-buttons">
<button class="modal-btn-cancel" @tap="closeAvatarModal">取消</button>
</view>
</view>
</view>
</view>
<!-- 注销账号确认弹窗 -->
<view class="confirm-modal" v-if="showDeleteAccountModal" @tap="closeDeleteAccountModal">
<view class="modal-content" @tap.stop>
<view class="modal-title">注销账号</view>
<view class="modal-message">注销账号后您的所有数据将被永久删除且无法恢复确定要注销账号吗</view>
<view class="modal-buttons">
<button class="modal-btn-cancel" @tap="closeDeleteAccountModal">取消</button>
<button class="modal-btn-confirm danger" @tap="confirmDeleteAccount">确定注销</button>
</view>
</view>
<!-- 退出登录按钮 -->
<view class="logout-section">
<button class="logout-button" @tap="handleLogout">退出登录</button>
</view>
<!-- 退出登录确认弹窗 -->
<view class="confirm-modal" v-if="showLogoutModal" @tap="closeLogoutModal">
<view class="modal-content" @tap.stop>
<view class="modal-title">退出登录</view>
<view class="modal-message">确定要退出登录吗</view>
<view class="modal-buttons">
<button class="modal-btn-cancel" @tap="closeLogoutModal">取消</button>
<button class="modal-btn-confirm" @tap="confirmLogout">确定</button>
</view>
</view>
</view>
<!-- 修改头像弹窗 -->
<view class="avatar-modal" v-if="showAvatarModal" @tap="closeAvatarModal">
<view class="modal-content" @tap.stop>
<view class="modal-title">修改头像</view>
<!-- 头像预览 -->
<view class="avatar-preview">
<Avatar :key="avatarKey" :userId="uid" :size="200" :borderWidth="6"
:avatarUrl="userAvatarUrl" />
</view>
<!-- 上传按钮 -->
<button class="upload-avatar-btn" @tap="handleUploadAvatar" :disabled="uploadingAvatar">
{{ uploadingAvatar ? '上传中...' : '上传新头像' }}
</button>
<view class="upload-hint">支持JPGPNG格式大小不超过10MB</view>
<view class="modal-buttons">
<button class="modal-btn-cancel" @tap="closeAvatarModal">取消</button>
</view>
</view>
</view>
</view>
<!-- 退出登录按钮 -->
<view class="logout-section">
<button class="logout-button" @tap="handleLogout">退出登录</button>
</view>
</scroll-view>
<!-- 新手引导列表弹窗 -->
<GuideListModal :visible="showGuideListModal" @start-guide="handleStartGuide"
@claim-success="handleClaimSuccess" @close="showGuideListModal = false" />
<!-- 新手引导弹窗 -->
<GuideModal :visible="showGuideModal" @close="showGuideModal = false" @updated="handleGuideUpdated" />
<!-- 全局引导遮罩 -->
<GuideOverlay />
@ -268,7 +285,7 @@ import Avatar from '../components/Avatar.vue';
import { getUserProfileApi, deleteAccountApi, updateNicknameApi, updatePasswordApi, getFanIdentitiesApi, addFanIdentityApi, getMyFanIdentitiesApi, switchFanIdentityApi, getOssSignatureApi, updateAvatarApi } from '@/utils/api';
import { validateNickname } from '@/utils/validator.js';
import { clearAvatarCache } from '@/utils/avatarCache';
import GuideListModal from '@/components/GuideListModal.vue';
import GuideModal from '@/pages/tasks/GuideModal.vue';
import GuideOverlay from '@/components/GuideOverlay.vue';
import {
getClaimableRewardCount
@ -295,8 +312,13 @@ const newPassword = ref('');
const showOldPassword = ref(false);
//
const showGuideListModal = ref(false);
const showGuideModal = ref(false);
const guideClaimableCount = computed(() => getClaimableRewardCount());
//
const handleGuideUpdated = () => {
console.log('[Profile] Guide updated');
};
const showNewPassword = ref(false);
//
@ -325,18 +347,33 @@ const avatarKey = ref(0); // 用于强制刷新Avatar组件
//
const mobile = ref('');
//
// /
const showBlockNumber = ref(false);
const showMobile = ref(false);
// showMobile
const displayMobile = computed(() => {
return mobile.value || '';
console.log('displayMobile computed, mobile:', mobile.value, 'showMobile:', showMobile.value);
if (!mobile.value) return '';
// showMobiletruefalse
if (showMobile.value) {
return mobile.value;
}
// 34
const phone = mobile.value;
return phone.length === 11 ? phone.slice(0, 3) + '****' + phone.slice(-4) : phone;
});
//
const displayAddress = computed(() => {
const address = blockchainAddress.value;
console.log('displayAddress computed, address:', address, 'showBlockNumber:', showBlockNumber.value);
//
if (!address) return '0xabcd...123c';
// showBlockNumbertruefalse
if (showBlockNumber.value) return address;
if (address.length <= 20) return address;
// 108
// 44
return address.substring(0, 4) + '...' + address.substring(address.length - 4);
});
@ -392,7 +429,7 @@ const fetchUserInfo = async (forceRefresh = false) => {
fanTag.value = userForCache.fan_identity?.name || '';
blockchainAddress.value = userForCache.blockchain_address || '';
userAvatarUrl.value = userForCache.avatar_url || '';
mobile.value = uni.getStorageSync('login_mobile') || '';
mobile.value = userForCache.mobile || uni.getStorageSync('login_mobile') || '';
}
} catch (error) {
console.error('获取用户信息失败:', error);
@ -408,7 +445,7 @@ const fetchUserInfo = async (forceRefresh = false) => {
fanTag.value = cachedUser.fan_identity?.tag || '';
blockchainAddress.value = cachedUser.blockchain_address || '';
userAvatarUrl.value = cachedUser.avatar_url || '';
mobile.value = uni.getStorageSync('login_mobile') || '';
mobile.value = cachedUser.mobile || uni.getStorageSync('login_mobile') || '';
} catch (e) {
console.error('解析缓存用户信息失败:', e);
}
@ -423,6 +460,12 @@ const fetchUserInfo = async (forceRefresh = false) => {
}
};
//
const toggleMobileDisplay = () => {
console.log('toggleMobileDisplay called, showMobile:', showMobile.value);
showMobile.value = !showMobile.value;
};
// UID
const copyUid = () => {
if (!uid.value) {
@ -445,19 +488,6 @@ const handleViewNickname = () => {
});
};
//
const handleViewMobile = () => {
if (!displayMobile.value) {
uni.showToast({ title: '未绑定手机号', icon: 'none' });
return;
}
uni.setClipboardData({
data: displayMobile.value,
success: () => uni.showToast({ title: '已复制手机号', icon: 'success' }),
fail: () => uni.showToast({ title: '复制失败', icon: 'none' })
});
};
//
const copyAddress = () => {
if (!blockchainAddress.value) {
@ -917,50 +947,7 @@ const handleDeleteAccount = () => {
//
const handleGuideClick = () => {
showGuideListModal.value = true;
};
//
const handleStartGuide = (params) => {
// { key, fromStep, targetPage } key
const key = typeof params === 'string' ? params : (params?.key || '');
const fromStep = typeof params === 'object' ? (params.fromStep ?? 0) : 0;
const targetPage = typeof params === 'object' ? (params.targetPage || '') : '';
console.log('[Profile] handleStartGuide:', { key, fromStep, targetPage });
showGuideListModal.value = false;
//
if (key === 'square_home') {
// 使 targetPage
const navigateUrl = targetPage || '/pages/square/square';
uni.navigateTo({
url: navigateUrl,
success: () => {
//
setTimeout(() => {
if (fromStep === 0) {
store.dispatch("guide/startGuideFromBeginning", key);
} else {
store.dispatch("guide/resumeGuide", key);
}
}, 500);
}
});
} else {
//
if (fromStep === 0) {
store.dispatch("guide/startGuideFromBeginning", key);
} else {
store.dispatch("guide/resumeGuide", key);
}
}
};
//
const handleClaimSuccess = (reward) => {
console.log("[Profile] 领取奖励成功:", reward);
showGuideModal.value = true;
};
//
@ -1309,12 +1296,12 @@ onShow(() => {
display: none;
}
.close-icon-img{
.close-icon-img {
width: 80rpx;
height: 80rpx;
position: relative;
top: 32rpx;
left: 32rpx;
top: 32rpx;
left: 32rpx;
}
.user-info-card {
@ -1353,8 +1340,8 @@ onShow(() => {
gap: 8rpx;
margin-left: 8rpx;
background-image: url(/static/rank/activity-support-icon/beijingkuang.png);
background-size: 100% 110%;
background-position: center;
background-size: 100% 110%;
background-position: center;
padding: 24rpx 24rpx 24rpx 240rpx;
min-width: 356rpx;
}
@ -1371,6 +1358,11 @@ onShow(() => {
min-width: 112rpx;
}
.address-row {
display: flex;
align-items: center;
}
.info-value {
font-size: 24rpx;
color: #ffffff;
@ -1378,15 +1370,18 @@ onShow(() => {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
min-width: 200rpx;
}
.uid-value {
max-width: 200rpx;
.uid-value {}
.toggle-icon {
width: 32rpx;
height: 32rpx;
}
.address-value {
max-width: 160rpx;
}
.address-value {}
.info-btn {
font-size: 20rpx;
@ -1619,8 +1614,10 @@ onShow(() => {
.logout-section {
padding: 10rpx 30rpx;
padding-bottom: calc(40rpx + constant(safe-area-inset-bottom)); /* iOS 11.0 */
padding-bottom: calc(40rpx + env(safe-area-inset-bottom)); /* iOS 11.2+ */
padding-bottom: calc(40rpx + constant(safe-area-inset-bottom));
/* iOS 11.0 */
padding-bottom: calc(40rpx + env(safe-area-inset-bottom));
/* iOS 11.2+ */
display: flex;
position: relative;
}
@ -1686,7 +1683,10 @@ onShow(() => {
.modal-content {
width: 80%;
max-width: 600rpx;
background: #ffffff;
/* background: #ffffff; */
background-image: url('/static/starbookcontent/beijing.png');
background-size: cover;
background-position: center bottom;
border-radius: 30rpx;
padding: 60rpx 40rpx;
box-sizing: border-box;

View File

@ -17,7 +17,7 @@
<view class="modal-header">
<!-- 返回按钮 -->
<view class="back-button" @click="handleClose">
<image class="back-icon" src="/static/icon/back.png" mode="aspectFit" />
<image class="back-icon" src="/static/starbookcontent/tuichu.png" mode="aspectFit" />
</view>
<!-- 标题 -->

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 354 KiB

After

Width:  |  Height:  |  Size: 110 KiB

View File

@ -96,8 +96,8 @@ const actions = {
// 缓存用户信息
const user = res.data.user
// 缓存登录手机号(优先使用后端返回的脱敏手机号)
const loginMobile = user.mobile_masked || mobile
// 缓存登录手机号
const loginMobile = mobile
uni.setStorageSync('login_mobile', loginMobile)
uni.setStorageSync('user', JSON.stringify(user))
@ -131,8 +131,8 @@ const actions = {
// 缓存用户信息
const user = res.data.user
// 缓存登录手机号(优先使用后端返回的脱敏手机号)
const loginMobile = user.mobile_masked || mobile
// 缓存登录手机号
const loginMobile = mobile
uni.setStorageSync('login_mobile', loginMobile)
uni.setStorageSync('user', JSON.stringify(user))