feat(live): 优化直播间功能和界面

- 修改返回逻辑,仅在首页时退出全屏- 优化国际化处理,使用 t 函数替代 $t
-调整直播室错误和成功提示信息的显示
- 修复签名面板的确认功能
-
This commit is contained in:
xingyy 2025-02-17 15:18:55 +08:00
parent 3893938ac1
commit 767e05209c
5 changed files with 54 additions and 19 deletions

View File

@ -7,7 +7,7 @@ const route = useRoute()
const router = useRouter()
const {auctionDetail} = goodStore();
function onBack() {
if (fullLive.value){
if (fullLive.value&&route.name==='index'){
fullLive.value=false
return
}

View File

@ -7,12 +7,13 @@ import xButton from '@/components/x-button/index.vue'
import tangPopup from './tangPopup.vue'
import { goodStore } from "@/stores/goods/index.js"
import { authStore } from "~/stores/auth/index.js"
import {showMinWindow} from "~/components/liveMinWindow/createMinWindow.js";
const { quoteStatus, changeStatus, show, auctionData, getSocketData } = liveStore()
const { quoteStatus, changeStatus, show, auctionData, getSocketData ,lastSnapshot,fullLive} = liveStore()
const { pageRef } = goodStore()
const { userInfo } = authStore()
const showTang = ref(false)
const router = useRouter()
//
const isDragging = ref(false)
const startY = ref(0)
@ -74,7 +75,39 @@ const handleTouchMove = (e) => {
const handleTouchEnd = () => {
isDragging.value = false
}
const captureVideoFrame = () => {
try {
const video = document.querySelector('#J_prismPlayer video')
if (!video) {
console.error('未找到视频元素')
return null
}
const canvas = document.createElement('canvas')
canvas.width = video.videoWidth
canvas.height = video.videoHeight
const ctx = canvas.getContext('2d')
ctx.drawImage(video, 0, 0, canvas.width, canvas.height)
return canvas.toDataURL('image/jpeg', 0.9)
} catch (error) {
console.error('获取视频截图失败:', error)
return null
}
}
const handleCapture = () => {
const imageUrl = captureVideoFrame()
if (imageUrl) {
lastSnapshot.value=imageUrl
showMinWindow(lastSnapshot.value,{
onClick:()=>{
router.replace('/')
fullLive.value=true
console.log('执行')
}
})
}
}
//
onMounted(() => {
if (sidebarRef.value) {
@ -102,7 +135,8 @@ const paySide = computed(() => {
})
const goPay = () => {
show.value = true
handleCapture()
router.push('/signature/protocol')
}
</script>

View File

@ -14,7 +14,7 @@ import {artworkBuy} from "@/api/goods/index.js"
import {useI18n} from 'vue-i18n'
import gsap from 'gsap'
import {CountUp} from 'countup.js'
const { t } = useI18n()
const countUpRef = ref(null)
const nextPriceRef = ref(null)
@ -55,7 +55,7 @@ const initializePlayer = async () => {
player.value.on('error', handlePlayerError)
} catch (error) {
showConfirmDialog({
message: useI18n().t('live_room.error_mess'),
message: t('live_room.error_mess'),
showCancelButton: true
}).then(() => {
@ -118,12 +118,12 @@ const goBuy = async () => {
buyMoney: String(auctionData.value?.nowAuctionPrice?.nextPrice ?? 0)
})
if (res.status === 0) {
message.success(useI18n().t('live_room.success_mess'))
message.success(t('live_room.success_mess'))
}
}
const tipOpen = () => {
message.warning(useI18n().t('live_room.warn_mess'))
message.warning(t('live_room.warn_mess'))
}
</script>
@ -136,24 +136,24 @@ const tipOpen = () => {
<div class="absolute left-1/2 transform -translate-x-1/2 flex flex-col items-center"
style="bottom:calc(var(--safe-area-inset-bottom) + 26px)">
<div class="text-16px text-#FFB25F font-600 flex">
<div class="mr-5px">{{ $t('live_room.now_price') }}{{ auctionData?.nowAuctionPrice?.currency }}</div>
<div class="mr-5px">{{ t('live_room.now_price') }}{{ auctionData?.nowAuctionPrice?.currency }}</div>
<div ref="countUpRef" class="min-w-50px"></div>
</div>
<div class="text-16px text-#fff font-600 flex">
<div class="mr-5px">{{ $t('live_room.lower_price') }}{{ auctionData?.nowAuctionPrice?.currency }}</div>
<div class="mr-5px">{{ t('live_room.lower_price') }}{{ auctionData?.nowAuctionPrice?.currency }}</div>
<div ref="nextPriceRef" class="min-w-50px"></div>
</div>
<div v-if="quoteStatus" class="mt-10px mb-10px">
<van-button @click="goBuy" color="#FFB25F" class="w-344px !h-[40px]">
<div>{{
$t('live_room.confirm')` ${auctionData?.nowAuctionPrice?.currency} ${auctionData?.nowAuctionPrice?.nextPrice ?? 0}`
`${t('live_room.confirm')} ${auctionData?.nowAuctionPrice?.currency} ${auctionData?.nowAuctionPrice?.nextPrice ?? 0}`
}}
</div>
</van-button>
</div>
<div v-else class="mt-10px mb-10px">
<van-button @click="tipOpen" color="#D6D6D8" class="w-344px !h-[40px]" v-if="!quoteStatus">
<div class="text-#7D7D7F text-14px">{{ $t('live_room.button') }}</div>
<div v-if="!quoteStatus" class="mt-10px mb-10px">
<van-button @click="tipOpen" color="#D6D6D8" class="w-344px !h-[40px]" >
<div class="text-#7D7D7F text-14px">{{ t('live_room.button') }}</div>
</van-button>
</div>
@ -167,7 +167,7 @@ const tipOpen = () => {
class="w-344px h-31px rounded-4px absolute top-9px bg-[#151824]/45 backdrop-blur-[10px] backdrop-saturate-[180%] left-1/2 transform translate-x--1/2 flex text-#fff text-14px items-center px-12px line-height-none">
<div class="mr-11px whitespace-nowrap">LOT{{ auctionData.artwork.index }}</div>
<div class="mr-10px truncate">{{ auctionData.artwork.name }}</div>
<div class="whitespace-nowrap">{{ $t('live_room.start') }}</div>
<div class="whitespace-nowrap">{{ t('live_room.start') }}</div>
</div>
</div>
</transition>
@ -190,7 +190,7 @@ const tipOpen = () => {
/* 定义过渡动画 */
.fade-enter-active {
transition: opacity 1.5s ease;
transition: opacity 1s ease;
}
.fade-leave-active {

View File

@ -58,10 +58,11 @@ const handleSignatureSubmit = async (data) => {
};
const confirm = async () => {
const res = await signOffline({
signImgFileData: data.image
signImgFileData: imgUrl.value
})
if (res.status===0){
console.log('res', res)
}
}
const goBack = () => {
router.back()

View File

@ -234,7 +234,7 @@ export const liveStore = createGlobalState(() => {
}
const changeStatus = () => {
if (auctionData.value.artwork.isSelling&&!auctionData.value.artwork.isSoled){
quoteStatus.value = true
quoteStatus.value = !quoteStatus.value
}else {
if (quoteStatus.value){
quoteStatus.value = false