topfans/frontend/pages/asset-detail/asset-detail.vue

1043 lines
24 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="detail-container">
<!-- 背景图片 -->
<image class="background-image" src="/static/square/squearbj.png" mode="aspectFill"></image>
<!-- Header -->
<view class="header-bar">
<view class="back-btn" @tap="handleBack">
<image class="back-icon" src="/static/starbookcontent/tuichu.png" mode="aspectFit"></image>
</view>
</view>
<!-- 加载中 -->
<view v-if="loading" class="loading-wrapper">
<!-- 旋转光环 -->
<view class="loading-ring-outer">
<view class="loading-ring"></view>
</view>
<!-- 三颗脉冲粒子 -->
<view class="loading-dots">
<view class="loading-dot dot-1"></view>
<view class="loading-dot dot-2"></view>
<view class="loading-dot dot-3"></view>
</view>
<!-- 文字淡入淡出 -->
<text class="loading-text">正在加载藏品...</text>
</view>
<!-- 错误状态 -->
<view v-else-if="loadError" class="error-wrapper">
<text class="error-text">{{ loadError }}</text>
<button class="retry-btn" @tap="loadData">重试</button>
</view>
<!-- 详情内容 -->
<scroll-view v-else scroll-y class="content-scroll">
<view class="content-wrapper">
<!-- 藏品卡片区域 -->
<view class="card-section">
<view class="card-wrapper">
<image class="card-frame" src="/static/square/gerenzhongxincangpinkuang.png" mode="aspectFit">
</image>
<image class="card-image" :src="coverUrl" mode="aspectFill"></image>
<!-- <view class="card-badge"></view> -->
</view>
<!-- 点赞 + 收益 + 倒计时行 -->
<view class="card-meta-row">
<!-- 点赞 -->
<view class="like-area" @tap="handleLike">
<image :src="isLiked ? '/static/icon/like-after.png' : '/static/icon/like-before.png'" class="like-icon" mode="aspectFit"></image>
<text class="like-num">{{ likeCount }}</text>
</view>
<!-- 收益 -->
<view class="earnings-area">
<image class="crystal-icon" src="/static/icon/crystal.png" mode="aspectFit"></image>
<text class="earnings-text">{{ assetData.earnings || 0 }}/时</text>
</view>
<!-- 倒计时(如有) -->
<view v-if="showCountdown" class="countdown-area">
<view class="countdown-pill">
<text class="countdown-val">{{ countdownText }}</text>
</view>
</view>
</view>
</view>
<!-- 信息行(创作者 + 铸造时间 + 来源) -->
<view class="info-row">
<view class="info-col">
<view class="info-item">
<text class="info-label">创作者</text>
<text class="info-value">{{ assetData.owner_nickname || '未知' }}</text>
</view>
</view>
<view class="info-col">
<view class="info-item">
<text class="info-label">铸造时间</text>
<text class="info-value">{{ formattedAcquireTime }}</text>
</view>
</view>
<view class="info-col">
<view class="info-item">
<text class="info-label">来源</text>
<text class="info-value">{{ assetData.source || '铸造' }}</text>
</view>
</view>
</view>
<!-- 创作者信息模块 -->
<view class="creator-section" @tap="showLikeUsersModal = true">
<!-- 点赞用户头像区域 -->
<view class="liked-users-area">
<view
v-for="(user, index) in likedUsers"
:key="index"
class="liked-user-avatar"
:style="{
transform: `translate(${user.ellipseX || 0}rpx, ${user.ellipseY || 0}rpx) scale(${user.size || 1})`,
zIndex: index < 2 ? index + 1 : (index < 4 ? index + 3 : index + 1)
}"
>
<image class="liked-user-image" :src="user.avatar" mode="aspectFill"></image>
</view>
</view>
<view class="creator-info">
<text class="creator-title">TA们最近为你点过赞</text>
<view class="creator-card">
<text class="creator-tip">点击查看</text>
<image class="creator-preview" src="/static/rank/activity-support-icon/tubiao.png" mode="aspectFill"></image>
</view>
</view>
</view>
<!-- 链上数据 -->
<view class="chain-section">
<image class="chain-logo" src="/static/logo/APPLOGO.png" mode="aspectFit"></image>
<view class="chain-left">
<view class="chain-row">
<text class="chain-label">数根名称</text>
<view class="chain-value-wrap">
<text class="chain-value">{{ assetData.name || '未知' }}</text>
</view>
</view>
<view class="chain-row">
<text class="chain-label">数根发行方</text>
<view class="chain-value-wrap">
<text class="chain-value">TOPFANS</text>
</view>
</view>
<view class="chain-row">
<text class="chain-label">区块链编号</text>
<view class="chain-value-wrap">
<text class="chain-value">{{ showBlockNumber ? (assetData.block_number || '未知') : hiddenBlockNumber }}</text>
<view class="toggle-btn" @tap="showBlockNumber = !showBlockNumber">
<text class="toggle-icon">{{ showBlockNumber ? '👁' : '👁‍🗨' }}</text>
</view>
</view>
</view>
<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>
<view class="toggle-btn" @tap="showTxHash = !showTxHash">
<text class="toggle-icon">{{ showTxHash ? '👁' : '👁‍🗨' }}</text>
</view>
</view>
</view>
</view>
</view>
</view>
</scroll-view>
<!-- 点赞用户弹窗 -->
<LikeUsersModal
:visible="showLikeUsersModal"
:tabs="['今日', '历史']"
@close="showLikeUsersModal = false"
@tab-change="handleLikeUsersTabChange"
>
<template #content>
<view class="like-users-list">
<view v-for="(user, index) in displayedLikeUsers" :key="index" class="like-user-item" >
<image class="like-user-avatar" :src="user.avatar" mode="aspectFill"></image>
<view class="like-user-info">
<text class="like-user-name">{{ user.nickname }}</text>
</view>
<!-- 拜访按钮 -->
<view
class="visit-button"
@tap="handleVisit"
>
<image
class="visit-icon"
src="/static/square/dianjibaifang.png"
mode="aspectFit"
lazy-load
></image>
<text class="visit-text">点击拜访</text>
</view>
</view>
</view>
</template>
</LikeUsersModal>
</view>
</template>
<script setup>
import { ref, computed, onUnmounted } from 'vue';
import { onLoad, onShow } from '@dcloudio/uni-app';
import { getAssetDetailApi, getMintOrderDetailApi, likeAssetApi, unlikeAssetApi } from '@/utils/api.js';
import { getAssetCoverRealUrl } from '@/utils/assetImageHelper.js';
import LikeUsersModal from '@/pages/components/LikeUsersModal.vue';
// 页面参数
const assetIdParam = ref('');
const orderIdParam = ref('');
const fromParam = ref('');
const lastLoadKey = ref(''); // 记录上次加载的key避免重复加载
// 数据状态
const loading = ref(true);
const loadError = ref('');
const assetData = ref({});
const coverUrl = ref('');
const isLiked = ref(false);
const likeCount = ref(0);
const liking = ref(false);
// 点赞用户头像数据最多6个按椭圆排列每个头像有独立的偏移量配置
// avatar: 头像地址, ellipseX: 椭圆X轴坐标, ellipseY: 椭圆Y轴坐标, size: 缩放比例
const likedUsers = ref([
{ avatar: '/static/sucai/image-01.png', ellipseX: -40, ellipseY: -40, size: 0.85 },
{ avatar: '/static/sucai/image-02.png', ellipseX: 40, ellipseY: -40, size: 0.85 },
{ avatar: '/static/sucai/image-03.png', ellipseX: -96, ellipseY: 0, size: 0.9 },
{ avatar: '/static/sucai/image-04.png', ellipseX: 120, ellipseY: -40, size: 0.9 },
{ avatar: '/static/sucai/image-05.png', ellipseX: 64, ellipseY: 32},
{ avatar: '/static/sucai/image-06.png', ellipseX: -16, ellipseY: 32 ,size:1.15 }
]);
// 弹窗相关
const showLikeUsersModal = ref(false);
const likeUsersActiveTab = ref(0);
// 今日/历史点赞用户数据(模拟)
const todayLikeUsers = ref([
{ userId: '1', nickname: '用户A', avatar: '/static/sucai/image-01.png', time: '10分钟前' },
{ userId: '2', nickname: '用户B', avatar: '/static/sucai/image-02.png', time: '30分钟前' },
{ userId: '3', nickname: '用户C', avatar: '/static/sucai/image-03.png', time: '1小时前' },
]);
const historyLikeUsers = ref([
{ userId: '4', nickname: '用户D', avatar: '/static/sucai/image-04.png', time: '昨天' },
{ userId: '5', nickname: '用户E', avatar: '/static/sucai/image-05.png', time: '3天前' },
]);
const displayedLikeUsers = computed(() => {
return likeUsersActiveTab.value === 0 ? todayLikeUsers.value : historyLikeUsers.value;
});
const handleLikeUsersTabChange = ({ tabIndex }) => {
likeUsersActiveTab.value = tabIndex;
};
// 拜访按钮
const handleVisit = () => {
uni.navigateTo({
url: `/pages/profile/hisWorks?userId=${user.userId}&nickname=${encodeURIComponent(user.nickname)}`
});
};
// 区块链编号和交易哈希的显示切换
const showBlockNumber = ref(false);
const showTxHash = ref(false);
// 倒计时
const remainSeconds = ref(0);
let countdownTimer = null;
const showCountdown = computed(() => remainSeconds.value > 0);
const countdownText = computed(() => {
const h = String(Math.floor(remainSeconds.value / 3600)).padStart(2, '0');
const m = String(Math.floor((remainSeconds.value % 3600) / 60)).padStart(2, '0');
const s = String(Math.floor(remainSeconds.value % 60)).padStart(2, '0');
return `${h}:${m}:${s}`;
});
// 格式化获取时间(字段名 created_at来自 getAssetDetailApi 响应)
const formattedAcquireTime = computed(() => {
const raw = assetData.value.created_at || '';
if (!raw) return '未知';
const d = new Date(raw);
if (isNaN(d.getTime())) return raw;
const yyyy = d.getFullYear();
const mm = String(d.getMonth() + 1).padStart(2, '0');
const dd = String(d.getDate()).padStart(2, '0');
return `${yyyy}.${mm}.${dd}`;
});
// 截断交易哈希
const displayTxHash = computed(() => {
const hash = assetData.value.tx_hash;
if (!hash) return '未知';
if (hash.length <= 20) return hash;
return `${hash.substring(0, 10)}...${hash.substring(hash.length - 8)}`;
});
// 隐藏交易哈希保留前6位 + 6个*
const hiddenTxHash = computed(() => {
const hash = assetData.value.tx_hash;
if (!hash) return '******';
if (hash.length <= 6) return hash + '******';
return `${hash.substring(0, 6)}******`;
});
// 隐藏区块链编号保留前6位 + 6个*
const hiddenBlockNumber = computed(() => {
const num = assetData.value.block_number;
if (!num) return '******';
const str = String(num);
if (str.length <= 6) return str + '******';
return `${str.substring(0, 6)}******`;
});
// 复制完整哈希
const copyHash = () => {
const hash = assetData.value.tx_hash;
if (!hash) return;
uni.setClipboardData({
data: hash,
success: () => uni.showToast({ title: '已复制', icon: 'success', duration: 1500 })
});
};
// 加载数据
const loadData = async () => {
console.log('loadData 开始执行');
loading.value = true;
loadError.value = '';
try {
let assetId = assetIdParam.value;
console.log('assetIdParam:', assetIdParam.value, 'orderIdParam:', orderIdParam.value);
if (!assetId && orderIdParam.value) {
console.log('通过 order_id 获取资产信息');
const mintRes = await getMintOrderDetailApi(orderIdParam.value);
console.log('getMintOrderDetailApi 响应:', mintRes);
if (mintRes.code === 200 && mintRes.data?.asset?.asset_id) {
assetId = mintRes.data.asset.asset_id;
console.log('获取到 assetId:', assetId);
} else {
throw new Error('获取铸造订单详情失败');
}
}
if (!assetId) throw new Error('藏品信息不完整');
console.log('调用 getAssetDetailApiassetId:', assetId);
const res = await getAssetDetailApi(assetId);
console.log('getAssetDetailApi 响应:', res);
if (res.code === 200 && res.data?.asset) {
const asset = res.data.asset;
assetData.value = asset;
isLiked.value = res.data.asset.is_liked || res.data.is_liked || false;
likeCount.value = asset.like_count || 0;
if (asset.remain_time > 0) {
remainSeconds.value = asset.remain_time;
startCountdown();
}
console.log(res.data)
// 异步加载封面图片,不阻塞页面渲染
console.log('开始加载封面图片:', asset.cover_url);
getAssetCoverRealUrl(asset.cover_url).then(url => {
console.log('封面图片加载成功:', url);
coverUrl.value = url;
}).catch(err => {
console.error('加载封面图片失败:', err);
coverUrl.value = ''; // 失败时不显示默认图片
});
console.log('loadData 执行成功');
} else {
throw new Error(res.message || '获取藏品详情失败');
}
} catch (err) {
console.error('loadData 出错:', err);
loadError.value = err.message || '加载失败,请重试';
} finally {
loading.value = false;
console.log('loadData 执行完成loading:', loading.value);
}
};
// 倒计时
const startCountdown = () => {
if (countdownTimer) clearInterval(countdownTimer);
countdownTimer = setInterval(() => {
if (remainSeconds.value > 0) {
remainSeconds.value--;
} else {
clearInterval(countdownTimer);
}
}, 1000);
};
// 点赞
const handleLike = async () => {
if (liking.value || !assetData.value.asset_id) return;
liking.value = true;
try {
// if (isLiked.value) {
// await unlikeAssetApi(assetData.value.asset_id);
// isLiked.value = false;
// likeCount.value = Math.max(0, likeCount.value - 1);
// } else {
await likeAssetApi(assetData.value.asset_id);
isLiked.value = true;
likeCount.value += 1;
// }
// 通知展馆页面更新点赞数
uni.$emit('assetLikeChanged', {
asset_id: assetData.value.asset_id,
like_count: likeCount.value,
is_liked: isLiked.value
});
} catch (err) {
const errMsg = err?.message || '';
const errCode = err?.code || err?.data?.code || '';
if (errMsg.includes('未在展示中')) {
uni.showToast({ title: '未展览无法点赞', icon: 'none', duration: 2000 });
} else {
uni.showToast({ title: '今日已点赞', icon: 'none', duration: 2000 });
}
} finally {
liking.value = false;
}
};
// 返回逻辑
const handleBack = () => {
if (fromParam.value === 'castlove') {
uni.reLaunch({ url: '/pages/castlove/mall' });
} else {
uni.navigateBack();
}
};
onLoad((options) => {
console.log('onLoad 触发,参数:', options);
assetIdParam.value = options?.asset_id || '';
orderIdParam.value = options?.order_id || '';
fromParam.value = options?.from || '';
});
onShow(() => {
console.log('onShow 触发');
const currentKey = `${assetIdParam.value}_${orderIdParam.value}`;
console.log('当前key:', currentKey, '上次key:', lastLoadKey.value);
// 如果参数变化了,或者是首次加载,则重新加载数据
if ((assetIdParam.value || orderIdParam.value) && currentKey !== lastLoadKey.value) {
lastLoadKey.value = currentKey;
loadData();
}
});
onUnmounted(() => {
if (countdownTimer) clearInterval(countdownTimer);
});
</script>
<style scoped>
.detail-container {
position: relative;
width: 100vw;
min-height: 100vh;
overflow: hidden;
background-color: #0d0820;
}
.background-image {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
z-index: 0;
}
/* Header */
.header-bar {
position: fixed;
top: 32rpx;
left: 32rpx;
z-index: 100;
}
.back-btn {
display: flex;
align-items: center;
justify-content: center;
}
.back-btn:active {
opacity: 0.6;
}
.back-icon {
width: 80rpx;
height: 80rpx;
}
/* 加载/错误 */
.loading-wrapper,
.error-wrapper {
position: relative;
z-index: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
gap: 30rpx;
}
/* 旋转光环 */
.loading-ring-outer {
position: relative;
width: 160rpx;
height: 160rpx;
display: flex;
align-items: center;
justify-content: center;
}
.loading-ring {
width: 160rpx;
height: 160rpx;
border-radius: 50%;
border: 6rpx solid transparent;
border-top-color: #F0E4B1;
border-right-color: #F08399;
border-bottom-color: #B94E73;
border-left-color: transparent;
box-shadow:
0 0 24rpx rgba(240, 131, 153, 0.5),
inset 0 0 16rpx rgba(183, 78, 115, 0.2);
animation: ring-spin 1.2s linear infinite;
}
@keyframes ring-spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
/* 三颗脉冲粒子 */
.loading-dots {
display: flex;
align-items: center;
gap: 24rpx;
}
.loading-dot {
width: 20rpx;
height: 20rpx;
border-radius: 50%;
animation: dot-pulse 1.4s ease-in-out infinite;
}
.dot-1 {
background: #F0E4B1;
box-shadow: 0 0 12rpx rgba(240, 228, 177, 0.8);
animation-delay: 0s;
}
.dot-2 {
background: #F08399;
box-shadow: 0 0 12rpx rgba(240, 131, 153, 0.8);
animation-delay: 0.2s;
}
.dot-3 {
background: #834B9E;
box-shadow: 0 0 12rpx rgba(131, 75, 158, 0.8);
animation-delay: 0.4s;
}
@keyframes dot-pulse {
0%,
100% {
transform: scale(0.6);
opacity: 0.4;
}
50% {
transform: scale(1.3);
opacity: 1;
}
}
/* 加载文字 */
.loading-text {
font-size: 28rpx;
color: rgba(255, 255, 255, 0.85);
font-family: 'yt', sans-serif;
letter-spacing: 4rpx;
animation: text-breathe 2s ease-in-out infinite;
}
@keyframes text-breathe {
0%,
100% {
opacity: 0.5;
}
50% {
opacity: 1;
}
}
.error-text {
font-size: 32rpx;
color: rgba(255, 255, 255, 0.8);
font-family: 'yt', sans-serif;
}
.retry-btn {
padding: 16rpx 48rpx;
background: linear-gradient(165deg, #F0E4B1 0%, #F08399 50%, #B94E73 90%, #834B9E 100%);
color: #fff;
border-radius: 40rpx;
font-size: 28rpx;
border: none;
}
.retry-btn::after {
border: none;
}
/* 滚动区 */
.content-scroll {
position: relative;
z-index: 1;
height: 100vh;
}
.content-wrapper {
padding: 104rpx 40rpx 80rpx;
display: flex;
flex-direction: column;
align-items: center;
gap: 0;
}
/* 卡片区域 */
.card-section {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
}
.card-wrapper {
position: relative;
width: 352rpx;
height: 520rpx;
margin-bottom: 32rpx;
}
.card-image {
width: 88%;
height: 96%;
left: 6%;
top: 1.5%;
border-radius: 48rpx;
transform-origin: center center;
position: absolute;
z-index: 3;
overflow: hidden;
transform: rotate(-10deg);
}
.card-frame {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 2;
transform: rotate(-10deg);
}
.card-badge {
position: absolute;
top: 40rpx;
left: 40rpx;
width: 60rpx;
height: 60rpx;
background: red;
border-radius: 20rpx;
z-index: 4;
}
.card-meta-row {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
gap: 24rpx;
}
/* 点赞 */
.like-area {
display: flex;
align-items: center;
gap: 10rpx;
background: linear-gradient(to bottom right,
#F0E4B1 0%,
#F08399 50%,
#B94E73 100%);
border-radius: 999rpx;
box-shadow:
0 4rpx 12rpx rgba(255, 143, 158, 0.2),
inset 0 2rpx 4rpx rgba(255, 255, 255, 0.4);
padding: 10rpx 28rpx;
backdrop-filter: blur(12rpx);
}
.like-area:active {
opacity: 0.75;
}
.like-icon, .heart-icon, .crystal-icon {
width: 44rpx;
height: 44rpx;
}
.like-num {
font-size: 32rpx;
font-weight: bold;
color: #e6e6e6;
font-family: 'yt', sans-serif;
font-variant-numeric: tabular-nums;
}
/* 收益 */
.earnings-area {
display: flex;
align-items: center;
gap: 10rpx;
background: linear-gradient(to bottom right,
#F0E4B1 0%,
#F08399 50%,
#B94E73 100%);
border-radius: 999rpx;
box-shadow:
0 4rpx 12rpx rgba(255, 143, 158, 0.2),
inset 0 2rpx 4rpx rgba(255, 255, 255, 0.4);
padding: 10rpx 28rpx;
}
.earnings-text {
font-size: 32rpx;
font-weight: bold;
color: #e6e6e6;
font-family: 'yt', sans-serif;
font-variant-numeric: tabular-nums;
}
/* 倒计时 */
.countdown-area {
display: flex;
align-items: center;
}
.countdown-pill {
background: linear-gradient(165deg, #F0E4B1 0%, #F08399 50%, #B94E73 90%, #834B9E 100%);
border-radius: 999rpx;
padding: 10rpx 24rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.4);
}
.countdown-val {
font-size: 28rpx;
font-weight: bold;
color: #fff;
font-family: 'yt', sans-serif;
font-variant-numeric: tabular-nums;
}
/* 信息行(持有人 + 铸造时间) */
.info-row {
width: 100%;
display: flex;
align-items: stretch;
justify-content: center;
gap: 20rpx;
padding: 24rpx 32rpx;
border-radius: 24rpx;
margin-bottom: 40rpx;
flex-direction: column;
}
.info-col {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
}
.info-item {
display: flex;
gap: 8rpx;
width: 416rpx;
justify-content: space-between;
align-items: center;
}
.info-label {
font-size: 32rpx;
color: rgba(255, 255, 255, 0.7);
font-family: 'yt', sans-serif;
}
.info-value {
font-size: 32rpx;
font-weight: bold;
color: #ffffff;
font-family: 'yt', sans-serif;
text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.7);
}
/* 点赞用户头像区域 */
.liked-users-area {
position: relative;
flex: 1;
height: 184rpx;
display: flex;
align-items: center;
justify-content: center;
}
.liked-user-avatar {
position: absolute;
width: 80rpx;
height: 80rpx;
border-radius: 50%;
border: 3rpx solid #F0E4B1;
overflow: hidden;
}
.liked-user-image{
width: 100%;
height: 100%;
}
/* 创作者信息模块 */
.creator-section {
width: calc(100% - 80rpx);
display: flex;
flex-direction: row;
align-items: center;
gap: 24rpx;
padding: 16rpx;
background: url('/static/rank/activity-support-icon/beijingkuang.png') no-repeat center center;
background-size: 105% 120%;
border-radius: 24rpx;
margin-bottom: 64rpx;
}
.creator-avatar {
width: 100rpx;
height: 100rpx;
border-radius: 50%;
}
.creator-info {
flex: 1;
display: flex;
flex-direction: column;
gap: 12rpx;
}
.creator-title {
font-size: 28rpx;
color: #fff;
font-family: 'yt', sans-serif;
}
.creator-card {
display: flex;
flex-direction: row;
align-items: center;
flex-direction: column;
gap: 16rpx;
border-radius: 16rpx;
}
.creator-tip {
font-size: 32rpx;
color: #ffcc00;
font-family: 'yt', sans-serif;
text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.7);
}
.creator-preview {
width: 112rpx;
height: 80rpx;
border-radius: 12rpx;
}
/* 链上数据 */
.chain-section {
width: calc(100% - 80rpx);
background: url('/static/rank/activity-support-icon/beijingkuang.png') no-repeat center center;
background-size: 105% 120%;
border-radius: 24rpx;
padding: 30rpx 16rpx;
display: flex;
flex-direction: row;
align-items: center;
gap: 24rpx;
}
.chain-left {
flex: 1;
display: flex;
flex-direction: column;
}
.chain-row {
display: flex;
justify-content: space-between;
align-items: flex-start;
}
.chain-logo {
width: 156rpx;
height: 156rpx;
}
.chain-label {
font-size: 28rpx;
color: rgba(255, 255, 255, 0.6);
font-family: 'yt', sans-serif;
flex-shrink: 0;
margin-right: 20rpx;
}
.chain-value {
font-size: 28rpx;
color: #ffffff;
font-family: 'yt', sans-serif;
text-align: right;
flex: 1;
word-break: break-all;
display: flex
}
.chain-value-wrap {
display: flex;
align-items: center;
gap: 12rpx;
width: 240rpx;
}
.toggle-btn {
padding: 4rpx 8rpx;
}
.toggle-icon {
font-size: 28rpx;
}
.chain-hash {
color: rgba(255, 255, 255, 0.75);
}
/* 点赞用户列表 */
.like-users-list {
display: flex;
flex-direction: column;
gap: 24rpx;
padding: 16rpx;
}
.like-user-item {
display: flex;
flex-direction: row;
align-items: center;
padding:0 16rpx;
background: linear-gradient(to bottom right,
#F0E4B1 0%,
#F08399 50%,
#B94E73 100%);
border-radius: 999rpx;
box-shadow:
0 4rpx 12rpx rgba(255, 143, 158, 0.2),
inset 0 2rpx 4rpx rgba(255, 255, 255, 0.4);
}
.like-user-avatar {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
}
.like-user-info {
flex: 1;
display: flex;
flex-direction: column;
margin: 0 24rpx;
}
.like-user-name {
font-size: 28rpx;
color: #fff;
font-family: 'yt', sans-serif;
}
.like-user-time {
font-size: 24rpx;
color: rgba(255, 255, 255, 0.6);
font-family: 'yt', sans-serif;
}
/* 拜访按钮 - 只显示图标 */
.visit-button {
display: flex;
align-items: center;
justify-content: center;
width: 80rpx;
height: 80rpx;
padding: 8rpx;
flex-direction: column;
}
.visit-icon {
width: 80rpx;
height: 80rpx;
margin-bottom: 8rpx;
/* transform: scale(1.2); */
}
.visit-text{
color: #FFFFFF;
font-size:16rpx;
}
</style>