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.
 
 
 
 

836 lines
18 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" v-if="goodsInfo.agent" @click.stop="toAgent(goodsInfo)">
<image
class="avatar"
:src="showImg(goodsInfo.agent.headImage)"
mode="aspectFill"
></image>
</view> -->
</view>
<!-- 商品信息区域 -->
<view class="product-info">
<!-- 标题和标签 -->
<view class="" style="display: flex;justify-content: space-between">
<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="agent-info" v-if="goodsInfo.agent" @click.stop="toAgent(goodsInfo)">
<image class="avatar" :src="showImg(goodsInfo.agent.headImage)" mode="aspectFill"></image>
<view class="agent">
IP-AGENT
</view>
<view class="agent-name">
{{goodsInfo.agent.name}}
</view>
<view class="agent-use">
点击收听
</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-details">
<!-- 显示前两个权益项 -->
<view class="equity-detail-item" v-for="(item, index) in displayEquityList" :key="index">
<view class="detail-content-wrapper">
<image style="width: 110rpx;height: 110rpx;flex-shrink: 0;margin-right: 20rpx;" mode="aspectFill"
:src="showImgJdsz(item.mainUrl&&item.mainUrl.split(',')[0])"></image>
<view class="detail-info">
<view class="detail-label">
产品{{
["一", "二", "三", "四", "五", "六", "七", "八", "九", "十"][
index
]
}}
</view>
<view class="detail-content">{{ item.goodsName }}{{ item.skuName || "" }}X{{ item.bindQuantity }}</view>
<view class="detail-content" style="font-size: 22rpx;margin-top: auto;color: #808080;">
{{ item.goodsType==3?item.subtitle: item.description }}
</view>
</view>
</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>
<!-- 商品详情 -->
<view v-if="currentTab === 3 && goodsInfo.detailUrl" class="tab-panel">
<view class="" v-html="goodsInfo.detailUrl"> </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.goodsInfo.detailUrl = this.addImgStyleToHtml(this.goodsInfo.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
this.toJdszWx('pages/info/sceneProductInfo/index?id=' + id)
// 这里可以添加购买逻辑
},
// 切换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%">`;
}
});
},
toAgent(e) {
if (e.agentStatus) {
uni.navigateTo({
url: "/subPackages/other/evita?id="+e.agent.agentId
});
} else {
uni.showToast({
title: '请先购买当前商品',
icon: 'none'
})
}
},
showImgJdsz(img) {
if (!img) return;
if (img.indexOf("https://") != -1 || img.indexOf("http://") != -1) {
return img;
} else {
return this.JDSU_IMG_URL + img;
}
},
// 根据商品信息动态生成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: "门票详情"
});
}
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: 1000rpx;
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 {
padding: 40rpx 10rpx;
margin: 20rpx;
padding-bottom: 1rpx;
.title-section {
width: 370rpx;
margin-bottom: 30rpx;
.product-title {
font-size: 34rpx;
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;
}
.limit-count {
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: 40rpx;
margin-top: 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;
.equity-detail-item {
margin-bottom: 30rpx;
line-height: 1.5;
.detail-content-wrapper {
display: flex;
align-items: center;
.detail-info{
display: flex;
flex-direction: column;
justify-content: space-between;
height: 110rpx;
}
.detail-label {
width: 100%;
font-size: 22rpx;
color: #808080;
font-weight: bold;
margin-right: 10rpx;
}
.detail-content {
width: 550rpx;
font-size: 26rpx;
color: #000000;
font-weight: 500;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.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;
}
.avatar {
width: 119rpx;
height: 119rpx;
border-radius: 50%;
}
.agent-info {
text-align: center;
.agent {
font-size: 18rpx;
}
.agent-name {
font-size: 28rpx;
font-weight: bold;
}
.agent-use {
font-size: 22rpx;
color: #00FFFF;
margin-top: 5rpx;
}
}
</style>