Browse Source

fix: 首页和图表添加实时消毒等级和ui优化

master
guoapeng 1 week ago
parent
commit
30ac801641
  1. 7
      src/app.vue
  2. 85
      src/components/home/HomeFormula.vue
  3. 11
      src/components/home/HomeOperation.vue
  4. 1
      src/components/home/HomeSetting.vue
  5. 10
      src/components/home/LineChart.vue
  6. 18
      src/libs/constant.ts
  7. 7
      src/stores/homeStore.ts
  8. 187
      src/views/home/chart.vue
  9. 12
      src/views/home/index.vue

7
src/app.vue

@ -1,16 +1,15 @@
<script setup lang="ts">
import { useDebugStore } from 'stores/debugStore'
import { useDeviceStore } from 'stores/deviceStore'
import { useFormulaStore } from 'stores/formulaStore'
import { useHomeStore } from 'stores/homeStore'
import { useLiquidStore } from 'stores/liquidStore'
import { useSealStore } from 'stores/sealStore'
import { useSystemStore } from 'stores/systemStore'
import { onBeforeMount, ref } from 'vue'
import { sendCmd, subscribeEvent } from '@/apis/system'
import { useDebugStore } from './stores/debugStore'
import { useFormulaStore } from './stores/formulaStore'
import { useSealStore } from './stores/sealStore'
/**
* 应用初始化组件
* @description 负责系统初始化流程控制包括设备信息获取数据同步及进度展示

85
src/components/home/HomeFormula.vue

@ -9,45 +9,60 @@ const formulaStore = useFormulaStore()
const homeStore = useHomeStore()
const formulaInfo = ref()
const rate = ref()
const log = ref()
watchEffect(async () => {
if (['idle', 'finished'].includes(homeStore.disinfectionState.state)) {
formulaInfo.value = formulaStore.selectedFormulaInfo
rate.value = formulaStore.selectedFormulaInfo?.injection_pump_speed
log.value = formulaStore.selectedFormulaInfo?.loglevel
}
else {
rate.value = homeStore.realRate || (await formulaStore.getRealtimeConfig()).rely?.injection_pump_speed
const realForm = (await formulaStore.getRealtimeConfig()).rely
rate.value = homeStore.realRate || realForm?.injection_pump_speed
log.value = homeStore.realLog || realForm?.loglevel
}
})
</script>
<template>
<div class="home-right-title">
<div class="title-formula">
<el-icon style="color: #31cb7a; font-size: 1.5rem">
<SuccessFilled />
</el-icon>
<el-descriptions :column="1">
<el-descriptions-item label="配方">
<el-tooltip :content="formulaInfo?.name || '默认'" placement="bottom-start">
<div class="name-text">
<div class="text">
{{ formulaInfo?.name || '默认' }}
</div>
</el-tooltip>
</div>
<div v-if="rate" class="title-spend">
<span>速率</span>
<span style="color: #31cb7a">{{ homeStore.disinfectionState.injectedVelocity }}</span>g/分钟
</div>
</el-descriptions-item>
<el-descriptions-item label="设定注射速率">
<el-tag>
<span style="color: #31cb7a; font-size: 18px; margin: 0 5px">{{ rate }}</span>g/min
</el-tag>
</el-descriptions-item>
<el-descriptions-item label="实时注射速率">
<el-tag>
<span style="color: #31cb7a; font-size: 18px; margin: 0 5px">{{
homeStore.disinfectionState.injectedVelocity
}}</span>g/min
</el-tag>
</el-descriptions-item>
<el-descriptions-item label="目标消毒等级">
<el-tag>
<span style="color: #31cb7a; font-size: 18px; margin: 0 5px">{{ log }}</span>Log
</el-tag>
</el-descriptions-item>
<el-descriptions-item label="实时消毒等级">
<el-tag>
<span style="color: #31cb7a; font-size: 18px; margin: 0 5px">{{ homeStore.disinfectionState.nlog }}</span>Log
</el-tag>
</el-descriptions-item>
</el-descriptions>
</div>
</template>
<style lang="scss" scoped>
.home-right-title {
background: #fff;
width: 100%;
border-radius: 10px;
margin: 10px auto;
display: grid;
grid-template-columns: 1fr 1fr;
font-size: 1.5rem;
.title-formula {
width: 100%;
display: flex;
@ -79,4 +94,38 @@ watchEffect(async () => {
font-size: 1.5rem;
}
}
:deep(.el-descriptions) {
width: 100%;
.el-descriptions__body {
background: rgba(0, 0, 0, 0);
}
}
:deep(.el-descriptions__cell) {
display: flex;
align-items: center;
background: #fff;
margin-bottom: 5px;
padding: 5px !important;
.el-descriptions__label {
display: inline-block;
width: 120px;
margin: 0;
font-size: 15px;
font-weight: 600;
color: #606266;
}
.el-descriptions__content {
flex: 1;
text-align: right;
display: flex;
justify-content: flex-end;
}
}
.text {
text-align: right;
width: 150px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>

11
src/components/home/HomeOperation.vue

@ -117,6 +117,7 @@ const doStartDisinfect = async () => {
const onFinishDisinfect = () => {
FtMessageBox.warning('请确认是否结束消毒').then(() => {
homeStore.setRate(undefined)
homeStore.setLog(undefined)
doStopDisinfect()
})
}
@ -264,16 +265,14 @@ const formatSeconds = (seconds: number) => {
background: #ff6767;
}
.home-remain-time {
background: #f6fafe;
margin-top: 1.5em;
margin-left: 1rem;
margin-right: 1rem;
height: 8vh;
background: #fff;
margin: 10px;
height: 40px;
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
font-size: 20px;
gap: 10px;
.home-remaini-value {
color: #2892f3;

1
src/components/home/HomeSetting.vue

@ -124,6 +124,7 @@ const onSave = async () => {
)
FtMessage.success('设定成功')
homeStore.setRate(formData.injection_pump_speed)
homeStore.setLog(formData.loglevel)
}
}
/**

10
src/components/home/LineChart.vue

@ -50,10 +50,10 @@ watch(
case '相对湿度':
unit = ' %RH'
break
case 'H2O2浓度':
case 'H₂O₂浓度':
unit = ' ppm'
break
case 'H2O2相对饱和度':
case 'H₂O₂相对饱和度':
unit = ' %RS'
break
}
@ -64,7 +64,7 @@ watch(
},
},
legend: {
data: ['温度', '相对湿度', 'H2O2浓度', 'H2O2相对饱和度'],
data: ['温度', '相对湿度', 'H₂O₂浓度', 'H₂O₂相对饱和度'],
orient: 'horizontal', //
itemWidth: 10, //
itemHeight: 10, //
@ -104,7 +104,7 @@ watch(
},
},
{
name: 'H2O2浓度',
name: 'H₂O₂浓度',
type: 'line',
data: newValue.data?.map(item => item.h2o2.toFixed(2)),
symbol: 'circle',
@ -115,7 +115,7 @@ watch(
},
},
{
name: 'H2O2相对饱和度',
name: 'H₂O₂相对饱和度',
type: 'line',
data: newValue.data?.map(item => item.rs.toFixed(2)),
symbol: 'circle',

18
src/libs/constant.ts

@ -3,24 +3,6 @@ export const HEADER_TOKEN_KEY = 'Authorization'
// sessionStorage里token的名称
export const SESSIONSTORAGE_TOKEN_KEY = 'web_token'
export const formulaNameMap: Record<string, any> = {
stoped_gs: '停止H2o2浓度',
continued_gs: '继续H2o2浓度',
stoped_satur: '停止H2o2饱和度',
continued_satur: '继续H2o2饱和度',
max_humidity: '消毒最大湿度',
injection_pump_speed: '喷射蠕动泵转速',
pre_heat_time_s: '预热时间',
stoped_humi: '停止相对湿度',
continued_humi: '湿度',
proportional_valve_default_value: '正负压比例',
loglevel: '消毒等级',
dvalue_correct_coefficient: 'D值修正系数',
record_period_min: '消毒日志记录间隔',
record_printer_period_min: '消毒日志打印间隔',
}
// 空气压力初始化数据
export const PARSSURE_DATA = {
intensitys: {

7
src/stores/homeStore.ts

@ -134,6 +134,7 @@ export const useHomeStore = defineStore('home', () => {
const defaultIntensityTypeValue = ref()
const realRate = ref()
const realLog = ref()
const allData = ref<any[]>([])
@ -141,6 +142,10 @@ export const useHomeStore = defineStore('home', () => {
realRate.value = data
}
const setLog = (data: any) => {
realLog.value = data
}
/**
* @function updateHomeData
* @param {Home.DisplayrelyMgr[]} data -
@ -235,7 +240,9 @@ export const useHomeStore = defineStore('home', () => {
return {
realRate,
realLog,
setRate,
setLog,
isDeviceIdle,
h2O2SensorData,

187
src/views/home/chart.vue

@ -1,12 +1,12 @@
<script lang="ts" setup>
import { syncSendCmd } from 'apis/system'
import { sendCmd, syncSendCmd } from 'apis/system'
import homeFinish from 'assets/images/home/home-finish.svg'
import homeSettingSvg from 'assets/images/home/home-setting.svg'
import BtButton from 'components/common/BTButton/index.vue'
import RunFormulaConfig from 'components/formula/RunFormulaConfig.vue'
import LineChart from 'components/home/LineChart.vue'
import { ElLoading } from 'element-plus'
import { stopTimer } from 'libs/countdownTimer'
import { FtMessage } from 'libs/message'
import { FtMessageBox } from 'libs/messageBox'
import { compareJSON, deviceStateMap } from 'libs/utils'
import { computed, onMounted, onUnmounted, provide, ref, watchEffect } from 'vue'
import { useRouter } from 'vue-router'
@ -26,13 +26,26 @@ const disinfectionState = ref(homeStore.disinfectionState)
const curStateRemainTime = ref(homeStore.curStateRemainTime)
const disinfectFormulaVisible = ref(false)
const isDeviceIdle = ref(homeStore.isDeviceIdle)
const loading = ref(false)
watchEffect(() => {
const rate = ref()
const log = ref()
watchEffect(async () => {
formulaInfo.value = formulaStore.currentSelectedFormulaInfo
disinfectionState.value = homeStore.disinfectionState
curStateRemainTime.value = homeStore.curStateRemainTime
isDeviceIdle.value = homeStore.isDeviceIdle
if (['idle', 'finished'].includes(homeStore.disinfectionState.state)) {
formulaInfo.value = formulaStore.selectedFormulaInfo
rate.value = formulaStore.selectedFormulaInfo?.injection_pump_speed
log.value = formulaStore.selectedFormulaInfo?.loglevel
}
else {
const realForm = (await formulaStore.getRealtimeConfig()).rely
rate.value = homeStore.realRate || realForm?.injection_pump_speed
log.value = homeStore.realLog || realForm?.loglevel
}
})
const onDisinfectConfig = () => {
@ -41,20 +54,33 @@ const onDisinfectConfig = () => {
//
const onFinishDisinfect = async () => {
await FtMessageBox.warning('请确认是否结束消毒')
homeStore.setRate(undefined)
homeStore.setLog(undefined)
stopTimer()
const loading = ElLoading.service({
lock: true,
text: '正在结束消毒',
background: 'rgba(255, 255, 255, 0.8)',
})
try {
const stopParams = {
className: 'DisinfectionCtrlServiceExt',
fnName: 'stop',
params: {
loglevel: formulaStore.loglevel,
},
params: { loglevel: formulaStore.loglevel },
}
loading.value = true
syncSendCmd(stopParams).then((res) => {
if (res.ackcode === 0) {
loading.value = false
await sendCmd(stopParams)
const poll = setInterval(() => {
if (operationState.value) {
loading.close()
clearInterval(poll)
}
}, 100)
}
catch (e) {
console.log(e)
loading.close()
}
})
}
const chartRef = ref()
const onSave = async () => {
@ -74,6 +100,7 @@ const onSave = async () => {
)
FtMessage.success('设定成功')
homeStore.setRate(formData.injection_pump_speed)
homeStore.setLog(formData.loglevel)
}
}
@ -151,11 +178,31 @@ const formatSeconds = (seconds: number) => {
<template>
<main class="main-content">
<!-- <div class="line-chart-title"> -->
<!-- <div class="line-chart-formula"> -->
<!-- <HomeFormula style="background: #e0f0ff" /> -->
<!-- </div> -->
<!-- </div> -->
<el-descriptions :column="4">
<el-descriptions-item label="设定注射速率">
<el-tag>
<span style="color: #31cb7a; font-size: 18px; margin: 0 5px">{{ rate }}</span>g/min
</el-tag>
</el-descriptions-item>
<el-descriptions-item label="实时注射速率">
<el-tag>
<span style="color: #31cb7a; font-size: 18px; margin: 0 5px">{{
homeStore.disinfectionState.injectedVelocity
}}</span>g/min
</el-tag>
</el-descriptions-item>
<el-descriptions-item label="目标消毒等级">
<el-tag>
<span style="color: #31cb7a; font-size: 18px; margin: 0 5px">{{ log }}</span>Log
</el-tag>
</el-descriptions-item>
<el-descriptions-item label="实时消毒等级">
<el-tag>
<span style="color: #31cb7a; font-size: 18px; margin: 0 5px">{{ homeStore.disinfectionState.nlog }}</span>Log
</el-tag>
</el-descriptions-item>
</el-descriptions>
<div
v-loading="chartLoading"
class="line-chart-content"
@ -179,46 +226,21 @@ const formatSeconds = (seconds: number) => {
</div>
</div>
<div class="home-chart-btn">
<BtButton
v-if="!isDeviceIdle"
button-text="结束消毒"
bg-color="#FF6767"
text-color="#FFFFFF"
width="15vw"
height="3.5rem"
text-size="24px"
border-radius="5px"
@click="onFinishDisinfect"
>
<template #icon>
<img :src="homeFinish" alt="">
</template>
</BtButton>
<BtButton
v-if="!isDeviceIdle"
button-text="运行参数"
text-size="24px"
border-radius="5px"
height="3.5rem"
text-color="#1989fa"
padding="0.8vw"
@click="onDisinfectConfig"
>
<el-button v-if="!isDeviceIdle" type="danger" @click="onFinishDisinfect">
<template #icon>
<img :src="homeSettingSvg" width="15" alt="">
<img :src="homeFinish" alt="" style="height: 20px">
</template>
</BtButton>
<BtButton
button-text="返回"
width="10vw"
height="7vh"
text-color="#1989fa"
text-size="24px"
border-radius="5px"
@click="goHome"
/>
结束消毒
</el-button>
<el-button v-if="!isDeviceIdle" type="primary" @click="onDisinfectConfig">
运行参数
</el-button>
<el-button @click="goHome">
返回
</el-button>
</div>
</div>
<ft-dialog v-model="disinfectFormulaVisible" title="运行参数" width="80vw">
<div class="formula-config">
<RunFormulaConfig ref="chartRef" />
@ -240,8 +262,11 @@ const formatSeconds = (seconds: number) => {
<style lang="scss" scoped>
.main-content {
overflow: hidden;
background: $gradient-color;
height: $main-container-height;
background: rgba(147, 203, 255, 0.1);
height: 100%;
border-radius: 10px;
box-shadow: 0 1px 5px 0 rgba(9, 39, 62, 0.15);
padding: 10px;
.formula-config {
display: grid;
padding: 10px;
@ -272,10 +297,10 @@ const formatSeconds = (seconds: number) => {
}
.line-chart-content {
display: grid;
height: calc(100% - 60px);
height: calc(100% - 80px);
}
.line-chart-bottom {
height: 60px;
height: 40px;
display: flex;
padding-right: 20px;
align-items: center;
@ -287,21 +312,55 @@ const formatSeconds = (seconds: number) => {
.home-chart-time {
width: 35%;
.home-remain-time {
background: #f6fafe;
width: 27vw;
height: 8vh;
background: #fff;
margin: 10px;
height: 40px;
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
font-size: 20px;
gap: 10px;
margin-left: 1rem;
.home-chart-value {
.home-remaini-value {
color: #2892f3;
}
}
}
}
}
:deep(.el-descriptions) {
width: 100%;
height: 40px;
.el-descriptions__body {
background: rgba(0, 0, 0, 0);
.el-descriptions__table {
tr {
display: flex;
justify-content: center;
gap: 20px;
}
}
}
}
:deep(.el-descriptions__cell) {
display: flex;
align-items: center;
//background: #fff;
//margin-bottom: 5px;
//padding: 5px !important;
//.el-descriptions__label {
// display: inline-block;
// width: 120px;
// margin: 0;
// font-size: 15px;
// font-weight: 600;
// color: #606266;
//}
//.el-descriptions__content {
// flex: 1;
// text-align: right;
// display: flex;
// justify-content: flex-end;
//}
}
</style>

12
src/views/home/index.vue

@ -1,7 +1,6 @@
<script lang="ts" setup>
import Environment from 'components/home/Environment.vue'
import HomeFormula from 'components/home/HomeFormula.vue'
import HomeLogLevel from 'components/home/HomeLogLevel.vue'
import HomeOperation from 'components/home/HomeOperation.vue'
import HomeSetting from 'components/home/HomeSetting.vue'
import PressureControl from 'components/home/PressureControl.vue'
@ -120,14 +119,14 @@ const deviceType = computed(() => {
</div>
</div>
<div class="card-num-g">
消毒液剩余:{{ nowLiquid }}g
消毒液剩余:{{ nowLiquid || 0 }}g
</div>
</div>
</div>
<div class="middle">
<!-- 选择消毒的等级 -->
<HomeLogLevel v-if="!formulaStore.selectedFormulaInfo?.name" />
<!-- <HomeLogLevel v-if="!formulaStore.selectedFormulaInfo?.name" /> -->
<!-- 开始消毒停止消毒及状态区 -->
<HomeOperation />
</div>
@ -143,9 +142,8 @@ const deviceType = computed(() => {
</div>
</div>
</div>
<div v-else>
<router-view />
</div>
<router-view v-else />
</div>
</template>
@ -181,6 +179,7 @@ $input-height: 3rem;
border-radius: 10px 10px 10px 10px;
background: #ffffff;
background: linear-gradient(180deg, rgba(147, 203, 255, 1) -190%, #ffffff 24%);
background: rgba(147, 203, 255, 0.1);
.title-line {
height: 1vw;
@ -204,6 +203,7 @@ $input-height: 3rem;
.home-right {
padding: 10px;
background: linear-gradient(180deg, rgba(147, 203, 255, 1) -190%, #ffffff 24%);
background: rgba(147, 203, 255, 0.1);
border-radius: 10px;
box-shadow: 0 1px 5px 0 rgba(9, 39, 62, 0.15);
display: flex;

Loading…
Cancel
Save