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

304 lines
8.1 KiB

4 weeks ago
2 months ago
2 months ago
2 months ago
1 month ago
2 weeks ago
2 months ago
2 months ago
2 months ago
4 weeks ago
4 weeks ago
3 weeks ago
3 weeks ago
4 weeks ago
4 weeks ago
2 weeks ago
2 weeks ago
4 weeks ago
2 months ago
2 months ago
1 month ago
  1. <script lang="ts" setup>
  2. import { syncSendCmd } from 'apis/system'
  3. import BtButton from 'components/common/BTButton/index.vue'
  4. import CascadingSelectModal from 'components/common/CascadingSelectModal/index.vue'
  5. import RunFormulaConfig from 'components/formula/RunFormulaConfig.vue'
  6. import Config from 'components/home/config.vue'
  7. import { compareJSON } from 'libs/utils'
  8. import { cloneDeep } from 'lodash'
  9. import { computed, onMounted, provide, ref, watchEffect } from 'vue'
  10. import { useRouter } from 'vue-router'
  11. import { FtMessage } from '@/libs/message'
  12. import { useDeviceStore } from '@/stores/deviceStore'
  13. import { useFormulaStore } from '@/stores/formulaStore'
  14. import { useHomeStore } from '@/stores/homeStore'
  15. /**
  16. * 主页操作控制组件
  17. * @description 负责处理压力控制消毒设置图表导航等功能协调组件间通信
  18. */
  19. // 依赖注入
  20. const runtimeRef = ref()
  21. provide<(methods: Home.GrandsonMethods) => void>('registerGrandsonMethods', (methods) => {
  22. runtimeRef.value = methods
  23. })
  24. // 状态管理
  25. const router = useRouter()
  26. const formulaStore = useFormulaStore()
  27. const deviceStore = useDeviceStore()
  28. const homeStore = useHomeStore()
  29. // 组件状态
  30. const isModalOpen = ref(false) // 级联选择模态框是否打开
  31. const optionsLeft = ref<System.Option[]>([]) // 压力类型选项(左列)
  32. const optionsRight = ref<System.Option[]>([]) // 压力强度选项(右列)
  33. const selectedValue = ref() // 选中的压力配置值
  34. const disinfectionState = ref(homeStore.disinfectionState) // 消毒状态
  35. const disinfectConfigVisible = ref(false) // 消毒设置对话框是否显示
  36. const disinfectRuntimeVisible = ref(false)
  37. const selectedByFormulas = ref(cloneDeep(formulaStore.selectedFormulaInfo)) // 当前选中的配方信息
  38. const pressureConfig = ref(homeStore.pressureConfig)
  39. const defaultIntensityValue = ref()
  40. /**
  41. * @hook 响应式依赖监听
  42. * @description 监听消毒状态和配方变化同步更新组件状态
  43. */
  44. watchEffect(() => {
  45. disinfectionState.value = homeStore.disinfectionState
  46. selectedByFormulas.value = formulaStore.selectedFormulaInfo
  47. pressureConfig.value = homeStore.pressureConfig
  48. })
  49. /**
  50. * @hook 生命周期钩子 - 组件挂载完成时执行
  51. * @description 初始化压力配置
  52. */
  53. onMounted(async () => {
  54. if (__DEVICE_TYPE__ !== useDeviceStore().deviceTypeMap.LargeSpaceDM_B) {
  55. await getPressureConfig() // 获取压力配置
  56. }
  57. })
  58. /**
  59. * @function getPressureConfig
  60. * @desc 获取当前压力配置信息
  61. */
  62. const getPressureConfig = async () => {
  63. const pressureParams = {
  64. className: 'PipelinePressureControl',
  65. fnName: 'getConfig',
  66. }
  67. const res = await syncSendCmd(pressureParams)
  68. if (res.ackcode === 0) {
  69. homeStore.updatePressureConfig(res.rely)
  70. }
  71. }
  72. /**
  73. * @computed 计算属性 - 设备状态判断
  74. * @returns {boolean} - 设备是否处于空闲或已完成状态
  75. * @desc 控制按钮可用状态
  76. */
  77. const deviceState = computed(() => {
  78. return disinfectionState.value.state === 'idle' || disinfectionState.value.state === 'finished'
  79. })
  80. /**
  81. * @function 打开消毒设置对话框
  82. * @desc 根据当前选中配方或默认配方初始化设置
  83. */
  84. const onDisinfectConfig = () => {
  85. formulaStore.updateSelectedFormula(selectedByFormulas.value || cloneDeep(formulaStore.defaultFormulaInfo))
  86. disinfectConfigVisible.value = true
  87. }
  88. const onDisinfectRuntime = () => {
  89. disinfectRuntimeVisible.value = true
  90. }
  91. /**
  92. * @function 导航到图表页面
  93. * @desc 路由跳转至消毒图表页面
  94. */
  95. const onShowChart = () => {
  96. router.push('/home/chart')
  97. }
  98. /**
  99. * @function 保存消毒运行参数
  100. * @desc 处理表单数据保存逻辑区分消毒中与非消毒状态
  101. */
  102. const onSave = async () => {
  103. const formData = await runtimeRef.value?.saveFormData()
  104. if (!formData) {
  105. return
  106. }
  107. // 消毒中更新实时配置
  108. const res = await formulaStore.getRealtimeConfig()
  109. const diff = compareJSON(res.rely, formData)
  110. const diffKeys = Object.keys(diff)
  111. if (diffKeys.length) {
  112. await Promise.all(
  113. diffKeys.map(async (key) => {
  114. await formulaStore.setRealtimeConfig(key, diff[key].newVal)
  115. }),
  116. )
  117. FtMessage.success('设定成功')
  118. homeStore.setRate(formData.injection_pump_speed)
  119. }
  120. }
  121. /**
  122. * @function 确认压力选择
  123. * @param {string|number[]} value - 选中的压力配置值[类型, 强度]
  124. * @desc 关闭模态框并更新压力配置
  125. */
  126. const handleConfirm = (value: string | number[]) => {
  127. isModalOpen.value = false
  128. homeStore.updatePressure(value)
  129. }
  130. /**
  131. * @function 取消压力选择
  132. * @desc 关闭模态框
  133. */
  134. const handleCancel = () => {
  135. isModalOpen.value = false
  136. }
  137. /**
  138. * @function 关闭消毒设置对话框
  139. * @desc 重置对话框状态
  140. */
  141. const onCloseConfig = () => {
  142. disinfectConfigVisible.value = false
  143. }
  144. const onCloseRuntime = () => {
  145. disinfectRuntimeVisible.value = false
  146. }
  147. const settingWidth = computed(() => {
  148. if (__DEVICE_TYPE__ === deviceStore.deviceTypeMap.LargeSpaceDM_B) {
  149. return '12rem'
  150. }
  151. return '7.5rem'
  152. })
  153. </script>
  154. <template>
  155. <div class="home-start-opt">
  156. <div class="home-opt-flex">
  157. <div class="home-opt-ml">
  158. <BtButton
  159. button-text="查看图表"
  160. text-size="1.3rem"
  161. border-radius="5px"
  162. :width="settingWidth"
  163. height="3rem"
  164. text-color="#1989fa"
  165. :disabled="deviceState"
  166. @click="onShowChart"
  167. />
  168. </div>
  169. <div class="home-opt-ml">
  170. <BtButton
  171. v-if="deviceState"
  172. button-text="消毒设置"
  173. text-size="1.3rem"
  174. border-radius="5px"
  175. :width="settingWidth"
  176. text-color="#1989fa"
  177. height="3rem"
  178. @click="onDisinfectConfig()"
  179. />
  180. <BtButton
  181. v-else
  182. button-text="运行参数"
  183. text-size="1.3rem"
  184. border-radius="5px"
  185. :width="settingWidth"
  186. text-color="#1989fa"
  187. height="3rem"
  188. @click="onDisinfectRuntime()"
  189. />
  190. </div>
  191. </div>
  192. </div>
  193. <!-- 消毒设置 -->
  194. <ft-dialog v-model="disinfectConfigVisible" title="消毒设置" width="80vw">
  195. <div style="height: 80vh; overflow: auto">
  196. <Config />
  197. </div>
  198. <template #footer>
  199. <div class="config-btn">
  200. <BtButton
  201. button-text="关闭"
  202. border-radius="5px"
  203. width="7rem"
  204. text-size="1.5rem"
  205. text-color="#1989fa"
  206. height="3rem"
  207. @click="onCloseConfig"
  208. />
  209. </div>
  210. </template>
  211. </ft-dialog>
  212. <!-- 运行参数 -->
  213. <ft-dialog v-model="disinfectRuntimeVisible" title="运行参数" width="80vw">
  214. <div class="main-content">
  215. <div class="formula-config">
  216. <RunFormulaConfig ref="runtimeRef" />
  217. </div>
  218. </div>
  219. <template #footer>
  220. <div class="config-btn">
  221. <BtButton
  222. button-text="关闭"
  223. border-radius="5px"
  224. width="7rem"
  225. text-size="1.5rem"
  226. text-color="#1989fa"
  227. height="3rem"
  228. @click="onCloseRuntime"
  229. />
  230. <BtButton
  231. v-if="!deviceState"
  232. bg-color="#1989fa"
  233. button-text="确认"
  234. border-radius="5px"
  235. width="7rem"
  236. text-size="1.5rem"
  237. text-color="#ffffff"
  238. height="3rem"
  239. @click="onSave"
  240. />
  241. </div>
  242. </template>
  243. </ft-dialog>
  244. <CascadingSelectModal
  245. v-if="isModalOpen"
  246. :options-left="optionsLeft"
  247. :options="optionsRight"
  248. :selected-value="selectedValue"
  249. :default-value="defaultIntensityValue"
  250. placeholder="请选择"
  251. @confirm="handleConfirm"
  252. @cancel="handleCancel"
  253. />
  254. </template>
  255. <style lang="scss" scoped>
  256. .main-content {
  257. overflow: hidden;
  258. //height: auto;
  259. //background: $gradient-color;
  260. padding: 15px;
  261. .formula-config {
  262. display: grid;
  263. padding: 10px;
  264. width: 100%;
  265. }
  266. .formula-config-form {
  267. display: grid;
  268. grid-template-columns: 1fr 1fr;
  269. gap: 5px;
  270. }
  271. .formdata-input {
  272. width: 10vw;
  273. }
  274. }
  275. .home-start-opt {
  276. margin: 0.5rem;
  277. }
  278. .home-opt-flex {
  279. display: flex;
  280. justify-content: center;
  281. align-items: center;
  282. gap: 1rem;
  283. }
  284. .home-opt-ml {
  285. margin-left: 0;
  286. }
  287. .config {
  288. border: 1px solid red;
  289. }
  290. </style>