Browse Source

优化消毒状态

master
LiLongLong 1 month ago
parent
commit
8ef2d8e0c3
  1. 40
      error.md
  2. 1
      src/apis/home.ts
  3. 13
      src/app.vue
  4. 6
      src/components/common/SelectModal/index.vue
  5. 27
      src/components/formula/FormulaConfig.vue
  6. 29
      src/components/formula/FormulaTable.vue
  7. 12
      src/components/home/Environment.vue
  8. 2
      src/components/home/HomeFormula.vue
  9. 18
      src/components/home/HomeLogLevel.vue
  10. 96
      src/components/home/HomeOperation.vue
  11. 75
      src/components/home/HomeSetting.vue
  12. 60
      src/components/home/LineChart.vue
  13. 43
      src/components/home/config.vue
  14. 66
      src/components/setting/AddUser.vue
  15. 37
      src/components/setting/Device.vue
  16. 149
      src/components/setting/ModifyPwd.vue
  17. 68
      src/components/setting/SystemDate.vue
  18. 79
      src/components/setting/User.vue
  19. 60
      src/layouts/default.vue
  20. 42
      src/libs/deviceComm.ts
  21. 3
      src/libs/socket.ts
  22. 68
      src/libs/utils.ts
  23. 151
      src/stores/formulaStore.ts
  24. 146
      src/stores/homeStore.ts
  25. 4
      src/stores/initHomeData.ts
  26. 2
      src/stores/liquidStore.ts
  27. 34
      src/stores/settingStore.ts
  28. 8
      src/types/audit.d.ts
  29. 4
      src/types/formula.d.ts
  30. 19
      src/types/home.d.ts
  31. 14
      src/types/user.d.ts
  32. 53
      src/views/audit/index.vue
  33. 66
      src/views/debug/index.vue
  34. 90
      src/views/home/chart.vue
  35. 21
      src/views/home/index.vue
  36. 92
      src/views/liquid/index.vue
  37. 18
      src/views/seal/index.vue
  38. 6
      src/views/setting/index.vue

40
error.md

@ -0,0 +1,40 @@
tsucc = 0,
ksucc = 0,
kappe_begin = 10000,
kappe_code_error = 10001, // 代码错误
kappe_cmd_not_support = 10003, // 命令不支持
kappe_parse_json_err = 10004, // 解析json错误
kappe_std_exception = 10005, // 标准库异常
kappe_db_operate_error = 10006, // 数据库操作错误
kappe_missing_param = 10007, // 缺少参数
kappe_param_num_err = 10008, // 参数个数错误
kappe_param_value_err = 10009, // 参数值错误
kappe_user_not_exist = 10101, // 用户不存在
kappe_passwd_error = 10102, // 密码错误
kappe_disinfectant_insufficient = 10201, // 消毒液不足
kappe_the_bottom_of_the_device_has_water = 10202, // 设备底部有水
kappe_the_evaporation_bin_has_water = 10203, // 蒸发仓有水
kappe_the_sensor_is_preheating = 10204, // 传感器正在预热
kappe_not_detect_udisk = 10205, // 未检测到U盘
kappe_udisk_wr_fail = 10206, // U盘读写错误
kappe_open_file_error = 10207, // 文件操作错误
kappe_adding_liquid_is_already_in_place = 10208, // 液体已加到位
kappe_adding_liquid_is_greater_than_the_maximum_capacity_of_the_device = 10209, // 加液大于设备最大容量
kappe_sensor_is_pre_heating = 10210, // 传感器正在预热
kappe_state_is_busy = 10211, // 设备忙
kappe_is_adding_liquid = 10212, // 加液中
kappe_is_draining_liquid = 10213, // 排液中
kappe_is_dis infecting = 10214, // 消毒中
kappe_is_air_leak_detect_testing = 10215, // 气密性测试中
kappe_setting_id_out_of_range = 10216, // 设置ID超出范围
kappe_exception_flag_is_setted = 10217, // 异常标志已设置
kappe_disinfection_state_is_wrong = 10218, // 消毒状态错误
kappe_component_cfg_not_find = 10219, // 组件配置未找到
kappe_liquid_ctrl_reboot = 10300,
kappe_power_control_reboot = 10301,
kappe_device_checkpoint_check_fail = 20000, //

1
src/apis/home.ts

@ -10,6 +10,5 @@ export const initHomeData: () => Promise<Socket.WebSocketResponse<Home.ResultDat
params: { params: {
}, },
}) })
console.log('res------', res)
return res return res
} }

13
src/app.vue

