|
|
@@ -134,7 +134,10 @@
|
|
|
<cover-view class="close-box" @click.stop="closeCardPopup">
|
|
|
<cover-image src="/static/images/close.png"></cover-image>
|
|
|
</cover-view>
|
|
|
-
|
|
|
+ <cover-view class="goods-cover-hot" v-if="hasHotSaleTag(currentCardItem) && getProductHotCount(currentCardItem) > 0">
|
|
|
+ <cover-image style="height: 28px;" src="https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/class/remai.png" mode="heightFix"></cover-image>
|
|
|
+ <cover-view class="goods-cover-hot-text">{{ getProductHotCount(currentCardItem) }}</cover-view>
|
|
|
+ </cover-view>
|
|
|
<cover-view class="goods-cover-inner">
|
|
|
<!-- 商品主图 -->
|
|
|
<cover-view class="goods-cover-img">
|
|
|
@@ -182,6 +185,10 @@
|
|
|
<view class="close-box" @click.stop="closeCardPopup">
|
|
|
<image src="/static/images/close.png"></image>
|
|
|
</view>
|
|
|
+ <view class="goods-card-hot" v-if="hasHotSaleTag(currentCardItem) && getProductHotCount(currentCardItem) > 0">
|
|
|
+ <image style="height: 56rpx;" src="https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/class/remai.png" mode="heightFix"></image>
|
|
|
+ <text class="goods-card-hot-count">{{ getProductHotCount(currentCardItem) }}</text>
|
|
|
+ </view>
|
|
|
<view class="goods-card-inner">
|
|
|
<image class="goods-card-img" :src="currentCardItem.images || currentCardItem.image" mode="aspectFill"></image>
|
|
|
<view class="goods-card-info">
|
|
|
@@ -513,7 +520,7 @@
|
|
|
<!-- 购物车弹窗 -->
|
|
|
<u-popup :show="isCart" @close="closeShop" round="20rpx" bgColor="#fff">
|
|
|
<scroll-view class="scroll-view" style="height:500rpx;box-sizing: border-box;padding: 24rpx;" scroll-y="true" enable-flex>
|
|
|
- <goodsList ref="goodsList" :treatmentPackage="displayProductList" :urlOption="urlOption"></goodsList>
|
|
|
+ <goodsList ref="goodsList" :treatmentPackage="displayProductList" :hotCountMap="productHotCountMap" :urlOption="urlOption"></goodsList>
|
|
|
</scroll-view>
|
|
|
</u-popup>
|
|
|
<!-- 更多操作弹窗 -->
|
|
|
@@ -755,6 +762,7 @@
|
|
|
import descInfoNav from "./components/descInfoNav.vue"
|
|
|
import commentBox from "./components/commentBox.vue"
|
|
|
import goodsList from "./components/goodsList.vue"
|
|
|
+ import { hasHotSaleTag, getProductHotKey, clampHotSaleCount } from './utils/productHotSale.js'
|
|
|
import {TOKEN_KEYAuto,generateRandomString} from '@/utils/courseTool.js'
|
|
|
import { buildFakeOrderPool } from '@/utils/videovipFakeMarquee.js'
|
|
|
import ykscreenRecord from "@/components/yk-screenRecord/yk-screenRecord.vue"
|
|
|
@@ -973,6 +981,8 @@
|
|
|
displayProductList: [], // 根据上架/下架时间过滤后的展示列表(用于购物车弹窗)
|
|
|
cardPopup: false, // 商品卡片弹窗
|
|
|
currentCardItem: null,
|
|
|
+ productHotCountMap: {},
|
|
|
+ productHotTimer: null,
|
|
|
dismissedCardKey: '',
|
|
|
// 跑马灯数据就绪门禁:避免首次进入时使用旧状态导致闪现
|
|
|
marqueeDataReady: false,
|
|
|
@@ -1193,7 +1203,19 @@
|
|
|
this._closeFeaturedCommentComposerUi()
|
|
|
this.closeFeaturedMediaActionSheet()
|
|
|
}
|
|
|
- }
|
|
|
+ },
|
|
|
+ displayProductList: {
|
|
|
+ handler() {
|
|
|
+ this.syncProductHotCounts()
|
|
|
+ },
|
|
|
+ deep: true,
|
|
|
+ },
|
|
|
+ cardPopup() {
|
|
|
+ this.syncProductHotCounts()
|
|
|
+ },
|
|
|
+ currentCardItem() {
|
|
|
+ this.syncProductHotCounts()
|
|
|
+ },
|
|
|
},
|
|
|
onLoad(option) {
|
|
|
this.getWebviewUrl()
|
|
|
@@ -1288,6 +1310,7 @@
|
|
|
this.stopFakeMarqueeLoop()
|
|
|
}
|
|
|
this.stopCountdown()
|
|
|
+ this.stopProductHotTimer()
|
|
|
// if (this.interval != null) {
|
|
|
// clearInterval(this.interval)
|
|
|
// this.interval = null
|
|
|
@@ -1313,6 +1336,7 @@
|
|
|
}
|
|
|
this.fullscreenToggleLock = false
|
|
|
this.stopCountdown()
|
|
|
+ this.stopProductHotTimer()
|
|
|
this.clearIntegral()
|
|
|
this.stopFakeMarqueeLoop()
|
|
|
this.fakeOrderPool = []
|
|
|
@@ -1344,6 +1368,7 @@
|
|
|
}
|
|
|
this.fullscreenToggleLock = false
|
|
|
this.stopCountdown()
|
|
|
+ this.stopProductHotTimer()
|
|
|
this.clearIntegral()
|
|
|
this.stopFakeMarqueeLoop()
|
|
|
// #ifndef H5
|
|
|
@@ -1679,6 +1704,74 @@
|
|
|
}
|
|
|
this.cardPopup = false
|
|
|
},
|
|
|
+ hasHotSaleTag(item) {
|
|
|
+ return hasHotSaleTag(item)
|
|
|
+ },
|
|
|
+ getProductHotCount(item) {
|
|
|
+ if (!hasHotSaleTag(item)) return 0
|
|
|
+ const key = getProductHotKey(item)
|
|
|
+ return key ? clampHotSaleCount(this.productHotCountMap[key]) : 0
|
|
|
+ },
|
|
|
+ _collectHotSaleProducts() {
|
|
|
+ const seen = new Set()
|
|
|
+ const list = []
|
|
|
+ const add = (item) => {
|
|
|
+ if (!hasHotSaleTag(item)) return
|
|
|
+ const key = getProductHotKey(item)
|
|
|
+ if (!key || seen.has(key)) return
|
|
|
+ seen.add(key)
|
|
|
+ list.push(item)
|
|
|
+ }
|
|
|
+ ;(this.displayProductList || []).forEach(add)
|
|
|
+ if (this.cardPopup && this.currentCardItem) add(this.currentCardItem)
|
|
|
+ return list
|
|
|
+ },
|
|
|
+ _randomInt(min, max) {
|
|
|
+ return Math.floor(Math.random() * (max - min + 1)) + min
|
|
|
+ },
|
|
|
+ syncProductHotCounts() {
|
|
|
+ const products = this._collectHotSaleProducts()
|
|
|
+ const next = { ...this.productHotCountMap }
|
|
|
+ const activeKeys = new Set()
|
|
|
+ products.forEach((item) => {
|
|
|
+ const key = getProductHotKey(item)
|
|
|
+ if (!key) return
|
|
|
+ activeKeys.add(key)
|
|
|
+ if (!next[key]) {
|
|
|
+ next[key] = clampHotSaleCount(this._randomInt(100, 800))
|
|
|
+ }
|
|
|
+ })
|
|
|
+ Object.keys(next).forEach((key) => {
|
|
|
+ if (!activeKeys.has(key)) delete next[key]
|
|
|
+ })
|
|
|
+ this.productHotCountMap = next
|
|
|
+ if (activeKeys.size) {
|
|
|
+ this.startProductHotTimer()
|
|
|
+ } else {
|
|
|
+ this.stopProductHotTimer()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ startProductHotTimer() {
|
|
|
+ if (this.productHotTimer) return
|
|
|
+ this.productHotTimer = setInterval(() => {
|
|
|
+ const products = this._collectHotSaleProducts()
|
|
|
+ if (!products.length) return
|
|
|
+ const next = { ...this.productHotCountMap }
|
|
|
+ products.forEach((item) => {
|
|
|
+ const key = getProductHotKey(item)
|
|
|
+ if (key && next[key]) {
|
|
|
+ next[key] = clampHotSaleCount(next[key] + this._randomInt(10, 20))
|
|
|
+ }
|
|
|
+ })
|
|
|
+ this.productHotCountMap = next
|
|
|
+ }, 30000)
|
|
|
+ },
|
|
|
+ stopProductHotTimer() {
|
|
|
+ if (this.productHotTimer) {
|
|
|
+ clearInterval(this.productHotTimer)
|
|
|
+ this.productHotTimer = null
|
|
|
+ }
|
|
|
+ },
|
|
|
openList(){
|
|
|
const wasShu = this.isShu
|
|
|
this.isShu=!this.isShu
|
|
|
@@ -2683,6 +2776,7 @@
|
|
|
this.cardPopup = !!activeCard && this.dismissedCardKey !== activeCardKey
|
|
|
//this.getVideoContainerHeight()
|
|
|
this.currentCardItem = activeCard
|
|
|
+ this.syncProductHotCounts()
|
|
|
this._syncFakeMarqueeIfEligibleChanged()
|
|
|
},
|
|
|
//播放时间更新事件方法
|
|
|
@@ -5462,11 +5556,35 @@
|
|
|
z-index: 99999;
|
|
|
background: #FFFFFF;
|
|
|
border-radius: 10px;
|
|
|
- overflow: hidden;
|
|
|
+ overflow: visible;
|
|
|
bottom: 40px;
|
|
|
+
|
|
|
+ &-hot {
|
|
|
+ position: absolute;
|
|
|
+ top: -33px;
|
|
|
+ left: 15px;
|
|
|
+ z-index: 11;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ &-hot-text {
|
|
|
+ position: absolute;
|
|
|
+ left:65px;
|
|
|
+ font-family: PingFangSC, PingFang SC;
|
|
|
+ font-weight: 600;
|
|
|
+ font-size: 20px;
|
|
|
+ color: #FFFFFF;
|
|
|
+ line-height: 28px;
|
|
|
+ text-align: justify;
|
|
|
+ }
|
|
|
+
|
|
|
&-inner {
|
|
|
display: flex;
|
|
|
flex-direction:column;
|
|
|
+ border-radius: 10px;
|
|
|
+ overflow: hidden;
|
|
|
}
|
|
|
|
|
|
&-img {
|
|
|
@@ -5562,11 +5680,47 @@
|
|
|
width: 300rpx;
|
|
|
background: #FFFFFF;
|
|
|
border-radius: 20rpx 20rpx 0rpx 0rpx;
|
|
|
- overflow: hidden;
|
|
|
+ overflow: visible;
|
|
|
+
|
|
|
+ &-hot {
|
|
|
+ position: absolute;
|
|
|
+ top: -66rpx;
|
|
|
+ left: 30rpx;
|
|
|
+ z-index: 11;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: row;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ &-hot-flame {
|
|
|
+ font-size: 24rpx;
|
|
|
+ line-height: 1;
|
|
|
+ margin-right: 4rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ &-hot-label {
|
|
|
+ font-size: 24rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #FFFFFF;
|
|
|
+ line-height: 44rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ &-hot-count {
|
|
|
+ position: absolute;
|
|
|
+ left:130rpx;
|
|
|
+ font-family: PingFangSC, PingFang SC;
|
|
|
+ font-weight: 600;
|
|
|
+ font-size: 40rpx;
|
|
|
+ color: #FFFFFF;
|
|
|
+ line-height: 56rpx;
|
|
|
+ text-align: justify;
|
|
|
+ }
|
|
|
|
|
|
&-inner {
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
+ border-radius: 20rpx 20rpx 0 0;
|
|
|
+ overflow: hidden;
|
|
|
}
|
|
|
|
|
|
&-img {
|