Commit 6ae1d5a5 authored by 王炽's avatar 王炽

Merge branch 'dev' of http://gitlab.dui88.com/fh/20250528_FHQ1 into dev

parents a4a2b658 5b1d1b1c
import requestModule from './request.js'
const {api} = requestModule
const { api } = requestModule
/**
* 星妈会藏馆
......@@ -38,3 +38,5 @@ export const fetchRecordDetail = (data) => api.get('/c/lab/record/detail', data)
export const fetchFavoriteAdd = (data) => api.get('/c/lab/favorite/add', data)
export const fetchFavoriteRemove = (data) => api.get('/c/lab/favorite/remove', data)
export const generateQRCode = (data) => api.post('/c/wechat/generateQRCode', data)
\ No newline at end of file
<template>
<view v-if="visible" class="poster-page-overlay" @tap="handleOverlayClick">
<view class="poster-page-container" @tap.stop>
<!-- 海报背景 -->
<view class="poster-wrapper">
<image class="poster-bg" :src="`${$baseUrl}homepage/Q3Res/xingmaLabPosterBg.png`" mode="aspectFit">
</image>
<!-- 昵称区域 -->
<view class="poster-nickname-wrapper">
<!-- 昵称背景 -->
<image class="poster-nickname-bg" :src="`${$baseUrl}homepage/Q3Res/xingmaLabPosterNickBg2.png`"
mode="aspectFit"></image>
<!-- 头像 -->
<image v-if="avatar" class="poster-avatar" :src="avatar" mode="aspectFit"></image>
<text class="poster-nickname-text">{{ nickname || '' }}</text>
</view>
<!-- 图片区域 -->
<view class="poster-image-wrapper">
<image class="poster-image-bg" :src="`${$baseUrl}homepage/Q3Res/xingmaLabPosterImgBg.png`"
mode="aspectFit"></image>
<image v-if="imageUrl" class="poster-image" :src="imageUrl" mode="aspectFit"></image>
<!-- 文字内容 -->
<view class="poster-content">
<text class="poster-content-text">{{ content || '' }}</text>
</view>
<!-- 唯一藏品编号 -->
<view class="poster-collection-number">
<text class="collection-number-text">唯一藏品编号: {{ collectionNumber }}</text>
</view>
<!-- 下载按钮 -->
<view class="poster-download-btn" @tap="handleDownload">
<image class="download-icon" :src="`${$baseUrl}homepage/Q3Res/xingmaLabPosterDownloadBtn.png`"
mode="aspectFit"></image>
</view>
<!-- 二维码区域 -->
<view class="poster-qrcode-wrapper">
<image v-if="qrcodeImageUrl" class="poster-qrcode-image" :src="qrcodeImageUrl" mode="aspectFit">
</image>
</view>
</view>
</view>
<!-- 关闭按钮 -->
<view class="poster-close-btn" @tap="handleClose">
<image class="close-icon" :src="`${$baseUrl}homepage/Q3Res/xingmaLabPosterBtnConCloseBtn2.png`"
mode="aspectFit"></image>
</view>
</view>
<!-- 隐藏的 canvas 用于合成海报 -->
<canvas canvas-id="posterCanvas" class="poster-canvas"
:style="{ width: canvasWidth + 'px', height: canvasHeight + 'px' }"></canvas>
</view>
</template>
<script setup>
import { ref, watch, getCurrentInstance, nextTick, computed } from 'vue'
import md from '../../md'
import { generateQRCode } from '../../api/xingmaLab'
const { proxy } = getCurrentInstance()
const $baseUrl = proxy.$baseUrl
const props = defineProps({
visible: {
type: Boolean,
default: false
},
imageUrl: {
type: String,
default: ''
},
content: {
type: String,
default: '可爱'
},
collectionNumber: {
type: String,
default: ''
},
defaultNickname: {
type: String,
default: ''
},
avatar: {
type: String,
default: ''
},
recordId: {
type: String,
default: ''
}
})
const emit = defineEmits(['close', 'download'])
// 昵称从 props 传入,不可编辑
const nickname = computed(() => props.defaultNickname || '')
const qrcodeImageUrl = ref('') // 二维码图片 URL
const isDownloading = ref(false) // 是否正在下载
// Canvas 尺寸(海报尺寸:542rpx x 956rpx)
const systemInfo = uni.getSystemInfoSync()
const screenWidth = systemInfo.windowWidth || 375
const canvasWidth = (542 / 750) * screenWidth
const canvasHeight = (956 / 750) * screenWidth
// 监听 visible 变化,生成二维码
watch(() => props.visible, (newVal) => {
if (newVal) {
nextTick(() => {
generateQrcodeFunc()
})
}
})
// 生成二维码
const generateQrcodeFunc = async () => {
if (!props.recordId) {
console.warn('recordId 未传入,无法生成二维码')
return
}
try {
const result = await generateQRCode({
scene: `id=${props.recordId}`,
page: `pages/XingmaLabDetailPage/XingmaLabDetailPage`,
envVersion: 'develop'
})
if (result && result.ok && result.data && result.data.qrCodeBase64) {
// 接口返回的二维码图片 Base64 编码
const qrCodeBase64 = result.data.qrCodeBase64
// 判断是否为 JPEG 格式(JPEG Base64 通常以 /9j/ 开头)
const isJPEG = qrCodeBase64.startsWith('/9j/')
// 移除可能存在的 data:image 前缀,只保留纯 Base64 字符串
let base64String = qrCodeBase64
if (base64String.includes(',')) {
base64String = base64String.split(',')[1]
}
// 将 Base64 转换为 Data URI
const base64Data = isJPEG
? `data:image/jpeg;base64,${base64String}`
: `data:image/png;base64,${base64String}`
// 直接赋值给图片 URL
qrcodeImageUrl.value = base64Data
} else {
console.warn('生成二维码接口返回数据格式异常:', result)
}
} catch (error) {
console.error('生成二维码失败:', error)
}
}
// 关闭弹窗
const handleClose = () => {
emit('close')
}
// 点击遮罩关闭
const handleOverlayClick = () => {
handleClose()
}
// 下载海报
const handleDownload = async () => {
if (isDownloading.value) {
return
}
// 检查二维码是否已生成,如果没有则等待生成
if (!qrcodeImageUrl.value) {
uni.showLoading({
title: '二维码生成中...',
mask: true
})
// 等待二维码生成,最多等待 5 秒
let waitCount = 0
while (!qrcodeImageUrl.value && waitCount < 50) {
await new Promise(resolve => setTimeout(resolve, 100))
waitCount++
}
uni.hideLoading()
if (!qrcodeImageUrl.value) {
uni.showToast({
title: '二维码生成失败,请重试',
icon: 'none'
})
return
}
}
isDownloading.value = true
uni.showLoading({
title: '生成中...',
mask: true
})
try {
// 等待所有图片加载完成
await nextTick()
// 额外等待一下,确保二维码图片已加载
await new Promise(resolve => setTimeout(resolve, 500))
const ctx = uni.createCanvasContext('posterCanvas', proxy)
// 保存初始状态
ctx.save()
// 海报尺寸(rpx 转 px)
const posterWidth = canvasWidth
const posterHeight = canvasHeight
// 绘制背景
await drawImage(ctx, `${$baseUrl}homepage/Q3Res/xingmaLabPosterBg.png`, 0, 0, posterWidth, posterHeight)
// 绘制昵称背景和头像、昵称
const nicknameBgX = (24 / 750) * screenWidth
const nicknameBgY = (40 / 750) * screenWidth
const nicknameBgW = (256 / 750) * screenWidth
const nicknameBgH = (58 / 750) * screenWidth
await drawImage(ctx, `${$baseUrl}homepage/Q3Res/xingmaLabPosterNickBg2.png`, nicknameBgX, nicknameBgY, nicknameBgW, nicknameBgH)
// 绘制头像(带圆角)
if (props.avatar) {
// 头像位置:相对于昵称背景,top: 2rpx, left: 4rpx
const avatarX = nicknameBgX + (8 / 750) * screenWidth
const avatarY = nicknameBgY + (6 / 750) * screenWidth
const avatarSize = (48 / 750) * screenWidth
const avatarRadius = avatarSize / 2
// 保存当前状态
ctx.save()
// 创建圆形裁剪路径
ctx.beginPath()
ctx.arc(avatarX + avatarRadius, avatarY + avatarRadius, avatarRadius, 0, 2 * Math.PI)
ctx.clip()
// 绘制头像图片
await drawImage(ctx, props.avatar, avatarX, avatarY, avatarSize, avatarSize)
// 恢复裁剪区域
ctx.restore()
}
// 绘制昵称文字
ctx.setFillStyle('#333333')
ctx.setFontSize((28 / 750) * screenWidth)
ctx.setTextAlign('left')
const nicknameTextX = nicknameBgX + (props.avatar ? (48 + 20) / 750 * screenWidth : 30 / 750 * screenWidth)
const nicknameTextY = nicknameBgY + nicknameBgH / 2 + (28 / 750) * screenWidth / 3
ctx.fillText(nickname.value || '', nicknameTextX, nicknameTextY)
// 绘制图片区域背景(居中)
const imageBgW = (494 / 750) * screenWidth
const imageBgH = (802 / 750) * screenWidth
const imageBgX = (posterWidth - imageBgW) / 2
const imageBgY = (120 / 750) * screenWidth
await drawImage(ctx, `${$baseUrl}homepage/Q3Res/xingmaLabPosterImgBg.png`, imageBgX, imageBgY, imageBgW, imageBgH)
// 绘制主图片
if (props.imageUrl) {
const imageX = imageBgX + (26 / 750) * screenWidth
const imageY = imageBgY + (26 / 750) * screenWidth
const imageW = imageBgW - (52 / 750) * screenWidth
const imageH = (586 / 750) * screenWidth
await drawImage(ctx, props.imageUrl, imageX, imageY, imageW, imageH)
}
// 绘制文字内容
ctx.setFillStyle('#000000')
ctx.setFontSize((28 / 750) * screenWidth)
ctx.setTextAlign('left')
const contentX = imageBgX + (22 / 750) * screenWidth
const contentY = imageBgY + imageBgH - (146 / 750) * screenWidth
ctx.fillText(props.content || '', contentX, contentY)
// 绘制唯一藏品编号
ctx.setFillStyle('#D3A458')
ctx.setFontSize((20 / 750) * screenWidth)
ctx.setTextAlign('left')
const collectionX = imageBgX + (22 / 750) * screenWidth
const collectionY = imageBgY + imageBgH - (116 / 750) * screenWidth
ctx.fillText(`唯一藏品编号: ${props.collectionNumber || ''}`, collectionX, collectionY)
// 绘制二维码(在图片区域右下角)
if (qrcodeImageUrl.value) {
const qrcodeSize = (114 / 750) * screenWidth
// 二维码位置:图片区域右下角,距离右边 22rpx,距离底部 26rpx
const qrcodeX = imageBgX + imageBgW - qrcodeSize - (22 / 750) * screenWidth
const qrcodeY = imageBgY + imageBgH - qrcodeSize - (26 / 750) * screenWidth
console.log('开始绘制二维码:', {
qrcodeX,
qrcodeY,
qrcodeSize,
imageBgX,
imageBgY,
imageBgW,
imageBgH,
qrcodeImageUrl: qrcodeImageUrl.value.substring(0, 50) + '...'
})
await drawImage(ctx, qrcodeImageUrl.value, qrcodeX, qrcodeY, qrcodeSize, qrcodeSize)
console.log('二维码绘制完成')
} else {
console.warn('二维码图片 URL 为空,无法绘制')
}
// 等待所有绘制完成后再调用 draw
await nextTick()
// 绘制到 canvas
ctx.draw(false, async () => {
await nextTick()
// 转换为临时文件
uni.canvasToTempFilePath({
canvasId: 'posterCanvas',
width: posterWidth,
height: posterHeight,
destWidth: posterWidth,
destHeight: posterHeight,
success: (res) => {
// 保存到相册
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: () => {
uni.hideLoading()
uni.showToast({
title: '保存成功',
icon: 'success'
})
isDownloading.value = false
},
fail: (err) => {
uni.hideLoading()
console.error('保存失败:', err)
uni.showToast({
title: '保存失败',
icon: 'none'
})
isDownloading.value = false
}
})
},
fail: (err) => {
uni.hideLoading()
console.error('生成图片失败:', err)
uni.showToast({
title: '生成失败',
icon: 'none'
})
isDownloading.value = false
}
}, proxy)
})
} catch (error) {
uni.hideLoading()
console.error('下载海报失败:', error)
uni.showToast({
title: '生成失败',
icon: 'none'
})
isDownloading.value = false
}
}
// 将 Base64 Data URI 转换为临时文件路径
const base64ToTempFilePath = (base64Data) => {
return new Promise((resolve, reject) => {
if (!base64Data || !base64Data.startsWith('data:image')) {
reject(new Error('无效的 Base64 数据'))
return
}
const fs = uni.getFileSystemManager()
const base64String = base64Data.split(',')[1]
const isJPEG = base64String.startsWith('/9j/')
const fileExtension = isJPEG ? 'jpg' : 'png'
const fileName = `qrcode_${Date.now()}_${Math.random().toString(36).substr(2, 9)}.${fileExtension}`
// #ifdef MP-WEIXIN
const userDataPath = wx.env.USER_DATA_PATH
// #endif
// #ifndef MP-WEIXIN
const userDataPath = uni.env.USER_DATA_PATH || ''
// #endif
const filePath = `${userDataPath}/${fileName}`
// 先尝试清理旧的临时文件(异步方式,避免阻塞)
// #ifdef MP-WEIXIN
if (userDataPath) {
fs.readdir({
dirPath: userDataPath,
success: (res) => {
const qrcodeFiles = res.files.filter(f => f.startsWith('qrcode_'))
// 只保留最新的 2 个文件,删除其他旧文件
if (qrcodeFiles.length > 2) {
qrcodeFiles.sort().slice(0, qrcodeFiles.length - 2).forEach(oldFile => {
fs.unlink({
filePath: `${userDataPath}/${oldFile}`,
success: () => { },
fail: () => { }
})
})
}
// 清理完成后写入新文件
writeBase64File()
},
fail: () => {
// 如果读取目录失败,直接写入
writeBase64File()
}
})
} else {
writeBase64File()
}
// #endif
// #ifndef MP-WEIXIN
writeBase64File()
// #endif
function writeBase64File() {
fs.writeFile({
filePath: filePath,
data: base64String,
encoding: 'base64',
success: () => {
resolve(filePath)
},
fail: (err) => {
console.error('Base64 图片写入失败:', err)
// 如果写入失败,尝试使用临时文件路径(uni.downloadFile 返回的路径)
reject(err)
}
})
}
})
}
// 绘制图片到 canvas(异步加载图片)
const drawImage = (ctx, src, x, y, w, h) => {
return new Promise((resolve) => {
// 如果是 Base64 Data URI,先转换为临时文件
if (src.startsWith('data:image')) {
base64ToTempFilePath(src).then((filePath) => {
ctx.drawImage(filePath, x, y, w, h)
resolve()
}).catch((err) => {
console.error('Base64 图片处理失败:', err)
// 尝试直接使用 Base64(某些平台可能支持)
try {
ctx.drawImage(src, x, y, w, h)
resolve()
} catch (e) {
console.warn('无法绘制 Base64 图片,跳过')
resolve() // 即使失败也继续
}
})
} else {
// 普通图片 URL,下载后绘制
uni.downloadFile({
url: src,
success: (res) => {
if (res.statusCode === 200) {
ctx.drawImage(res.tempFilePath, x, y, w, h)
resolve()
} else {
console.warn('图片下载失败:', src, 'statusCode:', res.statusCode)
resolve() // 即使失败也继续
}
},
fail: (err) => {
console.warn('图片下载失败:', src, err)
resolve() // 即使失败也继续
}
})
}
})
}
</script>
<style lang="less" scoped>
.poster-page-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.8);
display: flex;
align-items: center;
justify-content: center;
z-index: 10000;
}
.poster-page-container {
position: relative;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
padding: 40rpx;
}
.poster-wrapper {
position: relative;
width: 542rpx;
height: 956rpx;
display: flex;
flex-direction: column;
align-items: center;
}
.poster-bg {
width: 542rpx;
height: 956rpx;
z-index: 0;
}
.poster-nickname-wrapper {
position: absolute;
top: 40rpx;
left: 24rpx;
display: flex;
align-items: center;
z-index: 1;
}
.poster-nickname-bg {
position: relative;
width: 256rpx;
height: 58rpx;
z-index: 0;
}
.poster-avatar {
width: 48rpx;
height: 48rpx;
border-radius: 50%;
flex-shrink: 0;
z-index: 1;
position: absolute;
top: 6rpx;
left: 8rpx;
}
.poster-nickname-text {
position: absolute;
left: 0;
top: 0;
width: 256rpx;
height: 58rpx;
padding: 0 30rpx;
font-size: 28rpx;
color: #333333;
text-align: center;
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.poster-image-wrapper {
position: absolute;
top: 120rpx;
left: 50%;
transform: translateX(-50%);
width: 494rpx;
height: 802rpx;
display: flex;
justify-content: center;
z-index: 1;
}
.poster-image-bg {
position: absolute;
top: 0;
left: 0;
width: 494rpx;
height: 802rpx;
z-index: 0;
}
.poster-image {
position: relative;
height: 586rpx;
z-index: 1;
object-fit: contain;
margin: 26rpx;
box-sizing: border-box;
}
.poster-content {
position: absolute;
bottom: 146rpx;
left: 22rpx;
width: calc(100% - 44rpx);
z-index: 2;
}
.poster-content-text {
font-size: 28rpx;
font-weight: 500;
color: #000000;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.poster-collection-number {
position: absolute;
bottom: 116rpx;
left: 22rpx;
width: calc(100% - 44rpx);
text-align: left;
z-index: 2;
}
.collection-number-text {
font-size: 20rpx;
color: #D3A458;
}
.poster-download-btn {
position: absolute;
bottom: 36rpx;
left: 22rpx;
width: 118rpx;
height: 46rpx;
display: flex;
z-index: 2;
}
.download-icon {
width: 100%;
height: 100%;
}
.poster-qrcode-wrapper {
position: absolute;
bottom: 26rpx;
right: 22rpx;
width: 114rpx;
height: 114rpx;
z-index: 2;
}
.poster-qrcode-image {
width: 114rpx;
height: 114rpx;
}
.poster-close-btn {
position: absolute;
left: 50%;
top: 1400rpx;
transform: translateX(-50%);
width: 56rpx;
height: 56rpx;
display: flex;
align-items: center;
justify-content: center;
z-index: 2;
}
.close-icon {
width: 56rpx;
height: 56rpx;
}
.poster-canvas {
position: fixed;
left: -9999px;
top: -9999px;
width: 542rpx;
height: 956rpx;
z-index: -1;
opacity: 0;
}
</style>
<template>
<view v-if="visible" class="share-popup-overlay" @tap="handleOverlayClick">
<view class="share-popup-container" @tap.stop>
<!-- 背景 -->
<image class="share-popup-bg" :src="`${$baseUrl}homepage/Q3Res/xingmaLabPosterBtnConBg.png`"
mode="aspectFit"></image>
<!-- 标题 -->
<view class="share-popup-title">
<view class="close-btn" @tap="handleClose">
<image class="close-icon" :src="`${$baseUrl}homepage/Q3Res/xingmaLabPosterBtnConCloseBtn.png`"
mode="aspectFit"></image>
</view>
</view>
<!-- 按钮区域 -->
<view class="share-popup-buttons">
<!-- 分享给好友 -->
<view class="share-button-item">
<button open-type="share" class="share-button-trigger" @tap="handleShareToFriend">
<view class="button-icon button-icon-share">
<image class="icon-image"
:src="`${$baseUrl}homepage/Q3Res/xingmaLabPosterBtnConShareBtn.png`" mode="aspectFit">
</image>
</view>
</button>
</view>
<!-- 生成分享海报 -->
<view class="share-button-item" @tap="handleGeneratePoster">
<view class="button-icon button-icon-poster">
<image class="icon-image"
:src="`${$baseUrl}homepage/Q3Res/xingmaLabPosterBtnConShowPosterBtn.png`" mode="aspectFit">
</image>
</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { getCurrentInstance } from 'vue'
const { proxy } = getCurrentInstance()
const $baseUrl = proxy.$baseUrl
const props = defineProps({
visible: {
type: Boolean,
default: false
}
})
const emit = defineEmits(['close', 'shareToFriend', 'generatePoster'])
// 关闭弹窗
const handleClose = () => {
emit('close')
}
// 点击遮罩关闭
const handleOverlayClick = () => {
handleClose()
}
// 分享给好友
const handleShareToFriend = () => {
emit('shareToFriend')
handleClose()
}
// 生成分享海报
const handleGeneratePoster = () => {
emit('generatePoster')
handleClose()
}
</script>
<style lang="less" scoped>
.share-popup-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
align-items: flex-end;
justify-content: center;
z-index: 9999;
}
.share-popup-container {
position: relative;
width: 750rpx;
height: 432rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.share-popup-bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 0;
}
.share-popup-title {
position: relative;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
padding-top: 60rpx;
z-index: 1;
}
.title-text {
font-size: 36rpx;
font-weight: 500;
color: #333333;
}
.close-btn {
position: absolute;
right: 40rpx;
top: 50%;
transform: translateY(-50%);
width: 48rpx;
height: 48rpx;
display: flex;
align-items: center;
justify-content: center;
}
.close-icon {
width: 48rpx;
height: 48rpx;
}
.share-popup-buttons {
position: relative;
width: 100%;
display: flex;
align-items: center;
justify-content: space-around;
padding: 80rpx 60rpx 0;
z-index: 1;
}
.share-button-item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
position: relative;
}
.share-button-trigger {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: transparent;
border: none;
padding: 0;
margin: 0;
line-height: normal;
}
.share-button-trigger::after {
border: none;
}
.button-icon {
margin-bottom: 20rpx;
display: flex;
align-items: center;
justify-content: center;
}
.button-icon-share {
width: 148rpx;
height: 202rpx;
}
.button-icon-poster {
width: 170rpx;
height: 202rpx;
}
.icon-image {
width: 100%;
height: 100%;
}
.button-text {
font-size: 28rpx;
color: #333333;
}
</style>
......@@ -42,9 +42,9 @@
@click="handleLikeClick"></span>
<!-- 分享按钮 -->
<button open-type="share" class="xingmalabdetailpagebottomconsharebtn"
<view class="xingmalabdetailpagebottomconsharebtn"
:style="{ backgroundImage: `url(${$baseUrl}${getImageUrl(config.images.bottomConShareBtn)})` }"
@click="handleShareClick"></button>
@click="handleShareClick"></view>
<!-- 未登录时覆盖的授权按钮层 -->
<div v-if="homeStore && !homeStore.isLogin" class="auth-overlay">
......@@ -57,6 +57,25 @@
class="auth-share-btn phone-auth-btn-cover"></button>
</div>
</div>
<!-- 分享弹窗 -->
<XingmaLabSharePopup
:visible="showSharePopup"
@close="handleCloseSharePopup"
@shareToFriend="handleShareToFriend"
@generatePoster="handleGeneratePoster" />
<!-- 海报页面 -->
<XingmaLabPosterPage
:visible="showPosterPage"
:imageUrl="detailData.imgUrl"
:content="detailData.content || '可爱'"
:collectionNumber="detailData.bizNo || collectionNumber"
:defaultNickname="detailData.nickname || '星妈用户'"
:avatar="detailData.avatar || ''"
:recordId="recordId || detailData.id || ''"
@close="handleClosePosterPage"
@download="handleDownloadPoster" />
</view>
</template>
......@@ -83,6 +102,8 @@
useUserStore
} from '@/stores/user.js'
import md from '../../md';
import XingmaLabSharePopup from '@/components/xingmaLab/XingmaLabSharePopup.vue'
import XingmaLabPosterPage from '@/components/xingmaLab/XingmaLabPosterPage.vue'
// 组件名称
defineOptions({
......@@ -104,6 +125,10 @@
state: null
})
// 分享弹窗和海报页面状态
const showSharePopup = ref(false)
const showPosterPage = ref(false)
// 配置对象
const config = xingmaLabDetailConfig
......@@ -259,22 +284,58 @@
}
const handleShareClick = () => {
// 使用 open-type="share" 时,点击事件可以为空
// 分享内容通过页面配置自动设置
console.log('分享按钮被点击')
//TODO:埋点
// 显示分享弹窗
showSharePopup.value = true
// 埋点
md.sensorComponentLogTake({
xcxComponentClick: "true",
pageName: "星妈lab-藏品详情页",
componentName: "藏品详情",
componentContent: "分享"
});
}
// 手动触发分享(如果需要的话)
// uni.showShareMenu({
// withShareTicket: true,
// menus: ['shareAppMessage'] // 仅分享给好友,禁用朋友圈
// })
// 关闭分享弹窗
const handleCloseSharePopup = () => {
showSharePopup.value = false
}
// 分享给好友
const handleShareToFriend = () => {
// 埋点
md.sensorComponentLogTake({
xcxComponentClick: "true",
pageName: "星妈lab-藏品详情页",
componentName: "分享弹窗",
componentContent: "分享给好友"
});
// 分享功能由 button 的 open-type="share" 自动触发
}
// 生成分享海报
const handleGeneratePoster = () => {
showPosterPage.value = true
// 埋点
md.sensorComponentLogTake({
xcxComponentClick: "true",
pageName: "星妈lab-藏品详情页",
componentName: "分享弹窗",
componentContent: "生成分享海报"
});
}
// 关闭海报页面
const handleClosePosterPage = () => {
showPosterPage.value = false
}
// 下载海报
const handleDownloadPoster = (data) => {
// TODO: 实现海报下载逻辑
// 可以使用 canvas 将海报内容绘制成图片,然后保存到相册
console.log('下载海报', data)
}
......
......@@ -505,6 +505,17 @@ export default {
// 根据商品类型设置规格选项
this.setSpecOptions(data.skus);
// 检查接口返回是否包含 activityId 和 sessionKey,如果有则设置为秒杀商品
if (data.activityId && data.sessionKey) {
this.isSeckill = true;
this.seckillParams = {
activityId: data.activityId,
sessionKey: data.sessionKey,
appGoodsId: data.id || this.goodsData.id || ''
};
console.log('普通商品详情接口返回秒杀参数,设置为秒杀商品:', this.seckillParams);
}
} else {
uni.showToast({
title: response.msg || '获取商品详情失败',
......@@ -584,6 +595,17 @@ export default {
// 秒杀商品固定数量为1
this.quantity = 1;
// 检查接口返回是否包含 activityId 和 sessionKey,更新秒杀参数
if (data.activityId && data.sessionKey) {
this.isSeckill = true;
this.seckillParams = {
activityId: data.activityId,
sessionKey: data.sessionKey,
appGoodsId: data.id || this.goodsData.id || ''
};
console.log('秒杀商品详情接口返回秒杀参数:', this.seckillParams);
}
} else {
uni.showToast({
title: response.msg || '获取秒杀商品详情失败',
......@@ -1101,11 +1123,11 @@ export default {
storeId: this.orderParams.storeId || '',
projectId: this.orderParams.projectId || '',
// 秒杀相关参数
// 秒杀相关参数(如果有 activityId 和 sessionKey 则传递,即使原本是普通商品)
isSeckill: this.isSeckill,
activityId: this.seckillParams.activityId,
sessionKey: this.seckillParams.sessionKey,
appGoodsId: this.seckillParams.appGoodsId
activityId: this.seckillParams.activityId || '',
sessionKey: this.seckillParams.sessionKey || '',
appGoodsId: this.seckillParams.appGoodsId || ''
};
console.log('结算页面参数:', settlementParams);
......
......@@ -285,11 +285,11 @@ export default {
parsePageParams(options) {
console.log('结算页面接收到的参数:', options);
// 判断是否为秒杀
this.isSeckill = !!(options.isSeckill === 'true' || options.isSeckill === true || options.activityId);
// 判断是否为秒杀:如果有 activityId 和 sessionKey,则判断为秒杀
this.isSeckill = !!(options.isSeckill === 'true' || options.isSeckill === true || (options.activityId && options.sessionKey));
// 解析秒杀参数
if (this.isSeckill) {
if (this.isSeckill && options.activityId && options.sessionKey) {
this.seckillParams = {
activityId: options.activityId || '',
sessionKey: options.sessionKey || '',
......
<template>
<view class="brand-container">
<view class="content">
<swiper
id="firstScreen"
class="swiper banner"
:current="swiperIndex"
@animationfinish="intervalChange"
circular
:indicator-dots="indicatorDots"
:autoplay="autoplay"
:interval="interval"
:duration="duration"
:indicator-color="indicatorColor"
:indicator-active-color="indicatoractiveColor"
>
<swiper id="firstScreen" class="swiper banner" :current="swiperIndex" @animationfinish="intervalChange" circular
:indicator-dots="indicatorDots" :autoplay="autoplay" :interval="interval" :duration="duration"
:indicator-color="indicatorColor" :indicator-active-color="indicatoractiveColor">
<swiper-item v-for="(item, index) in swiperList" :key="index">
<view class="swiper-item banneritem">
<image
:data-log="{
<image :data-log="{
xcxClick: '品牌故事-首屏页面点击',
pageName: '品牌故事-首屏页面',
buttonName: `背景图-${swiperNameList[index]}`,
}"
:data-comlog="{
}" :data-comlog="{
xcxComponentClick: 'true',
pageName: '品牌故事页',
componentName: '品牌故事页banner',
componentContent: item.title || '',
}"
:data-link="item.link"
@tap="jumpLink(item.link, item.videoUrl, $event)"
class="b-img"
:src="item?.url?.indexOf('http') === 0 ? item.url : $baseUrl + item.url"
>
}" :data-link="item.link" @tap="jumpLink(item.link, item.videoUrl, $event)" class="b-img"
:src="item?.url?.indexOf('http') === 0 ? item.url : $baseUrl + item.url">
</image>
</view>
</swiper-item>
......@@ -62,170 +46,106 @@
<view class="swiper-mask">
<image class="swiper-mask-img" :src="$baseUrl + 'homepage/home_format_v2.png'"></image>
</view>
<view
class="videoposterbox"
v-if="video1Channel.videoUrl || (video1Channel.finderUserName && video1Channel.feedId)"
>
<video
v-if="video1Channel.videoUrl"
ref="brandVideo1Ref"
id="brandVideo1"
class="videoposter"
:src="
video1Channel.videoUrl?.indexOf('http') === 0
<view class="videoposterbox"
v-if="video1Channel.videoUrl || (video1Channel.finderUserName && video1Channel.feedId)">
<video v-if="video1Channel.videoUrl" ref="brandVideo1Ref" id="brandVideo1" class="videoposter" :src="video1Channel.videoUrl?.indexOf('http') === 0
? video1Channel.videoUrl
: $baseUrl + video1Channel.videoUrl
"
:autoplay="false"
:data-log="{
" :autoplay="false" :data-log="{
xcxClick: '品牌故事-次屏页面点击',
pageName: '品牌故事-首屏页面',
buttonName: '腰部品牌Video',
}"
:poster="
video1Channel.posterUrl?.indexOf('http') === 0
}" :poster="video1Channel.posterUrl?.indexOf('http') === 0
? video1Channel.posterUrl
: $baseUrl + video1Channel.posterUrl
"
object-fit="cover"
@loadedmetadata="onVideoLoadedMeta"
@play="onVideo1Play"
@ended="onVideo1Ended"
></video>
<image
v-else
:data-log="{
" object-fit="cover" @loadedmetadata="onVideoLoadedMeta" @play="onVideo1Play" @ended="onVideo1Ended"></video>
<image v-else :data-log="{
xcxClick: '品牌故事-次屏页面点击',
pageName: '品牌故事-首屏页面',
buttonName: '腰部品牌Video',
}"
:data-comlog="{
}" :data-comlog="{
xcxComponentClick: 'true',
pageName: '品牌故事页',
componentName: '品牌故事视频',
componentContent: video1Channel.title || '',
}"
@tap="openChannel(video1Channel, $event)"
class="videoposter"
:src="
video1Channel.posterUrl?.indexOf('http') === 0
}" @tap="openChannel(video1Channel, $event)" class="videoposter" :src="video1Channel.posterUrl?.indexOf('http') === 0
? video1Channel.posterUrl
: $baseUrl + video1Channel.posterUrl
"
>
">
</image>
<view class="videoposterboxtitle" v-if="showVideo1Title">{{ video1Channel.title || '' }}</view>
</view>
<!-- 产品家族 -->
<view
id="secondScreen"
class="productcontai"
v-if="productTabList.length > 0 && productInfoList.length > 0"
>
<view id="secondScreen" class="productcontai" v-if="productTabList.length > 0 && productInfoList.length > 0">
<text class="maintitle">{{ erqiPeizhi.title1 }}</text>
<!-- tab容器 -->
<scroll-view
class="listbox"
scroll-x="true"
show-scrollbar="false"
:scroll-into-view="'tab-' + channelTabIndex"
:scroll-with-animation="true"
>
<scroll-view class="listbox" scroll-x="true" show-scrollbar="false" :scroll-into-view="'tab-' + channelTabIndex"
:scroll-with-animation="true">
<view class="tab-container">
<view
@tap="channelTabHandler(index, $event)"
:data-log="{
<view @tap="channelTabHandler(index, $event)" :data-log="{
xcxClick: '品牌故事-次屏页面点击',
pageName: '品牌故事-次屏页面',
buttonName: `${item}`,
}"
:data-comlog="{
}" :data-comlog="{
xcxComponentClick: 'true',
pageName: '品牌故事页',
componentName: '飞鹤产品家族',
componentContent: '产品家族切换分类-' + item,
}"
:class="channelTabIndex === index ? 'tabitem tabActive' : 'tabitem'"
v-for="(item, index) in productTabList"
:key="index"
:id="'tab-' + index"
>
}" :class="channelTabIndex === index ? 'tabitem tabActive' : 'tabitem'"
v-for="(item, index) in productTabList" :key="index" :id="'tab-' + index">
{{ item }}
</view>
</view>
</scroll-view>
<!-- 内容 -->
<scroll-view
v-if="productInfoList.length > 0"
class="productbox"
scroll-x="true"
show-scrollbar="false"
>
<scroll-view v-if="productInfoList.length > 0" class="productbox" scroll-x="true" show-scrollbar="false">
<view class="product-grid">
<view class="product-row">
<view
class="infobox"
:key="'top-' + index"
v-for="(infoItem, index) in productInfoList[channelTabIndex].filter((item, i) => i % 2 === 0)"
:style="{
<view class="infobox" :key="'top-' + index"
v-for="(infoItem, index) in productInfoList[channelTabIndex].filter((item, i) => i % 2 === 0)" :style="{
background: `url(${$baseUrl}brandpage/infoBoxBg.png) no-repeat center/contain`,
}"
:data-log="{
}" :data-log="{
xcxClick: '品牌故事-次屏页面点击',
pageName: '品牌故事-次屏页面',
buttonName: `${productTabList[channelTabIndex] + '中的' + infoItem.title}+'商品'`,
}"
:data-comlog="{
}" :data-comlog="{
xcxComponentClick: 'true',
pageName: '品牌故事页',
componentName: '飞鹤产品家族',
componentContent: '产品家族商品-' + infoItem.desc,
}"
@tap="jumpProduct(infoItem, $event)"
>
}" @tap="jumpProduct(infoItem, $event)">
<view class="flexbox">
<view class="infotitle">
{{ infoItem.title }}
</view>
<image
class="infoimg"
:src="infoItem.bgUrl?.indexOf('http') === 0 ? infoItem.bgUrl : $baseUrl + infoItem.bgUrl"
>
<image class="infoimg"
:src="infoItem.bgUrl?.indexOf('http') === 0 ? infoItem.bgUrl : $baseUrl + infoItem.bgUrl">
</image>
</view>
<view class="infodesc">{{ infoItem.desc }}</view>
</view>
</view>
<view class="product-row">
<view
class="infobox"
:key="'bottom-' + index"
v-for="(infoItem, index) in productInfoList[channelTabIndex].filter((item, i) => i % 2 === 1)"
:style="{
<view class="infobox" :key="'bottom-' + index"
v-for="(infoItem, index) in productInfoList[channelTabIndex].filter((item, i) => i % 2 === 1)" :style="{
background: `url(${$baseUrl}brandpage/infoBoxBg.png) no-repeat center/contain`,
}"
:data-log="{
}" :data-log="{
xcxClick: '品牌故事-次屏页面点击',
pageName: '品牌故事-次屏页面',
buttonName: `${productTabList[channelTabIndex] + '中的' + infoItem.title}+'商品'`,
}"
:data-comlog="{
}" :data-comlog="{
xcxComponentClick: 'true',
pageName: '品牌故事页',
componentName: '飞鹤产品家族',
componentContent: '产品家族商品-' + infoItem.desc,
}"
@tap="jumpProduct(infoItem, $event)"
>
}" @tap="jumpProduct(infoItem, $event)">
<view class="flexbox">
<view class="infotitle">
{{ infoItem.title }}
</view>
<image
class="infoimg"
:src="infoItem.bgUrl?.indexOf('http') === 0 ? infoItem.bgUrl : $baseUrl + infoItem.bgUrl"
>
<image class="infoimg"
:src="infoItem.bgUrl?.indexOf('http') === 0 ? infoItem.bgUrl : $baseUrl + infoItem.bgUrl">
</image>
</view>
<view class="infodesc">{{ infoItem.desc }}</view>
......@@ -235,68 +155,37 @@
</scroll-view>
</view>
<!-- 视频 -->
<view
class="videoposterbox"
v-if="video2Channel.videoUrl || (video2Channel.finderUserName && video2Channel.feedId)"
>
<video
v-if="video2Channel.videoUrl"
ref="brandVideo2Ref"
id="brandVideo2"
class="videoposter"
:src="
video2Channel.videoUrl?.indexOf('http') === 0
<view class="videoposterbox"
v-if="video2Channel.videoUrl || (video2Channel.finderUserName && video2Channel.feedId)">
<video v-if="video2Channel.videoUrl" ref="brandVideo2Ref" id="brandVideo2" class="videoposter" :src="video2Channel.videoUrl?.indexOf('http') === 0
? video2Channel.videoUrl
: $baseUrl + video2Channel.videoUrl
"
:autoplay="false"
object-fit="cover"
@loadedmetadata="onVideoLoadedMeta"
@play="onVideo2Play"
:poster="
video2Channel.posterUrl?.indexOf('http') === 0
" :autoplay="false" object-fit="cover" @loadedmetadata="onVideoLoadedMeta" @play="onVideo2Play" :poster="video2Channel.posterUrl?.indexOf('http') === 0
? video2Channel.posterUrl
: $baseUrl + video2Channel.posterUrl
"
@ended="onVideo2Ended"
></video>
<image
v-else
class="videoposter"
:data-comlog="{
" @ended="onVideo2Ended"></video>
<image v-else class="videoposter" :data-comlog="{
xcxComponentClick: 'true',
pageName: '品牌故事页',
componentName: '品牌故事视频',
componentContent: video2Channel.title || '',
}"
@tap="openChannel(video2Channel, $event)"
:src="
video2Channel.posterUrl?.indexOf('http') === 0
}" @tap="openChannel(video2Channel, $event)" :src="video2Channel.posterUrl?.indexOf('http') === 0
? video2Channel.posterUrl
: $baseUrl + video2Channel.posterUrl
"
>
">
</image>
<view class="videoposterboxtitle" v-if="showVideo2Title">{{ video2Channel.title || '' }}</view>
</view>
<!-- 鹤小飞一家 -->
<view
id="thirdScreen"
class="ipbox"
v-if="erqiPeizhi.appId1 && erqiPeizhi.appId2"
:style="{ background: `url(${$baseUrl}brandpage/hexiaofeiBg.png) no-repeat center/contain` }"
>
<view id="thirdScreen" class="ipbox" v-if="erqiPeizhi.appId1 && erqiPeizhi.appId2"
:style="{ background: `url(${$baseUrl}brandpage/hexiaofeiBg.png) no-repeat center/contain` }">
<!-- <store-product appid="wx1ad0903b95889ea1" product-id="10000239570622" custom-content="true"> -->
<image
:data-log="{
<image :data-log="{
xcxClick: '品牌故事-三屏页面点击',
pageName: '品牌故事-三屏页面',
buttonName: `全家形象`,
}"
class="iphexiaofei"
@tap="jumpLink(erqiPeizhi.link, erqiPeizhi.videoUrl, $event)"
:src="erqiPeizhi.iphexiaofeiUrl"
>
}" class="iphexiaofei" @tap="jumpLink(erqiPeizhi.link, erqiPeizhi.videoUrl, $event)"
:src="erqiPeizhi.iphexiaofeiUrl">
</image>
<!-- </store-product> -->
<view class="ipcard">
......@@ -308,26 +197,17 @@
<view class="ipflex">
<!-- 竖版商品 -->
<view class="ipbg ip1" id="ip1" @tap="ipTapEvent(1, $event)">
<store-product
:appid="erqiPeizhi.appId1"
:product-id="erqiPeizhi.productId1"
custom-content="true"
class="store-product-container"
>
<store-product :appid="erqiPeizhi.appId1" :product-id="erqiPeizhi.productId1" custom-content="true"
class="store-product-container">
<view class="ipcontainer">
<image
:data-log="{
<image :data-log="{
xcxClick: '品牌故事-三屏页面点击',
pageName: '品牌故事-三屏页面',
buttonName: `${hexiaofeiNameList[0]}`,
}"
:src="
erqiPeizhi.ipImg1?.indexOf('http') === 0
}" :src="erqiPeizhi.ipImg1?.indexOf('http') === 0
? erqiPeizhi.ipImg1
: $baseUrl + erqiPeizhi.ipImg1
"
class="ip1"
>
" class="ip1">
</image>
<view class="ipcontext">
<view class="ipcontext-desc">{{ erqiPeizhi.ipDesc1 || '' }}</view>
......@@ -340,29 +220,21 @@
<view class="ipright">
<!-- 横版商品 -->
<view class="ipbg ip2" id="ip2" @tap="ipTapEvent(2, $event)">
<store-product
:appid="erqiPeizhi.appId2"
:product-id="erqiPeizhi.productId2"
custom-content="true"
class="store-product-container"
>
<store-product :appid="erqiPeizhi.appId2" :product-id="erqiPeizhi.productId2" custom-content="true"
class="store-product-container">
<view class="ipcontainer">
<view class="ipcontext">
<view class="ipcontext-title">{{ erqiPeizhi.ipTitle2 || '' }}</view>
<view class="ipcontext-desc">{{ erqiPeizhi.ipDesc2 || '' }}</view>
</view>
<image
:data-log="{
<image :data-log="{
xcxClick: '品牌故事-三屏页面点击',
pageName: '品牌故事-三屏页面',
buttonName: `${hexiaofeiNameList[1]}`,
}"
:src="
erqiPeizhi.ipImg2?.indexOf('http') === 0
}" :src="erqiPeizhi.ipImg2?.indexOf('http') === 0
? erqiPeizhi.ipImg2
: $baseUrl + erqiPeizhi.ipImg2
"
>
">
</image>
</view>
</store-product>
......@@ -370,36 +242,26 @@
<view style="display: flex; justify-content: space-between; margin-top: 20rpx">
<!-- 视频号 -->
<view class="ipbg ip3" id="ip3" @tap="ipTapEvent(3, $event)">
<image
:data-log="{
<image :data-log="{
xcxClick: '品牌故事-三屏页面点击',
pageName: '品牌故事-三屏页面',
buttonName: `${hexiaofeiNameList[2]}`,
}"
@tap="showPopup(0, $event)"
:src="
erqiPeizhi.ipImg3?.indexOf('http') === 0
}" @tap="showPopup(0, $event)" :src="erqiPeizhi.ipImg3?.indexOf('http') === 0
? erqiPeizhi.ipImg3
: $baseUrl + erqiPeizhi.ipImg3
"
>
">
</image>
</view>
<!-- 小红书 -->
<view class="ipbg ip4" id="ip4" @tap="ipTapEvent(4, $event)">
<image
:data-log="{
<image :data-log="{
xcxClick: '品牌故事-三屏页面点击',
pageName: '品牌故事-三屏页面',
buttonName: `${hexiaofeiNameList[3]}`,
}"
@tap="showPopup(2, $event)"
:src="
erqiPeizhi.ipImg4?.indexOf('http') === 0
}" @tap="showPopup(2, $event)" :src="erqiPeizhi.ipImg4?.indexOf('http') === 0
? erqiPeizhi.ipImg4
: $baseUrl + erqiPeizhi.ipImg4
"
>
">
</image>
</view>
</view>
......@@ -412,31 +274,21 @@
<!-- <text class="subtitle">关注祖国下一代的营养、教育和陪伴</text> -->
<view class="channelscroll">
<view class="box">
<view
class="infobox"
:key="index"
v-for="(infoItem, index) in esgInfoList"
:id="'esg' + (index + 1)"
<view class="infobox" :key="index" v-for="(infoItem, index) in esgInfoList" :id="'esg' + (index + 1)"
:style="{
background: `url(${$baseUrl}brandpage/esgItemBg.png) no-repeat center/505rpx 638rpx`,
}"
:data-log="{
}" :data-log="{
xcxClick: `品牌故事-三屏页面点击`,
pageName: `品牌故事-三屏页面ESG点击`,
buttonName: `${index + 1}-${infoItem.desc}`,
}"
:data-comlog="{
}" :data-comlog="{
xcxComponentClick: 'true',
pageName: '品牌故事页',
componentName: '飞鹤ESG',
componentContent: infoItem.desc,
}"
@tap="jumpLink(infoItem.link, infoItem.videoUrl, $event)"
>
<image
class="infoimg imgRaduis"
:src="infoItem.bgUrl?.indexOf('http') === 0 ? infoItem.bgUrl : $baseUrl + infoItem.bgUrl"
>
}" @tap="jumpLink(infoItem.link, infoItem.videoUrl, $event)">
<image class="infoimg imgRaduis"
:src="infoItem.bgUrl?.indexOf('http') === 0 ? infoItem.bgUrl : $baseUrl + infoItem.bgUrl">
</image>
<view class="infotitle">{{ infoItem.desc }}</view>
<view class="infodesc">{{ infoItem.desc2 }}</view>
......@@ -448,13 +300,7 @@
<view>
<!-- 普通弹窗 -->
<uni-popup
:is-mask-click="false"
:safe-area="false"
ref="popup"
background-color="#fff"
border-radius="48rpx"
>
<uni-popup :is-mask-click="false" :safe-area="false" ref="popup" background-color="#fff" border-radius="48rpx">
<view v-if="qrInfoObj !== null" class="popup-content">
<image class="btnclose" @tap="closePop" :src="$baseUrl + 'homepage/btnclose.png'"></image>
<view class="title">
......@@ -462,11 +308,8 @@
</view>
<rich-text class="desc" :nodes="qrInfoObj.desc"> </rich-text>
<image :show-menu-by-longpress="true" class="qrcode" :src="$baseUrl + qrInfoObj.qrUrl"></image>
<image
@tap="downloadHandler($baseUrl + qrInfoObj.qrUrl)"
class="btndownload"
:src="$baseUrl + 'homepage/btn_download.png'"
></image>
<image @tap="downloadHandler($baseUrl + qrInfoObj.qrUrl)" class="btndownload"
:src="$baseUrl + 'homepage/btn_download.png'"></image>
</view>
<view v-else class="popup-content" style="height: 899rpx">
<image class="xingmahui" :src="$baseUrl + 'brandpage/hexiaofei.png'"></image>
......@@ -475,14 +318,8 @@
</uni-popup>
</view>
<view v-if="showVideo" class="video-popup">
<video
:src="currentVideoUrl"
controls
autoplay
:style="{ width: videoWidth + 'px', height: videoHeight + 'px' }"
@loadedmetadata="onVideoLoadedMeta"
@play="onVideoPlay"
></video>
<video :src="currentVideoUrl" controls autoplay :style="{ width: videoWidth + 'px', height: videoHeight + 'px' }"
@loadedmetadata="onVideoLoadedMeta" @play="onVideoPlay"></video>
<view class="close-btn-bottom" @tap="closeVideo">×</view>
</view>
</view>
......@@ -630,8 +467,8 @@ export default {
data.videoUrl = this.$baseUrl + data.videoUrl;
}
this.currentVideoUrl = data.videoUrl;
this.video1Channel = data.video1Channel;
this.video2Channel = data.video2Channel;
this.video1Channel = data.video1Channel || {};
this.video2Channel = data.video2Channel || {};
this.initExposure();
}
},
......@@ -1444,6 +1281,7 @@ export default {
.ipcontainer {
position: relative;
.ipcontext {
display: flex;
flex-direction: column;
......@@ -1451,6 +1289,7 @@ export default {
justify-content: flex-start;
font-size: 20rpx;
text-align: center;
.ipcontext-desc,
.ipcontext-title {
width: 100%;
......@@ -1458,6 +1297,7 @@ export default {
text-overflow: ellipsis;
white-space: nowrap;
}
.ipcontext-title {
color: @color-gold-main;
}
......@@ -1475,6 +1315,7 @@ export default {
display: flex;
justify-content: center;
align-items: center;
.store-product-container {
display: flex;
justify-content: center;
......@@ -1486,6 +1327,7 @@ export default {
width: 288rpx;
height: 380rpx;
overflow: hidden;
.ipcontainer {
display: flex;
flex-direction: column;
......@@ -1493,6 +1335,7 @@ export default {
justify-content: center;
width: 268rpx;
height: 330rpx;
.ipcontext {
width: 100%;
margin-top: 6rpx;
......@@ -1508,6 +1351,7 @@ export default {
.ip2 {
width: 342rpx;
height: 201rpx;
.ipcontainer {
height: 152rpx;
width: 322rpx;
......@@ -1515,6 +1359,7 @@ export default {
flex-direction: row;
align-items: center;
justify-content: space-between;
.ipcontext {
// width: 210rpx;
flex: 1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment