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.
972 lines
24 KiB
972 lines
24 KiB
<template>
|
|
<div class="graphite_home component-page overflow-auto" id="heatArea">
|
|
<div class="heat_area">
|
|
<div v-for="(item, index) in heatList" :key="item.id">
|
|
<HeatPosition
|
|
:heatInfo="{ ...item, index }"
|
|
:tubeIndex="index + 1"
|
|
@onSelectedTray="onSelectedTray"
|
|
@onSetHeatAreaTemp="onSetHeatAreaTemp"
|
|
@onSelectCraft="
|
|
craftData => {
|
|
onSelectCraft(item, craftData);
|
|
}
|
|
"></HeatPosition>
|
|
</div>
|
|
<!--执行中状态的遮罩层-->
|
|
</div>
|
|
<!--拍照区-->
|
|
<div class="picture_area">
|
|
<!--加液区和拍照区可切换-->
|
|
<TakePickture></TakePickture>
|
|
<!-- <div v-else style="display: flex;justify-content: center;">
|
|
<div class="home_tube">
|
|
<div
|
|
class="inner-circle"
|
|
v-for="(tubeItem, index) in tubeList"
|
|
:key="index"
|
|
:style="{ background: tubeItem.color }"
|
|
|
|
></div>
|
|
</div>
|
|
</div> -->
|
|
<!--操作区-->
|
|
<div class="graphite_btn_container">
|
|
<van-button v-if="doorStatus" size="large" class="btn_size op_open_door" @click="onCloseDoor">关门</van-button>
|
|
<van-button v-else size="large" class="btn_size op_open_door" @click="onOPenDoor">开门</van-button>
|
|
|
|
<van-button size="large" class="btn_size op_start_task" @click="startTask">开始实验</van-button>
|
|
<van-button size="large" class="btn_size op_stop_task" @click="onEndTask">结束实验</van-button>
|
|
<van-button size="large" class="btn_size op_select_craft" @click="onChooseCaft">{{ craftName }}</van-button>
|
|
<van-button size="large" class="btn_size op_exec_craft" @click="onCraftStart()">{{ exeCraftName }}</van-button>
|
|
<van-button size="large" class="btn_size op_add_liquid" @click="onAddLiquid">添加溶液</van-button>
|
|
<van-button v-if="!isSharking" size="large" class="btn_size op_shake_up" @click="onStartShakingTube"
|
|
>摇匀</van-button
|
|
>
|
|
<van-button v-else size="large" class="btn_size op_shake_up" @click="onStopShakingTube">结束摇匀</van-button>
|
|
<van-button size="large" class="btn_size op_move_heat" @click="onMoveToHeat">移至加热</van-button>
|
|
<van-button size="large" class="btn_size op_move_act" @click="onMoveToOperationArea">移至加液</van-button>
|
|
<van-button size="large" class="btn_size op_move_exception" @click="onMoveToSpecial">移至特殊</van-button>
|
|
<van-button v-if="!isHeating" size="large" class="btn_size op_start_heat" @click="onStartHeat"
|
|
>开始加热</van-button
|
|
>
|
|
<van-button v-else size="large" class="btn_size op_start_heat" @click="onStopHeat">停止加热</van-button>
|
|
|
|
<van-button size="large" class="btn_size op_up_tray" @click="onUpTray">抬起托盘</van-button>
|
|
</div>
|
|
</div>
|
|
<van-overlay :show="liquidVisible" v-if="liquidVisible" style="z-index: 9999">
|
|
<div class="liquid">
|
|
<div class="addLiquid">
|
|
<AddLiquid
|
|
:currentSelectedTube="currentSelectedTube"
|
|
@cancel="liquidVisible = false"
|
|
@onAddSolution="onAddSolution"></AddLiquid>
|
|
</div>
|
|
</div>
|
|
</van-overlay>
|
|
<!--选择工艺-->
|
|
<OverlayModal :visible="craftVisible">
|
|
<CraftList @changeVisible="changeVisible" @selectedCraft="onHandleSelectedCraft"></CraftList>
|
|
</OverlayModal>
|
|
|
|
<!--实验名称-->
|
|
<OverlayModal :visible="taskNameVisible">
|
|
<div class="task_name">
|
|
<div class="task_title">开始新实验</div>
|
|
<div class="task_name_content">
|
|
<div class="mt-3">实验名称:</div>
|
|
<div class="task_auto">
|
|
<input v-model="taskName" placeholder="实验名称" class="task_input" />
|
|
<div v-if="!taskName" style="color: red; font-size: 1rem">请输入实验名称</div>
|
|
</div>
|
|
</div>
|
|
|
|
<br />
|
|
<footer class="task_button">
|
|
<button class="btn-dark px-2 py-1 min-w-20" @click="onSave">保存</button>
|
|
<button class="cancel_btn" @click="onCancel">取消</button>
|
|
</footer>
|
|
</div>
|
|
</OverlayModal>
|
|
</div>
|
|
</template>
|
|
<script lang="ts" setup>
|
|
import { ref, reactive, onMounted, onUnmounted, watch } from "vue";
|
|
//@ts-ignore
|
|
import { ElMessage, ElMessageBox } from "element-plus";
|
|
import { createWebSocket, sharedWsUrl } from "@/services/socket";
|
|
import { HeatPosition, TakePickture, AddLiquid } from "./components";
|
|
import OverlayModal from "@/components/OverlayModal.vue";
|
|
import CraftList from "@/views/graphite/components/CraftList.vue";
|
|
import { injectFluid } from "@/services/task/task";
|
|
import { setOnGoingStatus, useStatusStore } from "@/stores/status";
|
|
import { getIngTask, saveTaskName, stopTask } from "@/services/task/task";
|
|
import { CmdDescMap, taskCmd, type OperationCmd } from "@/services/globalCmd/globalCmd";
|
|
import { craftStart, craftStop } from "@/services/ore/oreManage";
|
|
import { getTxnRecord } from "@/services/txn";
|
|
import { useSettingStore } from "@/stores/setting";
|
|
import { useCraftStore } from "@/stores/craft";
|
|
|
|
const craftStore = useCraftStore();
|
|
const craftInfo = ref(craftStore.craftInfo);
|
|
const settingStore = useSettingStore();
|
|
const craftName = ref("选择工艺");
|
|
const exeCraftName = ref("执行工艺");
|
|
watch(
|
|
() => craftStore.craftInfo,
|
|
newVal => {
|
|
craftInfo.value = newVal;
|
|
if (newVal?.status == 1) {
|
|
craftName.value = "暂停工艺";
|
|
exeCraftName.value = "停止工艺";
|
|
}
|
|
}
|
|
);
|
|
//设备的全局状态
|
|
const statusStore = useStatusStore();
|
|
const heatAearStatusList = ref(statusStore.status?.heatArea || []);
|
|
const heatList: any = ref([]);
|
|
const craftVisible = ref(false);
|
|
let tubeList = reactive<any>([]);
|
|
const selectedColor = "#4F85FB";
|
|
const emptyColor = "#FFFFFF";
|
|
const taskName = ref("");
|
|
let globeStatus: any = 0;
|
|
onMounted(() => {
|
|
//6个加热区数据
|
|
heatList.value = settingStore.heatAreaConfig.map((item: any) => {
|
|
//添加一个字段,默认为未选中
|
|
item.isSelect = false;
|
|
heatAearStatusList.value.forEach((areaItem: any) => {
|
|
if (areaItem.hardwareId == item.hardwareId) {
|
|
item = {
|
|
...item,
|
|
heatAearStatus: areaItem,
|
|
};
|
|
}
|
|
});
|
|
return item;
|
|
});
|
|
//设备16个试管的基础数据
|
|
tubeBaseConfig();
|
|
//连接socket
|
|
const wsClient = createWebSocket(sharedWsUrl);
|
|
const subscription = wsClient.dataOb.subscribe(data => {
|
|
if (!globeStatus) {
|
|
//为了只输入一行,不想后台一直打印此处日志 TODO
|
|
console.log("globeStatus====", data);
|
|
}
|
|
globeStatus = 1;
|
|
if (data.type === "cmd") {
|
|
const cmdInfo = getTxnRecord(data.data.commandId, "task");
|
|
if (cmdInfo) {
|
|
const command: any = cmdInfo.command;
|
|
//@ts-ignore
|
|
const cmdName = CmdDescMap[command];
|
|
const result = data.data.success ? "执行完毕" : `执行失败 ${data.data.message}`;
|
|
ElMessage({
|
|
message: `${cmdName} ${result}`,
|
|
type: data.data.success ? "success" : "error",
|
|
});
|
|
}
|
|
}
|
|
});
|
|
wsClient.connect();
|
|
|
|
onUnmounted(() => {
|
|
subscription.unsubscribe();
|
|
});
|
|
});
|
|
|
|
//选中的托盘
|
|
const selectedTrayList = ref<any>([]);
|
|
const selectedTrayObj: any = {};
|
|
const onSelectedTray = (heatAreaItem: any, type: string) => {
|
|
heatList.value[heatAreaItem.index] = heatAreaItem;
|
|
//取消选中,已经存在selectedTrayList中
|
|
let ids = selectedTrayList.value.map((tube: any) => tube.id);
|
|
if (type == "isClick") {
|
|
//点击加热区
|
|
if (ids.includes(heatAreaItem.id)) {
|
|
heatAreaItem.isSelect = false;
|
|
selectedTrayList.value = selectedTrayList.value.filter((selectedItem: any) => selectedItem.id != heatAreaItem.id);
|
|
} else {
|
|
heatAreaItem.isSelect = true;
|
|
selectedTrayList.value.push(heatAreaItem);
|
|
}
|
|
} else {
|
|
heatAreaItem.isSelect = true;
|
|
}
|
|
heatList.value.forEach((item: any) => {
|
|
if (item.id == heatAreaItem.id) {
|
|
item = heatAreaItem;
|
|
onHeadleCraft(item);
|
|
}
|
|
});
|
|
console.log("hasCraftInfo---", hasCraftInfo.value);
|
|
};
|
|
|
|
//选择的加热区是否选择了工艺
|
|
let hasCraftInfo = ref(false);
|
|
const onHeadleCraft = (areaItem: any) => {
|
|
if (areaItem.craftInfo) {
|
|
hasCraftInfo.value = true;
|
|
}
|
|
};
|
|
|
|
//设置加热区温度
|
|
const onSetHeatAreaTemp = (dataInfo: any) => {
|
|
selectedTrayObj[dataInfo.id] = dataInfo;
|
|
selectedTrayList.value = Object.values(selectedTrayObj);
|
|
};
|
|
|
|
//加热区选择的工艺
|
|
const onSelectCraft = (item: any, craftInfo: any) => {
|
|
item.isSelect = true;
|
|
item.craftInfo = craftInfo;
|
|
onSelectedTray(item, "isMove");
|
|
};
|
|
//开始执行工艺
|
|
const onCraftStart = () => {
|
|
if (!selectedTrayList.value.length) {
|
|
ElMessage.error("请选择目标加热区");
|
|
return;
|
|
}
|
|
|
|
//可能会选择多个加热区执行工艺, 批量发送指令
|
|
let hasCraft = true;
|
|
let len = selectedTrayList.value.length;
|
|
for (let i = 0; i < len; i++) {
|
|
let item = selectedTrayList.value[i];
|
|
if (!item.craftInfo) {
|
|
hasCraft = false;
|
|
ElMessage.error("选择的加热区未选择工艺");
|
|
break;
|
|
}
|
|
const params = {
|
|
craftId: null,
|
|
heatId: item.id,
|
|
};
|
|
if (craftInfo.value?.status == 1) {
|
|
craftStop(params).then(res => {
|
|
ElMessage.success("已停止执行工艺的指令");
|
|
});
|
|
return;
|
|
} else {
|
|
params.craftId = item.craftInfo.id;
|
|
craftStart(params).then(res => {
|
|
ElMessage.success("已执行工艺的指令");
|
|
});
|
|
}
|
|
}
|
|
|
|
if (hasCraft) {
|
|
//给选择加热区heatList加一个正在执行工艺的标识
|
|
const selectedIds = selectedTrayList.value.map((item: any) => item.id);
|
|
heatList.value.forEach((item: any) => {
|
|
if (selectedIds.includes(item.id)) {
|
|
item.executing_craft = true;
|
|
}
|
|
});
|
|
}
|
|
};
|
|
|
|
//停止工艺
|
|
const onCraftStop = () => {};
|
|
|
|
const tubeBaseConfig = () => {
|
|
//默认为16个
|
|
for (let i = 0; i < 16; i++) {
|
|
tubeList.push({
|
|
id: i + 1,
|
|
color: "rgb(212, 212, 212)",
|
|
});
|
|
}
|
|
};
|
|
|
|
//添加溶液
|
|
const liquidVisible = ref(false);
|
|
const onAddLiquid = () => {
|
|
//检查加液区是否有试管。
|
|
const liquidArea = statusStore.status?.liquidArea;
|
|
if (liquidArea) {
|
|
liquidVisible.value = true;
|
|
} else {
|
|
ElMessage.error("加液区未检测到托盘,无法进行加液操作");
|
|
}
|
|
};
|
|
|
|
const onAddSolution = (data: any) => {
|
|
let ids = data.map((item: any) => item.id);
|
|
//批量发送加液指令
|
|
const params = {
|
|
injectFluids: data,
|
|
};
|
|
injectFluid(params).then(res => {
|
|
if (res.success) {
|
|
setOnGoingStatus("injecting");
|
|
} else {
|
|
ElMessage.error(res.msg);
|
|
}
|
|
});
|
|
globeStatus = 0;
|
|
// tubeList.forEach((item: any) => {
|
|
// if (ids.includes(item.id)) {
|
|
// item.default = defaultColor;
|
|
// item.color = defaultColor;
|
|
// item.isSelected = true;
|
|
// }
|
|
// });
|
|
};
|
|
|
|
const changeVisible = () => {
|
|
craftVisible.value = false;
|
|
};
|
|
|
|
//选择工艺
|
|
const onChooseCaft = () => {
|
|
//1、是否选择了加热区
|
|
if (!selectedTrayList.value.length) {
|
|
ElMessage.error("请选择目标加热区");
|
|
return;
|
|
}
|
|
craftVisible.value = true;
|
|
};
|
|
|
|
//选择的工艺
|
|
const onHandleSelectedCraft = (craftInfo: any) => {
|
|
selectedTrayList.value.forEach((item: any) => {
|
|
item.isSelect = true;
|
|
item.craftInfo = craftInfo;
|
|
onSelectedTray(item, "isMove");
|
|
});
|
|
const selectedIds = selectedTrayList.value.map((item: any) => item.id);
|
|
heatList.value.forEach((item: any) => {
|
|
if (selectedIds.includes(item.id)) {
|
|
item.craftInfo = craftInfo;
|
|
}
|
|
});
|
|
changeVisible();
|
|
};
|
|
|
|
const onChooseTube = (tubeItem: any, index: any) => {
|
|
if (!tubeItem.id) return;
|
|
//@ts-ignore
|
|
let list = [...tubeList];
|
|
for (let i = 0; i < list.length; i++) {
|
|
let item = list[i];
|
|
if (index == i) {
|
|
item.color = selectedColor;
|
|
item.isSelected = true;
|
|
} else {
|
|
item.color = item.default ? item.default : emptyColor;
|
|
item.isSelected = false;
|
|
}
|
|
}
|
|
tubeList = [...list];
|
|
};
|
|
|
|
//移至加热
|
|
const onMoveToHeat = () => {
|
|
//1、是否选择了加热区
|
|
if (!selectedTrayList.value.length) {
|
|
ElMessage.error("请选择目标加热区");
|
|
return;
|
|
}
|
|
//2、只能选择一个加热区
|
|
if (selectedTrayList.value.length != 1) {
|
|
ElMessage.error("只能选择一个加热区");
|
|
return;
|
|
}
|
|
let selectedDataItem = selectedTrayList.value[0];
|
|
//2、判断选择的加热区是否已经有了试管架, 加热区是否有试管是通过设备上报的数据获取的
|
|
let hardwareId = selectedDataItem.hardwareId;
|
|
// let trayStatus = heatAearStatusList.value[selectedDataItem.index].trayStatus;
|
|
let trayStatus;
|
|
heatAearStatusList.value.forEach((item: any) => {
|
|
if (hardwareId == item.hardwareId) {
|
|
trayStatus = item.trayStatus;
|
|
}
|
|
});
|
|
// trayStatus: 0为无托盘,1为有托盘,2为托盘抬起
|
|
if (trayStatus == 1) {
|
|
ElMessage.error("选择的加热区已有试管架,重新选择加热区");
|
|
return;
|
|
}
|
|
|
|
//调用移至加热接口
|
|
const params = {
|
|
heatId: selectedDataItem.id,
|
|
};
|
|
const command: OperationCmd = "moveToHeatArea";
|
|
taskCmd({ command, params }).then(res => {
|
|
if (res.success) {
|
|
// ElMessage.success("指令已发送,请稍等");
|
|
setOnGoingStatus("movingToHeat");
|
|
} else {
|
|
ElMessage.error(res.msg);
|
|
}
|
|
});
|
|
|
|
//指令完成成更新UI
|
|
let list = [...heatList.value];
|
|
list.forEach((item: any) => {
|
|
if (item.id == selectedDataItem.id) {
|
|
item.tubeList = JSON.parse(JSON.stringify(tubeList));
|
|
selectedDataItem.tubeList = JSON.parse(JSON.stringify(tubeList));
|
|
//标注该加热区是选中状态
|
|
item.isSelect = true;
|
|
}
|
|
});
|
|
tubeList.forEach((item: any) => {
|
|
item.color = "";
|
|
item.default = "";
|
|
});
|
|
heatList.value = [...list];
|
|
};
|
|
|
|
//移至加液区(操作区)
|
|
const currentSelectedTube = ref({});
|
|
const onMoveToOperationArea = () => {
|
|
//1、判断加液区是否有试管架(暂时获取不到这个状态)
|
|
//1、是否选择了试管架/加热区
|
|
if (!selectedTrayList.value.length) {
|
|
ElMessage.error("请选择加热区");
|
|
return false;
|
|
}
|
|
//2、只能选择一个试管架/加热区
|
|
if (selectedTrayList.value.length != 1) {
|
|
ElMessage.error("只能选择一个加热区");
|
|
return false;
|
|
}
|
|
let selectedDataItem = selectedTrayList.value[0];
|
|
currentSelectedTube.value = selectedDataItem;
|
|
//3、选择的加热区有没有试管架
|
|
if (!selectedDataItem.tubeList || !selectedDataItem.tubeList.length) {
|
|
ElMessage.error("选择的加热区没有试管架");
|
|
return false;
|
|
}
|
|
//4、发送移至加液区指令
|
|
const params = {
|
|
heatId: selectedDataItem.id,
|
|
};
|
|
onSendCmd("moveToActionArea", params);
|
|
//更新UI
|
|
heatList.value.forEach((item: any) => {
|
|
if (item.id == selectedDataItem.id) {
|
|
tubeList = [...item.tubeList];
|
|
}
|
|
});
|
|
onSelectedTray(selectedDataItem, "isMove");
|
|
return true;
|
|
};
|
|
|
|
//移至特殊区域
|
|
const onMoveToSpecial = () => {
|
|
//检查是否设置了异常区域
|
|
const systemSetting = settingStore.systemSetting;
|
|
let specialArea: any = {};
|
|
if (systemSetting && systemSetting.length) {
|
|
systemSetting.forEach(item => {
|
|
if (item.code == "sys_setting_abnormal_area") {
|
|
specialArea = item;
|
|
}
|
|
});
|
|
|
|
if (!specialArea.id) {
|
|
ElMessage.error("未设置异常区域,请在系统配置中设置");
|
|
return;
|
|
}
|
|
|
|
//是否选择了加热区的试管架
|
|
if (!selectedTrayList.value.length) {
|
|
ElMessage.error("请选择试管架");
|
|
return;
|
|
}
|
|
//2、只能选择一个试管架/加热区
|
|
if (selectedTrayList.value.length != 1) {
|
|
ElMessage.error("只能选择一个试管架");
|
|
return;
|
|
}
|
|
let selectedDataItem = selectedTrayList.value[0];
|
|
selectedDataItem.isSelect = false;
|
|
onSelectedTray(selectedDataItem, "isMove");
|
|
|
|
const params = {
|
|
heatId: selectedDataItem.id,
|
|
};
|
|
onSendCmd("moveToActionArea", params);
|
|
}
|
|
};
|
|
|
|
//开始实验
|
|
const taskNameVisible = ref(false);
|
|
const taskId = ref();
|
|
const onSave = () => {
|
|
if (!taskName.value) return;
|
|
const params = {
|
|
name: taskName.value,
|
|
};
|
|
saveTaskName(params).then(res => {
|
|
if (res.success) {
|
|
taskId.value = res.data.id;
|
|
ElMessage.success("保存成功");
|
|
onCancel();
|
|
} else {
|
|
ElMessage.error(res.msg);
|
|
}
|
|
});
|
|
};
|
|
|
|
const startTask = async () => {
|
|
const res = await getIngTask();
|
|
|
|
if (res.data) {
|
|
ElMessageBox.confirm(`上一实验"${res.data.name}"未结束,是否结束并开始新的实验`, "提示", {
|
|
confirmButtonText: "确定",
|
|
cancelButtonText: "取消",
|
|
center: true,
|
|
})
|
|
.then(() => {
|
|
stopTask({ taskId: res.data.id })
|
|
.then(res => {
|
|
if (res.success) {
|
|
ElMessage.success("实验已停止");
|
|
taskNameVisible.value = true;
|
|
} else {
|
|
ElMessage.error("实验停止失败");
|
|
}
|
|
})
|
|
.catch(e => {
|
|
ElMessage.error(e);
|
|
});
|
|
})
|
|
.catch(() => {});
|
|
} else {
|
|
taskNameVisible.value = true;
|
|
}
|
|
};
|
|
|
|
//结束实验
|
|
const onEndTask = () => {
|
|
const params = {
|
|
taskId: taskId.value,
|
|
};
|
|
stopTask(params)
|
|
.then(res => {
|
|
heatList.value.forEach((item: any) => {
|
|
item.executing_craft = false;
|
|
});
|
|
if (res.success) {
|
|
ElMessage.success("实验已停止");
|
|
} else {
|
|
ElMessage.error("实验停止失败");
|
|
}
|
|
})
|
|
.catch(e => {
|
|
ElMessage.error(e);
|
|
});
|
|
};
|
|
|
|
const onCancel = () => {
|
|
taskNameVisible.value = false;
|
|
};
|
|
|
|
//开门
|
|
const doorStatus = ref(false); //开门状态 。true: 门已打开, false: 门未打开
|
|
const onOPenDoor = () => {
|
|
const params = {};
|
|
const command: OperationCmd = "openDoor";
|
|
taskCmd({ command, params }).then(res => {
|
|
if (res.success) {
|
|
// ElMessage.success("指令已发送,请稍等");
|
|
doorStatus.value = true;
|
|
setOnGoingStatus("doorOpening");
|
|
} else {
|
|
ElMessage.error(res.msg);
|
|
}
|
|
});
|
|
};
|
|
|
|
//关门
|
|
const onCloseDoor = () => {
|
|
const params = {};
|
|
const command: OperationCmd = "closeDoor";
|
|
taskCmd({ command, params }).then(res => {
|
|
if (res.success) {
|
|
// ElMessage.success("指令已发送,请稍等");
|
|
doorStatus.value = false;
|
|
setOnGoingStatus("doorClosing");
|
|
} else {
|
|
ElMessage.error(res.msg);
|
|
}
|
|
});
|
|
};
|
|
|
|
//开始加热
|
|
const isHeating = ref(false);
|
|
const onStartHeat = () => {
|
|
//选择的加热区
|
|
if (!selectedTrayList.value.length) {
|
|
ElMessage.error("请选择目标加热区");
|
|
return;
|
|
}
|
|
//判断选中的加热区是否有试管架
|
|
let existTubeRack = true;
|
|
//加热区是否设置了加热温度
|
|
let hasSetTemp = true;
|
|
selectedTrayList.value.forEach((item: any) => {
|
|
let tubeList = item.tubeList;
|
|
if (!tubeList || !tubeList.length) {
|
|
existTubeRack = false;
|
|
}
|
|
if (!item.temperature) {
|
|
hasSetTemp = false;
|
|
}
|
|
});
|
|
|
|
if (!existTubeRack) {
|
|
ElMessage.error("选择的加热区未放置试管架,请重新选择");
|
|
return;
|
|
}
|
|
if (!hasSetTemp) {
|
|
ElMessage.error("选择的加热区未设置温度,请设置温度");
|
|
return;
|
|
}
|
|
|
|
//后台批量发送指令
|
|
const cmdList: any = [];
|
|
selectedTrayList.value.forEach((heatArea: any) => {
|
|
const params = {
|
|
heatId: heatArea.id,
|
|
temperature: heatArea.temperature,
|
|
};
|
|
taskCmd({ command: "startHeat", params }).then(res => {
|
|
if (res.success) {
|
|
// ElMessage.success("指令已发送,请稍等");
|
|
isHeating.value = true;
|
|
} else {
|
|
ElMessage.error(res.msg);
|
|
}
|
|
});
|
|
});
|
|
// onSendCmd("startHeat", cmdList)
|
|
};
|
|
|
|
//停止加热
|
|
const onStopHeat = () => {
|
|
//选择的加热区
|
|
if (!selectedTrayList.value.length) {
|
|
ElMessage.error("请选择目标加热区");
|
|
return;
|
|
}
|
|
selectedTrayList.value.forEach((heatArea: any) => {
|
|
const params = {
|
|
heatId: heatArea.id,
|
|
};
|
|
taskCmd({ command: "stopHeat", params }).then(res => {
|
|
if (res.success) {
|
|
// ElMessage.success("指令已发送,请稍等");
|
|
isHeating.value = false;
|
|
} else {
|
|
ElMessage.error(res.msg);
|
|
}
|
|
});
|
|
});
|
|
};
|
|
|
|
//开始摇匀
|
|
const isSharking = ref(false);
|
|
const onStartShakingTube = () => {
|
|
const params = {};
|
|
taskCmd({ command: "startShakeUp", params }).then(res => {
|
|
if (res.success) {
|
|
// ElMessage.success("指令已发送,请稍等");
|
|
isSharking.value = true;
|
|
setOnGoingStatus("shaking");
|
|
} else {
|
|
ElMessage.error(res.msg);
|
|
}
|
|
});
|
|
};
|
|
|
|
//结束摇匀
|
|
const onStopShakingTube = () => {
|
|
const params = {};
|
|
taskCmd({ command: "stopShakeUp", params }).then(res => {
|
|
if (res.success) {
|
|
// ElMessage.success("指令已发送,请稍等");
|
|
isSharking.value = false;
|
|
} else {
|
|
ElMessage.error(res.msg);
|
|
}
|
|
});
|
|
};
|
|
|
|
//抬起托盘
|
|
const onUpTray = () => {
|
|
if (!selectedTrayList.value.length) {
|
|
ElMessage.error("请选择目标加热区");
|
|
return;
|
|
}
|
|
//选择了多个加热区,可托起多个加热区试管加
|
|
selectedTrayList.value.forEach((heatAreaItem: any) => {
|
|
const params = {
|
|
heatId: heatAreaItem.id,
|
|
};
|
|
|
|
taskCmd({ command: "upTray", params }).then(res => {
|
|
if (res.success) {
|
|
// ElMessage.success("指令已发送,请稍等");
|
|
} else {
|
|
ElMessage.error(res.msg);
|
|
}
|
|
});
|
|
});
|
|
};
|
|
|
|
//修改加热区状态 selectedValue: 0 | 1 | 2; // 0为无托盘,1为有托盘,2为托盘抬起
|
|
const updateheatAearStatus = (selectedValue: any, heatId: string) => {
|
|
let heaterList = statusStore.status?.heatArea;
|
|
if (heaterList) {
|
|
heaterList.forEach((item: any) => {
|
|
if (item.heaterId == heatId) {
|
|
item.trayStatus = selectedValue;
|
|
}
|
|
});
|
|
const data: any = {
|
|
...statusStore.status,
|
|
heater: [...heaterList],
|
|
};
|
|
statusStore.setStatus(data);
|
|
}
|
|
};
|
|
|
|
const onSendCmd = (command: OperationCmd, params: any) => {
|
|
//发送加热指令
|
|
taskCmd({ command, params }).then(res => {
|
|
if (res.success) {
|
|
// ElMessage.success("指令已发送,请稍等");
|
|
setOnGoingStatus("movingToAct");
|
|
} else {
|
|
ElMessage.error(res.msg);
|
|
}
|
|
});
|
|
};
|
|
</script>
|
|
<style lang="scss" scoped>
|
|
@use "@/assets/style/mixin.scss" as *;
|
|
|
|
.graphite_home {
|
|
background: #f6f6f6;
|
|
display: flex;
|
|
// @media (min-width: $md) {
|
|
flex-direction: column;
|
|
align-items: stretch;
|
|
// }
|
|
.picture_area {
|
|
display: flex;
|
|
flex-direction: column-reverse;
|
|
margin: 0 12px;
|
|
}
|
|
@media (min-width: $lg) {
|
|
flex-direction: row;
|
|
align-items: start;
|
|
.picture_area {
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
}
|
|
}
|
|
.heat_area {
|
|
margin: 5px 0;
|
|
|
|
background: #ffffff;
|
|
border-radius: 20px;
|
|
|
|
column-gap: 8px;
|
|
row-gap: 10px;
|
|
padding: 1.5rem 0.5rem;
|
|
min-width: 600px;
|
|
flex: 1 1 auto;
|
|
display: grid;
|
|
grid-template-columns: repeat(3, 1fr);
|
|
> * {
|
|
justify-self: center;
|
|
align-self: center;
|
|
}
|
|
|
|
@media (min-width: $md) {
|
|
column-gap: 12px;
|
|
row-gap: 20px;
|
|
height: 47.5rem;
|
|
}
|
|
|
|
@media (min-width: $xl) {
|
|
padding: 4.5rem 1rem;
|
|
}
|
|
|
|
.craft_executing_modal {
|
|
position: absolute;
|
|
width: 10.5rem;
|
|
height: 18rem;
|
|
background: rgb(230, 230, 230);
|
|
opacity: 0.5;
|
|
z-index: 9999;
|
|
}
|
|
}
|
|
|
|
.picture_area {
|
|
display: flex;
|
|
flex-direction: column;
|
|
margin: 5px;
|
|
// margin-left: 1.25rem;
|
|
background: #ffffff;
|
|
border-radius: 20px;
|
|
padding: 0 1.5rem;
|
|
@media (min-width: $lg) {
|
|
flex: 1 1 180px;
|
|
}
|
|
@media (min-width: $xl) {
|
|
flex: 0 0 auto;
|
|
width: 27rem;
|
|
}
|
|
|
|
.graphite_btn_container {
|
|
margin: 2rem 0;
|
|
gap: 0.625rem;
|
|
display: grid;
|
|
@media (max-width: calc($md - 0.1px)) {
|
|
grid-template-columns: repeat(2, 1fr);
|
|
.op_open_door {
|
|
grid-column: 1/-1;
|
|
}
|
|
.op_up_tray {
|
|
grid-column: 1/-1;
|
|
}
|
|
}
|
|
@media (min-width: $md) and (max-width: calc($lg - 0.1px)) {
|
|
grid-template-columns: repeat(6, 1fr);
|
|
> * {
|
|
grid-column: span 3;
|
|
}
|
|
.op_open_door {
|
|
grid-column: 1/-1;
|
|
}
|
|
.op_move_heat {
|
|
grid-column: span 2;
|
|
}
|
|
.op_move_act {
|
|
grid-column: span 2;
|
|
}
|
|
.op_move_exception {
|
|
grid-column: span 2;
|
|
}
|
|
}
|
|
@media (min-width: $lg) and (max-width: calc($xl - 0.1px)) {
|
|
grid-template-columns: repeat(2, 1fr);
|
|
.op_open_door {
|
|
grid-column: 1/-1;
|
|
}
|
|
.op_up_tray {
|
|
grid-column: 1/-1;
|
|
}
|
|
}
|
|
@media (min-width: $xl) {
|
|
grid-template-columns: repeat(6, 1fr);
|
|
> * {
|
|
grid-column: span 3;
|
|
}
|
|
.op_open_door {
|
|
grid-column: 1/-1;
|
|
}
|
|
.op_move_heat {
|
|
grid-column: span 2;
|
|
}
|
|
.op_move_act {
|
|
grid-column: span 2;
|
|
}
|
|
.op_move_exception {
|
|
grid-column: span 2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.btn_size {
|
|
height: 2.75rem;
|
|
color: #1989fa;
|
|
border: 1px solid #1989fa;
|
|
font-size: 1.25rem;
|
|
}
|
|
|
|
.liquid {
|
|
display: flex;
|
|
justify-content: center;
|
|
width: 100%;
|
|
height: 100%;
|
|
align-items: center;
|
|
.addLiquid {
|
|
width: 70.375rem;
|
|
height: 52rem;
|
|
background: #ffffff;
|
|
}
|
|
}
|
|
|
|
.home_tube {
|
|
width: 13rem;
|
|
height: 13rem;
|
|
background: #384d5d;
|
|
opacity: 1;
|
|
margin-top: 0.5rem;
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
justify-content: center;
|
|
gap: 0.6rem;
|
|
padding-top: 0.2rem;
|
|
border-radius: 1.5rem;
|
|
.inner-circle {
|
|
border-radius: 50%;
|
|
width: 2.5rem;
|
|
height: 2.5rem;
|
|
background-color: rgb(212, 212, 212);
|
|
}
|
|
}
|
|
|
|
.task_name {
|
|
height: 17.25rem;
|
|
width: 27.5rem;
|
|
background: #ffffff;
|
|
|
|
.task_title {
|
|
font-size: 1.25rem;
|
|
color: #40474e;
|
|
margin-left: 1.25rem;
|
|
margin-top: 1.875rem;
|
|
}
|
|
|
|
.task_name_content {
|
|
margin-top: 1.875rem;
|
|
margin-left: 1.5rem;
|
|
font-size: 1.25rem;
|
|
color: #40474e;
|
|
display: flex;
|
|
.task_input {
|
|
border: 1px solid #dcdcdc;
|
|
border-radius: 8px;
|
|
height: 3rem;
|
|
}
|
|
}
|
|
|
|
.task_button {
|
|
display: flex;
|
|
justify-content: center;
|
|
}
|
|
}
|
|
.cancel_btn {
|
|
border: 1px solid rgb(226, 226, 226);
|
|
width: 5rem;
|
|
margin-left: 2rem;
|
|
}
|
|
</style>
|