632 lines
13 KiB
Vue
632 lines
13 KiB
Vue
<template>
|
|
<view class="page-container">
|
|
<!-- 背景图片 -->
|
|
<image class="bg-image" src="/static/square/beijingban.png" mode="aspectFill"></image>
|
|
|
|
<!-- 顶部导航 -->
|
|
<view class="nav-bar">
|
|
<view class="nav-back" @tap="goBack">
|
|
<image class="nav-back-icon" src="/static/icon/back.png" mode="aspectFit"></image>
|
|
</view>
|
|
<text class="nav-title">{{ nickname }}的作品</text>
|
|
<view class="nav-placeholder"></view>
|
|
</view>
|
|
|
|
<view class="scroll-content">
|
|
|
|
<!-- 他人的在展作品 -->
|
|
<view class="section-block section-1">
|
|
<view class="section-label section-label-1">
|
|
<image class="section-label-bg" src="/static/nft/dingbutubiao_liang.png" mode="aspectFill"></image>
|
|
<text class="section-label-text">当前在展作品</text>
|
|
</view>
|
|
|
|
<view class="exhibition-grid">
|
|
<view v-for="(item, index) in exhibitionWorks" :key="item.id" class="exhibition-card"
|
|
:class="index % 2 === 0 ? 'card-tilt-left' : 'card-tilt-right'"
|
|
@tap="goToAssetDetail(item.id)">
|
|
<image class="card-image" :src="item.cover_url || '/static/nft/placeholder.png'"
|
|
mode="aspectFill"></image>
|
|
<image class="card-frame" src="/static/square/gerenzhongxincangpinkuang.png" mode="aspectFill">
|
|
</image>
|
|
<!-- 点赞数 -->
|
|
<view class="card-rate-badge">
|
|
<image class="heart-icon" src="/static/icon/heart-icon.png" mode="aspectFit"></image>
|
|
<view class="card-rate-text-wrap">
|
|
<text class="card-rate-text">{{ item.like_count || 0 }}</text>
|
|
</view>
|
|
</view>
|
|
<!-- 图片下方收益 -->
|
|
<view class="card-income-row"
|
|
:class="index % 2 === 0 ? 'income-tilt-right' : 'income-tilt-left'">
|
|
<image class="topfans-icon" src="/static/icon/crystal.png" mode="aspectFit"></image>
|
|
<view class="card-income-text-wrap">
|
|
<text class="card-income-text">{{ item.earnings || 0 }}/时</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 空状态占位 -->
|
|
<view v-if="exhibitionWorks.length === 0" class="empty-exhibition">
|
|
<text class="empty-text">该用户暂无在展作品</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 他人的点赞作品 -->
|
|
<view class="section-block">
|
|
<view class="liked-tabs">
|
|
<view class="section-label" :class="{ 'tab-active': likedTab === 'current' }"
|
|
@tap="switchLikedTab('current')">
|
|
<image class="section-label-bg" src="/static/nft/dingbutubiao_liang.png" mode="aspectFill">
|
|
</image>
|
|
<text class="section-label-text">当前点赞作品</text>
|
|
</view>
|
|
<!-- <view class="section-label" :class="{ 'tab-active': likedTab === 'today' }"
|
|
@tap="switchLikedTab('today')">
|
|
<image class="section-label-bg" src="/static/nft/dingbutubiao_liang.png" mode="aspectFill">
|
|
</image>
|
|
<text class="section-label-text">今日点赞作品</text>
|
|
</view>
|
|
<view class="section-label" :class="{ 'tab-active': likedTab === 'week' }"
|
|
@tap="switchLikedTab('week')">
|
|
<image class="section-label-bg" src="/static/nft/dingbutubiao_liang.png" mode="aspectFill">
|
|
</image>
|
|
<text class="section-label-text">本周点赞作品</text>
|
|
</view> -->
|
|
</view>
|
|
|
|
<scroll-view class="liked-list" scroll-y="true" :show-scrollbar="false">
|
|
<view v-for="(item, index) in likedWorks" :key="item.id" class="liked-row"
|
|
@tap="goToAssetDetail(item.id)">
|
|
<!-- 卡片主体 -->
|
|
<view class="liked-item" :class="index === 0 ? 'liked-item-first' : ''">
|
|
<!-- 排名图标 -->
|
|
<image v-if="index < 3" :src="rankIcons[index]" :class="'rank-icon rank-icon-' + (index + 1)" mode="aspectFit"></image>
|
|
<!-- 作品封面 -->
|
|
<view class="liked-cover-wrap" :class="index === 0 ? 'liked-cover-wrap-first' : ''">
|
|
<image class="liked-cover" :src="item.cover_url || '/static/nft/placeholder.png'"
|
|
mode="aspectFill"></image>
|
|
<image class="liked-cover-frame" src="/static/square/cangpinkuang1.png"
|
|
mode="aspectFill"></image>
|
|
</view>
|
|
|
|
<!-- 作品信息 -->
|
|
<view class="liked-info">
|
|
<text class="liked-status">{{ item.status_text }}</text>
|
|
<view class="liked-score-row">
|
|
<text class="liked-score">{{ formatScore(item.score) }}</text>
|
|
<image class="fire-icon" src="/static/square/rementubiao.png" mode="aspectFit">
|
|
</image>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 右侧奖励 -->
|
|
<view class="liked-reward">
|
|
<image class="reward-token-icon" :src="item.earnings > 10 ? '/static/square/shuijingtubiao.png' : '/static/icon/crystal.png'" mode="aspectFit">
|
|
</image>
|
|
<text class="reward-amount">+{{ item.reward }}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 空状态 -->
|
|
<view v-if="likedWorks.length === 0" class="empty-liked">
|
|
<text class="empty-text">当前暂无点赞作品</text>
|
|
</view>
|
|
</scroll-view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, onMounted } from 'vue';
|
|
import { onLoad } from '@dcloudio/uni-app';
|
|
import { getUserExhibitedAssetsApi, getUserLikedAssetsApi, getUserProfileApi } from '@/utils/api.js';
|
|
|
|
const userId = ref('');
|
|
const nickname = ref('');
|
|
|
|
onLoad((options) => {
|
|
if (options.userId) userId.value = options.userId;
|
|
if (options.nickname) nickname.value = decodeURIComponent(options.nickname);
|
|
});
|
|
|
|
const goBack = () => {
|
|
const pages = getCurrentPages();
|
|
if (pages.length > 1) {
|
|
uni.navigateBack();
|
|
} else {
|
|
uni.reLaunch({
|
|
url: '/pages/square/square'
|
|
});
|
|
}
|
|
};
|
|
|
|
const goToAssetDetail = (id) => {
|
|
if (!id) return;
|
|
uni.navigateTo({ url: `/pages/asset-detail/asset-detail?asset_id=${id}` });
|
|
};
|
|
|
|
const formatScore = (score) => {
|
|
if (!score && score !== 0) return '0';
|
|
return Number(score).toLocaleString();
|
|
};
|
|
|
|
const rankIcons = [
|
|
'/static/rank/rank-icon1.png',
|
|
'/static/rank/rank-icon2.png',
|
|
'/static/rank/rank-icon3.png',
|
|
];
|
|
|
|
// 在展作品列表
|
|
const exhibitionWorks = ref([]);
|
|
|
|
// 点赞作品列表
|
|
const likedWorks = ref([]);
|
|
|
|
// 点赞标签状态: current-当前, today-今日, week-本周
|
|
const likedTab = ref('current');
|
|
|
|
// 切换点赞标签
|
|
const switchLikedTab = async (tab) => {
|
|
if (likedTab.value === tab) return;
|
|
likedTab.value = tab;
|
|
likedWorks.value = [];
|
|
await loadLikedAssets();
|
|
};
|
|
|
|
// 加载他人的展出作品
|
|
const loadExhibitedAssets = async () => {
|
|
if (!userId.value) return;
|
|
try {
|
|
const res = await getUserExhibitedAssetsApi(userId.value, 1, 20);
|
|
if (res.data && res.data.items) {
|
|
exhibitionWorks.value = res.data.items.map(item => ({
|
|
id: item.asset_id,
|
|
cover_url: item.cover_url,
|
|
like_count: item.like_count,
|
|
earnings: item.earnings,
|
|
name: item.name,
|
|
}));
|
|
}
|
|
} catch (err) {
|
|
console.error('加载展出作品失败:', err);
|
|
}
|
|
};
|
|
|
|
// 加载他人的点赞作品
|
|
const loadLikedAssets = async () => {
|
|
if (!userId.value) return;
|
|
try {
|
|
let res;
|
|
switch (likedTab.value) {
|
|
case 'today':
|
|
// 后端暂无今日/本周接口,暂时复用全部接口
|
|
res = await getUserLikedAssetsApi(userId.value, 1, 20);
|
|
break;
|
|
case 'week':
|
|
res = await getUserLikedAssetsApi(userId.value, 1, 20);
|
|
break;
|
|
default:
|
|
res = await getUserLikedAssetsApi(userId.value, 1, 20);
|
|
}
|
|
if (res.data && res.data.items) {
|
|
likedWorks.value = res.data.items.map((item, index) => ({
|
|
id: item.asset_id,
|
|
cover_url: item.cover_url,
|
|
like_count: item.like_count,
|
|
earnings: item.earnings,
|
|
name: item.name,
|
|
status_text: index < 3 ? '排名进榜' : '潜力待挖',
|
|
score: item.like_count,
|
|
reward: Math.floor(item.earnings || 0),
|
|
}));
|
|
}
|
|
} catch (err) {
|
|
console.error('加载点赞作品失败:', err);
|
|
}
|
|
};
|
|
|
|
onMounted(() => {
|
|
loadExhibitedAssets();
|
|
loadLikedAssets();
|
|
});
|
|
</script>
|
|
|
|
<style scoped>
|
|
.page-container {
|
|
min-height: 100vh;
|
|
position: relative;
|
|
}
|
|
|
|
.bg-image {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 120%;
|
|
z-index: 0;
|
|
}
|
|
|
|
.nav-bar {
|
|
position: relative;
|
|
z-index: 10;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 80rpx 32rpx 16rpx;
|
|
}
|
|
|
|
.nav-back {
|
|
width: 80rpx;
|
|
height: 80rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.nav-back-icon {
|
|
width: 80rpx;
|
|
height: 80rpx;
|
|
}
|
|
|
|
.nav-title {
|
|
font-size: 48rpx;
|
|
font-weight: 700;
|
|
color: #fff;
|
|
text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.9);
|
|
letter-spacing: 2rpx;
|
|
}
|
|
|
|
.nav-placeholder {
|
|
width: 80rpx;
|
|
}
|
|
|
|
.scroll-content {
|
|
position: relative;
|
|
z-index: 1;
|
|
}
|
|
|
|
.section-block {
|
|
/* background: rgb(249 159 192 / 45%);
|
|
border-radius: 48rpx; */
|
|
padding: 16rpx;
|
|
}
|
|
|
|
.section-label {
|
|
position: relative;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
height: 80rpx;
|
|
min-width: 180rpx;
|
|
opacity: 0.6;
|
|
transition: opacity 0.2s;
|
|
}
|
|
|
|
.section-label.section-label-1 {
|
|
opacity: 1;
|
|
}
|
|
|
|
.section-label.tab-active {
|
|
opacity: 1;
|
|
}
|
|
|
|
.liked-tabs {
|
|
display: flex;
|
|
gap: 16rpx;
|
|
margin-bottom: 16rpx;
|
|
}
|
|
|
|
.section-label-bg {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.section-label-text {
|
|
position: relative;
|
|
z-index: 1;
|
|
font-size: 26rpx;
|
|
color: #fff;
|
|
text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.9);
|
|
font-weight: 600;
|
|
padding: 0 28rpx;
|
|
}
|
|
|
|
.exhibition-grid {
|
|
display: flex;
|
|
flex-direction: row;
|
|
padding: 10rpx 10rpx 80rpx;
|
|
justify-content: center;
|
|
}
|
|
|
|
.exhibition-card {
|
|
width: 248rpx;
|
|
height: 380rpx;
|
|
border-radius: 20rpx;
|
|
overflow: visible;
|
|
position: relative;
|
|
}
|
|
|
|
.card-tilt-left {
|
|
transform: rotate(-4deg) translateY(10rpx);
|
|
margin-right: 32rpx;
|
|
}
|
|
|
|
.card-tilt-right {
|
|
transform: rotate(4deg) translateY(10rpx);
|
|
}
|
|
|
|
.card-income-row.income-tilt-right {
|
|
transform: translateX(-50%) rotate(4deg);
|
|
}
|
|
|
|
.card-income-row.income-tilt-left {
|
|
transform: translateX(-50%) rotate(-4deg);
|
|
}
|
|
|
|
.card-image {
|
|
width: 88%;
|
|
height: 92%;
|
|
border-radius: 80rpx;
|
|
transform-origin: center center;
|
|
position: relative;
|
|
z-index: 3;
|
|
padding: 16rpx;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.card-frame {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
z-index: 2;
|
|
}
|
|
|
|
.card-rate-badge {
|
|
position: absolute;
|
|
bottom: 16rpx;
|
|
left: 40%;
|
|
transform: translateX(-50%);
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6rpx;
|
|
padding: 6rpx 16rpx;
|
|
z-index: 9;
|
|
}
|
|
|
|
.card-income-row {
|
|
position: absolute;
|
|
bottom: -52rpx;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
display: flex;
|
|
align-items: center;
|
|
white-space: nowrap;
|
|
overflow: visible;
|
|
}
|
|
|
|
.topfans-icon {
|
|
width: 52rpx;
|
|
height: 52rpx;
|
|
position: relative;
|
|
z-index: 2;
|
|
margin-right: -16rpx;
|
|
left: 20rpx;
|
|
top: 8rpx;
|
|
}
|
|
|
|
.card-income-text-wrap {
|
|
width: 64rpx;
|
|
background: linear-gradient(to bottom right,
|
|
#F0E4B1 0%,
|
|
#F08399 50%,
|
|
#B94E73 100%);
|
|
border-radius: 999rpx;
|
|
padding: 8rpx 20rpx 8rpx 40rpx;
|
|
box-shadow: 0 4rpx 12rpx rgba(255, 143, 158, 0.2),
|
|
inset 0 2rpx 4rpx rgba(255, 255, 255, 0.4);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.card-income-text {
|
|
font-size: 16rpx;
|
|
color: #fff;
|
|
font-weight: 700;
|
|
text-align: center;
|
|
}
|
|
|
|
.heart-icon {
|
|
width: 28rpx;
|
|
height: 28rpx;
|
|
}
|
|
|
|
.card-rate-text-wrap {
|
|
background: linear-gradient(to bottom right,
|
|
#F0E4B1 0%,
|
|
#F08399 50%,
|
|
#B94E73 100%);
|
|
border-radius: 999rpx;
|
|
padding: 2rpx 16rpx;
|
|
box-shadow: 0 4rpx 12rpx rgba(255, 143, 158, 0.2),
|
|
inset 0 2rpx 4rpx rgba(255, 255, 255, 0.4);
|
|
display: flex;
|
|
}
|
|
|
|
.card-rate-text {
|
|
font-size: 22rpx;
|
|
color: #fff;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.empty-exhibition {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 80rpx 0;
|
|
}
|
|
|
|
.empty-text {
|
|
font-size: 28rpx;
|
|
color: #b09cc0;
|
|
}
|
|
|
|
.liked-list {
|
|
max-height: 732rpx;
|
|
}
|
|
|
|
.liked-row {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: flex-end;
|
|
margin-bottom: 16rpx;
|
|
}
|
|
|
|
.liked-item {
|
|
display: flex;
|
|
align-items: center;
|
|
background: #ffffff50;
|
|
border-radius: 32rpx;
|
|
padding: 16rpx 20rpx;
|
|
gap: 16rpx;
|
|
overflow: hidden;
|
|
box-sizing: border-box;
|
|
width: 80%;
|
|
padding-left: 10%;
|
|
}
|
|
|
|
.liked-item-first {
|
|
padding: 28rpx 20rpx;
|
|
width: 90%;
|
|
padding-left: 20%;
|
|
}
|
|
|
|
/* 排名图标 - 排名越靠前越大 */
|
|
.rank-icon {
|
|
flex-shrink: 0;
|
|
/* margin-right: 8rpx; */
|
|
position: relative;
|
|
left: 32rpx;
|
|
}
|
|
|
|
.rank-icon-1 {
|
|
width: 72rpx;
|
|
height: 88rpx;
|
|
}
|
|
|
|
.rank-icon-2 {
|
|
width: 64rpx;
|
|
height: 78rpx;
|
|
}
|
|
|
|
.rank-icon-3 {
|
|
width: 56rpx;
|
|
height: 68rpx;
|
|
}
|
|
|
|
.liked-cover-wrap {
|
|
width: 88rpx;
|
|
height: 88rpx;
|
|
flex-shrink: 0;
|
|
margin-left: -18rpx;
|
|
margin-right: 48rpx;
|
|
position: relative;
|
|
}
|
|
|
|
.liked-cover {
|
|
width: 90%;
|
|
height: 90%;
|
|
border-radius: 24rpx;
|
|
transform: rotate(-22deg);
|
|
transform-origin: center center;
|
|
position: relative;
|
|
z-index: 3;
|
|
padding: 0.25rem;
|
|
}
|
|
|
|
.liked-cover-frame {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 110%;
|
|
height: 110%;
|
|
z-index: 2;
|
|
transform: rotate(-22deg);
|
|
transform-origin: center center;
|
|
}
|
|
|
|
.liked-info {
|
|
flex: 1;
|
|
min-width: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.liked-status {
|
|
font-size: 28rpx;
|
|
color: #fff;
|
|
text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.7);
|
|
font-weight: 600;
|
|
white-space: nowrap;
|
|
text-overflow: ellipsis;
|
|
margin-bottom: 16rpx;
|
|
}
|
|
|
|
.liked-score-row {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.liked-score {
|
|
font-size: 26rpx;
|
|
color: #fff;
|
|
text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.7);
|
|
font-weight: 700;
|
|
margin-right: 8rpx;
|
|
}
|
|
|
|
.fire-icon {
|
|
width: 32rpx;
|
|
height: 32rpx;
|
|
align-self: flex-end;
|
|
margin-top: 4rpx;
|
|
}
|
|
|
|
.liked-reward {
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 8rpx;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.reward-token-icon {
|
|
width: 56rpx;
|
|
height: 56rpx;
|
|
}
|
|
|
|
.reward-amount {
|
|
font-size: 28rpx;
|
|
color: #c060e0;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.empty-liked {
|
|
padding: 60rpx 0;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
</style>
|