1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105 |
- <script setup>
- import { ref, onMounted, computed, unref, watch, h, onUnmounted } from 'vue';
- import { NScrollbar, useMessage, NTabs, NTabPane, NSwitch, useNotification } from 'naive-ui';
- import { TheChatView } from '@/components';
- import { controlApi } from "@/api/control";
- import BaseTitle from './components/BaseTitle.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';
- const warningList = ref([]);
- const notification = useNotification()
- const message = useMessage();
- const isVisibleBtn = ref(true);
- const isVisibleUpdateInfo = ref(false);
- const zuTaiStatus = ref({});
- const minAndMaxValue = ref({});
- const setting = ref({
- isVisibleBtnOne: true,
- isVisibleBtnTwo: true
- })
- let msgReactive = '';
- let timer1 = '';
- let timer2 = '';
- let timerInterval = '';
- const resultNumberSet = ref({
- flowNum1: 0,
- flowNum2: 0,
- doseNum1: 0,
- doseNum2: 0,
- updateNum1: 0,
- updateNum2: 0,
- currentResultNum1: 0,
- currentResultNum2: 0
- });
- const railStyle = ({ focused,checked }) => {
- const style = {};
- if (checked) {
- style.background = "#0055f9";
- if (focused) {
- style.boxShadow = "0 0 0 2px #0055f940";
- }
- } else {
- style.background = "#6965ee";
- if (focused) {
- style.boxShadow = "0 0 0 2px #6965ee40";
- }
- }
- return style;
- }
- const southColumnData = ref([
- { label: '后反馈设定', key: 'htfksdOne', value: null },
- { label: '基准系数', key: 'jzxsOne', value: null },
- { label: '修正系数', key: 'xzxsOne', value: null },
- { label: '控制系数', key: 'kzxsOne', value: null },
- { label: '水量分配系数', key: 'slfpxsOne', value: null },
- { label: '碳源当量', key: 'tydlOne', value: null },
- { label: '转换系数', key: 'zhxsOne', value: null },
- { label: '稀释倍数', key: 'sxpsOne', value: null },
- { label: '药剂密度', key: 'yymdOne', value: null },
- // { label: '最小启动流量', key: 'zxqdllOne', value: null },
- { label: '碳氮比', key: 'tdbOne', value: null }
- ]);
- const northColumnData = ref([
- { label: '后反馈设定', key: 'htfksdTwo', value: null },
- { label: '基准系数', key: 'jzxsTwo', value: null },
- { label: '修正系数', key: 'xzxsTwo', value: null },
- { label: '控制系数', key: 'kzxsTwo', value: null },
- { label: '水量分配系数', key: 'slfpxsTwo', value: null },
- { label: '碳源当量', key: 'tydlTwo', value: null },
- { label: '转换系数', key: 'zhxsTwo', value: null },
- { label: '稀释倍数', key: 'sxpsTwo', value: null },
- { label: '药剂密度', key: 'yymdTwo', value: null },
- // { label: '最小启动流量', key: 'zxqdllTwo', value: null },
- { label: '碳氮比', key: 'tdbTwo', value: null }
- ]);
- // water实时数据
- const waterConfigParams = ref({});
- // 基础数据
- const dataSourceParams = ref({
- type: 0,
- typeOne: true,
- typeTwo: true
- })
- // 系数
- const baseSourceParams = ref({
- type: 0
- })
- // 计算碳氮比
- const tdbNum = computed(() => {
- const type = dataSourceParams.value.type;
- const [r1, r2, rOne, rTwo] = getTotalNum();
- const {
- jsLlOne, jsLlTwo,
- jsCodOne, jsCodTwo,
- jsTnOne, jsTnTwo,
- tydlOne, tydlTwo,
- zhxsOne, zhxsTwo
- } = dataSourceParams.value;
- if (type == 0) {
- return Number(((rOne * 1000 / jsLlOne * tydlOne + jsCodOne * zhxsOne * tydlOne) / jsTnOne).toFixed(2));
- }
- if (type == 1) {
- return Number(((rTwo * 1000 / jsLlTwo * tydlTwo + jsCodTwo * zhxsTwo * tydlTwo) / jsTnTwo).toFixed(2));
- }
- })
- watch(() => tdbNum.value, tdb => {
- if ( dataSourceParams.value.type === 0 ) {
- southColumnData.value[southColumnData.value.length - 1].value = tdb;
- dataSourceParams.value.tdbOne = tdb;
- } else {
- northColumnData.value[northColumnData.value.length - 1].value = tdb;
- dataSourceParams.value.tdbTwo = tdb;
- }
- })
- const transformData = (list) => {
- list = list.map(item => {
- Object.keys(dataSourceParams.value).forEach(([key]) => {
- dataSourceParams.value[item.key] = item.value;
- })
- return item;
- })
- return list;
- }
- // 编辑系数 - confirm
- const onEditConfirm = (source) => {
- setting.value['isVisibleBtn' + source] = true;
- // isVisibleBtn.value = true;
-
- transformData(southColumnData.value);
- transformData(northColumnData.value);
- handleMedicateAmount();
- }
- // 编辑系数 - cancel
- const onEditCancel = (source) => {
- setting.value['isVisibleBtn' + source] = true;
- isVisibleBtn.value = true;
- Object.keys(dataSourceParams.value).forEach((key) => {
- southColumnData.value.map((item) => {
- if (item.key === key) {
- item.value = dataSourceParams.value[key];
- }
- })
- northColumnData.value.map((item) => {
- if (item.key === key) {
- item.value = dataSourceParams.value[key];
- }
- })
- })
- }
- // 切换tabs
- const onUpdateTab = (index) => {
- dataSourceParams.value.type = index;
- onEditCancel('One');
- onEditCancel('Two');
- // setTimeout(() => handleMedicateAmount())
- }
- function getTotalNum() {
- const {
- hycXsyOne = 0, hycXsyTwo = 0,
- qycAdOne = 0, qycAdTwo = 0,
- qycYxyOne = 0, qycYxyTwo = 0,
- jsLlOne = 0, jsLlTwo = 0,
- jsCodOne = 0, jsCodTwo = 0,
- 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) + (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) + (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;
-
- 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;
- if ( r2 > maxAddAmount ) r2 = maxAddAmount;
- if ( r2 < minAddAmount ) r2 = minAddAmount;
- return [r1, r2, stepSouthTwo, stepNorthTwo];
- }
- const onConfirmUpdate = async () => {
- const params = {
- ...dataSourceParams.value,
- typeOne: dataSourceParams.value.typeOne ? 0 : 1,
- typeTwo: dataSourceParams.value.typeTwo ? 0 : 1,
- medicineAmountOne: dataSourceParams.value.typeOne ? null : dataSourceParams.value.medicineAmountOne,
- medicineAmountTwo: dataSourceParams.value.typeTwo ? null : dataSourceParams.value.medicineAmountTwo,
- }
- await controlApi.postAddRecord(params);
- isVisibleUpdateInfo.value = false;
- message.success("系统加药量,更新成功");
-
- 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) => {
- const key = dataSourceParams.value.type === 0 ? 'typeOne' : 'typeTwo';
-
- dataSourceParams.value[key] = val;
-
- handleMedicateAmount();
- }
- // 更新投药结果
- const handleMedicateAmount = () => {
- const type = dataSourceParams.value.type;
- const { updateNum1, updateNum2 } = unref(resultNumberSet);
- const tdb = tdbNum.value;
- const [r1, r2] = getTotalNum();
- waringTips();
- if ( type == 0 ) {
- // && dataSourceParams.value.medicineAmountOne != updateNum1
- if ( !dataSourceParams.value.typeOne ) { // 手动
- const medicineAmountOne = dataSourceParams.value.medicineAmountOne;
- if ( medicineAmountOne && medicineAmountOne != 0 ) {
- resultNumberSet.value.updateNum1 = dataSourceParams.value.medicineAmountOne;
- resultNumberSet.value.currentResultNum1 = dataSourceParams.value.medicineAmountOne;
- isVisibleUpdateInfo.value = true;
- // message.warning("北池有新的投放方案, 请查看");
- } else {
- // resultNumberSet.value.updateNum1 = dataSourceParams.value.medicineAmountOne;
- // isVisibleUpdateInfo.value = true;
- }
- // r1 != updateNum1 &&
- } else if ( r1 != updateNum1 && dataSourceParams.value.typeOne ) {
- resultNumberSet.value.updateNum1 = r1;
- isVisibleUpdateInfo.value = true;
- dataSourceParams.value.tdbOne = tdb;
- // message.warning("北池有新的投放方案, 请查看");
- }
- }
- if ( type == 1 ) {
- // && dataSourceParams.value.medicineAmountTwo != updateNum2
- if (!dataSourceParams.value.typeTwo ) {
- const medicineAmountTwo = dataSourceParams.value.medicineAmountTwo;
- if (medicineAmountTwo && medicineAmountTwo != 0 ) {
- resultNumberSet.value.updateNum2 = dataSourceParams.value.medicineAmountTwo;
- resultNumberSet.value.currentResultNum2 = dataSourceParams.value.medicineAmountTwo;
- isVisibleUpdateInfo.value = true;
- // message.warning("南池有新的投放方案, 请查看");
- } else {
- // resultNumberSet.value.updateNum2 = dataSourceParams.value.medicineAmountTwo;
- // isVisibleUpdateInfo.value = true;
- }
- //
- } else if ( r2 != updateNum2 && dataSourceParams.value.typeTwo) {
- resultNumberSet.value.updateNum2 = r2;
- isVisibleUpdateInfo.value = true;
- dataSourceParams.value.tdbTwo = tdb;
- // message.warning("南池有新的投放方案, 请查看");
- }
- }
- }
- // 查看系统警报
- 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: () => h('ul', [
- h('li', {style: { fontWeight: 'bold' }}, '• 系统计算加药与现场实际流量计偏移过大'),
- h('li', '请排查现场碳源储罐液位、加药泵和流量计等,确保运行正常'),
- ])
- }
- }
-
- const result = {
- twoTips: [],
- oneTips: [],
- threeTips: []
- }
-
- const qEnum = ['• 好氧池硝酸盐超管控值', '• 好氧池硝酸盐控制目标偏移过大']
- const questionCollect = {
- firstItem: [],
- secondItem: [],
- }
-
- if ( isEmpty(hycXsyOne) && isEmpty(htfksdOne) && isEmpty(kzmbplbjz) ) {
- if (( hycXsyOne - htfksdOne ) > kzmbplbjz ) {
- questionCollect.firstItem.push('北池');
- }
-
- if ( hycXsyOne > hycxsygkz ) {
- questionCollect.secondItem.push('北池');
- }
- }
-
- if ( isEmpty(hycXsyTwo) && isEmpty(htfksdTwo) && isEmpty(kzmbplbjz) ) {
- if ( (hycXsyTwo - htfksdTwo) > kzmbplbjz ) {
- questionCollect.firstItem.push('南池');
- }
- if ( hycXsyTwo > hycxsygkz ) {
- questionCollect.secondItem.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) && zuTaiStatus.value.activeOne == 1) {
- if (addDifferenceOne > minAddAmount && addDifferenceOne > jylpybjz) {
- result.threeTips.push('北池');
- }
- }
-
- if ( isEmpty(addDifferenceTwo) && isEmpty(jylpybjz) && isEmpty(minAddAmount) && zuTaiStatus.value.activeTwo == 1) {
- if (addDifferenceTwo > minAddAmount && addDifferenceTwo > jylpybjz) {
- result.threeTips.push('南池');
- }
- }
-
- const r = Object.entries(questionCollect).map(([ key, value ], index) => {
- if ( !value.length ) return;
- return qEnum[index] + "(" + value.join(' | ') + ")";
- }).filter(Boolean);
- warningList.value = Object.entries(result).map(([key, value]) => {
- if ( key === 'oneTips' ) {
- if ( !r.length ) return;
- const renderDomArr = r.map(text => h('li', {style: { fontWeight: 'bold' }}, text));
- return {
- title: tipsEnum[key].title,
- content: () => h('ul', renderDomArr.concat(h('li', tipsEnum[key].content))),
- duration: 30 * 1000,
- keepAliveOnHover: true,
- 'container-style': {
- width: '500px'
- }
- }
- }
- if ( value.length ) {
- return {
- ...tipsEnum[key],
- title: tipsEnum[key].title + "(" + value.join(' | ') + ")",
- duration: 30 * 1000,
- keepAliveOnHover: true,
- }
- }
- }).filter(Boolean);
- console.log("warningList", warningList);
- }
- onMounted(async () => {
- let countDown = 5;
- timer1 = setTimeout(() => {
- message.warning('有新检测数据,30秒后刷新系统,请注意保存设置',
- { duration: 6 * 1000 }
- )
- timer2 = setTimeout(() => {
- msgReactive = message.create('即将更新系统数据,5秒后刷新', {
- type: 'warning',
- duration: 6 * 10000
- });
- timerInterval = setInterval(() => {
- if ( countDown == 1 ) {
- clearInterval(timerInterval);
- return location.reload();
- }
- countDown --;
- msgReactive.content = `即将更新系统数据,${countDown}秒后刷新`;
- }, 1000)
- }, 25 * 1000)
- }, 4.5 * 60 * 1000);
- const { data: valSet } = await controlApi.getMinMaxVal();
-
- minAndMaxValue.value = valSet;
- // 获取最后一条记录 getSystemStatus
- await controlApi.getBaseData().then(({ data }) => {
- const {
- addTypeOne,
- addTypeTwo,
- typeOne = 0,
- typeTwo = 0,
- jsLlTypeOne, jsLlOne, jsCodTypeOne, jsCodOne, hycXsyTypeOne, hycXsyOne, qycYxyTypeOne, qycYxyOne, qycAdTypeOne, qycAdOne, jsTnTypeOne, jsTnOne,
- jsLlTypeTwo, jsLlTwo, jsCodTypeTwo, jsCodTwo, hycXsyTypeTwo, hycXsyTwo, qycYxyTypeTwo, qycYxyTwo, qycAdTypeTwo, qycAdTwo, jsTnTypeTwo, jsTnTwo,
- htfksdOne, jzxsOne, xzxsOne, kzxsOne, slfpxsOne, tydlOne, zhxsOne, sxpsOne, yymdOne, zxqdllOne, tdbOne,
- htfksdTwo, jzxsTwo, xzxsTwo, kzxsTwo, slfpxsTwo, tydlTwo, zhxsTwo, sxpsTwo, yymdTwo, zxqdllTwo, tdbTwo,
- // 投加量
- medicineAmountOne, medicineAmountTwo,
- // 瞬时流量
- tytjTransientLLOne, tytjTransientLLTwo,
- addDifferenceOne,
- addDifferenceTwo
- } = data;
-
- // 0 不可以 组态投放 1 可以 系统投放
- zuTaiStatus.value = { activeOne: addTypeOne, activeTwo: addTypeTwo };
- // 系数
- baseSourceParams.value = {
- ...data
- };
- resultNumberSet.value = {
- updateNum1: medicineAmountOne,
- updateNum2: medicineAmountTwo,
- flowNum1: tytjTransientLLOne,
- flowNum2: tytjTransientLLTwo,
- doseNum1: medicineAmountOne,
- doseNum2: medicineAmountTwo,
- currentResultNum1: medicineAmountOne,
- currentResultNum2: medicineAmountTwo
- }
- // 数据源
- dataSourceParams.value = {
- type: 0,
- typeOne: !!!typeOne,
- typeTwo: !!!typeTwo,
- jsLlTypeOne, jsLlOne, jsCodTypeOne, jsCodOne, hycXsyTypeOne, hycXsyOne, qycYxyTypeOne, qycYxyOne, qycAdTypeOne, qycAdOne, jsTnTypeOne, jsTnOne,
- htfksdOne, jzxsOne, xzxsOne, kzxsOne, slfpxsOne, tydlOne, zhxsOne, sxpsOne, yymdOne, zxqdllOne, tdbOne,
-
- jsLlTypeTwo, jsLlTwo, jsCodTypeTwo, jsCodTwo, hycXsyTypeTwo, hycXsyTwo, qycYxyTypeTwo, qycYxyTwo, qycAdTypeTwo, qycAdTwo, jsTnTypeTwo, jsTnTwo,
- htfksdTwo, jzxsTwo, xzxsTwo, kzxsTwo, slfpxsTwo, tydlTwo, zhxsTwo, sxpsTwo, yymdTwo, zxqdllTwo, tdbTwo,
- medicineAmountOne: typeOne == 0 || !typeOne ? null : medicineAmountOne,
- medicineAmountTwo: typeTwo == 0 || !typeOne ? null : medicineAmountTwo,
- addDifferenceOne,
- addDifferenceTwo
- };
- waringTips();
- })
-
- // 获取实时数据
- await controlApi.getNumValue().then(({ data }) => {
- // water实时数据
- waterConfigParams.value = data;
-
- // 重新计算碳氮比
- const tdb = tdbNum.value;
- dataSourceParams.value.tdbOne = tdb;
- southColumnData.value = southColumnData.value.map(item => {
- item.value = dataSourceParams.value[item.key];
- if ( item.key === 'tdbOne' ) {
- item.value = tdb;
- }
- return item;
- })
- northColumnData.value = northColumnData.value.map(item => {
- item.value = dataSourceParams.value[item.key];
- return item;
- })
- })
- // 获取是否允许投药开关 - 锡林浩特
- // await controlApi.getSystemStatus().then(({ data }) => {
- // // 0不允许 1允许
- // // 系统 未投放 系统 投放中
- // systemStatus.value = { ...data };
- // });
- })
- onUnmounted(() => {
- clearTimeout(timer1);
- clearTimeout(timer2);
- clearTimeout(timerInterval);
- })
- </script>
- <template>
- <section class="flex items-start h-full">
- <TheChatView leftTitle="智适应碳源投加" :isChatSlot="false" :isFooter="false">
- <template #control>
- <div class="control-container space-x-[12px]">
- <div class="left-section">
- <BaseTitle title="智能投加计算"></BaseTitle>
- <n-scrollbar class="scrollbar" style="height: 100%;">
- <div class="form-content">
- <BaseCard title="选择池组手自动方式">
- <n-tabs justify-content="space-between" type="line" :bar-width="0" tab-style="width: 200px;"
- tab-class="custom-tab_item" animated :on-update:value="onUpdateTab" :value="dataSourceParams.type">
- <n-tab-pane :name="0" tab="北池">
- <div class="panel-header_main">
- <p>设置投放方式</p>
- <NSwitch size="small" v-model:value="dataSourceParams.typeOne" class="text-[12px]" :rail-style="railStyle" :on-update:value="handleAutoSwitch">
- <template #checked>自动</template>
- <template #unchecked>手动</template>
- </NSwitch>
- </div>
- <div v-show="dataSourceParams.typeOne">
- <div class="space-y-[12px] mb-[20px]">
- <BaseChooseItem
- tab-key="south"
- title="进水流量"
- unit="m³"
- @on-update="handleMedicateAmount"
- v-model:type="dataSourceParams.jsLlTypeOne"
- v-model:value1="dataSourceParams.jsLlOne"
- :min="minAndMaxValue.minJsll"
- :max="minAndMaxValue.maxJsll"
- :btn-group="[
- { label: '手动', value1: '', value2: '' },
- { label: '仪表', value1: waterConfigParams.jslYB }
- ]"></BaseChooseItem>
- <BaseChooseItem
- tab-key="south"
- title="进水COD"
- unit="mg/L"
- @on-update="handleMedicateAmount"
- v-model:type="dataSourceParams.jsCodTypeOne"
- v-model:value1="dataSourceParams.jsCodOne"
- :min="minAndMaxValue.minJsCod"
- :max="minAndMaxValue.maxJsCod"
- :btn-group="[
- { label: '手动', value1: '', value2: '' },
- { label: '仪表', value1: waterConfigParams.jsCodYB },
- { label: '化验', value1: waterConfigParams.jsCodHY }
- ]"></BaseChooseItem>
- <BaseChooseItem
- tab-key="south"
- title="好氧池硝酸盐"
- unit="mg/L"
- @on-update="handleMedicateAmount"
- v-model:type="dataSourceParams.hycXsyTypeOne"
- v-model:value1="dataSourceParams.hycXsyOne"
- :btn-group="[
- { label: '手动', value1: '', value2: '' },
- { label: '化验', value1: waterConfigParams.hyXsyHYOne },
- { label: '预测', value1: '', disabled: true }
- ]"></BaseChooseItem>
- <BaseChooseItem
- tab-key="south"
- title="缺氧池硝酸盐"
- unit="mg/L"
- @on-update="handleMedicateAmount"
- v-model:type="dataSourceParams.qycYxyTypeOne"
- v-model:value1="dataSourceParams.qycYxyOne"
- :btn-group="[
- { label: '手动', value1: '', value2: '' },
- { label: '化验', value1: waterConfigParams.qyXsyHYOne },
- { label: '预测', value1: '', disabled: true }
- ]"></BaseChooseItem>
- <BaseChooseItem
- tab-key="south"
- title="缺氧池氨氮"
- unit="mg/L"
- @on-update="handleMedicateAmount"
- v-model:type="dataSourceParams.qycAdTypeOne"
- v-model:value1="dataSourceParams.qycAdOne"
- :btn-group="[
- { label: '手动', value1: '', value2: '' },
- { label: '化验', value1: waterConfigParams.qyAdHYOne },
- { label: '预测', value1: '', disabled: true }
- ]"></BaseChooseItem>
- <BaseChooseItem
- tab-key="south"
- title="进水总氮"
- unit="mg/L"
- @on-update="handleMedicateAmount"
- v-model:type="dataSourceParams.jsTnTypeOne"
- v-model:value1="dataSourceParams.jsTnOne"
- :btn-group="[
- { label: '手动', value1: '', value2: '' },
- { label: '仪表', value1: waterConfigParams.jsTnYB }
- ]"></BaseChooseItem>
- </div>
- <BaseCard title="设定参数系数" style="margin: 0" tips="建议使用默认值,非必要不修改">
- <template #titleRight>
- <div>
- <div class="flex items-center space-x-[4px] cursor-pointer text-[#2454FF] text-[13px]"
- v-show="setting.isVisibleBtnOne" @click="setting.isVisibleBtnOne = false">
- <svg width="16" height="16" viewBox="0 0 16 16" fill="none"
- xmlns="http://www.w3.org/2000/svg">
- <path d="M2.33337 14H14.3334" stroke="#2454FF" stroke-linecap="round"
- stroke-linejoin="round" />
- <path d="M3.66663 8.90663V11.3333H6.10569L13 4.43603L10.565 2L3.66663 8.90663Z"
- stroke="#2454FF" stroke-linejoin="round" />
- </svg>
- <span>编辑</span>
- </div>
- <ul class="flex items-center text-[13px] space-x-[8px] cursor-pointer"
- v-show="!setting.isVisibleBtnOne">
- <li class="cursor-pointer" @click="onEditConfirm('One')" style="color: #2454FF">确定</li>
- <li class="cursor-pointer text-[#B0B7C0]" @click="onEditCancel('One')">取消</li>
- </ul>
- </div>
- </template>
- <ul class="data-source-list space-y-[12px]">
- <li class="data-soruce-item" v-for="item, index in southColumnData">
- <span>{{ item.label }}:</span>
- <span class="unit" v-show="setting.isVisibleBtnOne">
- {{ dataSourceParams[item.key] }}
- {{ index === 0 ? 'mg/L' : '' }}
- </span>
- <div style="width: 140px;" v-show="!setting.isVisibleBtnOne">
- <BaseInput
- :unit="index === 0 ? 'mg/L' : ''"
- size='small'
- :isNeedFlotBtn="false"
- v-model="item.value"
- isCenter
- placeholder=""
- :readonly="index === southColumnData.length - 1"
- >
- </BaseInput>
- </div>
- </li>
- </ul>
- </BaseCard>
- </div>
-
- <div class="w-full flex items-center justify-between" v-show="!dataSourceParams.typeOne">
- <span>人工投放:</span>
- <div class="w-[200px] flex items-center space-x-[8px]">
- <BaseInput
- placeholder="请输入人工投放量"
- :isCloseIcon="false"
- v-model="dataSourceParams.medicineAmountOne"
- @on-blur="handleMedicateAmount"
- unit="L/h"
- :min="minAndMaxValue.minAddAmount"
- :max="minAndMaxValue.maxAddAmount"
- >
- </BaseInput>
- </div>
- </div>
- </n-tab-pane>
-
- <!-- 北池 start -->
- <n-tab-pane :name="1" tab="南池">
- <div class="panel-header_main">
- <p>设置投放方式</p>
- <NSwitch size="small" v-model:value="dataSourceParams.typeTwo" class="text-[12px]" :rail-style="railStyle" :on-update:value="handleAutoSwitch">
- <template #checked>自动</template>
- <template #unchecked>手动</template>
- </NSwitch>
- </div>
- <div v-show="dataSourceParams.typeTwo">
- <div class="space-y-[12px] mb-[20px]">
- <BaseChooseItem
- tab-key="south"
- title="进水流量"
- unit="m³"
- @on-update="handleMedicateAmount"
- v-model:type="dataSourceParams.jsLlTypeTwo"
- v-model:value1="dataSourceParams.jsLlTwo"
- :min="minAndMaxValue.minJsll"
- :max="minAndMaxValue.maxJsll"
- :btn-group="[
- { label: '手动', value1: '', value2: '' },
- { label: '仪表', value1: waterConfigParams.jslYB }
- ]"></BaseChooseItem>
- <BaseChooseItem
- tab-key="south"
- title="进水COD"
- unit="mg/L"
- @on-update="handleMedicateAmount"
- v-model:type="dataSourceParams.jsCodTypeTwo"
- v-model:value1="dataSourceParams.jsCodTwo"
- :min="minAndMaxValue.minCod"
- :max="minAndMaxValue.manCod"
- :btn-group="[
- { label: '手动', value1: '', value2: '' },
- { label: '仪表', value1: waterConfigParams.jsCodYB },
- { label: '化验', value1: waterConfigParams.jsCodHY }
- ]"></BaseChooseItem>
- <BaseChooseItem
- tab-key="south"
- title="好氧池硝酸盐"
- unit="mg/L"
- @on-update="handleMedicateAmount"
- v-model:type="dataSourceParams.hycXsyTypeTwo"
- v-model:value1="dataSourceParams.hycXsyTwo"
- :btn-group="[
- { label: '手动', value1: '', value2: '' },
- { label: '化验', value1: waterConfigParams.hyXsyHYTwo },
- { label: '预测', value1: '', disabled: true }
- ]"></BaseChooseItem>
- <BaseChooseItem
- tab-key="south"
- title="缺氧池硝酸盐"
- unit="mg/L"
- @on-update="handleMedicateAmount"
- v-model:type="dataSourceParams.qycYxyTypeTwo"
- v-model:value1="dataSourceParams.qycYxyTwo"
- :btn-group="[
- { label: '手动', value1: '', value2: '' },
- { label: '化验', value1: waterConfigParams.qyXsyHYTwo},
- { label: '预测', value1: '', disabled: true }
- ]"></BaseChooseItem>
- <BaseChooseItem
- tab-key="south"
- title="缺氧池氨氮"
- unit="mg/L"
- @on-update="handleMedicateAmount"
- v-model:type="dataSourceParams.qycAdTypeTwo"
- v-model:value1="dataSourceParams.qycAdTwo"
- :btn-group="[
- { label: '手动', value1: '', value2: '' },
- { label: '化验', value1: waterConfigParams.qyAdHYTwo},
- { label: '预测', value1: '', disabled: true }
- ]"></BaseChooseItem>
- <BaseChooseItem
- tab-key="south"
- title="进水总氮"
- unit="mg/L"
- @on-update="handleMedicateAmount"
- v-model:type="dataSourceParams.jsTnTypeTwo"
- v-model:value1="dataSourceParams.jsTnTwo"
- :btn-group="[
- { label: '手动', value1: '', value2: '' },
- { label: '仪表', value1: waterConfigParams.jsTnYB }
- ]"></BaseChooseItem>
- </div>
- <BaseCard title="设定参数系数" style="margin: 0" tips="建议使用默认值,非必要不修改">
- <template #titleRight>
- <div>
- <div class="flex items-center space-x-[4px] cursor-pointer text-[#2454FF] text-[13px]"
- v-show="setting.isVisibleBtnTwo" @click="setting.isVisibleBtnTwo = false">
- <svg width="16" height="16" viewBox="0 0 16 16" fill="none"
- xmlns="http://www.w3.org/2000/svg">
- <path d="M2.33337 14H14.3334" stroke="#2454FF" stroke-linecap="round"
- stroke-linejoin="round" />
- <path d="M3.66663 8.90663V11.3333H6.10569L13 4.43603L10.565 2L3.66663 8.90663Z"
- stroke="#2454FF" stroke-linejoin="round" />
- </svg>
- <span>编辑</span>
- </div>
- <ul class="flex items-center text-[13px] space-x-[8px] cursor-pointer"
- v-show="!setting.isVisibleBtnTwo">
- <li class="cursor-pointer" @click="onEditConfirm('Two')" style="color: #2454FF">确定</li>
- <li class="cursor-pointer text-[#B0B7C0]" @click="onEditCancel('Two')">取消</li>
- </ul>
- </div>
- </template>
- <ul class="data-source-list space-y-[12px]">
- <li class="data-soruce-item" v-for="item, index in northColumnData">
- <span>{{ item.label }}:</span>
- <span class="unit" v-show="setting.isVisibleBtnTwo">
- {{ dataSourceParams[item.key] }}
- {{ index === 0 ? 'mg/L' : '' }}
- </span>
- <div style="width: 140px;" v-show="!setting.isVisibleBtnTwo">
- <BaseInput
- isCenter
- placeholder=""
- size='small'
- v-model="item.value"
- :unit="index === 0 ? 'mg/L' : ''"
- :isNeedFlotBtn="false"
- :readonly="index === northColumnData.length - 1"
- :min="minAndMaxValue.minAddAmount"
- :max="minAndMaxValue.maxAddAmount"
- >
- </BaseInput>
- </div>
- </li>
- </ul>
- </BaseCard>
- </div>
- <div class="w-full flex items-center justify-between" v-show="!dataSourceParams.typeTwo">
- <span>人工投放:</span>
- <div class="w-[200px] flex items-center space-x-[8px ]">
- <BaseInput :isCloseIcon="false" v-model="dataSourceParams.medicineAmountTwo"
- @on-blur="handleMedicateAmount" unit="L/h" placeholder="请输入人工投放量">
- </BaseInput>
- </div>
- </div>
- </n-tab-pane>
- </n-tabs>
- </BaseCard>
- </div>
- </n-scrollbar>
- </div>
- <div class="right-section">
- <BaseTitle title="智能投加计算结果" type="second">
- <template #right>
- <div class="warning-btn" @click="onSystemWarning" v-show="warningList.length">查看系统警报</div>
- </template>
- </BaseTitle>
- <div class="right-section-content">
- <TheResultPanel
- :nums="resultNumberSet"
- :minAndMaxNum="minAndMaxValue"
- v-model:system="zuTaiStatus"
- v-model="isVisibleUpdateInfo"
- @on-update="onConfirmUpdate"
- >
- </TheResultPanel>
- <TheEchartPanel
- :htfksdOne="dataSourceParams.htfksdOne"
- :htfksdTwo="dataSourceParams.htfksdTwo"
- v-model:change="isVisibleUpdateInfo"
- ></TheEchartPanel>
- </div>
- </div>
- </div>
- </template>
- </TheChatView>
- </section>
- </template>
- <style lang="scss" scoped>
- .control-container {
- @include flex(x, start, start);
- height: 100%;
- .left-section {
- display: flex;
- flex-flow: column;
- flex-shrink: 0;
- width: 440px;
- height: 100%;
- border-radius: 10px;
- background: #fff;
- .status-bar {
- display: inline-block;
- padding: 4px 14px;
- margin-left: 20px;
- border-top: 0.5px solid rgba(212, 241, 255, 0.00);
- border-bottom: 0.5px solid rgba(212, 241, 255, 0.00);
- background: linear-gradient(90deg, rgba(240, 250, 255, 0.00) 0%, #E9F8FF 27.27%, rgba(240, 250, 255, 0.00) 100%);
- i {
- line-height: 24px;
- background: linear-gradient(92deg, #5ABBF2 12.24%, #2454FF 63.2%);
- background-clip: text;
- -webkit-background-clip: text;
- -webkit-text-fill-color: transparent;
- font-weight: bold;
- }
- }
- .scrollbar {
- height: 100%;
- }
- .form-content {
- padding: 0 16px 0px 16px;
- }
- .panel-header_main {
- @include flex(x, center, between);
- padding-bottom: 10px;
- padding-right: 5px;
- margin-bottom: 12px;
- border-bottom: 1px solid #EEE;
- color: #86909C;
- span {
- position: relative;
- display: inline-block;
- width: 60px;
- cursor: pointer;
- }
- .active {
- &:after {
- position: absolute;
- left: 50%;
- bottom: -10px;
- transform: translateX(-50%);
- content: ' ';
- display: block;
- width: 28px;
- height: 2px;
- background: #2454FF;
- }
- }
- }
- }
- .data-source-list {
- .data-soruce-item {
- @include flex(x, center, between);
- .inp-inner {
- width: 112px;
- }
- .unit {
- font-family: "D-DIN-PRO-700-Bold";
- font-weight: bold;
- font-size: 12px;
- color: #333;
- }
- }
- }
- }
- .right-section {
- width: 100%;
- height: 100%;
- border-radius: 8px;
- background: #fff;
- overflow: hidden;
- .right-section-content {
- display: flex;
- flex-flow: column;
- height: calc(100% - 75px);
- }
- }
- .warning-btn {
- width: 116px;
- height: 32px;
- border-radius: 8px;
- background: #FFF7F7;
- line-height: 32px;
- font-size: 14px;
- text-align: center;
- color: #FD5D4D;
- cursor: pointer;
- }
- // 通用区域的样式
- .btn {
- width: 80px;
- height: 32px;
- border-radius: 4px;
- border: 1px solid #D3D7DD;
- text-align: center;
- font-size: 14px;
- line-height: 32px;
- color: #1A2029;
- }
- .btn-primary {
- border: 0;
- background: var(--Linear, linear-gradient(270deg, #3BD6E3 0%, #019AFE 100%));
- font-weight: bold;
- color: #fff;
- }
- .btn-info {
- width: 44px;
- height: 28px;
- border-radius: 4px;
- border: 1px solid #D3D7DD;
- background: #fff;
- font-size: 12px;
- text-align: center;
- line-height: 28px;
- color: #1A2029;
- cursor: pointer;
- }
- .btn-info_active {
- color: #2454FF;
- border: 1px solid #2454FF;
- background: #EBF0FF;
- }
- .radio {
- display: block;
- width: 12px;
- height: 12px;
- border-radius: 100%;
- border: 1px solid #ccc;
- cursor: pointer;
- }
- .radio_big {
- width: 16px;
- height: 16px;
- }
- .radio-active {
- transition: all .1s;
- border: 3px solid #2454FF;
- }
- .radio_big.radio-active {
- border: 4px solid #2454FF;
- }
- </style>
- <style lang="scss">
- .custom-tab_item {
- @include flex (x, center, center);
- height: 35px;
- border-radius: 4px;
- background: #F3F5FA;
- &.n-tabs-tab--active {
- transition: none !important;
- border-radius: 4px;
- transition: none !important;
- background: url('@/assets/images/control/bg-tabs-item.png') -3px 0px no-repeat, linear-gradient(180deg, #F1F3FE 0%, #FFF 100%);
- background-size: 103% 100%;
- }
- }
- .control-container .left-section {
- .n-tabs-nav-scroll-content {
- padding-bottom: 10px;
- }
- .n-tabs-nav-scroll-content {
- border: 0px solid red !important;
- }
- }
- </style>
|