|
@@ -1,6 +1,6 @@
|
|
|
<script setup>
|
|
|
import { ref, onMounted, computed, unref, watch } from 'vue';
|
|
|
-import { NScrollbar, useMessage, NTabs, NTabPane, NSwitch } from 'naive-ui';
|
|
|
+import { NScrollbar, useMessage, NTabs, NTabPane, NSwitch, useNotification, NButton } from 'naive-ui';
|
|
|
import { TheChatView } from '@/components';
|
|
|
import { controlApi } from "@/api/control";
|
|
|
import BaseTitle from './components/BaseTitle.vue';
|
|
@@ -10,6 +10,8 @@ import BaseInput from './components/BaseInput.vue';
|
|
|
import TheResultPanel from './components/TheResultPanel.vue';
|
|
|
import TheEchartPanel from './components/TheEchartPanel.vue';
|
|
|
|
|
|
+const warningList = ref([]);
|
|
|
+const notification = useNotification()
|
|
|
const message = useMessage();
|
|
|
const isVisibleBtn = ref(true);
|
|
|
const isVisibleUpdateInfo = ref(false);
|
|
@@ -21,7 +23,9 @@ const resultNumberSet = ref({
|
|
|
doseNum1: 0,
|
|
|
doseNum2: 0,
|
|
|
updateNum1: 0,
|
|
|
- updateNum2: 0
|
|
|
+ updateNum2: 0,
|
|
|
+ currentResultNum1: 0,
|
|
|
+ currentResultNum2: 0
|
|
|
});
|
|
|
|
|
|
const railStyle = ({ focused,checked }) => {
|
|
@@ -50,7 +54,7 @@ const southColumnData = ref([
|
|
|
{ label: '转换系数', key: 'zhxsOne', value: null },
|
|
|
{ label: '稀释倍数', key: 'sxpsOne', value: null },
|
|
|
{ label: '药剂密度', key: 'yymdOne', value: null },
|
|
|
- { label: '最小启动流量', key: 'zxqdllOne', value: null },
|
|
|
+ // { label: '最小启动流量', key: 'zxqdllOne', value: null },
|
|
|
{ label: '碳氮比', key: 'tdbOne', value: null }
|
|
|
]);
|
|
|
|
|
@@ -64,7 +68,7 @@ const northColumnData = ref([
|
|
|
{ label: '转换系数', key: 'zhxsTwo', value: null },
|
|
|
{ label: '稀释倍数', key: 'sxpsTwo', value: null },
|
|
|
{ label: '药剂密度', key: 'yymdTwo', value: null },
|
|
|
- { label: '最小启动流量', key: 'zxqdllTwo', value: null },
|
|
|
+ // { label: '最小启动流量', key: 'zxqdllTwo', value: null },
|
|
|
{ label: '碳氮比', key: 'tdbTwo', value: null }
|
|
|
]);
|
|
|
|
|
@@ -170,7 +174,7 @@ const onFinalResult = async (type) => {
|
|
|
// 切换tabs
|
|
|
const onUpdateTab = (index) => {
|
|
|
dataSourceParams.value.type = index;
|
|
|
- setTimeout(() => handleMedicateAmount())
|
|
|
+ // setTimeout(() => handleMedicateAmount())
|
|
|
}
|
|
|
|
|
|
function getTotalNum() {
|
|
@@ -183,22 +187,29 @@ function getTotalNum() {
|
|
|
htfksdOne, jzxsOne, xzxsOne, kzxsOne, slfpxsOne, tydlOne, zhxsOne, sxpsOne, yymdOne,
|
|
|
htfksdTwo, jzxsTwo, xzxsTwo, kzxsTwo, slfpxsTwo, tydlTwo, zhxsTwo, sxpsTwo, yymdTwo,
|
|
|
} = dataSourceParams.value;
|
|
|
+
|
|
|
+ const oneStep = ((qycAdOne + qycYxyOne) * xzxsOne - htfksdOne) > 0 ? ((qycAdOne + qycYxyOne) * xzxsOne - htfksdOne) : 0;
|
|
|
+ const twoStep = ((qycAdTwo + qycYxyTwo) * xzxsTwo - htfksdTwo) > 0 ? ((qycAdTwo + qycYxyTwo) * xzxsTwo - htfksdTwo) : 0;
|
|
|
|
|
|
- const stepSouthOne = (((2 * hycXsyOne - htfksdOne) + ((qycAdOne + qycYxyOne) * xzxsOne - htfksdOne)) * (jzxsOne - 1)) * (jsLlOne * slfpxsOne) / 1000;
|
|
|
- const stepSouthTwo = (stepSouthOne * kzxsOne - (jsLlOne * slfpxsOne * jsCodOne * zhxsOne / 1000)) / tydlOne;
|
|
|
+ const stepSouthOne = (((2 * hycXsyOne - htfksdOne) + (oneStep)) * (jzxsOne - 1)) * (jsLlOne * slfpxsOne) / 1000;
|
|
|
+ const stepSouthTwo = Number(((stepSouthOne * kzxsOne - (jsLlOne * slfpxsOne * jsCodOne * zhxsOne / 1000).toFixed(10)) / tydlOne).toFixed(10));
|
|
|
const stepSouthThree = stepSouthTwo / yymdOne / 1000 * sxpsOne;
|
|
|
|
|
|
- const stepNorthOne = (((2 * hycXsyTwo - htfksdTwo) + ((qycAdTwo + qycYxyTwo) * xzxsTwo - htfksdTwo)) * (jzxsTwo - 1)) * (jsLlTwo * slfpxsTwo) / 1000;
|
|
|
- const stepNorthTwo = (stepNorthOne * kzxsTwo - (jsLlTwo * slfpxsTwo * jsCodTwo * zhxsTwo / 1000)) / tydlTwo;
|
|
|
+ const stepNorthOne = (((2 * hycXsyTwo - htfksdTwo) + (twoStep)) * (jzxsTwo - 1)) * (jsLlTwo * slfpxsTwo) / 1000;
|
|
|
+ const stepNorthTwo = Number(((stepNorthOne * kzxsTwo - (jsLlTwo * slfpxsTwo * jsCodTwo * zhxsTwo / 1000).toFixed(10)) / tydlTwo).toFixed(10));
|
|
|
const stepNorthThree = stepNorthTwo / yymdTwo / 1000 * sxpsTwo;
|
|
|
|
|
|
+
|
|
|
let r11 = Number((stepSouthThree < 0 || !stepSouthThree) ? 0 : stepSouthThree) || 0;
|
|
|
let r22 = Number((stepNorthThree < 0 || !stepNorthThree) ? 0 : stepNorthThree) || 0;
|
|
|
|
|
|
let r1 = Number((r11 * 1000).toFixed(3));
|
|
|
let r2 = Number((r22 * 1000).toFixed(3));
|
|
|
|
|
|
- const {maxAddAmount, minAddAmount } = minAndMaxValue.value;
|
|
|
+ const { maxAddAmount, minAddAmount } = minAndMaxValue.value;
|
|
|
+
|
|
|
+ resultNumberSet.value.currentResultNum1 = Number((stepSouthThree * 1000).toFixed(3));
|
|
|
+ resultNumberSet.value.currentResultNum2 = Number((stepNorthThree * 1000).toFixed(3));
|
|
|
|
|
|
if ( r1 > maxAddAmount ) r1 = maxAddAmount;
|
|
|
if ( r1 < minAddAmount ) r1 = minAddAmount;
|
|
@@ -225,6 +236,9 @@ const onConfirmUpdate = async () => {
|
|
|
|
|
|
resultNumberSet.value.doseNum1 = resultNumberSet.value.updateNum1;
|
|
|
resultNumberSet.value.doseNum2 = resultNumberSet.value.updateNum2;
|
|
|
+
|
|
|
+ resultNumberSet.value.currentResultNum1 = resultNumberSet.value.updateNum1;
|
|
|
+ resultNumberSet.value.currentResultNum2 = resultNumberSet.value.updateNum2;
|
|
|
}
|
|
|
|
|
|
const handleAutoSwitch = (val) => {
|
|
@@ -245,48 +259,148 @@ const handleMedicateAmount = () => {
|
|
|
const tdb = tdbNum.value;
|
|
|
|
|
|
const [r1, r2] = getTotalNum();
|
|
|
-
|
|
|
+
|
|
|
+ waringTips();
|
|
|
+
|
|
|
if ( type == 0 ) {
|
|
|
- if ( !dataSourceParams.value.typeOne && dataSourceParams.value.medicineAmountOne != updateNum1 ) {
|
|
|
+ // && dataSourceParams.value.medicineAmountOne != updateNum1
|
|
|
+ if ( !dataSourceParams.value.typeOne ) {
|
|
|
const medicineAmountOne = dataSourceParams.value.medicineAmountOne
|
|
|
if ( medicineAmountOne && medicineAmountOne != 0 ) {
|
|
|
resultNumberSet.value.updateNum1 = dataSourceParams.value.medicineAmountOne;
|
|
|
isVisibleUpdateInfo.value = true;
|
|
|
- message.warning("北池有新的投放方案, 请查看");
|
|
|
+ // message.warning("北池有新的投放方案, 请查看");
|
|
|
} else {
|
|
|
resultNumberSet.value.updateNum1 = dataSourceParams.value.medicineAmountOne;
|
|
|
// isVisibleUpdateInfo.value = true;
|
|
|
}
|
|
|
- } else if (r1 != updateNum1 && dataSourceParams.value.typeOne) {
|
|
|
+ // r1 != updateNum1 &&
|
|
|
+ } else if ( dataSourceParams.value.typeOne) {
|
|
|
resultNumberSet.value.updateNum1 = r1;
|
|
|
isVisibleUpdateInfo.value = true;
|
|
|
dataSourceParams.value.tdbOne = tdb;
|
|
|
- message.warning("北池有新的投放方案, 请查看");
|
|
|
+ // message.warning("北池有新的投放方案, 请查看");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if ( type == 1 ) {
|
|
|
- if (!dataSourceParams.value.typeTwo && dataSourceParams.value.medicineAmountTwo != updateNum2) {
|
|
|
+ // && dataSourceParams.value.medicineAmountTwo != updateNum2
|
|
|
+ if (!dataSourceParams.value.typeTwo ) {
|
|
|
const medicineAmountTwo = dataSourceParams.value.medicineAmountTwo;
|
|
|
if (medicineAmountTwo && medicineAmountTwo != 0 ) {
|
|
|
resultNumberSet.value.updateNum2 = dataSourceParams.value.medicineAmountTwo;
|
|
|
isVisibleUpdateInfo.value = true;
|
|
|
- message.warning("南池有新的投放方案, 请查看");
|
|
|
+ // message.warning("南池有新的投放方案, 请查看");
|
|
|
} else {
|
|
|
resultNumberSet.value.updateNum2 = dataSourceParams.value.medicineAmountTwo;
|
|
|
// isVisibleUpdateInfo.value = true;
|
|
|
}
|
|
|
- } else if (r2 != updateNum2 && dataSourceParams.value.typeTwo) {
|
|
|
+ // r2 != updateNum2 &&
|
|
|
+ } else if ( dataSourceParams.value.typeTwo) {
|
|
|
resultNumberSet.value.updateNum2 = r2;
|
|
|
isVisibleUpdateInfo.value = true;
|
|
|
dataSourceParams.value.tdbTwo = tdb;
|
|
|
- message.warning("南池有新的投放方案, 请查看");
|
|
|
+ // message.warning("南池有新的投放方案, 请查看");
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-onMounted(async () => {
|
|
|
+// 查看系统警报
|
|
|
+const onSystemWarning = () => {
|
|
|
+ warningList.value.forEach(item => {
|
|
|
+ notification.warning({...item})
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+const isEmpty = (val) => {
|
|
|
+ return !(val == null || val == undefined || val == '')
|
|
|
+}
|
|
|
+
|
|
|
+const waringTips = () => {
|
|
|
+ const { kzmbplbjz, hycxsygkz, xhycbjz, jylpybjz, minAddAmount } = minAndMaxValue.value;
|
|
|
+
|
|
|
+ const {
|
|
|
+ hycXsyOne, htfksdOne, hycXsyTwo, htfksdTwo,
|
|
|
+ qycYxyOne, qycAdOne, qycYxyTwo, qycAdTwo,
|
|
|
+ // 加药偏移量 北池
|
|
|
+ addDifferenceOne,
|
|
|
+ // 加药偏移量 南池
|
|
|
+ addDifferenceTwo
|
|
|
+ } = dataSourceParams.value;
|
|
|
+
|
|
|
+
|
|
|
+ const tipsEnum = {
|
|
|
+ oneTips: {
|
|
|
+ title: '反硝化异常报警',
|
|
|
+ content: '排查现场工况/调整控制参数,非碳源量的问题,请切手动控制',
|
|
|
+ },
|
|
|
+ twoTips: {
|
|
|
+ title: '硝化异常报警',
|
|
|
+ content: '排查进水水质、曝气系统、活性污泥系统等,请切手动运行',
|
|
|
+ },
|
|
|
+ threeTips: {
|
|
|
+ title: '加药量偏移报警',
|
|
|
+ content: '排查现场碳源储罐液位、加药泵和流量计等,确保运行正常',
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const result = {
|
|
|
+ oneTips: [],
|
|
|
+ twoTips: [],
|
|
|
+ threeTips: []
|
|
|
+ }
|
|
|
|
|
|
+ if ( isEmpty(hycXsyOne) && isEmpty(htfksdOne) && isEmpty(kzmbplbjz) ) {
|
|
|
+ if ( (hycXsyOne - htfksdOne) > kzmbplbjz || hycXsyOne > hycxsygkz) {
|
|
|
+ result.oneTips.push('北池');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( isEmpty(hycXsyTwo) && isEmpty(htfksdTwo) && isEmpty(kzmbplbjz) ) {
|
|
|
+ if ( (hycXsyTwo - htfksdTwo) > kzmbplbjz || hycXsyTwo > hycxsygkz) {
|
|
|
+ result.oneTips.push('南池');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( isEmpty(hycXsyOne) && isEmpty(qycYxyOne) && isEmpty(qycAdOne) ) {
|
|
|
+ if (qycYxyOne + qycAdOne - hycXsyOne > xhycbjz) {
|
|
|
+ result.twoTips.push('北池');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( isEmpty(hycXsyTwo) && isEmpty(qycYxyTwo) && isEmpty(qycAdTwo) ) {
|
|
|
+ if (qycYxyTwo + qycAdTwo - hycXsyTwo > xhycbjz) {
|
|
|
+ result.twoTips.push('南池');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( isEmpty(addDifferenceOne) && isEmpty(jylpybjz) && isEmpty(minAddAmount)) {
|
|
|
+ if (addDifferenceOne > minAddAmount && addDifferenceOne > jylpybjz) {
|
|
|
+ result.threeTips.push('北池');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( isEmpty(addDifferenceTwo) && isEmpty(jylpybjz) && isEmpty(minAddAmount)) {
|
|
|
+ if (addDifferenceTwo > minAddAmount && addDifferenceTwo > jylpybjz) {
|
|
|
+ result.threeTips.push('南池');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ warningList.value = Object.entries(result).map(([key, value]) => {
|
|
|
+ if ( value.length ) {
|
|
|
+ return {
|
|
|
+ ...tipsEnum[key],
|
|
|
+ title: tipsEnum[key].title + "(" + value.join(' | ') + ")",
|
|
|
+ duration: 30 * 1000,
|
|
|
+ keepAliveOnHover: true,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }).filter(Boolean);
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+onMounted(async () => {
|
|
|
+
|
|
|
const { data: valSet } = await controlApi.getMinMaxVal();
|
|
|
|
|
|
minAndMaxValue.value = valSet;
|
|
@@ -305,9 +419,12 @@ onMounted(async () => {
|
|
|
// 投加量
|
|
|
medicineAmountOne, medicineAmountTwo,
|
|
|
// 瞬时流量
|
|
|
- tytjTransientLLOne, tytjTransientLLTwo
|
|
|
+ tytjTransientLLOne, tytjTransientLLTwo,
|
|
|
+
|
|
|
+ addDifferenceOne,
|
|
|
+ addDifferenceTwo
|
|
|
} = data;
|
|
|
-
|
|
|
+
|
|
|
systemStatus.value = { activeTwo: addTypeOne, activeTwo: addTypeTwo };
|
|
|
|
|
|
// 系数
|
|
@@ -321,7 +438,9 @@ onMounted(async () => {
|
|
|
flowNum1: tytjTransientLLOne,
|
|
|
flowNum2: tytjTransientLLTwo,
|
|
|
doseNum1: medicineAmountOne,
|
|
|
- doseNum2: medicineAmountTwo
|
|
|
+ doseNum2: medicineAmountTwo,
|
|
|
+ currentResultNum1: medicineAmountOne,
|
|
|
+ currentResultNum2: medicineAmountTwo
|
|
|
}
|
|
|
|
|
|
// 数据源
|
|
@@ -339,7 +458,12 @@ onMounted(async () => {
|
|
|
|
|
|
medicineAmountOne: typeOne === 0 ? 0 : medicineAmountOne,
|
|
|
medicineAmountTwo: typeTwo === 0 ? 0 : medicineAmountTwo,
|
|
|
+
|
|
|
+ addDifferenceOne,
|
|
|
+ addDifferenceTwo
|
|
|
};
|
|
|
+
|
|
|
+ waringTips();
|
|
|
})
|
|
|
|
|
|
// 获取实时数据
|
|
@@ -669,15 +793,23 @@ onMounted(async () => {
|
|
|
</n-scrollbar>
|
|
|
</div>
|
|
|
<div class="right-section">
|
|
|
- <TheResultPanel
|
|
|
- :nums="resultNumberSet"
|
|
|
- v-model:system="systemStatus"
|
|
|
- v-model="isVisibleUpdateInfo"
|
|
|
- @on-click="onFinalResult"
|
|
|
- @on-update="onConfirmUpdate"
|
|
|
- >
|
|
|
- </TheResultPanel>
|
|
|
- <TheEchartPanel></TheEchartPanel>
|
|
|
+ <BaseTitle title="智能投加计算结果" type="second">
|
|
|
+ <template #right>
|
|
|
+ <NButton strong secondary type="warning" @click="onSystemWarning" v-show="warningList.length">查看系统警报</NButton>
|
|
|
+ </template>
|
|
|
+ </BaseTitle>
|
|
|
+ <div class="right-section-content">
|
|
|
+ <TheResultPanel
|
|
|
+ :nums="resultNumberSet"
|
|
|
+ :minAndMaxNum="minAndMaxValue"
|
|
|
+ v-model:system="systemStatus"
|
|
|
+ v-model="isVisibleUpdateInfo"
|
|
|
+ @on-click="onFinalResult"
|
|
|
+ @on-update="onConfirmUpdate"
|
|
|
+ >
|
|
|
+ </TheResultPanel>
|
|
|
+ <TheEchartPanel v-model:change="isVisibleUpdateInfo"></TheEchartPanel>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
@@ -781,6 +913,12 @@ onMounted(async () => {
|
|
|
border-radius: 8px;
|
|
|
background: #fff;
|
|
|
overflow: hidden;
|
|
|
+
|
|
|
+ .right-section-content {
|
|
|
+ display: flex;
|
|
|
+ flex-flow: column;
|
|
|
+ height: calc(100% - 75px);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|