| | |
| | | <script setup> |
| | | import { ref } from "vue"; |
| | | <script setup name="tabSystem"> |
| | | import { nextTick, ref, reactive, computed, watch, onMounted } from "vue"; |
| | | import svgDiagram from '@/components/svgDiagram.vue'; |
| | | import info from '@/components/info.vue'; |
| | | // import lineChart from '@/components/echarts/line1.vue'; |
| | | import lineChart from '@/components/echarts/BaseChart.vue'; |
| | | import lineChart from '@/components/echarts/line1.vue'; |
| | | import lineChart2 from '@/components/echarts/line2.vue'; |
| | | import hrParams from '@/components/hrParams.vue'; |
| | | import devAlarmParams from '../devAlarmParams.vue'; |
| | | |
| | | import lineChart3 from '@/components/echarts/line-scroll.vue'; |
| | | // import lineChart from '@/components/echarts/BaseChart.vue'; |
| | | // import lineChart from '../bar8.vue'; |
| | | import moment from 'moment'; |
| | | import getBinaryDigits from '@/utils/getBinaryDigits.js'; |
| | | |
| | | import useElement from "@/hooks/useElement.js"; |
| | | const { $loading, $message, $confirm } = useElement(); |
| | | |
| | | |
| | | import { |
| | | getBattDevData100, |
| | | getPwrHisAcinData100, |
| | | getPwrHisDcoutData100, |
| | | getPwrHeartParam, |
| | | } from "@/api/realtime"; |
| | | |
| | | import { |
| | | stopDis, |
| | | restart, |
| | | } from '@/api/control'; |
| | | |
| | | |
| | | const props = defineProps({ |
| | | data: { |
| | | type: Object, |
| | | default: {}, |
| | | }, |
| | | data: { |
| | | type: Object, |
| | | default: {}, |
| | | }, |
| | | powerId: { |
| | | type: [Number, String], |
| | | }, |
| | | devId: { |
| | | type: [Number, String], |
| | | }, |
| | | battgroupId: { |
| | | type: [Number, String], |
| | | }, |
| | | }); |
| | | |
| | | const tabIdx0 = ref(0); |
| | | const tabIdx1 = ref(0); |
| | | |
| | | const chart0 = ref(null); |
| | | const chart1 = ref(null); |
| | | const chart2 = ref(null); |
| | | |
| | | const labels_0 = [ |
| | | [ |
| | | ['一路A相电流', 'acin1Curra'], |
| | | ['一路B相电流', 'acin1Currb'], |
| | | ['一路C相电流', 'acin1Currc'], |
| | | ['二路A相电流', 'acin2Curra'], |
| | | ['二路B相电流', 'acin2Currb'], |
| | | ['二路C相电流', 'acin2Currc'], |
| | | ], |
| | | [ |
| | | ['一路A相电压', 'acin1Vola'], |
| | | ['一路B相电压', 'acin1Volb'], |
| | | ['一路C相电压', 'acin1Volc'], |
| | | ['二路A相电压', 'acin2Vola'], |
| | | ['二路B相电压', 'acin2Volb'], |
| | | ['二路C相电压', 'acin2Volc'], |
| | | ] |
| | | ]; |
| | | |
| | | const labels_1 = reactive([[], []]); |
| | | |
| | | const devRt = ref({ |
| | | devIp: "127.0.0.0", |
| | | devVersion: "1", |
| | | devId: 0, |
| | | devOnline: 0, |
| | | recordDatetime: "", |
| | | devTesttype: 0, |
| | | devTestgroupnum: 0, |
| | | devWorkstate: -1, |
| | | devAlarmstate: 0, |
| | | devTemp: 0.0, |
| | | devResTestState: 0, |
| | | devOnlinevollow: 0, |
| | | devEachgroupBattsum: 0, |
| | | devCaptestOnlinevol: 0.0, |
| | | devCaptestGroupvol: 0.0, |
| | | devCaptestCurr: 0.0, |
| | | devCaptestCap: 0.0, |
| | | devCaptestTimelong: 0, |
| | | devRestestCount: 0, |
| | | devCommcount: 0, |
| | | devErrcommcount: 0, |
| | | devRxnullerrcount: 0, |
| | | devLastCaptestStopType: 0, |
| | | devCondvoldp: 0.0, |
| | | devConresist: 0.0, |
| | | devConresist1: 0.0, |
| | | dev61850alarms: "", |
| | | devCondvoldp1: 0.0, |
| | | groupVol1: 0.0, |
| | | groupVol2: 0.0, |
| | | groupCurr1: 0.0, |
| | | groupCurr2: 0.0, |
| | | }); |
| | | |
| | | const battRt = ref({ |
| | | groupCurr: 0, |
| | | }); |
| | | |
| | | watch( |
| | | () => tabIdx0.value, |
| | | () => { |
| | | nextTick(() => { |
| | | tabIdx0Change(); |
| | | }); |
| | | }, |
| | | { immediate: true } |
| | | ); |
| | | |
| | | watch( |
| | | () => tabIdx1.value, |
| | | () => { |
| | | nextTick(() => { |
| | | tabIdx1Change(); |
| | | }); |
| | | }, |
| | | { immediate: true } |
| | | ); |
| | | |
| | | watch( |
| | | () => props.powerId, |
| | | (n) => { |
| | | if (!n) return; |
| | | |
| | | nextTick(() => { |
| | | getHeartParam(); |
| | | // getAcinData(); |
| | | // getDevData(); |
| | | // getDcoutData(); |
| | | numChange('acin'); |
| | | numChange('dcout'); |
| | | numChange('dev'); |
| | | }); |
| | | }, |
| | | { immediate: true } |
| | | ); |
| | | |
| | | watch( |
| | | () => props.data, |
| | | (n) => { |
| | | if (!n) return; |
| | | nextTick(() => { |
| | | updateRt(); |
| | | if (n.deviceState) { |
| | | devRt.value = n.deviceState; |
| | | } |
| | | if (n.battRtstate) { |
| | | battRt.value = n.battRtstate; |
| | | } |
| | | }); |
| | | }, |
| | | { immediate: true, deep: true } |
| | | ); |
| | | |
| | | const show_num = reactive({ |
| | | acin: 5, |
| | | dcout: 5, |
| | | dev: 5, |
| | | }); |
| | | |
| | | // 用来绘图的数据 |
| | | const chartData = reactive({ |
| | | acin: [], |
| | | dcout: [], |
| | | dev: [], |
| | | }); |
| | | |
| | | const modelCfg = ref([]); |
| | | const startIdx = ref(0); |
| | | |
| | | // 半小时的数据条数 1秒一笔计 |
| | | // 改为100笔 可配置 三个属性可以设置不同 |
| | | const counter = 30 * 60; |
| | | |
| | | let xLabels1 = ref([]); |
| | | let xLabels2 = ref([]); |
| | | |
| | | // 根据粒度 和查询结果 补全数据 |
| | | function completeData(type) { |
| | | // 根据粒度 计算出需要的条数 |
| | | let num = Math.ceil(counter / show_num[type]); |
| | | let _num = num - chartData[type].length; |
| | | let obj = null; |
| | | let res = [...chartData[type]]; |
| | | switch (type) { |
| | | case 'acin': |
| | | obj = { |
| | | acin1Vola: 0, |
| | | acin1Volb: 0, |
| | | acin1Volc: 0, |
| | | acin2Vola: 0, |
| | | acin2Volb: 0, |
| | | acin2Volc: 0, |
| | | acin1Curra: 0, |
| | | acin1Currb: 0, |
| | | acin1Currc: 0, |
| | | acin2Curra: 0, |
| | | acin2Currb: 0, |
| | | acin2Currc: 0, |
| | | }; |
| | | break; |
| | | case 'dcout': |
| | | obj = { |
| | | m1Outcurr: 0.0, |
| | | m2Outcurr: 0.0, |
| | | m3Outcurr: 0.0, |
| | | m4Outcurr: 0.0, |
| | | m5Outcurr: 0.0, |
| | | m6Outcurr: 0.0, |
| | | m7Outcurr: 0.0, |
| | | m8Outcurr: 0.0, |
| | | m9Outcurr: 0.0, |
| | | m10Outcurr: 0.0, |
| | | m11Outcurr: 0.0, |
| | | m12Outcurr: 0.0, |
| | | m13Outcurr: 0.0, |
| | | m14Outcurr: 0.0, |
| | | m15Outcurr: 0.0, |
| | | m16Outcurr: 0.0, |
| | | m1OutVol: 0.0, |
| | | m2OutVol: 0.0, |
| | | m3OutVol: 0.0, |
| | | m4OutVol: 0.0, |
| | | m5OutVol: 0.0, |
| | | m6OutVol: 0.0, |
| | | m7OutVol: 0.0, |
| | | m8OutVol: 0.0, |
| | | m9OutVol: 0.0, |
| | | m10OutVol: 0.0, |
| | | m11OutVol: 0.0, |
| | | m12OutVol: 0.0, |
| | | m13OutVol: 0.0, |
| | | m14OutVol: 0.0, |
| | | m15OutVol: 0.0, |
| | | m16OutVol: 0.0, |
| | | moutputvol: 0.0, |
| | | }; |
| | | break; |
| | | case 'dev': |
| | | obj = { |
| | | groupVol: 0.0, |
| | | onlineVol: 0.0, |
| | | groupCurr: 0.0, |
| | | groupTmp: 0.0, |
| | | loadCurr: 0.0, |
| | | }; |
| | | break; |
| | | } |
| | | let _xLabels1 = chartData['dcout'].map(item => item.recordDatetime); |
| | | let _xLabels2 = chartData['dev'].map(item => item.recordDatetime); |
| | | // 数据最小时间 |
| | | let minTime = chartData[type].length ? chartData[type][0].recordDatetime : moment().format('YYYY-MM-DD HH:mm:ss'); |
| | | if (_num > 0) { |
| | | for (let i = _num; i--;) { |
| | | minTime = moment(minTime).subtract(show_num[type], 'seconds').format('YYYY-MM-DD HH:mm:ss'); |
| | | res.unshift({ |
| | | recordDatetime: minTime, |
| | | ...obj, |
| | | }); |
| | | _xLabels1.unshift(minTime); |
| | | _xLabels2.unshift(minTime); |
| | | } |
| | | } |
| | | switch (type) { |
| | | case 'acin': |
| | | break; |
| | | case 'dcout': |
| | | xLabels1.value = yLabels.value.length ? _xLabels1 : []; |
| | | break; |
| | | case 'dev': |
| | | xLabels2.value = _xLabels2; |
| | | break; |
| | | } |
| | | chartData[type] = res; |
| | | } |
| | | |
| | | |
| | | function tabIdx0Change() { |
| | | updateChart0(); |
| | | } |
| | | |
| | | function tabIdx1Change() { |
| | | updateChart1(); |
| | | } |
| | | |
| | | async function getAcinData() { |
| | | let { code, data, data2 } = await getPwrHisAcinData100(props.powerId); |
| | | let list = []; |
| | | if (code && data) { |
| | | list = data2; |
| | | } |
| | | return list; |
| | | } |
| | | |
| | | async function getDevData() { |
| | | let { code, data, data2 } = await getBattDevData100(props.battgroupId, props.powerId); |
| | | let list = []; |
| | | if (code && data) { |
| | | list = data2; |
| | | } |
| | | return list; |
| | | } |
| | | |
| | | async function getDcoutData() { |
| | | let { code, data, data2, data3 } = await getPwrHisDcoutData100(props.powerId); |
| | | let list = []; |
| | | let cfg = []; |
| | | if (code && data) { |
| | | list = data2; |
| | | cfg = getBinaryDigits(data3).map((v, i) => ({ value: v, label: i + 1 })).filter(vv => vv.value).map(v => v.label); |
| | | } |
| | | console.log('cfg', cfg, '=============', data3); |
| | | |
| | | modelCfg.value = cfg; |
| | | if (cfg.length < 4) { |
| | | startIdx.value = 0; |
| | | } |
| | | // setLabel1(); |
| | | return list; |
| | | } |
| | | |
| | | const yLabels = computed(() => { |
| | | let res = modelCfg.value.map((idx) => `${idx}#整流器`); |
| | | if (modelCfg.value.length > 4) { |
| | | res = res.slice(startIdx.value, startIdx.value + 4); |
| | | } |
| | | return res; |
| | | }); |
| | | |
| | | // function setLabel1() { |
| | | // // console.log('??', modelCfg.value, '============='); |
| | | // if (modelCfg.value.length <= 4) { |
| | | // yLabels.value = modelCfg.value.map((idx) => `${idx}#整流器`); |
| | | // } else { |
| | | // yLabels.value = modelCfg.value.slice(startIdx.value, startIdx.value + 4).map((idx) => `${idx}#整流器`); |
| | | // } |
| | | // } |
| | | |
| | | const chartData1 = ref([]); |
| | | |
| | | function formatData1() { |
| | | let res = []; |
| | | for (let i = 0, len = chartData['dcout'].length; i < len; i++) { |
| | | yLabels.value.forEach((item, idx) => { |
| | | res[idx] = res[idx] || []; |
| | | let type = ['curr', 'Vol'][tabIdx1.value]; |
| | | let _prop = `m${idx + 1}Out${type}`; |
| | | |
| | | res[idx].push(chartData['dcout'][i][_prop]); |
| | | }); |
| | | } |
| | | // console.log('res format', res, yLabels.value, '============='); |
| | | |
| | | chartData1.value = res; |
| | | } |
| | | |
| | | |
| | | function stopHrTest() { |
| | | $confirm("停止核容测试", async () => { |
| | | let loading = $loading(); |
| | | let res = await stopDis(props.powerId, props.battgroupId); |
| | | loading.close(); |
| | | let { code, data } = res; |
| | | if (code && data) { |
| | | $message.success('操作成功'); |
| | | } else { |
| | | $message.error('操作失败'); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | function remoteRestart() { |
| | | $confirm("远程重启", async () => { |
| | | let loading = $loading(); |
| | | let res = await restart(props.powerId, props.battgroupId); |
| | | loading.close(); |
| | | let { code, data } = res; |
| | | if (code && data) { |
| | | $message.success('操作成功'); |
| | | } else { |
| | | $message.error('操作失败'); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | const devAlmVisible = ref(false); |
| | | function showDevAlarmParam() { |
| | | devAlmVisible.value = true; |
| | | } |
| | | |
| | | |
| | | async function numChange(type) { |
| | | switch (type) { |
| | | case 'acin': |
| | | chartData.acin = await getAcinData(); |
| | | completeData('acin'); |
| | | updateChart0(); |
| | | break; |
| | | case 'dcout': |
| | | chartData.dcout = await getDcoutData(); |
| | | // setLabel1(); |
| | | completeData('dcout'); |
| | | formatData1(); |
| | | updateChart1(); |
| | | break; |
| | | case 'dev': |
| | | chartData.dev = await getDevData(); |
| | | completeData('dev'); |
| | | updateChart2(); |
| | | break; |
| | | } |
| | | |
| | | } |
| | | |
| | | const battInfo = ref({}); |
| | | // 更新实时数据 |
| | | function updateRt() { |
| | | let pwrData = props.data.pwrdevAcdcdata; |
| | | if (!pwrData) { |
| | | return false; |
| | | } |
| | | // 修改三个图表的数据 |
| | | // chart0 chartData['acin'] |
| | | // 根据粒度 计算出需要的条数 |
| | | // let num = Math.ceil(counter / show_num['acin']); |
| | | chartData['acin'].shift(); |
| | | chartData['acin'].push(pwrData); |
| | | updateChart0(); |
| | | |
| | | // chart1 chartData['dcout'] |
| | | // 根据粒度 计算出需要的条数 |
| | | if (!chartData1.value.length) { |
| | | modelCfg.value = getBinaryDigits(props.data.powerInf.modelCfg).map((v, i) => ({ value: v, label: i + 1 })).filter(vv => vv.value).map(v => v.label); |
| | | pwrData.recordDatetime |
| | | let minTime = pwrData.recordDatetime; |
| | | let num = Math.ceil(counter / show_num['dcout']); |
| | | let _label = []; |
| | | let list = []; |
| | | for (let i = num; i--;) { |
| | | minTime = moment(minTime).subtract(show_num['dcout'], 'seconds').format('YYYY-MM-DD HH:mm:ss'); |
| | | list.unshift({ |
| | | recordDatetime: minTime, |
| | | m1Outcurr: 0.0, |
| | | m2Outcurr: 0.0, |
| | | m3Outcurr: 0.0, |
| | | m4Outcurr: 0.0, |
| | | m5Outcurr: 0.0, |
| | | m6Outcurr: 0.0, |
| | | m7Outcurr: 0.0, |
| | | m8Outcurr: 0.0, |
| | | m9Outcurr: 0.0, |
| | | m10Outcurr: 0.0, |
| | | m11Outcurr: 0.0, |
| | | m12Outcurr: 0.0, |
| | | m13Outcurr: 0.0, |
| | | m14Outcurr: 0.0, |
| | | m15Outcurr: 0.0, |
| | | m16Outcurr: 0.0, |
| | | m1OutVol: 0.0, |
| | | m2OutVol: 0.0, |
| | | m3OutVol: 0.0, |
| | | m4OutVol: 0.0, |
| | | m5OutVol: 0.0, |
| | | m6OutVol: 0.0, |
| | | m7OutVol: 0.0, |
| | | m8OutVol: 0.0, |
| | | m9OutVol: 0.0, |
| | | m10OutVol: 0.0, |
| | | m11OutVol: 0.0, |
| | | m12OutVol: 0.0, |
| | | m13OutVol: 0.0, |
| | | m14OutVol: 0.0, |
| | | m15OutVol: 0.0, |
| | | m16OutVol: 0.0, |
| | | moutputvol: 0.0, |
| | | }); |
| | | _label.unshift(minTime); |
| | | } |
| | | xLabels1.value = _label; |
| | | chartData['dcout'] = list; |
| | | } |
| | | |
| | | xLabels1.value.shift(); |
| | | xLabels1.value.push(pwrData.recordDatetime); |
| | | chartData['dcout'].shift(); |
| | | chartData['dcout'].push(pwrData); |
| | | nextTick(() => { |
| | | |
| | | formatData1(); |
| | | updateChart1(); |
| | | }); |
| | | |
| | | |
| | | // chart2 chartData['dev'] |
| | | // 根据粒度 计算出需要的条数 |
| | | // let num = Math.ceil(counter / show_num['dev']); |
| | | // TODO battRtstate 缺少loadCurr |
| | | let devObj = props.data.battRtstate; |
| | | xLabels2.value.shift(); |
| | | xLabels2.value.push(devObj.recDatetime); |
| | | chartData['dev'].shift(); |
| | | chartData['dev'].push(devObj); |
| | | updateChart2(); |
| | | |
| | | // 蓄电池信息 |
| | | battInfo.value = props.data.sticRtdata; |
| | | } |
| | | |
| | | const configVisible = ref(false); |
| | | const formRef = ref(); |
| | | const form1 = reactive({ |
| | | time: 5, |
| | | count: 100, |
| | | }); |
| | | |
| | | function validatorTime(rule, value, callback) { |
| | | if(/^\d+$/.test(value)) { |
| | | if(value<1 || value>30) { |
| | | callback(new Error('范围1~30')); |
| | | } else { |
| | | callback(); |
| | | } |
| | | }else { |
| | | callback(new Error('请输入整数')); |
| | | } |
| | | } |
| | | |
| | | function validatorCount(rule, value, callback) { |
| | | if(/^\d+$/.test(value)) { |
| | | if (value<50 || value>200) { |
| | | callback(new Error('范围50~200')); |
| | | } else { |
| | | callback(); |
| | | } |
| | | }else { |
| | | callback(new Error('请输入整数')); |
| | | } |
| | | } |
| | | |
| | | const rules = { |
| | | time: [{ required: true, message: '请输入时间', trigger: ['blur', 'change'] }, |
| | | { validator: validatorTime, trigger: ['blur', 'change'] }, |
| | | ], |
| | | count: [{ required: true, message: '请输入条数', trigger: ['blur', 'change'] }, |
| | | { validator: validatorCount, trigger: ['blur', 'change'] }, |
| | | ], |
| | | }; |
| | | |
| | | // 取前半小时数据 更新图表 |
| | | |
| | | // 更新图表 1 2 3 |
| | | function updateChart0() { |
| | | if (chart0.value) { |
| | | chart0.value.updateChart(labels_0[tabIdx0.value], chartData['acin']); |
| | | } |
| | | } |
| | | |
| | | function updateChart1() { |
| | | if (chart1.value) { |
| | | chart1.value.updateChart(xLabels1.value, chartData1.value); |
| | | } |
| | | } |
| | | |
| | | function updateChart2() { |
| | | if (chart2.value) { |
| | | chart2.value.updateChart(xLabels2.value, chartData['dev']); |
| | | } |
| | | } |
| | | |
| | | function scrollHandler(data) { |
| | | console.log('data', data, '============='); |
| | | |
| | | startIdx.value += data * 1; |
| | | nextTick(() => { |
| | | // updateChart1(); |
| | | }) |
| | | } |
| | | |
| | | const hrParamTitle = ref('核容测试'); |
| | | const hrParamVisible = ref(false); |
| | | function startHrTest() { |
| | | hrParamVisible.value = true; |
| | | } |
| | | |
| | | const config = ref({}); |
| | | |
| | | async function getHeartParam() { |
| | | let res = await getPwrHeartParam(props.powerId); |
| | | let { code, data, data2 } = res.data; |
| | | let cfg = {}; |
| | | if (code && data) { |
| | | cfg = data2; |
| | | } |
| | | config.value = cfg; |
| | | } |
| | | |
| | | const configTitle = ref(''); |
| | | function setConfig(type) { |
| | | switch(type) { |
| | | case 0: |
| | | configTitle.value = '设置交流输入采集参数'; |
| | | form1.time = config.value.acinInterverCfg || 5; |
| | | form1.count = config.value.acinCountCfg || 100; |
| | | break; |
| | | case 1: |
| | | configTitle.value = '设置直流输出采集参数'; |
| | | form1.time = config.value.acoutInterverCfg || 5; |
| | | form1.count = config.value.acoutCountCfg || 100; |
| | | break; |
| | | case 2: |
| | | configTitle.value = '设置核容设备采集参数'; |
| | | form1.time = config.value.hrInterverCfg || 5; |
| | | form1.count = config.value.hrCountCfg || 100; |
| | | break; |
| | | } |
| | | configVisible.value = true; |
| | | } |
| | | |
| | | function updateConfig() { |
| | | configVisible.value = false; |
| | | } |
| | | |
| | | onMounted(async () => { |
| | | |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | |
| | | </div> |
| | | </div> |
| | | <div class="p-main"> |
| | | <svg-diagram class="svg-diagram"></svg-diagram> |
| | | <svg-diagram :data="devRt" :battRt="battRt" class="svg-diagram"></svg-diagram> |
| | | </div> |
| | | <div class="p-right"> |
| | | <div class="control-contain"> |
| | | <div class="control-title"><svg-icon icon-class="controls"></svg-icon><span>控制管理</span></div> |
| | | <div class="control-btn">核容测试</div> |
| | | <div class="control-btn">停止核容测试</div> |
| | | <div class="control-title"> |
| | | <svg-icon icon-class="controls"></svg-icon><span>控制管理</span> |
| | | </div> |
| | | <div class="control-btn" @click="startHrTest">核容测试</div> |
| | | <div class="control-btn" @click="stopHrTest">停止核容测试</div> |
| | | </div> |
| | | <div class="control-contain"> |
| | | <div class="control-title"><svg-icon icon-class="dev"></svg-icon><span>设备管理</span></div> |
| | | <div class="control-btn">远程重启</div> |
| | | <div class="control-title"> |
| | | <svg-icon icon-class="dev"></svg-icon><span>设备管理</span> |
| | | </div> |
| | | <div class="control-btn" @click="remoteRestart">远程重启</div> |
| | | <div class="control-btn">系统参数设置</div> |
| | | <div class="control-btn">告警参数设置</div> |
| | | <div class="control-btn" @click="showDevAlarmParam">告警参数设置</div> |
| | | </div> |
| | | <div class="control-contain no-wrap"> |
| | | <div class="control-btn">放电申请</div> |
| | |
| | | <el-radio-button label="电流" :value="0" /> |
| | | <el-radio-button label="电压" :value="1" /> |
| | | </el-radio-group> |
| | | <svg-icon class-name="btn-setting" icon-class="setting"></svg-icon> |
| | | <svg-icon class-name="btn-setting" icon-class="setting" @click="setConfig(0)"></svg-icon> |
| | | </template> |
| | | <line-chart></line-chart> |
| | | <line-chart ref="chart0"></line-chart> |
| | | </card> |
| | | </div> |
| | | <div class="card-item"> |
| | | <card title="直流输入"> |
| | | <card title="直流输出"> |
| | | <template #tools> |
| | | <el-radio-group class="tab-idx" v-model="tabIdx1" size="small"> |
| | | <el-radio-button label="电流" :value="0" /> |
| | | <el-radio-button label="电压" :value="1" /> |
| | | </el-radio-group> |
| | | <svg-icon class-name="btn-setting" icon-class="setting"></svg-icon> |
| | | <svg-icon class-name="btn-setting" icon-class="setting" @click="setConfig(1)"></svg-icon> |
| | | </template> |
| | | <line-chart3 |
| | | ref="chart1" |
| | | :type="['电流', '电压'][tabIdx1]" |
| | | :yLabels="yLabels" |
| | | :start-idx="startIdx" |
| | | :mode-count="modelCfg.length" |
| | | @scroll="scrollHandler" |
| | | ></line-chart3> |
| | | </card> |
| | | </div> |
| | | <div class="card-item"> |
| | | <card title="核容设备信息"> |
| | | <template #tools> |
| | | <svg-icon class-name="btn-setting" icon-class="setting"></svg-icon> |
| | | <svg-icon class-name="btn-setting" icon-class="setting" @click="setConfig(2)"></svg-icon> |
| | | </template> |
| | | <line-chart2 ref="chart2"></line-chart2> |
| | | </card> |
| | | </div> |
| | | <div class="card-item"> |
| | | <card title="蓄电池信息"> |
| | | <div class="batt grid"> |
| | | <info |
| | | label="最大容量" |
| | | value="#3 8Ah" |
| | | ></info> |
| | | <info |
| | | label="最小容量" |
| | | value="100" |
| | | ></info> |
| | | <info |
| | | label="最高内阻" |
| | | value="100" |
| | | ></info> |
| | | <info |
| | | label="最低内阻" |
| | | value="100" |
| | | ></info> |
| | | <info |
| | | label="最高电压" |
| | | value="100" |
| | | ></info> |
| | | <info |
| | | label="最低电压" |
| | | value="100" |
| | | ></info> |
| | | <info |
| | | label="最高温度" |
| | | value="100" |
| | | ></info> |
| | | <info |
| | | label="最低温度" |
| | | value="100" |
| | | ></info> |
| | | <info label="最大容量"> |
| | | <template |
| | | #value |
| | | v-if="battInfo.maxCapNumList && battInfo.maxCapNumList.length" |
| | | > |
| | | <span class="mon-num">#{{ battInfo.maxCapNumList[0] }}</span> |
| | | <span class="val">{{ battInfo.maxCap }}Ah</span> |
| | | </template> |
| | | </info> |
| | | <info label="最小容量"> |
| | | <template |
| | | #value |
| | | v-if="battInfo.minCapNumList && battInfo.minCapNumList.length" |
| | | > |
| | | <span class="mon-num">#{{ battInfo.minCapNumList[0] }}</span> |
| | | <span class="val">{{ battInfo.minCap }}Ah</span> |
| | | </template> |
| | | </info> |
| | | <info label="最高内阻"> |
| | | <template |
| | | #value |
| | | v-if="battInfo.maxResNumList && battInfo.maxResNumList.length" |
| | | > |
| | | <span class="mon-num">#{{ battInfo.maxResNumList[0] }}</span> |
| | | <span class="val">{{ battInfo.maxRes }}mΩ</span> |
| | | </template> |
| | | </info> |
| | | <info label="最低内阻"> |
| | | <template |
| | | #value |
| | | v-if="battInfo.minResNumList && battInfo.minResNumList.length" |
| | | > |
| | | <span class="mon-num">#{{ battInfo.minResNumList[0] }}</span> |
| | | <span class="val">{{ battInfo.minRes }}mΩ</span> |
| | | </template> |
| | | </info> |
| | | <info label="最高电压"> |
| | | <template |
| | | #value |
| | | v-if="battInfo.maxVolNumList && battInfo.maxVolNumList.length" |
| | | > |
| | | <span class="mon-num">#{{ battInfo.maxVolNumList[0] }}</span> |
| | | <span class="val">{{ battInfo.maxVol }}V</span> |
| | | </template> |
| | | </info> |
| | | <info label="最低电压"> |
| | | <template |
| | | #value |
| | | v-if="battInfo.minVolNumList && battInfo.minVolNumList.length" |
| | | > |
| | | <span class="mon-num">#{{ battInfo.minVolNumList[0] }}</span> |
| | | <span class="val">{{ battInfo.minVol }}V</span> |
| | | </template> |
| | | </info> |
| | | <info label="最高温度"> |
| | | <template |
| | | #value |
| | | v-if="battInfo.maxTmpNumList && battInfo.maxTmpNumList.length" |
| | | > |
| | | <span class="mon-num">#{{ battInfo.maxTmpNumList[0] }}</span> |
| | | <span class="val">{{ battInfo.maxTmp }}℃</span> |
| | | </template> |
| | | </info> |
| | | <info label="最低温度"> |
| | | <template |
| | | #value |
| | | v-if="battInfo.minTmpNumList && battInfo.minTmpNumList.length" |
| | | > |
| | | <span class="mon-num">#{{ battInfo.minTmpNumList[0] }}</span> |
| | | <span class="val">{{ battInfo.minTmp }}℃</span> |
| | | </template> |
| | | </info> |
| | | </div> |
| | | </card> |
| | | </div> |
| | | </div> |
| | | <!-- 设置间隔参数 --> |
| | | <el-dialog v-model="configVisible" draggable :title="configTitle" width="560"> |
| | | <el-form ref="formRef" :model="form1" :rules="rules" label-width="10em"> |
| | | <el-form-item label="间隔时间(分)" prop="time"> |
| | | <el-input v-model="form1.time"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="数据笔数" prop="count"> |
| | | <el-input v-model="form1.count"></el-input> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <el-button @click="configVisible = false">关闭</el-button> |
| | | <!-- <el-button type="primary" @click="getConfig">读取</el-button> --> |
| | | <el-button type="primary" @click="updateConfig">设定</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | <!-- 设置核容参数 --> |
| | | <el-dialog v-model="hrParamVisible" draggable :title="hrParamTitle" width="960"> |
| | | <hr-params :devId="devId" v-model:visible="hrParamVisible" :battgroupId="battgroupId"></hr-params> |
| | | </el-dialog> |
| | | <!-- 设置设备告警参数 --> |
| | | <el-dialog v-model="devAlmVisible" draggable title="设备告警参数" width="960"> |
| | | <dev-alarm-params :devId="devId" v-model:visible="devAlmVisible"></dev-alarm-params> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | padding-right: 8px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | |
| | | .row { |
| | | flex: 1.52; |
| | | |
| | | .row-content { |
| | | display: flex; |
| | | flex-direction: row; |
| | | height: 100%; |
| | | } |
| | | |
| | | .p-left { |
| | | width: 240px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | |
| | | .p-item { |
| | | margin: 8px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | |
| | | .panel-title { |
| | | font-size: 24px; |
| | | } |
| | | |
| | | .panel { |
| | | border: 1px solid #5FA9CF; |
| | | background: #073451; |
| | |
| | | font-size: 12px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | |
| | | .panel-row { |
| | | display: flex; |
| | | flex-direction: row; |
| | | margin-bottom: 4px; |
| | | |
| | | .label { |
| | | flex: 0 0 6em; |
| | | margin-right: 0.6em; |
| | | text-align: right; |
| | | |
| | | &::after { |
| | | content: ":"; |
| | | } |
| | | } |
| | | |
| | | .value { |
| | | flex: 1; |
| | | } |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | .p-main { |
| | | flex: 1; |
| | | } |
| | | |
| | | .p-right { |
| | | width: 160px; |
| | | margin-left: 20px; |
| | |
| | | padding-top: 20px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | |
| | | .control-contain { |
| | | display: flex; |
| | | flex-direction: column; |
| | |
| | | padding-bottom: 4px; |
| | | overflow: hidden; |
| | | font-size: 12px; |
| | | |
| | | .control-title { |
| | | background: #0B415D; |
| | | font-size: 20px; |
| | |
| | | text-align: center; |
| | | font-weight: 700; |
| | | margin-bottom: 4px; |
| | | |
| | | span { |
| | | margin-left: 0.6em; |
| | | } |
| | | } |
| | | |
| | | .control-btn { |
| | | margin: 2px 4px; |
| | | cursor: pointer; |
| | |
| | | padding: 6px 0; |
| | | text-align: center; |
| | | border-radius: 4px; |
| | | |
| | | &:hover { |
| | | color: #FDFE01; |
| | | border: 1px solid #DF7B26; |
| | | box-shadow: inset 0 0 10px 4px #DF7B26; |
| | | } |
| | | } |
| | | |
| | | &.no-wrap { |
| | | background: transparent; |
| | | |
| | | .control-btn { |
| | | flex: 1; |
| | | border: 1px solid #0BF9FE; |
| | |
| | | font-weight: bold; |
| | | font-size: 14px; |
| | | box-shadow: inset 0 0 10px 4px #0BF9FE; |
| | | |
| | | &:hover { |
| | | color: #FDFE01; |
| | | border: 1px solid #DF7B26; |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | &.row2 { |
| | | flex: 1; |
| | | margin-top: 4px; |
| | | display: flex; |
| | | flex-direction: row; |
| | | |
| | | .card-item { |
| | | flex: 1; |
| | | margin: 4px; |
| | | } |
| | | } |
| | | } |
| | | .svg-diagram { |
| | | |
| | | } |
| | | |
| | | .svg-diagram {} |
| | | |
| | | .btn-setting { |
| | | display: inline-block; |
| | | cursor: pointer; |
| | | margin-left: 0.4em; |
| | | transition: all 1.3s ease; |
| | | |
| | | &:hover { |
| | | transform: rotate(360deg); |
| | | color: #FDFE01; |
| | |
| | | border-radius: 0; |
| | | box-shadow: none !important; |
| | | } |
| | | |
| | | // .el-radio-button--small .el-radio-button__inner { |
| | | // border-radius: 0; |
| | | // font-size: 12px; |
| | | // padding: 5px 11px; |
| | | // } |
| | | :deep(.el-radio-button__inner) { |
| | | background: #183A55; |
| | | border: 1px solid #4D81BA; |
| | | border-left: 0; |
| | | border-radius: 0; |
| | | color: #fff; |
| | | font-weight: 500; |
| | | padding: 4px 10px; |
| | | background: #183A55; |
| | | border: 1px solid #4D81BA; |
| | | border-left: 0; |
| | | border-radius: 0; |
| | | color: #fff; |
| | | font-weight: 500; |
| | | padding: 4px 10px; |
| | | } |
| | | |
| | | :deep(.el-radio-button.is-active .el-radio-button__original-radio:not(:disabled)+.el-radio-button__inner) { |
| | | background: linear-gradient(69deg, #6EABE4, #6EABE4 25%, #0A3E77 75%, #0A3E77); |
| | | // border: 0 none; |
| | | box-shadow: none; |
| | | color: #fff; |
| | | background: linear-gradient(69deg, #6EABE4, #6EABE4 25%, #0A3E77 75%, #0A3E77); |
| | | // border: 0 none; |
| | | box-shadow: none; |
| | | color: #fff; |
| | | } |
| | | } |
| | | |
| | | .page-filter { |
| | | display: flex; |
| | | flex-direction: row; |
| | | align-items: center; |
| | | margin-right: 6px; |
| | | margin-top: 0; |
| | | margin-bottom: 0; |
| | | padding: 0; |
| | | background: transparent; |
| | | border: 0 none; |
| | | |
| | | .label { |
| | | font-size: 12px; |
| | | margin-right: 6px; |
| | | |
| | | &::after { |
| | | content: ":"; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .mon-num { |
| | | margin-right: 1em; |
| | | } |
| | | } |
| | | </style> |
| | | </style> |