<script setup> import { ref, computed, onMounted, onBeforeUnmount } from "vue" import lockClosed from "@/static/images/lockdfd@2x.png" import lockOpen from "@/static/images/lock4@2x.png" import { liveStore } from "@/stores/live/index.js" 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 ,lastSnapshot,fullLive} = liveStore() const { pageRef } = goodStore() const { userInfo ,payment} = authStore() const showTang = ref(false) const router = useRouter() // 拖动相关状态 const isDragging = ref(false) const startX = ref(0) const startY = ref(0) const currentTop = ref(196) const currentLeft = ref(window.innerWidth - 60) const sidebarRef = ref(null) // 限制拖动范围 const minTop = 0 const maxTop = window.innerHeight - 180 const minLeft = 0 const maxLeft = window.innerWidth - 60 // 吸附相关 const snapThreshold = 30 const snapPosition = () => { const centerX = currentLeft.value + 30 if (centerX < window.innerWidth / 2) { currentLeft.value = 0 } else { currentLeft.value = window.innerWidth - 60 } } // 开始拖动 const handleMouseDown = (e) => { isDragging.value = true startX.value = e.clientX - currentLeft.value startY.value = e.clientY - currentTop.value document.addEventListener('mousemove', handleMouseMove) document.addEventListener('mouseup', handleMouseUp) } // 拖动中 const handleMouseMove = (e) => { if (!isDragging.value) return let newTop = e.clientY - startY.value let newLeft = e.clientX - startX.value // 限制范围 newTop = Math.max(minTop, Math.min(newTop, maxTop)) newLeft = Math.max(minLeft, Math.min(newLeft, maxLeft)) currentTop.value = newTop currentLeft.value = newLeft // 更新位置 if (sidebarRef.value) { sidebarRef.value.style.top = `${newTop}px` sidebarRef.value.style.left = `${newLeft}px` } } // 结束拖动 const handleMouseUp = () => { isDragging.value = false snapPosition() if (sidebarRef.value) { sidebarRef.value.style.left = `${currentLeft.value}px` } document.removeEventListener('mousemove', handleMouseMove) document.removeEventListener('mouseup', handleMouseUp) } // 触摸事件处理 const handleTouchStart = (e) => { isDragging.value = true startX.value = e.touches[0].clientX - currentLeft.value startY.value = e.touches[0].clientY - currentTop.value } const handleTouchMove = (e) => { if (!isDragging.value) return let newTop = e.touches[0].clientY - startY.value let newLeft = e.touches[0].clientX - startX.value newTop = Math.max(minTop, Math.min(newTop, maxTop)) newLeft = Math.max(minLeft, Math.min(newLeft, maxLeft)) currentTop.value = newTop currentLeft.value = newLeft if (sidebarRef.value) { sidebarRef.value.style.top = `${newTop}px` sidebarRef.value.style.left = `${newLeft}px` } } const handleTouchEnd = () => { isDragging.value = false snapPosition() if (sidebarRef.value) { sidebarRef.value.style.left = `${currentLeft.value}px` } } 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) { sidebarRef.value.style.top = `${currentTop.value}px` sidebarRef.value.style.left = `${currentLeft.value}px` } }) // 组件卸载时清理事件监听 onBeforeUnmount(() => { document.removeEventListener('mousemove', handleMouseMove) document.removeEventListener('mouseup', handleMouseUp) }) const openOne = () => { showTang.value = true } const paySide = computed(() => { //当前是否已成交,以及成交人是当前登录用户 if (auctionData.value.artwork?.isSoled && auctionData.value.artwork?.buyInfo?.userID === userInfo.value.ID) { return true } else { return false } }) const goPay = () => { payment.value.leftCurrency=auctionData.value?.nowAuctionPrice?.currency payment.value.leftPrice=auctionData.value?.nowAuctionPrice?.successPrice payment.value.buyUid=auctionData.value?.nowAuctionPrice?.successBuyUuid handleCapture() router.push('/signature/protocol') } </script> <template> <div ref="sidebarRef" class="bg-white w-60px rounded-4px overflow-hidden absolute z-999 cursor-move" @mousedown="handleMouseDown" @touchstart="handleTouchStart" @touchmove="handleTouchMove" @touchend="handleTouchEnd" > <!-- 拍品信息 --> <van-button class="w-60px !h-60px" @click="openOne" style="border: none;border-radius: 0" > <div class="text-center flex flex-col justify-center items-center text-#7D7D7F text-12px"> <div>{{ $t('live_room.lots') }}</div> <div>({{ auctionData?.artwork?.index }}/{{ pageRef.itemCount ?? 0 }})</div> </div> </van-button> <tangPopup v-model:show="showTang"></tangPopup> <!-- 出价开关 --> <van-button class="w-60px !h-60px" @click="changeStatus" style="border-right: none;border-left: none;border-radius: 0;padding: 0" > <div class="text-center flex flex-col justify-center items-center"> <div class="mb-4px"> <img :src="quoteStatus ? lockClosed : lockOpen" class="w-16px h-21px" alt="锁图标" /> </div> <div :class="quoteStatus ? 'text-gray-500' : 'text-blue-600'" class="text-10px transition-colors duration-200" > {{ quoteStatus ? $t('live_room.colse_bid') : $t('live_room.start_bid') }} </div> </div> </van-button> <!-- 支付 --> <van-button v-if="paySide" class="w-60px !h-60px" style="border: none;border-radius: 0" @click="goPay" > <div class="text-center flex flex-col justify-center items-center text-yellow-600"> <div class="text-10px">{{auctionData?.nowAuctionPrice?.currency}}</div> <div class="text-12px">{{auctionData?.nowAuctionPrice?.successPrice}}</div> <div class="text-10px">{{ $t('art_detail_page.button') }}</div> </div> </van-button> </div> </template> <style scoped> .cursor-move { cursor: move; user-select: none; touch-action: none; transition: left 0.3s ease; } </style>