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.

418 lines
15 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
  1. <script setup lang="ts">
  2. import { 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 selectCraftVisible = ref(false)
  42. const executeCraftHandle = async () => {
  43. selectCraftVisible.value = true
  44. }
  45. const setTemperatureVisible = ref(false)
  46. const currentTemperatureData = ref<{ id: string, label: string | undefined }>({
  47. id: '',
  48. label: 'A-1',
  49. })
  50. provide('currentTemperatureData', currentTemperatureData)
  51. const setTemperature = (data: System.HeatArea) => {
  52. const craft = systemStore.systemStatus.trays?.find(item => item.heatModuleCode === data.moduleCode)?.crafts
  53. if (craft?.craft) {
  54. FtMessage.warning(`当前加热区已绑定工艺`)
  55. return
  56. }
  57. currentTemperatureData.value = {
  58. id: data.moduleCode,
  59. label: homeStore.heatAreaList.find(item => item.value === data.moduleCode)?.label,
  60. }
  61. setTemperatureVisible.value = true
  62. }
  63. const fillSolutionVisible = ref(false)
  64. const addLiquidVisible = ref(false)
  65. const cleanVisible = ref(false)
  66. const extractLiquidVisible = ref(false)
  67. const commandHandle = async (command: string, params?: unknown) => {
  68. currentCommandId = Date.now().toString()
  69. const data = {
  70. commandId: currentCommandId,
  71. command,
  72. params,
  73. }
  74. await homeStore.sendControl(data)
  75. }
  76. const move_to_liquid_area = async () => {
  77. if (!selectedHeatArea.value?.value) {
  78. await ElMessageBox.confirm(
  79. '是否要将上料区托盘移至加液位? ',
  80. '提示',
  81. {
  82. confirmButtonText: '确认',
  83. showClose: false,
  84. closeOnClickModal: false,
  85. closeOnPressEscape: false,
  86. type: 'warning',
  87. customClass: 'init-message',
  88. },
  89. )
  90. }
  91. await commandHandle('move_to_liquid_area', { heatModuleCode: selectedHeatArea.value?.value })
  92. }
  93. const move_to_feed_area = async () => {
  94. if (!selectedHeatArea.value?.value) {
  95. await ElMessageBox.confirm(
  96. '是否要将加液位托盘移至上料区? ',
  97. '提示',
  98. {
  99. confirmButtonText: '确认',
  100. showClose: false,
  101. closeOnClickModal: false,
  102. closeOnPressEscape: false,
  103. type: 'warning',
  104. customClass: 'init-message',
  105. },
  106. )
  107. }
  108. await commandHandle('move_to_feed_area', { heatModuleCode: selectedHeatArea.value?.value })
  109. }
  110. const move_to_anneal_area = async () => {
  111. if (!selectedHeatArea.value?.value) {
  112. await ElMessageBox.confirm(
  113. '是否要将加液位或上料区的托盘移至退火区? ',
  114. '提示',
  115. {
  116. confirmButtonText: '确认',
  117. showClose: false,
  118. closeOnClickModal: false,
  119. closeOnPressEscape: false,
  120. type: 'warning',
  121. customClass: 'init-message',
  122. },
  123. )
  124. }
  125. await commandHandle('move_to_anneal_area', { heatModuleCode: selectedHeatArea.value?.value })
  126. }
  127. const trayInHandle = async () => {
  128. await trayIn()
  129. FtMessage.success('设置放入托盘成功')
  130. }
  131. // const trayOutHandle = async () => {
  132. // await trayOut()
  133. // }
  134. const checkCraftVisible = ref(false)
  135. const moreVisible = ref(false)
  136. const cleanHandle = async () => {
  137. await ElMessageBox.confirm(
  138. '请确认已把托盘放至上料位或移至加液位? ',
  139. '提示',
  140. {
  141. confirmButtonText: '确认',
  142. showClose: false,
  143. closeOnClickModal: false,
  144. closeOnPressEscape: false,
  145. type: 'warning',
  146. customClass: 'init-message',
  147. },
  148. )
  149. cleanVisible.value = true
  150. }
  151. const addLiquidHandle = async () => {
  152. await ElMessageBox.confirm(
  153. '请确认已把托盘放至上料位或移至加液位? ',
  154. '提示',
  155. {
  156. confirmButtonText: '确认',
  157. showClose: false,
  158. closeOnClickModal: false,
  159. closeOnPressEscape: false,
  160. type: 'warning',
  161. customClass: 'init-message',
  162. },
  163. )
  164. addLiquidVisible.value = true
  165. }
  166. const extractLiquidHandle = async () => {
  167. await ElMessageBox.confirm(
  168. '请确认已把托盘放至上料位或移至加液位? ',
  169. '提示',
  170. {
  171. confirmButtonText: '确认',
  172. showClose: false,
  173. closeOnClickModal: false,
  174. closeOnPressEscape: false,
  175. type: 'warning',
  176. customClass: 'init-message',
  177. },
  178. )
  179. extractLiquidVisible.value = true
  180. }
  181. </script>
  182. <template>
  183. <div class="home-page">
  184. <div class="page-top">
  185. <Tube
  186. v-for="(item, index) in systemStore.systemStatus.heatModule"
  187. :key="item.moduleCode"
  188. :data="item"
  189. @select-change="homeStore.selectChange(index)"
  190. @set-temperature="setTemperature(item)"
  191. />
  192. </div>
  193. <div class="button-box">
  194. <el-row style="width: 100%; height: 100%" :gutter="20">
  195. <el-col :span="24">
  196. <div style="padding: 30px 0;display: grid; gap: 20px; grid-template-columns: repeat(4, 1fr);grid-template-rows: repeat(1, 1fr);height: 100%">
  197. <el-card>
  198. <ft-button type="primary" size="large" :disabled="!systemStore.systemStatus.doorModule.actionable" :click-handle="() => commandHandle('door_open')">
  199. 开门
  200. </ft-button>
  201. <ft-button type="primary" size="large" :disabled="systemStore.systemStatus.doorModule.actionable" :click-handle="() => commandHandle('door_close')">
  202. 关门
  203. </ft-button>
  204. </el-card>
  205. <el-card>
  206. <ft-button type="primary" size="large" :click-handle="trayInHandle">
  207. 放入托盘
  208. </ft-button>
  209. <ft-button type="primary" size="large" :click-handle="() => commandHandle('out_tray', { heatModuleCode: selectedHeatArea!.value })" :disabled="!selectedHeatArea">
  210. 取出托盘
  211. </ft-button>
  212. </el-card>
  213. <el-card>
  214. <ft-button type="primary" style="margin: auto 0;" class="manual-button" size="large" :click-handle="executeCraftHandle">
  215. 执行工艺
  216. </ft-button>
  217. <!-- <ft-button type="primary" size="large" :click-handle="() => checkCraftVisible = true"> -->
  218. <!-- <el-icon v-if="systemStore.errorCraft" color="#DF1515" size="15" style="margin-right: 5px"> -->
  219. <!-- <WarningFilled /> -->
  220. <!-- </el-icon> -->
  221. <!-- 异常工艺 -->
  222. <!-- </ft-button> -->
  223. </el-card>
  224. <el-card>
  225. <el-popover
  226. :visible="moreVisible"
  227. placement="left-start"
  228. width="auto"
  229. trigger="click"
  230. popper-class="button-popper"
  231. >
  232. <template #reference>
  233. <ft-button type="primary" size="large" style="margin: auto 0;" class="manual-button" @click="moreVisible = !moreVisible">
  234. 手动操作
  235. </ft-button>
  236. </template>
  237. <template #default>
  238. <div class="container-box">
  239. <ft-button type="primary" size="large" :disabled="!selectedHeatArea" :click-handle="() => commandHandle('heater_start', { heatModuleCode: selectedHeatArea!.value })">
  240. 开始加热
  241. </ft-button>
  242. <ft-button type="primary" size="large" :disabled="!selectedHeatArea || selectedHeatArea?.label === '退火区'" :click-handle="() => commandHandle('dry_start', { heatModuleCode: selectedHeatArea!.value })">
  243. 开始烘干
  244. </ft-button>
  245. <ft-button type="primary" size="large" :disabled="!selectedHeatArea || selectedHeatArea?.label !== '退火区'" :click-handle="() => commandHandle('anneal_start', { heatModuleCode: selectedHeatArea!.value })">
  246. 开始退火
  247. </ft-button>
  248. <ft-button type="primary" size="large" :disabled="!selectedHeatArea" :click-handle="() => commandHandle('heater_stop', { heatModuleCode: selectedHeatArea!.value })">
  249. 停止加热
  250. </ft-button>
  251. <ft-button type="primary" size="large" :disabled="!selectedHeatArea" :click-handle="() => commandHandle('fan_start', { heatModuleCode: selectedHeatArea!.value })">
  252. 开始降温
  253. </ft-button>
  254. <ft-button type="primary" size="large" :disabled="!selectedHeatArea" :click-handle="() => commandHandle('fan_stop', { heatModuleCode: selectedHeatArea!.value })">
  255. 停止降温
  256. </ft-button>
  257. <ft-button type="primary" size="large" :click-handle="() => commandHandle('move_to_heat_area', { heatModuleCode: selectedHeatArea!.value })" :disabled="!selectedHeatArea">
  258. 移至加热位
  259. </ft-button>
  260. <ft-button type="primary" size="large" :click-handle="move_to_liquid_area">
  261. 移至加液位
  262. </ft-button>
  263. <ft-button type="primary" size="large" :click-handle="move_to_feed_area">
  264. 移至上料区
  265. </ft-button>
  266. <ft-button type="primary" size="large" :click-handle="move_to_anneal_area">
  267. 移至退火位
  268. </ft-button>
  269. <ft-button type="primary" size="large" @click="cleanHandle">
  270. 开始清洗
  271. </ft-button>
  272. <ft-button type="primary" size="large" @click=" fillSolutionVisible = true">
  273. 预充管路
  274. </ft-button>
  275. <ft-button type="primary" size="large" @click="addLiquidHandle">
  276. 添加溶液
  277. </ft-button>
  278. <ft-button type="primary" size="large" @click="extractLiquidHandle">
  279. 抽取溶液
  280. </ft-button>
  281. <ft-button type="primary" size="large" :click-handle="() => commandHandle('drain_liquid')">
  282. 关机排空
  283. </ft-button>
  284. <ft-button type="primary" size="large" :click-handle="() => commandHandle('liquid_motor_origin')">
  285. 加液臂回原点
  286. </ft-button>
  287. <ft-button type="primary" size="large" :click-handle="() => commandHandle('z_origin')">
  288. z轴回原点
  289. </ft-button>
  290. <ft-button type="primary" size="large" :click-handle="() => commandHandle('x_origin')">
  291. x轴回原点
  292. </ft-button>
  293. </div>
  294. </template>
  295. </el-popover>
  296. </el-card>
  297. </div>
  298. </el-col>
  299. </el-row>
  300. </div>
  301. <CheckCraft v-if="checkCraftVisible" @close="checkCraftVisible = false" />
  302. <StartExperiment v-if="startVisible" @ok="startVisible = false" @cancel="startVisible = false" />
  303. <StartClean v-if="cleanVisible" @ok="cleanVisible = false" @cancel="cleanVisible = false" />
  304. <ExecuteCraft v-if="selectCraftVisible" @ok="selectCraftVisible = false" @cancel="selectCraftVisible = false" />
  305. <SetTemperature v-if="setTemperatureVisible" @ok="setTemperatureVisible = false" @cancel="setTemperatureVisible = false" />
  306. <AddLiquid v-if="addLiquidVisible" @ok="addLiquidVisible = false" @cancel="addLiquidVisible = false" />
  307. <ExtractLiquid v-if="extractLiquidVisible" @ok="extractLiquidVisible = false" @cancel="extractLiquidVisible = false" />
  308. <FillSolution v-if="fillSolutionVisible" @ok="fillSolutionVisible = false" @cancel="fillSolutionVisible = false" />
  309. </div>
  310. </template>
  311. <style scoped lang="scss">
  312. .home-page {
  313. .page-top{
  314. height: 65%;
  315. border-radius: 8px;
  316. padding: 0 10px 10px;
  317. display: grid;
  318. grid-template-columns: repeat(4, 1fr); /* 创建3列等宽轨道 */
  319. grid-template-rows: repeat(1, auto); /* 创建2行自动高度 */
  320. gap: 10px;
  321. justify-content: center; /* 水平居中 */
  322. align-items: center;
  323. }
  324. .button-box {
  325. height: 35%;
  326. //display: grid;
  327. //grid-template-columns: repeat(6, 1fr); /* 创建3列等宽轨道 */
  328. //grid-template-rows: repeat(4, 1fr); /* 创建2行自动高度 */
  329. //gap: 10px 20px;
  330. .ft-button {
  331. //width: 100px;
  332. font-weight: bold;
  333. margin-right: 0;
  334. .my-button {
  335. padding: 0 !important;
  336. border: 3px solid #1989fa !important;
  337. }
  338. }
  339. }
  340. }
  341. .el-col {
  342. height: 100%;
  343. }
  344. .manual-box {
  345. width: 100%;
  346. height: 100%;
  347. display: flex;
  348. align-items: center;
  349. justify-content: center;
  350. }
  351. .container-box {
  352. width: 600px;
  353. display: grid;
  354. grid-template-columns: repeat(4, 1fr);
  355. grid-template-rows: repeat(2, 1fr);
  356. gap: 10px;
  357. }
  358. .manual-button {
  359. height: 80px;
  360. line-height: 80px;
  361. text-align: center;
  362. border-radius: 10px;
  363. :deep(.my-button) {
  364. height: 100%;
  365. }
  366. }
  367. :deep(.el-card__body){
  368. width: 100%;
  369. height: 100%;
  370. display: flex;
  371. flex-direction: column;
  372. justify-content: space-between;
  373. .ft-button {
  374. box-shadow: 0 0 25px rgba(0,0,0,0.2);
  375. }
  376. }
  377. </style>