You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

820 lines
19 KiB

<template>
<view class="detail-container">
<!-- 轮播图区域 -->
<view class="banner-content">
<swiper
class="top-banner"
:circular="true"
:interval="6000"
:duration="800"
:indicator-dots="false"
:autoplay="true"
@change="swiperChange"
>
<swiper-item v-for="(item, index) in topBanner" :key="index">
<image
class="top-banner"
:src="showImg(item)"
mode="aspectFill"
></image>
</swiper-item>
</swiper>
<view class="dot-container">
<view
:class="['dot-line', index == swiperIndex ? 'active' : '']"
v-for="(item, index) in topBanner"
:key="index"
></view>
</view>
<!-- 页码指示器 -->
<view class="page-indicator">
<text class="page-text"
>{{ swiperIndex + 1 }}/{{ topBanner.length }}</text
>
</view>
</view>
<!-- 商品信息区域 -->
<view class="product-info">
<!-- 标题和标签 -->
<view class="title-section">
<view class="product-title">{{ goodsInfo.title||'-' }}</view>
<view class="tags-container">
<view class="limit-tag">限量</view>
<view class="limit-count">{{ goodsInfo.publishQuantity||0 }}份</view>
<view class="remaining">剩余 {{ goodsInfo.remainQuantity||0 }}份</view>
</view>
</view>
<!-- 价格和收藏 -->
<view class="price-section">
<view class="price-container">
<text class="currency">¥</text>
<text class="price">{{ goodsInfo.price||0 }}</text>
</view>
<view class="collect-container">
<image
v-if="!goodsInfo.type"
class="heart-icon"
src="https://epic.js-dyyj.com/uploads/20250728/2f3ae212c01fa3b67be81abc5723cf5c.png"
@click.stop="handleLikeClick()"
></image>
<image
v-if="goodsInfo.type"
class="heart-icon"
src="https://epic.js-dyyj.com/uploads/20250728/dd7ed269b24e84a2dd141da6ab980fd6.png"
@click.stop="handleLikeClick()"
></image>
<text class="collect-count"
>{{ goodsInfo.collectQuantity || 0 }}人收藏</text
>
</view>
</view>
<!-- 权益信息 -->
<!-- <view class="equity-section">
<view class="equity-row">
<view class="equity-item">
<view class="equity-label">创作数字资产所属方者</view>
<view class="equity-value">苏州xxx博物馆</view>
</view>
<view class="equity-item">
<view class="equity-label">数字资产权力方</view>
<view class="equity-value">江苏大运河见</view>
</view>
<view class="equity-item">
<view class="equity-label">备案平台</view>
<view class="equity-value">江苏文交所</view>
</view>
</view>
</view> -->
<!-- 权益信息标题 -->
<!-- <view class="equity-title">
<view class="title-line"></view>
<text class="title-text">权益信息</text>
<view class="title-line"></view>
</view> -->
<!-- 权益详情 -->
<view class="equity-details">
<!-- 显示前两个权益项 -->
<view
class="equity-detail-item"
v-for="(item, index) in displayEquityList"
:key="index"
>
<view class="detail-content-wrapper">
<!-- <text v-if="item.goodsType == 1" class="detail-label">
{{index+1}}、 数字资产
</text>
<text class="detail-label" v-else-if="item.goodsType == 2">
{{index+1}}、 资源产品
</text>
<text class="detail-label" v-else-if="item.goodsType == 3">
{{index+1}}、 景点门票
</text> -->
<text class="detail-label">
产品{{
["一", "二", "三", "四", "五", "六", "七", "八", "九", "十"][
index
]
}}:
</text>
<text class="detail-content"
>{{ item.goodsName }}{{ item.skuName || "" }}</text
>
<text class="detail-content">X{{ item.bindQuantity }}份</text>
</view>
<!-- 在最后一个显示项的右侧添加展开收起图标 -->
<!-- <view v-if="index === displayEquityList.length - 1" class="toggle-icon" @click="toggleEquityExpand">
<text class="icon-text">{{
isEquityExpanded ? "收起" : "展开"
}}</text>
<text class="icon-arrow" :class="{ expanded: isEquityExpanded }">▼</text>
</view> -->
</view>
</view>
</view>
<!-- Tab切换区域 -->
<scroll-view class="tab-nav" scroll-x="true" :show-scrollbar="false">
<view class="tab-container">
<view
v-for="(tab, index) in tabList"
:key="index"
:class="['tab-item', { active: currentTab === index }]"
@click="switchTab(index)"
>
<text class="tab-text">{{ tab.name }}</text>
</view>
</view>
</scroll-view>
<view class="tab-section">
<!-- Tab导航 -->
<!-- Tab内容 -->
<view class="tab-content">
<!-- 登记证书 -->
<view v-if="currentTab === 0" class="tab-panel">
<view class="certificate-container">
<image
class="certificate-image"
:src="goodsInfo.ipDigitalAsset.copyrightUrl"
mode="widthFix"
>
</image>
</view>
</view>
<!-- IP资产详情 -->
<view v-if="currentTab === 1" class="tab-panel">
<view class="" v-html="goodsInfo.ipDigitalAsset.detailUrl"> </view>
</view>
<!-- 门票详情 -->
<view
v-if="currentTab === 2 && goodsInfo.sku && goodsInfo.sku.product"
class="tab-panel"
>
<view class="" v-html="scene.content"> </view>
<view class="" v-html="goodsInfo.sku.extend.bookInfo"> </view>
<view class="" v-html="scene.time_info"> </view>
<view class="" v-html="scene.extra_info"> </view>
<!-- <view class="" v-html="goodsInfo.sku.product.bookInfo"> </view>
<view class="" v-html="goodsInfo.sku.product.cancelInfo"> </view> -->
</view>
<!-- 商品详情 -->
<template v-for="(item, index) in goodsInfo.goodsVos">
<view v-if="currentTab == index + 3" class="tab-panel">
<view class="" v-html="item.detailUrl"> </view>
</view>
</template>
</view>
</view>
<!-- 立即购买按钮 -->
<view class="purchase-section">
<view class="purchase-button" @click="handlePurchase">
<text class="purchase-text">立即购买</text>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
topBanner: [],
list: [],
swiperIndex: 0,
isEquityExpanded: false, // 权益详情展开状态
currentTab: 0, // 当前选中的tab索引
tabList: [],
equityList: [],
goodsInfo: null,
scene:null,
};
},
computed: {
// 根据展开状态显示不同数量的权益项
displayEquityList() {
return this.equityList;
// return this.isEquityExpanded ?
// this.equityList :
// this.equityList.slice(0, 2);
},
},
onLoad(e) {
this.getDetail(e.id);
},
methods: {
getDetail(benefitPackageId) {
this.Post(
{},
`/framework/benefitPackage/detail/${benefitPackageId}`,
"DES"
).then((res) => {
res.data.goodsVos.forEach((element) => {
element.detailUrl = this.addImgStyleToHtml(element.detailUrl);
});
if(res.data.sku&&res.data.sku.product.scene){
this.scene = JSON.parse(res.data.sku.product.scene)
this.scene.content = this.addImgStyleToHtml(this.scene.content);
}
console.log(this.scene,'场景信息')
this.goodsInfo = res.data;
this.goodsInfo.ipDigitalAsset.detailUrl = this.addImgStyleToHtml(
this.goodsInfo.ipDigitalAsset.detailUrl
);
this.topBanner = res.data.coverUrl.split(",");
this.equityList = res.data.benefitGoods;
this.generateTabList();
});
},
handleLikeClick() {
this.Post(
{
packageId: this.goodsInfo.benefitPackageId,
type: !this.goodsInfo.type,
},
"/framework/benefitPackage/collect",
"DES"
).then((res) => {
this.goodsInfo.type = !this.goodsInfo.type;
});
},
swiperChange(e) {
this.swiperIndex = e.detail.current;
},
// 切换权益详情展开收起状态
toggleEquityExpand() {
this.isEquityExpanded = !this.isEquityExpanded;
},
// 处理购买点击
handlePurchase() {
let id = this.goodsInfo.sku&&this.goodsInfo.sku.product.sceneId
wx.navigateToMiniProgram({
appId: 'wx4bb7b6050831f585',
path: 'pages/info/sceneProductInfo/index?id='+id,
envVersion: process.env.NODE_ENV === 'development'?'trial':'release',
success(res) {
// 打开成功
},
fail(e){
console.log(e)
}
})
// 这里可以添加购买逻辑
},
// 切换tab
switchTab(index) {
this.currentTab = index;
},
addImgStyleToHtml(htmlStr) {
return htmlStr.replace(/<img\b([^>]*)>/gi, (match, attrs) => {
// 检查是否已有 style 属性
if (/style\s*=/.test(attrs)) {
// 已有 style,合并 width:100%
return `<img${attrs.replace(
/style\s*=\s*(['"])(.*?)\1/,
(m, quote, styleVal) => {
// 合并 width:100% 到已有 style
let newStyle = styleVal;
if (!/width\s*:\s*100%/.test(styleVal)) {
newStyle = `width:100%;${styleVal}`;
}
return `style=${quote}${newStyle}${quote}`;
}
)}>`;
} else {
// 没有 style,直接加
return `<img${attrs} style="width:100%">`;
}
});
},
// 根据商品信息动态生成Tab列表
generateTabList() {
this.tabList = [];
// 基础Tab - 始终显示
this.tabList.push({ name: "登记证书" });
this.tabList.push({ name: "IP资产详情" });
// 根据商品信息动态添加Tab
if (this.goodsInfo) {
// 如果有门票信息添加门票详情Tab
if (this.goodsInfo.sku && this.goodsInfo.sku.product) {
this.tabList.push({ name: "门票详情" });
}
// 如果有goodsVos内容添加商品详情Tab
if (this.goodsInfo.goodsVos) {
this.goodsInfo.goodsVos.forEach((element) => {
this.tabList.push({ name: "权益商品" });
});
}
}
},
},
};
</script>
<style lang="scss" scoped>
.detail-container {
background: #f5f5f5;
min-height: 100vh;
}
.banner-content {
width: 100%;
height: 700rpx;
position: relative;
.top-banner {
width: 100%;
height: 100%;
}
.dot-container {
position: absolute;
bottom: 43rpx;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
left: 0;
.dot-line {
width: 52rpx;
height: 4rpx;
margin: 0 8rpx;
background: RGBA(189, 170, 173, 0.8);
&.active {
background: #94fafa;
}
}
}
.page-indicator {
position: absolute;
bottom: 20rpx;
right: 20rpx;
// background: rgba(0, 0, 0, 0.5);
border-radius: 10rpx;
padding: 10rpx 20rpx;
.page-text {
font-size: 24rpx;
color: #fff;
font-weight: 500;
}
}
}
.product-info {
background: white;
padding: 40rpx 30rpx;
margin: 20rpx;
border-radius: 20rpx 20rpx 0 0;
padding-bottom: 20rpx;
.title-section {
margin-bottom: 30rpx;
.product-title {
font-size: 31rpx;
font-weight: bold;
color: #000000;
line-height: 1.4;
margin-bottom: 20rpx;
}
.tags-container {
display: flex;
align-items: center;
flex-wrap: wrap;
.limit-tag {
background: #94fafa;
color: #333333;
padding: 8rpx 16rpx;
font-size: 26rpx;
border-radius: 6rpx 0 0 6rpx;
}
.limit-count {
background: #f0f0f0;
color: #000000;
padding: 8rpx 16rpx;
font-size: 26rpx;
border-radius: 0rpx 6rpx 6rpx 0;
}
.remaining {
color: #808080;
font-size: 26rpx;
margin-left: auto;
}
}
}
.price-section {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
.price-container {
display: flex;
align-items: baseline;
.currency {
font-size: 28rpx;
color: #333;
font-weight: bold;
}
.price {
font-size: 40rpx;
color: #333;
font-weight: bold;
font-family: "Futura";
}
}
.collect-container {
display: flex;
align-items: center;
gap: 10rpx;
.heart-icon {
width: 35rpx;
height: 29rpx;
transition: all 0.3s ease;
flex-shrink: 0;
&.liked {
opacity: 1;
filter: hue-rotate(320deg) saturate(2);
}
&:active {
transform: scale(1.2);
}
}
.collect-count {
color: #231815;
font-size: 28rpx;
font-weight: 500;
}
}
}
.equity-section {
margin-bottom: 40rpx;
border-top: 0.5rpx solid #e5e5e5;
border-bottom: 0.5rpx solid #e5e5e5;
padding: 40rpx 0;
.equity-row {
display: flex;
justify-content: space-between;
gap: 20rpx;
.equity-item {
text-align: left;
.equity-label {
font-size: 23rpx;
color: #231815;
font-weight: bold;
margin-bottom: 10rpx;
line-height: 1.3;
}
.equity-value {
font-size: 20rpx;
color: #595757;
font-weight: 500;
line-height: 1.3;
}
}
}
}
.equity-title {
display: flex;
align-items: center;
justify-content: center;
margin: 40rpx 0 30rpx;
.title-line {
width: 30rpx;
height: 2rpx;
background: #94fafa;
}
.title-text {
padding: 0 30rpx;
font-size: 25rpx;
color: #94fafa;
font-weight: bold;
}
}
.equity-details {
border-top: 1rpx solid #e5e5e5;
padding-top: 60rpx;
padding-bottom: 20rpx;
.equity-detail-item {
margin-bottom: 10rpx;
line-height: 1.5;
.detail-content-wrapper {
.detail-label {
font-size: 28rpx;
color: #808080;
font-weight: 500;
margin-right: 10rpx;
}
.detail-content {
font-size: 28rpx;
color: #808080;
font-weight: 500;
margin-right: 10rpx;
}
}
.toggle-icon {
display: flex;
align-items: center;
gap: 8rpx;
cursor: pointer;
padding: 0rpx;
margin-left: 20rpx;
.icon-text {
font-size: 22rpx;
color: #666;
}
.icon-arrow {
font-size: 20rpx;
color: #666;
transition: transform 0.3s ease;
transform: rotate(0deg);
&.expanded {
transform: rotate(180deg);
}
}
&:active {
opacity: 0.7;
}
}
}
}
}
// Tab导航
.tab-nav {
margin: 0 40rpx;
margin-top: 40rpx;
white-space: nowrap;
width: 690rpx;
.tab-container {
display: flex;
min-width: 100%;
.tab-item {
padding: 10rpx 20rpx;
text-align: center;
color: #3e3a39;
cursor: pointer;
transition: all 0.3s ease;
background-color: #94fafa66;
display: flex;
align-items: center;
flex-shrink: 0;
margin-right: 16rpx;
&:last-child {
margin-right: 0;
}
&.active {
background-color: #94fafa;
color: #525454;
font-size: 30rpx;
border-radius: 10rpx 10rpx 0 0;
font-weight: bold;
}
.tab-text {
font-size: 30rpx;
white-space: nowrap;
}
}
}
}
// Tab切换区域
.tab-section {
margin: 0 20rpx;
background-color: #fff;
border-radius: 20rpx;
overflow: hidden;
margin-bottom: calc(20px + constant(safe-area-inset-bottom));
margin-bottom: calc(20px + env(safe-area-inset-bottom));
// Tab内容
.tab-content {
padding: 30rpx;
.tab-panel {
min-height: 400rpx;
img {
width: 100%;
}
// 证书容器
.certificate-container {
display: flex;
justify-content: center;
align-items: center;
.certificate-image {
width: 100%;
max-width: 600rpx;
height: auto;
border-radius: 12rpx;
}
}
// 信息内容
.info-content {
padding: 20rpx 0;
.info-item {
display: flex;
margin-bottom: 20rpx;
align-items: flex-start;
.info-label {
font-size: 28rpx;
color: #666;
min-width: 160rpx;
flex-shrink: 0;
}
.info-value {
font-size: 28rpx;
color: #333;
flex: 1;
line-height: 1.5;
}
}
}
// 权益信息内容
.equity-info-content {
padding: 20rpx 0;
.equity-info-item {
display: flex;
margin-bottom: 20rpx;
align-items: flex-start;
.equity-info-label {
font-size: 28rpx;
color: #666;
min-width: 160rpx;
flex-shrink: 0;
}
.equity-info-value {
font-size: 28rpx;
color: #333;
flex: 1;
line-height: 1.5;
}
}
.equity-description {
margin-top: 30rpx;
padding: 20rpx;
background-color: #f8f9fa;
border-radius: 12rpx;
.description-text {
font-size: 26rpx;
color: #666;
line-height: 1.6;
}
}
}
// 权益详情列表
.equity-detail-list {
.equity-detail-item {
margin-bottom: 30rpx;
padding: 20rpx;
background: #f8f9fa;
border-radius: 12rpx;
.equity-name {
font-size: 28rpx;
color: #333;
font-weight: 600;
margin-bottom: 12rpx;
}
.equity-desc {
font-size: 26rpx;
color: #666;
line-height: 1.5;
}
}
}
}
}
}
// 立即购买按钮
.purchase-section {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background: white;
padding: 20rpx 30rpx;
border-top: 1rpx solid #e5e5e5;
z-index: 100;
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
.purchase-button {
width: 690rpx;
height: 88rpx;
margin: 0 auto;
background: #94fafa;
border-radius: 44rpx;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 8rpx 20rpx #94fafa;
transition: all 0.3s ease;
&:active {
transform: scale(0.98);
box-shadow: 0 4rpx 10rpx rgba(255, 30, 85, 0.2);
}
.purchase-text {
font-size: 32rpx;
font-weight: bold;
color: #525454;
}
}
}
// 为底部按钮预留空间
.detail-container {
padding-bottom: 140rpx;
}
</style>