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.

347 lines
9.8 KiB

5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
  1. <script setup lang="ts">
  2. import { getDeviceStatus } from 'apis/system'
  3. import FtStream from 'components/common/FTStream/index.vue'
  4. import Check from 'components/home/Check/index.vue'
  5. import Stop from 'components/home/Stop/index.vue'
  6. import { ElMessageBox } from 'element-plus'
  7. import { FtMessage } from 'libs/message'
  8. import { isClose, socket } from 'libs/socket'
  9. import { sendControl } from 'libs/utils'
  10. import { useSystemStore } from 'stores/useSystemStore' // 引入 systemStore
  11. import { computed, ref, watch } from 'vue'
  12. import { useRoute, useRouter } from 'vue-router'
  13. const route = useRoute()
  14. const router = useRouter()
  15. const systemStore = useSystemStore() // 使用 systemStore
  16. const checkVisible = ref(false)
  17. console.log(import.meta.env.FT_NODE_ENV)
  18. const cancel = () => {
  19. checkVisible.value = false
  20. }
  21. const getStatus = async () => {
  22. await getDeviceStatus().then((res: any) => {
  23. systemStore.updateSystemStatus(res)
  24. if (!systemStore.systemStatus.selfTestCompleted && import.meta.env.FT_NODE_ENV !== 'test') {
  25. ElMessageBox.confirm('检测到您还未完成自检,是否开始自检?', '提示', {
  26. type: 'warning',
  27. confirmButtonText: '确定',
  28. showCancelButton: false,
  29. showClose: false,
  30. closeOnClickModal: false,
  31. closeOnPressEscape: false,
  32. closeOnHashChange: false,
  33. }).then(() => {
  34. checkVisible.value = true
  35. })
  36. }
  37. })
  38. }
  39. // getStatus()
  40. const ok = () => {
  41. checkVisible.value = false
  42. }
  43. const statusMessage = (data: any) => {
  44. // 更新 systemStore 的 systemStatus
  45. console.log(data)
  46. const stopPressed = systemStore.systemStatus.stopPressed
  47. if (stopPressed !== data.stopPressed && data.stopPressed === false) {
  48. getStatus()
  49. }
  50. console.log(data)
  51. systemStore.updateSystemStatus(data)
  52. }
  53. const sensorMessage = async (data: any) => {
  54. // 更新 systemStore 的 systemInfo
  55. systemStore.updateSystemSensor(data)
  56. if (systemStore.systemStatus.dehumidifierRunning && systemStore.systemSensor.humidity <= systemStore.targetHumidity) {
  57. const params = {
  58. cmdCode: 'dehumidifier_stop',
  59. cmdId: '',
  60. }
  61. await sendControl(params)
  62. FtMessage.success('当前湿度已达目标湿度,除湿已完成')
  63. }
  64. if (systemStore.systemStatus.slidePlatHeating && systemStore.systemSensor.slideTemperature >= systemStore.targetSlideTemperature) {
  65. const params = {
  66. cmdCode: 'slide_plat_heat_stop',
  67. cmdId: '',
  68. }
  69. await sendControl(params)
  70. FtMessage.success('当前温度已达目标温度,加热已完成')
  71. }
  72. if (systemStore.systemStatus.nozzleHeating && systemStore.systemSensor.nozzleTemperature <= systemStore.targetNozzleTemperature) {
  73. const params = {
  74. cmdCode: 'nozzle_heat_stop',
  75. cmdId: '',
  76. }
  77. await sendControl(params)
  78. FtMessage.success('当前温度已达目标温度,加热已完成')
  79. }
  80. }
  81. socket.init(statusMessage, 'device_status_change')
  82. socket.init(sensorMessage, 'sensor')
  83. socket.init(() => {}, 'pong')
  84. const ingObj = {
  85. idle: '空闲',
  86. spraying: '正在喷涂中',
  87. paused: '喷涂暂停中',
  88. cleaningSyringePipeline: '正在清洗注射器管路',
  89. cleaningNozzlePipeline: '正在清洗喷嘴管路',
  90. prefilling: '正在预充中',
  91. dehumidifierRunning: '正在除湿中',
  92. stopPressed: '急停中',
  93. virtual: '虚拟模式',
  94. nozzleHeating: '喷嘴加热中',
  95. slidePlatHeating: '玻片加热中',
  96. }
  97. const status = computed(() => {
  98. const keys = Object.keys(systemStore.systemStatus).filter((key) => {
  99. return !['suspendable', 'selfTestCompleted'].includes(key)
  100. })
  101. let str = ''
  102. console.log(keys)
  103. keys.forEach((key) => {
  104. if (systemStore.systemStatus[key as keyof typeof systemStore.systemStatus]) {
  105. str += `${ingObj[key as keyof typeof ingObj]} | `
  106. }
  107. })
  108. console.log(str)
  109. if (str === '') {
  110. return '空闲'
  111. }
  112. else {
  113. return str.slice(0, -2)
  114. }
  115. })
  116. const logoClickCount = ref(0)
  117. let clickTimeout: NodeJS.Timeout | null = null
  118. const handleLogoClick = () => {
  119. if (clickTimeout) {
  120. clearTimeout(clickTimeout)
  121. }
  122. logoClickCount.value++
  123. if (logoClickCount.value === 10) {
  124. systemStore.updateDebug()
  125. logoClickCount.value = 0 // 重置计数器
  126. }
  127. clickTimeout = setTimeout(() => {
  128. logoClickCount.value = 0 // 重置计数器
  129. }, 1000)
  130. }
  131. // const slideTrayIn = async () => {
  132. // const params = {
  133. // cmdCode: 'slide_tray_in',
  134. // cmdId: '',
  135. // }
  136. // await sendControl(params)
  137. // }
  138. //
  139. // const slideTrayOut = async () => {
  140. // const params = {
  141. // cmdCode: 'slide_tray_out',
  142. // cmdId: '',
  143. // }
  144. // await sendControl(params)
  145. // }
  146. watch(() => isClose.value, async (newValue) => {
  147. if (!newValue) {
  148. await getStatus()
  149. if (systemStore.systemStatus.spraying && router.currentRoute.value.path !== '/spray') {
  150. ElMessageBox.confirm('检测到您有正在喷涂的任务,是否进入喷涂?', '提示', {
  151. type: 'warning',
  152. confirmButtonText: '确定',
  153. cancelButtonText: '取消',
  154. showCancelButton: true,
  155. showClose: false,
  156. closeOnClickModal: false,
  157. closeOnPressEscape: false,
  158. closeOnHashChange: false,
  159. }).then(() => {
  160. router.push('/spray')
  161. })
  162. }
  163. }
  164. })
  165. const slideSwitch = async () => {
  166. if (systemStore.systemStatus.slidePlatHeating) {
  167. ElMessageBox.confirm('确认关闭喷头加热?', '提示', {
  168. type: 'warning',
  169. confirmButtonText: '确定',
  170. cancelButtonText: '取消',
  171. showCancelButton: true,
  172. showClose: false,
  173. closeOnClickModal: false,
  174. closeOnPressEscape: false,
  175. closeOnHashChange: false,
  176. }).then(async () => {
  177. const params = {
  178. cmdCode: 'slide_plat_heat_stop',
  179. cmdId: '',
  180. }
  181. await sendControl(params)
  182. FtMessage.success('已关闭载台加热')
  183. })
  184. }
  185. else {
  186. FtMessage.success('载台加热已关闭')
  187. }
  188. }
  189. const nozzleSwitch = async () => {
  190. if (systemStore.systemStatus.nozzleHeating) {
  191. ElMessageBox.confirm('确认关闭喷头加热?', '提示', {
  192. type: 'warning',
  193. confirmButtonText: '确定',
  194. cancelButtonText: '取消',
  195. showCancelButton: true,
  196. showClose: false,
  197. closeOnClickModal: false,
  198. closeOnPressEscape: false,
  199. closeOnHashChange: false,
  200. }).then(async () => {
  201. const params = {
  202. cmdCode: 'nozzle_heat_stop',
  203. cmdId: '',
  204. }
  205. await sendControl(params)
  206. FtMessage.success('已关闭喷头加热')
  207. })
  208. }
  209. else {
  210. FtMessage.success('喷头加热已经关闭')
  211. }
  212. }
  213. </script>
  214. <template>
  215. <el-container>
  216. <el-header>
  217. <div class="logo" @click="handleLogoClick">
  218. <div style="display: flex;align-items: center">
  219. <img src="@/assets/images/logo.svg" alt="">
  220. </div>
  221. <div v-if="route.path !== '/'">
  222. <el-divider direction="vertical" />
  223. <span class="router-name">{{ route.meta.tagName }}</span>
  224. </div>
  225. </div>
  226. <div style="display: flex">
  227. <img v-show="!isClose" class="wifi-icon" src="../../assets/images/icon_wifi.svg" alt="">
  228. <img v-show="isClose" class="wifi-icon" src="../../assets/images/icon_wifi_red.svg" alt="">
  229. <ft-button v-if="systemStore.isDebug" @click="router.push('/debug')">
  230. 调试
  231. </ft-button>
  232. <ft-button v-if="route.path !== '/'" @click="router.push('/')">
  233. 返回
  234. </ft-button>
  235. </div>
  236. </el-header>
  237. <el-main>
  238. <router-view v-slot="{ Component }" class="main-container">
  239. <Transition mode="out-in">
  240. <component :is="Component" :key="route.fullPath" />
  241. </Transition>
  242. </router-view>
  243. </el-main>
  244. <el-footer>
  245. <div>
  246. <ft-button type="info">
  247. 当前湿度: {{ systemStore.systemSensor.humidity }}%RH
  248. </ft-button>
  249. </div>
  250. <div>
  251. <ft-button type="info" :click-handle="nozzleSwitch">
  252. <img v-if="systemStore.systemStatus.nozzleHeating" src="../../assets/images/entry/heat_icon.svg" alt="" width="20px">
  253. 喷头温度: {{ systemStore.systemSensor.nozzleTemperature }}
  254. </ft-button>
  255. </div>
  256. <div>
  257. <ft-button type="info" :click-handle="slideSwitch">
  258. <img v-if="systemStore.systemStatus.slidePlatHeating" src="../../assets/images/entry/heat_icon.svg" alt="" width="20px">
  259. 载玻台温度: {{ systemStore.systemSensor.slideTemperature }}
  260. </ft-button>
  261. </div>
  262. <div>
  263. <ft-button type="info">
  264. 设备状态: {{ status }}
  265. </ft-button>
  266. </div>
  267. <!-- <div> -->
  268. <!-- <ft-button :click-handle="slideTrayIn" :disabled="systemStore.systemStatus.spraying"> -->
  269. <!-- 推入托盘 -->
  270. <!-- </ft-button> -->
  271. <!-- <ft-button :click-handle="slideTrayOut" :disabled="systemStore.systemStatus.spraying"> -->
  272. <!-- 推出托盘 -->
  273. <!-- </ft-button> -->
  274. <!-- </div> -->
  275. </el-footer>
  276. <FtStream :visible="systemStore.streamVisible" />
  277. <Stop v-if="systemStore.systemStatus.stopPressed" />
  278. <Check v-if="checkVisible" @ok="ok" @cancel="cancel" />
  279. </el-container>
  280. </template>
  281. <style scoped lang="scss">
  282. .el-container {
  283. background: #26509C;
  284. overflow: hidden;
  285. .el-header {
  286. height: 120px;
  287. display: flex;
  288. align-items: center;
  289. justify-content: space-between;
  290. padding:0 65px;
  291. .logo {
  292. margin-left: 35px;
  293. display: flex;
  294. img {
  295. width: 250px;
  296. }
  297. }
  298. .el-divider {
  299. margin: 0 60px;
  300. height: 62px;
  301. }
  302. }
  303. .el-main {
  304. padding:0 65px;
  305. .main-container {
  306. width: 100%;
  307. height: 100%;
  308. background: #EEF3FB;
  309. border-radius: 60px;
  310. padding: 60px;
  311. overflow: auto;
  312. }
  313. }
  314. .el-footer {
  315. padding:0 65px;
  316. height: 120px;
  317. display: flex;
  318. justify-content: space-evenly;
  319. align-items: center;
  320. }
  321. }
  322. .router-name {
  323. font-size: 50px;
  324. color: #fff;
  325. }
  326. .wifi-icon {
  327. width: 50px;
  328. margin: 0 30px;
  329. }
  330. </style>