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.
368 lines
13 KiB
368 lines
13 KiB
<script setup lang="ts">
|
|
import { stopTask, trayIn } from 'apis/home'
|
|
import AddLiquid from 'components/home/AddLiquid/index.vue'
|
|
import CheckCraft from 'components/home/CheckCraft/index.vue'
|
|
import ExecuteCraft from 'components/home/ExecuteCraft/index.vue'
|
|
import ExtractLiquid from 'components/home/ExtractLiquid/index.vue'
|
|
import FillSolution from 'components/home/FillSolution/index.vue'
|
|
import SetTemperature from 'components/home/SetTemperature/index.vue'
|
|
|
|
import StartClean from 'components/home/StartClean/index.vue'
|
|
import StartExperiment from 'components/home/StartExperiment/index.vue'
|
|
import Tube from 'components/home/Tube/index.vue'
|
|
import { ElMessageBox } from 'element-plus'
|
|
import { FtMessage } from 'libs/message'
|
|
import { socket } from 'libs/socket'
|
|
import { cmdNameMap, formatDateTime } from 'libs/utils'
|
|
import { useHomeStore } from 'stores/homeStore'
|
|
import { useSystemStore } from 'stores/systemStore'
|
|
import { computed, onMounted, onUnmounted, provide, ref } from 'vue'
|
|
|
|
const homeStore = useHomeStore()
|
|
const systemStore = useSystemStore()
|
|
|
|
onMounted(() => {
|
|
socket.init(receiveMessage, 'cmd_debug')
|
|
socket.init(receiveMessage, 'cmd_response')
|
|
})
|
|
|
|
onUnmounted(() => {
|
|
socket.unregisterCallback(receiveMessage, 'cmd_debug')
|
|
socket.unregisterCallback(receiveMessage, 'cmd_response')
|
|
})
|
|
|
|
let currentCommandId = ''
|
|
const receiveMessage = (data: Socket.cmdData) => {
|
|
data.commandId === currentCommandId && systemStore.pushSystemList(data)
|
|
if (['start', 'success', 'fail'].includes(data.status)) {
|
|
const cmdName = cmdNameMap[data.command as keyof typeof cmdNameMap] || data.command
|
|
systemStore.insertLog({ cmdName, status: data.status as System.SystemLog['status'], time: formatDateTime() })
|
|
}
|
|
}
|
|
|
|
const selectedHeatArea = computed(() => {
|
|
return homeStore.heatAreaList.find(item => item.selected)
|
|
})
|
|
|
|
const startVisible = ref(false)
|
|
|
|
const startExperimentHandle = () => {
|
|
if (systemStore.systemStatus.currentTasks) {
|
|
FtMessage.error('记录已经开启')
|
|
return
|
|
}
|
|
startVisible.value = true
|
|
}
|
|
|
|
const stopExperimentHandle = async () => {
|
|
if (!systemStore.systemStatus.currentTasks) {
|
|
FtMessage.error('当前没有记录在开始')
|
|
return
|
|
}
|
|
await stopTask()
|
|
FtMessage.success('记录已停止')
|
|
}
|
|
|
|
const selectCraftVisible = ref(false)
|
|
|
|
const executeCraftHandle = async () => {
|
|
selectCraftVisible.value = true
|
|
}
|
|
|
|
const setTemperatureVisible = ref(false)
|
|
const currentTemperatureData = ref<{ id: string, label: string | undefined }>({
|
|
id: '',
|
|
label: 'A-1',
|
|
})
|
|
provide('currentTemperatureData', currentTemperatureData)
|
|
const setTemperature = (data: System.HeatArea) => {
|
|
const craft = systemStore.systemStatus.trays?.find(item => item.heatModuleCode === data.moduleCode)?.crafts
|
|
if (craft?.craft) {
|
|
FtMessage.warning(`当前加热区已绑定预设`)
|
|
return
|
|
}
|
|
currentTemperatureData.value = {
|
|
id: data.moduleCode,
|
|
label: homeStore.heatAreaList.find(item => item.value === data.moduleCode)?.label,
|
|
}
|
|
setTemperatureVisible.value = true
|
|
}
|
|
|
|
const fillSolutionVisible = ref(false)
|
|
|
|
const addLiquidVisible = ref(false)
|
|
|
|
const cleanVisible = ref(false)
|
|
|
|
const extractLiquidVisible = ref(false)
|
|
|
|
const commandHandle = async (command: string, params?: unknown) => {
|
|
currentCommandId = Date.now().toString()
|
|
const data = {
|
|
commandId: currentCommandId,
|
|
command,
|
|
params,
|
|
}
|
|
await homeStore.sendControl(data)
|
|
}
|
|
|
|
const move_to_liquid_area = async () => {
|
|
if (!selectedHeatArea.value?.value) {
|
|
await ElMessageBox.confirm(
|
|
'是否要将上料区托盘移至加液位? ',
|
|
'提示',
|
|
{
|
|
confirmButtonText: '确认',
|
|
showClose: false,
|
|
closeOnClickModal: false,
|
|
closeOnPressEscape: false,
|
|
type: 'warning',
|
|
customClass: 'init-message',
|
|
},
|
|
)
|
|
}
|
|
await commandHandle('move_to_liquid_area', { heatModuleCode: selectedHeatArea.value?.value })
|
|
}
|
|
|
|
const move_to_feed_area = async () => {
|
|
if (!selectedHeatArea.value?.value) {
|
|
await ElMessageBox.confirm(
|
|
'是否要将加液位托盘移至上料区? ',
|
|
'提示',
|
|
{
|
|
confirmButtonText: '确认',
|
|
showClose: false,
|
|
closeOnClickModal: false,
|
|
closeOnPressEscape: false,
|
|
type: 'warning',
|
|
customClass: 'init-message',
|
|
},
|
|
)
|
|
}
|
|
await commandHandle('move_to_feed_area', { heatModuleCode: selectedHeatArea.value?.value })
|
|
}
|
|
|
|
const move_to_anneal_area = async () => {
|
|
if (!selectedHeatArea.value?.value) {
|
|
await ElMessageBox.confirm(
|
|
'是否要将加液位或上料区的托盘移至退火区? ',
|
|
'提示',
|
|
{
|
|
confirmButtonText: '确认',
|
|
showClose: false,
|
|
closeOnClickModal: false,
|
|
closeOnPressEscape: false,
|
|
type: 'warning',
|
|
customClass: 'init-message',
|
|
},
|
|
)
|
|
}
|
|
await commandHandle('move_to_anneal_area', { heatModuleCode: selectedHeatArea.value?.value })
|
|
}
|
|
|
|
const trayInHandle = async () => {
|
|
await trayIn()
|
|
FtMessage.success('设置放入托盘成功')
|
|
}
|
|
|
|
// const trayOutHandle = async () => {
|
|
// await trayOut()
|
|
// }
|
|
|
|
const checkCraftVisible = ref(false)
|
|
</script>
|
|
|
|
<template>
|
|
<div class="home-page">
|
|
<div class="page-top">
|
|
<Tube v-for="(item, index) in systemStore.systemStatus.heatModule" :key="item.moduleCode" :data="item" @select-change="homeStore.selectChange(index)" @set-temperature="setTemperature(item)" />
|
|
</div>
|
|
<div class="button-box">
|
|
<el-row style="width: 100%; height: 100%" :gutter="20">
|
|
<el-col :span="20">
|
|
<div style="display: grid; gap: 10px; grid-template-columns: repeat(2, 1fr);grid-template-rows: repeat(4, 1fr);height: 100%">
|
|
<ft-button size="large" :click-handle="() => commandHandle('door_open')">
|
|
开门
|
|
</ft-button>
|
|
<ft-button size="large" :click-handle="() => commandHandle('door_close')">
|
|
关门
|
|
</ft-button>
|
|
<ft-button size="large" :click-handle="trayInHandle">
|
|
放入托盘
|
|
</ft-button>
|
|
<ft-button size="large" :click-handle="() => commandHandle('out_tray', { heatModuleCode: selectedHeatArea!.value })" :disabled="!selectedHeatArea">
|
|
取出托盘
|
|
</ft-button>
|
|
<ft-button size="large" @click="startExperimentHandle">
|
|
开始记录
|
|
</ft-button>
|
|
<ft-button size="large" :click-handle="stopExperimentHandle">
|
|
结束记录
|
|
</ft-button>
|
|
<ft-button size="large" :click-handle="executeCraftHandle">
|
|
执行预设
|
|
</ft-button>
|
|
<ft-button size="large" :click-handle="() => checkCraftVisible = true">
|
|
异常预设
|
|
</ft-button>
|
|
</div>
|
|
</el-col>
|
|
<el-col :span="4" style="display: grid; gap: 10px; grid-template-columns: repeat(1, 1fr);grid-template-rows: repeat(1, 1fr)">
|
|
<div class="manual-box">
|
|
<el-popover
|
|
placement="top-start"
|
|
width="auto"
|
|
trigger="click"
|
|
>
|
|
<template #reference>
|
|
<div class="manual-button">
|
|
手动操作
|
|
</div>
|
|
</template>
|
|
<template #default>
|
|
<div class="container-box">
|
|
<ft-button size="large" :disabled="!selectedHeatArea || selectedHeatArea?.label === '退火区'" :click-handle="() => commandHandle('heater_start', { heatModuleCode: selectedHeatArea!.value })">
|
|
开始加热
|
|
</ft-button>
|
|
|
|
<ft-button size="large" :disabled="!selectedHeatArea || selectedHeatArea?.label === '退火区'" :click-handle="() => commandHandle('heater_stop', { heatModuleCode: selectedHeatArea!.value })">
|
|
停止加热
|
|
</ft-button>
|
|
|
|
<ft-button size="large" :disabled="!selectedHeatArea || selectedHeatArea?.label === '退火区'" :click-handle="() => commandHandle('fan_start', { heatModuleCode: selectedHeatArea!.value })">
|
|
开始降温
|
|
</ft-button>
|
|
|
|
<ft-button size="large" :disabled="!selectedHeatArea || selectedHeatArea?.label === '退火区'" :click-handle="() => commandHandle('fan_stop', { heatModuleCode: selectedHeatArea!.value })">
|
|
停止降温
|
|
</ft-button>
|
|
|
|
<ft-button size="large" :disabled="!selectedHeatArea || selectedHeatArea?.label === '退火区'" :click-handle="() => commandHandle('dry_start', { heatModuleCode: selectedHeatArea!.value })">
|
|
开始烘干
|
|
</ft-button>
|
|
|
|
<ft-button size="large" :disabled="!selectedHeatArea || selectedHeatArea?.label === '退火区'" :click-handle="() => commandHandle('dry_stop', { heatModuleCode: selectedHeatArea!.value })">
|
|
停止烘干
|
|
</ft-button>
|
|
|
|
<ft-button size="large" :disabled="!selectedHeatArea || selectedHeatArea?.label !== '退火区'" :click-handle="() => commandHandle('anneal_start', { heatModuleCode: selectedHeatArea!.value })">
|
|
开始退火
|
|
</ft-button>
|
|
|
|
<ft-button size="large" :disabled="!selectedHeatArea || selectedHeatArea?.label !== '退火区'" :click-handle="() => commandHandle('anneal_stop', { heatModuleCode: selectedHeatArea!.value })">
|
|
停止退火
|
|
</ft-button>
|
|
<ft-button size="large" :click-handle="() => commandHandle('move_to_heat_area', { heatModuleCode: selectedHeatArea!.value })" :disabled="!selectedHeatArea">
|
|
移至加热位
|
|
</ft-button>
|
|
|
|
<ft-button size="large" :click-handle="move_to_liquid_area">
|
|
移至加液位
|
|
</ft-button>
|
|
<ft-button size="large" :click-handle="move_to_feed_area">
|
|
移至上料区
|
|
</ft-button>
|
|
<ft-button size="large" :click-handle="move_to_anneal_area">
|
|
移至退火位
|
|
</ft-button>
|
|
<ft-button size="large" @click="cleanVisible = true">
|
|
开始清洗
|
|
</ft-button>
|
|
|
|
<ft-button size="large" @click=" fillSolutionVisible = true">
|
|
预充管路
|
|
</ft-button>
|
|
|
|
<ft-button size="large" @click="addLiquidVisible = true">
|
|
添加溶液
|
|
</ft-button>
|
|
|
|
<ft-button size="large" @click="extractLiquidVisible = true">
|
|
抽取溶液
|
|
</ft-button>
|
|
<ft-button size="large" :click-handle="() => commandHandle('liquid_motor_origin')">
|
|
加液臂回原点
|
|
</ft-button>
|
|
<ft-button size="large" :click-handle="() => commandHandle('z_origin')">
|
|
z轴回原点
|
|
</ft-button>
|
|
<ft-button size="large" :click-handle="() => commandHandle('x_origin')">
|
|
x轴回原点
|
|
</ft-button>
|
|
</div>
|
|
</template>
|
|
</el-popover>
|
|
</div>
|
|
</el-col>
|
|
</el-row>
|
|
</div>
|
|
<CheckCraft v-if="checkCraftVisible" @close="checkCraftVisible = false" />
|
|
<StartExperiment v-if="startVisible" @ok="startVisible = false" @cancel="startVisible = false" />
|
|
<StartClean v-if="cleanVisible" @ok="cleanVisible = false" @cancel="cleanVisible = false" />
|
|
<ExecuteCraft v-if="selectCraftVisible" @ok="selectCraftVisible = false" @cancel="selectCraftVisible = false" />
|
|
<SetTemperature v-if="setTemperatureVisible" @ok="setTemperatureVisible = false" @cancel="setTemperatureVisible = false" />
|
|
<AddLiquid v-if="addLiquidVisible" @ok="addLiquidVisible = false" @cancel="addLiquidVisible = false" />
|
|
<ExtractLiquid v-if="extractLiquidVisible" @ok="extractLiquidVisible = false" @cancel="extractLiquidVisible = false" />
|
|
<FillSolution v-if="fillSolutionVisible" @ok="fillSolutionVisible = false" @cancel="fillSolutionVisible = false" />
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped lang="scss">
|
|
.home-page {
|
|
.page-top{
|
|
height: 65%;
|
|
border-radius: 8px;
|
|
padding: 0 10px 10px;
|
|
display: grid;
|
|
grid-template-columns: repeat(4, 1fr); /* 创建3列等宽轨道 */
|
|
grid-template-rows: repeat(1, auto); /* 创建2行自动高度 */
|
|
gap: 10px;
|
|
justify-content: center; /* 水平居中 */
|
|
align-items: center;
|
|
}
|
|
.button-box {
|
|
height: 35%;
|
|
//display: grid;
|
|
//grid-template-columns: repeat(6, 1fr); /* 创建3列等宽轨道 */
|
|
//grid-template-rows: repeat(4, 1fr); /* 创建2行自动高度 */
|
|
//gap: 10px 20px;
|
|
.ft-button {
|
|
//width: 100px;
|
|
font-weight: bold;
|
|
margin-right: 0;
|
|
|
|
.my-button {
|
|
padding: 0 !important;
|
|
border: 3px solid #1989fa !important;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
.el-col {
|
|
height: 100%;
|
|
}
|
|
.manual-box {
|
|
width: 100%;
|
|
height: 100%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
.container-box {
|
|
width: 600px;
|
|
display: grid;
|
|
grid-template-columns: repeat(4, 1fr);
|
|
grid-template-rows: repeat(2, 1fr);
|
|
gap: 10px;
|
|
}
|
|
.manual-button {
|
|
border:1px solid #1989FA;
|
|
color: #1989FA;
|
|
width: 100%;
|
|
height: 100px;
|
|
line-height: 100px;
|
|
text-align: center;
|
|
border-radius: 10px;
|
|
}
|
|
</style>
|