@ -13,6 +13,10 @@ const liquidStore = useLiquidStore()
onBeforeMount(async () => { onBeforeMount(async () => {
// //
startProgress() startProgress()
// ()
setInterval(async () => {
await readH2o2Data()
}, 2000)
}) })
const initDeviceInfo = async () => { const initDeviceInfo = async () => {
@ -55,7 +59,8 @@ const startProgress = () => {
} }
}, 100) }, 100)
} }
const initData = async () => {
const readH2o2Data = async () => {
const envParams = { const envParams = {
fnName: 'readH2O2SensorData', fnName: 'readH2O2SensorData',
className: 'FrontEndRealtimeDisplayContentMgr', className: 'FrontEndRealtimeDisplayContentMgr',
@ -65,7 +70,8 @@ const initData = async () => {
if (resData.val.length) { if (resData.val.length) {
homeStore.updateHomeData(resData.val) homeStore.updateHomeData(resData.val)
} }
}
const initData = async () => {
// //
const disinfectionParams = { const disinfectionParams = {
className: 'DisinfectionCtrlServiceExt', className: 'DisinfectionCtrlServiceExt',
@ -75,7 +81,7 @@ const initData = async () => {
const disinfectionData = await sendCmd(disinfectionParams) const disinfectionData = await sendCmd(disinfectionParams)
homeStore.updateHomeDisinfectionState(disinfectionData) homeStore.updateHomeDisinfectionState(disinfectionData)
// 使
// 使
const liquidParams = { const liquidParams = {
fnName: 'getState', fnName: 'getState',
className: 'AddLiquidService', className: 'AddLiquidService',
@ -94,6 +100,7 @@ const initData = async () => {
homeStore.setDeviceState(deviceData) homeStore.setDeviceState(deviceData)
} }
//
const initLiquidConfig = async () => { const initLiquidConfig = async () => {
const params = { const params = {
className: 'AddLiquidService', className: 'AddLiquidService',

6
src/components/common/SelectModal/index.vue

@ -1,5 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed, defineEmits, defineProps, ref, toRefs } from 'vue'
import { computed, defineEmits, defineProps, ref, toRefs, watch } from 'vue'
const props = defineProps({ const props = defineProps({
options: { options: {
@ -24,6 +24,10 @@ const emits = defineEmits(['confirm', 'cancel'])
const { options, selectedValue } = toRefs(props) const { options, selectedValue } = toRefs(props)
watch(() => props.options, (newVal) => {
options.value = newVal
})
const tempSelectedValue = ref(selectedValue.value) const tempSelectedValue = ref(selectedValue.value)
const selectOption = (option: System.Option) => { const selectOption = (option: System.Option) => {

27
src/components/formula/FormulaConfig.vue

@ -1,5 +1,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import { FtMessage } from '@/libs/message' import { FtMessage } from '@/libs/message'
import { convertValuesToString } from '@/libs/utils'
import { useFormulaStore } from '@/stores/formulaStore' import { useFormulaStore } from '@/stores/formulaStore'
import { syncSendCmd } from 'apis/system' import { syncSendCmd } from 'apis/system'
import SelectModal from 'components/common/SelectModal/index.vue' import SelectModal from 'components/common/SelectModal/index.vue'
@ -14,7 +15,7 @@ const props = defineProps<{
const formulaStore = useFormulaStore() const formulaStore = useFormulaStore()
const formData = ref<Record<string, any>>({ const formData = ref<Record<string, any>>({
...formulaStore.initFormulaInfo,
...formulaStore.defaultFormulaInfo,
}) })
const inputValue = ref<string>('') const inputValue = ref<string>('')
const keyboardVisible = ref(false) const keyboardVisible = ref(false)
@ -23,7 +24,7 @@ const softKeyboardRef = ref()
const focusedInput = ref<string | null>(null) const focusedInput = ref<string | null>(null)
const registerGrandsonMethods = inject<(methods: any) => void>('registerGrandsonMethods', () => {}) const registerGrandsonMethods = inject<(methods: any) => void>('registerGrandsonMethods', () => {})
const formulaConfigList = ref(formulaStore.formulaConfigList) const formulaConfigList = ref(formulaStore.formulaConfigList)
const options = ref(formulaStore.logLevels)
const options = ref(formulaStore.logLevelOptions)
const labelUnitMap: Record<string, any> = { const labelUnitMap: Record<string, any> = {
injection_pump_speed: 'g/min', injection_pump_speed: 'g/min',
continued_gs: 'ppm', continued_gs: 'ppm',
@ -67,22 +68,9 @@ watch(inputValue, (newVal: string | number) => {
} }
}) })
// const getFormualDefaultData = () => {
// const defaultParams = {
// className: 'SettingMgrService',
// fnName: 'getAllSetting',
// params: {},
// }
// syncSendCmd(defaultParams).then((res) => {
// if (res.ackcode === 0) {
// formulaStore.updateFormulaConfigData(res.rely)
// }
// })
// }
// form // form
const getFormData = () => { const getFormData = () => {
return formData.value
return convertValuesToString(formData.value, 'name')
} }
// //
@ -99,12 +87,13 @@ const handleSubmit = () => {
return return
} }
if (formData.value.formula_id) { if (formData.value.formula_id) {
const formulaForm: Record<string, string> = convertValuesToString(formData.value, 'name')
const editParams = { const editParams = {
className: 'SettingMgrService', className: 'SettingMgrService',
fnName: 'updateFormula', fnName: 'updateFormula',
params: { params: {
formula_id: formData.value.formula_id, formula_id: formData.value.formula_id,
formula: cloneDeep(formData.value),
formula: cloneDeep(formulaForm),
}, },
} }
syncSendCmd(editParams).then(() => { syncSendCmd(editParams).then(() => {
@ -150,6 +139,7 @@ const handleConfirm = (value: string) => {
const handleLogConfirm = (value: any) => { const handleLogConfirm = (value: any) => {
isModalOpen.value = false isModalOpen.value = false
formData.value.loglevel = value formData.value.loglevel = value
formulaStore.loglevel = value
} }
const handleLogCancel = () => { const handleLogCancel = () => {
@ -165,7 +155,7 @@ const openKeyboardType = (labelName: string) => {
<div class="formula-form"> <div class="formula-form">
<el-form :model="formData" label-width="auto" label-position="left" class="formulaFormItem" inline> <el-form :model="formData" label-width="auto" label-position="left" class="formulaFormItem" inline>
<el-form-item label="配方名称" style="margin-top:20px"> <el-form-item label="配方名称" style="margin-top:20px">
<el-input v-model="formData.name" v-prevent-keyboard name="name" class="formdata-input-home" @focus="openKeyboard" placeholder="配方名称" />
<el-input v-model="formData.name" v-prevent-keyboard name="name" placeholder="配方名称" class="formdata-input-home" @focus="openKeyboard" />
</el-form-item> </el-form-item>
<el-form-item <el-form-item
v-for="item in formulaConfigList" v-for="item in formulaConfigList"
@ -251,6 +241,7 @@ const openKeyboardType = (labelName: string) => {
<style lang="scss" scoped> <style lang="scss" scoped>
.formula-form{ .formula-form{
padding: 5px; padding: 5px;
padding-left: 15px;
max-height: 80vh; max-height: 80vh;
overflow: auto; overflow: auto;
.formulaFormItem{ .formulaFormItem{

29
src/components/formula/FormulaTable.vue

@ -1,13 +1,18 @@
<script lang="ts" setup> <script lang="ts" setup>
import { FtMessage } from '@/libs/message' import { FtMessage } from '@/libs/message'
import { FtMessageBox } from '@/libs/messageBox'
import { useFormulaStore } from '@/stores/formulaStore' import { useFormulaStore } from '@/stores/formulaStore'
import { useHomeStore } from '@/stores/homeStore'
import { syncSendCmd } from 'apis/system' import { syncSendCmd } from 'apis/system'
import { ElMessageBox } from 'element-plus' import { ElMessageBox } from 'element-plus'
import { onMounted, ref, watchEffect } from 'vue' import { onMounted, ref, watchEffect } from 'vue'
const formulaStore = useFormulaStore() const formulaStore = useFormulaStore()
const homeStore = useHomeStore()
const selectedIndex = ref<number | null>(null) const selectedIndex = ref<number | null>(null)
const recipes = ref<Formula.FormulaItem[]>([]) const recipes = ref<Formula.FormulaItem[]>([])
const currectFormula = ref<Formula.FormulaItem>()
onMounted(() => { onMounted(() => {
initFormulaList() initFormulaList()
}) })
@ -32,8 +37,26 @@ const selectRecipe = (item: Formula.FormulaItem, index: number) => {
formulaStore.updateSelectedFormulaData(item) formulaStore.updateSelectedFormulaData(item)
} }
const viewRecipe = (item: Formula.FormulaItem) => {
const onStartFormula = (item: Formula.FormulaItem) => {
formulaStore.updateSelectedFormulaData(item) formulaStore.updateSelectedFormulaData(item)
FtMessageBox.warning('请确认是否使用此配方进行消毒?').then(() => {
currectFormula.value = item
if (item.formula_id) {
const params = {
className: 'DisinfectionCtrlServiceExt',
fnName: 'startWithFormula',
params: {
formulaid: item.formula_id,
},
}
syncSendCmd(params).then((res) => {
if (res.ackcode === 0) {
//
homeStore.subscribeDisinfectEvent()
}
})
}
})
} }
const deleteRecipe = (item: Formula.FormulaItem) => { const deleteRecipe = (item: Formula.FormulaItem) => {
@ -74,8 +97,8 @@ const deleteRecipe = (item: Formula.FormulaItem) => {
> >
<span>{{ item.name }}</span> <span>{{ item.name }}</span>
<div class="actions"> <div class="actions">
<button class="view-button" @click.stop="viewRecipe(item)">
查看
<button class="view-button" @click.stop="onStartFormula(item)">
执行配方
</button> </button>
<button class="delete-button" @click.stop="deleteRecipe(item)"> <button class="delete-button" @click.stop="deleteRecipe(item)">
删除 删除

12
src/components/home/Environment.vue

@ -18,8 +18,8 @@ defineProps({
const imgs: Record<string, any> = { const imgs: Record<string, any> = {
inside: homeInside, inside: homeInside,
probe1: homeProbe1,
probe2: homeProbe2,
env1: homeProbe1,
env2: homeProbe2,
} }
onMounted(() => { onMounted(() => {
}) })
@ -34,7 +34,7 @@ onMounted(() => {
温度 温度
</div> </div>
<div class="env-row-value "> <div class="env-row-value ">
{{ roundNumber(envParams.temp, 2) }}°C
{{ roundNumber(envParams.temp || 0, 2) }}°C
</div> </div>
</div> </div>
<div class="env-row"> <div class="env-row">
@ -42,7 +42,7 @@ onMounted(() => {
相对湿度 相对湿度
</div> </div>
<div class="env-row-value"> <div class="env-row-value">
{{ roundNumber(envParams.rh, 2) }}%RH
{{ roundNumber(envParams.rh || 0, 2) }}%RH
</div> </div>
</div> </div>
<div class="env-row odd"> <div class="env-row odd">
@ -50,7 +50,7 @@ onMounted(() => {
相对饱和度 相对饱和度
</div> </div>
<div class="env-row-value "> <div class="env-row-value ">
{{ roundNumber(envParams.rs, 2) }}%RS
{{ roundNumber(envParams.rs || 0, 2) }}%RS
</div> </div>
</div> </div>
<div class="env-row"> <div class="env-row">
@ -58,7 +58,7 @@ onMounted(() => {
汽化过氧化氢 汽化过氧化氢
</div> </div>
<div class="env-row-value "> <div class="env-row-value ">
{{ roundNumber(envParams.h2o2, 2) }}ppm
{{ roundNumber(envParams.h2o2 || 0, 2) }}ppm
</div> </div>
</div> </div>
</template> </template>

2
src/components/home/HomeFormula.vue

@ -6,7 +6,7 @@ import { ref, watchEffect } from 'vue'
const formulaStore = useFormulaStore() const formulaStore = useFormulaStore()
const formulaInfo = ref() const formulaInfo = ref()
watchEffect(() => { watchEffect(() => {
formulaInfo.value = formulaStore.selectedFormulaInfo
formulaInfo.value = formulaStore.selectedFormulaInfo || formulaStore.currentSelectedFormulaInfo
}) })
</script> </script>

18
src/components/home/HomeLogLevel.vue

@ -1,23 +1,27 @@
<script lang="ts" setup> <script lang="ts" setup>
import { useFormulaStore } from '@/stores/formulaStore' import { useFormulaStore } from '@/stores/formulaStore'
import { useHomeStore } from '@/stores/homeStore'
import SelectModal from 'components/common/SelectModal/index.vue' import SelectModal from 'components/common/SelectModal/index.vue'
import { ref } from 'vue'
import { ref, watchEffect } from 'vue'
const formulaStore = useFormulaStore() const formulaStore = useFormulaStore()
const homeStore = useHomeStore()
const options = ref(formulaStore.logLevels)
const loglevel = ref(homeStore.loglevel)
const options = ref(formulaStore.logLevelOptions)
const loglevel = ref(formulaStore.loglevel)
const selectedValue = ref() const selectedValue = ref()
const isModalOpen = ref(false) const isModalOpen = ref(false)
watchEffect(() => {
options.value = formulaStore.logLevelOptions
loglevel.value = formulaStore.loglevel
})
const openModal = () => { const openModal = () => {
isModalOpen.value = true isModalOpen.value = true
} }
const handleConfirm = (value: any) => { const handleConfirm = (value: any) => {
isModalOpen.value = false
loglevel.value = value loglevel.value = value
homeStore.updateLogLevel(value)
formulaStore.updateLogLevel(value)
isModalOpen.value = false
} }
const handleCancel = () => { const handleCancel = () => {

96
src/components/home/HomeOperation.vue

@ -1,8 +1,9 @@
<script lang="ts" setup> <script lang="ts" setup>
import { getDeviceStatus } from '@/libs/deviceComm'
import { FtMessage } from '@/libs/message' import { FtMessage } from '@/libs/message'
import { FtMessageBox } from '@/libs/messageBox'
import { useFormulaStore } from '@/stores/formulaStore'
import { useHomeStore } from '@/stores/homeStore' import { useHomeStore } from '@/stores/homeStore'
import { useLiquidStore } from '@/stores/liquidStore'
import { useSealStore } from '@/stores/sealStore'
import { useSystemStore } from '@/stores/systemStore' import { useSystemStore } from '@/stores/systemStore'
import { sendCmd, subscribeEvent } from 'apis/system' import { sendCmd, subscribeEvent } from 'apis/system'
import homeFinish from 'assets/images/home/home-finish.svg' import homeFinish from 'assets/images/home/home-finish.svg'
@ -12,11 +13,17 @@ import { deviceStateMap } from 'libs/utils'
import { computed, onMounted, ref, watchEffect } from 'vue' import { computed, onMounted, ref, watchEffect } from 'vue'
const homeStore = useHomeStore() const homeStore = useHomeStore()
const liquidStore = useLiquidStore()
const sealStore = useSealStore()
const formulaStore = useFormulaStore()
const systemStore = useSystemStore() const systemStore = useSystemStore()
const curStateRemainTimeS = ref<string>('') const curStateRemainTimeS = ref<string>('')
const disinfectionState = ref(homeStore.disinfectionState) const disinfectionState = ref(homeStore.disinfectionState)
const btnStyle = {
width: '27vw',
height: '7vh',
textSize: '24px',
borderRadius: '12px',
textColor: '#FFFFFF',
}
let isDisinfection = false let isDisinfection = false
watchEffect(() => { watchEffect(() => {
@ -42,44 +49,31 @@ const handleDisinfectState = (report: Socket.WebSocketResponse<Home.DisinfectSta
} }
// //
const onStartDisinfect = async () => { const onStartDisinfect = async () => {
if (!homeStore.loglevel) {
if (!formulaStore.loglevel) {
FtMessage.warning('选择消毒等级') FtMessage.warning('选择消毒等级')
return return
} }
//
if (liquidStore.liquidAddWorkState.workState !== 'idle') {
FtMessage.warning('正在进行加液操作...')
return
}
//
if (liquidStore.liquidDrainWorkState.workState !== 'idle') {
FtMessage.warning('正在进行排液操作...')
const statusName = getDeviceStatus()
if (statusName) {
FtMessageBox.error(statusName)
return return
} }
//
if (sealStore.sealInfo.workState !== 'idle') {
FtMessage.warning('正在进行排液操作...')
return
if (formulaStore.selectedFormulaInfo && formulaStore.selectedFormulaInfo.formula_id) {
formulaStore.saveDisinfectFormula(formulaStore.selectedFormulaInfo)
} }
const startParams = {
className: 'DisinfectionCtrlServiceExt',
fnName: 'start',
params: {
loglevel: homeStore.loglevel,
},
else {
const startParams = {
className: 'DisinfectionCtrlServiceExt',
fnName: 'start',
params: {
loglevel: formulaStore.loglevel,
},
}
systemStore.updateLoading(true)
await sendCmd(startParams)
} }
systemStore.updateLoading(true)
await sendCmd(startParams)
//
const subParams = {
className: 'DisinfectionCtrlServiceExt',
fnName: 'startStateReport',
params: {},
}
sendCmd(subParams)
homeStore.subscribeDisinfectEvent()
} }
// //
@ -89,23 +83,11 @@ const onFinishDisinfect = async () => {
className: 'DisinfectionCtrlServiceExt', className: 'DisinfectionCtrlServiceExt',
fnName: 'stop', fnName: 'stop',
params: { params: {
loglevel: homeStore.loglevel,
loglevel: formulaStore.loglevel,
}, },
} }
systemStore.updateLoading(true) systemStore.updateLoading(true)
await sendCmd(stopParams) await sendCmd(stopParams)
//
const params = {
className: 'DisinfectionCtrlServiceExt',
fnName: 'stopStateReport',
params: {},
}
sendCmd(params)
// homeStore.updateHomeDisinfectionState({
// ...disinfectionState.value,
// state: 'idle',
// })
} }
const operationState = computed(() => { const operationState = computed(() => {
@ -119,11 +101,11 @@ const operationState = computed(() => {
v-if="operationState" v-if="operationState"
button-text="开始消毒" button-text="开始消毒"
bg-color="#31CB7A" bg-color="#31CB7A"
text-color="#FFFFFF"
width="27vw"
height="7vh"
text-size="24px"
border-radius="12px"
:text-color="btnStyle.textColor"
:width="btnStyle.width"
:height="btnStyle.height"
:text-size="btnStyle.textSize"
:border-radius="btnStyle.borderRadius"
@click="onStartDisinfect" @click="onStartDisinfect"
> >
<template #icon> <template #icon>
@ -134,11 +116,11 @@ const operationState = computed(() => {
v-else v-else
button-text="结束消毒" button-text="结束消毒"
bg-color="#FF6767" bg-color="#FF6767"
text-color="#FFFFFF"
width="27vw"
height="7vh"
text-size="24px"
border-radius="12px"
:text-color="btnStyle.textColor"
:width="btnStyle.width"
:height="btnStyle.height"
:text-size="btnStyle.textSize"
:border-radius="btnStyle.borderRadius"
@click="onFinishDisinfect" @click="onFinishDisinfect"
> >
<template #icon> <template #icon>

75
src/components/home/HomeSetting.vue

@ -1,13 +1,16 @@
<script lang="ts" setup> <script lang="ts" setup>
import { FtMessage } from '@/libs/message'
import { useFormulaStore } from '@/stores/formulaStore' import { useFormulaStore } from '@/stores/formulaStore'
import { useHomeStore } from '@/stores/homeStore' import { useHomeStore } from '@/stores/homeStore'
import { sendCmd } from 'apis/system'
import homeChart from 'assets/images/home/home-chart.svg' import homeChart from 'assets/images/home/home-chart.svg'
import homeRunSvg from 'assets/images/home/home-run.svg' import homeRunSvg from 'assets/images/home/home-run.svg'
import homeSettingSvg from 'assets/images/home/home-setting.svg' import homeSettingSvg from 'assets/images/home/home-setting.svg'
import CascadingSelectModal from 'components/common/CascadingSelectModal/index.vue' import CascadingSelectModal from 'components/common/CascadingSelectModal/index.vue'
import Config from 'components/home/Config.vue' import Config from 'components/home/Config.vue'
import { compareJSON } from 'libs/utils'
import { cloneDeep } from 'lodash' import { cloneDeep } from 'lodash'
import { onMounted, provide, ref, watchEffect } from 'vue'
import { computed, onMounted, provide, ref, watchEffect } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
const configRef = ref() const configRef = ref()
@ -17,7 +20,6 @@ provide<(methods: Home.GrandsonMethods) => void>('registerGrandsonMethods', (met
const router = useRouter() const router = useRouter()
const formulaStore = useFormulaStore() const formulaStore = useFormulaStore()
const homeStore = useHomeStore() const homeStore = useHomeStore()
const deviceState = ref(1)
const isModalOpen = ref(false) const isModalOpen = ref(false)
const optionsLeft = ref<System.Option[]>([]) const optionsLeft = ref<System.Option[]>([])
const optionsRight = ref<System.Option[]>([]) const optionsRight = ref<System.Option[]>([])
@ -27,16 +29,6 @@ const disinfectionState = ref(homeStore.disinfectionState)
const disinfectFormulaVisible = ref(false) const disinfectFormulaVisible = ref(false)
const selectedByFormulas = ref(cloneDeep(formulaStore.selectedFormulaInfo)) const selectedByFormulas = ref(cloneDeep(formulaStore.selectedFormulaInfo))
const onDisinfectConfig = () => {
if (selectedByFormulas.value) {
formulaStore.updateSelectedFormulaDataByList(cloneDeep(selectedByFormulas.value))
}
else {
formulaStore.updateSelectedFormulaDataByList(cloneDeep(formulaStore.defaultFormulaInfo))
}
disinfectFormulaVisible.value = true
}
watchEffect(() => { watchEffect(() => {
disinfectionState.value = homeStore.disinfectionState disinfectionState.value = homeStore.disinfectionState
selectedByFormulas.value = formulaStore.selectedFormulaInfo selectedByFormulas.value = formulaStore.selectedFormulaInfo
@ -47,17 +39,68 @@ onMounted(() => {
homeStore.getPressureConfig() homeStore.getPressureConfig()
}) })
const deviceState = computed(() => {
return disinfectionState.value.state === 'idle' || disinfectionState.value.state === 'finished'
})
const onDisinfectConfig = () => {
if (selectedByFormulas.value) {
formulaStore.updateSelectedFormulaDataByList(cloneDeep(selectedByFormulas.value))
}
else {
formulaStore.updateSelectedFormulaDataByList(cloneDeep(formulaStore.defaultFormulaInfo))
}
disinfectFormulaVisible.value = true
}
const onShowChart = () => { const onShowChart = () => {
router.push('/home/chart') router.push('/home/chart')
} }
// //
const onSave = () => {
const onSave = async () => {
const formData = configRef.value?.getFormData() const formData = configRef.value?.getFormData()
console.log('formData---', JSON.stringify(formData))
formulaStore.updateSelectedFormulaDataByList(cloneDeep(formData)) formulaStore.updateSelectedFormulaDataByList(cloneDeep(formData))
//
if (!homeStore.isDeviceIdle) {
//
const params = {
className: 'DisinfectionCtrlServiceExt',
fnName: 'getRealtimeConfig',
params: {},
}
const res = await sendCmd(params)
const result = compareJSON(res, formData)
const resultKey = Object.keys(result)
if (resultKey && resultKey.length) {
resultKey.forEach(async (item) => {
await setRealtimeConfig(item, result[item].newVal)
})
FtMessage.success('配方修改成功')
}
}
else {
//
if (formData.formula_id) {
await formulaStore.saveDisinfectFormula(formData)
}
}
onClose() onClose()
} }
const setRealtimeConfig = async (key: string, val: string) => {
const params = {
className: 'DisinfectionCtrlServiceExt',
fnName: 'setRealtimeConfig',
params: {
key,
val,
},
}
await sendCmd(params)
}
// //
const onSetPressure = () => { const onSetPressure = () => {
// //
@ -90,7 +133,6 @@ const onSetPressure = () => {
optionsRight.value = right optionsRight.value = right
isModalOpen.value = true isModalOpen.value = true
} }
const handleConfirm = (value: string | number[]) => { const handleConfirm = (value: string | number[]) => {
isModalOpen.value = false isModalOpen.value = false
homeStore.updatePressure(value) homeStore.updatePressure(value)
@ -98,7 +140,6 @@ const handleConfirm = (value: string | number[]) => {
const handleCancel = () => { const handleCancel = () => {
isModalOpen.value = false isModalOpen.value = false
} }
const onClose = () => { const onClose = () => {
disinfectFormulaVisible.value = false disinfectFormulaVisible.value = false
} }
@ -125,7 +166,7 @@ const onClose = () => {
border-radius="5px" border-radius="5px"
text-color="#1989fa" text-color="#1989fa"
padding="0.8vw" padding="0.8vw"
:disabled="disinfectionState.state === 'idle'"
:disabled="deviceState"
@click="onShowChart" @click="onShowChart"
> >
<template #icon> <template #icon>
@ -134,7 +175,7 @@ const onClose = () => {
</bt-button> </bt-button>
<bt-button <bt-button
v-if="deviceState === 1"
v-if="deviceState"
button-text="消毒设置" button-text="消毒设置"
text-size="14px" text-size="14px"
border-radius="5px" border-radius="5px"

60
src/components/home/LineChart.vue

@ -1,16 +1,26 @@
<script lang="ts" setup> <script lang="ts" setup>
import * as echarts from 'echarts' import * as echarts from 'echarts'
import { onMounted } from 'vue'
import { onMounted, ref, watchEffect } from 'vue'
const props = defineProps({
title: {
type: String,
default: '仓内',
},
chartId: {
type: String,
default: 'inside',
},
const props = defineProps<{
title: string
chartId: string
envData: Home.DisplayrelyMgrParams
}>()
const temperatureData = ref<(number)[]>([0])
const humidityData = ref<(number)[]>([0])
const h2o2ConcentrationData = ref<(number)[]>([0])
const h2o2SaturationData = ref<(number)[]>([0])
const dataLength = ref(10)
watchEffect(() => {
console.log('envData.temp====', props.envData.temp)
temperatureData.value.push(props.envData.temp)
humidityData.value.push(props.envData.rh)
h2o2ConcentrationData.value.push(props.envData.rs)
h2o2SaturationData.value.push(props.envData.h2o2)
dataLength.value = temperatureData.value.length
}) })
onMounted(() => { onMounted(() => {
@ -18,24 +28,6 @@ onMounted(() => {
if (chartDom) { if (chartDom) {
const myChart = echarts.init(chartDom) const myChart = echarts.init(chartDom)
// mock
const generateRandomData = (maxValue: number) => {
return Math.floor(Math.random() * maxValue)
}
const temperatureData: number[] = [0]
const humidityData: number[] = [0]
const h2o2ConcentrationData: number[] = [0]
const h2o2SaturationData: number[] = [0]
const dataLength = 20
for (let i = 0; i < dataLength; i++) {
temperatureData.push(generateRandomData(400))
humidityData.push(generateRandomData(200))
h2o2ConcentrationData.push(generateRandomData(100))
h2o2SaturationData.push(generateRandomData(500))
}
const option = { const option = {
title: { title: {
text: props.title, text: props.title,
@ -56,7 +48,7 @@ onMounted(() => {
xAxis: { xAxis: {
type: 'category', type: 'category',
boundaryGap: false, boundaryGap: false,
data: Array.from({ length: dataLength }, (_, i) => `${i + 1}`),
data: Array.from({ length: dataLength.value }, (_, i) => `${i + 1}`),
}, },
yAxis: { yAxis: {
type: 'value', type: 'value',
@ -65,7 +57,7 @@ onMounted(() => {
{ {
name: '温度', name: '温度',
type: 'line', type: 'line',
data: temperatureData.sort((a, b) => a - b),
data: temperatureData.value.sort((a, b) => a - b),
symbol: 'circle', symbol: 'circle',
symbolSize: 2, symbolSize: 2,
lineStyle: { lineStyle: {
@ -76,7 +68,7 @@ onMounted(() => {
{ {
name: '湿度', name: '湿度',
type: 'line', type: 'line',
data: humidityData.sort((a, b) => a - b),
data: humidityData.value.sort((a, b) => a - b),
symbol: 'circle', symbol: 'circle',
symbolSize: 2, symbolSize: 2,
lineStyle: { lineStyle: {
@ -87,7 +79,7 @@ onMounted(() => {
{ {
name: 'H2O2浓度', name: 'H2O2浓度',
type: 'line', type: 'line',
data: h2o2ConcentrationData.sort((a, b) => a - b),
data: h2o2ConcentrationData.value.sort((a, b) => a - b),
symbol: 'circle', symbol: 'circle',
symbolSize: 2, symbolSize: 2,
lineStyle: { lineStyle: {
@ -98,7 +90,7 @@ onMounted(() => {
{ {
name: 'H2O2饱和度', name: 'H2O2饱和度',
type: 'line', type: 'line',
data: h2o2SaturationData.sort((a, b) => a - b),
data: h2o2SaturationData.value.sort((a, b) => a - b),
symbol: 'circle', symbol: 'circle',
symbolSize: 2, symbolSize: 2,
lineStyle: { lineStyle: {
@ -115,7 +107,7 @@ onMounted(() => {
<template> <template>
<div class="line-chart"> <div class="line-chart">
<div :id="chartId" style="width: 32vw; height: 50vh;" />
<div :id="chartId" style="height: 50vh;" />
</div> </div>
</template> </template>

43
src/components/home/config.vue

@ -1,4 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import { convertValuesToInt } from '@/libs/utils'
import { useFormulaStore } from '@/stores/formulaStore' import { useFormulaStore } from '@/stores/formulaStore'
import { useHomeStore } from '@/stores/homeStore' import { useHomeStore } from '@/stores/homeStore'
import SelectModal from 'components/common/SelectModal/index.vue' import SelectModal from 'components/common/SelectModal/index.vue'
@ -7,17 +8,11 @@ import { computed, onMounted, ref, watchEffect } from 'vue'
const formulaStore = useFormulaStore() const formulaStore = useFormulaStore()
const homeStore = useHomeStore() const homeStore = useHomeStore()
// const formData = ref<Formula.FormulaItem>(formulaStore.currentSelectedFormulaInfo || formulaStore.initFormulaInfo)
const recipes = ref<Formula.FormulaItem[]>([]) const recipes = ref<Formula.FormulaItem[]>([])
const softKeyboardRef = ref()
const isModalOpen = ref(false) const isModalOpen = ref(false)
const keyboardVisible = ref(false)
const selectedValue = ref() const selectedValue = ref()
// const focusedInput = ref<string | null>(null)
// const logLevelList = ref(formulaStore.logEnums)
const deviceState = ref(homeStore.deviceStete)
const isDeviceIdle = ref(homeStore.isDeviceIdle)
onMounted(() => { onMounted(() => {
onWatchKeyboard()
// store // store
if (!formulaStore.formulaList || !formulaStore.formulaList.length) { if (!formulaStore.formulaList || !formulaStore.formulaList.length) {
formulaStore.initFormulaList() formulaStore.initFormulaList()
@ -25,6 +20,7 @@ onMounted(() => {
}) })
watchEffect(() => { watchEffect(() => {
recipes.value = [...formulaStore.formulaList] recipes.value = [...formulaStore.formulaList]
isDeviceIdle.value = homeStore.isDeviceIdle
}) })
const options = computed(() => { const options = computed(() => {
@ -46,8 +42,9 @@ const handleConfirm = (value: any) => {
selectedFormula = item selectedFormula = item
} }
}) })
const selectedFormulaToInt = convertValuesToInt(selectedFormula, 'name')
// //
formulaStore.updateSelectedFormulaDataByList(selectedFormula as Formula.FormulaItem)
formulaStore.updateSelectedFormulaDataByList(selectedFormulaToInt as Formula.FormulaItem)
} }
const handleCancel = () => { const handleCancel = () => {
isModalOpen.value = false isModalOpen.value = false
@ -56,39 +53,14 @@ const onChooseFormula = () => {
isModalOpen.value = true isModalOpen.value = true
} }
const onDefaultFormula = () => { const onDefaultFormula = () => {
//
formulaStore.initFormulaData() formulaStore.initFormulaData()
} }
const onWatchKeyboard = () => {
document.addEventListener('click', (e: any) => {
if (softKeyboardRef.value && !e.target?.name) {
keyboardVisible.value = false
}
})
}
// const openKeyboard = (e: any) => {
// setTimeout(() => {
// keyboardVisible.value = true
// const labelName: string = e.target.name
// openKeyboardType(labelName)
// const formValue = formData.value[labelName as keyof typeof formData.value]
// inputValue.value = formValue.toString()
// focusedInput.value = e.target.name
// }, 100)
// }
//
// const openKeyboardType = (labelName: string) => {
// keyboardType.value = labelName === 'name' ? 'text' : 'number'
// }
// const goHome = () => {
// router.push('/home')
// }
</script> </script>
<template> <template>
<div class="main-content"> <div class="main-content">
<div v-if="deviceState.state.toLocaleLowerCase() === 'idle'">
<div v-if="isDeviceIdle">
<bt-button <bt-button
type="primary" type="primary"
button-text="选择配方" button-text="选择配方"
@ -101,7 +73,6 @@ const onWatchKeyboard = () => {
</el-icon> </el-icon>
</template> </template>
</bt-button> </bt-button>
<bt-button <bt-button
button-text="默认配置" button-text="默认配置"
width="10vw" width="10vw"

66
src/components/setting/AddUser.vue

@ -1,9 +1,12 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { FormInstance } from 'element-plus' import type { FormInstance } from 'element-plus'
import { useSettingStore } from '@/stores/settingStore' import { useSettingStore } from '@/stores/settingStore'
import { syncSendCmd } from 'apis/system'
import SoftKeyboard from 'components/common/SoftKeyboard/index.vue' import SoftKeyboard from 'components/common/SoftKeyboard/index.vue'
import { onMounted, ref, watchEffect } from 'vue'
import { FtMessage } from 'libs/message'
import { ref, watchEffect } from 'vue'
const emits = defineEmits(['refresh'])
const settingStore = useSettingStore() const settingStore = useSettingStore()
const visible = ref(settingStore.addUserVisible) const visible = ref(settingStore.addUserVisible)
const modalType = ref(settingStore.userModalState) const modalType = ref(settingStore.userModalState)
@ -14,13 +17,13 @@ const softKeyboardRef = ref()
const userFormRef = ref() const userFormRef = ref()
const focusedInput = ref<string | null>(null) const focusedInput = ref<string | null>(null)
const modalTitle = ref('新增用户') const modalTitle = ref('新增用户')
const userForm = ref<Setting.User>({
uid: '',
id: '',
const userForm = ref<Record<string, any>>({
name: '',
passwd: '', passwd: '',
confirmPassword: '',
is_admin: false,
confirmPasswd: '',
roleType: '',
}) })
watchEffect(() => { watchEffect(() => {
modalType.value = settingStore.userModalState modalType.value = settingStore.userModalState
if (settingStore.userModalState === 'edit') { if (settingStore.userModalState === 'edit') {
@ -34,19 +37,10 @@ watchEffect(() => {
} }
visible.value = settingStore.addUserVisible visible.value = settingStore.addUserVisible
if (focusedInput.value) { if (focusedInput.value) {
userForm.value[focusedInput.value as keyof typeof userForm.value] = inputValue.value
userForm.value[focusedInput.value] = inputValue.value
} }
}) })
onMounted(() => {
//
document.addEventListener('click', (e: any) => {
if (softKeyboardRef.value && !e.target?.name) {
keyboardVisible.value = false
}
})
})
const onSave = (formRef: FormInstance | undefined) => { const onSave = (formRef: FormInstance | undefined) => {
if (!formRef) { if (!formRef) {
return return
@ -78,6 +72,30 @@ const openKeyboard = (e: any) => {
const doEdit = () => { const doEdit = () => {
} }
const doSave = () => { const doSave = () => {
const name = userForm.value.name
const passwd = userForm.value.passwd
const confirmPasswd = userForm.value.confirmPasswd
const roleType = userForm.value.roleType
if (passwd !== confirmPasswd) {
FtMessage.error('输入的密码不一致')
return
}
const saveParams = {
className: 'UserMgrService',
fnName: 'addUser',
params: {
name,
passwd,
roleType: roleType ? 'admin' : 'maintainer',
},
}
syncSendCmd(saveParams).then((res) => {
if (res.ackcode === 0) {
FtMessage.success('成功')
emits('refresh')
}
})
} }
const onClose = () => { const onClose = () => {
settingStore.updateVisible(false) settingStore.updateVisible(false)
@ -92,17 +110,18 @@ const handleConfirm = (value: string) => {
<div> <div>
<el-form ref="userFormRef" :model="userForm" label-width="auto" style="max-width: 400px"> <el-form ref="userFormRef" :model="userForm" label-width="auto" style="max-width: 400px">
<el-form-item <el-form-item
v-if="!userForm.id"
label="登录名:" label="登录名:"
prop="uid"
prop="name"
:rules="[{ :rules="[{
required: true, required: true,
message: '输入登录名', message: '输入登录名',
trigger: ['blur', 'change'], trigger: ['blur', 'change'],
}]" }]"
> >
<el-input v-model="userForm.uid" v-prevent-keyboard name="uid" @focus="openKeyboard" placeholder="登录名" />
<el-input v-model="userForm.name" v-prevent-keyboard name="name" @focus="openKeyboard" placeholder="登录名" />
</el-form-item> </el-form-item>
<div v-if="!userForm.id">
<div>
<el-form-item <el-form-item
label="密码:" label="密码:"
prop="passwd" prop="passwd"
@ -112,24 +131,24 @@ const handleConfirm = (value: string) => {
trigger: ['blur', 'change'], trigger: ['blur', 'change'],
}" }"
> >
<el-input v-model="userForm.passwd" v-prevent-keyboard name="passwd" @focus="openKeyboard" type="password" placeholder="密码" />
<el-input v-model="userForm.passwd" v-prevent-keyboard name="passwd" @focus="openKeyboard" type="password" placeholder="密码" />
</el-form-item> </el-form-item>
<el-form-item <el-form-item
label="确认密码:" label="确认密码:"
prop="confirmPassword"
prop="confirmPasswd"
:rules="{ :rules="{
required: true, required: true,
message: '输入密码', message: '输入密码',
trigger: ['blur', 'change'], trigger: ['blur', 'change'],
}" }"
> >
<el-input v-model="userForm.confirmPassword" v-prevent-keyboard name="confirmPassword" @focus="openKeyboard" type="password" placeholder="确认密码" />
<el-input v-model="userForm.confirmPasswd" v-prevent-keyboard name="confirmPasswd" @focus="openKeyboard" type="password" placeholder="确认密码" />
</el-form-item> </el-form-item>
</div> </div>
<el-form-item <el-form-item
label="是否管理员:" label="是否管理员:"
> >
<el-checkbox v-model="userForm.is_admin" size="small" />
<el-checkbox v-model="userForm.roleType" size="small" />
</el-form-item> </el-form-item>
</el-form> </el-form>
<Teleport to="body"> <Teleport to="body">
@ -138,6 +157,7 @@ const handleConfirm = (value: string) => {
v-model="inputValue" v-model="inputValue"
:is-visible="keyboardVisible" :is-visible="keyboardVisible"
:keyboard-type="keyboardType" :keyboard-type="keyboardType"
@update-keyboard-visible="(visible) => keyboardVisible = visible"
@confirm="handleConfirm" @confirm="handleConfirm"
@close="keyboardVisible = false" @close="keyboardVisible = false"
/> />

37
src/components/setting/Device.vue

@ -0,0 +1,37 @@
<script lang="ts" setup>
import { useDeviceStore } from 'stores/deviceStore'
import { ref } from 'vue'
const deviceStore = useDeviceStore()
const deviceInfo = ref(deviceStore.deviceInfo)
</script>
<template>
<div>
<div class="device-ul">
<div>设备ID{{ deviceInfo.deviceId }}</div>
</div>
<div class="device-ul">
<div>设备类型{{ deviceInfo.deviceType }}</div>
</div>
<div class="device-ul">
<div>IP地址{{ deviceInfo.ip }}</div>
</div>
<div class="device-ul">
<div>初始化状态{{ deviceInfo.deviceTypeInited ? '已初始化' : '未初始化' }}</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.device-ul{
background: #F6FAFE;
height: 4rem;
display: flex;
align-items: center;
width: 100%;
border-radius: 10px;
margin-top: 1rem;
padding-left: 2rem;
}
</style>

149
src/components/setting/ModifyPwd.vue

@ -0,0 +1,149 @@
<script lang="ts" setup>
import type { FormInstance } from 'element-plus'
import { useSettingStore } from '@/stores/settingStore'
import { syncSendCmd } from 'apis/system'
import SoftKeyboard from 'components/common/SoftKeyboard/index.vue'
import { FtMessage } from 'libs/message'
import { ref, watchEffect } from 'vue'
const emits = defineEmits(['refresh'])
const settingStore = useSettingStore()
const visible = ref(settingStore.modifyPwdVisible)
const modalType = ref(settingStore.userModalState)
const inputValue = ref<string>('')
const keyboardVisible = ref(false)
const keyboardType = ref<'text' | 'number'>('text')
const softKeyboardRef = ref()
const userFormRef = ref()
const focusedInput = ref<string | null>(null)
const modalTitle = ref('修改密码')
const userForm = ref<Record<string, any>>({
passwd: '',
newpasswd: '',
confirmPasswd: '',
})
watchEffect(() => {
modalType.value = settingStore.userModalState
visible.value = settingStore.modifyPwdVisible
if (settingStore.currentEditUser) {
userForm.value = settingStore.currentEditUser
}
if (focusedInput.value) {
userForm.value[focusedInput.value] = inputValue.value
}
})
const onSave = (formRef: FormInstance | undefined) => {
if (!formRef) {
return
}
formRef.validate((valid) => {
if (valid) {
doSave()
}
else {
console.log('error submit!')
}
})
}
const openKeyboard = (e: any) => {
setTimeout(() => {
keyboardVisible.value = true
const labelName = e.target.name
const formValue = userForm.value[labelName as keyof typeof userForm.value]
inputValue.value = formValue ? formValue.toString() : ''
focusedInput.value = e.target.name
}, 100)
}
const doSave = () => {
const passwd = userForm.value.passwd
const newpasswd = userForm.value.newpasswd
const confirmNewPasswd = userForm.value.confirmNewPasswd
if (newpasswd !== confirmNewPasswd) {
FtMessage.error('输入的密码不一致')
return
}
const saveParams = {
className: 'UserMgrService',
fnName: 'chpasswd',
params: {
id: userForm.value.id,
passwd,
newpasswd,
},
}
syncSendCmd(saveParams).then((res) => {
if (res.ackcode === 0) {
FtMessage.success('密码修改成功')
userForm.value = {}
emits('refresh')
onClose()
}
})
}
const onClose = () => {
settingStore.updatePwdVisible(false)
}
const handleConfirm = (value: string) => {
console.log('确认输入:', value)
}
</script>
<template>
<FtDialog v-model="visible" :title="modalTitle" :ok-handle="() => { onSave(userFormRef) }" @cancel="onClose">
<div>
<el-form ref="userFormRef" :model="userForm" label-width="auto" style="max-width: 400px">
<div>
<el-form-item
label="旧密码:"
prop="passwd"
:rules="{
required: true,
message: '输入密码',
trigger: ['blur', 'change'],
}"
>
<el-input v-model="userForm.passwd" v-prevent-keyboard name="passwd" @focus="openKeyboard" type="password" placeholder="密码" />
</el-form-item>
<el-form-item
label="新密码:"
prop="newpasswd"
:rules="{
required: true,
message: '输入密码',
trigger: ['blur', 'change'],
}"
>
<el-input v-model="userForm.newpasswd" v-prevent-keyboard name="newpasswd" @focus="openKeyboard" type="password" placeholder="密码" />
</el-form-item>
<el-form-item
label="确认新密码:"
prop="confirmNewPasswd"
:rules="{
required: true,
message: '输入密码',
trigger: ['blur', 'change'],
}"
>
<el-input v-model="userForm.confirmNewPasswd" v-prevent-keyboard name="confirmNewPasswd" @focus="openKeyboard" type="password" placeholder="确认密码" />
</el-form-item>
</div>
</el-form>
<Teleport to="body">
<SoftKeyboard
ref="softKeyboardRef"
v-model="inputValue"
:is-visible="keyboardVisible"
:keyboard-type="keyboardType"
@update-keyboard-visible="(visible) => keyboardVisible = visible"
@confirm="handleConfirm"
@close="keyboardVisible = false"
/>
</Teleport>
</div>
</FtDialog>
</template>
<style lang="scss" scoped>
</style>

68
src/components/setting/SystemDate.vue

@ -0,0 +1,68 @@
<script lang="ts" setup>
import { sendCmd } from '@/apis/system'
import { FtMessage } from '@/libs/message'
import { ref } from 'vue'
const dateVal = ref()
const onChangeDate = async (value: string) => {
if (value) {
const splitDate = value.split(' ') //
const YMD = splitDate[0].split('-')
//
const year = Number(YMD[0])
const month = Number(YMD[1])
const day = Number(YMD[2])
const dateParams = {
className: 'OsMgrService',
fnName: 'updateDate',
params: {
year,
month,
day,
},
}
await sendCmd(dateParams)
const HMS = splitDate[1].split(':')
//
const hour = Number(HMS[0])
const min = Number(HMS[1])
const second = Number(HMS[2])
const timeParams = {
className: 'OsMgrService',
fnName: 'updateTime',
params: {
hour,
min,
second,
},
}
await sendCmd(timeParams)
FtMessage.success('日期设置成功')
}
}
</script>
<template>
<div>
<div class="date-main">
<div class="date-com">
设置日期
<el-date-picker
v-model="dateVal"
type="datetime"
placeholder="日期:年-月-日 时:分:秒"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
@change="onChangeDate"
/>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.date-main{
margin: 2rem;
}
</style>

79
src/components/setting/User.vue

@ -1,33 +1,69 @@
<script lang="ts" setup> <script lang="ts" setup>
import { useSettingStore } from '@/stores/settingStore' import { useSettingStore } from '@/stores/settingStore'
import { ElMessageBox } from 'element-plus'
import { ref } from 'vue'
import { syncSendCmd } from 'apis/system'
import { FtMessage } from 'libs/message'
import { FtMessageBox } from 'libs/messageBox'
import { onMounted, ref } from 'vue'
import AddUser from './AddUser.vue' import AddUser from './AddUser.vue'
import ModifyPwd from './ModifyPwd.vue'
const settingStore = useSettingStore() const settingStore = useSettingStore()
const tableData = ref(settingStore.userList) const tableData = ref(settingStore.userList)
const updatePwd = (userItem: Setting.User) => {
console.log('userItem===', userItem)
const selectedUserList = ref<User.UserItem[]>([])
onMounted(() => {
queryUserList()
})
const queryUserList = () => {
const userParams = {
className: 'UserMgrService',
fnName: 'getAllUser',
params: {},
}
syncSendCmd(userParams).then((res) => {
if (res.ackcode === 0) {
tableData.value = res.rely
}
})
}
const updatePwd = (userItem: User.UserItem) => {
settingStore.updateCurrentEditUser(userItem) settingStore.updateCurrentEditUser(userItem)
settingStore.updateUserModalState('edit')
settingStore.updateVisible(true)
settingStore.updatePwdVisible(true)
} }
const onAddUser = () => { const onAddUser = () => {
settingStore.updateUserModalState('add') settingStore.updateUserModalState('add')
settingStore.updateVisible(true) settingStore.updateVisible(true)
} }
const onDelUser = () => { const onDelUser = () => {
ElMessageBox.confirm(
'请确认是否删除?',
'删除',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
},
).then(() => {
if (selectedUserList.value.length !== 1) {
FtMessage.warning('选择一条数据进行删除')
return
}
const user = selectedUserList.value[0]
if (user.roleType === 'admin') {
FtMessage.warning('不可删除管理员用户')
return
}
FtMessageBox.warning('请确认是否删除?').then(() => {
const delParams = {
className: 'UserMgrService',
fnName: 'delUser',
params: {
id: user.id,
},
}
syncSendCmd(delParams).then((res) => {
if (res.ackcode === 0) {
FtMessage.success('删除成功')
queryUserList()
}
})
}) })
} }
const handleSelectionChange = (users: User.UserItem[]) => {
selectedUserList.value = users
}
</script> </script>
<template> <template>
@ -44,18 +80,21 @@ const onDelUser = () => {
/> />
</div> </div>
<div> <div>
<el-table :data="tableData" stripe style="width: 100%">
<el-table :data="tableData" stripe style="width: 100%" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" /> <el-table-column type="selection" width="55" />
<el-table-column prop="uid" label="用户名" />
<el-table-column prop="name" label="用户名" />
<el-table-column prop="detail" label="操作"> <el-table-column prop="detail" label="操作">
<template #default="scoped"> <template #default="scoped">
<el-link type="primary" @click="updatePwd(scoped.row)">修改密码</el-link>
<el-link type="primary" @click="updatePwd(scoped.row)">
修改密码
</el-link>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</div> </div>
<div> <div>
<AddUser/>
<AddUser @refresh="queryUserList" />
<ModifyPwd @refresh="queryUserList" />
</div> </div>
</div> </div>
</template> </template>
@ -69,7 +108,5 @@ const onDelUser = () => {
.history-export{ .history-export{
margin: 2vw; margin: 2vw;
} }
.history-table{
}
} }
</style> </style>

60
src/layouts/default.vue

@ -1,4 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { getDeviceStatus } from '@/libs/deviceComm'
import { FtMessageBox } from '@/libs/messageBox' import { FtMessageBox } from '@/libs/messageBox'
import { useHomeStore } from '@/stores/homeStore' import { useHomeStore } from '@/stores/homeStore'
import { useLiquidStore } from '@/stores/liquidStore' import { useLiquidStore } from '@/stores/liquidStore'
@ -6,10 +7,10 @@ import { useSealStore } from '@/stores/sealStore'
import { useSystemStore } from '@/stores/systemStore' import { useSystemStore } from '@/stores/systemStore'
import HomeAlarmSvg from 'assets/images/home/home-alarm.svg' import HomeAlarmSvg from 'assets/images/home/home-alarm.svg'
import ErrorBox from 'libs/modalUtil' import ErrorBox from 'libs/modalUtil'
import { formatDateTime } from 'libs/utils'
import { formatDateTime, openFullscreen } from 'libs/utils'
import { authRoutes } from 'router/routes' import { authRoutes } from 'router/routes'
import { useDeviceStore } from 'stores/deviceStore' import { useDeviceStore } from 'stores/deviceStore'
import { onUnmounted, ref, watchEffect } from 'vue'
import { onMounted, onUnmounted, ref, watchEffect } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
const router = useRouter() const router = useRouter()
@ -30,6 +31,26 @@ const disinfectState = ref(homeStore.disinfectionState.state)
const liquidAddState = ref(liquidStore.liquidAddWorkState) const liquidAddState = ref(liquidStore.liquidAddWorkState)
const liquidDrainState = ref(liquidStore.liquidDrainWorkState) const liquidDrainState = ref(liquidStore.liquidDrainWorkState)
const sealInfo = ref(sealStore.sealInfo) const sealInfo = ref(sealStore.sealInfo)
let touchStartTime = 0
let touchCount = 0
onMounted(() => {
// 3
document.body.addEventListener('touchstart', (event) => {
const now = Date.now()
const timeDiff = now - touchStartTime
if (timeDiff < 300 && timeDiff > 0) {
touchCount++
if (touchCount === 3) {
event.preventDefault()
openFullscreen()
}
}
else {
touchCount = 1
}
touchStartTime = now
})
})
const showWorkState = () => { const showWorkState = () => {
// //
@ -72,38 +93,13 @@ const showErrorModal = () => {
const onLogout = () => { const onLogout = () => {
// //
const hasEx = getDeviceStatus() const hasEx = getDeviceStatus()
if (hasEx) { //
if (hasEx) { //
FtMessageBox.error('退出登录前请停止当前的操作') FtMessageBox.error('退出登录前请停止当前的操作')
return
} }
else { //
FtMessageBox.warning('请确认是否退出登录?').then(() => {
router.push('/login')
})
}
}
const getDeviceStatus = () => {
console.log('disinfectState.value.state---', disinfectState.value)
if (disinfectState.value !== 'idle' && disinfectState.value !== 'finished') {
console.log('---正在消毒---')
return true
}
//
if (liquidAddState.value.workState !== 'idle') {
console.log('---正在加液---')
return true
}
//
if (liquidDrainState.value.workState !== 'idle') {
console.log('---正在排液---')
return true
}
//
if (sealInfo.value.workState !== 'idle') {
console.log('---正在密封性测试---')
return true
}
return false
FtMessageBox.warning('请确认是否退出登录?').then(() => {
router.push('/login')
})
} }
</script> </script>

42
src/libs/deviceComm.ts

@ -0,0 +1,42 @@
import { useHomeStore } from '@/stores/homeStore'
import { useLiquidStore } from '@/stores/liquidStore'
import { useSealStore } from '@/stores/sealStore'
import { ref, watchEffect } from 'vue'
const homeStore = useHomeStore()
const liquidStore = useLiquidStore()
const sealStore = useSealStore()
const addWorkState = ref(liquidStore.liquidStateData)// 加液状态
const drainWorkState = ref(liquidStore.liquidStateData)// 排液状态
const sealInfo = ref(sealStore.sealInfo)
watchEffect(() => {
addWorkState.value = liquidStore.liquidAddWorkState
drainWorkState.value = liquidStore.liquidDrainWorkState
sealInfo.value = sealStore.sealInfo
})
export const getDeviceStatus = () => {
let statusName = ''
if (!homeStore.isDeviceIdle) {
statusName = '正在进行消毒,不可操作'
return statusName
}
// 正在进行加液
if (addWorkState.value.workState !== 'idle') {
statusName = '正在进行加液操作...'
return statusName
}
// 正在进行排液
if (drainWorkState.value.workState !== 'idle') {
statusName = '正在进行排液操作...'
return statusName
}
// 正在密封测试
if (sealInfo.value.workState !== 'idle') {
statusName = '正在进行排液操作...'
return statusName
}
return statusName
}

3
src/libs/socket.ts

@ -1,4 +1,3 @@
// src/utils/websocket.ts
import type { Ref } from 'vue' import type { Ref } from 'vue'
import { ref, watch } from 'vue' import { ref, watch } from 'vue'
import { FtMessageBox } from './messageBox' import { FtMessageBox } from './messageBox'
@ -142,7 +141,7 @@ export class WebSocketClient {
} }
} }
// 类型安全的取消订阅方法
// 取消订阅方法
public unsubscribe(messageType: string | '*', callback: (response: Socket.WebSocketResponse) => void) { public unsubscribe(messageType: string | '*', callback: (response: Socket.WebSocketResponse) => void) {
const listeners = this.eventListeners.get(messageType) const listeners = this.eventListeners.get(messageType)
if (listeners) { if (listeners) {

68
src/libs/utils.ts

@ -40,3 +40,71 @@ export const sealStateMap = <Record<string, any>>{
leakText: '检漏中', leakText: '检漏中',
stopping: '停止中', stopping: '停止中',
} }
export const compareJSON = (obj1: any, obj2: any) => {
const result: Record<string, any> = {}
// 遍历obj1的所有属性
for (const key in obj1) {
if (Object.prototype.hasOwnProperty.call(obj1, key)) {
if (!Object.prototype.hasOwnProperty.call(obj2, key)) {
// obj2中不存在该属性
result[key] = { obj1: obj1[key], obj2: undefined }
}
else if (typeof obj1[key] !== typeof obj2[key]) {
// 类型不同
result[key] = { obj1: obj1[key], obj2: obj2[key] }
}
else if (typeof obj1[key] === 'object' && obj1[key] !== null && obj2[key] !== null) {
// 递归比较对象
const nestedDiff = compareJSON(obj1[key], obj2[key])
if (Object.keys(nestedDiff).length > 0) {
result[key] = nestedDiff
}
}
else if (obj1[key] !== obj2[key]) {
// 基本类型值不同
result[key] = { oldVal: obj1[key], newVal: obj2[key] }
}
}
}
return result
}
let isFullscreen = false
export const openFullscreen = () => {
const elem = document.documentElement
if (!isFullscreen) {
isFullscreen = true
elem.requestFullscreen()
}
else {
isFullscreen = false
document.exitFullscreen()
}
}
export const convertValuesToString = (jsonObj: Record<string, any>, exName: string) => {
const result: Record<string, any> = {}
for (const [key, value] of Object.entries(jsonObj)) {
if (key !== exName) {
result[key] = String(value)
}
else {
result[key] = value
}
}
return result
}
export const convertValuesToInt = (jsonObj: Record<string, any>, exName: string) => {
const result: Record<string, any> = {}
for (const [key, value] of Object.entries(jsonObj)) {
if (key !== exName) {
result[key] = Number(value)
}
else {
result[key] = value
}
}
return result
}

151
src/stores/formulaStore.ts

@ -1,18 +1,23 @@
import { syncSendCmd } from 'apis/system'
import { FtMessage } from '@/libs/message'
import { sendCmd, syncSendCmd } from 'apis/system'
import { cloneDeep } from 'lodash' import { cloneDeep } from 'lodash'
import { nanoid } from 'nanoid'
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { ref } from 'vue'
import { computed, ref } from 'vue'
const logList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].map((el) => {
return {
value: el,
name: `${el} Log`,
}
})
// 常量定义
const LOG_ITEMS = Array.from({ length: 12 }, (_, i) => ({
value: i + 1,
name: `${i + 1} Log`,
}))
const PRESSURE_TYPES = [
{ name: '常压', value: 'constantPressure' },
{ name: '正压', value: 'positivePressure' },
{ name: '负压', value: 'negativePressure' },
]
// 默认配方信息
const createDefaultFormulaInfo = () => ({
// 默认配方函数
const createDefaultFormulaInfo = (): Formula.FormulaItem => ({
continued_gs: 200, continued_gs: 200,
continued_humi: 60, continued_humi: 60,
continued_satur: 60, continued_satur: 60,
@ -25,114 +30,131 @@ const createDefaultFormulaInfo = () => ({
stoped_humi: 85, stoped_humi: 85,
stoped_satur: 85, stoped_satur: 85,
name: '默认配置', name: '默认配置',
formula_id: nanoid(),
}) })
export const useFormulaStore = defineStore('formula', () => { export const useFormulaStore = defineStore('formula', () => {
// 初始化数据
const logEnums = logList
const pressurList = [
{ name: '常压', value: 'constantPressure' },
{ name: '正压', value: 'positivePressure' },
{ name: '负压', value: 'negativePressure' },
]
const logLevels = ref<System.Option[]>([{
label: '',
value: '',
}])
// 状态定义
const logEnums = LOG_ITEMS
const pressurList = PRESSURE_TYPES
const logLevelOptions = ref<System.Option[]>([])
const defaultFormulaInfo = ref<Formula.FormulaItem>(createDefaultFormulaInfo()) const defaultFormulaInfo = ref<Formula.FormulaItem>(createDefaultFormulaInfo())
const pressurOptionList = ref<string[]>(['10%', '20%', '30%', '40%', '50%', '60%', '70%', '80%', '90%', '100%']) const pressurOptionList = ref<string[]>(['10%', '20%', '30%', '40%', '50%', '60%', '70%', '80%', '90%', '100%'])
const currentSelectedFormulaInfo = ref<Formula.FormulaItem>(cloneDeep(defaultFormulaInfo.value)) const currentSelectedFormulaInfo = ref<Formula.FormulaItem>(cloneDeep(defaultFormulaInfo.value))
const selectedFormulaInfo = ref()
const initFormulaInfo = ref<Formula.FormulaItem>(cloneDeep(defaultFormulaInfo.value))
// 配方可配置数据
const selectedFormulaInfo = ref<Formula.FormulaItem | null>(null)
const formulaConfigList = ref<Formula.FormulaConfig[]>([]) const formulaConfigList = ref<Formula.FormulaConfig[]>([])
const formulaList = ref<Formula.FormulaItem[]>([]) const formulaList = ref<Formula.FormulaItem[]>([])
const loglevel = ref<string>('1')
// 计算属性
const isDefaultFormula = computed(() => currentSelectedFormulaInfo.value.name === defaultFormulaInfo.value.name)
const names: Record<string, any> = {}
const initData = () => {
// 重置配方默认值 及 消毒等级
formulaConfigList.value.forEach((item) => {
// defaultFormulaInfo.value[item.setting_id] = item.default_val
names[item.setting_id] = item.name_ch
// 私有
const mapConfigToFormula = (config: Formula.FormulaConfig[]) => {
const formulaMap: Record<string, any> = {}
config.forEach((item) => {
formulaMap[item.setting_id] = Number(item.val)
if (item.val_type === 'enum' && item.setting_id === 'loglevel') { if (item.val_type === 'enum' && item.setting_id === 'loglevel') {
updateLogLevels(item) updateLogLevels(item)
} }
}) })
formulaMap.name = '默认配置'
return formulaMap as Formula.FormulaItem
} }
// 公共方法
const updateFormulaConfigData = (data: Formula.FormulaConfig[]) => { const updateFormulaConfigData = (data: Formula.FormulaConfig[]) => {
const config = data.filter(item => item.is_visible_in_formula_page)
formulaConfigList.value = config
const formulaMap: Record<string, any> = {}
config.forEach((item) => {
formulaMap[item.setting_id] = Number(item.val)
})
formulaMap.name = '默认配置'
defaultFormulaInfo.value = formulaMap as Formula.FormulaItem
const visibleConfig = data.filter(item => item.is_visible_in_formula_page)
formulaConfigList.value = visibleConfig
defaultFormulaInfo.value = mapConfigToFormula(visibleConfig)
} }
const updateLogLevels = (logLevelItem: Formula.FormulaConfig) => { const updateLogLevels = (logLevelItem: Formula.FormulaConfig) => {
const list: System.Option[] = [] const list: System.Option[] = []
const enum_display_names = logLevelItem.enum_display_names
const enums = logLevelItem.enums
enums && enums.forEach((item: number, index: number) => {
const { enum_display_names, enums } = logLevelItem
loglevel.value = String(logLevelItem.default_val)
enums?.forEach((item: number, index: number) => {
list.push({ list.push({
label: enum_display_names[index],
label: enum_display_names?.[index] || '',
value: item, value: item,
}) })
}) })
logLevels.value = list
logLevelOptions.value = list
}
const updateLogLevel = (level: string) => {
loglevel.value = level
} }
// 配方中的压力控制
const updatePressurList = (pressurData: string[]) => { const updatePressurList = (pressurData: string[]) => {
pressurOptionList.value = cloneDeep(pressurData) pressurOptionList.value = cloneDeep(pressurData)
} }
// 配方管理从列表中选择的配方 用来编辑及回显
const updateSelectedFormulaData = (formulaItem: Formula.FormulaItem) => { const updateSelectedFormulaData = (formulaItem: Formula.FormulaItem) => {
console.error('formulaItem----', formulaItem)
currentSelectedFormulaInfo.value = cloneDeep(formulaItem) currentSelectedFormulaInfo.value = cloneDeep(formulaItem)
} }
// 从配方列表中选择的配方
const updateSelectedFormulaDataByList = (formulaItem: Formula.FormulaItem) => { const updateSelectedFormulaDataByList = (formulaItem: Formula.FormulaItem) => {
selectedFormulaInfo.value = cloneDeep(formulaItem) selectedFormulaInfo.value = cloneDeep(formulaItem)
} }
const initFormulaList = () => {
const params = {
className: 'SettingMgrService',
fnName: 'getAllFormula',
params: {},
}
syncSendCmd(params).then((res) => {
const initFormulaList = async () => {
try {
const params = {
className: 'SettingMgrService',
fnName: 'getAllFormula',
params: {},
}
const res = await syncSendCmd(params)
if (res.rely) { if (res.rely) {
formulaList.value = res.rely formulaList.value = res.rely
} }
})
}
catch (error) {
console.error('获取配方列表失败', error)
}
} }
const initFormulaData = () => { const initFormulaData = () => {
initFormulaInfo.value = cloneDeep(defaultFormulaInfo.value)
selectedFormulaInfo.value = null
resetToDefaultFormula()
}
const resetToDefaultFormula = () => {
currentSelectedFormulaInfo.value = cloneDeep(defaultFormulaInfo.value)
} }
initData()
const saveDisinfectFormula = async (formData: Formula.FormulaItem) => {
try {
const params = {
className: 'DisinfectionCtrlServiceExt',
fnName: 'startWithFormula',
params: {
formulaid: formData.formula_id,
},
}
await sendCmd(params)
FtMessage.success('已启动消毒程序')
}
catch (error) {
console.error('保存消毒配方失败', error)
FtMessage.error('启动消毒程序失败')
}
}
return { return {
// 变量
// 属性
logEnums, logEnums,
pressurList, pressurList,
pressurOptionList, pressurOptionList,
initFormulaInfo,
currentSelectedFormulaInfo, currentSelectedFormulaInfo,
formulaList, formulaList,
formulaConfigList, formulaConfigList,
logLevels,
loglevel,
logLevelOptions,
selectedFormulaInfo, selectedFormulaInfo,
defaultFormulaInfo, defaultFormulaInfo,
isDefaultFormula,
// 方法 // 方法
updatePressurList, updatePressurList,
updateSelectedFormulaData, updateSelectedFormulaData,
@ -140,5 +162,8 @@ export const useFormulaStore = defineStore('formula', () => {
initFormulaList, initFormulaList,
updateSelectedFormulaDataByList, updateSelectedFormulaDataByList,
updateFormulaConfigData, updateFormulaConfigData,
saveDisinfectFormula,
updateLogLevel,
resetToDefaultFormula,
} }
}) })

146
src/stores/homeStore.ts

@ -1,7 +1,7 @@
import { sendCmd } from 'apis/system' import { sendCmd } from 'apis/system'
import { PARSSURE_DATA } from 'libs/constant' import { PARSSURE_DATA } from 'libs/constant'
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { ref } from 'vue'
import { computed, ref } from 'vue'
// 空闲 idle // 空闲 idle
// 初始化 init // 初始化 init
@ -16,43 +16,37 @@ import { ref } from 'vue'
const h2O2Data: Home.DisplayrelyMgrParams[] = [{ const h2O2Data: Home.DisplayrelyMgrParams[] = [{
type: 'inside', type: 'inside',
title: '仓内', title: '仓内',
temp: '20',
rh: '30',
rs: '40',
h2o2: '20',
}, {
type: 'probe1',
title: '探头1',
temp: '0',
rh: '0',
rs: '0',
h2o2: '0',
}, {
type: 'probe2',
title: '探头2',
temp: '0',
rh: '0',
rs: '0',
h2o2: '0',
temp: 0,
rh: 0,
rs: 0,
h2o2: 0,
chartId: 'inside',
}] }]
// 消毒中状态初始值
const initDisinfectState = {
curStateRemainTimeS: 0,
h2o2SensorData: h2O2Data,
injectedVelocity: 0,
nlog: 0,
state: 'idle',
statedisplayName: '空闲',
tlog: 0,
}
export const useHomeStore = defineStore('home', () => { export const useHomeStore = defineStore('home', () => {
const h2O2SensorData = ref(h2O2Data) const h2O2SensorData = ref(h2O2Data)
const pressureConfig = ref<Home.ParssureData>(PARSSURE_DATA)
const curStateRemainTime = ref<string>() const curStateRemainTime = ref<string>()
const loglevel = ref('1')
const logLevelList = [{
label: '1级',
value: 1,
}, {
label: '2级',
value: 2,
}, {
label: '3级',
value: 3,
}, {
label: '4级',
value: 4,
}]
const disinfectionState = ref<Home.DisinfectState>(initDisinfectState)// 当前设备正在消毒时的状态
const deviceStete = ref({ state: 'idle' }) // 设备状态
let renderTimer: any
/**
* @function updateHomeData
* @params data
* @desc
*/
const updateHomeData = (data: Home.DisplayrelyMgr[]) => { const updateHomeData = (data: Home.DisplayrelyMgr[]) => {
if (data && data.length) { if (data && data.length) {
data.forEach((item, index) => { data.forEach((item, index) => {
@ -64,8 +58,10 @@ export const useHomeStore = defineStore('home', () => {
} }
} }
// 压力值
const pressureConfig = ref<Home.ParssureData>(PARSSURE_DATA)
/**
* @function getPressureConfig
* @desc
*/
const getPressureConfig = async () => { const getPressureConfig = async () => {
const pressureParams = { const pressureParams = {
className: 'PipelinePressureControl', className: 'PipelinePressureControl',
@ -76,7 +72,11 @@ export const useHomeStore = defineStore('home', () => {
pressureConfig.value = res pressureConfig.value = res
} }
// 设置压力
/**
* @function updatePressure
* @param pressureData : 数组
* @desc
*/
const updatePressure = async (pressureData: string | number[]) => { const updatePressure = async (pressureData: string | number[]) => {
if (pressureData && pressureData.length) { if (pressureData && pressureData.length) {
const type = pressureData[0] const type = pressureData[0]
@ -88,8 +88,7 @@ export const useHomeStore = defineStore('home', () => {
}, },
} }
await sendCmd(pressureTypeParams) await sendCmd(pressureTypeParams)
// type 是正压或负压时保存设置的压力值
if (type === 'positivePressure' || type === 'positivePressure') {
if (type === 'positivePressure' || type === 'positivePressure') { // type 是正压或负压时保存设置的压力值
const intensity = pressureData[1] const intensity = pressureData[1]
const intensityParams = { const intensityParams = {
className: 'PipelinePressureControl', className: 'PipelinePressureControl',
@ -103,65 +102,64 @@ export const useHomeStore = defineStore('home', () => {
} }
} }
// 设置消毒等级
const updateLogLevel = (level: string) => {
loglevel.value = String(level)
}
const stopDisinfect = () => {
disinfectionState.value.state = 'finished'
}
// 设备状态
const deviceStete = ref({
state: 'idle',
})
/**
* @function setDeviceState
* @param deviceInfo
*/
const setDeviceState = (deviceInfo: Device.State) => { const setDeviceState = (deviceInfo: Device.State) => {
deviceStete.value = deviceInfo deviceStete.value = deviceInfo
} }
// 当前设备正在消毒时的状态
const disinfectionState = ref<Home.DisinfectState>({
curStateRemainTimeS: 0,
h2o2SensorData: [
{
h2o2: 0,
online: true,
rh: 32.79,
rs: 32.08,
temp: 25.89,
},
],
injectedVelocity: 0,
nlog: 0,
state: 'idle',
statedisplayName: '空闲',
tlog: 0,
})
/**
* @function updateHomeDisinfectionState
* @param disinfectState
*/
const updateHomeDisinfectionState = (disinfectState: Home.DisinfectState) => { const updateHomeDisinfectionState = (disinfectState: Home.DisinfectState) => {
disinfectionState.value = disinfectState disinfectionState.value = disinfectState
if (!renderTimer) {
renderTimer = setTimeout(() => {
h2O2SensorData.value = [...disinfectionState.value.h2o2SensorData] // 创建副本
renderTimer = null
}, 3000) as unknown as NodeJS.Timeout // 类型断言兼容不同环境
}
} }
/**
* @function updateHomeRemainTime
* @param timer
*/
const updateHomeRemainTime = (timer: string) => { const updateHomeRemainTime = (timer: string) => {
curStateRemainTime.value = timer curStateRemainTime.value = timer
} }
const isDeviceIdle = computed(() => {
return disinfectionState.value.state.toLocaleLowerCase() === 'idle' || disinfectionState.value.state === 'finished'
})
const subscribeDisinfectEvent = () => {
// 发起订阅
const subParams = {
className: 'DisinfectionCtrlServiceExt',
fnName: 'startStateReport',
params: {},
}
sendCmd(subParams)
}
return { return {
// 变量
// 属性
h2O2SensorData, h2O2SensorData,
logLevelList,
loglevel,
deviceStete, deviceStete,
disinfectionState, disinfectionState,
pressureConfig, pressureConfig,
curStateRemainTime, curStateRemainTime,
isDeviceIdle,
// 方法 // 方法
updateHomeData, updateHomeData,
updatePressure, updatePressure,
updateLogLevel,
stopDisinfect,
setDeviceState, setDeviceState,
updateHomeDisinfectionState, updateHomeDisinfectionState,
getPressureConfig, getPressureConfig,
updateHomeRemainTime, updateHomeRemainTime,
subscribeDisinfectEvent,
} }
}) })

4
src/stores/initHomeData.ts

@ -7,14 +7,11 @@ const liquidStore = useLiquidStore()
export const initData = async () => { export const initData = async () => {
// 初始化消毒液桶数据 // 初始化消毒液桶数据
console.log('--------1-------')
await initLiquidConfig() await initLiquidConfig()
// 轮询设备状态、消毒状态、消毒液使用状态 // 轮询设备状态、消毒状态、消毒液使用状态
// setInterval(() => { // setInterval(() => {
// }, 1000) // }, 1000)
console.log('--------2-------')
await initBaseData() await initBaseData()
console.log('--------3-------')
} }
const initLiquidConfig = async () => { const initLiquidConfig = async () => {
@ -24,7 +21,6 @@ const initLiquidConfig = async () => {
params: {}, params: {},
} }
const liquidConfig = await sendCmd(params) const liquidConfig = await sendCmd(params)
console.log('liquidConfig----------', liquidConfig)
liquidStore.initLiquidConfig(liquidConfig) liquidStore.initLiquidConfig(liquidConfig)
} }

2
src/stores/liquidStore.ts

@ -33,11 +33,13 @@ export const useLiquidStore = defineStore('Liquid', () => {
} }
return { return {
// 属性
liquidAddWorkState, liquidAddWorkState,
liquidDrainWorkState, liquidDrainWorkState,
liquidTotal, liquidTotal,
liquidPeriod, liquidPeriod,
liquidStateData, liquidStateData,
// 方法
updateAddLiquidWorkState, updateAddLiquidWorkState,
updateDrainLiquidWorkState, updateDrainLiquidWorkState,
initLiquidConfig, initLiquidConfig,

34
src/stores/settingStore.ts

@ -19,51 +19,37 @@ export const useSettingStore = defineStore('setting', () => {
code: 'deviceInfo', code: 'deviceInfo',
}] }]
const historyList = [
{
name: '2021-01-03',
},
{
name: '2021-01-02',
},
{
name: '2021-01-01',
},
]
const historyList: Record<string, string>[] = []
/* ********************** 用户管理 **************************** */ /* ********************** 用户管理 **************************** */
const userList = ref<Setting.User[]>([{
uid: 'admin(管理员)',
passwd: '111',
is_admin: true,
id: '02384',
}, {
uid: '测试人员',
passwd: '222',
is_admin: true,
id: '1111',
}])
const userList = ref<User.UserItem[]>([])
const addUserVisible = ref(false) const addUserVisible = ref(false)
const modifyPwdVisible = ref(false)
const userModalState = ref('add') const userModalState = ref('add')
const currentEditUser = ref<Setting.User>()
const currentEditUser = ref<User.UserItem>()
const updateUserModalState = (state: string) => { const updateUserModalState = (state: string) => {
userModalState.value = state userModalState.value = state
} }
const updateCurrentEditUser = (userItem: Setting.User) => {
const updateCurrentEditUser = (userItem: User.UserItem) => {
currentEditUser.value = userItem currentEditUser.value = userItem
} }
const updateVisible = (visible: boolean) => { const updateVisible = (visible: boolean) => {
addUserVisible.value = visible addUserVisible.value = visible
} }
const updatePwdVisible = (visible: boolean) => {
modifyPwdVisible.value = visible
}
return { return {
settingMenus, settingMenus,
historyList, historyList,
addUserVisible, addUserVisible,
modifyPwdVisible,
userModalState, userModalState,
currentEditUser, currentEditUser,
userList, userList,
updateVisible, updateVisible,
updateUserModalState, updateUserModalState,
updateCurrentEditUser, updateCurrentEditUser,
updatePwdVisible,
} }
}) })

8
src/types/audit.d.ts

@ -0,0 +1,8 @@
declare namespace Audit {
interface AuditItem {
behaviorZH: string
behaviorinfo: string
date: string
userName: string
}
}

4
src/types/formula.d.ts

@ -12,11 +12,11 @@ declare namespace Formula {
stoped_humi: string | number stoped_humi: string | number
stoped_satur: string | number stoped_satur: string | number
name: string | number name: string | number
formula_id: string | number
formula_id?: string | number
} }
interface FormulaConfig { interface FormulaConfig {
default_val: number | boolean
default_val: string | number | boolean
enum_display_names: Array enum_display_names: Array
enums: Array enums: Array
is_editable: boolean is_editable: boolean

19
src/types/home.d.ts

@ -1,13 +1,14 @@
declare namespace Home { declare namespace Home {
interface DisplayrelyMgr { interface DisplayrelyMgr {
temp: string
rh: string
rs: string
h2o2: string
temp: number
rh: number
rs: number
h2o2: number
} }
interface DisplayrelyMgrParams extends DisplayrelyMgr { interface DisplayrelyMgrParams extends DisplayrelyMgr {
type: string type: string
title: string title: string
chartId: string
} }
interface ResultData { interface ResultData {
@ -18,11 +19,11 @@ declare namespace Home {
getFormData: () => void getFormData: () => void
} }
interface DisinfectH2owState {
h2o2: string | number
temp: string | number
rh: string | number
rs: string | number
interface DisinfectH2owState extends DisplayrelyMgrParams {
h2o2: number
temp: number
rh: number
rs: number
online?: boolean online?: boolean
} }

14
src/types/user.d.ts

@ -30,4 +30,18 @@ declare namespace User {
name: string name: string
roleType: string roleType: string
} }
interface UserItem {
id?: number
name: string
passwd: string
roleType: string
confirmPasswd?: string
}
interface Passwd {
passwd: string
newpasswd: string
confirmNewpasswd?: string
}
} }

53
src/views/audit/index.vue

@ -1,30 +1,53 @@
<script lang="ts" setup> <script lang="ts" setup>
import { syncSendCmd } from 'apis/system'
import { FtMessage } from '@/libs/message'
import { sendCmd } from 'apis/system'
import { onMounted, ref } from 'vue' import { onMounted, ref } from 'vue'
const pageNum = ref(1) const pageNum = ref(1)
const pageSize = ref(10) const pageSize = ref(10)
const selectedUserList = ref<Audit.AuditItem[]>([])
const totle = ref(0)
onMounted(() => { onMounted(() => {
// //
getAuditList() getAuditList()
}) })
const getAuditList = () => {
const getAuditList = async () => {
const params = { const params = {
className: 'AuditMgrService', className: 'AuditMgrService',
fnName: 'getRecords', fnName: 'getRecords',
params: { params: {
page: pageNum.value, page: pageNum.value,
page_size: pageSize.value,
pageSize: pageSize.value,
}, },
} }
syncSendCmd(params).then((res) => {
console.log('audit === ', res)
})
const res = await sendCmd(params)
const items = res.items
tableData.value = items
totle.value = res.total
} }
const tableData = ref() const tableData = ref()
const onExportRecord = () => {}
const onExportRecord = () => {
if (selectedUserList.value.length !== 1) {
FtMessage.warning('选择一条数据进行导出')
return
}
const params = {
className: 'AuditMgrService',
fnName: 'exportData',
params: {},
}
sendCmd(params)
}
const handleCurrentChange = (page: number) => {
pageNum.value = page
getAuditList()
}
const handleSelectionChange = (users: Audit.AuditItem[]) => {
selectedUserList.value = users
}
</script> </script>
<template> <template>
@ -39,13 +62,16 @@ const onExportRecord = () => {}
/> />
</div> </div>
<div> <div>
<el-table :data="tableData" stripe style="width: 100%">
<el-table :data="tableData" stripe style="width: 100%" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" /> <el-table-column type="selection" width="55" />
<el-table-column prop="name" label="操作人" />
<el-table-column prop="content" label="操作内容" />
<el-table-column prop="createTime" label="操作时间" />
<el-table-column prop="usrName" label="操作人" width="100" />
<el-table-column prop="behaviorinfo" label="操作内容" />
<el-table-column prop="date" label="操作时间" />
</el-table> </el-table>
</div> </div>
<div class="audit-pagination">
<el-pagination layout="prev, pager, next" :total="totle" @current-change="handleCurrentChange" />
</div>
</div> </div>
</main> </main>
</div> </div>
@ -60,5 +86,10 @@ const onExportRecord = () => {}
.audit-export{ .audit-export{
margin: 2vw; margin: 2vw;
} }
.audit-pagination{
bottom: 3rem;
position: absolute;
right: 2rem;
}
} }
</style> </style>

66
src/views/debug/index.vue

@ -5,13 +5,11 @@ import { useHomeStore } from 'stores/homeStore'
import { ref, watch } from 'vue' import { ref, watch } from 'vue'
const homeStore = useHomeStore() const homeStore = useHomeStore()
const insideEnvParams = ref<Home.DisplayrelyMgrParams>(homeStore.h2O2SensorData[0])
const env1Params = ref<Home.DisplayrelyMgrParams>(homeStore.h2O2SensorData[1])
const env2Params = ref<Home.DisplayrelyMgrParams>(homeStore.h2O2SensorData[2])
const h2O2SensorData = ref<Home.DisplayrelyMgrParams[]>(homeStore.h2O2SensorData)
watch(() => homeStore.h2O2SensorData, (newVal) => { watch(() => homeStore.h2O2SensorData, (newVal) => {
if (newVal && newVal.length) { if (newVal && newVal.length) {
insideEnvParams.value = newVal[0]
h2O2SensorData.value = newVal
} }
}, { deep: true }) }, { deep: true })
@ -88,56 +86,26 @@ const onBottomState = () => {}
<main class="main-content"> <main class="main-content">
<!-- 上下布局 --> <!-- 上下布局 -->
<section class="debug-upper"> <section class="debug-upper">
<div class="debug-left-lh">
<div v-for="(item, index) in h2O2SensorData" :key="index" class="debug-left-lh">
<div class="debug-label"> <div class="debug-label">
仓内环境
{{ index === 0 ? '仓内环境' : item.title }}
</div> </div>
<div> <div>
<span>温度</span> <span>温度</span>
<span class="debug-text">{{ roundNumber(insideEnvParams.temp, 2) }}</span>°C
<span class="debug-text">{{ roundNumber(item.temp, 2) }}</span>°C
</div> </div>
<div> <div>
<span>湿度</span> <span>湿度</span>
<span class="debug-text">{{ roundNumber(insideEnvParams.rh, 2) }}</span>
<span class="debug-text">{{ roundNumber(item.rh, 2) }}</span>
</div> </div>
<div> <div>
<span>过氧化氢浓度</span> <span>过氧化氢浓度</span>
<span class="debug-text">{{ roundNumber(insideEnvParams.rs, 2) }}</span>PPM
</div>
</div>
<div class="debug-left-lh">
<div class="debug-label">探头1环境</div>
<div>
<span>温度</span>
<span class="debug-text">{{ roundNumber(env1Params.temp, 2) }}</span>°C
</div>
<div>
<span>湿度</span>
<span class="debug-text">{{ roundNumber(env2Params.rh, 2) }}</span>
</div>
<div>
<span>过氧化氢浓度</span>
<span class="debug-text">60</span>PPM
</div>
</div>
<div class="debug-left-lh">
<div class="debug-label">探头2环境</div>
<div>
<span>温度</span>
<span class="debug-text">{{ roundNumber(env2Params.temp, 2) }}</span>°C
</div>
<div>
<span>湿度</span>
<span class="debug-text">{{ roundNumber(env2Params.rh, 2) }}</span>
</div>
<div>
<span>过氧化氢浓度</span>
<span class="debug-text">{{ roundNumber(env2Params.rs, 2) }}</span>PPM
<span class="debug-text">{{ roundNumber(item.h2o2, 2) }}</span>PPM
</div> </div>
</div> </div>
</section> </section>
<div class="debug-lower"> <div class="debug-lower">
<section >
<section>
<div> <div>
<div class="debug-left-lh"> <div class="debug-left-lh">
<div class="debug-label"> <div class="debug-label">
@ -147,8 +115,8 @@ const onBottomState = () => {}
<bt-button <bt-button
type="primary" type="primary"
button-text="加液" button-text="加液"
@click="onAddLiquid">
</bt-button>
@click="onAddLiquid"
/>
</div> </div>
<div> <div>
<bt-button <bt-button
@ -160,8 +128,8 @@ const onBottomState = () => {}
<div> <div>
<bt-button <bt-button
button-text="关闭" button-text="关闭"
@click="onOffLiquidMotor">
</bt-button>
@click="onOffLiquidMotor"
/>
</div> </div>
</div> </div>
<div class="debug-left-lh"> <div class="debug-left-lh">
@ -174,17 +142,15 @@ const onBottomState = () => {}
<div> <div>
<bt-button <bt-button
type="primary" type="primary"
@click="onOpenAirPump"
button-text="打开" button-text="打开"
>
</bt-button>
@click="onOpenAirPump"
/>
</div> </div>
<div> <div>
<bt-button <bt-button
@click="onCloseAirPump"
button-text="关闭" button-text="关闭"
>
</bt-button>
@click="onCloseAirPump"
/>
</div> </div>
</div> </div>
<div class="debug-left-lh"> <div class="debug-left-lh">

90
src/views/home/chart.vue

@ -1,45 +1,83 @@
<script lang="ts" setup> <script lang="ts" setup>
import { useFormulaStore } from '@/stores/formulaStore' import { useFormulaStore } from '@/stores/formulaStore'
import { useHomeStore } from '@/stores/homeStore' import { useHomeStore } from '@/stores/homeStore'
import { sendCmd } from 'apis/system'
import homeFinish from 'assets/images/home/home-finish.svg' import homeFinish from 'assets/images/home/home-finish.svg'
import homeSettingSvg from 'assets/images/home/home-setting.svg' import homeSettingSvg from 'assets/images/home/home-setting.svg'
import Config from 'components/home/Config.vue'
import HomeFormula from 'components/home/HomeFormula.vue' import HomeFormula from 'components/home/HomeFormula.vue'
import LineChart from 'components/home/LineChart.vue' import LineChart from 'components/home/LineChart.vue'
import { stopTimer } from 'libs/countdownTimer' import { stopTimer } from 'libs/countdownTimer'
import { ref, watchEffect } from 'vue'
import { deviceStateMap } from 'libs/utils'
import { cloneDeep } from 'lodash'
import { provide, ref, watchEffect } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
const configRef = ref()
provide<(methods: Home.GrandsonMethods) => void>('registerGrandsonMethods', (methods) => {
configRef.value = methods
})
const router = useRouter() const router = useRouter()
const formulaStore = useFormulaStore() const formulaStore = useFormulaStore()
const homeStore = useHomeStore() const homeStore = useHomeStore()
const formulaInfo = ref() const formulaInfo = ref()
const disinfectionState = ref(homeStore.disinfectionState) const disinfectionState = ref(homeStore.disinfectionState)
const curStateRemainTime = ref(homeStore.curStateRemainTime) const curStateRemainTime = ref(homeStore.curStateRemainTime)
const disinfectFormulaVisible = ref(false)
const isDeviceIdle = ref(homeStore.isDeviceIdle)
const loading = ref(false)
const h2O2SensorData = ref(homeStore.h2O2SensorData)
watchEffect(() => { watchEffect(() => {
formulaInfo.value = formulaStore.currentSelectedFormulaInfo formulaInfo.value = formulaStore.currentSelectedFormulaInfo
disinfectionState.value = homeStore.disinfectionState disinfectionState.value = homeStore.disinfectionState
curStateRemainTime.value = homeStore.curStateRemainTime curStateRemainTime.value = homeStore.curStateRemainTime
isDeviceIdle.value = homeStore.isDeviceIdle
console.log('homeStore.h2O2SensorData---', homeStore.h2O2SensorData)
h2O2SensorData.value = homeStore.h2O2SensorData.map((item, index) => {
return {
...item,
title: index === 0 ? '仓内' : `探头${index}`,
chartId: index === 0 ? 'inside' : `env${index}`,
}
})
}) })
const onDisinfectConfig = () => {
const onDisinfectConfig = () => {
disinfectFormulaVisible.value = true
} }
// //
const onFinishDisinfect = () => {
const onFinishDisinfect = async () => {
stopTimer() stopTimer()
homeStore.updateHomeDisinfectionState({
...disinfectionState.value,
state: 'idle',
})
const stopParams = {
className: 'DisinfectionCtrlServiceExt',
fnName: 'stop',
params: {
loglevel: formulaStore.loglevel,
},
}
loading.value = true
await sendCmd(stopParams)
loading.value = false
}
const onSave = () => {
const formData = configRef.value?.getFormData()
formulaStore.updateSelectedFormulaDataByList(cloneDeep(formData))
onClose()
} }
const goHome = () => { const goHome = () => {
router.back() router.back()
} }
const onClose = () => {
disinfectFormulaVisible.value = false
}
</script> </script>
<template> <template>
<main class="main-content">
<main v-loading="loading" class="main-content">
<div class="line-chart-title"> <div class="line-chart-title">
<div v-if="formulaInfo && formulaInfo.name" class="line-chart-formula"> <div v-if="formulaInfo && formulaInfo.name" class="line-chart-formula">
<HomeFormula /> <HomeFormula />
@ -52,10 +90,12 @@ const goHome = () => {
height="3.5rem" height="3.5rem"
text-color="#1989fa" text-color="#1989fa"
padding="0.8vw" padding="0.8vw"
@click="onDisinfectConfig"
@click="goHome"
> >
<template #icon> <template #icon>
<el-icon style="font-weight: bold;"><Operation /></el-icon>
<el-icon style="font-weight: bold;">
<Operation />
</el-icon>
</template> </template>
</bt-button> </bt-button>
<bt-button <bt-button
@ -73,33 +113,33 @@ const goHome = () => {
</bt-button> </bt-button>
</div> </div>
</div> </div>
<div class="line-chart-content">
<div>
<LineChart key="1" title="仓内" chart-id="inside" />
</div>
<div>
<LineChart key="2" title="探头1" chart-id="env1" />
</div>
<div>
<LineChart key="3" title="探头2" chart-id="env2" />
<div class="line-chart-content" :style="{ 'grid-template-columns': `repeat(${h2O2SensorData.length},1fr)` }">
<div v-for="item in h2O2SensorData" :key=" item.title">
<LineChart :title="item.title" :chart-id="item.chartId" :env-data="item" />
</div> </div>
</div> </div>
<div class="line-chart-bottom"> <div class="line-chart-bottom">
<div class="home-chart-time"> <div class="home-chart-time">
<div class="home-remain-time">
<div v-if="!homeStore.isDeviceIdle" class="home-remain-time">
<div class="home-chart-label"> <div class="home-chart-label">
预计剩余时间:
<span v-if="disinfectionState.state === 'disinfection'">
预计剩余时间:
</span>
<span v-else>
消毒状态
</span>
</div> </div>
<div v-if="curStateRemainTime" class="home-chart-value"> <div v-if="curStateRemainTime" class="home-chart-value">
{{ curStateRemainTime }} {{ curStateRemainTime }}
</div> </div>
<div v-else class="home-chart-value"> <div v-else class="home-chart-value">
空闲
{{ deviceStateMap[disinfectionState.state] }}
</div> </div>
</div> </div>
</div> </div>
<div class="home-chart-btn"> <div class="home-chart-btn">
<bt-button <bt-button
v-if="!isDeviceIdle"
button-text="结束消毒" button-text="结束消毒"
bg-color="#FF6767" bg-color="#FF6767"
text-color="#FFFFFF" text-color="#FFFFFF"
@ -124,6 +164,11 @@ const goHome = () => {
/> />
</div> </div>
</div> </div>
<ft-dialog v-model="disinfectFormulaVisible" width="80vw" :ok-handle="onSave" @cancel="onClose">
<div>
<Config ref="configRef" />
</div>
</ft-dialog>
</main> </main>
</template> </template>
@ -156,7 +201,6 @@ const goHome = () => {
} }
.line-chart-content{ .line-chart-content{
display: grid; display: grid;
grid-template-columns: repeat(3,1fr);
height: 65%; height: 65%;
} }
.line-chart-bottom{ .line-chart-bottom{

21
src/views/home/index.vue

@ -19,8 +19,16 @@ const liquidStore = useLiquidStore()
const formulaStore = useFormulaStore() const formulaStore = useFormulaStore()
const systemStore = useSystemStore() const systemStore = useSystemStore()
const environmentParams = ref<Home.DisplayrelyMgrParams>(homeStore.h2O2SensorData[0]) const environmentParams = ref<Home.DisplayrelyMgrParams>(homeStore.h2O2SensorData[0])
const probe1Params = ref<Home.DisplayrelyMgrParams>(homeStore.h2O2SensorData[1])
const probe2Params = ref<Home.DisplayrelyMgrParams>(homeStore.h2O2SensorData[2])
const initEnv1 = {
type: 'env1',
title: '探头1',
}
const initEnv2 = {
type: 'env2',
title: '探头2',
}
const probe1Params = ref<Home.DisplayrelyMgrParams>(homeStore.h2O2SensorData[1] || initEnv1)
const probe2Params = ref<Home.DisplayrelyMgrParams>(homeStore.h2O2SensorData[2] || initEnv2)
const liquidInfo = ref<Liquid.LiquidData>(liquidStore.liquidStateData) const liquidInfo = ref<Liquid.LiquidData>(liquidStore.liquidStateData)
const liquidTotal = ref<number>(liquidStore.liquidTotal) const liquidTotal = ref<number>(liquidStore.liquidTotal)
const formulaInfo = ref() const formulaInfo = ref()
@ -32,14 +40,21 @@ watchEffect(() => {
liquidInfo.value = liquidStore.liquidStateData liquidInfo.value = liquidStore.liquidStateData
loading.value = systemStore.loading loading.value = systemStore.loading
if (homeStore.h2O2SensorData && homeStore.h2O2SensorData.length) { if (homeStore.h2O2SensorData && homeStore.h2O2SensorData.length) {
environmentParams.value = homeStore.h2O2SensorData[0]
environmentParams.value = {
...homeStore.h2O2SensorData[0],
title: '仓内',
type: 'inside',
}
} }
}) })
//
const nowLiquidProgress = computed(() => { const nowLiquidProgress = computed(() => {
const nl = roundNumber(Number(((liquidInfo.value.nowLiquid / liquidTotal.value) * 100)), 0) const nl = roundNumber(Number(((liquidInfo.value.nowLiquid / liquidTotal.value) * 100)), 0)
return nl return nl
}) })
//
const nowLiquid = computed(() => { const nowLiquid = computed(() => {
return roundNumber(liquidInfo.value.nowLiquid, 0) return roundNumber(liquidInfo.value.nowLiquid, 0)
}) })

92
src/views/liquid/index.vue

@ -1,5 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { getDeviceStatus } from '@/libs/deviceComm'
import { FtMessage } from '@/libs/message' import { FtMessage } from '@/libs/message'
import { FtMessageBox } from '@/libs/messageBox'
import { useHomeStore } from '@/stores/homeStore' import { useHomeStore } from '@/stores/homeStore'
import { useLiquidStore } from '@/stores/liquidStore' import { useLiquidStore } from '@/stores/liquidStore'
import { useSealStore } from '@/stores/sealStore' import { useSealStore } from '@/stores/sealStore'
@ -23,15 +25,19 @@ const keyboardVisible = ref(false)
const keyboardType = ref<'text' | 'number'>('number') const keyboardType = ref<'text' | 'number'>('number')
const softKeyboardRef = ref() const softKeyboardRef = ref()
const liquidStateData = ref(liquidStore.liquidStateData) const liquidStateData = ref(liquidStore.liquidStateData)
//
const addWorkState = ref(liquidStore.liquidStateData)
//
const drainWorkState = ref(liquidStore.liquidStateData)
//
const liquidTotoal = ref(liquidStore.liquidTotal)
const addWorkState = ref(liquidStore.liquidStateData)//
const drainWorkState = ref(liquidStore.liquidStateData)//
const liquidTotoal = ref(liquidStore.liquidTotal)//
const disinfectionState = ref(homeStore.disinfectionState) const disinfectionState = ref(homeStore.disinfectionState)
const sealInfo = ref(sealStore.sealInfo) const sealInfo = ref(sealStore.sealInfo)
const loading = ref(false) const loading = ref(false)
const btnStyle = {
width: '27vw',
height: '7vh',
textSize: '24px',
borderRadius: '12px',
textColor: '#FFFFFF',
}
onMounted(() => { onMounted(() => {
subScribeLiquid() subScribeLiquid()
@ -48,7 +54,7 @@ watchEffect(() => {
loading.value = systemStore.loading loading.value = systemStore.loading
}) })
const subScribeLiquid = () => {
const subScribeLiquid = () => { //
subscribeEvent('stateUpdate', (data: Socket.WebSocketResponse<Liquid.LiquidData>) => { subscribeEvent('stateUpdate', (data: Socket.WebSocketResponse<Liquid.LiquidData>) => {
if (data.fromClass === 'AddLiquidService') { if (data.fromClass === 'AddLiquidService') {
liquidStore.updateAddLiquidWorkState(data.rely) liquidStore.updateAddLiquidWorkState(data.rely)
@ -75,7 +81,7 @@ const handleConfirm = (value: string) => {
const onStartAddLiquid = async () => { const onStartAddLiquid = async () => {
const statusName = getDeviceStatus() const statusName = getDeviceStatus()
if (statusName) { if (statusName) {
ElMessage.warning(statusName)
FtMessageBox.error(statusName)
return return
} }
if (!stopatg.value || stopatg.value < 0) { if (!stopatg.value || stopatg.value < 0) {
@ -118,7 +124,7 @@ const onStopAddLiquid = () => {
const onStartDrainLiquid = async () => { const onStartDrainLiquid = async () => {
const statusName = getDeviceStatus() const statusName = getDeviceStatus()
if (statusName) { if (statusName) {
ElMessage.warning(statusName)
FtMessageBox.error(statusName)
return return
} }
const params = { const params = {
@ -135,7 +141,6 @@ const onStartDrainLiquid = async () => {
params: {}, params: {},
} }
syncSendCmd(subParams) syncSendCmd(subParams)
// liquidStore.updateDrainLiquidWorkState('work')
} }
const onStopDrainLiquid = async () => { const onStopDrainLiquid = async () => {
@ -151,31 +156,6 @@ const onStopDrainLiquid = async () => {
systemStore.updateLoading(true) systemStore.updateLoading(true)
await syncSendCmd(params) await syncSendCmd(params)
} }
const getDeviceStatus = () => {
let statusName = ''
if (disinfectionState.value.state !== 'idle' && disinfectionState.value.state !== 'finished') {
statusName = '正在进行消毒,不可操作'
return statusName
}
//
if (addWorkState.value.workState !== 'idle') {
statusName = '正在进行加液操作...'
return statusName
}
//
if (drainWorkState.value.workState !== 'idle') {
statusName = '正在进行排液操作...'
return statusName
}
//
if (sealInfo.value.workState !== 'idle') {
statusName = '正在进行排液操作...'
return statusName
}
return statusName
}
</script> </script>
<template> <template>
@ -207,7 +187,7 @@ const getDeviceStatus = () => {
<template #append> <template #append>
<bt-button <bt-button
type="primary" type="primary"
button-text="2500g"
:button-text="`${liquidTotoal}g`"
bg-color="#2892F3" bg-color="#2892F3"
text-color="#ffffff" text-color="#ffffff"
height="4rem" height="4rem"
@ -225,11 +205,11 @@ const getDeviceStatus = () => {
v-if="addWorkState.workState === 'idle'" v-if="addWorkState.workState === 'idle'"
button-text="开始加液" button-text="开始加液"
bg-color="#31CB7A" bg-color="#31CB7A"
text-color="#FFFFFF"
width="27vw"
height="7vh"
text-size="24px"
border-radius="12px"
:text-color="btnStyle.textColor"
:width="btnStyle.width"
:height="btnStyle.height"
:text-size="btnStyle.textSize"
:border-radius="btnStyle.borderRadius"
@click="onStartAddLiquid" @click="onStartAddLiquid"
> >
<template #icon> <template #icon>
@ -240,11 +220,11 @@ const getDeviceStatus = () => {
v-else v-else
button-text="停止加液" button-text="停止加液"
bg-color="#FF6767" bg-color="#FF6767"
text-color="#FFFFFF"
width="27vw"
height="7vh"
text-size="24px"
border-radius="12px"
:text-color="btnStyle.textColor"
:width="btnStyle.width"
:height="btnStyle.height"
:text-size="btnStyle.textSize"
:border-radius="btnStyle.borderRadius"
@click="onStopAddLiquid" @click="onStopAddLiquid"
> >
<template #icon> <template #icon>
@ -257,11 +237,11 @@ const getDeviceStatus = () => {
v-if="drainWorkState.workState === 'idle'" v-if="drainWorkState.workState === 'idle'"
button-text="开始排液" button-text="开始排液"
bg-color="#2892F3" bg-color="#2892F3"
text-color="#FFFFFF"
width="27vw"
height="7vh"
text-size="24px"
border-radius="12px"
:text-color="btnStyle.textColor"
:width="btnStyle.width"
:height="btnStyle.height"
:text-size="btnStyle.textSize"
:border-radius="btnStyle.borderRadius"
@click="onStartDrainLiquid" @click="onStartDrainLiquid"
> >
<template #icon> <template #icon>
@ -272,11 +252,11 @@ const getDeviceStatus = () => {
v-else v-else
button-text="停止排液" button-text="停止排液"
bg-color="#FF6767" bg-color="#FF6767"
text-color="#FFFFFF"
width="27vw"
height="7vh"
text-size="24px"
border-radius="12px"
:text-color="btnStyle.textColor"
:width="btnStyle.width"
:height="btnStyle.height"
:text-size="btnStyle.textSize"
:border-radius="btnStyle.borderRadius"
@click="onStopDrainLiquid" @click="onStopDrainLiquid"
> >
<template #icon> <template #icon>

18
src/views/seal/index.vue

@ -1,5 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { getDeviceStatus } from '@/libs/deviceComm'
import { FtMessage } from '@/libs/message' import { FtMessage } from '@/libs/message'
import { FtMessageBox } from '@/libs/messageBox'
import { useSealStore } from '@/stores/sealStore' import { useSealStore } from '@/stores/sealStore'
import { useSystemStore } from '@/stores/systemStore' import { useSystemStore } from '@/stores/systemStore'
import { subscribeEvent, syncSendCmd } from 'apis/system' import { subscribeEvent, syncSendCmd } from 'apis/system'
@ -69,6 +71,11 @@ const onStartTest = () => {
FtMessage.warning('请输入测试时间') FtMessage.warning('请输入测试时间')
return return
} }
const statusName = getDeviceStatus()
if (statusName) {
FtMessageBox.error(statusName)
return
}
const params = { const params = {
className: 'AirLeakDetectTest', className: 'AirLeakDetectTest',
fnName: 'start', fnName: 'start',
@ -94,7 +101,6 @@ const onStartTest = () => {
}) })
} }
const onFinishTest = () => { const onFinishTest = () => {
// sealStore.updateSealState('idle')
const stopParams = { const stopParams = {
className: 'AirLeakDetectTest', className: 'AirLeakDetectTest',
fnName: 'stop', fnName: 'stop',
@ -136,7 +142,7 @@ const stopDisabled = computed(() => {
<div v-if="sealInfo.workState === 'idle'" class="seal-time-statue seal-time-text"> <div v-if="sealInfo.workState === 'idle'" class="seal-time-statue seal-time-text">
未开始 未开始
</div> </div>
<div v-else>
<div v-else class="seal-test-time">
{{ sealRemainTimeS }} {{ sealRemainTimeS }}
</div> </div>
</div> </div>
@ -147,7 +153,7 @@ const stopDisabled = computed(() => {
<div v-if="sealInfo.workState === 'idle'" class="seal-diff-statue seal-diff-text"> <div v-if="sealInfo.workState === 'idle'" class="seal-diff-statue seal-diff-text">
未开始 未开始
</div> </div>
<div v-else>
<div v-else class="seal-test-time">
{{ realTimePressure }} {{ realTimePressure }}
</div> </div>
</div> </div>
@ -274,7 +280,7 @@ const stopDisabled = computed(() => {
justify-content: center; justify-content: center;
align-items: center; align-items: center;
background: #F6FAFE; background: #F6FAFE;
width: 15rem;
width: 16rem;
height: 5rem; height: 5rem;
border-radius: 15px; border-radius: 15px;
} }
@ -283,6 +289,10 @@ const stopDisabled = computed(() => {
font-weight: 500; font-weight: 500;
padding-left: 0.5rem; padding-left: 0.5rem;
} }
.seal-test-time{
font-size: 24px;
color: #2892F3;
}
.seal-time-statue{ .seal-time-statue{
height: 3rem; height: 3rem;
width: 5rem; width: 5rem;

6
src/views/setting/index.vue

@ -1,5 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import FormulaConfig from '@/components/formula/FormulaConfig.vue' import FormulaConfig from '@/components/formula/FormulaConfig.vue'
import Device from '@/components/setting/Device.vue'
import SystemDate from '@/components/setting/SystemDate.vue'
import User from '@/components/setting/User.vue' import User from '@/components/setting/User.vue'
import { useSettingStore } from '@/stores/settingStore' import { useSettingStore } from '@/stores/settingStore'
import History from 'components/setting/History.vue' import History from 'components/setting/History.vue'
@ -40,10 +42,10 @@ const selectItem = (menuCode: string) => {
<User /> <User />
</div> </div>
<div v-if="selectedMenuCode === 'date'"> <div v-if="selectedMenuCode === 'date'">
日期
<SystemDate />
</div> </div>
<div v-if="selectedMenuCode === 'deviceInfo'"> <div v-if="selectedMenuCode === 'deviceInfo'">
设备信息
<Device />
</div> </div>
</div> </div>
</main> </main>

Loading…
Cancel
Save