<script setup>
|
import { ref, onMounted, nextTick } from 'vue'
|
import dayjs from 'dayjs'
|
import UQRCode from 'uqrcodejs'
|
import { getLargeScreenData } from '@/utils/request'
|
import duration from 'dayjs/plugin/duration'
|
dayjs.extend(duration)
|
import VScaleScreen from 'v-scale-screen'
|
|
const qrcode = ref('')
|
const contentList = ref([])
|
const contentTempList = ref([])
|
const page = ref(1)
|
const timer = ref()
|
|
const callList = ref([])
|
const activeCall = ref({})
|
const pageCall = ref(0)
|
const timerCall = ref()
|
|
const initData = () => {
|
getLargeScreenData().then(res => {
|
if (res.data && res.data.allList) {
|
contentList.value = res.data.allList.map(item => {
|
if (item.optTime) {
|
item.optTimeTemp = dayjs(item.optTime).format('HH:mm')
|
// item.optTimeTemp = dayjs.duration(Math.abs(new Date().getTime() - item.optTime)).format('HH:mm')
|
}
|
return item
|
})
|
clearInterval(timer.value)
|
setInitContent()
|
}
|
if (res.data && res.data.waitWorkList) {
|
callList.value = res.data.waitWorkList
|
}
|
qrcode.value = res.data.qrCode
|
initQrcode()
|
clearInterval(timerCall.value)
|
setInitCall()
|
})
|
}
|
|
const frequencyFn = (length) => {
|
if (length <= 16) { // 2
|
return 30 * 1000
|
} else if (length <= 24) { // 3
|
return 20 * 1000
|
} else if (length <= 32) {// 4
|
return 15 * 1000
|
} else if (length <= 48) {// 6
|
return 10 * 1000
|
} else if (length <= 60) {// 10
|
return 6 * 1000
|
} else {
|
return 4 * 1000
|
}
|
}
|
const frequencyCallFn = (length) => {
|
if (length <= 10) { // 2
|
return 6 * 1000
|
} else if (length <= 20) { // 3
|
return 3 * 1000
|
} else {
|
return 2 * 1000
|
}
|
}
|
const setInitContent = () => {
|
if (contentList.value && contentList.value.length > 0) {
|
contentTempList.value = contentList.value.slice(0, 8)
|
if (page.value * 8 >= contentList.value.length) {
|
page.value = 1
|
} else {
|
page.value++
|
}
|
timer.value = setInterval(() => {
|
if (page.value * 8 >= contentList.value.length) {
|
page.value = 1
|
} else {
|
page.value++
|
}
|
contentTempList.value = contentList.value.slice((page.value - 1) * 8, page.value * 8)
|
}, frequencyFn(contentList.value.length))
|
}
|
}
|
const setInitCall = () => {
|
if (callList.value && callList.value.length > 0) {
|
activeCall.value = callList.value[0]
|
timerCall.value = setInterval(() => {
|
if (pageCall.value >= callList.value.length - 1) {
|
pageCall.value = 0
|
} else {
|
pageCall.value++
|
}
|
activeCall.value = callList.value[pageCall.value]
|
}, frequencyCallFn(callList.value.length))
|
}
|
}
|
|
onMounted(() => {
|
initData()
|
setInterval(() => {
|
initData()
|
}, 60 * 1000)
|
})
|
|
const initQrcode = () => {
|
var qr = new UQRCode()
|
// 设置二维码内容
|
qr.data = qrcode.value
|
qr.size = 268
|
// 调用制作二维码方法
|
qr.make()
|
var canvas = document.getElementById("qrcode")
|
var canvasContext = canvas.getContext("2d")
|
qr.canvasContext = canvasContext
|
qr.drawCanvas()
|
}
|
|
const statusMap = {
|
0: '待确认',
|
1: '待签到',
|
2: '等待叫号',
|
3: '入园等待',
|
4: '已叫号', // 已叫号 月台等待
|
5: '作业中',
|
6: '作业完成',
|
7: '转移中',
|
8: '异常挂起',
|
9: '已授权离园',
|
10: '已离园',
|
11: '已过号',
|
12: '已取消',
|
}
|
const weekMap = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
|
const newWeek = ref(weekMap[new Date().getDay()])
|
const newDate = ref(dayjs().format('YYYY-MM-DD'))
|
const newTime = ref(dayjs().format('HH:mm'))
|
setInterval(() => {
|
newWeek.value = weekMap[new Date().getDay()]
|
newDate.value = dayjs().format('YYYY-MM-DD')
|
newTime.value = dayjs().format('HH:mm')
|
}, 1000)
|
|
const isFullscreen = ref(false)
|
const handleFull = () => {
|
if (!isFullscreen.value) {
|
handleFullScreen()
|
} else {
|
cancelFullscreen()
|
}
|
}
|
const handler = () => {
|
isFullscreen.value = document.fullscreenElement !== null
|
if (!isFullscreen) {
|
// 退出全屏时候解除监听,不然每次监听都会添加一次绑定
|
document.removeEventListener("fullscreenchange", handler)
|
}
|
}
|
document.addEventListener("fullscreenchange", handler)
|
const handleFullScreen = () => {
|
let elem = document.documentElement
|
// 尝试启用全屏模式
|
if (elem.requestFullscreen) {
|
elem.requestFullscreen()
|
} else if (elem.mozRequestFullScreen) { // 兼容 Firefox
|
elem.mozRequestFullScreen()
|
} else if (elem.webkitRequestFullscreen) { // 兼容 Chrome, Safari 和 Opera
|
elem.webkitRequestFullscreen()
|
} else if (elem.msRequestFullscreen) { // 兼容 IE/Edge
|
elem.msRequestFullscreen()
|
}
|
}
|
function cancelFullscreen() {
|
if (document.exitFullscreen) {
|
document.exitFullscreen()
|
} else if (document.msExitFullscreen) {
|
document.msExitFullscreen()
|
} else if (document.mozCancelFullScreen) {
|
document.mozCancelFullScreen()
|
} else if (document.webkitExitFullscreen) {
|
document.webkitExitFullscreen()
|
}
|
}
|
|
</script>
|
<template>
|
<v-scale-screen width="1920" height="1080" :fullScreen="true">
|
<div class="main_app">
|
<div class="main_header">
|
<img class="bg" src="@/assets/images/call/title@2x.png" alt="">
|
<div class="title">安泰智慧物流园区-车辆叫号大屏</div>
|
<div class="time_wrap" @click="handleFull">
|
<div class="left">
|
<div class="week">{{ newWeek }}</div>
|
<div class="date">{{ newDate }}</div>
|
</div>
|
<div class="time">{{ newTime }}</div>
|
</div>
|
</div>
|
<div class="main_content">
|
<div class="list">
|
<div class="line header">
|
<div class="item no">序号</div>
|
<div class="item">车牌号</div>
|
<div class="item status">状态</div>
|
<div class="item">停靠月台</div>
|
<div class="item">时间</div>
|
</div>
|
<div class="line" v-for="item in contentTempList" :key="item.id">
|
<div class="item no">{{ item.signNum }}</div>
|
<div class="item">{{ item.carCodeFront }}</div>
|
<div class="item">
|
<div :class="{
|
call_ed: item.status == 4,
|
underway: item.status == 5,
|
padding: item.status == 2 || item.status == 3,
|
}" class="status">{{ statusMap[item.status] }}</div>
|
</div>
|
<div class="item">{{ item.platformName || '-' }}</div>
|
<div class="item">
|
<div v-if="item.optTimeTemp" class="time_place">预计完成时间</div>
|
<div>{{ item.optTimeTemp || '-' }}</div>
|
</div>
|
</div>
|
</div>
|
<div class="current">
|
<div class="tip_wrap">
|
<img src="@/assets/images/call/ic_left@2x.png" class="icon icon_l" alt="">
|
<img src="@/assets/images/call/ic_right@2x.png" class="icon icon_r" alt="">
|
<div v-if="callList.length > 0" class="current_plat">
|
<div class="id_card">{{ activeCall.carCodeFront }}</div>
|
<div class="no">({{ activeCall.signNum }})</div>
|
<div class="place">
|
<span>前往</span>
|
<span class="plat"> {{ activeCall.platformName }} </span>
|
<span>作业</span>
|
</div>
|
</div>
|
<div v-else class="empty">
|
<div class="title">温馨提示</div>
|
<div class="line">1、请司机根据叫号屏提示入园</div>
|
<div class="line">2、未叫号车辆请耐心等待</div>
|
<div class="line">3、请有序排队入园</div>
|
<div class="line">4、装卸货结束禁止在园区逗留</div>
|
<div class="line">5、请遵守园区安全规章制度</div>
|
</div>
|
</div>
|
<div class="qrcode_wrap">
|
<div class="qrcode">
|
<canvas id="qrcode" width="268" height="268"></canvas>
|
</div>
|
<div class="title">请扫码签到</div>
|
</div>
|
</div>
|
</div>
|
<div class="main_footer">
|
<img src="@/assets/images/call/ic_news@2x.png" class="icon" alt="">
|
<div class="title">请根据队列提示信息,依次等候进场</div>
|
<div class="icon"></div>
|
</div>
|
</div>
|
</v-scale-screen>
|
|
</template>
|
|
<style lang="scss" scoped>
|
div {
|
box-sizing: border-box;
|
}
|
|
.main_app {
|
color: #fff;
|
width: 1920px;
|
height: 1080px;
|
overflow: hidden;
|
background-color: #092030;
|
position: relative;
|
display: flex;
|
flex-direction: column;
|
justify-content: space-between;
|
|
.main_header {
|
width: 100%;
|
flex: 10.3;
|
position: relative;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
padding: 0 50px;
|
z-index: 11;
|
|
.title {
|
font-weight: 800;
|
font-size: 48px;
|
}
|
|
.time_wrap {
|
display: flex;
|
align-items: center;
|
|
.date {
|
font-weight: 500;
|
font-size: 20px;
|
text-align: right;
|
}
|
|
.week {
|
font-weight: 500;
|
font-size: 20px;
|
text-align: right;
|
}
|
|
.time {
|
font-weight: 500;
|
font-size: 50px;
|
margin-left: 15px;
|
}
|
}
|
|
.bg {
|
position: absolute;
|
top: 0;
|
left: 0;
|
width: 100%;
|
height: 100%;
|
object-fit: cover;
|
z-index: -1;
|
}
|
}
|
|
.main_content {
|
flex: 82.2;
|
display: flex;
|
padding: 30px 20px;
|
position: relative;
|
|
.list {
|
flex: 5;
|
margin-right: 20px;
|
display: flex;
|
flex-direction: column;
|
|
.line {
|
display: flex;
|
align-items: center;
|
height: 11.1%;
|
|
&:nth-of-type(2n) {
|
background: rgba(255, 255, 255, 0);
|
}
|
|
&:nth-of-type(2n + 1) {
|
background: rgba(0, 237, 255, 0.13);
|
}
|
|
.item {
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
flex-direction: column;
|
font-weight: 500;
|
font-size: 30px;
|
flex: 10;
|
height: 100%;
|
|
.time_place {
|
font-weight: 500;
|
font-size: 22px;
|
}
|
|
.status {
|
/* padding: 0 28px; */
|
width: 170px;
|
height: 72%;
|
border-radius: 8px;
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
}
|
|
.underway {
|
background-color: #51b2ce;
|
}
|
|
.call_ed {
|
background-color: #f2a43a;
|
}
|
|
.padding {
|
background-color: #1c485a;
|
}
|
}
|
|
.no {
|
flex: 5;
|
}
|
|
}
|
|
.header {
|
.item {
|
font-size: bold;
|
font-size: 36px;
|
}
|
|
background: linear-gradient(180deg, #00B5D1 0%, #003C57 100%) !important;
|
}
|
}
|
|
.current {
|
/* height: calc( 100vh - 192px ); */
|
flex: 2;
|
display: flex;
|
flex-direction: column;
|
|
.tip_wrap {
|
margin-bottom: 20px;
|
width: 100%;
|
position: relative;
|
/* flex-shrink: 0; */
|
flex: 1;
|
|
.current_plat {
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
justify-content: center;
|
padding: 30px 40px;
|
color: #FFA000;
|
height: 100%;
|
|
.id_card {
|
font-weight: 500;
|
font-size: 68px;
|
}
|
|
.no {
|
margin: 8px 0;
|
font-weight: 500;
|
font-size: 52px;
|
}
|
|
.place {
|
font-weight: 500;
|
font-size: 36px;
|
}
|
|
.plat {
|
color: #fff;
|
margin: 0 6px;
|
}
|
}
|
|
.empty {
|
display: flex;
|
flex-direction: column;
|
justify-content: center;
|
font-weight: 500;
|
font-size: 26px;
|
height: 100%;
|
|
.title {
|
text-align: center;
|
font-weight: bold;
|
font-size: 32px;
|
margin-bottom: 16px;
|
}
|
|
.line {
|
margin-bottom: 8px;
|
padding-left: 32px;
|
}
|
}
|
|
.icon {
|
position: absolute;
|
width: 52px;
|
height: 52px;
|
}
|
|
.icon_l {
|
left: 0;
|
top: 0;
|
}
|
|
.icon_r {
|
right: 0;
|
bottom: 0;
|
}
|
}
|
|
.qrcode_wrap {
|
width: 100%;
|
flex: 1;
|
/* flex-shrink: 0; */
|
background-color: #51b2ce;
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
justify-content: center;
|
|
.qrcode {
|
padding: 6px 6px 4px;
|
background-color: #fff;
|
}
|
|
.title {
|
margin-top: 16px;
|
font-weight: bold;
|
font-size: 28px;
|
color: #111111;
|
}
|
}
|
}
|
}
|
|
.main_footer {
|
background-color: #1D8D9E;
|
flex: 7.4;
|
display: flex;
|
align-items: center;
|
padding: 0 50px;
|
|
.icon {
|
width: 52px;
|
height: 52px;
|
}
|
|
.title {
|
flex: 1;
|
text-align: center;
|
font-weight: 500;
|
font-size: 37px;
|
}
|
}
|
|
}
|
</style>
|