Browse Source

style

dev_des
1054425342@qq.com 2 months ago
parent
commit
c3ebf719d3
  1. 2
      App.vue
  2. 2
      components/Book.vue
  3. 39
      components/DynamicIsland.vue
  4. 32
      components/GPT/index.vue
  5. 48
      components/GPT/utils/socket.js
  6. 29
      components/ProductSection.vue
  7. 15
      components/header.vue
  8. 2
      main.js
  9. 3
      pages.json
  10. 50
      pages/index/iSoul.vue
  11. 7
      pages/index/index.vue
  12. 4
      pages/index/intelligentAgent.vue
  13. 15
      pages/index/readingBody.vue
  14. 19
      pages/index/sensoryStore.vue
  15. 5
      pages/index/timeShopBank.vue
  16. 324
      subPackages/equityGoods/detail.vue
  17. 85
      subPackages/other/evita.vue
  18. 15
      vue.config.js

2
App.vue

@ -7,6 +7,7 @@ export default {
bgMusic: null,
isMusicPlaying: false,
musicSrc: "https://static.ticket.sz-trip.com/epicSoul/EpicSouls.mp3",
initMusicSrc:"https://static.ticket.sz-trip.com/epicSoul/EpicSouls.mp3",
// 使
userSessionId: null,
networkStartTime: null, //
@ -235,6 +236,7 @@ export default {
console.log("bgMusic", this.globalData.bgMusic);
//
if (this.globalData.bgMusic) {
console.log('销毁bgMusic')
this.globalData.bgMusic.stop();
this.globalData.bgMusic.destroy();
this.globalData.bgMusic = null;

2
components/Book.vue

@ -10,7 +10,7 @@
@click="handleMoreClick"
>
<text class="title">EPIC SOUL阅读体</text>
<view class="more-btn">更多 <uni-icons size="16" color="#000000" type="arrowright" /></view>
<view class="more-btn"><image src="https://des.js-dyyj.com/data/2025/08/31/affb21f0-fcc1-4746-9543-0d54369aa315.png" style="width:124.6rpx;height: 36rpx;"/></view>
</div>
</view>
<!-- 轮播容器 -->

39
components/DynamicIsland.vue

@ -18,6 +18,11 @@
<image class="avatar"
src="https://epic.js-dyyj.com/uploads/20250826/92b0a21e9125fc21ca294a408bf3508f.png"
mode="aspectFill"></image>
<view
class="ai-label"
>智能体</view
>
</view>
<view class="" style="display: flex;flex-direction: column;justify-content: space-between;height: 100%;">
<view class="profile-info">
@ -25,9 +30,9 @@
<text class="profile-name">EVITA</text>
</view>
<view class="platform-link">
<view class="link-text" @click="toDesInfo" style="margin-bottom: 30rpx;">DES介绍 >>
<view class="link-text" @click="toDesInfo" >DES介绍 >>
</view>
<view class="link-text">DES广播 >></view>
<!-- <view class="link-text">DES广播 >></view> -->
</view>
</view>
</view>
@ -363,7 +368,7 @@
// "https://des.js-dyyj.com/dist/#/",
// });
uni.navigateTo({
url:'/subPackages/other/evita?id=1'
url:'/subPackages/other/evita?id=0'
})
},
@ -599,12 +604,14 @@
position: relative;
margin-right: 10rpx;
width: 140rpx;
height: 140rpx;
display: flex;
flex-direction: column;
align-items: center;
}
.avatar {
width: 140rpx;
height: 140rpx;
width: 130rpx;
height: 130rpx;
border-radius: 50%;
}
@ -805,4 +812,24 @@
margin-right: 10rpx;
}
}
.ai-label {
border: 1rpx solid;
padding: 0rpx 15rpx;
height: 40rpx;
line-height: 38rpx;
font-weight: bold;
font-size: 20rpx;
border-radius: 4rpx;
border-color: #333333;
color: #333333;
display: inline;
margin-top: 10rpx;
}
.ai-name {
font-size: 27rpx;
font-weight: bold;
color: #ffffff;
margin-left: 10rpx;
}
</style>

32
components/GPT/index.vue

