import { ref } from 'vue' export function useDialogRotation() { let timer = null let screenWidth = 375 let screenHeight = 812 const initDialogRotation = ({ screenW, screenH }) => { screenWidth = screenW screenHeight = screenH } const isCabinInViewport = (cabin) => { return new Promise((resolve) => { const query = uni.createSelectorQuery() query.select(`#cabin-${cabin.key}`).boundingClientRect((rect) => { if (!rect) { resolve(false) return } const visibleTop = Math.max(0, rect.top) const visibleBottom = Math.min(screenHeight, rect.bottom) const visibleLeft = Math.max(0, rect.left) const visibleRight = Math.min(screenWidth, rect.right) const visibleWidth = Math.max(0, visibleRight - visibleLeft) const visibleHeight = Math.max(0, visibleBottom - visibleTop) const visibleArea = visibleWidth * visibleHeight const totalArea = rect.width * rect.height const visiblePercent = totalArea > 0 ? visibleArea / totalArea : 0 resolve(visiblePercent > 0.7) }).exec() }) } const rotateDialogVisibility = async (cabins) => { if (!cabins.length) return // 先全部重置为 false cabins.forEach(c => c.showDialog = false) // 筛选符合条件的 cabin:有昵称、有展位剩余 const hasData = cabins.filter(c => c.nickname && c.sharedBoothSlotsRemaining !== null) // 批量检查所有 cabin 是否在可视区域内 const viewportChecks = await Promise.all(hasData.map(c => isCabinInViewport(c))) const eligible = hasData.filter((c, i) => viewportChecks[i]) if (eligible.length === 0) return // 随机选择 2-3 个 const count = Math.min(Math.floor(Math.random() * 2) + 2, eligible.length, 3) const shuffled = eligible.sort(() => Math.random() - 0.5) for (let i = 0; i < count; i++) { shuffled[i].showDialog = true } } const startDialogRotation = (cabins) => { stopDialogRotation() const rotate = async () => { await rotateDialogVisibility(cabins) const interval = Math.floor(Math.random() * 1000) + 2000 timer = setTimeout(rotate, interval) } rotate() } const stopDialogRotation = () => { if (timer) { clearTimeout(timer) timer = null } } return { initDialogRotation, startDialogRotation, stopDialogRotation, } }