消毒机设备
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.

405 lines
12 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
1 month ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
  1. <script lang="ts" setup>
  2. import homeProbe1 from 'assets/images/home/home-probe1.svg'
  3. import Environment from 'components/home/Environment.vue'
  4. import HomeFormula from 'components/home/HomeFormula.vue'
  5. import HomeOperation from 'components/home/HomeOperation.vue'
  6. import HomeSetting from 'components/home/HomeSetting.vue'
  7. import PressureControl from 'components/home/PressureControl.vue'
  8. import { FtMessageBox } from 'libs/messageBox'
  9. import { useDeviceStore } from 'stores/deviceStore'
  10. import { useGasStore } from 'stores/gasStore'
  11. import { useHomeStore } from 'stores/homeStore'
  12. import { useLiquidStore } from 'stores/liquidStore'
  13. import { computed, onMounted, ref, watchEffect } from 'vue'
  14. import { useRoute } from 'vue-router'
  15. import { roundNumber } from '@/libs/utils'
  16. import { useFormulaStore } from '@/stores/formulaStore'
  17. import { useSystemStore } from '@/stores/systemStore'
  18. const gasStore = useGasStore()
  19. const selectChannel = (channel: string, name: any) => {
  20. FtMessageBox.warning(`请确认打开${name}?`).then(() => {
  21. gasStore.selectChannel(channel)
  22. })
  23. }
  24. const route = useRoute()
  25. const homeStore = useHomeStore()
  26. const deviceStore = useDeviceStore()
  27. const liquidStore = useLiquidStore()
  28. const formulaStore = useFormulaStore()
  29. const systemStore = useSystemStore()
  30. const environmentParams = ref<Home.DisplayrelyMgrParams>(homeStore.h2O2SensorData[0])
  31. const liquidInfo = ref<Liquid.LiquidData>(liquidStore.liquidStateData)
  32. const liquidTotal = ref<number>(liquidStore.liquidTotal)
  33. const formulaInfo = ref()
  34. const loading = ref(false)
  35. onMounted(() => {
  36. watchEffect(() => {
  37. formulaInfo.value = formulaStore.currentSelectedFormulaInfo
  38. liquidTotal.value = liquidStore.liquidTotal
  39. liquidInfo.value = liquidStore.liquidStateData
  40. loading.value = systemStore.loading
  41. if (homeStore.h2O2SensorData && homeStore.h2O2SensorData.length) {
  42. styles.value = computedStyle()
  43. // console.log('homeStore.h2O2SensorData', homeStore.h2O2SensorData)
  44. environmentParams.value = {
  45. ...homeStore.h2O2SensorData[0],
  46. title: '仓内',
  47. type: 'inside',
  48. }
  49. }
  50. })
  51. })
  52. // 当前消毒液余量百分比(最大不超过100)
  53. const nowLiquidProgress = computed(() => {
  54. const now = Number(liquidInfo.value.nowLiquid)
  55. const total = Number(liquidTotal.value)
  56. if (!now || total <= 0) {
  57. return 0
  58. }
  59. // 先算出百分比并四舍五入
  60. const rawPercent = roundNumber((now / total) * 100, 0)
  61. // 如果大于100,就返回100;否则返回原值
  62. return rawPercent > 100 ? 100 : rawPercent
  63. })
  64. // 当前消毒液余量
  65. const nowLiquid = computed(() => {
  66. return roundNumber(liquidInfo.value.nowLiquid, 0)
  67. })
  68. const styles = ref<any>({
  69. gridTemplateColumns: 'repeat(2, 1fr)',
  70. gridTemplateRows: 'repeat(2, 1fr)',
  71. })
  72. const computedStyle = () => {
  73. if (
  74. deviceType.value === deviceStore.deviceTypeMap.PipeDM
  75. || deviceType.value === deviceStore.deviceTypeMap.DrawBarDM
  76. ) {
  77. return {
  78. gridTemplateColumns: 'repeat(3, 1fr)',
  79. gridTemplateRows: 'repeat(2, 1fr)',
  80. }
  81. }
  82. return {
  83. gridTemplateColumns: 'repeat(3, 1fr)',
  84. gridTemplateRows: 'repeat(2, 1fr)',
  85. }
  86. }
  87. const deviceType = computed(() => {
  88. return __DEVICE_TYPE__
  89. })
  90. </script>
  91. <template>
  92. <div class="home">
  93. <div v-if="route.path === '/home'" class="home-grid-container">
  94. <div
  95. class="home-left"
  96. :style="{
  97. 'grid-template-rows': [
  98. deviceStore.deviceTypeMap.DrawBarDM,
  99. deviceStore.deviceTypeMap.LargeSpaceDM_B,
  100. ].includes(deviceType)
  101. ? 'repeat(1, 1fr)'
  102. : 'repeat(2, 1fr)',
  103. }"
  104. >
  105. <div
  106. class="left-box"
  107. :class="{
  108. 'left-box-1': [deviceStore.deviceTypeMap.DrawBarDM].includes(deviceType),
  109. }"
  110. >
  111. <el-card
  112. v-for="item in homeStore.h2O2SensorData
  113. .filter(item =>
  114. [deviceStore.deviceTypeMap.DrawBarDM, deviceStore.deviceTypeMap.LargeSpaceDM_B].includes(deviceType)
  115. ? item.type === 'Internal'
  116. : item.type !== 'WirelessExtSensor',
  117. )
  118. .concat(
  119. [deviceStore.deviceTypeMap.LargeSpaceDM_B].includes(deviceType)
  120. ? homeStore.h2O2SensorData
  121. .filter(item => item.type === 'WirelessExtSensor')
  122. .filter((item, index) => index < 2)
  123. : [],
  124. )"
  125. :key="item.sensorId"
  126. class="card"
  127. :class="{
  128. 'card-one': [deviceStore.deviceTypeMap.PipeDM].includes(deviceType),
  129. 'card-two': [deviceStore.deviceTypeMap.DrawBarDM].includes(deviceType),
  130. }"
  131. >
  132. <Environment :env-params="item" />
  133. </el-card>
  134. <el-card v-if="deviceStore.deviceTypeMap.DrawBarDM === deviceType" class="card card-three">
  135. <div class="box">
  136. <div class="title">
  137. <div style="width: 100%; display: flex; align-items: center">
  138. <img :src="homeProbe1" alt="" style="margin-right: 10px">气路控制
  139. </div>
  140. <el-tag v-if="!gasStore.isOnline" type="danger">
  141. 离线
  142. </el-tag>
  143. </div>
  144. <h4 style="text-align: center">
  145. 当前通道{{
  146. gasStore.currentChannel === gasStore.channelSwitcherMap[0]
  147. ? '降解通道'
  148. : gasStore.currentChannel === gasStore.channelSwitcherMap[1]
  149. ? '消毒通道'
  150. : '除湿通道'
  151. }}
  152. </h4>
  153. <div class="btn-box">
  154. <el-button
  155. size="large"
  156. :type="gasStore.currentChannel === gasStore.channelSwitcherMap[0] ? 'info' : 'primary'"
  157. :disabled="!gasStore.isOnline || gasStore.currentChannel === gasStore.channelSwitcherMap[0]"
  158. @click="() => selectChannel(gasStore.channelSwitcherMap[0], '降解通道')"
  159. >
  160. 降解通道
  161. </el-button>
  162. <el-button
  163. size="large"
  164. :type="gasStore.currentChannel === gasStore.channelSwitcherMap[1] ? 'info' : 'primary'"
  165. :disabled="!gasStore.isOnline || gasStore.currentChannel === gasStore.channelSwitcherMap[1]"
  166. @click="() => selectChannel(gasStore.channelSwitcherMap[1], '消毒通道')"
  167. >
  168. 消毒通道
  169. </el-button>
  170. <el-button
  171. size="large"
  172. :type="gasStore.currentChannel === gasStore.channelSwitcherMap[2] ? 'info' : 'primary'"
  173. :disabled="!gasStore.isOnline || gasStore.currentChannel === gasStore.channelSwitcherMap[2]"
  174. @click="() => selectChannel(gasStore.channelSwitcherMap[2], '除湿通道')"
  175. >
  176. 除湿通道
  177. </el-button>
  178. </div>
  179. </div>
  180. </el-card>
  181. </div>
  182. <div v-if="deviceType !== deviceStore.deviceTypeMap.DrawBarDM" class="left-box">
  183. <el-card
  184. v-for="item in homeStore.h2O2SensorData.filter(item => item.type === 'WirelessExtSensor')"
  185. :key="item.sensorId"
  186. class="card"
  187. >
  188. <Environment :env-params="item" />
  189. </el-card>
  190. </div>
  191. </div>
  192. <div class="home-grid-item home-right">
  193. <!-- 正在进行的配方 -->
  194. <div class="top">
  195. <HomeFormula />
  196. <div
  197. v-if="![deviceStore.deviceTypeMap.LargeSpaceDM_B, deviceStore.deviceTypeMap.DrawBarDM].includes(deviceType)"
  198. style="margin-top: 60px"
  199. >
  200. <div class="card-progress">
  201. <!-- <div class="card-title-name"> -->
  202. <!-- <img :src="homeLiquid"> -->
  203. <!-- </div> -->
  204. <div class="card-progress-content">
  205. <el-progress size="small" :text-inside="true" :stroke-width="40" :percentage="nowLiquidProgress" />
  206. </div>
  207. </div>
  208. <div class="card-num-g">
  209. 消毒液剩余:{{ nowLiquid || 0 }}g
  210. </div>
  211. </div>
  212. </div>
  213. <div class="middle">
  214. <!-- 选择消毒的等级 -->
  215. <!-- <HomeLogLevel v-if="!formulaStore.selectedFormulaInfo?.name" /> -->
  216. <!-- 开始消毒停止消毒及状态区 -->
  217. <HomeOperation />
  218. </div>
  219. <!-- 消毒设置 -->
  220. <div
  221. class="bottom"
  222. :style="{
  223. justifyContent: deviceType === deviceStore.deviceTypeMap.PipeDM ? 'space-between' : 'space-evenly',
  224. }"
  225. >
  226. <PressureControl />
  227. <HomeSetting />
  228. </div>
  229. </div>
  230. </div>
  231. <router-view v-else />
  232. </div>
  233. </template>
  234. <style lang="scss" scoped>
  235. .bottom {
  236. display: flex;
  237. }
  238. $input-height: 3rem;
  239. .home {
  240. width: 100%;
  241. height: 100%;
  242. }
  243. .home-grid-container .home-left .left-box-1 {
  244. flex-direction: column !important;
  245. .card {
  246. height: calc(50% - 5px) !important;
  247. width: 100% !important;
  248. }
  249. }
  250. .home-grid-container {
  251. height: 100%;
  252. width: 100%;
  253. display: grid;
  254. grid-template-columns: 2fr 1fr;
  255. gap: 10px;
  256. }
  257. .home-left {
  258. height: 100%;
  259. width: 100%;
  260. display: grid;
  261. //grid-template-rows: repeat(2, 1fr);
  262. grid-template-columns: repeat(1, 1fr);
  263. gap: 20px;
  264. .left-box {
  265. display: flex; // 使用 Flexbox 布局
  266. flex-direction: row; // 子元素水平排列(默认值)
  267. align-items: flex-start; // 子元素顶部对齐
  268. overflow-x: auto; // 横向滚动支持
  269. width: 100%; // 父容器宽度占满
  270. gap: 10px; // 子元素之间的间距(可选)
  271. .card-one {
  272. width: 100% !important;
  273. }
  274. .card-two {
  275. width: calc((100% / 3) * 2 - 10px) !important;
  276. }
  277. .card-three {
  278. width: calc(100% / 3 - 10px) !important;
  279. }
  280. .card {
  281. flex: 0 0 auto;
  282. width: calc(100% / 3 - 10px);
  283. height: 100%;
  284. min-width: 200px;
  285. border: 1px solid rgb(225, 225, 225);
  286. border-radius: 10px;
  287. background: rgba(147, 203, 255, 0.1);
  288. box-shadow: 0 0 8px rgba(0, 0, 0, 0.1);
  289. .title-line {
  290. height: 1vw;
  291. background-color: #b3d9ff;
  292. position: absolute;
  293. width: 100%;
  294. border-radius: 10px 10px 0 0;
  295. margin: -2.12rem;
  296. }
  297. .card-title-name {
  298. display: flex;
  299. align-items: center;
  300. gap: 10px;
  301. font-size: 20px;
  302. padding: 1rem;
  303. }
  304. }
  305. }
  306. }
  307. .home-right {
  308. padding: 10px;
  309. background: linear-gradient(180deg, rgba(147, 203, 255, 1) -190%, #ffffff 24%);
  310. background: rgba(147, 203, 255, 0.1);
  311. border-radius: 10px;
  312. box-shadow: 0 1px 5px 0 rgba(9, 39, 62, 0.15);
  313. display: flex;
  314. flex-direction: column;
  315. justify-content: space-between;
  316. }
  317. .middle {
  318. display: flex;
  319. flex-direction: column;
  320. gap: 5px;
  321. padding: 5px 0;
  322. }
  323. .el-button {
  324. /* background-color: #2892f3 !important;*/
  325. }
  326. .card-center-1 {
  327. grid-column: 1 / -1; // 占据整行
  328. justify-self: center; // 横向居中
  329. }
  330. .card-center-2 {
  331. grid-column: 1 / 3; // 占据整行
  332. justify-self: center; // 横向居中
  333. }
  334. :deep(.el-card__body) {
  335. height: 100%;
  336. }
  337. .card-progress {
  338. margin-top: 10px;
  339. padding: 0 10px;
  340. display: flex;
  341. justify-content: center;
  342. align-items: center;
  343. .card-title-name {
  344. margin-right: 10px;
  345. }
  346. .card-progress-content {
  347. width: 100%;
  348. }
  349. }
  350. .card-num-g {
  351. text-align: center;
  352. font-size: 15px;
  353. color: #3f4349;
  354. font-weight: bold;
  355. margin-top: 10px;
  356. }
  357. .title {
  358. display: flex;
  359. align-items: center;
  360. justify-content: space-between;
  361. gap: 10px;
  362. font-size: 18px;
  363. padding: 10px;
  364. }
  365. .box {
  366. height: 100%;
  367. display: flex;
  368. flex-direction: column;
  369. justify-content: space-between;
  370. padding: 10px 0;
  371. }
  372. .btn-box {
  373. flex: 1;
  374. display: flex;
  375. flex-direction: row;
  376. justify-content: center;
  377. align-items: center;
  378. gap: 20px;
  379. .el-button {
  380. margin: 0;
  381. }
  382. }
  383. </style>