|
@@ -1,15 +1,9 @@
|
|
|
<script setup>
|
|
|
-import { ref, onMounted, computed, unref, watch } from 'vue';
|
|
|
-import { NScrollbar, useMessage, NTabs, NTabPane, NProgress } from 'naive-ui';
|
|
|
+import { ref, onMounted, computed, onUnmounted } from 'vue';
|
|
|
+import {useMessage, NProgress } from 'naive-ui';
|
|
|
import { TheChatView } from '@/components';
|
|
|
import { controlApi } from "@/api/control";
|
|
|
import BaseTitle from './components/BaseTitle.vue';
|
|
|
-import BaseRadioCard from './components/BaseRadioCard.vue';
|
|
|
-import BaseCard from './components/BaseCard.vue';
|
|
|
-import BaseChooseItem from './components/BaseChooseItem.vue';
|
|
|
-import BaseInput from './components/BaseInput.vue';
|
|
|
-import TheResultPanel from './components/TheResultPanel.vue';
|
|
|
-import TheEchartPanel from './components/TheEchartPanel.vue';
|
|
|
|
|
|
import NumberPanel from './NumberPanel.vue';
|
|
|
import CirclePanel from './CirclePanel.vue';
|
|
@@ -18,15 +12,25 @@ import EchartRight from './EchartRight.vue'
|
|
|
import DrawerSetting from './DrawerSetting.vue';
|
|
|
import ParamterCard from './ParamterCard.vue';
|
|
|
import DrawerWarning from './DrawerWarning.vue';
|
|
|
+import dayjs from 'dayjs';
|
|
|
|
|
|
let isProcessing = false;
|
|
|
|
|
|
+const lastDataSource = ref({});
|
|
|
+const warningCollectList = ref([]);
|
|
|
+
|
|
|
+const updateTime = ref(dayjs(new Date()).format("YYYY-MM-DD HH:mm:ss"));
|
|
|
+
|
|
|
const message = useMessage();
|
|
|
const processNumber = ref(0);
|
|
|
const systemStatus = ref(0);
|
|
|
const configurationStatus = ref(1);
|
|
|
-const medicineAmount = ref(0);
|
|
|
-const tytjTransientLL = ref(0);
|
|
|
+
|
|
|
+const timerPanel = ref(null);
|
|
|
+const timerParams = ref(null);
|
|
|
+
|
|
|
+// 中间面板数值
|
|
|
+const panelResultData = ref({});
|
|
|
|
|
|
const paramterDrawerVisible = ref(false);
|
|
|
const warningDrawerVisible = ref(false);
|
|
@@ -41,7 +45,7 @@ const handleSystemStatus = () => {
|
|
|
if ( isProcessing ) return;
|
|
|
|
|
|
isProcessing = true;
|
|
|
-
|
|
|
+ console.log( configurationStatus.value );
|
|
|
if ( configurationStatus.value == 1 ) {
|
|
|
return message.warning('当前组态未启用,无法投放');
|
|
|
}
|
|
@@ -63,7 +67,7 @@ const handleUpdateParams = () => {
|
|
|
initData();
|
|
|
}
|
|
|
|
|
|
-const getNumVal = (type, n1, n2, activeIndex) => {
|
|
|
+const getNumVal = (type, n1, n2) => {
|
|
|
|
|
|
if ( type == 0 ) {
|
|
|
return Math.max(n1, n2);
|
|
@@ -79,6 +83,45 @@ const getNumVal = (type, n1, n2, activeIndex) => {
|
|
|
|
|
|
}
|
|
|
|
|
|
+const getCurrentTypeData = () => {
|
|
|
+ const {
|
|
|
+ type,
|
|
|
+ hycXsyOne, hycXsyTwo,
|
|
|
+ qycYxyOne, qycYxyTwo, qycAdOne, qycAdTwo,
|
|
|
+ htfksd,
|
|
|
+ } = lastDataSource.value;
|
|
|
+
|
|
|
+ if ( type == 0 ) {
|
|
|
+ return {
|
|
|
+ type,
|
|
|
+ hycXsy: Math.max(hycXsyOne, hycXsyTwo),
|
|
|
+ qycYxy: Math.max(qycYxyOne, qycYxyTwo),
|
|
|
+ qycAd: Math.max(qycAdOne, qycAdTwo),
|
|
|
+ htfksd,
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (type == 1) {
|
|
|
+ return {
|
|
|
+ type,
|
|
|
+ hycXsy: hycXsyOne,
|
|
|
+ qycYxy: qycYxyOne,
|
|
|
+ qycAd: qycAdOne,
|
|
|
+ htfksd
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (type == 2) {
|
|
|
+ return {
|
|
|
+ type,
|
|
|
+ hycXsy: hycXsyTwo,
|
|
|
+ qycYxy: qycYxyTwo,
|
|
|
+ qycAd: qycAdTwo,
|
|
|
+ htfksd
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
const operateNumbers = (operationType, callBack) => {
|
|
|
const totalTime = 3000;
|
|
|
const steps = 100;
|
|
@@ -101,8 +144,81 @@ const operateNumbers = (operationType, callBack) => {
|
|
|
}, intervalTime);
|
|
|
}
|
|
|
|
|
|
+const isEmpty = (val) => {
|
|
|
+ return !(val === null || val === undefined || val === '')
|
|
|
+}
|
|
|
+
|
|
|
+const handleWarningDraw = () => {
|
|
|
+ if ( !warningCollectList.value.length ) {
|
|
|
+ return message.warning('当前没有系统告警');
|
|
|
+ }
|
|
|
+ warningDrawerVisible.value = true;
|
|
|
+}
|
|
|
+
|
|
|
+const getWarningInfo = async () => {
|
|
|
+
|
|
|
+ const { data } = await controlApi.getWarningParams();
|
|
|
+ const { kzmbplbjz, hycxsygkz, xhycbjz, jylpybjz, minAddAmount } = data;
|
|
|
+
|
|
|
+ const {
|
|
|
+ hycXsy,
|
|
|
+ qycYxy,
|
|
|
+ qycAd,
|
|
|
+ htfksd,
|
|
|
+ // 系统加药量
|
|
|
+ medicineAmount,
|
|
|
+
|
|
|
+ } = getCurrentTypeData();
|
|
|
+
|
|
|
+ if ( isEmpty(hycXsy) && isEmpty(htfksd) && isEmpty(kzmbplbjz)) {
|
|
|
+ const content = [];
|
|
|
+ if (( hycXsy - htfksd ) > kzmbplbjz ) {
|
|
|
+ content.push('• 好氧池硝酸盐控制目标偏移过大')
|
|
|
+ }
|
|
|
+ if ( hycXsy > hycxsygkz ) {
|
|
|
+ content.push('• 好氧池硝酸盐超管控值')
|
|
|
+ }
|
|
|
+ if (content.length) {
|
|
|
+ warningCollectList.value.push({
|
|
|
+ title: '反硝化异常报警',
|
|
|
+ content,
|
|
|
+ desc: '请排查现场工况/调整控制参数,非碳源量的问题,建议切换手动控制'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (isEmpty(qycYxy) && isEmpty(qycAd) && isEmpty(hycXsy) && isEmpty(xhycbjz)) {
|
|
|
+ if ((qycYxy + qycAd - hycXsy) > xhycbjz) {
|
|
|
+ warningCollectList.value.push({
|
|
|
+ title: '硝化异常报警',
|
|
|
+ content: [],
|
|
|
+ desc: '请排查进水水质、曝气系统、活性污泥系统等,请切手动运行'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (isEmpty(medicineAmount) && isEmpty(minAddAmount) && isEmpty(jylpybjz)) {
|
|
|
+ if ( medicineAmount > minAddAmount && medicineAmount > jylpybjz) {
|
|
|
+ warningCollectList.value.push({
|
|
|
+ title: '加药量偏移报警',
|
|
|
+ content: ['• 系统计算加药与现场实际流量计偏移过大'],
|
|
|
+ desc: '请排查现场碳源储罐液位、加药泵和流量计等,确保运行正常'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const initPanelData = async () => {
|
|
|
+ const { data } = await controlApi.getLastResult();
|
|
|
+
|
|
|
+ panelResultData.value = data;
|
|
|
+
|
|
|
+ updateTime.value = dayjs(new Date()).format("YYYY-MM-DD HH:mm:ss");
|
|
|
+}
|
|
|
+
|
|
|
const initData = async () => {
|
|
|
const { data } = await controlApi.getBaseData();
|
|
|
+
|
|
|
const {
|
|
|
addType,
|
|
|
|
|
@@ -140,19 +256,25 @@ const initData = async () => {
|
|
|
cod: getNumVal(type, jsCodOne, jsCodTwo) + ' mg/L',
|
|
|
jszd: getNumVal(type, jsTnOne, jsTnTwo) + ' mg/L',
|
|
|
hycxsy: getNumVal(type, hycXsyOne, hycXsyTwo) + ' mg/L',
|
|
|
- hycad: '没有',
|
|
|
qycxsy: getNumVal(type, qycYxyOne, qycYxyTwo) + ' mg/L',
|
|
|
qycan: getNumVal(type, qycAdOne, qycAdTwo) + ' mg/L',
|
|
|
};
|
|
|
|
|
|
configurationStatus.value = addType;
|
|
|
|
|
|
+ lastDataSource.value = data;
|
|
|
}
|
|
|
|
|
|
onMounted(async () => {
|
|
|
// 初始化
|
|
|
await initData();
|
|
|
|
|
|
+ // 投药量数据
|
|
|
+ initPanelData();
|
|
|
+
|
|
|
+ // 获取报警相关数据
|
|
|
+ getWarningInfo();
|
|
|
+
|
|
|
// 获取是否允许投药开关
|
|
|
await controlApi.getSystemStatus().then(({ data }) => {
|
|
|
// 0不允许 1允许
|
|
@@ -160,7 +282,16 @@ onMounted(async () => {
|
|
|
});
|
|
|
|
|
|
processNumber.value = systemSwitchType.value ? 100 : 0;
|
|
|
+
|
|
|
+ timerPanel.value = setInterval(initPanelData, 5 * 1000)
|
|
|
+ timerParams.value = setInterval(initData, 40 * 60 * 1000);
|
|
|
})
|
|
|
+
|
|
|
+onUnmounted(() => {
|
|
|
+ clearInterval(timerPanel);
|
|
|
+ clearInterval(timerParams);
|
|
|
+})
|
|
|
+
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
@@ -171,7 +302,7 @@ onMounted(async () => {
|
|
|
<div class="arg-section">
|
|
|
|
|
|
<div class="left-card space-y-[16px]">
|
|
|
- <BaseTitle title="智能投加计算"></BaseTitle>
|
|
|
+ <BaseTitle title="智能投加计算" type="1"></BaseTitle>
|
|
|
<ParamterCard :data="paramterValue"></ParamterCard>
|
|
|
</div>
|
|
|
|
|
@@ -182,20 +313,20 @@ onMounted(async () => {
|
|
|
<li class="item" @click="paramterDrawerVisible = true">
|
|
|
<span>参数设置</span>
|
|
|
</li>
|
|
|
- <li class="item" @click="warningDrawerVisible = true">
|
|
|
+ <li class="item" @click="handleWarningDraw">
|
|
|
<span>系统告警</span>
|
|
|
- <span class="waring-circle-icon"></span>
|
|
|
+ <span class="waring-circle-icon" v-show="warningCollectList.length != 0"></span>
|
|
|
</li>
|
|
|
</ul>
|
|
|
</div>
|
|
|
<div class="result-content">
|
|
|
<div class="number_card space-x-[20px]">
|
|
|
- <NumberPanel direction="left" title="智能控制系数" :value="123"></NumberPanel>
|
|
|
- <CirclePanel :medicineAmount="medicineAmount" :tytjTransientLL="tytjTransientLL"></CirclePanel>
|
|
|
- <NumberPanel direction="right" title="硝酸盐智能设定" unit="mg/L" :value="22"></NumberPanel>
|
|
|
+ <NumberPanel direction="left" title="智能控制系数" :value="panelResultData.kzxs"></NumberPanel>
|
|
|
+ <CirclePanel :medicineAmount="panelResultData.calculateVal" :tytjTransientLL="panelResultData.realValue"></CirclePanel>
|
|
|
+ <NumberPanel direction="right" title="硝酸盐智能设定" unit="mg/L" :value="panelResultData.htfksd"></NumberPanel>
|
|
|
</div>
|
|
|
<div class="progress_card space-y-[8px]">
|
|
|
- <span class="time">模型更新时间: 2025-04-11 12:11:11</span>
|
|
|
+ <span class="time">模型更新时间: {{ updateTime }}</span>
|
|
|
<div class="progress">
|
|
|
<NProgress
|
|
|
processing
|
|
@@ -238,6 +369,7 @@ onMounted(async () => {
|
|
|
<!-- 系统告警 - 抽屉 -->
|
|
|
<DrawerWarning
|
|
|
v-model:show="warningDrawerVisible"
|
|
|
+ :warning-collect-list="warningCollectList"
|
|
|
></DrawerWarning>
|
|
|
</template>
|
|
|
|
|
@@ -310,7 +442,7 @@ onMounted(async () => {
|
|
|
.result-content {
|
|
|
@include flex(y, center, around);
|
|
|
height: calc(100% - 40px);
|
|
|
- padding: 0px 86px 0 86px;
|
|
|
+ // padding: 0px 86px 0 86px;
|
|
|
background-clip: padding-box;
|
|
|
|
|
|
.number_card {
|