@ -279,6 +279,7 @@ export default {
async audio(n, cb) {
console.log('【audio------>】', n);
this.audioArray = this.audioArray.slice(-10)
const txt = this.stripHtmlTags(n.content)
if (!txt) { return }
this.audioCtx && this.audioCtx.destroy()
@ -290,7 +291,6 @@ export default {
}
const texts = splitTextForTTS(txt)
console.log('语言划分', texts)
this.audioActive = n.timestamp
for (let index = 0; index < texts.length; index++) {
const txt = texts[index];
@ -309,17 +309,15 @@ export default {
return new Promise(async (resolve, reject) => {
if (!this.audioStatus) { reject() }
const url = await this.loadAudioUrl(text)
console.log('播放文字', text)
console.log('开始播放文字', text)
cb && cb(text)
this.audioCtx = wx.createInnerAudioContext();
this.audioCtx.src = url //'data:audio/wav;base64,' + res.data.data
this.audioCtx.src = 'data:audio/wav;base64,' + url
this.audioCtx.play()
this.audioCtx.onStop(() => {
this.delAudioFile(url)
resolve()
})
this.audioCtx.onEnded(() => {
this.delAudioFile(url)
resolve()
})
});
@ -328,6 +326,7 @@ export default {
if (this.audioArray[text]) {
return Promise.resolve(this.audioArray[text])
} else {
console.log('-----开始请求语音合成-----', text)
return new Promise((resolve, reject) => {
uni.request({
method: "post",
@ -336,28 +335,23 @@ export default {
voiceType: this.socketObj.robotObj.voiceType ?? 1002
},
dataType: "json",
url: `https://des.js-dyyj.com/xcx/api/voice/tts`,
url: `https://des.js-dyyj.com/xcx/api/voice/tts/new`,
success: (res) => {
console.log('文字合成语音', res)
if (res.data.code) {
this.audioArray[text] = res.data.msg
const audio = wx.createInnerAudioContext();
audio.src = res.data.msg;
audio.onCanplay(() => {
audio.destroy(); //
});
resolve(res.data.msg)
console.log('-----请求语音合成回参-----', res)
if (res.data.code == 200) {
console.log('-----请求语音合成成功-----', text)
this.audioArray[text] = res.data.data.audio
resolve(res.data.data.audio)
} else {
console.log('-----请求语音合成失败-----', text)
wx.showToast({ title: '文字转化失败' });
reject()
}
},
fail: (err) => {
console.log("【init msg-------getDemoToken---->】", err);
console.log("-------请求语音合成失败---->】", err);
wx.showToast({ title: '文字转化失败' });
},
});
})

48
components/GPT/utils/socket.js

@ -3,7 +3,7 @@ import GLOBAL_OBJ from "./global";
import "./EventHub";
import { setMsgData } from "./message";
// 心跳间隔
const HEART_BEAT_TIME = 20000;
const HEART_BEAT_TIME = 15000;
// 心跳最大失败次数(超过此次数重连)
const HEART_BEAT_FAIL_NUM = 1;
// 重连间隔
@ -18,9 +18,13 @@ export default class Socket {
this.selfCloseStatus = false
this.reconnectLock = false
console.log("Socket init", GLOBAL_OBJ);
// 失败回答
this.failMsg = {}
}
getToken() {
return new Promise((resolve, reject) => {
console.log('-----开始请求token-----')
uni.request({
method: "GET",
dataType: "json",
@ -67,7 +71,7 @@ export default class Socket {
const socket = wx.connectSocket({
url: `${origin}${path}?EIO=4&transport=websocket`,
success: (e) => {
console.log("创建链接成功", e, socket);
console.log("创建链接成功", e);
},
complete: (e) => {
console.log("socket - complete", e);
@ -136,7 +140,11 @@ export default class Socket {
}
const num = "" + data.substring(0, 2);
if (num == "40") {
console.log("创建对话成功", e);
// 发送失败信息
this.sendFailMsg()
resolve();
// 链接成功
}
this.createInter();
@ -162,27 +170,41 @@ export default class Socket {
doConnectTimeout() {
// 重连一次
if (!this.reconnectLock) {
this.reconnectLock = true;
console.log("websocket 异常关闭 开始重连");
this.connectSocketTimeOut = setTimeout(() => {
this.createSocket({
complete: function (res) {
this.reconnectLock = false;
// this.reconnectLock = false;
},
});
}, RECONNECT_TIME);
}
}
onConnect(e) {
console.log("websocket connect", e);
}
send(e, t) {
console.log("开始请求 websocket send", e);
this.socket && this.socket.send(e);
this.createInter();
}
sendFailMsg() {
const content = Object.values(this.failMsg)
if (content.length) {
console.log('开始重新发送失败信息')
// 重新发送失败的信息
for (let index = 0; index < content.length; index++) {
const item = content[index];
if (!item.status) {
console.log('失败消息', item)
// 失败消息 在发送一遍
this.send(item.data.socketParams,item.data.contentType )
}
}
}
}
getMsgData(e) {
if (e && typeof e == "string") {
const status = e.indexOf("42");
@ -231,7 +253,13 @@ export default class Socket {
content: params.realContent ? params.realContent : params.content,
};
msgParams && setMsgData(msgParams);
this.failMsg[params.request_id] = {
data: {
socketParams,
contentType
},
statue: false
}
break;
}
}
@ -256,6 +284,11 @@ export default class Socket {
}
if (!params.is_from_self && params.is_final) {
if (this.failMsg[tmpParams.request_id]) {
this.failMsg[tmpParams.request_id].status = true
// 已回复 状态为true
}
// 回复结束 写入缓存
setMsgData(tmpParams);
}
@ -270,6 +303,7 @@ export default class Socket {
this.socket && this.socket.close();
this.socket = null;
}
this.failMsg={}
}
createInter() {

29
components/ProductSection.vue

@ -4,13 +4,15 @@
<view class="title-section" >
<div style="display: flex; align-items: center;justify-content: space-between;" @click="handleMoreClick">
<text class="title">{{ title }}</text>
<view class="more-btn" v-if="type!=3">更多 <uni-icons size="16" color="#000000" type="arrowright" /></view>
<view class="more-btn" v-if="type!=3">
<image src="https://des.js-dyyj.com/data/2025/08/31/affb21f0-fcc1-4746-9543-0d54369aa315.png" style="width:124.6rpx;height: 36rpx;"/>
</view>
</div>
</view>
<!-- 商品列表 -->
<view class="product-list">
<view class="" v-if="type==3">
<view class="" v-if="type==3" @click="toCGCwx">
<image
style="height: 357rpx;width: 657rpx;border-radius: 20rpx;"
:src="showImg('/uploads/20250829/66732062c2d566802a7842525e9b92e6.png')"
@ -188,19 +190,24 @@ export default {
});
},
toCGCwx(){
wx.navigateToMiniProgram({
appId: 'wx9d68934300b1fe90',
path: 'pages/index/index',
envVersion: 'release',
success(res) {
//
},
fail(e){
console.log(e)
}
})
},
toAgent(e){
if(e.agentStatus){
uni.navigateTo({
url: "/subPackages/other/evita?id="+e.agent.agentId
url: "/subPackages/other/evita?id="+e.benefitPackageId
});
}else{
uni.showToast({
title:'请先购买当前商品',
icon:'none'
})
}
},
//

15
components/header.vue

@ -39,12 +39,14 @@
</AreaPicker>
</view>
<image
<!-- <image
class="search-icon"
src="https://static.ticket.sz-trip.com/epicSoul/readingBody/search.png"
mode="heightFix"
@click="gotoPath('/subPackages/search/search?type=' + type)"
></image>
></image> -->
<uni-icons @click="handleBack" v-if="isBack" type="left" size="28"></uni-icons>
</view>
<view class="left-section" v-else></view>
@ -74,6 +76,10 @@ export default {
isSearch: {
type: Boolean,
default: true,
},
isBack: {
type: Boolean,
default: true,
},
address: {
type: Object,
@ -130,6 +136,11 @@ export default {
this.initRectInfo();
},
methods: {
handleBack(){
uni.switchTab({
url:'/pages/index/index'
})
},
initRectInfo() {
const sysInfo = uni.getSystemInfoSync();
this.statusBarHeight = sysInfo.statusBarHeight;

2
main.js

@ -13,7 +13,7 @@ Vue.config.productionTip = false
// 去除生产环境console
if (uni.getSystemInfoSync().platform !== "devtools") {
console.log = () => {}
// console.log = () => {}
}
App.mpType = 'app'

3
pages.json

@ -21,7 +21,8 @@
{
"path": "pages/index/sensoryStore",
"style": {
"navigationStyle": "custom"
"navigationStyle": "custom",
"navigationBarTextStyle": "white"
}
},
{

50
pages/index/iSoul.vue

@ -1,5 +1,6 @@
<template>
<view class="profile-container">
<BackButton />
<view
class="user-top"
:style="{
@ -9,7 +10,7 @@
}"
>
<!-- 状态栏占位 -->
<view class="status-bar-placeholder"></view>
<view class="status-bar-placeholder" :style="{ paddingTop: statusBarHeight + 'px' }"></view>
<!-- 顶部导航 -->
<view class="header">
<!-- <view class="back-btn" @click="goBack">
@ -225,6 +226,11 @@
<!-- 有感商品 -->
<view class="feeling-goods">
<view class="memorial-divider" style="margin-bottom: 0">
<view class="divider-line"></view>
<view class="divider-text">有感商品订单</view>
<view class="divider-line"></view>
</view>
<view class="goods-card">
<image
:src="
@ -254,7 +260,7 @@
<view class="memorial-section">
<view class="memorial-divider">
<view class="divider-line"></view>
<view class="divider-text">数字资产纪念册</view>
<view class="divider-text">数字资产收藏夹</view>
<view class="divider-line"></view>
</view>
<!-- 有数据时显示 -->
@ -273,9 +279,9 @@
class="memorial-img-single"
></image>
<view class="single-overlay">
<view class="single-badge">专属纪念册</view>
<view class="single-badge">专属收藏夹</view>
<view class="single-title">{{
memorialItems[0].goodsTitle || "数字资产纪念册"
memorialItems[0].goodsTitle || "数字资产收藏夹"
}}</view>
<view class="single-desc">{{ memorialItems[0].code }}</view>
<view class="single-action">
@ -301,7 +307,7 @@
></image>
<view class="memorial-info">
<text class="memorial-title">{{
item.goodsTitle || "数字资产纪念册"
item.goodsTitle || "数字资产收藏夹"
}}</text>
<text class="memorial-more">MORE</text>
</view>
@ -312,9 +318,9 @@
<view class="memorial-empty" v-else>
<view class="empty-content">
<view class="empty-icon">📖</view>
<text class="empty-title">暂无纪念册</text>
<text class="empty-desc">您还没有数字资产纪念册</text>
<text class="empty-tip">快去购买数字资产创建您的专属纪念册</text>
<text class="empty-title">暂无收藏夹</text>
<text class="empty-desc">您还没有数字资产收藏夹</text>
<text class="empty-tip">快去购买数字资产创建您的专属收藏夹</text>
</view>
</view>
</view>
@ -381,11 +387,13 @@ import moment from "moment";
import CustomTabBar from "@/components/CustomTabBar.vue";
import MusicControl from "@/components/MusicControl.vue";
import ActivateAgentPopup from "@/components/ActivateAgentPopup.vue";
import BackButton from "@/components/BackButton.vue";
export default {
components: {
CustomTabBar,
MusicControl,
ActivateAgentPopup,
BackButton
},
data() {
return {
@ -393,9 +401,9 @@ export default {
defaultAvatar:
"https://changshu.js-dyyj.com/uploads/20250326/516242619f0772bee371a60684618c01.png",
userStats: {
following: "140",
followers: "2462",
likes: "5.4万",
following: "0",
followers: "0",
likes: "0",
},
menuItems: [
{
@ -428,11 +436,15 @@ export default {
assetList: [],
agentList: [],
orderStatus: [],
statusBarHeight:0
};
},
onLoad() {
//
},
mounted() {
this.setStatusBarHeight()
},
onShow() {
console.log(uni.getStorageSync("userInfo"));
this.userInfo =
@ -449,6 +461,15 @@ export default {
}
},
methods: {
setStatusBarHeight() {
try {
const systemInfo = uni.getSystemInfoSync();
this.statusBarHeight = systemInfo.statusBarHeight || 0;
} catch (e) {
// 使
this.statusBarHeight = 0;
}
},
getOrderStatus() {
this.Post({}, "/framework/order/orderCountByStatus", "DES").then(
(res) => {
@ -770,6 +791,9 @@ export default {
::v-deep .uni-popup {
z-index: 999 !important;
}
::v-deep .back-btn{
background-color: transparent !important;
}
view {
box-sizing: border-box;
}
@ -781,7 +805,6 @@ view {
/* 状态栏占位 */
.status-bar-placeholder {
height: var(--status-bar-height);
width: 100%;
}
@ -1254,6 +1277,9 @@ view {
margin-bottom: 16rpx;
font-weight: bold;
line-height: 1.4;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.asset-action {

7
pages/index/index.vue

@ -5,6 +5,7 @@
:address="addressInfo"
fixed
isLocation
:isBack="false"
></headerVue>
<!-- 灵动岛组件 -->
@ -23,7 +24,7 @@
v-show="productList.length"
title="EPIC SOUL文旅权益商品"
:productList="productList"
moreUrl="/subPackages/equityGoods/index"
moreUrl="/subPackages/equityGoods/list"
detailUrlPrefix="/subPackages/equityGoods/detail"
@like-toggle="handleLikeToggle"
color="#D2FFDE"
@ -151,9 +152,9 @@ export default {
this.selectedText = res && res.city;
uni.setStorageSync("SYS_ADDRESS_INFO", JSON.stringify(res));
this.getList();
this.geBenefitPackaget();
},
onShow() {
this.geBenefitPackaget();
this.browse_record({
type: "page",
title: "首页",
@ -213,7 +214,7 @@ export default {
geBenefitPackaget() {
this.Post(
{
cityId: this.addressInfo.cityId,
cityId: this.addressInfo&&this.addressInfo.cityId||320500,
},
"/framework/index/benefitPackage/list",
"DES"

4
pages/index/intelligentAgent.vue

@ -1,5 +1,6 @@
<template>
<view class="bg">
<BackButton />
<view class="content">
<!-- <swiper class="top-banner" :indicator-dots="false" :autoplay="false" v-if="topBanner && topBanner.length > 0">
<swiper-item v-for="(item, index) in topBanner" :key="index" @click.stop="gotoUrlNew(item)">
@ -17,8 +18,9 @@
import headerVue from "@/components/header.vue"
import CustomTabBar from '@/components/CustomTabBar.vue';
import MusicControl from '@/components/MusicControl.vue';
import BackButton from "@/components/BackButton.vue";
export default {
components: {CustomTabBar,headerVue,MusicControl},
components: {CustomTabBar,headerVue,MusicControl,BackButton},
data() {
return {
topBanner: []

15
pages/index/readingBody.vue

@ -8,7 +8,7 @@
></video>
</view>
<view class="title-box-about">
关于阅读
关于阅读
<image
src="https://des.js-dyyj.com/data/2025/08/29/a1bfbd3e-f63c-4dea-8aa6-9008bcf129c6.png"
mode=""
@ -35,15 +35,11 @@
</view>
<view class="desc-box">
<view class="">
在这里你的每一次人文漫游每一次灵感闪现都值得被郑重记录我们鼓励你分享高质量的图文笔记将旅途中的美与感动化为这座精神星球上的璀璨星辰
Epic soul交响 | 阅读体以数字文化资产IP为核心以消费产品创新为导向每个生命都有史诗般的灵魂作为创作宗旨通过文字图像音视频交互式展览等多种技术工具创作完成的轻量化数字文化内容产品邀您一起收藏这颗星球所有未被传唱的英雄史诗
</view>
<view class="">
Epic
soul交响阅读体以数字文化资产IP为核心,以消费产品创新为导向,每个生命都有史诗般的灵魂作为创作宗旨,通过文字图像音视频交互式展览等多种技术工具创作完成的轻量化数字文化内容产品,邀您一起收藏这颗星球所有未被传唱的英雄史诗
</view>
<view class="">
Epic
soul交响阅读体将长期关注乡村振兴城市更新文化焕新等领域,践行探索未来文化信息的解构分发和互动方式
soul交响|阅读体将长期关注乡村振兴城市更新文化焕新等领域,践行探索未来文化信息的解构分发和互动方式
</view>
</view>
<image
@ -472,7 +468,7 @@ export default {
.reading-box {
margin: 20rpx 25rpx 0;
padding: 35rpx 10rpx 5rpx;
padding: 35rpx 0rpx 5rpx;
display: flex;
justify-content: space-around;
flex-wrap: wrap;
@ -486,7 +482,7 @@ export default {
}
.reading-box-item {
flex: 0 0 calc(50% - 8rpx);
flex: 0 0 calc(50% - 20rpx);
border-radius: 20rpx;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
background-color: #fff;
@ -524,6 +520,7 @@ export default {
color: #616161;
margin: 30rpx 0;
font-size: 22rpx;
padding: 0 40rpx;
view {
margin-bottom: 20rpx;

19
pages/index/sensoryStore.vue

@ -18,8 +18,10 @@
</view>
<view class="product-content">
<image class="head-img" src="https://static.ticket.sz-trip.com/uploads/20250625/e3112c280ef9761af741907a737ef221.png"></image>
<!-- <image class="head-img" src="https://static.ticket.sz-trip.com/uploads/20250625/e3112c280ef9761af741907a737ef221.png"></image> -->
<view class="title-sec">
有感商品上新
</view>
<scroll-view style="width: 100%;" scroll-x>
<view class="product">
<view class="item" v-for="(item,i) in list" :key="item.goods.id" @click="goDetailByType(item)">
@ -36,8 +38,10 @@
</view>
</scroll-view>
<image style="margin: 53rpx 0 35rpx;" class="head-img" src="https://static.ticket.sz-trip.com/uploads/20250627/73153098ff5c115e02afb0328ade1e29.png"></image>
<!-- <image style="margin: 53rpx 0 35rpx;" class="head-img" src="https://static.ticket.sz-trip.com/uploads/20250627/73153098ff5c115e02afb0328ade1e29.png"></image> -->
<view class="title-sec">
有感商品精选
</view>
<view class="img-container">
<image v-for="(type,i) in typeList" :key="i" :src="showImg(type.img)"
@click="gotoPath(`/subPackages/haveFeeling/detailXiang?id=${type.id}`)"></image>
@ -170,8 +174,10 @@
}
.product-content{
padding: 63rpx 26rpx 0;
padding-top: 0;
.product{
padding: 36rpx 0 0;
padding-top: 0;
display: flex;
flex-wrap: nowrap;
// justify-content: space-between;
@ -223,4 +229,9 @@
width: 183.45rpx;
height: 42.57rpx;
}
.title-sec{
font-size: 34rpx;
font-weight: 500;
margin: 30rpx 0;
}
</style>

5
pages/index/timeShopBank.vue

@ -17,10 +17,10 @@
在这里你的每一次人文漫游每一次灵感闪现都值得被郑重记录我们鼓励你分享高质量的图文笔记将旅途中的美与感动化为这座精神星球上的璀璨星辰
</view>
<view class="">
为他人的美好驻足点赞留言,每一次真诚的互动,都是在为你的时间银行存入-笔宝贵的精神货币这些资产不仅可以兑换独家福利与实体好物,更能为你解锁专属的荣誉身份,让你成为这座星球上最闪耀的共创者
为他人的美好驻足点赞留言每一次真诚的互动都是在为你的时间银行存入一笔宝贵的精神货币这些资产不仅可以兑换独家福利与实体好物更能为你解锁专属的荣誉身份让你成为这座星球上最闪耀的共创者
</view>
<view class="">
即刻发布你的第一篇笔记,开启你的财富积累之旅吧!
即刻发布你的第一篇笔记开启你的财富积累之旅吧
</view>
</view>
@ -513,6 +513,7 @@ page {
color: #616161;
margin: 30rpx 0;
font-size: 22rpx;
padding: 0 40rpx;
view{
margin-bottom: 20rpx;
&:nth-child(1){

324
subPackages/equityGoods/detail.vue

@ -2,16 +2,30 @@
<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
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>
<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
:class="['dot-line', index == swiperIndex ? 'active' : '']"
v-for="(item, index) in topBanner"
:key="index"
></view>
</view>
<!-- 页码指示器 -->
@ -27,53 +41,80 @@
<!-- 商品信息区域 -->
<view class="product-info">
<!-- 标题和标签 -->
<view class="" style="display: flex;justify-content: space-between">
<view class="" style="display: flex; justify-content: space-between">
<view class="title-section">
<view class="product-title">{{ goodsInfo.title||'-' }}</view>
<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="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">
点击收听
{{ goodsInfo.agent.name }}
</view>
<view class="agent-use" v-if="!e.agentStatus"> 点击收听 </view>
</view>
</view>
<!-- 价格和收藏 -->
<view class="price-section">
<view class="price-container">
<text class="currency">¥</text>
<text class="price">{{ goodsInfo.price||0 }}</text>
<text class="price">{{ goodsInfo.price || 0 }}</text>
</view>
<view class="collect-container">
<image v-if="!goodsInfo.type" class="heart-icon"
<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"
@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>
@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="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>
<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">
产品{{
@ -82,9 +123,16 @@
]
}}
</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 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>
@ -102,8 +150,12 @@
<!-- 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)">
<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>
@ -114,32 +166,39 @@
<!-- Tab内容 -->
<view class="tab-content">
<!-- 登记证书 -->
<view v-if="currentTab === 0" class="tab-panel">
<view v-if="currentTab === 2" class="tab-panel">
<view class="certificate-container">
<image class="certificate-image" :src="goodsInfo.ipDigitalAsset.copyrightUrl" mode="widthFix">
<image
class="certificate-image"
:src="goodsInfo.ipDigitalAsset.copyrightUrl"
mode="widthFix"
>
</image>
</view>
</view>
<!-- 商品详情 -->
<view v-if="currentTab === 0 && goodsInfo.detailUrl" class="tab-panel">
<view class="" v-html="goodsInfo.detailUrl"> </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
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>
<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>
@ -159,7 +218,7 @@
</template>
<script>
export default {
export default {
data() {
return {
topBanner: [],
@ -185,9 +244,18 @@
onLoad(e) {
this.getDetail(e.id);
},
onUnload() {
console.log("页面卸载,停止音频");
// this.stopCurrentAudio();
},
onHide() {
console.log("页面隐藏,停止音频");
// this.stopCurrentAudio();
},
methods: {
getDetail(benefitPackageId) {
this.Post({},
this.Post(
{},
`/framework/benefitPackage/detail/${benefitPackageId}`,
"DES"
).then((res) => {
@ -195,22 +263,26 @@
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 = JSON.parse(res.data.sku.product.scene);
this.scene.content = this.addImgStyleToHtml(this.scene.content);
}
console.log(this.scene, '场景信息')
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)
console.log(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({
this.Post(
{
packageId: this.goodsInfo.benefitPackageId,
type: !this.goodsInfo.type,
},
@ -218,6 +290,9 @@
"DES"
).then((res) => {
this.goodsInfo.type = !this.goodsInfo.type;
this.goodsInfo.collectQuantity = this.goodsInfo.type
? this.goodsInfo.collectQuantity + 1
: this.goodsInfo.collectQuantity - 1;
});
},
swiperChange(e) {
@ -230,8 +305,8 @@
},
//
handlePurchase() {
let id = this.goodsInfo.sku && this.goodsInfo.sku.product.sceneId
this.toJdszWx('pages/info/sceneProductInfo/index?id=' + id)
let id = this.goodsInfo.sku && this.goodsInfo.sku.product.sceneId;
this.toJdszWx("pages/info/sceneProductInfo/index?id=" + id);
//
},
@ -252,17 +327,7 @@
if (!/width\s*:\s*100%/.test(styleVal)) {
newStyle = `width:100%;${styleVal}`;
}
return `
style = $ {
quote
}
$ {
newStyle
}
$ {
quote
}
`;
return `style = ${quote}${newStyle}${quote}`;
}
)}>`;
} else {
@ -272,18 +337,49 @@
});
},
toAgent(e) {
if (e.agentStatus) {
uni.navigateTo({
url: "/subPackages/other/evita?id="+e.agent.agentId
url: "/subPackages/other/evita?id=" + e.benefitPackageId,
});
} else {
uni.showToast({
title: '请先购买当前商品',
icon: 'none'
})
// if (e.agentStatus) {
// uni.navigateTo({
// url: "/subPackages/other/evita?id=" + e.agent.agentId,
// });
// } else {
// const app = getApp();
// //
// if (app.globalData.bgMusic) {
// app.globalData.bgMusic.stop();
// }
// //
// app.updateMusicSrc(e.agent.voiceUrl);
// app.initBackgroundMusic(); //
// uni.$bgMusic.play(); //
// // uni.showToast({
// // title: '',
// // icon: 'none'
// // })
// }
},
//
stopCurrentAudio() {
try {
const app = getApp();
//
if (app.globalData.bgMusic) {
app.globalData.bgMusic.stop();
app.globalData.bgMusic.destroy();
app.globalData.bgMusic = null;
}
//
if (app.globalData.initMusicSrc) {
app.updateMusicSrc(app.globalData.initMusicSrc);
app.initBackgroundMusic();
uni.$bgMusic.play(); //
}
console.log("音频已停止并恢复初始音乐");
} catch (error) {
console.error("停止音频时出错:", error);
}
},
showImgJdsz(img) {
if (!img) return;
@ -299,23 +395,26 @@
// Tab -
this.tabList.push({
name: "登记证书"
name: "整合应用产品",
});
this.tabList.push({
name: "数资详情",
});
this.tabList.push({
name: "IP资产详情"
name: "数资证书",
});
// Tab
if (this.goodsInfo) {
// Tab
if (this.goodsInfo.sku && this.goodsInfo.sku.product) {
this.tabList.push({
name: "门票详情"
});
}
this.tabList.push({
name: "权益商品"
});
// if (this.goodsInfo.sku && this.goodsInfo.sku.product) {
// this.tabList.push({
// name: "",
// });
// }
// this.tabList.push({
// name: "",
// });
// goodsVosTab
// if (this.goodsInfo.goodsVos) {
// this.goodsInfo.goodsVos.forEach((element) => {
@ -325,16 +424,16 @@
}
},
},
};
};
</script>
<style lang="scss" scoped>
.detail-container {
.detail-container {
background: #f5f5f5;
min-height: 100vh;
}
}
.banner-content {
.banner-content {
width: 100%;
height: 1000rpx;
position: relative;
@ -379,9 +478,9 @@
font-weight: 500;
}
}
}
}
.product-info {
.product-info {
padding: 40rpx 10rpx;
margin: 20rpx;
padding-bottom: 1rpx;
@ -542,7 +641,7 @@
.detail-content-wrapper {
display: flex;
align-items: center;
.detail-info{
.detail-info {
display: flex;
flex-direction: column;
justify-content: space-between;
@ -565,7 +664,6 @@
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
@ -599,14 +697,14 @@
}
}
}
}
}
// Tab
.tab-nav {
// Tab
.tab-nav {
margin: 0 40rpx;
margin-top: 40rpx;
white-space: nowrap;
width: 690rpx;
width: 666rpx;
.tab-container {
display: flex;
@ -619,9 +717,9 @@
cursor: pointer;
transition: all 0.3s ease;
background-color: #94fafa66;
display: flex;
align-items: center;
text-align: center;
flex-shrink: 0;
flex: 1;
margin-right: 16rpx;
&:last-child {
@ -642,10 +740,10 @@
}
}
}
}
}
// Tab
.tab-section {
// Tab
.tab-section {
margin: 0 20rpx;
background-color: #fff;
border-radius: 20rpx;
@ -765,10 +863,10 @@
}
}
}
}
}
//
.purchase-section {
//
.purchase-section {
position: fixed;
bottom: 0;
left: 0;
@ -802,20 +900,20 @@
color: #525454;
}
}
}
}
//
.detail-container {
//
.detail-container {
padding-bottom: 140rpx;
}
}
.avatar {
.avatar {
width: 119rpx;
height: 119rpx;
border-radius: 50%;
}
}
.agent-info {
.agent-info {
text-align: center;
.agent {
@ -829,8 +927,8 @@
.agent-use {
font-size: 22rpx;
color: #00FFFF;
color: #00ffff;
margin-top: 5rpx;
}
}
}
</style>

85
subPackages/other/evita.vue

@ -24,8 +24,37 @@
this.agentId = e.id
this.getInfo()
},
onUnload() {
console.log("页面卸载,停止音频");
this.stopCurrentAudio();
},
onHide() {
console.log("页面隐藏,停止音频");
this.stopCurrentAudio();
},
methods:{
stopCurrentAudio() {
try {
const app = getApp();
//
if (app.globalData.bgMusic) {
app.globalData.bgMusic.stop();
app.globalData.bgMusic.destroy();
app.globalData.bgMusic = null;
}
//
if (app.globalData.initMusicSrc) {
app.updateMusicSrc(app.globalData.initMusicSrc);
app.initBackgroundMusic();
uni.$bgMusic.play(); //
}
console.log("音频已停止并恢复初始音乐");
} catch (error) {
console.error("停止音频时出错:", error);
}
},
getInfo(){
if(this.agentId==0){
this.Post(
{
},
@ -34,6 +63,41 @@
).then((res) => {
if (res.code == 200) {
this.agentInfo = res.data
const app = getApp();
//
if (app.globalData.bgMusic) {
app.globalData.bgMusic.stop();
}
//
app.updateMusicSrc(this.agentInfo.voiceUrl);
app.initBackgroundMusic(); //
uni.$bgMusic.play(); //
} else {
uni.showToast({
title: res.msg,
icon: "none",
});
}
});
}else{
this.Post(
{
},
"/framework/benefitPackage/detail/"+this.agentId,
"DES"
).then((res) => {
if (res.code == 200) {
this.agentInfo = res.data.agent
const app = getApp();
//
if (app.globalData.bgMusic) {
app.globalData.bgMusic.stop();
}
//
app.updateMusicSrc(this.agentInfo.voiceUrl);
app.initBackgroundMusic(); //
uni.$bgMusic.play(); //
} else {
uni.showToast({
title: res.msg,
@ -41,11 +105,30 @@
});
}
});
}
},
toWebView() {
if(this.agentInfo.agentId==0){
uni.navigateTo({
url: "/pages/agent/index?id="+this.agentInfo.agentId
});
}else{
if(this.agentInfo.agentStatus){
uni.navigateTo({
url: "/pages/agent/index?id="+this.agentId
url: "/pages/agent/index?id="+this.agentInfo.agentId
});
}else{
uni.redirectTo({
url: "/subPackages/equityGoods/detail?id="+this.agentId
});
// uni.showToast({
// title: '',
// icon: 'none'
// })
}
}
},
}

15
vue.config.js

@ -0,0 +1,15 @@
module.exports = {
chainWebpack: (config) => {
// 发行或运行时启用了压缩时会生效
config.optimization.minimizer('terser').tap((args) => {
const compress = args[0].terserOptions.compress
// 非 App 平台移除 console 代码(包含所有 console 方法,如 log,debug,info...)
compress.drop_console = false
compress.pure_funcs = [
'__f__', // App 平台 vue 移除日志代码
// 'console.debug' // 可移除指定的 console 方法
]
return args
})
}
}
Loading…
Cancel
Save