topfans/frontend/pages/components/ShareModal.vue
2026-05-21 18:51:15 +08:00

320 lines
6.2 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="share-modal" v-if="visible" @tap="handleClose">
<view class="modal-content" @tap.stop>
<!-- 标题 -->
<text class="modal-title">分享藏品</text>
<!-- 关闭按钮 -->
<view class="close-btn" @tap="handleClose">
<image class="close-icon" src="/static/starbookcontent/tuichu.png" mode="aspectFit"></image>
</view>
<!-- 图片区域 -->
<view class="share-image-wrapper">
<image class="share-image" :src="coverUrl" mode="aspectFill" @error="onImageError"></image>
<!-- 头像+ID 遮罩 -->
<view class="user-info-overlay">
<image class="user-avatar" :src="userAvatarUrl || '/static/square/gerenzhongxincangpinkuang.png'"
mode="aspectFill"></image>
<text class="user-id">ID: {{ ownerNickname }}</text>
</view>
<!-- 二维码 -->
<view class="qrcode-wrapper">
<image class="qrcode-image" :src="qrcodeUrl" mode="aspectFit" @error="onQrcodeError"></image>
</view>
<!-- 文字 -->
<view class="text-overlay">
<view class="brand-line">
<text class="brand-name">TOPFANS</text>
<text class="brand-slogan">让热爱被发现</text>
</view>
<text class="brand-desc">AI做周边应援全免费</text>
</view>
</view>
<!-- 保存图片 + 微信按钮 -->
<view class="action-buttons">
<view class="action-btn save-btn" @tap="handleSaveImage">
<image class="action-icon" src="/static/assetDetail/wenhao.png" mode="aspectFit"></image>
<text class="action-text">保存图片</text>
</view>
<view class="action-btn wechat-btn" @tap="handleShareToWeChat">
<image class="action-icon" src="/static/assetDetail/shangxiahuadong.png" mode="aspectFit"></image>
<text class="action-text">微信</text>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue';
const props = defineProps({
visible: {
type: Boolean,
default: false
},
coverUrl: {
type: String,
default: ''
},
ownerNickname: {
type: String,
default: ''
},
qrcodeUrl: {
type: String,
default: ''
}
});
// 当前用户头像
const userAvatarUrl = ref('');
const loadCurrentUser = () => {
try {
const userStr = uni.getStorageSync('user');
if (userStr) {
const userInfo = JSON.parse(userStr);
userAvatarUrl.value = userInfo?.avatar_url || '';
}
} catch (e) {
console.error('解析用户信息失败:', e);
}
};
loadCurrentUser();
const onImageError = (e) => {
console.log('图片加载失败', e);
};
const onQrcodeError = (e) => {
console.log('二维码加载失败', e);
};
// 关闭
const emit = defineEmits(['close']);
const handleClose = () => {
emit('close');
};
// 保存图片
const handleSaveImage = () => {
if (!props.coverUrl) {
uni.showToast({ title: '图片加载中', icon: 'none' });
return;
}
uni.saveImageToPhotosAlbum({
filePath: props.coverUrl,
success: () => {
uni.showToast({ title: '保存成功', icon: 'success' });
},
fail: () => {
uni.showToast({ title: '保存失败', icon: 'none' });
}
});
};
// 分享到微信
const handleShareToWeChat = () => {
uni.share({
provider: 'weixin',
scene: 'WXSceneSession',
title: 'TOPFANS - 让热爱被发现',
summary: 'AI做周边应援全免费',
imageUrl: props.coverUrl,
success: () => {
uni.showToast({ title: '分享成功', icon: 'success' });
},
fail: () => {
uni.showToast({ title: '分享失败', icon: 'none' });
}
});
};
</script>
<style scoped>
.share-modal {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.8);
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
}
.modal-content {
position: relative;
top: 128rpx;
width: 80%;
display: flex;
flex-direction: column;
align-items: center;
gap: 40rpx;
}
.modal-title {
font-size: 36rpx;
font-weight: bold;
color: #fff;
font-family: 'yt', sans-serif;
text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.8);
margin-bottom: 16rpx;
}
.close-btn {
position: absolute;
top: -36rpx;
left: 0;
width: 64rpx;
height: 64rpx;
z-index: 10;
padding: 10rpx;
}
.close-icon {
width: 64rpx;
height: 64rpx;
}
.share-image-wrapper {
position: relative;
width: 100%;
border-radius: 24rpx;
overflow: hidden;
background: #1a1a2e;
min-height: 960rpx;
}
.share-image {
width: 100%;
height: 960rpx;
display: block;
background: rgba(255, 255, 255, 0.1);
}
.user-info-overlay {
position: absolute;
top: 58%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
align-items: center;
gap: 12rpx;
}
.user-avatar {
width: 72rpx;
height: 72rpx;
border-radius: 50%;
/* border: 4rpx solid #fff; */
background: rgba(255, 255, 255, 0.2);
}
.user-id {
font-size: 32rpx;
color: #fff;
font-family: 'yt', sans-serif;
text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.8);
}
.qrcode-wrapper {
position: absolute;
bottom: 184rpx;
left: 50%;
transform: translateX(-50%);
width: 160rpx;
height: 160rpx;
background-image: url('@/static/rank/activity-support-icon/beijingkuang.png');
background-size: 105% 130%;
background-position: center;
}
.qrcode-image {
width: 144rpx;
height: 144rpx;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.text-overlay {
position: absolute;
bottom: 24rpx;
left: 0;
right: 0;
display: flex;
flex-direction: column;
align-items: center;
gap: 8rpx;
}
.brand-line {
display: flex;
align-items: center;
gap: 16rpx;
}
.brand-name {
font-size: 32rpx;
font-weight: bold;
color: #fff;
font-family: 'yt', sans-serif;
text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.8);
}
.brand-slogan {
font-size: 40rpx;
font-weight: bold;
color: #fff;
font-family: 'yt', sans-serif;
text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.8);
}
.brand-desc {
font-size: 32rpx;
color: rgba(255, 255, 255, 0.9);
font-family: 'yt', sans-serif;
text-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.6);
}
.action-buttons {
display: flex;
gap: 32rpx;
width: 100%;
justify-content: center;
}
.action-btn {
display: flex;
flex-direction: column;
align-items: center;
gap: 12rpx;
padding: 16rpx 24rpx;
border-radius: 24rpx;
}
.action-btn:active {
opacity: 0.8;
}
.action-icon {
width: 64rpx;
height: 64rpx;
}
.action-text {
font-size: 28rpx;
color: #fff;
font-family: 'yt', sans-serif;
text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.5);
}
</style>