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.
 
 
 
 
 

609 lines
18 KiB

<script setup lang="ts">
import { list as listMatrix } from 'apis/matrix'
import { getListByMatrixId, update } from 'apis/matrixCraft'
import { getDeviceStatus, getSprayStatus } from 'apis/system'
import route from 'assets/images/route.png'
import route_active from 'assets/images/route_active.png'
import route_horizontal_active from 'assets/images/route_horizontal2.png'
import route_horizontal from 'assets/images/route_horizontal.png'
import route_vertical_active from 'assets/images/route_vertical2.png'
import route_vertical from 'assets/images/route_vertical.png'
import Edit from 'components/martixCraft/Edit/index.vue'
import TrayGraph from 'components/spray/trayGraph/index.vue'
import { FtMessage } from 'libs/message'
import { socket } from 'libs/socket'
import { sendControl } from 'libs/utils'
import { useSystemStore } from 'stores/useSystemStore'
import { nextTick, onMounted, onUnmounted, ref } from 'vue'
const systemStore = useSystemStore()
const sprayRefs = ref<any>([])
const updateParam = () => {
updateForm.value = {
motorZHeight: form.value.motorZHeight, // 高度
gasPressure: form.value.gasPressure, // Mpa兆帕
volume: form.value.volume, // 单位uL微升
highVoltage: form.value.highVoltage, // 是否打开高压
highVoltageValue: form.value.highVoltageValue, // 高压值
movingSpeed: form.value.movingSpeed, // 毫米
}
infoVisible.value = true
}
const submitParam = async () => {
const params = {
cmdCode: 'matrix_spray_change_param',
cmdId: '',
params: updateForm.value,
}
form.value = {
...form.value,
...updateForm.value,
}
await sendControl(params)
infoVisible.value = false
}
const infoVisible = ref(false)
onMounted(async () => {
socket.init(sprayPointReceiveMessage, 'spray_point')
socket.init(finishMessage, 'cmd_response')
await getMatrixList()
await getDeviceStatus().then((res: any) => {
systemStore.updateSystemStatus(res)
if (systemStore.systemStatus.spraying) {
getSpraying()
}
})
})
const isActive = true
onUnmounted(() => {
socket.unregisterCallback(sprayPointReceiveMessage, 'spray_point')
socket.unregisterCallback(finishMessage, 'cmd_response')
// isActive = false
})
const getSpraying = async () => {
const res: any = await getSprayStatus()
const sprayTaskSprayedList = res.sprayTaskSprayedList
cmdId = res.cmdId
form.value = {
...res.sprayParams,
position: [{ select: false }, { select: false }, { select: false }, { select: false }],
}
res.sprayParams.position.forEach((p: any) => {
form.value.position[p.index] = p
nextTick(() => {
console.log('x', p.x1 * 5)
console.log('y', p.y1 * 5)
console.log('width', (p.x1 + p.x2) * 5)
console.log('height', (p.y1 + p.y2) * 5)
sprayRefs.value[p.index].updateSelection(p.x1 * 5, p.y1 * 5, (p.x2 - p.x1) * 5, (p.y2 - p.y1) * 5)
})
})
sprayTaskSprayedList.forEach((task: any) => {
nextTick(() => {
drawLine(task.index, { x: task.sprayedPoints.x * 5, y: task.sprayedPoints.y * 5 }, task.number)
})
})
}
const matrixList = ref([])
const getMatrixList = async () => {
const res = await listMatrix({ pageNum: 1, pageSize: 100, matrixName: '' })
matrixList.value = res.list
}
const form = ref({
matrixId: undefined,
matrixCraftId: undefined,
matrixPathType: 'horizontal', // 路径类型
motorZHeight: undefined, // 高度
gasPressure: undefined, // Mpa兆帕
volume: undefined, // 单位uL微升
highVoltage: true, // 是否打开高压
highVoltageValue: undefined, // 高压值
spacing: undefined, // 毫米
movingSpeed: undefined, // 移动速度
times: undefined, // 喷涂遍数
position: [{ select: true }, { select: false }, { select: false }, { select: false }],
})
const updateForm = ref({
motorZHeight: undefined, // 高度
gasPressure: undefined, // Mpa兆帕
volume: undefined, // 单位uL微升
highVoltage: true, // 是否打开高压
highVoltageValue: undefined, // 高压值
movingSpeed: undefined, // 移动速度
})
const formRef = ref()
const checkPosition = () => {
let position = form.value.position.filter((item: { select: boolean }) => item.select)
if (!position.length) {
FtMessage.error('至少选择一个玻片')
return false
}
position = form.value.position
.map((item: any, index: number) => {
return {
...item,
...sprayRefs.value[index].getSelection(),
index,
}
})
.filter((item: { select: boolean }) => item.select)
console.log(position)
for (let i = 0; i < position.length; i++) {
const p = position[i]
if (p.x1 < 0 || p.y1 < 0 || p.x2 < 0 || p.y2 < 0 || p.x1 > 25 || p.y1 > 75 || p.x2 > 25 || p.y2 > 75) {
FtMessage.error(`玻片${p.index + 1}喷涂区域超出玻片范围`)
return false
}
}
return position
}
const maskVisible = ref(false)
const startWork = async () => {
formRef.value.validate(async (valid: boolean) => {
console.log('valid', valid)
if (!valid) {
FtMessage.error('请检查参数配置')
return
}
const position = checkPosition()
if (!position) {
return
}
cmdId = Date.now().toString()
const params = {
cmdCode: 'matrix_spray_start',
cmdId,
params: {
...form.value,
position,
},
}
console.log(params)
// socket.init(sprayPointReceiveMessage, 'spray_point')
// socket.init(finishMessage, 'cmd_response')
maskVisible.value = true
await sendControl(params)
currentSpeed = Number(form.value.movingSpeed)
})
}
let currentSpeed = 0
// let poll: ReturnType<typeof setInterval>
console.log(currentSpeed)
const colors = ['#FAF0E6', '#191970', '#2E8B57', '#C0FF3E', '#8B658B', '#EE7942', '#EE1289', '#FF00FF', '#C6E2FF', '#556B2F', '#00BFFF', '#7B68EE']
const sprayPointReceiveMessage = (data: any) => {
if (data.cmdId === cmdId) {
const { currentPoint, index, number } = data
drawLine(index, { x: currentPoint.x * 5, y: currentPoint.y * 5 }, number)
// drawLine(index, { x: nextPoint.x * 5, y: nextPoint.y * 5 }, number)
}
// if (poll) {
// clearInterval(poll)
// }
// const { currentPoint, nextPoint, index } = data
// // 计算累加的mm
// const moveDistance = currentSpeed / 2
// // y轴移动
// if (currentPoint.x === nextPoint.x) {
// let currentY = currentPoint.y
// poll = setInterval(() => {
// currentY += moveDistance
// if (currentY >= nextPoint.y) {
// clearInterval(poll)
// }
// drawLine(index, { x: currentPoint.x * 5, y: currentY * 5 })
// }, 500)
// }
// else if (currentPoint.y === nextPoint.y) {
// // x轴移动
// let currentX = currentPoint.x
// poll = setInterval(() => {
// currentX += moveDistance
// if (currentX >= nextPoint.x) {
// clearInterval(poll)
// }
// drawLine(index, { x: currentX * 5, y: currentPoint.y * 5 })
// }, 500)
// }
}
let cmdId = ''
const finishMessage = (data: any) => {
if (data.cmdId === cmdId && data.status === 'spray_task_finish') {
form.value.position.forEach((item, index) => {
if (item.select) {
sprayRefs.value[index].clearLines()
}
})
maskVisible.value = false
}
}
const drawLine = async (index: number, point: { x: number, y: number }, number: number) => {
console.log('drawLine', sprayRefs.value[index], index, point, number)
await nextTick(() => {
if (!isActive) {
return
}
if (!(sprayRefs.value[index].hasLine(number))) {
sprayRefs.value[index].addLine(colors[number])
}
sprayRefs.value[index].updateLine(point, number, colors[number])
})
}
const pauseWork = async () => {
const params = {
cmdCode: 'matrix_spray_pause',
cmdId: '',
}
await sendControl(params)
}
const continueWork = async () => {
const params = {
cmdCode: 'matrix_spray_continue',
cmdId: '',
params: {
motorZHeight: form.value.motorZHeight, // 高度
gasPressure: form.value.gasPressure, // Mpa兆帕
volume: form.value.volume, // 单位uL微升
highVoltage: form.value.highVoltage, // 是否打开高压
highVoltageValue: form.value.highVoltageValue, // 高压值
movingSpeed: form.value.movingSpeed, // 毫米
},
}
await sendControl(params)
currentSpeed = Number(form.value.movingSpeed)
}
const stopWork = async () => {
const params = {
cmdCode: 'matrix_spray_stop',
cmdId: '',
}
await sendControl(params)
form.value.position.forEach((item, index) => {
if (item.select) {
sprayRefs.value[index].clearLines()
}
})
}
const matrixCraftList = ref<any>([])
const matrixChange = async (value: number) => {
form.value.matrixCraftId = undefined
matrixCraftList.value = await getListByMatrixId(value)
}
const matrixCraftChange = (value: number) => {
form.value = {
...form.value,
...matrixCraftList.value.find((item: { id: number }) => item.id === value),
}
// formRef.value.validate()
}
const rules = {
matrixId: [{ required: true, message: '请选择基质', trigger: 'change' }],
motorZHeight: [
{
required: true,
trigger: 'blur',
validator: (rule: any, value: any, callback: any) => {
setTimeout(() => {
if (value < 15) {
callback(new Error('最小安全高度为15mm'))
}
else {
callback()
}
}, 500)
},
},
],
gasPressure: [{ required: true, message: '请输入氮气气压', trigger: 'blur' }],
volume: [{ required: true, message: '请输入基质流速', trigger: 'blur' }],
highVoltageValue: [
{
required: true,
trigger: 'blur',
validator: (rule: any, value: any, callback: any) => {
if (form.value.highVoltage && !value) {
callback(new Error('请输入电压'))
}
else if (value > 6000) {
callback(new Error('最大电压为6000V'))
}
else {
callback()
}
},
},
],
movingSpeed: [{ required: true, message: '请输入移动速度', trigger: 'blur' }],
spacing: [{ required: true, message: '请输入间距', trigger: 'blur' }],
times: [{ required: true, message: '请输入喷涂次数', trigger: 'blur' }],
}
const addVisible = ref(false)
const ok = async () => {
addVisible.value = false
matrixCraftList.value = await getListByMatrixId(form.value.matrixId)
}
const upDateLoading = ref(false)
const updateCraft = async () => {
if (!form.value.matrixCraftId) {
FtMessage.error('请选择工艺')
return
}
upDateLoading.value = true
const params = {
...form.value,
id: form.value.matrixCraftId,
}
await update(params)
FtMessage.success('保存成功')
upDateLoading.value = false
}
const formData = ref({})
const addCraft = () => {
console.log(form.value)
formData.value = {
...form.value,
id: undefined,
name: undefined,
}
console.log(formData.value)
addVisible.value = true
}
</script>
<template>
<div class="spray-container">
<el-form ref="formRef" label-width="120" :model="form" :rules="rules">
<div class="spray-left">
<div>
<ft-button type="primary" @click="startWork">
开始喷涂
</ft-button>
<ft-button type="primary" @click="updateParam">
调整参数
</ft-button>
<ft-button @click="pauseWork">
暂停喷涂
</ft-button>
<ft-button @click="continueWork">
继续喷涂
</ft-button>
<ft-button @click="stopWork">
结束喷涂
</ft-button>
</div>
<div style="display: flex">
<div class="select-box" />
</div>
<div style="display: flex; position: relative">
<div v-show="maskVisible" class="mask-box" />
<div
v-for="(p, index) in form.position"
:key="index"
style="display: flex; flex-direction: column; align-items: center"
>
<p class="tray-name">
玻片{{ index + 1 }}
</p>
<TrayGraph ref="sprayRefs" :container="`spray-${index + 1}`" :select="p.select" />
<el-checkbox v-model="p.select" style="margin-top: 10px" />
</div>
</div>
</div>
<div class="spray-form">
<el-form-item label="基质" prop="matrixId">
<el-select v-model="form.matrixId" placeholder="" @change="matrixChange">
<el-option v-for="item in matrixList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="工艺">
<el-select v-model="form.matrixCraftId" placeholder="" @change="matrixCraftChange">
<el-option v-for="item in matrixCraftList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="喷涂路线">
<div class="route-img">
<img
style="margin-left: 20px"
:src="form.matrixPathType === 'horizontal' ? route_horizontal_active : route_horizontal"
alt=""
@click="form.matrixPathType = 'horizontal'"
>
<img
style="margin: 0 20px"
:src="form.matrixPathType === 'vertical' ? route_vertical_active : route_vertical"
alt=""
@click="form.matrixPathType = 'vertical'"
>
<img
:src="form.matrixPathType === 'grid' ? route_active : route"
alt=""
@click="form.matrixPathType = 'grid'"
>
</div>
</el-form-item>
<el-form-item label="Z轴高度" prop="motorZHeight">
<el-input v-model="form.motorZHeight" type="number" />
<span class="unit-text">mm</span>
</el-form-item>
<el-form-item label="氮气气压" prop="gasPressure">
<el-input v-model="form.gasPressure" type="number" />
<span class="unit-text">Mpa</span>
</el-form-item>
<el-form-item label="基质流速" prop="volume">
<el-input v-model="form.volume" type="number" />
<span class="unit-text">uL/min</span>
</el-form-item>
<el-form-item label="是否加电" prop="highVoltageValue">
<div class="voltage-box">
<el-switch v-model="form.highVoltage" />
<el-input
v-show="form.highVoltage"
v-model="form.highVoltageValue"
max="5000"
type="number"
class="voltage-input"
/>
<span v-show="form.highVoltage" class="unit-text"> V</span>
</div>
</el-form-item>
<el-form-item label="移动速度" prop="movingSpeed">
<el-input v-model="form.movingSpeed" type="number" />
<span class="unit-text">mm/s</span>
</el-form-item>
<el-form-item label="间距" prop="spacing">
<el-input v-model="form.spacing" type="number" />
<span class="unit-text">mm</span>
</el-form-item>
<el-form-item label="喷涂次数" prop="times">
<el-input v-model="form.times" type="number" />
<span class="unit-text">次</span>
</el-form-item>
<div style="display: flex; justify-content: center">
<ft-button type="primary" :loading="upDateLoading" @click="updateCraft">
更新工艺
</ft-button>
<ft-button type="primary" @click="addCraft">
保存到新工艺
</ft-button>
</div>
</div>
</el-form>
<el-drawer v-model="infoVisible" title="调整参数" direction="rtl" :close-on-click-modal="false">
<el-form label-width="auto" style="display: flex; flex-direction: column; justify-content: center">
<div>
<el-form-item label="Z轴高度" prop="motorZHeight">
<el-input v-model="updateForm.motorZHeight" type="number" />
<span class="unit-text">mm</span>
</el-form-item>
<el-form-item label="氮气气压" prop="gasPressure">
<el-input v-model="updateForm.gasPressure" type="number" />
<span class="unit-text">Mpa</span>
</el-form-item>
<el-form-item label="基质流速" prop="volume">
<el-input v-model="updateForm.volume" type="number" />
<span class="unit-text">uL/min</span>
</el-form-item>
<el-form-item label="是否加电" prop="highVoltageValue">
<div class="voltage-box">
<el-switch v-model="updateForm.highVoltage" />
<el-input
v-show="updateForm.highVoltage"
v-model="updateForm.highVoltageValue"
type="number"
class="voltage-input"
/>
<span v-show="updateForm.highVoltage" class="unit-text"> V</span>
</div>
</el-form-item>
<el-form-item label="移动速度" prop="movingSpeed">
<el-input v-model="updateForm.movingSpeed" type="number" />
<span class="unit-text">mm/s</span>
</el-form-item>
<el-form-item>
<div style="display: flex; justify-content: center; width: 100%">
<ft-button type="primary" @click="submitParam">
确定
</ft-button>
</div>
</el-form-item>
</div>
</el-form>
</el-drawer>
<!-- <start-spray v-model="wsList" :visible @close="visible = false" /> -->
<Edit v-if="addVisible" :matrix-list :form-data other-page @ok="ok" @cancel="addVisible = false" />
</div>
</template>
<style scoped lang="scss">
.spray-container {
width: 100%;
height: 100%;
.el-form {
width: 100%;
height: 100%;
display: flex;
justify-content: space-between;
overflow: auto;
.spray-left {
display: flex;
flex-direction: column;
}
.spray-form {
display: flex;
flex-direction: column;
justify-content: center;
}
}
}
.el-input,
.el-select {
width: 400px;
margin: 0 40px;
}
.unit-text {
font-size: 40px;
color: #0349a8;
font-weight: 500;
}
.select-box {
display: flex;
margin: 40px;
}
.route-img {
display: flex;
img {
width: 70px;
}
}
.voltage-box {
display: flex;
align-items: center;
margin-left: 40px;
.voltage-input {
width: 280px;
}
}
:deep(.el-form-item__error) {
font-size: 22px;
margin-left: 50px;
}
.mask-box {
position: absolute;
width: 100%;
height: 100%;
background: rgba(255, 255, 255, 0.1);
z-index: 5000;
}
.tray-name {
color: var(--el-color-primary);
}
</style>