You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
347 lines
9.8 KiB
347 lines
9.8 KiB
<script setup lang="ts">
|
|
import { getDeviceStatus } from 'apis/system'
|
|
import FtStream from 'components/common/FTStream/index.vue'
|
|
import Check from 'components/home/Check/index.vue'
|
|
import Stop from 'components/home/Stop/index.vue'
|
|
import { ElMessageBox } from 'element-plus'
|
|
import { FtMessage } from 'libs/message'
|
|
import { isClose, socket } from 'libs/socket'
|
|
import { sendControl } from 'libs/utils'
|
|
import { useSystemStore } from 'stores/useSystemStore' // 引入 systemStore
|
|
import { computed, ref, watch } from 'vue'
|
|
import { useRoute, useRouter } from 'vue-router'
|
|
|
|
const route = useRoute()
|
|
const router = useRouter()
|
|
const systemStore = useSystemStore() // 使用 systemStore
|
|
|
|
const checkVisible = ref(false)
|
|
console.log(import.meta.env.FT_NODE_ENV)
|
|
|
|
const cancel = () => {
|
|
checkVisible.value = false
|
|
}
|
|
|
|
const getStatus = async () => {
|
|
await getDeviceStatus().then((res: any) => {
|
|
systemStore.updateSystemStatus(res)
|
|
if (!systemStore.systemStatus.selfTestCompleted && import.meta.env.FT_NODE_ENV !== 'test') {
|
|
ElMessageBox.confirm('检测到您还未完成自检,是否开始自检?', '提示', {
|
|
type: 'warning',
|
|
confirmButtonText: '确定',
|
|
showCancelButton: false,
|
|
showClose: false,
|
|
closeOnClickModal: false,
|
|
closeOnPressEscape: false,
|
|
closeOnHashChange: false,
|
|
}).then(() => {
|
|
checkVisible.value = true
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
// getStatus()
|
|
|
|
const ok = () => {
|
|
checkVisible.value = false
|
|
}
|
|
const statusMessage = (data: any) => {
|
|
// 更新 systemStore 的 systemStatus
|
|
console.log(data)
|
|
const stopPressed = systemStore.systemStatus.stopPressed
|
|
if (stopPressed !== data.stopPressed && data.stopPressed === false) {
|
|
getStatus()
|
|
}
|
|
console.log(data)
|
|
systemStore.updateSystemStatus(data)
|
|
}
|
|
|
|
const sensorMessage = async (data: any) => {
|
|
// 更新 systemStore 的 systemInfo
|
|
systemStore.updateSystemSensor(data)
|
|
if (systemStore.systemStatus.dehumidifierRunning && systemStore.systemSensor.humidity <= systemStore.targetHumidity) {
|
|
const params = {
|
|
cmdCode: 'dehumidifier_stop',
|
|
cmdId: '',
|
|
}
|
|
await sendControl(params)
|
|
FtMessage.success('当前湿度已达目标湿度,除湿已完成')
|
|
}
|
|
if (systemStore.systemStatus.slidePlatHeating && systemStore.systemSensor.slideTemperature >= systemStore.targetSlideTemperature) {
|
|
const params = {
|
|
cmdCode: 'slide_plat_heat_stop',
|
|
cmdId: '',
|
|
}
|
|
await sendControl(params)
|
|
FtMessage.success('当前温度已达目标温度,加热已完成')
|
|
}
|
|
if (systemStore.systemStatus.nozzleHeating && systemStore.systemSensor.nozzleTemperature <= systemStore.targetNozzleTemperature) {
|
|
const params = {
|
|
cmdCode: 'nozzle_heat_stop',
|
|
cmdId: '',
|
|
}
|
|
await sendControl(params)
|
|
FtMessage.success('当前温度已达目标温度,加热已完成')
|
|
}
|
|
}
|
|
|
|
socket.init(statusMessage, 'device_status_change')
|
|
socket.init(sensorMessage, 'sensor')
|
|
socket.init(() => {}, 'pong')
|
|
|
|
const ingObj = {
|
|
idle: '空闲',
|
|
spraying: '正在喷涂中',
|
|
paused: '喷涂暂停中',
|
|
cleaningSyringePipeline: '正在清洗注射器管路',
|
|
cleaningNozzlePipeline: '正在清洗喷嘴管路',
|
|
prefilling: '正在预充中',
|
|
dehumidifierRunning: '正在除湿中',
|
|
stopPressed: '急停中',
|
|
virtual: '虚拟模式',
|
|
nozzleHeating: '喷嘴加热中',
|
|
slidePlatHeating: '玻片加热中',
|
|
}
|
|
|
|
const status = computed(() => {
|
|
const keys = Object.keys(systemStore.systemStatus).filter((key) => {
|
|
return !['suspendable', 'selfTestCompleted'].includes(key)
|
|
})
|
|
let str = ''
|
|
console.log(keys)
|
|
keys.forEach((key) => {
|
|
if (systemStore.systemStatus[key as keyof typeof systemStore.systemStatus]) {
|
|
str += `${ingObj[key as keyof typeof ingObj]} | `
|
|
}
|
|
})
|
|
console.log(str)
|
|
if (str === '') {
|
|
return '空闲'
|
|
}
|
|
else {
|
|
return str.slice(0, -2)
|
|
}
|
|
})
|
|
|
|
const logoClickCount = ref(0)
|
|
let clickTimeout: NodeJS.Timeout | null = null
|
|
|
|
const handleLogoClick = () => {
|
|
if (clickTimeout) {
|
|
clearTimeout(clickTimeout)
|
|
}
|
|
logoClickCount.value++
|
|
if (logoClickCount.value === 10) {
|
|
systemStore.updateDebug()
|
|
logoClickCount.value = 0 // 重置计数器
|
|
}
|
|
clickTimeout = setTimeout(() => {
|
|
logoClickCount.value = 0 // 重置计数器
|
|
}, 1000)
|
|
}
|
|
|
|
// const slideTrayIn = async () => {
|
|
// const params = {
|
|
// cmdCode: 'slide_tray_in',
|
|
// cmdId: '',
|
|
// }
|
|
// await sendControl(params)
|
|
// }
|
|
//
|
|
// const slideTrayOut = async () => {
|
|
// const params = {
|
|
// cmdCode: 'slide_tray_out',
|
|
// cmdId: '',
|
|
// }
|
|
// await sendControl(params)
|
|
// }
|
|
|
|
watch(() => isClose.value, async (newValue) => {
|
|
if (!newValue) {
|
|
await getStatus()
|
|
if (systemStore.systemStatus.spraying && router.currentRoute.value.path !== '/spray') {
|
|
ElMessageBox.confirm('检测到您有正在喷涂的任务,是否进入喷涂?', '提示', {
|
|
type: 'warning',
|
|
confirmButtonText: '确定',
|
|
cancelButtonText: '取消',
|
|
showCancelButton: true,
|
|
showClose: false,
|
|
closeOnClickModal: false,
|
|
closeOnPressEscape: false,
|
|
closeOnHashChange: false,
|
|
}).then(() => {
|
|
router.push('/spray')
|
|
})
|
|
}
|
|
}
|
|
})
|
|
const slideSwitch = async () => {
|
|
if (systemStore.systemStatus.slidePlatHeating) {
|
|
ElMessageBox.confirm('确认关闭喷头加热?', '提示', {
|
|
type: 'warning',
|
|
confirmButtonText: '确定',
|
|
cancelButtonText: '取消',
|
|
showCancelButton: true,
|
|
showClose: false,
|
|
closeOnClickModal: false,
|
|
closeOnPressEscape: false,
|
|
closeOnHashChange: false,
|
|
}).then(async () => {
|
|
const params = {
|
|
cmdCode: 'slide_plat_heat_stop',
|
|
cmdId: '',
|
|
}
|
|
await sendControl(params)
|
|
FtMessage.success('已关闭载台加热')
|
|
})
|
|
}
|
|
else {
|
|
FtMessage.success('载台加热已关闭')
|
|
}
|
|
}
|
|
const nozzleSwitch = async () => {
|
|
if (systemStore.systemStatus.nozzleHeating) {
|
|
ElMessageBox.confirm('确认关闭喷头加热?', '提示', {
|
|
type: 'warning',
|
|
confirmButtonText: '确定',
|
|
cancelButtonText: '取消',
|
|
showCancelButton: true,
|
|
showClose: false,
|
|
closeOnClickModal: false,
|
|
closeOnPressEscape: false,
|
|
closeOnHashChange: false,
|
|
}).then(async () => {
|
|
const params = {
|
|
cmdCode: 'nozzle_heat_stop',
|
|
cmdId: '',
|
|
}
|
|
await sendControl(params)
|
|
FtMessage.success('已关闭喷头加热')
|
|
})
|
|
}
|
|
else {
|
|
FtMessage.success('喷头加热已经关闭')
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<el-container>
|
|
<el-header>
|
|
<div class="logo" @click="handleLogoClick">
|
|
<div style="display: flex;align-items: center">
|
|
<img src="@/assets/images/logo.svg" alt="">
|
|
</div>
|
|
|
|
<div v-if="route.path !== '/'">
|
|
<el-divider direction="vertical" />
|
|
<span class="router-name">{{ route.meta.tagName }}</span>
|
|
</div>
|
|
</div>
|
|
<div style="display: flex">
|
|
<img v-show="!isClose" class="wifi-icon" src="../../assets/images/icon_wifi.svg" alt="">
|
|
<img v-show="isClose" class="wifi-icon" src="../../assets/images/icon_wifi_red.svg" alt="">
|
|
<ft-button v-if="systemStore.isDebug" @click="router.push('/debug')">
|
|
调试
|
|
</ft-button>
|
|
<ft-button v-if="route.path !== '/'" @click="router.push('/')">
|
|
返回
|
|
</ft-button>
|
|
</div>
|
|
</el-header>
|
|
<el-main>
|
|
<router-view v-slot="{ Component }" class="main-container">
|
|
<Transition mode="out-in">
|
|
<component :is="Component" :key="route.fullPath" />
|
|
</Transition>
|
|
</router-view>
|
|
</el-main>
|
|
<el-footer>
|
|
<div>
|
|
<ft-button type="info">
|
|
当前湿度: {{ systemStore.systemSensor.humidity }}%RH
|
|
</ft-button>
|
|
</div>
|
|
<div>
|
|
<ft-button type="info" :click-handle="nozzleSwitch">
|
|
<img v-if="systemStore.systemStatus.nozzleHeating" src="../../assets/images/entry/heat_icon.svg" alt="" width="20px">
|
|
喷头温度: {{ systemStore.systemSensor.nozzleTemperature }}℃
|
|
</ft-button>
|
|
</div>
|
|
<div>
|
|
<ft-button type="info" :click-handle="slideSwitch">
|
|
<img v-if="systemStore.systemStatus.slidePlatHeating" src="../../assets/images/entry/heat_icon.svg" alt="" width="20px">
|
|
载玻台温度: {{ systemStore.systemSensor.slideTemperature }}℃
|
|
</ft-button>
|
|
</div>
|
|
<div>
|
|
<ft-button type="info">
|
|
设备状态: {{ status }}
|
|
</ft-button>
|
|
</div>
|
|
<!-- <div> -->
|
|
<!-- <ft-button :click-handle="slideTrayIn" :disabled="systemStore.systemStatus.spraying"> -->
|
|
<!-- 推入托盘 -->
|
|
<!-- </ft-button> -->
|
|
<!-- <ft-button :click-handle="slideTrayOut" :disabled="systemStore.systemStatus.spraying"> -->
|
|
<!-- 推出托盘 -->
|
|
<!-- </ft-button> -->
|
|
<!-- </div> -->
|
|
</el-footer>
|
|
<FtStream :visible="systemStore.streamVisible" />
|
|
<Stop v-if="systemStore.systemStatus.stopPressed" />
|
|
<Check v-if="checkVisible" @ok="ok" @cancel="cancel" />
|
|
</el-container>
|
|
</template>
|
|
|
|
<style scoped lang="scss">
|
|
.el-container {
|
|
background: #26509C;
|
|
overflow: hidden;
|
|
.el-header {
|
|
height: 120px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding:0 65px;
|
|
.logo {
|
|
margin-left: 35px;
|
|
display: flex;
|
|
img {
|
|
width: 250px;
|
|
}
|
|
}
|
|
.el-divider {
|
|
margin: 0 60px;
|
|
height: 62px;
|
|
}
|
|
}
|
|
.el-main {
|
|
padding:0 65px;
|
|
.main-container {
|
|
width: 100%;
|
|
height: 100%;
|
|
background: #EEF3FB;
|
|
border-radius: 60px;
|
|
padding: 60px;
|
|
overflow: auto;
|
|
}
|
|
}
|
|
.el-footer {
|
|
padding:0 65px;
|
|
height: 120px;
|
|
display: flex;
|
|
justify-content: space-evenly;
|
|
align-items: center;
|
|
}
|
|
}
|
|
.router-name {
|
|
font-size: 50px;
|
|
color: #fff;
|
|
}
|
|
.wifi-icon {
|
|
width: 50px;
|
|
margin: 0 30px;
|
|
}
|
|
</style>
|