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

2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
  1. <script setup lang="ts">
  2. import { stopTask, trayIn } from 'apis/home'
  3. import AddLiquid from 'components/home/AddLiquid/index.vue'
  4. import CheckCraft from 'components/home/CheckCraft/index.vue'
  5. import ExecuteCraft from 'components/home/ExecuteCraft/index.vue'
  6. import ExtractLiquid from 'components/home/ExtractLiquid/index.vue'
  7. import FillSolution from 'components/home/FillSolution/index.vue'
  8. import SetTemperature from 'components/home/SetTemperature/index.vue'
  9. import StartClean from 'components/home/StartClean/index.vue'
  10. import StartExperiment from 'components/home/StartExperiment/index.vue'
  11. import Tube from 'components/home/Tube/index.vue'
  12. import { ElMessageBox } from 'element-plus'
  13. import { FtMessage } from 'libs/message'
  14. import { socket } from 'libs/socket'
  15. import { cmdNameMap, formatDateTime } from 'libs/utils'
  16. import { useHomeStore } from 'stores/homeStore'
  17. import { useSystemStore } from 'stores/systemStore'
  18. import { computed, onMounted, onUnmounted, provide, ref } from 'vue'
  19. const homeStore = useHomeStore()
  20. const systemStore = useSystemStore()
  21. onMounted(() => {
  22. socket.init(receiveMessage, 'cmd_debug')
  23. socket.init(receiveMessage, 'cmd_response')
  24. })
  25. onUnmounted(() => {
  26. socket.unregisterCallback(receiveMessage, 'cmd_debug')
  27. socket.unregisterCallback(receiveMessage, 'cmd_response')
  28. })
  29. let currentCommandId = ''
  30. const receiveMessage = (data: Socket.cmdData) => {
  31. data.commandId === currentCommandId && systemStore.pushSystemList(data)
  32. if (['start', 'success', 'fail'].includes(data.status)) {
  33. const cmdName = cmdNameMap[data.command as keyof typeof cmdNameMap] || data.command
  34. systemStore.insertLog({ cmdName, status: data.status as System.SystemLog['status'], time: formatDateTime() })
  35. }
  36. }
  37. const selectedHeatArea = computed(() => {
  38. return homeStore.heatAreaList.find(item => item.selected)
  39. })
  40. const startVisible = ref(false)
  41. const startExperimentHandle = () => {
  42. if (systemStore.systemStatus.currentTasks) {
  43. FtMessage.error('记录已经开启')
  44. return
  45. }
  46. startVisible.value = true
  47. }
  48. const stopExperimentHandle = async () => {
  49. if (!systemStore.systemStatus.currentTasks) {
  50. FtMessage.error('当前没有记录在开始')
  51. return
  52. }
  53. await stopTask()
  54. FtMessage.success('记录已停止')
  55. }
  56. const selectCraftVisible = ref(false)
  57. const executeCraftHandle = async () => {
  58. selectCraftVisible.value = true
  59. }
  60. const setTemperatureVisible = ref(false)
  61. const currentTemperatureData = ref<{ id: string, label: string | undefined }>({
  62. id: '',
  63. label: 'A-1',
  64. })
  65. provide('currentTemperatureData', currentTemperatureData)
  66. const setTemperature = (data: System.HeatArea) => {
  67. const craft = systemStore.systemStatus.trays?.find(item => item.heatModuleCode === data.moduleCode)?.crafts
  68. if (craft?.craft) {
  69. FtMessage.warning(`当前加热区已绑定预设`)
  70. return
  71. }
  72. currentTemperatureData.value = {
  73. id: data.moduleCode,
  74. label: homeStore.heatAreaList.find(item => item.value === data.moduleCode)?.label,
  75. }
  76. setTemperatureVisible.value = true
  77. }
  78. const fillSolutionVisible = ref(false)
  79. const addLiquidVisible = ref(false)
  80. const cleanVisible = ref(false)
  81. const extractLiquidVisible = ref(false)
  82. const commandHandle = async (command: string, params?: unknown) => {
  83. currentCommandId = Date.now().toString()
  84. const data = {
  85. commandId: currentCommandId,
  86. command,
  87. params,
  88. }
  89. await homeStore.sendControl(data)
  90. }
  91. const move_to_liquid_area = async () => {
  92. if (!selectedHeatArea.value?.value) {
  93. await ElMessageBox.confirm(
  94. '是否要将上料区托盘移至加液位? ',
  95. '提示',
  96. {
  97. confirmButtonText: '确认',
  98. showClose: false,
  99. closeOnClickModal: false,
  100. closeOnPressEscape: false,
  101. type: 'warning',
  102. customClass: 'init-message',
  103. },
  104. )
  105. }
  106. await commandHandle('move_to_liquid_area', { heatModuleCode: selectedHeatArea.value?.value })
  107. }
  108. const move_to_feed_area = async () => {
  109. if (!selectedHeatArea.value?.value) {
  110. await ElMessageBox.confirm(
  111. '是否要将加液位托盘移至上料区? ',
  112. '提示',
  113. {
  114. confirmButtonText: '确认',
  115. showClose: false,
  116. closeOnClickModal: false,
  117. closeOnPressEscape: false,
  118. type: 'warning',
  119. customClass: 'init-message',
  120. },
  121. )
  122. }
  123. await commandHandle('move_to_feed_area', { heatModuleCode: selectedHeatArea.value?.value })
  124. }
  125. const move_to_anneal_area = async () => {
  126. if (!selectedHeatArea.value?.value) {
  127. await ElMessageBox.confirm(
  128. '是否要将加液位或上料区的托盘移至退火区? ',
  129. '提示',
  130. {
  131. confirmButtonText: '确认',
  132. showClose: false,
  133. closeOnClickModal: false,
  134. closeOnPressEscape: false,
  135. type: 'warning',
  136. customClass: 'init-message',
  137. },
  138. )
  139. }
  140. await commandHandle('move_to_anneal_area', { heatModuleCode: selectedHeatArea.value?.value })
  141. }
  142. const trayInHandle = async () => {
  143. await trayIn()
  144. FtMessage.success('设置放入托盘成功')
  145. }
  146. // const trayOutHandle = async () => {
  147. // await trayOut()
  148. // }
  149. const checkCraftVisible = ref(false)
  150. </script>
  151. <template>
  152. <div class="home-page">
  153. <div class="page-top">
  154. <Tube v-for="(item, index) in systemStore.systemStatus.heatModule" :key="item.moduleCode" :data="item" @select-change="homeStore.selectChange(index)" @set-temperature="setTemperature(item)" />
  155. </div>
  156. <div class="button-box">
  157. <el-row style="width: 100%; height: 100%" :gutter="20">
  158. <el-col :span="20">
  159. <div style="display: grid; gap: 10px; grid-template-columns: repeat(2, 1fr);grid-template-rows: repeat(4, 1fr);height: 100%">
  160. <ft-button size="large" :click-handle="() => commandHandle('door_open')">
  161. 开门
  162. </ft-button>
  163. <ft-button size="large" :click-handle="() => commandHandle('door_close')">
  164. 关门
  165. </ft-button>
  166. <ft-button size="large" :click-handle="trayInHandle">
  167. 放入托盘
  168. </ft-button>
  169. <ft-button size="large" :click-handle="() => commandHandle('out_tray', { heatModuleCode: selectedHeatArea!.value })" :disabled="!selectedHeatArea">
  170. 取出托盘
  171. </ft-button>
  172. <ft-button size="large" @click="startExperimentHandle">
  173. 开始记录
  174. </ft-button>
  175. <ft-button size="large" :click-handle="stopExperimentHandle">
  176. 结束记录
  177. </ft-button>
  178. <ft-button size="large" :click-handle="executeCraftHandle">
  179. 执行预设
  180. </ft-button>
  181. <ft-button size="large" :click-handle="() => checkCraftVisible = true">
  182. 异常预设
  183. </ft-button>
  184. </div>
  185. </el-col>
  186. <el-col :span="4" style="display: grid; gap: 10px; grid-template-columns: repeat(1, 1fr);grid-template-rows: repeat(1, 1fr)">
  187. <div class="manual-box">
  188. <el-popover
  189. placement="top-start"
  190. width="auto"
  191. trigger="click"
  192. >
  193. <template #reference>
  194. <div class="manual-button">
  195. 手动操作
  196. </div>
  197. </template>
  198. <template #default>
  199. <div class="container-box">
  200. <ft-button size="large" :disabled="!selectedHeatArea || selectedHeatArea?.label === '退火区'" :click-handle="() => commandHandle('heater_start', { heatModuleCode: selectedHeatArea!.value })">
  201. 开始加热
  202. </ft-button>
  203. <ft-button size="large" :disabled="!selectedHeatArea || selectedHeatArea?.label === '退火区'" :click-handle="() => commandHandle('heater_stop', { heatModuleCode: selectedHeatArea!.value })">
  204. 停止加热
  205. </ft-button>
  206. <ft-button size="large" :disabled="!selectedHeatArea || selectedHeatArea?.label === '退火区'" :click-handle="() => commandHandle('fan_start', { heatModuleCode: selectedHeatArea!.value })">
  207. 开始降温
  208. </ft-button>
  209. <ft-button size="large" :disabled="!selectedHeatArea || selectedHeatArea?.label === '退火区'" :click-handle="() => commandHandle('fan_stop', { heatModuleCode: selectedHeatArea!.value })">
  210. 停止降温
  211. </ft-button>
  212. <ft-button size="large" :disabled="!selectedHeatArea || selectedHeatArea?.label === '退火区'" :click-handle="() => commandHandle('dry_start', { heatModuleCode: selectedHeatArea!.value })">
  213. 开始烘干
  214. </ft-button>
  215. <ft-button size="large" :disabled="!selectedHeatArea || selectedHeatArea?.label === '退火区'" :click-handle="() => commandHandle('dry_stop', { heatModuleCode: selectedHeatArea!.value })">
  216. 停止烘干
  217. </ft-button>
  218. <ft-button size="large" :disabled="!selectedHeatArea || selectedHeatArea?.label !== '退火区'" :click-handle="() => commandHandle('anneal_start', { heatModuleCode: selectedHeatArea!.value })">
  219. 开始退火
  220. </ft-button>
  221. <ft-button size="large" :disabled="!selectedHeatArea || selectedHeatArea?.label !== '退火区'" :click-handle="() => commandHandle('anneal_stop', { heatModuleCode: selectedHeatArea!.value })">
  222. 停止退火
  223. </ft-button>
  224. <ft-button size="large" :click-handle="() => commandHandle('move_to_heat_area', { heatModuleCode: selectedHeatArea!.value })" :disabled="!selectedHeatArea">
  225. 移至加热位
  226. </ft-button>
  227. <ft-button size="large" :click-handle="move_to_liquid_area">
  228. 移至加液位
  229. </ft-button>
  230. <ft-button size="large" :click-handle="move_to_feed_area">
  231. 移至上料区
  232. </ft-button>
  233. <ft-button size="large" :click-handle="move_to_anneal_area">
  234. 移至退火位
  235. </ft-button>
  236. <ft-button size="large" @click="cleanVisible = true">
  237. 开始清洗
  238. </ft-button>
  239. <ft-button size="large" @click=" fillSolutionVisible = true">
  240. 预充管路
  241. </ft-button>
  242. <ft-button size="large" @click="addLiquidVisible = true">
  243. 添加溶液
  244. </ft-button>
  245. <ft-button size="large" @click="extractLiquidVisible = true">
  246. 抽取溶液
  247. </ft-button>
  248. <ft-button size="large" :click-handle="() => commandHandle('liquid_motor_origin')">
  249. 加液臂回原点
  250. </ft-button>
  251. <ft-button size="large" :click-handle="() => commandHandle('z_origin')">
  252. z轴回原点
  253. </ft-button>
  254. <ft-button size="large" :click-handle="() => commandHandle('x_origin')">
  255. x轴回原点
  256. </ft-button>
  257. </div>
  258. </template>
  259. </el-popover>
  260. </div>
  261. </el-col>
  262. </el-row>
  263. </div>
  264. <CheckCraft v-if="checkCraftVisible" @close="checkCraftVisible = false" />
  265. <StartExperiment v-if="startVisible" @ok="startVisible = false" @cancel="startVisible = false" />
  266. <StartClean v-if="cleanVisible" @ok="cleanVisible = false" @cancel="cleanVisible = false" />
  267. <ExecuteCraft v-if="selectCraftVisible" @ok="selectCraftVisible = false" @cancel="selectCraftVisible = false" />
  268. <SetTemperature v-if="setTemperatureVisible" @ok="setTemperatureVisible = false" @cancel="setTemperatureVisible = false" />
  269. <AddLiquid v-if="addLiquidVisible" @ok="addLiquidVisible = false" @cancel="addLiquidVisible = false" />
  270. <ExtractLiquid v-if="extractLiquidVisible" @ok="extractLiquidVisible = false" @cancel="extractLiquidVisible = false" />
  271. <FillSolution v-if="fillSolutionVisible" @ok="fillSolutionVisible = false" @cancel="fillSolutionVisible = false" />
  272. </div>
  273. </template>
  274. <style scoped lang="scss">
  275. .home-page {
  276. .page-top{
  277. height: 65%;
  278. border-radius: 8px;
  279. padding: 0 10px 10px;
  280. display: grid;
  281. grid-template-columns: repeat(4, 1fr); /* 创建3列等宽轨道 */
  282. grid-template-rows: repeat(1, auto); /* 创建2行自动高度 */
  283. gap: 10px;
  284. justify-content: center; /* 水平居中 */
  285. align-items: center;
  286. }
  287. .button-box {
  288. height: 35%;
  289. //display: grid;
  290. //grid-template-columns: repeat(6, 1fr); /* 创建3列等宽轨道 */
  291. //grid-template-rows: repeat(4, 1fr); /* 创建2行自动高度 */
  292. //gap: 10px 20px;
  293. .ft-button {
  294. //width: 100px;
  295. font-weight: bold;
  296. margin-right: 0;
  297. .my-button {
  298. padding: 0 !important;
  299. border: 3px solid #1989fa !important;
  300. }
  301. }
  302. }
  303. }
  304. .el-col {
  305. height: 100%;
  306. }
  307. .manual-box {
  308. width: 100%;
  309. height: 100%;
  310. display: flex;
  311. align-items: center;
  312. justify-content: center;
  313. }
  314. .container-box {
  315. width: 600px;
  316. display: grid;
  317. grid-template-columns: repeat(4, 1fr);
  318. grid-template-rows: repeat(2, 1fr);
  319. gap: 10px;
  320. }
  321. .manual-button {
  322. border:1px solid #1989FA;
  323. color: #1989FA;
  324. width: 100%;
  325. height: 100px;
  326. line-height: 100px;
  327. text-align: center;
  328. border-radius: 10px;
  329. }
  330. </style>