sk_fems_ui commit
This commit is contained in:
77
components/widget/BlankWidget.vue
Normal file
77
components/widget/BlankWidget.vue
Normal file
@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<div class="l-layout">
|
||||
<v-row ref="rowParent">
|
||||
<v-col :cols="12">
|
||||
<v-card class="pa-5" style="min-height: 284px;"> </v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions, mapMutations, mapState } from 'vuex'; // , mapActions
|
||||
import Vue from 'vue';
|
||||
import DateUtility from '~/plugins/dateUtility';
|
||||
import Utility from '~/plugins/utility';
|
||||
import Grid from '~/components/common/Grid';
|
||||
import Chart from '~/components/common/Chart';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
parentPrgmId: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
DateUtility,
|
||||
Grid,
|
||||
Chart,
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
searchParam(state) {
|
||||
return state.pageData[this.parentPrgmId];
|
||||
},
|
||||
isDarkMode: 'isDarkMode',
|
||||
}),
|
||||
},
|
||||
watch: {},
|
||||
beforeCreate() {
|
||||
this.$store.commit('setWidgetPageData', {
|
||||
prgmId: this.$route.query.prgmId,
|
||||
blankWidget: { blankWidgetData },
|
||||
});
|
||||
// console.log("2.vue::beforeCreate");
|
||||
},
|
||||
created() {},
|
||||
mounted() {},
|
||||
data() {
|
||||
return {
|
||||
pop: null,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
...mapMutations({
|
||||
setPageData: 'setPageData',
|
||||
setWidgetChartOption: 'setWidgetChartOption',
|
||||
}),
|
||||
...mapActions({
|
||||
postApi: 'modules/list/postApi',
|
||||
postApiReturn: 'modules/list/postApiReturn',
|
||||
}),
|
||||
},
|
||||
};
|
||||
const blankWidgetData = {};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.v-avatar {
|
||||
border-radius: 21px;
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
.v-virtual-scroll-wrapper {
|
||||
overflow-y: auto;
|
||||
max-height: 210px;
|
||||
}
|
||||
</style>
|
343
components/widget/CaldWidget.vue
Normal file
343
components/widget/CaldWidget.vue
Normal file
@ -0,0 +1,343 @@
|
||||
<template>
|
||||
<div class="l-layout">
|
||||
<v-row ref="rowParent">
|
||||
<v-col :cols="12">
|
||||
<v-card class="pa-3 widget-card">
|
||||
<div class="d-flex align-center justify-space-between">
|
||||
<v-card-title class="pa-0"
|
||||
>캘린더
|
||||
<span class="pl-2"
|
||||
>{{ selectedYear }}년 {{ selectedMonth }}월</span
|
||||
></v-card-title
|
||||
>
|
||||
<v-card-subtitle class="mt-0 pa-0">
|
||||
<v-icon
|
||||
v-show="widgetPrgmId"
|
||||
class="mr-1"
|
||||
size="25"
|
||||
@click="btnAction('widgetCallPage')"
|
||||
>mdi-note-search</v-icon
|
||||
>
|
||||
<v-icon
|
||||
v-show="widgetPopFg"
|
||||
size="25"
|
||||
@click="btnAction('popWidget')"
|
||||
>mdi-plus-box-multiple</v-icon
|
||||
>
|
||||
</v-card-subtitle>
|
||||
</div>
|
||||
<div class="d-flex align-center justify-space-between mt-2">
|
||||
<div class="weekday redDay">일</div>
|
||||
<div class="weekday">월</div>
|
||||
<div class="weekday">화</div>
|
||||
<div class="weekday">수</div>
|
||||
<div class="weekday">목</div>
|
||||
<div class="weekday">금</div>
|
||||
<div class="weekday blueDay">토</div>
|
||||
</div>
|
||||
<div class="d-flex align-center justify-space-between">
|
||||
<div class="weekdayForm redDay"><span id="day0"></span></div>
|
||||
<div class="weekdayForm"><span id="day1"></span></div>
|
||||
<div class="weekdayForm"><span id="day2"></span></div>
|
||||
<div class="weekdayForm"><span id="day3"></span></div>
|
||||
<div class="weekdayForm"><span id="day4"></span></div>
|
||||
<div class="weekdayForm"><span id="day5"></span></div>
|
||||
<div class="weekdayForm blueDay"><span id="day6"></span></div>
|
||||
</div>
|
||||
<div class="d-flex align-center justify-space-between">
|
||||
<div class="weekdayForm redDay"><span id="day7"></span></div>
|
||||
<div class="weekdayForm"><span id="day8"></span></div>
|
||||
<div class="weekdayForm"><span id="day9"></span></div>
|
||||
<div class="weekdayForm"><span id="day10"></span></div>
|
||||
<div class="weekdayForm"><span id="day11"></span></div>
|
||||
<div class="weekdayForm"><span id="day12"></span></div>
|
||||
<div class="weekdayForm blueDay"><span id="day13"></span></div>
|
||||
</div>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions, mapMutations, mapState } from 'vuex'; // , mapActions
|
||||
import Vue from 'vue';
|
||||
import DateUtility from '~/plugins/dateUtility';
|
||||
import Utility from '~/plugins/utility';
|
||||
import Grid from '~/components/common/Grid';
|
||||
import Chart from '~/components/common/Chart';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
parentPrgmId: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
widgetId: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
widgetPrgmId: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
widgetPopFg: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
widgetReflashMm: {
|
||||
type: Number,
|
||||
require: true,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
DateUtility,
|
||||
Grid,
|
||||
Chart,
|
||||
Utility,
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
searchParam(state) {
|
||||
return state.pageData[this.parentPrgmId];
|
||||
},
|
||||
isDarkMode: 'isDarkMode',
|
||||
}),
|
||||
},
|
||||
watch: {},
|
||||
beforeMounted() {},
|
||||
beforeCreate() {
|
||||
this.$store.commit('setWidgetPageData', {
|
||||
prgmId: this.$route.query.prgmId,
|
||||
caldWidget: { caldWidgetData },
|
||||
});
|
||||
},
|
||||
created() {
|
||||
this.search();
|
||||
this.timer = setInterval(this.search, this.widgetReflashMm);
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.clearTimeout(this.timer);
|
||||
},
|
||||
mounted() {},
|
||||
data() {
|
||||
return {
|
||||
pop: null,
|
||||
selectedYear: this.convertStringToDateFormat(new Date()).substr(0, 4),
|
||||
selectedMonth: this.convertStringToDateFormat(new Date()).substr(5, 2),
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
...mapMutations({
|
||||
setPageData: 'setPageData',
|
||||
setWidgetChartOption: 'setWidgetChartOption',
|
||||
openDashboardWidget: 'openDashboardWidget',
|
||||
}),
|
||||
...mapActions({
|
||||
postApi: 'modules/list/postApi',
|
||||
postApiReturn: 'modules/list/postApiReturn',
|
||||
}),
|
||||
convertStringToDateFormat(val) {
|
||||
var result = '';
|
||||
|
||||
result = Utility.setFormatDate(val, 'YYYY-MM-DD');
|
||||
|
||||
return result;
|
||||
},
|
||||
btnAction(action) {
|
||||
switch (action) {
|
||||
case 'popWidget':
|
||||
this.openDashboardWidget({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetId: this.widgetId,
|
||||
});
|
||||
break;
|
||||
case 'widgetCallPage':
|
||||
this.$parent.$parent.$parent.openWidgetPrgm(this.widgetId);
|
||||
break;
|
||||
}
|
||||
},
|
||||
async search() {
|
||||
const res = await this.postApiReturn({
|
||||
apiKey: 'selectWeekWorkCald',
|
||||
resKey: 'workcaldData',
|
||||
sendParam: {},
|
||||
});
|
||||
|
||||
const res2 = await this.postApiReturn({
|
||||
apiKey: 'selectWeekWorkCaldDetl',
|
||||
resKey: 'workcaldData',
|
||||
sendParam: {},
|
||||
});
|
||||
for (var i = 0; i < res.length; i++) {
|
||||
var hldyNm = res[i].hldyNm == null ? '' : res[i].hldyNm;
|
||||
eval(
|
||||
"document.getElementById('day" +
|
||||
i +
|
||||
"').innerHTML = res[" +
|
||||
i +
|
||||
"].day + ' ' +hldyNm",
|
||||
);
|
||||
if (res[i].hldyFg == '1') {
|
||||
eval(
|
||||
"document.getElementById('day" + i + "').className += ' redDay'",
|
||||
);
|
||||
}
|
||||
for (var j = 0; j < res2.length; j++) {
|
||||
if (res[i].day == res2[j].day && res2[j].planTitle != null) {
|
||||
var tmpHtml =
|
||||
"<p class ='" +
|
||||
res2[j].planColor +
|
||||
"Plan'>" +
|
||||
res2[j].planTitle +
|
||||
'</p>';
|
||||
if (i == 0) {
|
||||
document.getElementById('day0').innerHTML += tmpHtml;
|
||||
} else if (i == 1) {
|
||||
document.getElementById('day1').innerHTML += tmpHtml;
|
||||
} else if (i == 2) {
|
||||
document.getElementById('day2').innerHTML += tmpHtml;
|
||||
} else if (i == 3) {
|
||||
document.getElementById('day3').innerHTML += tmpHtml;
|
||||
} else if (i == 4) {
|
||||
document.getElementById('day4').innerHTML += tmpHtml;
|
||||
} else if (i == 5) {
|
||||
document.getElementById('day5').innerHTML += tmpHtml;
|
||||
} else if (i == 6) {
|
||||
document.getElementById('day6').innerHTML += tmpHtml;
|
||||
} else if (i == 7) {
|
||||
document.getElementById('day7').innerHTML += tmpHtml;
|
||||
} else if (i == 8) {
|
||||
document.getElementById('day8').innerHTML += tmpHtml;
|
||||
} else if (i == 9) {
|
||||
document.getElementById('day9').innerHTML += tmpHtml;
|
||||
} else if (i == 10) {
|
||||
document.getElementById('day10').innerHTML += tmpHtml;
|
||||
} else if (i == 11) {
|
||||
document.getElementById('day11').innerHTML += tmpHtml;
|
||||
} else if (i == 12) {
|
||||
document.getElementById('day12').innerHTML += tmpHtml;
|
||||
} else if (i == 13) {
|
||||
document.getElementById('day13').innerHTML += tmpHtml;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
const caldWidgetData = {};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.v-avatar {
|
||||
border-radius: 21px;
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
.v-virtual-scroll-wrapper {
|
||||
overflow-y: auto;
|
||||
max-height: 210px;
|
||||
}
|
||||
.weekday {
|
||||
background-color: #383f5d;
|
||||
border-right: 1px solid rgba(255, 255, 255, 0.1);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 26px;
|
||||
width: 15%;
|
||||
padding: 0;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.weekdayForm {
|
||||
border-right: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||
height: 7.6vh;
|
||||
min-height: 80px;
|
||||
box-sizing: border-box;
|
||||
width: 15%;
|
||||
overflow-y: auto;
|
||||
font-size: 14px;
|
||||
// padding-left: 3px;
|
||||
// padding-right: 6px;
|
||||
padding: 3px 4px;
|
||||
}
|
||||
.redDay {
|
||||
color: #fb5a83;
|
||||
border-left: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.blueDay {
|
||||
color: #2d8cf6;
|
||||
}
|
||||
|
||||
.redPlan {
|
||||
//background-color: rgba(229,62,62,var(--bg-opacity));
|
||||
background-color: #e53e3e !important;
|
||||
color: #fff;
|
||||
border-radius: 0.125rem;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.25;
|
||||
text-align: left;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
.bluePlan {
|
||||
//background-color: rgba(66,153,225,var(--bg-opacity));
|
||||
background-color: #4299e1 !important;
|
||||
color: #fff;
|
||||
border-radius: 0.125rem;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.25;
|
||||
text-align: left;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
.puplePlan {
|
||||
//background-color: rgba(102,126,234,var(--bg-opacity));
|
||||
background-color: #667eea !important;
|
||||
color: #fff;
|
||||
border-radius: 0.125rem;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.25;
|
||||
text-align: left;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
.greenPlan {
|
||||
//background-color: rgba(56,178,172,var(--bg-opacity));
|
||||
background-color: #38b2ac !important;
|
||||
color: #fff;
|
||||
border-radius: 0.125rem;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.25;
|
||||
text-align: left;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
.orangePlan {
|
||||
//background-color: rgba(237,137,54,var(--bg-opacity));
|
||||
background-color: #ed8936 !important;
|
||||
color: #fff;
|
||||
border-radius: 0.125rem;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.25;
|
||||
text-align: left;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
.pinkPlan {
|
||||
//background-color: rgba(237,100,166,var(--bg-opacity));
|
||||
background-color: #ed64a6 !important;
|
||||
color: #fff;
|
||||
border-radius: 0.125rem;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.25;
|
||||
text-align: left;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
.greyPlan {
|
||||
background-color: #6d6d6d;
|
||||
color: #fff;
|
||||
border-radius: 0.125rem;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.25;
|
||||
text-align: left;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
</style>
|
359
components/widget/ChartWidget.vue
Normal file
359
components/widget/ChartWidget.vue
Normal file
@ -0,0 +1,359 @@
|
||||
<template>
|
||||
<div class="l-layout">
|
||||
<v-row ref="rowParent">
|
||||
<v-col :cols="12">
|
||||
<v-card class="pa-3 widget-card">
|
||||
<div class="d-flex align-center justify-space-between">
|
||||
<v-card-title class="pa-0">전력피크</v-card-title>
|
||||
<v-btn :ripple="false" @click="btnAction('popWidget')">화면</v-btn>
|
||||
<v-card-subtitle class="mt-0 pa-0">
|
||||
{{ blocNm }} {{ dtToday }} 기준</v-card-subtitle
|
||||
>
|
||||
</div>
|
||||
<div class="d-flex align-center justify-space-between mt-8">
|
||||
<div class="mr-5" :style="{ width: '240px', height: '170px' }">
|
||||
<component
|
||||
class="w100 h100"
|
||||
:is="loadChart_01 ? 'Chart' : null"
|
||||
:parentPrgmId="parentPrgmId"
|
||||
:widgetId="'peakWidget'"
|
||||
:widgetData="'peakWidgetData'"
|
||||
:chartName="chart_01"
|
||||
ref="chart_01"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div class="v-box">
|
||||
<v-icon size="48" :color="isDarkMode ? '#22273c' : '#4a568d'"
|
||||
>$darkDashCharge</v-icon
|
||||
>
|
||||
<div class="text-right">
|
||||
<strong class="custom-title-2"
|
||||
>{{ chargedPower }} <span class="body-2">kW</span></strong
|
||||
>
|
||||
<p class="body-2 mt-1 mb-0 text-color--non-activate">
|
||||
요금 적용전력
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="v-box">
|
||||
<v-icon size="48" :color="isDarkMode ? '#22273c' : '#4a568d'"
|
||||
>$darkDashPeak</v-icon
|
||||
>
|
||||
<div class="text-right">
|
||||
<strong class="custom-title-2"
|
||||
>{{ nowPeakVal }} <span class="body-2">kW</span></strong
|
||||
>
|
||||
<p class="body-2 mt-1 mb-0 text-color--non-activate">
|
||||
현재 피크전력
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="v-box">
|
||||
<v-icon size="48" :color="isDarkMode ? '#22273c' : '#4a568d'"
|
||||
>$darkDashCharge</v-icon
|
||||
>
|
||||
<div class="text-right">
|
||||
<strong class="custom-title-2"
|
||||
>{{ chargedPower }} <span class="body-2">kW</span></strong
|
||||
>
|
||||
<p class="body-2 mt-1 mb-0 text-color--non-activate">
|
||||
요금 적용전력
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="v-box">
|
||||
<v-icon size="48" :color="isDarkMode ? '#22273c' : '#4a568d'"
|
||||
>$darkDashPeak</v-icon
|
||||
>
|
||||
<div class="text-right">
|
||||
<strong class="custom-title-2"
|
||||
>{{ nowPeakVal }} <span class="body-2">kW</span></strong
|
||||
>
|
||||
<p class="body-2 mt-1 mb-0 text-color--non-activate">
|
||||
현재 피크전력
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions, mapMutations, mapState } from 'vuex'; // , mapActions
|
||||
import Vue from 'vue';
|
||||
import DateUtility from '~/plugins/dateUtility';
|
||||
import Utility from '~/plugins/utility';
|
||||
import Grid from '~/components/common/Grid';
|
||||
import Chart from '~/components/common/Chart';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
parentPrgmId: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
DateUtility,
|
||||
Grid,
|
||||
Chart,
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
searchParam(state) {
|
||||
return state.pageData[this.parentPrgmId];
|
||||
},
|
||||
isDarkMode: 'isDarkMode',
|
||||
}),
|
||||
},
|
||||
watch: {},
|
||||
beforeCreate() {
|
||||
this.$store.commit('setWidgetPageData', {
|
||||
prgmId: this.$route.query.prgmId,
|
||||
peakWidget: { peakWidgetData },
|
||||
});
|
||||
// console.log("2.vue::beforeCreate");
|
||||
},
|
||||
created() {
|
||||
this.search();
|
||||
},
|
||||
mounted() {},
|
||||
data() {
|
||||
return {
|
||||
dtToday: Utility.setFormatDate(new Date(), 'YYYY-MM-DD HH:mm'),
|
||||
dtYr: '1/1~' + Utility.setFormatDate(new Date(), 'M/D'),
|
||||
dtBf:
|
||||
DateUtility.addMonth(-1, 'M', new Date()) +
|
||||
'/1~' +
|
||||
DateUtility.addMonth(-1, 'M/D', new Date()),
|
||||
dtMm:
|
||||
Utility.setFormatDate(new Date(), 'M') +
|
||||
'/1~' +
|
||||
Utility.setFormatDate(new Date(), 'M/D'),
|
||||
currHour: '0시-' + Utility.setFormatDate(new Date(), 'H') + '시',
|
||||
blocNm: '',
|
||||
//차트
|
||||
chart_01: 'peakGauge',
|
||||
loadChart_01: false,
|
||||
//바인딩
|
||||
chargedPower: 0,
|
||||
nowPeakVal: 0,
|
||||
rdbEnrgUsage: 'hour',
|
||||
rdbElecQual: 'Kw',
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
...mapMutations({
|
||||
setPageData: 'setPageData',
|
||||
setWidgetChartOption: 'setWidgetChartOption',
|
||||
openDashboardWidget: 'openDashboardWidget',
|
||||
}),
|
||||
...mapActions({
|
||||
postApi: 'modules/list/postApi',
|
||||
postApiReturn: 'modules/list/postApiReturn',
|
||||
}),
|
||||
setBlocNm() {
|
||||
this.blocNm = this.$store.state.userInfo.blocNm;
|
||||
if (this.blocNm != '') {
|
||||
this.blocNm = '[' + this.blocNm + ']';
|
||||
}
|
||||
},
|
||||
async search() {
|
||||
this.setBlocNm();
|
||||
|
||||
this.dtToday = Utility.setFormatDate(new Date(), 'YYYY-MM-DD HH:mm');
|
||||
this.dtYr = '1/1~' + Utility.setFormatDate(new Date(), 'M/D');
|
||||
this.dtBf =
|
||||
DateUtility.addMonth(-1, 'M', new Date()) +
|
||||
'/1~' +
|
||||
DateUtility.addMonth(-1, 'M/D', new Date());
|
||||
this.dtMm =
|
||||
Utility.setFormatDate(new Date(), 'M') +
|
||||
'/1~' +
|
||||
Utility.setFormatDate(new Date(), 'M/D');
|
||||
this.currHour = '0시-' + Utility.setFormatDate(new Date(), 'H') + '시';
|
||||
|
||||
await this.getUseWithPeak();
|
||||
},
|
||||
async getUseWithPeak() {
|
||||
this.loadChart_01 = false;
|
||||
const res = await this.postApiReturn({
|
||||
apiKey: 'selectUseWithPeak',
|
||||
resKey: 'peakData',
|
||||
sendParam: {},
|
||||
});
|
||||
|
||||
res.forEach((item, idx) => {
|
||||
this.chargedPower = Utility.setFormatInt(item.peakVal);
|
||||
this.nowPeakVal = Utility.setFormatInt(item.curPeakVal);
|
||||
});
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.setChart01Data(res);
|
||||
});
|
||||
},
|
||||
|
||||
//차트Setting
|
||||
async setChart01Data(data) {
|
||||
this.$store.state.pageData[
|
||||
this.parentPrgmId
|
||||
].peakWidget.peakWidgetData.series = [];
|
||||
if (!data.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const arrDarkColors = {
|
||||
정상: '#01ae6a',
|
||||
주의: '#ffb046',
|
||||
위험: '#f6637b',
|
||||
};
|
||||
const arrLightColors = {
|
||||
정상: '#01ae6a',
|
||||
주의: '#ffb046',
|
||||
위험: '#f6637b',
|
||||
};
|
||||
|
||||
const darkGaugeColors = [
|
||||
[0.125, '#009245'],
|
||||
[0.25, '#39b54a'],
|
||||
[0.375, '#d9e021'],
|
||||
[0.5, '#fcee21'],
|
||||
[0.625, '#fbb03b'],
|
||||
[0.75, '#f7931e'],
|
||||
[0.875, '#f15a24'],
|
||||
[1.0, '#ed1c24'],
|
||||
];
|
||||
const lightGaugeColors = [
|
||||
[0.125, '#58c06f'],
|
||||
[0.25, '#7cd574'],
|
||||
[0.375, '#fbe462'],
|
||||
[0.5, '#ffd771'],
|
||||
[0.625, '#ffad7f'],
|
||||
[0.75, '#ff966e'],
|
||||
[0.875, '#ff706e'],
|
||||
[1.0, '#ff6689'],
|
||||
];
|
||||
|
||||
var chartOption = {
|
||||
series: [
|
||||
{
|
||||
type: 'gauge',
|
||||
startAngle: 180,
|
||||
endAngle: 0,
|
||||
min: 0,
|
||||
max: 100,
|
||||
radius: '100%',
|
||||
splitNumber: 8,
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
width: 30,
|
||||
color: this.isDarkMode ? darkGaugeColors : lightGaugeColors,
|
||||
},
|
||||
},
|
||||
splitLine: {
|
||||
show: false,
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
axisLabel: {
|
||||
show: false,
|
||||
},
|
||||
pointer: {
|
||||
length: '80%',
|
||||
width: 5,
|
||||
itemStyle: {
|
||||
color: this.isDarkMode ? '#fff' : '#333333',
|
||||
},
|
||||
},
|
||||
anchor: {
|
||||
show: true,
|
||||
showAbove: true,
|
||||
size: 10,
|
||||
itemStyle: {
|
||||
borderWidth: 10,
|
||||
borderColor: this.isDarkMode ? '#fff' : '#333333',
|
||||
},
|
||||
},
|
||||
title: {
|
||||
offsetCenter: ['90%', '30%'],
|
||||
fontSize: 20,
|
||||
color: this.isDarkMode
|
||||
? arrDarkColors[data[0].peakStat]
|
||||
: arrLightColors[data[0].peakStat],
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
detail: {
|
||||
fontSize: 20,
|
||||
offsetCenter: ['-75%', '30%'],
|
||||
valueAnimation: true,
|
||||
formatter: function(value) {
|
||||
return '{value|' + value.toFixed(2) + '}{unit|%}';
|
||||
},
|
||||
rich: {
|
||||
value: {
|
||||
fontSize: 20,
|
||||
color: this.isDarkMode ? '#fff' : '#111111',
|
||||
fontWeight: 'bolder',
|
||||
},
|
||||
unit: {
|
||||
fontSize: 14,
|
||||
color: this.isDarkMode ? '#fff' : '#111111',
|
||||
fontWeight: 'bolder',
|
||||
padding: [0, 0, -5, 0],
|
||||
},
|
||||
},
|
||||
},
|
||||
data: [
|
||||
{
|
||||
name: data[0].peakStat,
|
||||
value: data[0].peakRto,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
this.setWidgetChartOption({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetKey: 'peakWidget',
|
||||
widgetData: 'peakWidgetData',
|
||||
chartKey: 'peakGauge',
|
||||
value: chartOption,
|
||||
});
|
||||
|
||||
this.loadChart_01 = true;
|
||||
},
|
||||
btnAction(action) {
|
||||
switch (action) {
|
||||
case 'popWidget':
|
||||
this.openDashboardWidget({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetId: 'PeakWidget',
|
||||
});
|
||||
break;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
const peakWidgetData = {
|
||||
peakGauge: Utility.defaultChartOption(true),
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.v-avatar {
|
||||
border-radius: 21px;
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
.v-virtual-scroll-wrapper {
|
||||
overflow-y: auto;
|
||||
max-height: 210px;
|
||||
}
|
||||
</style>
|
351
components/widget/ComcUseReptWidget.vue
Normal file
351
components/widget/ComcUseReptWidget.vue
Normal file
@ -0,0 +1,351 @@
|
||||
<template>
|
||||
<div class="l-layout">
|
||||
<v-row ref="rowParent">
|
||||
<v-col :cols="12">
|
||||
<v-card class="pa-3 widget-card">
|
||||
<div class="d-flex align-center justify-space-between">
|
||||
<v-card-title class="pa-0">통신/사용 현황</v-card-title>
|
||||
<v-card-subtitle class="mt-0 pa-0">
|
||||
<v-icon
|
||||
v-show="widgetPrgmId"
|
||||
class="mr-1"
|
||||
size="25"
|
||||
@click="btnAction('widgetCallPage')"
|
||||
>mdi-note-search</v-icon
|
||||
>
|
||||
<v-icon
|
||||
v-show="widgetPopFg"
|
||||
size="25"
|
||||
@click="btnAction('popWidget')"
|
||||
>mdi-plus-box-multiple</v-icon
|
||||
>
|
||||
</v-card-subtitle>
|
||||
</div>
|
||||
<div class="row pt-2 px-2">
|
||||
<v-col :cols="3">
|
||||
<v-banner>
|
||||
<div class="d-flex align-center justify-space-between">
|
||||
<v-card-subtitle class="pa-0">전체검침개소</v-card-subtitle>
|
||||
<v-avatar
|
||||
size="36"
|
||||
:color="isDarkMode ? '#2fad35' : '#00c875'"
|
||||
min-width="72"
|
||||
class="font-weight-bold text-color--white-0"
|
||||
>{{ pointUse }}</v-avatar
|
||||
>
|
||||
</div>
|
||||
</v-banner>
|
||||
<component
|
||||
:is="'UnusedStatPopPage'"
|
||||
:parentPrgmId="parentPrgmId"
|
||||
:pointNoUse="pointNoUse"
|
||||
/>
|
||||
<component
|
||||
:is="'EtcStatPopPage'"
|
||||
:parentPrgmId="parentPrgmId"
|
||||
:pointEtc="pointEtc"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col :cols="4">
|
||||
<component
|
||||
:ref="gridName01"
|
||||
:is="loadGrid01 ? 'Grid' : null"
|
||||
:gridName="gridName01"
|
||||
:parentPrgmId="parentPrgmId"
|
||||
:dataPath="searchParam.ComcUseReptWidget.ComcUseReptWidgetData"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col :cols="5">
|
||||
<div>
|
||||
<component
|
||||
:ref="gridName02"
|
||||
:is="loadGrid02 ? 'Grid' : null"
|
||||
:gridName="gridName02"
|
||||
:parentPrgmId="parentPrgmId"
|
||||
:dataPath="
|
||||
searchParam.ComcUseReptWidget.ComcUseReptWidgetData
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</v-col>
|
||||
</div>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions, mapMutations, mapState } from 'vuex'; // , mapActions
|
||||
import Vue from 'vue';
|
||||
import DateUtility from '~/plugins/dateUtility';
|
||||
import Utility from '~/plugins/utility';
|
||||
import Grid from '~/components/common/Grid';
|
||||
import UnusedStatPopPage from '~/components/common/modal/UnusedStatPopPage';
|
||||
import EtcStatPopPage from '~/components/common/modal/EtcStatPopPage';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
parentPrgmId: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
widgetId: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
widgetPrgmId: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
widgetPopFg: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
widgetReflashMm: {
|
||||
type: Number,
|
||||
require: true,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
DateUtility,
|
||||
Grid,
|
||||
UnusedStatPopPage,
|
||||
EtcStatPopPage,
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
searchParam(state) {
|
||||
return state.pageData[this.parentPrgmId];
|
||||
},
|
||||
isDarkMode: 'isDarkMode',
|
||||
}),
|
||||
},
|
||||
watch: {},
|
||||
beforeCreate() {
|
||||
this.$store.commit('setWidgetPageData', {
|
||||
prgmId: this.$route.query.prgmId,
|
||||
// defaultData: defaultData,
|
||||
ComcUseReptWidget: { ComcUseReptWidgetData: ComcUseReptWidgetData },
|
||||
});
|
||||
},
|
||||
created() {
|
||||
this.search();
|
||||
this.timer = setInterval(this.search, this.widgetReflashMm);
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.clearTimeout(this.timer);
|
||||
},
|
||||
mounted() {},
|
||||
data() {
|
||||
return {
|
||||
pointUse: 0,
|
||||
pointNoUse: 0,
|
||||
pointEtc: 0,
|
||||
gridName01: 'grid01',
|
||||
gridName02: 'grid02',
|
||||
loadGrid01: false,
|
||||
loadGrid02: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
...mapMutations({
|
||||
setPageData: 'setPageData',
|
||||
setWidgetChartOption: 'setWidgetChartOption',
|
||||
setWidgetGridData: 'setWidgetGridData',
|
||||
setWidgetGridColumn: 'setWidgetGridColumn',
|
||||
setWidgetGridOption: 'setWidgetGridOption',
|
||||
openDashboardWidget: 'openDashboardWidget',
|
||||
}),
|
||||
...mapActions({
|
||||
postApi: 'modules/list/postApi',
|
||||
postApiReturn: 'modules/list/postApiReturn',
|
||||
}),
|
||||
async search() {
|
||||
await this.getReadplcStatus();
|
||||
this.gridInit();
|
||||
},
|
||||
async gridInit() {
|
||||
this.loadGrid01 = false;
|
||||
this.loadGrid02 = false;
|
||||
|
||||
const gridHeight = 180;
|
||||
|
||||
const myOptions = {
|
||||
scrollX: false,
|
||||
};
|
||||
|
||||
var gridOptions = Utility.defaultGridOption(gridHeight);
|
||||
gridOptions.columnOptions.minWidth = 10;
|
||||
gridOptions.columnOptions.maxWidth = 200;
|
||||
|
||||
this.setWidgetGridOption({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetKey: 'ComcUseReptWidget',
|
||||
widgetData: 'ComcUseReptWidgetData',
|
||||
gridKey: this.gridName01,
|
||||
value: gridOptions,
|
||||
});
|
||||
|
||||
this.setWidgetGridOption({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetKey: 'ComcUseReptWidget',
|
||||
widgetData: 'ComcUseReptWidgetData',
|
||||
gridKey: this.gridName02,
|
||||
value: gridOptions,
|
||||
});
|
||||
|
||||
var columnList01 = [
|
||||
// {header:'No', name:"No", width:50, align:"center"},
|
||||
{
|
||||
header: 'readplcId',
|
||||
name: 'readPlcId',
|
||||
align: 'center',
|
||||
hidden: true,
|
||||
},
|
||||
{ header: '미사용개소 ', name: 'readPlcNm', align: 'left' },
|
||||
];
|
||||
|
||||
var columnList02 = [
|
||||
// {header:'No', name:"No", width:50, align:"center"},
|
||||
{
|
||||
header: 'readplcId',
|
||||
name: 'readPlcId',
|
||||
align: 'center',
|
||||
hidden: true,
|
||||
},
|
||||
{ header: '통신이상개소', name: 'readPlcNm', align: 'left' },
|
||||
{ header: '최종검침시간', name: 'readTm', width: 90, align: 'center' },
|
||||
];
|
||||
|
||||
this.setWidgetGridColumn({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetKey: 'ComcUseReptWidget',
|
||||
widgetData: 'ComcUseReptWidgetData',
|
||||
gridKey: this.gridName01,
|
||||
value: columnList01,
|
||||
});
|
||||
|
||||
this.setWidgetGridColumn({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetKey: 'ComcUseReptWidget',
|
||||
widgetData: 'ComcUseReptWidgetData',
|
||||
gridKey: this.gridName02,
|
||||
value: columnList02,
|
||||
});
|
||||
|
||||
await this.getGridData();
|
||||
|
||||
this.loadGrid01 = true;
|
||||
this.loadGrid02 = true;
|
||||
},
|
||||
async getGridData() {
|
||||
// var res1 = [
|
||||
// {"No":1, "readplcId":123, "readPlcNm":"abc"},
|
||||
// {"No":2, "readplcId":123, "readPlcNm":"bcd"},
|
||||
// {"No":3, "readplcId":123, "readPlcNm":"cde"},
|
||||
// ];
|
||||
|
||||
// var res2 = [
|
||||
// {"No":1, "readplcId":123, "readPlcNm":"aaa"},
|
||||
// {"No":2, "readplcId":123, "readPlcNm":"bbb"},
|
||||
// {"No":3, "readplcId":123, "readPlcNm":"ccc"},
|
||||
// ];
|
||||
var res1;
|
||||
var res2;
|
||||
|
||||
res1 = await this.postApiReturn({
|
||||
apiKey: 'selectUnusedReadPlc',
|
||||
resKey: 'unusedData',
|
||||
sendParam: {},
|
||||
});
|
||||
|
||||
res2 = await this.postApiReturn({
|
||||
apiKey: 'selectEtcReadPlc',
|
||||
resKey: 'etcData',
|
||||
sendParam: {},
|
||||
});
|
||||
|
||||
res1.map((item, index) => {
|
||||
item.No = index + 1;
|
||||
});
|
||||
|
||||
res2.map((item, index) => {
|
||||
item.No = index + 1;
|
||||
});
|
||||
|
||||
this.setWidgetGridData({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetKey: 'ComcUseReptWidget',
|
||||
widgetData: 'ComcUseReptWidgetData',
|
||||
gridKey: this.gridName01,
|
||||
value: res1,
|
||||
});
|
||||
|
||||
this.setWidgetGridData({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetKey: 'ComcUseReptWidget',
|
||||
widgetData: 'ComcUseReptWidgetData',
|
||||
gridKey: this.gridName02,
|
||||
value: res2,
|
||||
});
|
||||
},
|
||||
async getReadplcStatus() {
|
||||
const res = await this.postApiReturn({
|
||||
apiKey: 'selectReadplcStatus',
|
||||
resKey: 'pointData',
|
||||
sendParam: {},
|
||||
});
|
||||
|
||||
res.forEach((item, idx) => {
|
||||
if (item.type == 'ALL') {
|
||||
this.pointUse = item.cnt;
|
||||
}
|
||||
if (item.type == 'UNUSED') {
|
||||
this.pointNoUse = item.cnt;
|
||||
}
|
||||
if (item.type == 'ABNORMAL') {
|
||||
this.pointEtc = item.cnt;
|
||||
}
|
||||
});
|
||||
},
|
||||
btnAction(action) {
|
||||
switch (action) {
|
||||
case 'popWidget':
|
||||
this.openDashboardWidget({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetId: this.widgetId,
|
||||
});
|
||||
break;
|
||||
case 'widgetCallPage':
|
||||
this.$parent.$parent.$parent.openWidgetPrgm(this.widgetId);
|
||||
break;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const ComcUseReptWidgetData = {
|
||||
grid01: {
|
||||
data: [],
|
||||
column: [],
|
||||
option: {},
|
||||
},
|
||||
grid02: {
|
||||
data: [],
|
||||
column: [],
|
||||
option: {},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.v-avatar {
|
||||
border-radius: 21px;
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
.v-virtual-scroll-wrapper {
|
||||
overflow-y: auto;
|
||||
max-height: 210px;
|
||||
}
|
||||
</style>
|
340
components/widget/ElecQualWidget.vue
Normal file
340
components/widget/ElecQualWidget.vue
Normal file
@ -0,0 +1,340 @@
|
||||
<template>
|
||||
<div class="l-layout">
|
||||
<v-row ref="rowParent">
|
||||
<v-col :cols="12">
|
||||
<v-card class="pa-3 widget-card">
|
||||
<div class="d-flex align-center justify-space-between">
|
||||
<v-card-title class="pa-0">전력품질</v-card-title>
|
||||
<v-card-subtitle class="mt-0 pa-0">
|
||||
<div hidden>
|
||||
<component
|
||||
:is="'SelectBlocMstr'"
|
||||
ref="SelectBlocMstr"
|
||||
:parentPrgmId="parentPrgmId"
|
||||
:hidden="true"
|
||||
/>
|
||||
</div>
|
||||
<component
|
||||
ref="MainReadReptReadObjMultiPop"
|
||||
:is="'MainReadReptReadObjMultiPop'"
|
||||
:parentPrgmId="parentPrgmId"
|
||||
:eqpmYn="0"
|
||||
:labelCols="2"
|
||||
:textCols="10"
|
||||
:popTitle="'검침대상 목록'"
|
||||
:widgetId="'ElecQualWidget'"
|
||||
@chDialogViewElecQualWidget="dialogViewChange"
|
||||
/>
|
||||
<v-tooltip bottom>
|
||||
<template v-slot:activator="{ on, attrs }">
|
||||
<v-icon
|
||||
class="mr-1"
|
||||
size="25"
|
||||
v-bind="attrs"
|
||||
v-on="on"
|
||||
@click="readObjDialog"
|
||||
>mdi-tooltip-plus</v-icon
|
||||
>
|
||||
</template>
|
||||
<span>품질</span>
|
||||
</v-tooltip>
|
||||
<component
|
||||
:is="'ReadPlcWidgetPop'"
|
||||
:parentPrgmId="parentPrgmId"
|
||||
:widGetKey="'ElecQualWidget'"
|
||||
:widgetDataKey="'ElecQualWidgetData'"
|
||||
:isMulti="true"
|
||||
@chDialogViewElecQualWidget="dialogViewChange"
|
||||
:mntrFg="'1'"
|
||||
/>
|
||||
<v-icon
|
||||
v-show="widgetPrgmId"
|
||||
class="mr-1"
|
||||
size="25"
|
||||
@click="btnAction('widgetCallPage')"
|
||||
>mdi-note-search</v-icon
|
||||
>
|
||||
<v-icon
|
||||
v-show="widgetPopFg"
|
||||
size="25"
|
||||
@click="btnAction('popWidget')"
|
||||
>mdi-plus-box-multiple</v-icon
|
||||
>
|
||||
</v-card-subtitle>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div :style="{ width: '100%', height: '230px' }">
|
||||
<component
|
||||
class="w100 h100"
|
||||
:is="loadChart ? 'Chart' : null"
|
||||
:parentPrgmId="parentPrgmId"
|
||||
:chartName="chartName"
|
||||
:widgetId="'ElecQualWidget'"
|
||||
:widgetData="'ElecQualWidgetData'"
|
||||
ref="chart"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions, mapMutations, mapState } from 'vuex'; // , mapActions
|
||||
import Vue from 'vue';
|
||||
import DateUtility from '~/plugins/dateUtility';
|
||||
import Utility from '~/plugins/utility';
|
||||
import Chart from '~/components/common/Chart';
|
||||
import ReadPlcWidgetPop from '~/components/common/modal/ReadPlcWidgetPop';
|
||||
import MainReadReptReadObjMultiPop from '~/components/common/modal/MainReadReptReadObjMultiPop';
|
||||
import SelectBlocMstr from '@/components/common/select/SelectBlocMstr';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
parentPrgmId: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
widgetId: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
widgetPrgmId: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
widgetPopFg: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
widgetReflashMm: {
|
||||
type: Number,
|
||||
require: true,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
DateUtility,
|
||||
Chart,
|
||||
ReadPlcWidgetPop,
|
||||
SelectBlocMstr,
|
||||
MainReadReptReadObjMultiPop,
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
searchParam(state) {
|
||||
return state.pageData[this.parentPrgmId];
|
||||
},
|
||||
isDarkMode: 'isDarkMode',
|
||||
}),
|
||||
},
|
||||
watch: {},
|
||||
beforeCreate() {
|
||||
this.$store.commit('setWidgetPageData', {
|
||||
prgmId: this.$route.query.prgmId,
|
||||
// defaultData: defaultData,
|
||||
ElecQualWidget: { ElecQualWidgetData: ElecQualWidget },
|
||||
});
|
||||
},
|
||||
created() {
|
||||
this.search();
|
||||
this.timer = setInterval(this.search, this.widgetReflashMm);
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.clearTimeout(this.timer);
|
||||
},
|
||||
mounted() {},
|
||||
data() {
|
||||
return {
|
||||
loadChart: false,
|
||||
selectedQualityKind: null,
|
||||
selectedReadPlcId: null,
|
||||
paramReadObjId: 'ROI00005',
|
||||
chartName: 'elecQualityChart',
|
||||
// readPlcPopItem:readPlcPopItem,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
...mapMutations({
|
||||
setPageData: 'setPageData',
|
||||
setWidgetChartOption: 'setWidgetChartOption',
|
||||
openDashboardWidget: 'openDashboardWidget',
|
||||
}),
|
||||
...mapActions({
|
||||
postApi: 'modules/list/postApi',
|
||||
postApiReturn: 'modules/list/postApiReturn',
|
||||
}),
|
||||
async search() {
|
||||
await this.getElecQuality();
|
||||
},
|
||||
async getElecQuality() {
|
||||
this.loadChart = false;
|
||||
var plcKindList =
|
||||
this.searchParam['ElecQualWidget']['ElecQualWidgetData'].plcKindList
|
||||
.length > 0
|
||||
? this.searchParam['ElecQualWidget'][
|
||||
'ElecQualWidgetData'
|
||||
].plcKindList.map(item => {
|
||||
return item.readPlcId;
|
||||
})
|
||||
: null;
|
||||
var readObjId =
|
||||
this.searchParam['ElecQualWidget']['ElecQualWidgetData'].readObjList
|
||||
.length > 0
|
||||
? this.searchParam['ElecQualWidget']['ElecQualWidgetData']
|
||||
.readObjList[0].readObjId
|
||||
: 'ROI000005';
|
||||
//console.log('plcKindList : ', plcKindList);
|
||||
const res = await this.postApiReturn({
|
||||
apiKey: 'selectWidgetElecQuality',
|
||||
resKey: 'elecQualData',
|
||||
sendParam: {
|
||||
readObjId: readObjId,
|
||||
readPlcIdList: plcKindList,
|
||||
},
|
||||
});
|
||||
|
||||
await this.setChartData(res);
|
||||
},
|
||||
async setChartData(data) {
|
||||
this.$store.state.pageData[
|
||||
this.parentPrgmId
|
||||
].ElecQualWidget.ElecQualWidgetData.series = [];
|
||||
//console.log('res : ', data);
|
||||
if (!data.length) {
|
||||
return;
|
||||
}
|
||||
var xAxisData = [];
|
||||
var seriesData = [];
|
||||
var legendData = [];
|
||||
var yName = data[0]['readObjUnit'];
|
||||
|
||||
var readPlcIdChk = data[0]['readPlcId'];
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
if (readPlcIdChk == data[i]['readPlcId']) {
|
||||
xAxisData.push(
|
||||
data[i]['readDttm']
|
||||
? Utility.setFormatDate(data[i]['readDttm'], 'HH:mm')
|
||||
: '',
|
||||
);
|
||||
}
|
||||
}
|
||||
var tempObj = {};
|
||||
tempObj['data'] = [];
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
if (i > 0) {
|
||||
if (readPlcIdChk == data[i]['readPlcId']) {
|
||||
tempObj['data'].push(data[i]['readVal']);
|
||||
if (i == data.length - 1) {
|
||||
seriesData.push(tempObj);
|
||||
}
|
||||
} else {
|
||||
seriesData.push(tempObj);
|
||||
//비교 readPlc 변경
|
||||
readPlcIdChk = data[i]['readPlcId'];
|
||||
tempObj = {};
|
||||
tempObj['data'] = [];
|
||||
tempObj['name'] = data[i]['readPlcNm'];
|
||||
tempObj['type'] = 'line';
|
||||
tempObj['data'].push(data[i]['readVal']);
|
||||
legendData.push(data[i]['readPlcNm']);
|
||||
}
|
||||
} else {
|
||||
tempObj['name'] = data[i]['readPlcNm'];
|
||||
tempObj['type'] = 'line';
|
||||
tempObj['data'].push(parseFloat(data[i]['readVal']));
|
||||
legendData.push(data[i]['readPlcNm']);
|
||||
}
|
||||
}
|
||||
|
||||
var chartOption = {
|
||||
grid: {
|
||||
top: '15%',
|
||||
bottom: '15%',
|
||||
},
|
||||
legend: {
|
||||
type: 'scroll',
|
||||
pageIconColor: '#18579e',
|
||||
pageIconInactiveColor: '#ffffff66',
|
||||
pageTextStyle: { color: '#fff' },
|
||||
data: legendData,
|
||||
},
|
||||
xAxis: {
|
||||
data: xAxisData,
|
||||
},
|
||||
yAxis: {
|
||||
name: yName,
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: this.isDarkMode ? '#fff' : '#cccccc',
|
||||
opacity: this.isDarkMode ? 0.2 : 1,
|
||||
type: 'dotted',
|
||||
width: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
series: seriesData,
|
||||
};
|
||||
// console.log('utility chartoption : ', Utility.defaultChartOption());
|
||||
|
||||
this.setWidgetChartOption({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetKey: 'ElecQualWidget',
|
||||
widgetData: 'ElecQualWidgetData',
|
||||
chartKey: 'elecQualityChart',
|
||||
value: chartOption,
|
||||
});
|
||||
|
||||
this.loadChart = true;
|
||||
},
|
||||
async dialogViewChange() {
|
||||
await this.search();
|
||||
},
|
||||
readObjDialog() {
|
||||
this.$store.state.pageData[this.parentPrgmId]['ElecQualWidget'][
|
||||
'ElecQualWidgetData'
|
||||
].enrgDiv = 'MTT_ELEC';
|
||||
this.$refs['MainReadReptReadObjMultiPop'].dialog = true;
|
||||
},
|
||||
btnAction(action) {
|
||||
switch (action) {
|
||||
case 'popWidget':
|
||||
this.openDashboardWidget({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetId: this.widgetId,
|
||||
});
|
||||
break;
|
||||
case 'widgetCallPage':
|
||||
this.$parent.$parent.$parent.openWidgetPrgm(this.widgetId);
|
||||
break;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const ElecQualWidget = {
|
||||
elecQualityChart: Utility.defaultChartOption(true),
|
||||
blocId: 0,
|
||||
blocMstrList: [],
|
||||
modalData: {},
|
||||
rowGridSelectData: null,
|
||||
rowGridSelectKey: 0,
|
||||
plcKindList: [],
|
||||
isMulti: false,
|
||||
readObjList: [],
|
||||
readObj: null,
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.v-avatar {
|
||||
border-radius: 21px;
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
.v-virtual-scroll-wrapper {
|
||||
overflow-y: auto;
|
||||
max-height: 210px;
|
||||
}
|
||||
</style>
|
346
components/widget/ElecReadReptWidget.vue
Normal file
346
components/widget/ElecReadReptWidget.vue
Normal file
@ -0,0 +1,346 @@
|
||||
<template>
|
||||
<div class="l-layout">
|
||||
<v-row ref="rowParent">
|
||||
<v-col :cols="12">
|
||||
<v-card class="pa-3 widget-card">
|
||||
<div class="d-flex align-center justify-space-between">
|
||||
<v-card-title class="pa-0">전력 검침현황</v-card-title>
|
||||
<v-card-subtitle class="mt-0 pa-0">
|
||||
<component
|
||||
ref="MainReadReptReadObjMultiPop"
|
||||
:is="'MainReadReptReadObjMultiPop'"
|
||||
:parentPrgmId="parentPrgmId"
|
||||
:eqpmYn="0"
|
||||
:popTitle="'검침대상 목록'"
|
||||
:widgetId="this.widgetId"
|
||||
@chDialogViewmainReadReptWidget="dialogViewChange"
|
||||
/>
|
||||
<v-tooltip bottom>
|
||||
<template v-slot:activator="{ on, attrs }">
|
||||
<v-icon
|
||||
class="mr-1"
|
||||
size="25"
|
||||
v-bind="attrs"
|
||||
v-on="on"
|
||||
@click="readObjDialog"
|
||||
>mdi-tooltip-plus</v-icon
|
||||
>
|
||||
</template>
|
||||
<span>품질</span>
|
||||
</v-tooltip>
|
||||
<v-icon
|
||||
v-show="widgetPrgmId"
|
||||
class="mr-1"
|
||||
size="25"
|
||||
@click="btnAction('widgetCallPage')"
|
||||
>mdi-note-search</v-icon
|
||||
>
|
||||
<v-icon
|
||||
v-show="widgetPopFg"
|
||||
size="25"
|
||||
@click="btnAction('popWidget')"
|
||||
>mdi-plus-box-multiple</v-icon
|
||||
>
|
||||
</v-card-subtitle>
|
||||
</div>
|
||||
<div class="px-2 pt-2">
|
||||
<v-banner single-line :style="{ paddingRight: '10px' }">
|
||||
<v-row justify="space-between" align="center" no-gutters>
|
||||
<v-col cols="auto" align="center">
|
||||
<p class="body-2 mb-0">No</p>
|
||||
</v-col>
|
||||
<v-col cols="4" align="center">
|
||||
검침개소
|
||||
</v-col>
|
||||
<v-col cols="2" align="center">
|
||||
<p class="body-2 mb-0">kW</p>
|
||||
</v-col>
|
||||
<v-col cols="2" align="center">
|
||||
상태
|
||||
</v-col>
|
||||
<v-col
|
||||
cols="2"
|
||||
align="center"
|
||||
v-for="(item, index) in readObjIdList"
|
||||
:key="item.readPlcId"
|
||||
:class="{
|
||||
'v-banner--last': index === readObjIdList.length - 1,
|
||||
}"
|
||||
>
|
||||
{{ item.readObjNm }}
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-banner>
|
||||
<div
|
||||
class="v-virtual-scroll-wrapper"
|
||||
style="padding-right: '5px'; overflow-y: auto; max-height:185px"
|
||||
>
|
||||
<v-banner
|
||||
single-line
|
||||
v-for="(item, index) in mainReadPlcData"
|
||||
:key="item.readPlcId"
|
||||
:class="{
|
||||
'v-banner--last': index === mainReadPlcData.length - 1,
|
||||
}"
|
||||
>
|
||||
<v-row justify="space-between" align="center" no-gutters>
|
||||
<v-col cols="auto">
|
||||
<p class="body-2 mb-0">{{ item.rowNum }}</p>
|
||||
</v-col>
|
||||
<v-col cols="4">
|
||||
<div
|
||||
class="d-flex align-center"
|
||||
style="white-space: normal"
|
||||
>
|
||||
<p class="body-2 mb-0 ml-2">{{ item.readPlcNm }}</p>
|
||||
</div>
|
||||
</v-col>
|
||||
<v-col cols="2" align="center">
|
||||
<p class="body-2 mb-0">
|
||||
{{
|
||||
String(Math.floor(item.instantVal)).replace(
|
||||
/\B(?=(\d{3})+(?!\d))/g,
|
||||
',',
|
||||
)
|
||||
}}
|
||||
</p>
|
||||
</v-col>
|
||||
<v-col cols="2" align="center">
|
||||
<v-icon
|
||||
:color="
|
||||
isDarkMode
|
||||
? tableDataGetDarkColorByState(item.stat)
|
||||
: tableDataGetLightColorByState(item.stat)
|
||||
"
|
||||
size="8"
|
||||
class="mr-1"
|
||||
>mdi-circle</v-icon
|
||||
>
|
||||
<span class="body-2">{{ item.stat }}</span>
|
||||
</v-col>
|
||||
<v-col
|
||||
cols="2"
|
||||
align="center"
|
||||
v-for="(item2, index) in readObjIdList"
|
||||
:key="item2.readPlcId"
|
||||
:class="{
|
||||
'v-banner--last': index === readObjIdList.length - 1,
|
||||
}"
|
||||
>
|
||||
<span class="body-2">{{ item[item2.readObjId] }}</span>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-banner>
|
||||
</div>
|
||||
</div>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions, mapMutations, mapState } from 'vuex'; // , mapActions
|
||||
import Vue from 'vue';
|
||||
import DateUtility from '~/plugins/dateUtility';
|
||||
import Utility from '~/plugins/utility';
|
||||
import Chart from '~/components/common/Chart';
|
||||
import MainReadReptReadObjMultiPop from '~/components/common/modal/MainReadReptReadObjMultiPop';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
parentPrgmId: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
widgetId: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
widgetPrgmId: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
widgetPopFg: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
widgetReflashMm: {
|
||||
type: Number,
|
||||
require: true,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
DateUtility,
|
||||
Chart,
|
||||
MainReadReptReadObjMultiPop,
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
searchParam(state) {
|
||||
return state.pageData[this.parentPrgmId][this.widgetId][
|
||||
this.widgetId + 'Data'
|
||||
];
|
||||
},
|
||||
isDarkMode: 'isDarkMode',
|
||||
}),
|
||||
},
|
||||
watch: {
|
||||
energyCd() {
|
||||
this.getMainReadPlcStat();
|
||||
},
|
||||
},
|
||||
beforeCreate() {
|
||||
this.$store.commit('setWidgetPageData', {
|
||||
prgmId: this.$route.query.prgmId,
|
||||
ElecReadReptWidget: { ElecReadReptWidgetData },
|
||||
});
|
||||
},
|
||||
async created() {
|
||||
this.search();
|
||||
this.timer = setInterval(this.search, this.widgetReflashMm);
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.clearTimeout(this.timer);
|
||||
},
|
||||
mounted() {},
|
||||
data() {
|
||||
return {
|
||||
blocNm: '',
|
||||
mainReadPlcData: [],
|
||||
//widgetId:"ElecReadReptWidget",
|
||||
dialogView: false,
|
||||
readObjIdList: [],
|
||||
readPlcIdList: [],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
...mapMutations({
|
||||
setPageData: 'setPageData',
|
||||
setWidgetChartOption: 'setWidgetChartOption',
|
||||
openDashboardWidget: 'openDashboardWidget',
|
||||
}),
|
||||
...mapActions({
|
||||
postApi: 'modules/list/postApi',
|
||||
postApiReturn: 'modules/list/postApiReturn',
|
||||
getEnergyList: 'modules/search/getEnergyList',
|
||||
}),
|
||||
setBlocNm() {
|
||||
this.blocNm = this.$store.state.userInfo.blocNm;
|
||||
if (this.blocNm != '') {
|
||||
this.blocNm = '[' + this.blocNm + ']';
|
||||
}
|
||||
},
|
||||
dialogViewChange() {
|
||||
this.getMainReadPlcStat();
|
||||
},
|
||||
async search() {
|
||||
this.setBlocNm();
|
||||
|
||||
await this.getMainReadPlcStat();
|
||||
},
|
||||
async getMainReadPlcStat() {
|
||||
if (
|
||||
this.$store.state.pageData[this.parentPrgmId].ElecReadReptWidget
|
||||
.ElecReadReptWidgetData.readObjList.length > 0
|
||||
) {
|
||||
this.readObjIdList = this.$store.state.pageData[
|
||||
this.parentPrgmId
|
||||
].ElecReadReptWidget.ElecReadReptWidgetData.readObjList.map(item => {
|
||||
return { readObjId: item.readObjId, readObjNm: item.readObjNm };
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
this.$store.state.pageData[this.parentPrgmId].ElecReadReptWidget
|
||||
.ElecReadReptWidgetData.plcKindList.length > 0
|
||||
) {
|
||||
this.readPlcIdList = this.$store.state.pageData[
|
||||
this.parentPrgmId
|
||||
].ElecReadReptWidget.ElecReadReptWidgetData.plcKindList.map(item => {
|
||||
return item.readPlcId;
|
||||
});
|
||||
}
|
||||
this.mainReadPlcData = await this.postApiReturn({
|
||||
apiKey: 'selectMainReadPlcStat',
|
||||
resKey: 'mainReadPlcData',
|
||||
sendParam: {
|
||||
readObjIdList: this.readObjIdList,
|
||||
},
|
||||
});
|
||||
|
||||
// this.mainReadPlcData = [
|
||||
// {
|
||||
// "rowNum" : 1,
|
||||
// "comId" : "CDR00",
|
||||
// "readPlcId" : "RPC000002",
|
||||
// "readPlcNm" : "[전력] LP-1_A동메인",
|
||||
// "readObjNm" : "Heartbit",
|
||||
// "readObjId" : "ROI000040",
|
||||
// "instantVal" : 11239.0,
|
||||
// "volt" : 228.9,
|
||||
// "ampr" : 55.1,
|
||||
// "ROI000001" : 93613.1,
|
||||
// "ROI000005" : 229.7,
|
||||
// "ROI000006" : 81.8,
|
||||
// "ROI000008" : 1,
|
||||
// "stat" : "가동중"
|
||||
// }
|
||||
// ]
|
||||
},
|
||||
btnAction(action) {
|
||||
switch (action) {
|
||||
case 'popWidget':
|
||||
this.openDashboardWidget({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetId: this.widgetId,
|
||||
});
|
||||
break;
|
||||
case 'widgetCallPage':
|
||||
this.$parent.$parent.$parent.openWidgetPrgm(this.widgetId);
|
||||
break;
|
||||
}
|
||||
},
|
||||
tableDataGetDarkColorByState: state => {
|
||||
return {
|
||||
가동중: '#01ae6a',
|
||||
미사용: '#ffb046',
|
||||
비정상: '#f6637b',
|
||||
}[state];
|
||||
},
|
||||
tableDataGetLightColorByState: state => {
|
||||
return {
|
||||
가동중: '#3cc380',
|
||||
미사용: '#ffb13b',
|
||||
비정상: '#f98694',
|
||||
}[state];
|
||||
},
|
||||
readObjDialog() {
|
||||
this.$store.state.pageData[
|
||||
this.parentPrgmId
|
||||
].ElecReadReptWidget.ElecReadReptWidgetData.enrgDiv = 'MTT_ELEC';
|
||||
this.$store.state.pageData[
|
||||
this.parentPrgmId
|
||||
].ElecReadReptWidget.ElecReadReptWidgetData.grpCd = 'MTT_STAT';
|
||||
this.$refs['MainReadReptReadObjMultiPop'].dialog = true;
|
||||
},
|
||||
},
|
||||
};
|
||||
const ElecReadReptWidgetData = {
|
||||
readObjModalData: {},
|
||||
isMulti: true,
|
||||
blocId: 0,
|
||||
blocMstrList: [],
|
||||
readObjList: [],
|
||||
readObj: {},
|
||||
enrgDiv: '',
|
||||
plcKindList: [],
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.v-avatar {
|
||||
border-radius: 21px;
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
</style>
|
413
components/widget/ElecUseReptWidget.vue
Normal file
413
components/widget/ElecUseReptWidget.vue
Normal file
@ -0,0 +1,413 @@
|
||||
<template>
|
||||
<div class="l-layout">
|
||||
<v-row ref="rowParent">
|
||||
<v-col :cols="12">
|
||||
<v-card class="pa-3 widget-card">
|
||||
<div class="d-flex align-center justify-space-between">
|
||||
<v-card-title class="pa-0">전력 사용현황</v-card-title>
|
||||
<v-card-subtitle class="mt-0 pa-0">
|
||||
<v-icon
|
||||
v-show="widgetPrgmId"
|
||||
class="mr-1"
|
||||
size="25"
|
||||
@click="btnAction('widgetCallPage')"
|
||||
>mdi-note-search</v-icon
|
||||
>
|
||||
<v-icon
|
||||
v-show="widgetPopFg"
|
||||
size="25"
|
||||
@click="btnAction('popWidget')"
|
||||
>mdi-plus-box-multiple</v-icon
|
||||
>
|
||||
</v-card-subtitle>
|
||||
</div>
|
||||
<v-card-actions class="d-flex justify-sm-end pb-0 pr-0 pt-1">
|
||||
<v-row>
|
||||
<v-col sm="7" lg="8"></v-col>
|
||||
<v-col sm="5" lg="4" class="d-flex align-center justify-end">
|
||||
<v-radio-group
|
||||
v-model="rdbElecUsage"
|
||||
hide-details
|
||||
dense
|
||||
row
|
||||
class="mt-0"
|
||||
>
|
||||
<v-radio
|
||||
label="금일"
|
||||
value="hour"
|
||||
:color="isDarkMode ? '#2d8cf6' : '#4777d9'"
|
||||
on-icon="mdi-record-circle"
|
||||
:ripple="false"
|
||||
></v-radio>
|
||||
<v-radio
|
||||
label="금월"
|
||||
value="month"
|
||||
:color="isDarkMode ? '#2d8cf6' : '#4777d9'"
|
||||
on-icon="mdi-record-circle"
|
||||
:ripple="false"
|
||||
></v-radio>
|
||||
</v-radio-group>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-actions>
|
||||
<div class="d-flex align-center justify-space-between">
|
||||
<div :style="{ width: '100%', height: '200px' }">
|
||||
<component
|
||||
class="w100 h100"
|
||||
:is="loadChart_01 ? 'Chart' : null"
|
||||
:parentPrgmId="parentPrgmId"
|
||||
:widgetId="'ElecUseReptWidget'"
|
||||
:widgetData="'ElecUseReptWidgetData'"
|
||||
:chartName="chart_01"
|
||||
ref="chart_01"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions, mapMutations, mapState } from 'vuex'; // , mapActions
|
||||
import Vue from 'vue';
|
||||
import DateUtility from '~/plugins/dateUtility';
|
||||
import Utility from '~/plugins/utility';
|
||||
import Chart from '~/components/common/Chart';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
parentPrgmId: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
widgetId: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
widgetPrgmId: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
widgetPopFg: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
widgetReflashMm: {
|
||||
type: Number,
|
||||
require: true,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
DateUtility,
|
||||
Chart,
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
searchParam(state) {
|
||||
return state.pageData[this.parentPrgmId];
|
||||
},
|
||||
isDarkMode: 'isDarkMode',
|
||||
}),
|
||||
},
|
||||
watch: {
|
||||
rdbElecUsage() {
|
||||
this.getElecUsage();
|
||||
},
|
||||
},
|
||||
beforeCreate() {
|
||||
this.$store.commit('setWidgetPageData', {
|
||||
prgmId: this.$route.query.prgmId,
|
||||
ElecUseReptWidget: { ElecUseReptWidgetData },
|
||||
});
|
||||
},
|
||||
async created() {
|
||||
this.search();
|
||||
this.timer = setInterval(this.search, this.widgetReflashMm);
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.clearTimeout(this.timer);
|
||||
},
|
||||
mounted() {},
|
||||
data() {
|
||||
return {
|
||||
blocNm: '',
|
||||
//차트
|
||||
chart_01: 'elecUsage',
|
||||
loadChart_01: false,
|
||||
//바인딩
|
||||
rdbElecUsage: 'hour',
|
||||
rdbElecQual: 'Kw',
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
...mapMutations({
|
||||
setPageData: 'setPageData',
|
||||
setWidgetChartOption: 'setWidgetChartOption',
|
||||
openDashboardWidget: 'openDashboardWidget',
|
||||
}),
|
||||
...mapActions({
|
||||
postApi: 'modules/list/postApi',
|
||||
postApiReturn: 'modules/list/postApiReturn',
|
||||
getEnergyList: 'modules/search/getEnergyList',
|
||||
}),
|
||||
setBlocNm() {
|
||||
this.blocNm = this.$store.state.userInfo.blocNm;
|
||||
if (this.blocNm != '') {
|
||||
this.blocNm = '[' + this.blocNm + ']';
|
||||
}
|
||||
},
|
||||
async search() {
|
||||
this.setBlocNm();
|
||||
await this.getElecUsage();
|
||||
},
|
||||
async getElecUsage() {
|
||||
this.loadChart_01 = false;
|
||||
let paramApiKey = '';
|
||||
let markAreaData = [];
|
||||
let markColor = {
|
||||
MAX: 'rgba(238, 102, 102, 0.1)',
|
||||
MID: 'rgba(250, 200, 88, 0.1)',
|
||||
MIN: 'rgba(145, 204, 117, 0.1)',
|
||||
};
|
||||
if (this.rdbElecUsage == 'hour') {
|
||||
paramApiKey = 'selectEnrgUsageHour';
|
||||
// 부하시간 가져오기
|
||||
let res3 = [];
|
||||
res3 = await this.postApiReturn({
|
||||
apiKey: 'selectPeakKine',
|
||||
resKey: 'peakData',
|
||||
sendParam: {
|
||||
readObjId: 'ROI000001',
|
||||
toObjDt: Utility.setFormatDate(new Date(), 'YYYYMMDD'),
|
||||
},
|
||||
});
|
||||
|
||||
markAreaData = res3.map(item => [
|
||||
{
|
||||
name: item.commCdNm,
|
||||
xAxis:
|
||||
parseInt(item.strtTm.split(':')[0].replace(/(^0+)/, '')) == 23
|
||||
? 0
|
||||
: parseInt(item.strtTm.split(':')[0].replace(/(^0+)/, '')),
|
||||
itemStyle: {
|
||||
color: markColor[item.peakKine],
|
||||
},
|
||||
label: {
|
||||
distance: [0],
|
||||
fontSize: 9,
|
||||
fontWeight: 'lighter',
|
||||
color: '#fff',
|
||||
},
|
||||
},
|
||||
{
|
||||
xAxis: parseInt(item.endTm.split(':')[0].replace(/(^0+)/, '')),
|
||||
},
|
||||
]);
|
||||
} else {
|
||||
paramApiKey = 'selectEnrgUsageMonth';
|
||||
}
|
||||
|
||||
let res = await this.postApiReturn({
|
||||
apiKey: paramApiKey,
|
||||
resKey: 'enrgUsageData',
|
||||
sendParam: {
|
||||
readObjId: 'ROI000001',
|
||||
},
|
||||
});
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.setChart01Data(res, markAreaData);
|
||||
});
|
||||
},
|
||||
|
||||
//차트Setting
|
||||
async setChart01Data(data, markAreaData) {
|
||||
this.$store.state.pageData[
|
||||
this.parentPrgmId
|
||||
].ElecUseReptWidget.ElecUseReptWidgetData.series = [];
|
||||
if (!data.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
let xAxisData = [];
|
||||
let seriesData = [];
|
||||
let legendData = [];
|
||||
let arrDarkColors = ['rgba(1, 174, 106, 0.7)', 'rgba(67, 133, 227, 0.7)'];
|
||||
let arrLightColors = [
|
||||
'rgba(207, 116, 229, 0.7)',
|
||||
'rgba(106, 155, 244, 0.7)',
|
||||
];
|
||||
const arrColors = this.isDarkMode ? arrDarkColors : arrLightColors;
|
||||
|
||||
if (this.rdbElecUsage == 'month') {
|
||||
var qtyNumber, qtyStr;
|
||||
for (var i = 1; i < 32; i++) {
|
||||
qtyNumber = i.toString().padStart(2, '0');
|
||||
qtyStr = 'qty' + qtyNumber;
|
||||
xAxisData.push(i + '일');
|
||||
}
|
||||
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var tempObj = {};
|
||||
tempObj['name'] = data[i]['type'];
|
||||
if (data[i]['type'] == '금월 사용량') {
|
||||
tempObj['type'] = 'bar';
|
||||
} else {
|
||||
tempObj['type'] = 'line';
|
||||
}
|
||||
tempObj['data'] = [];
|
||||
tempObj['color'] = arrColors[i];
|
||||
tempObj['lineStyle'] = { width: 2 };
|
||||
|
||||
tempObj['smooth'] = true;
|
||||
tempObj['showSymbol'] = false;
|
||||
|
||||
legendData.push(data[i]['type']);
|
||||
|
||||
for (var j = 0; j < 31; j++) {
|
||||
qtyNumber = (j + 1).toString().padStart(2, '0');
|
||||
qtyStr = 'qty' + qtyNumber;
|
||||
if (data[i].hasOwnProperty(qtyStr)) {
|
||||
tempObj['data'].push(
|
||||
parseFloat(
|
||||
Utility.setFormatIntDecimal(
|
||||
parseFloat(data[i][qtyStr]),
|
||||
2,
|
||||
).replace(',', ''),
|
||||
),
|
||||
);
|
||||
// tempObj['data'].push(parseFloat(data[i][qtyStr]));
|
||||
} else {
|
||||
tempObj['data'].push(0);
|
||||
}
|
||||
}
|
||||
seriesData.push(tempObj);
|
||||
}
|
||||
} else if (this.rdbElecUsage == 'hour') {
|
||||
var qtyNumber, qtyStr;
|
||||
for (var i = 0; i < 24; i++) {
|
||||
qtyNumber = i.toString().padStart(2, '0');
|
||||
qtyStr = 'qty' + qtyNumber;
|
||||
xAxisData.push(i + '시');
|
||||
}
|
||||
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var tempObj = {};
|
||||
tempObj['name'] = data[i]['type'];
|
||||
if (data[i]['type'] == '금일 사용량') {
|
||||
tempObj['type'] = 'bar';
|
||||
} else {
|
||||
tempObj['type'] = 'line';
|
||||
}
|
||||
tempObj['data'] = [];
|
||||
tempObj['color'] = arrColors[i];
|
||||
tempObj['lineStyle'] = { width: 2 };
|
||||
if (markAreaData != null) {
|
||||
tempObj['markArea'] = {
|
||||
data: markAreaData,
|
||||
};
|
||||
}
|
||||
// tempObj['areaStyle'] = {
|
||||
// opacity: 0.5,
|
||||
// color: arrColors[i]
|
||||
// };
|
||||
tempObj['smooth'] = true;
|
||||
tempObj['showSymbol'] = false;
|
||||
legendData.push(data[i]['type']);
|
||||
|
||||
for (var j = 0; j < 24; j++) {
|
||||
qtyNumber = j.toString().padStart(2, '0');
|
||||
qtyStr = 'qty' + qtyNumber;
|
||||
if (data[i].hasOwnProperty(qtyStr)) {
|
||||
tempObj['data'].push(
|
||||
Utility.setFormatIntDecimal(
|
||||
parseFloat(data[i][qtyStr]),
|
||||
2,
|
||||
).replace(',', ''),
|
||||
);
|
||||
// tempObj['data'].push(parseFloat(data[i][qtyStr]));
|
||||
} else {
|
||||
tempObj['data'].push(0);
|
||||
}
|
||||
}
|
||||
//console.log("data : " ,tempObj);
|
||||
seriesData.push(tempObj);
|
||||
}
|
||||
}
|
||||
|
||||
var chartOption = {
|
||||
series: seriesData,
|
||||
grid: {
|
||||
left: '1%',
|
||||
right: '2%',
|
||||
top: '15%',
|
||||
bottom: '15%',
|
||||
containLabel: true,
|
||||
},
|
||||
legend: {
|
||||
data: legendData,
|
||||
bottom: 'bottom',
|
||||
icon: 'bar',
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
//boundaryGap: false,
|
||||
splitLine: false,
|
||||
data: xAxisData,
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
name: 'kWh',
|
||||
splitLine: false,
|
||||
axisLabel: {
|
||||
color: '#767D83',
|
||||
fontSize: 10,
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
},
|
||||
};
|
||||
|
||||
this.setWidgetChartOption({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetKey: 'ElecUseReptWidget',
|
||||
widgetData: 'ElecUseReptWidgetData',
|
||||
chartKey: 'elecUsage',
|
||||
value: chartOption,
|
||||
});
|
||||
|
||||
this.loadChart_01 = true;
|
||||
},
|
||||
btnAction(action) {
|
||||
switch (action) {
|
||||
case 'popWidget':
|
||||
this.openDashboardWidget({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetId: this.widgetId,
|
||||
});
|
||||
break;
|
||||
case 'widgetCallPage':
|
||||
this.$parent.$parent.$parent.openWidgetPrgm(this.widgetId);
|
||||
break;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
const ElecUseReptWidgetData = {
|
||||
elecUsage: Utility.defaultChartOption(true),
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.v-avatar {
|
||||
border-radius: 21px;
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
.v-virtual-scroll-wrapper {
|
||||
overflow-y: auto;
|
||||
max-height: 210px;
|
||||
}
|
||||
</style>
|
685
components/widget/ElecUseRsltWidget.vue
Normal file
685
components/widget/ElecUseRsltWidget.vue
Normal file
@ -0,0 +1,685 @@
|
||||
<template>
|
||||
<div class="l-layout">
|
||||
<v-row ref="rowParent">
|
||||
<v-col :cols="12">
|
||||
<v-card class="pa-3 widget-card">
|
||||
<div class="d-flex align-center justify-space-between">
|
||||
<v-card-title class="pa-0">전력 사용량 실적</v-card-title>
|
||||
<v-card-subtitle class="mt-0 pa-0 text-right">
|
||||
<v-icon
|
||||
v-show="widgetPrgmId"
|
||||
class="mr-1"
|
||||
size="25"
|
||||
@click="btnAction('widgetCallPage')"
|
||||
>mdi-note-search</v-icon
|
||||
>
|
||||
<v-icon
|
||||
v-show="widgetPopFg"
|
||||
size="25"
|
||||
@click="btnAction('popWidget')"
|
||||
>mdi-plus-box-multiple</v-icon
|
||||
>
|
||||
</v-card-subtitle>
|
||||
</div>
|
||||
<div class="row wrapper">
|
||||
<div class="col-6">
|
||||
<div class="px-5 pb-1">
|
||||
<div class="text-center">
|
||||
<strong class="custom-title-2-5"
|
||||
>{{ dayUseQty }}
|
||||
<span class="font-weight-regular custom-text-2"
|
||||
>kWh</span
|
||||
></strong
|
||||
>
|
||||
<div class="d-flex align-center justify-center">
|
||||
<span class="body-2 text-color--non-activate"
|
||||
>전주 대비({{ currHour }})</span
|
||||
>
|
||||
<div
|
||||
class="d-flex align-baseline ml-2"
|
||||
:style="{
|
||||
color: isDarkMode
|
||||
? isUseQtyStat
|
||||
? '#f6637b'
|
||||
: '#01ae6a'
|
||||
: isUseQtyStat
|
||||
? '#ff76bb'
|
||||
: '#00c875',
|
||||
}"
|
||||
>
|
||||
<strong class="mr-1 custom-text-1">{{
|
||||
compareUseQty
|
||||
}}</strong>
|
||||
<span class="caption mr-1">kWh</span>
|
||||
<v-icon
|
||||
small
|
||||
:color="
|
||||
isDarkMode
|
||||
? isUseQtyStat
|
||||
? '#f6637b'
|
||||
: '#01ae6a'
|
||||
: isUseQtyStat
|
||||
? '#ff76bb'
|
||||
: '#00c875'
|
||||
"
|
||||
>{{ useQtyStat }}</v-icon
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="px-5 pb-1">
|
||||
<div class="text-center">
|
||||
<strong class="custom-title-2-5"
|
||||
>{{ dayUseCost }}
|
||||
<span class="font-weight-regular custom-text-2"
|
||||
>천원</span
|
||||
></strong
|
||||
>
|
||||
<div class="d-flex align-center justify-center">
|
||||
<span class="body-2 text-color--non-activate"
|
||||
>전주 대비(0시-{{ currHour }})</span
|
||||
>
|
||||
<div
|
||||
class="d-flex align-baseline ml-2"
|
||||
:style="{
|
||||
color: isDarkMode
|
||||
? isUseCostStat
|
||||
? '#f6637b'
|
||||
: '#01ae6a'
|
||||
: isUseCostStat
|
||||
? '#ff76bb'
|
||||
: '#00c875',
|
||||
}"
|
||||
>
|
||||
<strong class="mr-1 custom-text-1">{{
|
||||
compareUseCost
|
||||
}}</strong>
|
||||
<span class="caption mr-1">천원</span>
|
||||
<v-icon
|
||||
small
|
||||
:color="
|
||||
isDarkMode
|
||||
? isUseCostStat
|
||||
? '#f6637b'
|
||||
: '#01ae6a'
|
||||
: isUseCostStat
|
||||
? '#ff76bb'
|
||||
: '#00c875'
|
||||
"
|
||||
>{{ useCostStat }}</v-icon
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex align-center justify-space-between mt-2">
|
||||
<div :style="{ width: '100%', height: '160px' }">
|
||||
<component
|
||||
class="w100 h100"
|
||||
:is="loadChart_01 ? 'Chart' : null"
|
||||
:parentPrgmId="parentPrgmId"
|
||||
:widgetId="'EnrgUseRsltWidget'"
|
||||
:widgetData="'EnrgUseRsltWidgetData'"
|
||||
:chartName="chart_01"
|
||||
ref="chart_01"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions, mapMutations, mapState } from 'vuex'; // , mapActions
|
||||
import Vue from 'vue';
|
||||
import DateUtility from '~/plugins/dateUtility';
|
||||
import Utility from '~/plugins/utility';
|
||||
import Chart from '~/components/common/Chart';
|
||||
export default {
|
||||
props: {
|
||||
parentPrgmId: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
widgetId: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
widgetPrgmId: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
widgetPopFg: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
widgetReflashMm: {
|
||||
type: Number,
|
||||
require: true,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
DateUtility,
|
||||
Chart,
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
searchParam(state) {
|
||||
return state.pageData[this.parentPrgmId];
|
||||
},
|
||||
isDarkMode: 'isDarkMode',
|
||||
}),
|
||||
},
|
||||
watch: {
|
||||
// rdbEnrgUsage(){
|
||||
// this.getEnrgUsage();
|
||||
// },
|
||||
energyCd() {
|
||||
this.getEnrgUsage();
|
||||
this.getChartData();
|
||||
},
|
||||
},
|
||||
beforeCreate() {
|
||||
this.$store.commit('setWidgetPageData', {
|
||||
prgmId: this.$route.query.prgmId,
|
||||
EnrgUseRsltWidget: { EnrgUseRsltWidgetData },
|
||||
});
|
||||
},
|
||||
async created() {
|
||||
this.energyList = await this.postApiReturn({
|
||||
apiKey: 'selectEnergy',
|
||||
resKey: 'energyData',
|
||||
sendParam: {
|
||||
useFg: 1,
|
||||
},
|
||||
});
|
||||
|
||||
this.energyList.filter(item => {
|
||||
if (item.readObjCd == 'ELEC') {
|
||||
//전력
|
||||
this.energyCd = item.cd;
|
||||
this.unit = item.unit;
|
||||
}
|
||||
});
|
||||
|
||||
this.search();
|
||||
this.timer = setInterval(this.search, this.widgetReflashMm);
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.clearTimeout(this.timer);
|
||||
},
|
||||
mounted() {},
|
||||
data() {
|
||||
return {
|
||||
// blocNm:'',
|
||||
//바인딩
|
||||
energyCd: '',
|
||||
energyList: [],
|
||||
unit: '',
|
||||
currHour: Utility.setFormatDate(new Date(), 'H') + '시 기준',
|
||||
isUseQtyStat: true,
|
||||
isUseCostStat: true,
|
||||
dayUseQty: 0,
|
||||
compareUseQty: 0,
|
||||
useQtyStat: null,
|
||||
dayUseCost: 0,
|
||||
compareUseCost: 0,
|
||||
useCostStat: null,
|
||||
// 차트
|
||||
chart_01: 'enrgUsageChart',
|
||||
loadChart_01: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
...mapMutations({
|
||||
setPageData: 'setPageData',
|
||||
setWidgetChartOption: 'setWidgetChartOption',
|
||||
openDashboardWidget: 'openDashboardWidget',
|
||||
setWidgetChartYaxisData: 'setWidgetChartYaxisData',
|
||||
}),
|
||||
...mapActions({
|
||||
postApi: 'modules/list/postApi',
|
||||
postApiReturn: 'modules/list/postApiReturn',
|
||||
getEnergyList: 'modules/search/getEnergyList',
|
||||
}),
|
||||
async search() {
|
||||
// this.setBlocNm();
|
||||
await this.getEnrgUsage();
|
||||
await this.getChartData();
|
||||
},
|
||||
async getEnrgUsage() {
|
||||
const res = await this.postApiReturn({
|
||||
apiKey: 'selectUseCostDay',
|
||||
resKey: 'dayUseCostData',
|
||||
sendParam: {
|
||||
readObjId: this.energyCd,
|
||||
},
|
||||
});
|
||||
const res2 = await this.postApiReturn({
|
||||
apiKey: 'selectUseCostPast',
|
||||
resKey: 'pastUseCostData',
|
||||
sendParam: {
|
||||
readObjId: this.energyCd,
|
||||
},
|
||||
});
|
||||
res.forEach((item, idx) => {
|
||||
this.dayUseQty = Utility.setFormatInt(item.qty);
|
||||
this.dayUseCost = Utility.setFormatInt(item.cost);
|
||||
});
|
||||
let dayUseQty,
|
||||
dayUseQtyAvg,
|
||||
dayUseCost,
|
||||
dayUseCostAvg,
|
||||
dayUseMaxQty,
|
||||
dayUseMaxCost = 0;
|
||||
if (res.length > 0) {
|
||||
dayUseQty = res[0].qty;
|
||||
dayUseCost = res[0].cost;
|
||||
}
|
||||
if (res2.length > 0) {
|
||||
dayUseQtyAvg = res2[0].qtyAvg;
|
||||
dayUseCostAvg = res2[0].costAvg;
|
||||
dayUseMaxQty = res2[0].maxQty;
|
||||
dayUseMaxCost = res2[0].maxCost;
|
||||
}
|
||||
this.compareUseQty = Utility.setFormatInt(dayUseQty - dayUseQtyAvg);
|
||||
this.compareUseCost = Utility.setFormatInt(dayUseCost - dayUseCostAvg);
|
||||
this.useQtyStat =
|
||||
dayUseQty > dayUseQtyAvg ? 'mdi-arrow-up' : 'mdi-arrow-down';
|
||||
this.useCostStat =
|
||||
dayUseCost > dayUseCostAvg ? 'mdi-arrow-up' : 'mdi-arrow-down';
|
||||
|
||||
this.isUseQtyStat = this.useQtyStat == 'mdi-arrow-up' ? true : false;
|
||||
this.isUseCostStat = this.useCostStat == 'mdi-arrow-up' ? true : false;
|
||||
},
|
||||
setChartData(data, markAreaData) {
|
||||
let xAxisData = [];
|
||||
let seriesData = [];
|
||||
let legendData = [];
|
||||
let arrDarkColors = ['rgba(1, 174, 106, 0.7)', 'rgba(67, 133, 227, 0.7)'];
|
||||
let arrLightColors = [
|
||||
'rgba(207, 116, 229, 0.7)',
|
||||
'rgba(106, 155, 244, 0.7)',
|
||||
];
|
||||
const arrColors = this.isDarkMode ? arrDarkColors : arrLightColors;
|
||||
// chart x축 data
|
||||
var qtyNumber, qtyStr;
|
||||
for (var i = 0; i < 24; i++) {
|
||||
qtyNumber = i.toString().padStart(2, '0');
|
||||
qtyStr = 'qty' + qtyNumber;
|
||||
xAxisData.push(i + '시');
|
||||
}
|
||||
// chart_data 중 누적 사용량과 누적 금액 구분
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var tempObj = { data: [] };
|
||||
tempObj['type'] = 'line';
|
||||
tempObj['lineStyle'] = { width: 2 };
|
||||
tempObj['smooth'] = true;
|
||||
tempObj['showSymbol'] = false;
|
||||
tempObj['color'] = arrColors[i];
|
||||
if (data[i]['type'] == 'use') {
|
||||
tempObj['name'] = '누적 사용량';
|
||||
legendData.push('누적 사용량');
|
||||
tempObj['areaStyle'] = {
|
||||
opacity: 0.5,
|
||||
color: arrColors[i],
|
||||
};
|
||||
tempObj['yAxisIndex'] = 0;
|
||||
tempObj['markArea'] = { data: markAreaData };
|
||||
} else if (data[i]['type'] == 'cost') {
|
||||
tempObj['name'] = '누적 금액';
|
||||
legendData.push('누적 금액');
|
||||
tempObj['yAxisIndex'] = 1;
|
||||
} else if (data[i]['type'] == 'week') {
|
||||
tempObj['name'] = '전주 평균 누적 사용량';
|
||||
legendData.push('전주 평균 누적 사용량');
|
||||
tempObj['yAxisIndex'] = 0;
|
||||
}
|
||||
// 0~23시 까지의 데이터 seriesData 넣기
|
||||
for (var j = 0; j < 24; j++) {
|
||||
qtyNumber = j.toString().padStart(2, '0');
|
||||
qtyStr = 'qty' + qtyNumber;
|
||||
if (data[i].hasOwnProperty(qtyStr)) {
|
||||
// tempObj['data'].push(Utility.setFormatIntDecimal(parseFloat(data[i][qtyStr]), 2).replace(',',''));
|
||||
tempObj['data'].push(parseFloat(data[i][qtyStr]));
|
||||
} else {
|
||||
tempObj['data'].push(0);
|
||||
}
|
||||
}
|
||||
seriesData.push(tempObj);
|
||||
}
|
||||
|
||||
const yAxisData = [
|
||||
{
|
||||
type: 'value',
|
||||
name: this.unit,
|
||||
splitLine: {
|
||||
show: false,
|
||||
},
|
||||
nameTextStyle: {
|
||||
fontSize: 12,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#767D83',
|
||||
fontSize: 9,
|
||||
formatter: '{value}',
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'value',
|
||||
name: '원',
|
||||
splitLine: {
|
||||
show: false,
|
||||
},
|
||||
nameTextStyle: {
|
||||
fontSize: 12,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#767D83',
|
||||
fontSize: 9,
|
||||
formatter: '{value}',
|
||||
},
|
||||
},
|
||||
];
|
||||
var chartOption = {
|
||||
series: seriesData,
|
||||
grid: {
|
||||
left: '1%',
|
||||
right: '2%',
|
||||
top: '20%',
|
||||
bottom: '15%',
|
||||
containLabel: true,
|
||||
},
|
||||
legend: {
|
||||
data: legendData,
|
||||
bottom: 'bottom',
|
||||
icon: 'bar',
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
//boundaryGap: false,
|
||||
splitLine: false,
|
||||
data: xAxisData,
|
||||
axisLabel: {
|
||||
fontSize: 9,
|
||||
},
|
||||
},
|
||||
// yAxis: [
|
||||
// {
|
||||
// type: 'value',
|
||||
// name: this.unit,
|
||||
// splitLine: {
|
||||
// show: false
|
||||
// },
|
||||
// nameTextStyle: {
|
||||
// fontSize: 12,
|
||||
// fontWeight:'bold'
|
||||
// },
|
||||
// axisLabel:{
|
||||
// color: "#767D83",
|
||||
// fontSize: 9,
|
||||
// formatter: '{value}'
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// type: 'value',
|
||||
// name: '원',
|
||||
// splitLine: {
|
||||
// show: false
|
||||
// },
|
||||
// nameTextStyle: {
|
||||
// fontSize: 12,
|
||||
// fontWeight:'bold'
|
||||
// },
|
||||
// axisLabel:{
|
||||
// color: "#767D83",
|
||||
// fontSize: 9,
|
||||
// formatter: '{value}'
|
||||
// }
|
||||
// }
|
||||
// ],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
},
|
||||
};
|
||||
|
||||
this.setWidgetChartOption({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetKey: 'EnrgUseRsltWidget',
|
||||
widgetData: 'EnrgUseRsltWidgetData',
|
||||
chartKey: 'enrgUsageChart',
|
||||
value: chartOption,
|
||||
});
|
||||
this.setWidgetChartYaxisData({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetKey: 'EnrgUseRsltWidget',
|
||||
widgetData: 'EnrgUseRsltWidgetData',
|
||||
chartKey: 'enrgUsageChart',
|
||||
value: yAxisData,
|
||||
});
|
||||
this.loadChart_01 = true;
|
||||
},
|
||||
async getChartData() {
|
||||
this.loadChart_01 = false;
|
||||
var root_info = null;
|
||||
var res_useage = null;
|
||||
var res_cost = null;
|
||||
var facList = null;
|
||||
var filtered_res = null;
|
||||
var apiParameters = {
|
||||
blocId: 'BL0001',
|
||||
readObjId: this.energyCd,
|
||||
locKind: '',
|
||||
upEccId: '',
|
||||
};
|
||||
var sendParam_chart_data = {
|
||||
blocId: 'BL0001',
|
||||
eccId: [],
|
||||
eccNm: [],
|
||||
fromObjDt: Utility.setFormatDate(new Date(), 'YYYYMMDD'),
|
||||
lockKind: '',
|
||||
readObjId: this.energyCd,
|
||||
toObjDt: Utility.setFormatDate(new Date(), 'YYYYMMDD'),
|
||||
upEccId: '',
|
||||
};
|
||||
var check_flag = true;
|
||||
// 공정/설비 트리리스트 중 에너지원에 따른 최상위 정보 가져오기
|
||||
try {
|
||||
root_info = await this.postApiReturn({
|
||||
apiKey: 'selectFtnPlcListTree',
|
||||
resKey: 'ftnPlcTreeDatas',
|
||||
sendParam: {
|
||||
blocId: 'BL0001',
|
||||
roiId: this.energyCd,
|
||||
eqpmYn: 1,
|
||||
// search:this.searchWord
|
||||
},
|
||||
});
|
||||
filtered_res = root_info.filter(item => item.upEccId == 'ROOT');
|
||||
apiParameters['locKind'] = filtered_res[0].locKind;
|
||||
apiParameters['upEccId'] = filtered_res[0].eccId;
|
||||
sendParam_chart_data['lockKind'] = filtered_res[0].locKind;
|
||||
} catch (error) {
|
||||
root_info = [];
|
||||
filtered_res = [];
|
||||
}
|
||||
|
||||
// 위의 정보로 해당 검침개소 정보 가져오기
|
||||
try {
|
||||
facList = await this.postApiReturn({
|
||||
apiKey: 'selectEnergyUseReadDnPlc',
|
||||
resKey: 'energyUseReadDnPlc',
|
||||
sendParam: apiParameters,
|
||||
});
|
||||
for (var i in facList) {
|
||||
sendParam_chart_data['eccId'].push(facList[i]['eccId']);
|
||||
sendParam_chart_data['eccNm'].push(facList[i]['eccNm']);
|
||||
}
|
||||
// sendParam_chart_data['eccId'].push(facList[0]['eccId']);
|
||||
// sendParam_chart_data['eccNm'].push(facList[0]['eccNm']);
|
||||
sendParam_chart_data['upEccId'] = facList[0]['upEccId'];
|
||||
} catch (error) {
|
||||
check_flag = false;
|
||||
}
|
||||
|
||||
// 위의 정보로 검침개소 시간별 사용량 가져오기
|
||||
var final_chart_data = [];
|
||||
if (check_flag) {
|
||||
try {
|
||||
res_useage = await this.postApiReturn({
|
||||
apiKey: 'selectEnergyUseReadHourAddup',
|
||||
resKey: 'energyUseRead',
|
||||
sendParam: sendParam_chart_data,
|
||||
});
|
||||
|
||||
// root 하위 개소들의 사용량을 sum 함(쿼리에서 SUM 안했을 경우 사용)
|
||||
// var sum_data = {};
|
||||
// for (var i in res_useage){
|
||||
// res_useage[i]['type'] = 'use'
|
||||
// for (var key in res_useage[i]){
|
||||
// if(key.includes('qty')){
|
||||
// if(sum_data[key] == undefined){
|
||||
// sum_data[key] = res_useage[i][key]
|
||||
// }else{
|
||||
// sum_data[key] += res_useage[i][key]
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// // final_chart_data.push(res_useage[i])
|
||||
// }
|
||||
// final_chart_data.push({'type' : 'use', ...sum_data})
|
||||
|
||||
// root 하위 개소들의 사용량을 sum 함(쿼리에서 SUM을 했을 경우 사용)
|
||||
|
||||
res_useage[0]['type'] = 'use';
|
||||
final_chart_data.push(res_useage[0]);
|
||||
} catch (error) {
|
||||
res_useage = [];
|
||||
}
|
||||
|
||||
try {
|
||||
res_cost = await this.postApiReturn({
|
||||
apiKey: 'selectEnergyUseReadHourCostAddup',
|
||||
resKey: 'energyUseRead',
|
||||
sendParam: sendParam_chart_data,
|
||||
});
|
||||
res_cost[0]['type'] = 'cost';
|
||||
final_chart_data.push(res_cost[0]);
|
||||
} catch (error) {
|
||||
res_cost = [];
|
||||
}
|
||||
} else {
|
||||
res_useage = [];
|
||||
res_cost = [];
|
||||
}
|
||||
// 전주 평균 누적 사용량
|
||||
let res_week_read = [];
|
||||
res_week_read = await this.postApiReturn({
|
||||
apiKey: 'selectEnergyUseReadLastWeekAddup',
|
||||
resKey: 'energyUseRead',
|
||||
sendParam: sendParam_chart_data,
|
||||
});
|
||||
if (res_week_read.length != 0) {
|
||||
res_week_read[0]['type'] = 'week';
|
||||
final_chart_data.push(res_week_read[0]);
|
||||
}
|
||||
let res3 = [];
|
||||
let markAreaData = [];
|
||||
let markColor = {
|
||||
MAX: 'rgba(238, 102, 102, 0.1)',
|
||||
MID: 'rgba(250, 200, 88, 0.1)',
|
||||
MIN: 'rgba(145, 204, 117, 0.1)',
|
||||
};
|
||||
res3 = await this.postApiReturn({
|
||||
apiKey: 'selectPeakKine',
|
||||
resKey: 'peakData',
|
||||
sendParam: {
|
||||
readObjId: this.energyCd,
|
||||
toObjDt: Utility.setFormatDate(new Date(), 'YYYYMMDD'),
|
||||
},
|
||||
});
|
||||
markAreaData = res3.map(item => [
|
||||
{
|
||||
name: item.commCdNm,
|
||||
xAxis:
|
||||
parseInt(item.strtTm.split(':')[0].replace(/(^0+)/, '')) == 23
|
||||
? 0
|
||||
: parseInt(item.strtTm.split(':')[0].replace(/(^0+)/, '')),
|
||||
itemStyle: {
|
||||
color: markColor[item.peakKine],
|
||||
},
|
||||
label: {
|
||||
distance: [0],
|
||||
fontSize: 9,
|
||||
fontWeight: 'lighter',
|
||||
color: '#fff',
|
||||
},
|
||||
},
|
||||
{
|
||||
xAxis: parseInt(item.endTm.split(':')[0].replace(/(^0+)/, '')),
|
||||
},
|
||||
]);
|
||||
|
||||
// char data 넣기
|
||||
this.$nextTick(() => {
|
||||
this.setChartData(final_chart_data, markAreaData);
|
||||
});
|
||||
},
|
||||
btnAction(action) {
|
||||
switch (action) {
|
||||
case 'popWidget':
|
||||
this.openDashboardWidget({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetId: this.widgetId,
|
||||
});
|
||||
break;
|
||||
case 'widgetCallPage':
|
||||
this.$parent.$parent.$parent.openWidgetPrgm(this.widgetId);
|
||||
break;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const EnrgUseRsltWidgetData = {
|
||||
isFind: false,
|
||||
enrgUsageChart: Utility.defaultChartOption(true),
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.v-avatar {
|
||||
border-radius: 21px;
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
.v-virtual-scroll-wrapper {
|
||||
overflow-y: auto;
|
||||
max-height: 210px;
|
||||
}
|
||||
.v-radio > label {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
.v-list-item {
|
||||
min-height: 30px;
|
||||
line-height: 1;
|
||||
}
|
||||
.v-list-item__content > * {
|
||||
line-height: 1;
|
||||
}
|
||||
.v-select__widget > .v-input__control > .v-input__slot {
|
||||
min-width: 60%;
|
||||
}
|
||||
.wrapper {
|
||||
padding: 5px 10px 0px 10px !important;
|
||||
border-bottom: thin solid rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
</style>
|
488
components/widget/EnrgUseReptWidget.vue
Normal file
488
components/widget/EnrgUseReptWidget.vue
Normal file
@ -0,0 +1,488 @@
|
||||
<template>
|
||||
<div class="l-layout">
|
||||
<v-row ref="rowParent">
|
||||
<v-col :cols="12">
|
||||
<v-card class="pa-3 widget-card">
|
||||
<div class="d-flex align-center justify-space-between">
|
||||
<v-card-title class="pa-0">에너지 사용현황</v-card-title>
|
||||
<v-card-subtitle class="mt-0 pa-0">
|
||||
<v-icon
|
||||
v-show="widgetPrgmId"
|
||||
class="mr-1"
|
||||
size="25"
|
||||
@click="btnAction('widgetCallPage')"
|
||||
>mdi-note-search</v-icon
|
||||
>
|
||||
<v-icon
|
||||
v-show="widgetPopFg"
|
||||
size="25"
|
||||
@click="btnAction('popWidget')"
|
||||
>mdi-plus-box-multiple</v-icon
|
||||
>
|
||||
</v-card-subtitle>
|
||||
</div>
|
||||
<v-card-actions class="d-flex justify-sm-end pb-0 pr-0 pt-1">
|
||||
<v-row>
|
||||
<v-col cols="3" sm="3" md="4" lg="6"></v-col>
|
||||
<v-col
|
||||
cols="6"
|
||||
sm="6"
|
||||
md="5"
|
||||
lg="4"
|
||||
class="d-flex align-center justify-end"
|
||||
>
|
||||
<v-radio-group
|
||||
v-model="rdbEnrgUsage"
|
||||
hide-details
|
||||
dense
|
||||
row
|
||||
class="mt-0"
|
||||
style="float:right"
|
||||
>
|
||||
<v-radio
|
||||
label="금일"
|
||||
value="hour"
|
||||
:color="isDarkMode ? '#2d8cf6' : '#4777d9'"
|
||||
on-icon="mdi-record-circle"
|
||||
:ripple="false"
|
||||
></v-radio>
|
||||
<v-radio
|
||||
label="금월"
|
||||
value="month"
|
||||
:color="isDarkMode ? '#2d8cf6' : '#4777d9'"
|
||||
on-icon="mdi-record-circle"
|
||||
:ripple="false"
|
||||
></v-radio>
|
||||
</v-radio-group>
|
||||
</v-col>
|
||||
<v-col cols="3" sm="3" md="3" lg="2">
|
||||
<v-select
|
||||
v-model="selectValue"
|
||||
:items="this.energyList"
|
||||
item-text="enrgNm"
|
||||
item-value="cd"
|
||||
solo
|
||||
outlined
|
||||
:hide-details="true"
|
||||
append-icon="mdi-chevron-down"
|
||||
class="v-select__widget pr-2"
|
||||
></v-select>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-actions>
|
||||
<div class="d-flex align-center justify-space-between">
|
||||
<div :style="{ width: '100%', height: '200px' }">
|
||||
<component
|
||||
class="w100 h100"
|
||||
:is="loadChart_01 ? 'Chart' : null"
|
||||
:parentPrgmId="parentPrgmId"
|
||||
:widgetId="'EnrgUseReptWidget'"
|
||||
:widgetData="'EnrgUseReptWidgetData'"
|
||||
:chartName="chart_01"
|
||||
ref="chart_01"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions, mapMutations, mapState } from 'vuex'; // , mapActions
|
||||
import Vue from 'vue';
|
||||
import DateUtility from '~/plugins/dateUtility';
|
||||
import Utility from '~/plugins/utility';
|
||||
import Chart from '~/components/common/Chart';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
parentPrgmId: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
widgetId: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
widgetPrgmId: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
widgetPopFg: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
widgetReflashMm: {
|
||||
type: Number,
|
||||
require: true,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
DateUtility,
|
||||
Chart,
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
searchParam(state) {
|
||||
return state.pageData[this.parentPrgmId];
|
||||
},
|
||||
isDarkMode: 'isDarkMode',
|
||||
}),
|
||||
selectValue: {
|
||||
get() {
|
||||
return this.energyCd;
|
||||
},
|
||||
set(value) {
|
||||
this.energyCd = value;
|
||||
},
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
rdbEnrgUsage() {
|
||||
this.getEnrgUsage();
|
||||
},
|
||||
energyCd() {
|
||||
this.setUnitLabel();
|
||||
this.getEnrgUsage();
|
||||
},
|
||||
},
|
||||
beforeCreate() {
|
||||
this.$store.commit('setWidgetPageData', {
|
||||
prgmId: this.$route.query.prgmId,
|
||||
EnrgUseReptWidget: { EnrgUseReptWidgetData },
|
||||
});
|
||||
},
|
||||
async created() {
|
||||
this.energyList = await this.postApiReturn({
|
||||
apiKey: 'selectEnergy',
|
||||
resKey: 'energyData',
|
||||
sendParam: {
|
||||
useFg: 1,
|
||||
},
|
||||
});
|
||||
this.energyCd = this.energyList[0].cd;
|
||||
this.unit = this.energyList[0].unit;
|
||||
this.search();
|
||||
this.timer = setInterval(this.search, this.widgetReflashMm);
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.clearTimeout(this.timer);
|
||||
},
|
||||
mounted() {},
|
||||
data() {
|
||||
return {
|
||||
blocNm: '',
|
||||
//차트
|
||||
chart_01: 'enrgUsage',
|
||||
loadChart_01: false,
|
||||
//바인딩
|
||||
rdbEnrgUsage: 'hour',
|
||||
rdbElecQual: 'Kw',
|
||||
energyCd: '',
|
||||
energyList: [],
|
||||
unit: '',
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
...mapMutations({
|
||||
setPageData: 'setPageData',
|
||||
setWidgetChartOption: 'setWidgetChartOption',
|
||||
openDashboardWidget: 'openDashboardWidget',
|
||||
}),
|
||||
...mapActions({
|
||||
postApi: 'modules/list/postApi',
|
||||
postApiReturn: 'modules/list/postApiReturn',
|
||||
getEnergyList: 'modules/search/getEnergyList',
|
||||
}),
|
||||
setBlocNm() {
|
||||
this.blocNm = this.$store.state.userInfo.blocNm;
|
||||
if (this.blocNm != '') {
|
||||
this.blocNm = '[' + this.blocNm + ']';
|
||||
}
|
||||
},
|
||||
setUnitLabel() {
|
||||
this.energyList.filter(item => {
|
||||
if (item.cd == this.energyCd) {
|
||||
this.unit = item.unit;
|
||||
}
|
||||
});
|
||||
},
|
||||
async search() {
|
||||
this.setBlocNm();
|
||||
await this.getEnrgUsage();
|
||||
},
|
||||
async getEnrgUsage() {
|
||||
this.loadChart_01 = false;
|
||||
let paramApiKey = '';
|
||||
let markAreaData = [];
|
||||
let markColor = {
|
||||
MAX: 'rgba(238, 102, 102, 0.1)',
|
||||
MID: 'rgba(250, 200, 88, 0.1)',
|
||||
MIN: 'rgba(145, 204, 117, 0.1)',
|
||||
};
|
||||
if (this.rdbEnrgUsage == 'hour') {
|
||||
paramApiKey = 'selectEnrgUsageHour';
|
||||
if (this.energyCd == 'ROI000001') {
|
||||
let res3 = [];
|
||||
|
||||
// 부하시간 가져오기
|
||||
res3 = await this.postApiReturn({
|
||||
apiKey: 'selectPeakKine',
|
||||
resKey: 'peakData',
|
||||
sendParam: {
|
||||
readObjId: this.energyCd,
|
||||
toObjDt: Utility.setFormatDate(new Date(), 'YYYYMMDD'),
|
||||
},
|
||||
});
|
||||
markAreaData = res3.map(item => [
|
||||
{
|
||||
name: item.commCdNm,
|
||||
xAxis:
|
||||
parseInt(item.strtTm.split(':')[0].replace(/(^0+)/, '')) == 23
|
||||
? 0
|
||||
: parseInt(item.strtTm.split(':')[0].replace(/(^0+)/, '')),
|
||||
itemStyle: {
|
||||
color: markColor[item.peakKine],
|
||||
},
|
||||
label: {
|
||||
distance: [0],
|
||||
fontSize: 9,
|
||||
color: '#fff',
|
||||
},
|
||||
},
|
||||
{
|
||||
xAxis: parseInt(item.endTm.split(':')[0].replace(/(^0+)/, '')),
|
||||
},
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
paramApiKey = 'selectEnrgUsageMonth';
|
||||
}
|
||||
|
||||
let res = await this.postApiReturn({
|
||||
apiKey: paramApiKey,
|
||||
resKey: 'enrgUsageData',
|
||||
sendParam: {
|
||||
readObjId: this.energyCd,
|
||||
},
|
||||
});
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.setChart01Data(res, markAreaData);
|
||||
});
|
||||
},
|
||||
|
||||
//차트Setting
|
||||
async setChart01Data(data, markAreaData) {
|
||||
this.$store.state.pageData[
|
||||
this.parentPrgmId
|
||||
].EnrgUseReptWidget.EnrgUseReptWidgetData.series = [];
|
||||
if (!data.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
let xAxisData = [];
|
||||
let seriesData = [];
|
||||
let legendData = [];
|
||||
let arrDarkColors = ['rgba(1, 174, 106, 0.7)', 'rgba(67, 133, 227, 0.7)'];
|
||||
let arrLightColors = [
|
||||
'rgba(207, 116, 229, 0.7)',
|
||||
'rgba(106, 155, 244, 0.7)',
|
||||
];
|
||||
const arrColors = this.isDarkMode ? arrDarkColors : arrLightColors;
|
||||
|
||||
if (this.rdbEnrgUsage == 'month') {
|
||||
var qtyNumber, qtyStr;
|
||||
for (var i = 1; i < 32; i++) {
|
||||
qtyNumber = i.toString().padStart(2, '0');
|
||||
qtyStr = 'qty' + qtyNumber;
|
||||
xAxisData.push(i + '일');
|
||||
}
|
||||
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var tempObj = {};
|
||||
tempObj['name'] = data[i]['type'];
|
||||
if (data[i]['type'] == '금월 사용량') {
|
||||
tempObj['type'] = 'bar';
|
||||
} else {
|
||||
tempObj['type'] = 'line';
|
||||
}
|
||||
tempObj['data'] = [];
|
||||
tempObj['color'] = arrColors[i];
|
||||
tempObj['lineStyle'] = { width: 2 };
|
||||
// tempObj['areaStyle'] = {
|
||||
// opacity: 0.5,
|
||||
// color: arrColors[i]
|
||||
// };
|
||||
tempObj['smooth'] = true;
|
||||
tempObj['showSymbol'] = false;
|
||||
|
||||
legendData.push(data[i]['type']);
|
||||
|
||||
for (var j = 0; j < 31; j++) {
|
||||
qtyNumber = (j + 1).toString().padStart(2, '0');
|
||||
qtyStr = 'qty' + qtyNumber;
|
||||
if (data[i].hasOwnProperty(qtyStr)) {
|
||||
tempObj['data'].push(
|
||||
parseFloat(
|
||||
Utility.setFormatIntDecimal(
|
||||
parseFloat(data[i][qtyStr]),
|
||||
2,
|
||||
).replace(',', ''),
|
||||
),
|
||||
);
|
||||
// tempObj['data'].push(parseFloat(data[i][qtyStr]));
|
||||
} else {
|
||||
tempObj['data'].push(0);
|
||||
}
|
||||
}
|
||||
seriesData.push(tempObj);
|
||||
}
|
||||
} else if (this.rdbEnrgUsage == 'hour') {
|
||||
var qtyNumber, qtyStr;
|
||||
for (var i = 0; i < 24; i++) {
|
||||
qtyNumber = i.toString().padStart(2, '0');
|
||||
qtyStr = 'qty' + qtyNumber;
|
||||
xAxisData.push(i + '시');
|
||||
}
|
||||
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var tempObj = {};
|
||||
tempObj['name'] = data[i]['type'];
|
||||
if (data[i]['type'] == '금일 사용량') {
|
||||
tempObj['type'] = 'bar';
|
||||
} else {
|
||||
tempObj['type'] = 'line';
|
||||
}
|
||||
tempObj['data'] = [];
|
||||
tempObj['color'] = arrColors[i];
|
||||
tempObj['lineStyle'] = { width: 2 };
|
||||
if (markAreaData != null) {
|
||||
tempObj['markArea'] = {
|
||||
data: markAreaData,
|
||||
};
|
||||
}
|
||||
// tempObj['areaStyle'] = {
|
||||
// opacity: 0.5,
|
||||
// color: arrColors[i]
|
||||
// };
|
||||
tempObj['smooth'] = true;
|
||||
tempObj['showSymbol'] = false;
|
||||
legendData.push(data[i]['type']);
|
||||
|
||||
for (var j = 0; j < 24; j++) {
|
||||
qtyNumber = j.toString().padStart(2, '0');
|
||||
qtyStr = 'qty' + qtyNumber;
|
||||
if (data[i].hasOwnProperty(qtyStr)) {
|
||||
tempObj['data'].push(
|
||||
Utility.setFormatIntDecimal(
|
||||
parseFloat(data[i][qtyStr]),
|
||||
2,
|
||||
).replace(',', ''),
|
||||
);
|
||||
// tempObj['data'].push(parseFloat(data[i][qtyStr]));
|
||||
} else {
|
||||
tempObj['data'].push(0);
|
||||
}
|
||||
}
|
||||
//console.log("data : " ,tempObj);
|
||||
seriesData.push(tempObj);
|
||||
}
|
||||
}
|
||||
|
||||
var chartOption = {
|
||||
series: seriesData,
|
||||
grid: {
|
||||
left: '1%',
|
||||
right: '2%',
|
||||
top: '15%',
|
||||
bottom: '15%',
|
||||
containLabel: true,
|
||||
},
|
||||
legend: {
|
||||
data: legendData,
|
||||
bottom: 'bottom',
|
||||
icon: 'bar',
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
//boundaryGap: false,
|
||||
splitLine: false,
|
||||
data: xAxisData,
|
||||
axisLabel: {
|
||||
fontSize: 9,
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
name: this.unit,
|
||||
splitLine: false,
|
||||
nameTextStyle: {
|
||||
fontSize: 12,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#767D83',
|
||||
fontSize: 9,
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
},
|
||||
};
|
||||
|
||||
this.setWidgetChartOption({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetKey: 'EnrgUseReptWidget',
|
||||
widgetData: 'EnrgUseReptWidgetData',
|
||||
chartKey: 'enrgUsage',
|
||||
value: chartOption,
|
||||
});
|
||||
|
||||
this.loadChart_01 = true;
|
||||
},
|
||||
btnAction(action) {
|
||||
switch (action) {
|
||||
case 'popWidget':
|
||||
this.openDashboardWidget({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetId: this.widgetId,
|
||||
});
|
||||
break;
|
||||
case 'widgetCallPage':
|
||||
this.$parent.$parent.$parent.openWidgetPrgm(this.widgetId);
|
||||
break;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
const EnrgUseReptWidgetData = {
|
||||
enrgUsage: Utility.defaultChartOption(true),
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.v-avatar {
|
||||
border-radius: 21px;
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
.v-virtual-scroll-wrapper {
|
||||
overflow-y: auto;
|
||||
max-height: 210px;
|
||||
}
|
||||
.v-radio > label {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
.v-list-item {
|
||||
min-height: 30px;
|
||||
line-height: 1;
|
||||
}
|
||||
.v-list-item__content > * {
|
||||
line-height: 1;
|
||||
}
|
||||
.v-select__widget > .v-input__control > .v-input__slot {
|
||||
min-width: 60%;
|
||||
}
|
||||
</style>
|
725
components/widget/EnrgUseRsltWidget.vue
Normal file
725
components/widget/EnrgUseRsltWidget.vue
Normal file
@ -0,0 +1,725 @@
|
||||
<template>
|
||||
<div class="l-layout">
|
||||
<v-row ref="rowParent">
|
||||
<v-col :cols="12">
|
||||
<v-card class="pa-3 widget-card">
|
||||
<div class="d-flex align-center justify-space-between">
|
||||
<v-card-title class="pa-0">사용량 실적</v-card-title>
|
||||
<v-card-subtitle class="mt-0 pa-0 text-right">
|
||||
<v-icon
|
||||
v-show="widgetPrgmId"
|
||||
class="mr-1"
|
||||
size="25"
|
||||
@click="btnAction('widgetCallPage')"
|
||||
>mdi-note-search</v-icon
|
||||
>
|
||||
<v-icon
|
||||
v-show="widgetPopFg"
|
||||
size="25"
|
||||
@click="btnAction('popWidget')"
|
||||
>mdi-plus-box-multiple</v-icon
|
||||
>
|
||||
</v-card-subtitle>
|
||||
</div>
|
||||
<v-card-actions class="d-flex justify-sm-end pb-0 pr-0 pt-1">
|
||||
<v-row>
|
||||
<v-col cols="9" sm="9" md="9" lg="10"></v-col>
|
||||
<v-col cols="3" sm="3" md="3" lg="2">
|
||||
<v-select
|
||||
v-model="selectValue"
|
||||
:items="this.energyList"
|
||||
item-text="enrgNm"
|
||||
item-value="cd"
|
||||
solo
|
||||
outlined
|
||||
:hide-details="true"
|
||||
append-icon="mdi-chevron-down"
|
||||
class="v-select__widget"
|
||||
></v-select>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-actions>
|
||||
<div class="row wrapper">
|
||||
<div class="col-6">
|
||||
<div class="px-5 pb-1">
|
||||
<div class="text-center">
|
||||
<strong class="custom-title-2-5"
|
||||
>{{ dayUseQty }}
|
||||
<span class="font-weight-regular custom-text-2"
|
||||
>kWh</span
|
||||
></strong
|
||||
>
|
||||
<div class="d-flex align-center justify-center">
|
||||
<span class="body-2 text-color--non-activate"
|
||||
>전주 대비({{ currHour }})</span
|
||||
>
|
||||
<div
|
||||
class="d-flex align-baseline ml-2"
|
||||
:style="{
|
||||
color: isDarkMode
|
||||
? isUseQtyStat
|
||||
? '#f6637b'
|
||||
: '#01ae6a'
|
||||
: isUseQtyStat
|
||||
? '#ff76bb'
|
||||
: '#00c875',
|
||||
}"
|
||||
>
|
||||
<strong class="mr-1 custom-text-1">{{
|
||||
compareUseQty
|
||||
}}</strong>
|
||||
<span class="caption mr-1">kWh</span>
|
||||
<v-icon
|
||||
small
|
||||
:color="
|
||||
isDarkMode
|
||||
? isUseQtyStat
|
||||
? '#f6637b'
|
||||
: '#01ae6a'
|
||||
: isUseQtyStat
|
||||
? '#ff76bb'
|
||||
: '#00c875'
|
||||
"
|
||||
>{{ useQtyStat }}</v-icon
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="px-5 pb-1">
|
||||
<div class="text-center">
|
||||
<strong class="custom-title-2-5"
|
||||
>{{ dayUseCost }}
|
||||
<span class="font-weight-regular custom-text-2"
|
||||
>천원</span
|
||||
></strong
|
||||
>
|
||||
<div class="d-flex align-center justify-center">
|
||||
<span class="body-2 text-color--non-activate"
|
||||
>전주 대비(0시-{{ currHour }})</span
|
||||
>
|
||||
<div
|
||||
class="d-flex align-baseline ml-2"
|
||||
:style="{
|
||||
color: isDarkMode
|
||||
? isUseCostStat
|
||||
? '#f6637b'
|
||||
: '#01ae6a'
|
||||
: isUseCostStat
|
||||
? '#ff76bb'
|
||||
: '#00c875',
|
||||
}"
|
||||
>
|
||||
<strong class="mr-1 custom-text-1">{{
|
||||
compareUseCost
|
||||
}}</strong>
|
||||
<span class="caption mr-1">천원</span>
|
||||
<v-icon
|
||||
small
|
||||
:color="
|
||||
isDarkMode
|
||||
? isUseCostStat
|
||||
? '#f6637b'
|
||||
: '#01ae6a'
|
||||
: isUseCostStat
|
||||
? '#ff76bb'
|
||||
: '#00c875'
|
||||
"
|
||||
>{{ useCostStat }}</v-icon
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex align-center justify-space-between mt-2">
|
||||
<div :style="{ width: '100%', height: '130px' }">
|
||||
<component
|
||||
class="w100 h100"
|
||||
:is="loadChart_01 ? 'Chart' : null"
|
||||
:parentPrgmId="parentPrgmId"
|
||||
:widgetId="'EnrgUseRsltWidget'"
|
||||
:widgetData="'EnrgUseRsltWidgetData'"
|
||||
:chartName="chart_01"
|
||||
ref="chart_01"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions, mapMutations, mapState } from 'vuex'; // , mapActions
|
||||
import Vue from 'vue';
|
||||
import DateUtility from '~/plugins/dateUtility';
|
||||
import Utility from '~/plugins/utility';
|
||||
import Chart from '~/components/common/Chart';
|
||||
export default {
|
||||
props: {
|
||||
parentPrgmId: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
widgetId: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
widgetPrgmId: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
widgetPopFg: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
widgetReflashMm: {
|
||||
type: Number,
|
||||
require: true,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
DateUtility,
|
||||
Chart,
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
searchParam(state) {
|
||||
return state.pageData[this.parentPrgmId];
|
||||
},
|
||||
isDarkMode: 'isDarkMode',
|
||||
}),
|
||||
selectValue: {
|
||||
get() {
|
||||
return this.energyCd;
|
||||
},
|
||||
set(value) {
|
||||
this.energyCd = value;
|
||||
},
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
// rdbEnrgUsage(){
|
||||
// this.getEnrgUsage();
|
||||
// },
|
||||
energyCd() {
|
||||
this.setUnitLabel();
|
||||
this.getEnrgUsage();
|
||||
this.getChartData();
|
||||
},
|
||||
},
|
||||
beforeCreate() {
|
||||
this.$store.commit('setWidgetPageData', {
|
||||
prgmId: this.$route.query.prgmId,
|
||||
EnrgUseRsltWidget: { EnrgUseRsltWidgetData },
|
||||
});
|
||||
},
|
||||
async created() {
|
||||
this.energyList = await this.postApiReturn({
|
||||
apiKey: 'selectEnergy',
|
||||
resKey: 'energyData',
|
||||
sendParam: {
|
||||
useFg: 1,
|
||||
},
|
||||
});
|
||||
this.energyCd = this.energyList[0].cd;
|
||||
this.unit = this.energyList[0].unit;
|
||||
this.search();
|
||||
this.timer = setInterval(this.search, this.widgetReflashMm);
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.clearTimeout(this.timer);
|
||||
},
|
||||
mounted() {},
|
||||
data() {
|
||||
return {
|
||||
// blocNm:'',
|
||||
//바인딩
|
||||
energyCd: '',
|
||||
energyList: [],
|
||||
unit: '',
|
||||
currHour: Utility.setFormatDate(new Date(), 'H') + '시 기준',
|
||||
isUseQtyStat: true,
|
||||
isUseCostStat: true,
|
||||
dayUseQty: 0,
|
||||
compareUseQty: 0,
|
||||
useQtyStat: null,
|
||||
dayUseCost: 0,
|
||||
compareUseCost: 0,
|
||||
useCostStat: null,
|
||||
// 차트
|
||||
chart_01: 'enrgUsageChart',
|
||||
loadChart_01: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
...mapMutations({
|
||||
setPageData: 'setPageData',
|
||||
setWidgetChartOption: 'setWidgetChartOption',
|
||||
openDashboardWidget: 'openDashboardWidget',
|
||||
setWidgetChartYaxisData: 'setWidgetChartYaxisData',
|
||||
}),
|
||||
...mapActions({
|
||||
postApi: 'modules/list/postApi',
|
||||
postApiReturn: 'modules/list/postApiReturn',
|
||||
getEnergyList: 'modules/search/getEnergyList',
|
||||
}),
|
||||
// setBlocNm(){
|
||||
// this.blocNm = this.$store.state.userInfo.blocNm;
|
||||
// if (this.blocNm != ''){
|
||||
// this.blocNm = '[' + this.blocNm + ']'
|
||||
// }
|
||||
// },
|
||||
setUnitLabel() {
|
||||
this.energyList.filter(item => {
|
||||
if (item.cd == this.energyCd) {
|
||||
this.unit = item.unit;
|
||||
}
|
||||
});
|
||||
},
|
||||
async search() {
|
||||
// this.setBlocNm();
|
||||
await this.getEnrgUsage();
|
||||
await this.getChartData();
|
||||
},
|
||||
async getEnrgUsage() {
|
||||
const res = await this.postApiReturn({
|
||||
apiKey: 'selectUseCostDay',
|
||||
resKey: 'dayUseCostData',
|
||||
sendParam: {
|
||||
readObjId: this.energyCd,
|
||||
},
|
||||
});
|
||||
const res2 = await this.postApiReturn({
|
||||
apiKey: 'selectUseCostPast',
|
||||
resKey: 'pastUseCostData',
|
||||
sendParam: {
|
||||
readObjId: this.energyCd,
|
||||
},
|
||||
});
|
||||
res.forEach((item, idx) => {
|
||||
this.dayUseQty = Utility.setFormatInt(item.qty);
|
||||
this.dayUseCost = Utility.setFormatInt(item.cost);
|
||||
});
|
||||
let dayUseQty,
|
||||
dayUseQtyAvg,
|
||||
dayUseCost,
|
||||
dayUseCostAvg,
|
||||
dayUseMaxQty,
|
||||
dayUseMaxCost = 0;
|
||||
if (res.length > 0) {
|
||||
dayUseQty = res[0].qty;
|
||||
dayUseCost = res[0].cost;
|
||||
}
|
||||
if (res2.length > 0) {
|
||||
dayUseQtyAvg = res2[0].qtyAvg;
|
||||
dayUseCostAvg = res2[0].costAvg;
|
||||
dayUseMaxQty = res2[0].maxQty;
|
||||
dayUseMaxCost = res2[0].maxCost;
|
||||
}
|
||||
this.compareUseQty = Utility.setFormatInt(dayUseQty - dayUseQtyAvg);
|
||||
this.compareUseCost = Utility.setFormatInt(dayUseCost - dayUseCostAvg);
|
||||
this.useQtyStat =
|
||||
dayUseQty > dayUseQtyAvg ? 'mdi-arrow-up' : 'mdi-arrow-down';
|
||||
this.useCostStat =
|
||||
dayUseCost > dayUseCostAvg ? 'mdi-arrow-up' : 'mdi-arrow-down';
|
||||
|
||||
this.isUseQtyStat = this.useQtyStat == 'mdi-arrow-up' ? true : false;
|
||||
this.isUseCostStat = this.useCostStat == 'mdi-arrow-up' ? true : false;
|
||||
},
|
||||
setChartData(data, markAreaData) {
|
||||
let xAxisData = [];
|
||||
let seriesData = [];
|
||||
let legendData = [];
|
||||
let arrDarkColors = ['rgba(1, 174, 106, 0.7)', 'rgba(67, 133, 227, 0.7)'];
|
||||
let arrLightColors = [
|
||||
'rgba(207, 116, 229, 0.7)',
|
||||
'rgba(106, 155, 244, 0.7)',
|
||||
];
|
||||
const arrColors = this.isDarkMode ? arrDarkColors : arrLightColors;
|
||||
// chart x축 data
|
||||
var qtyNumber, qtyStr;
|
||||
for (var i = 0; i < 24; i++) {
|
||||
qtyNumber = i.toString().padStart(2, '0');
|
||||
qtyStr = 'qty' + qtyNumber;
|
||||
xAxisData.push(i + '시');
|
||||
}
|
||||
// chart_data 중 누적 사용량과 누적 금액 구분
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var tempObj = { data: [] };
|
||||
tempObj['type'] = 'line';
|
||||
tempObj['lineStyle'] = { width: 2 };
|
||||
tempObj['smooth'] = true;
|
||||
tempObj['showSymbol'] = false;
|
||||
tempObj['color'] = arrColors[i];
|
||||
if (data[i]['type'] == 'use') {
|
||||
tempObj['name'] = '누적 사용량';
|
||||
legendData.push('누적 사용량');
|
||||
tempObj['areaStyle'] = {
|
||||
opacity: 0.5,
|
||||
color: arrColors[i],
|
||||
};
|
||||
tempObj['yAxisIndex'] = 0;
|
||||
// markAreaData 추가
|
||||
if (markAreaData.length > 0) {
|
||||
tempObj['markArea'] = { data: markAreaData };
|
||||
}
|
||||
} else if (data[i]['type'] == 'cost') {
|
||||
tempObj['name'] = '누적 금액';
|
||||
legendData.push('누적 금액');
|
||||
tempObj['yAxisIndex'] = 1;
|
||||
} else if (data[i]['type'] == 'week') {
|
||||
tempObj['name'] = '전주 평균 누적 사용량';
|
||||
legendData.push('전주 평균 누적 사용량');
|
||||
tempObj['yAxisIndex'] = 0;
|
||||
}
|
||||
// 0~23시 까지의 데이터 seriesData 넣기
|
||||
for (var j = 0; j < 24; j++) {
|
||||
qtyNumber = j.toString().padStart(2, '0');
|
||||
qtyStr = 'qty' + qtyNumber;
|
||||
if (data[i].hasOwnProperty(qtyStr)) {
|
||||
// tempObj['data'].push(Utility.setFormatIntDecimal(parseFloat(data[i][qtyStr]), 2).replace(',',''));
|
||||
tempObj['data'].push(parseFloat(data[i][qtyStr]));
|
||||
} else {
|
||||
tempObj['data'].push(0);
|
||||
}
|
||||
}
|
||||
seriesData.push(tempObj);
|
||||
}
|
||||
|
||||
const yAxisData = [
|
||||
{
|
||||
type: 'value',
|
||||
name: this.unit,
|
||||
splitLine: {
|
||||
show: false,
|
||||
},
|
||||
nameTextStyle: {
|
||||
fontSize: 12,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#767D83',
|
||||
fontSize: 9,
|
||||
formatter: '{value}',
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'value',
|
||||
name: '원',
|
||||
splitLine: {
|
||||
show: false,
|
||||
},
|
||||
nameTextStyle: {
|
||||
fontSize: 12,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#767D83',
|
||||
fontSize: 9,
|
||||
formatter: '{value}',
|
||||
},
|
||||
},
|
||||
];
|
||||
var chartOption = {
|
||||
series: seriesData,
|
||||
grid: {
|
||||
left: '1%',
|
||||
right: '2%',
|
||||
top: '23%',
|
||||
bottom: '15%',
|
||||
containLabel: true,
|
||||
},
|
||||
legend: {
|
||||
data: legendData,
|
||||
bottom: 'bottom',
|
||||
icon: 'bar',
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
//boundaryGap: false,
|
||||
splitLine: false,
|
||||
data: xAxisData,
|
||||
axisLabel: {
|
||||
fontSize: 9,
|
||||
},
|
||||
},
|
||||
// yAxis: [
|
||||
// {
|
||||
// type: 'value',
|
||||
// name: this.unit,
|
||||
// splitLine: {
|
||||
// show: false
|
||||
// },
|
||||
// nameTextStyle: {
|
||||
// fontSize: 12,
|
||||
// fontWeight:'bold'
|
||||
// },
|
||||
// axisLabel:{
|
||||
// color: "#767D83",
|
||||
// fontSize: 9,
|
||||
// formatter: '{value}'
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// type: 'value',
|
||||
// name: '원',
|
||||
// splitLine: {
|
||||
// show: false
|
||||
// },
|
||||
// nameTextStyle: {
|
||||
// fontSize: 12,
|
||||
// fontWeight:'bold'
|
||||
// },
|
||||
// axisLabel:{
|
||||
// color: "#767D83",
|
||||
// fontSize: 9,
|
||||
// formatter: '{value}'
|
||||
// }
|
||||
// }
|
||||
// ],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
},
|
||||
};
|
||||
|
||||
this.setWidgetChartOption({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetKey: 'EnrgUseRsltWidget',
|
||||
widgetData: 'EnrgUseRsltWidgetData',
|
||||
chartKey: 'enrgUsageChart',
|
||||
value: chartOption,
|
||||
});
|
||||
this.setWidgetChartYaxisData({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetKey: 'EnrgUseRsltWidget',
|
||||
widgetData: 'EnrgUseRsltWidgetData',
|
||||
chartKey: 'enrgUsageChart',
|
||||
value: yAxisData,
|
||||
});
|
||||
this.loadChart_01 = true;
|
||||
},
|
||||
async getChartData() {
|
||||
this.loadChart_01 = false;
|
||||
var root_info = null;
|
||||
var res_useage = null;
|
||||
var res_cost = null;
|
||||
var facList = null;
|
||||
var filtered_res = null;
|
||||
var apiParameters = {
|
||||
blocId: 'BL0001',
|
||||
readObjId: this.energyCd,
|
||||
locKind: '',
|
||||
upEccId: '',
|
||||
};
|
||||
var sendParam_chart_data = {
|
||||
blocId: 'BL0001',
|
||||
eccId: [],
|
||||
eccNm: [],
|
||||
fromObjDt: Utility.setFormatDate(new Date(), 'YYYYMMDD'),
|
||||
lockKind: '',
|
||||
readObjId: this.energyCd,
|
||||
toObjDt: Utility.setFormatDate(new Date(), 'YYYYMMDD'),
|
||||
upEccId: '',
|
||||
};
|
||||
var check_flag = true;
|
||||
// 공정/설비 트리리스트 중 에너지원에 따른 최상위 정보 가져오기
|
||||
try {
|
||||
root_info = await this.postApiReturn({
|
||||
apiKey: 'selectFtnPlcListTree',
|
||||
resKey: 'ftnPlcTreeDatas',
|
||||
sendParam: {
|
||||
blocId: 'BL0001',
|
||||
roiId: this.energyCd,
|
||||
eqpmYn: 1,
|
||||
// search:this.searchWord
|
||||
},
|
||||
});
|
||||
filtered_res = root_info.filter(item => item.upEccId == 'ROOT');
|
||||
apiParameters['locKind'] = filtered_res[0].locKind;
|
||||
apiParameters['upEccId'] = filtered_res[0].eccId;
|
||||
sendParam_chart_data['lockKind'] = filtered_res[0].locKind;
|
||||
} catch (error) {
|
||||
root_info = [];
|
||||
filtered_res = [];
|
||||
}
|
||||
|
||||
// 위의 정보로 해당 검침개소 정보 가져오기
|
||||
try {
|
||||
facList = await this.postApiReturn({
|
||||
apiKey: 'selectEnergyUseReadDnPlc',
|
||||
resKey: 'energyUseReadDnPlc',
|
||||
sendParam: apiParameters,
|
||||
});
|
||||
for (var i in facList) {
|
||||
sendParam_chart_data['eccId'].push(facList[i]['eccId']);
|
||||
sendParam_chart_data['eccNm'].push(facList[i]['eccNm']);
|
||||
}
|
||||
// sendParam_chart_data['eccId'].push(facList[0]['eccId']);
|
||||
// sendParam_chart_data['eccNm'].push(facList[0]['eccNm']);
|
||||
sendParam_chart_data['upEccId'] = facList[0]['upEccId'];
|
||||
} catch (error) {
|
||||
check_flag = false;
|
||||
}
|
||||
|
||||
// 위의 정보로 검침개소 시간별 사용량 가져오기
|
||||
var final_chart_data = [];
|
||||
if (check_flag) {
|
||||
try {
|
||||
res_useage = await this.postApiReturn({
|
||||
apiKey: 'selectEnergyUseReadHourAddup',
|
||||
resKey: 'energyUseRead',
|
||||
sendParam: sendParam_chart_data,
|
||||
});
|
||||
|
||||
// root 하위 개소들의 사용량을 sum 함(쿼리에서 SUM 안했을 경우 사용)
|
||||
// var sum_data = {};
|
||||
// for (var i in res_useage){
|
||||
// res_useage[i]['type'] = 'use'
|
||||
// for (var key in res_useage[i]){
|
||||
// if(key.includes('qty')){
|
||||
// if(sum_data[key] == undefined){
|
||||
// sum_data[key] = res_useage[i][key]
|
||||
// }else{
|
||||
// sum_data[key] += res_useage[i][key]
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// // final_chart_data.push(res_useage[i])
|
||||
// }
|
||||
// final_chart_data.push({'type' : 'use', ...sum_data})
|
||||
|
||||
// root 하위 개소들의 사용량을 sum 함(쿼리에서 SUM을 했을 경우 사용)
|
||||
res_useage[0]['type'] = 'use';
|
||||
final_chart_data.push(res_useage[0]);
|
||||
} catch (error) {
|
||||
res_useage = [];
|
||||
}
|
||||
|
||||
try {
|
||||
res_cost = await this.postApiReturn({
|
||||
apiKey: 'selectEnergyUseReadHourCostAddup',
|
||||
resKey: 'energyUseRead',
|
||||
sendParam: sendParam_chart_data,
|
||||
});
|
||||
res_cost[0]['type'] = 'cost';
|
||||
final_chart_data.push(res_cost[0]);
|
||||
} catch (error) {
|
||||
res_cost = [];
|
||||
}
|
||||
} else {
|
||||
res_useage = [];
|
||||
res_cost = [];
|
||||
}
|
||||
// 전주 평균 누적 사용량
|
||||
let res_week_read = [];
|
||||
res_week_read = await this.postApiReturn({
|
||||
apiKey: 'selectEnergyUseReadLastWeekAddup',
|
||||
resKey: 'energyUseRead',
|
||||
sendParam: sendParam_chart_data,
|
||||
});
|
||||
if (res_week_read.length != 0) {
|
||||
res_week_read[0]['type'] = 'week';
|
||||
final_chart_data.push(res_week_read[0]);
|
||||
}
|
||||
// markAreaData 가져오기
|
||||
let res3 = [];
|
||||
let markAreaData = [];
|
||||
let markColor = {
|
||||
MAX: 'rgba(238, 102, 102, 0.1)',
|
||||
MID: 'rgba(250, 200, 88, 0.1)',
|
||||
MIN: 'rgba(145, 204, 117, 0.1)',
|
||||
};
|
||||
const result = this.energyList.filter(
|
||||
energy => energy.cd == this.energyCd,
|
||||
);
|
||||
if (result[0].enrgNm == '전력') {
|
||||
res3 = await this.postApiReturn({
|
||||
apiKey: 'selectPeakKine',
|
||||
resKey: 'peakData',
|
||||
sendParam: {
|
||||
readObjId: result[0].cd,
|
||||
toObjDt: Utility.setFormatDate(new Date(), 'YYYYMMDD'),
|
||||
},
|
||||
});
|
||||
markAreaData = res3.map(item => [
|
||||
{
|
||||
name: item.commCdNm,
|
||||
xAxis:
|
||||
parseInt(item.strtTm.split(':')[0].replace(/(^0+)/, '')) == 23
|
||||
? 0
|
||||
: parseInt(item.strtTm.split(':')[0].replace(/(^0+)/, '')),
|
||||
itemStyle: {
|
||||
color: markColor[item.peakKine],
|
||||
},
|
||||
label: {
|
||||
distance: [0],
|
||||
fontSize: 9,
|
||||
fontWeight: 'lighter',
|
||||
color: '#fff',
|
||||
},
|
||||
},
|
||||
{
|
||||
xAxis: parseInt(item.endTm.split(':')[0].replace(/(^0+)/, '')),
|
||||
},
|
||||
]);
|
||||
}
|
||||
// char data 넣기
|
||||
this.$nextTick(() => {
|
||||
this.setChartData(final_chart_data, markAreaData);
|
||||
});
|
||||
},
|
||||
btnAction(action) {
|
||||
switch (action) {
|
||||
case 'popWidget':
|
||||
this.openDashboardWidget({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetId: this.widgetId,
|
||||
});
|
||||
break;
|
||||
case 'widgetCallPage':
|
||||
this.$parent.$parent.$parent.openWidgetPrgm(this.widgetId);
|
||||
break;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const EnrgUseRsltWidgetData = {
|
||||
isFind: false,
|
||||
enrgUsageChart: Utility.defaultChartOption(true),
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.v-avatar {
|
||||
border-radius: 21px;
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
.v-virtual-scroll-wrapper {
|
||||
overflow-y: auto;
|
||||
max-height: 210px;
|
||||
}
|
||||
.v-radio > label {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
.v-list-item {
|
||||
min-height: 30px;
|
||||
line-height: 1;
|
||||
}
|
||||
.v-list-item__content > * {
|
||||
line-height: 1;
|
||||
}
|
||||
.v-select__widget > .v-input__control > .v-input__slot {
|
||||
min-width: 60%;
|
||||
}
|
||||
.wrapper {
|
||||
padding: 5px 10px 0px 10px !important;
|
||||
border-bottom: thin solid rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
</style>
|
350
components/widget/GasReadReptWidget.vue
Normal file
350
components/widget/GasReadReptWidget.vue
Normal file
@ -0,0 +1,350 @@
|
||||
<template>
|
||||
<div class="l-layout">
|
||||
<v-row ref="rowParent">
|
||||
<v-col :cols="12">
|
||||
<v-card class="pa-3 widget-card">
|
||||
<div class="d-flex align-center justify-space-between">
|
||||
<v-card-title class="pa-0">가스 검침현황</v-card-title>
|
||||
<v-card-subtitle class="mt-0 pa-0">
|
||||
<component
|
||||
ref="MainReadReptReadObjMultiPop"
|
||||
:is="'MainReadReptReadObjMultiPop'"
|
||||
:parentPrgmId="parentPrgmId"
|
||||
:eqpmYn="0"
|
||||
:popTitle="'검침대상 목록'"
|
||||
:widgetId="this.widgetId"
|
||||
@chDialogViewmainReadReptWidget="dialogViewChange"
|
||||
/>
|
||||
<v-tooltip bottom>
|
||||
<template v-slot:activator="{ on, attrs }">
|
||||
<v-icon
|
||||
class="mr-1"
|
||||
size="25"
|
||||
v-bind="attrs"
|
||||
v-on="on"
|
||||
@click="readObjDialog"
|
||||
>mdi-tooltip-plus</v-icon
|
||||
>
|
||||
</template>
|
||||
<span>품질</span>
|
||||
</v-tooltip>
|
||||
<v-icon
|
||||
v-show="widgetPrgmId"
|
||||
class="mr-1"
|
||||
size="25"
|
||||
@click="btnAction('widgetCallPage')"
|
||||
>mdi-note-search</v-icon
|
||||
>
|
||||
<v-icon
|
||||
v-show="widgetPopFg"
|
||||
size="25"
|
||||
@click="btnAction('popWidget')"
|
||||
>mdi-plus-box-multiple</v-icon
|
||||
>
|
||||
</v-card-subtitle>
|
||||
</div>
|
||||
<div class="px-2 pt-3">
|
||||
<v-banner single-line :style="{ paddingRight: '10px' }">
|
||||
<v-row justify="space-between" align="center" no-gutters>
|
||||
<v-col cols="auto" align="center">
|
||||
<p class="body-2 mb-0">No</p>
|
||||
</v-col>
|
||||
<v-col cols="4" align="center">
|
||||
검침개소
|
||||
</v-col>
|
||||
<v-col cols="2" align="center">
|
||||
<p class="body-2 mb-0">kW</p>
|
||||
</v-col>
|
||||
<v-col cols="2" align="center">
|
||||
상태
|
||||
</v-col>
|
||||
<v-col
|
||||
cols="2"
|
||||
align="center"
|
||||
v-for="(item, index) in readObjIdList"
|
||||
:key="item.readPlcId"
|
||||
:class="{
|
||||
'v-banner--last': index === readObjIdList.length - 1,
|
||||
}"
|
||||
>
|
||||
{{ item.readObjNm }}
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-banner>
|
||||
<div
|
||||
class="v-virtual-scroll-wrapper"
|
||||
:style="{ paddingRight: '5px' }"
|
||||
>
|
||||
<v-banner
|
||||
single-line
|
||||
v-for="(item, index) in mainReadPlcData"
|
||||
:key="item.readPlcId"
|
||||
:class="{
|
||||
'v-banner--last': index === mainReadPlcData.length - 1,
|
||||
}"
|
||||
>
|
||||
<v-row justify="space-between" align="center" no-gutters>
|
||||
<v-col cols="auto">
|
||||
<p class="body-2 mb-0">{{ item.rowNum }}</p>
|
||||
</v-col>
|
||||
<v-col cols="4">
|
||||
<div
|
||||
class="d-flex align-center"
|
||||
style="white-space: normal"
|
||||
>
|
||||
<p class="body-2 mb-0 ml-2">{{ item.readPlcNm }}</p>
|
||||
</div>
|
||||
</v-col>
|
||||
<v-col cols="2" align="center">
|
||||
<p class="body-2 mb-0">
|
||||
{{
|
||||
String(Math.floor(item.instantVal)).replace(
|
||||
/\B(?=(\d{3})+(?!\d))/g,
|
||||
',',
|
||||
)
|
||||
}}
|
||||
</p>
|
||||
</v-col>
|
||||
<v-col cols="2" align="center">
|
||||
<v-icon
|
||||
:color="
|
||||
isDarkMode
|
||||
? tableDataGetDarkColorByState(item.stat)
|
||||
: tableDataGetLightColorByState(item.stat)
|
||||
"
|
||||
size="8"
|
||||
class="mr-1"
|
||||
>mdi-circle</v-icon
|
||||
>
|
||||
<span class="body-2">{{ item.stat }}</span>
|
||||
</v-col>
|
||||
<v-col
|
||||
cols="2"
|
||||
align="center"
|
||||
v-for="(item2, index) in readObjIdList"
|
||||
:key="item2.readPlcId"
|
||||
:class="{
|
||||
'v-banner--last': index === readObjIdList.length - 1,
|
||||
}"
|
||||
>
|
||||
<span class="body-2">{{ item[item2.readObjId] }}</span>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-banner>
|
||||
</div>
|
||||
</div>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions, mapMutations, mapState } from 'vuex'; // , mapActions
|
||||
import Vue from 'vue';
|
||||
import DateUtility from '~/plugins/dateUtility';
|
||||
import Utility from '~/plugins/utility';
|
||||
import Chart from '~/components/common/Chart';
|
||||
import MainReadReptReadObjMultiPop from '~/components/common/modal/MainReadReptReadObjMultiPop';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
parentPrgmId: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
widgetId: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
widgetPrgmId: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
widgetPopFg: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
widgetReflashMm: {
|
||||
type: Number,
|
||||
require: true,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
DateUtility,
|
||||
Chart,
|
||||
MainReadReptReadObjMultiPop,
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
searchParam(state) {
|
||||
return state.pageData[this.parentPrgmId][this.widgetId][
|
||||
this.widgetId + 'Data'
|
||||
];
|
||||
},
|
||||
isDarkMode: 'isDarkMode',
|
||||
}),
|
||||
},
|
||||
watch: {
|
||||
energyCd() {
|
||||
this.getMainReadPlcStat();
|
||||
},
|
||||
},
|
||||
beforeCreate() {
|
||||
this.$store.commit('setWidgetPageData', {
|
||||
prgmId: this.$route.query.prgmId,
|
||||
gasReadReptWidget: { gasReadReptWidgetData },
|
||||
});
|
||||
},
|
||||
async created() {
|
||||
this.search();
|
||||
this.timer = setInterval(this.search, this.widgetReflashMm);
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.clearTimeout(this.timer);
|
||||
},
|
||||
mounted() {},
|
||||
data() {
|
||||
return {
|
||||
blocNm: '',
|
||||
mainReadPlcData: [],
|
||||
widgetId: 'gasReadReptWidget',
|
||||
dialogView: false,
|
||||
readObjIdList: [],
|
||||
readPlcIdList: [],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
...mapMutations({
|
||||
setPageData: 'setPageData',
|
||||
setWidgetChartOption: 'setWidgetChartOption',
|
||||
openDashboardWidget: 'openDashboardWidget',
|
||||
}),
|
||||
...mapActions({
|
||||
postApi: 'modules/list/postApi',
|
||||
postApiReturn: 'modules/list/postApiReturn',
|
||||
getEnergyList: 'modules/search/getEnergyList',
|
||||
}),
|
||||
setBlocNm() {
|
||||
this.blocNm = this.$store.state.userInfo.blocNm;
|
||||
if (this.blocNm != '') {
|
||||
this.blocNm = '[' + this.blocNm + ']';
|
||||
}
|
||||
},
|
||||
dialogViewChange() {
|
||||
this.getMainReadPlcStat();
|
||||
},
|
||||
async search() {
|
||||
this.setBlocNm();
|
||||
|
||||
await this.getMainReadPlcStat();
|
||||
},
|
||||
async getMainReadPlcStat() {
|
||||
if (
|
||||
this.$store.state.pageData[this.parentPrgmId].gasReadReptWidget
|
||||
.gasReadReptWidgetData.readObjList.length > 0
|
||||
) {
|
||||
this.readObjIdList = this.$store.state.pageData[
|
||||
this.parentPrgmId
|
||||
].gasReadReptWidget.gasReadReptWidgetData.readObjList.map(item => {
|
||||
return { readObjId: item.readObjId, readObjNm: item.readObjNm };
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
this.$store.state.pageData[this.parentPrgmId].gasReadReptWidget
|
||||
.gasReadReptWidgetData.plcKindList.length > 0
|
||||
) {
|
||||
this.readPlcIdList = this.$store.state.pageData[
|
||||
this.parentPrgmId
|
||||
].gasReadReptWidget.gasReadReptWidgetData.plcKindList.map(item => {
|
||||
return item.readPlcId;
|
||||
});
|
||||
}
|
||||
this.mainReadPlcData = await this.postApiReturn({
|
||||
apiKey: 'selectMainReadPlcStat',
|
||||
resKey: 'mainReadPlcData',
|
||||
sendParam: {
|
||||
readObjIdList: this.readObjIdList,
|
||||
},
|
||||
});
|
||||
|
||||
// this.mainReadPlcData = [
|
||||
// {
|
||||
// "rowNum" : 1,
|
||||
// "comId" : "CDR00",
|
||||
// "readPlcId" : "RPC000002",
|
||||
// "readPlcNm" : "[전력] LP-1_A동메인",
|
||||
// "readObjNm" : "Heartbit",
|
||||
// "readObjId" : "ROI000040",
|
||||
// "instantVal" : 11239.0,
|
||||
// "volt" : 228.9,
|
||||
// "ampr" : 55.1,
|
||||
// "ROI000001" : 93613.1,
|
||||
// "ROI000005" : 229.7,
|
||||
// "ROI000006" : 81.8,
|
||||
// "ROI000008" : 1,
|
||||
// "stat" : "가동중"
|
||||
// }
|
||||
// ]
|
||||
},
|
||||
btnAction(action) {
|
||||
switch (action) {
|
||||
case 'popWidget':
|
||||
this.openDashboardWidget({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetId: this.widgetId,
|
||||
});
|
||||
break;
|
||||
case 'widgetCallPage':
|
||||
this.$parent.$parent.$parent.openWidgetPrgm(this.widgetId);
|
||||
break;
|
||||
}
|
||||
},
|
||||
tableDataGetDarkColorByState: state => {
|
||||
return {
|
||||
가동중: '#01ae6a',
|
||||
미사용: '#ffb046',
|
||||
비정상: '#f6637b',
|
||||
}[state];
|
||||
},
|
||||
tableDataGetLightColorByState: state => {
|
||||
return {
|
||||
가동중: '#3cc380',
|
||||
미사용: '#ffb13b',
|
||||
비정상: '#f98694',
|
||||
}[state];
|
||||
},
|
||||
readObjDialog() {
|
||||
this.$store.state.pageData[
|
||||
this.parentPrgmId
|
||||
].gasReadReptWidget.gasReadReptWidgetData.enrgDiv = 'MTT_FUEL';
|
||||
this.$store.state.pageData[
|
||||
this.parentPrgmId
|
||||
].gasReadReptWidget.gasReadReptWidgetData.grpCd = 'MTT_STAT';
|
||||
this.$refs['MainReadReptReadObjMultiPop'].dialog = true;
|
||||
},
|
||||
},
|
||||
};
|
||||
const gasReadReptWidgetData = {
|
||||
readObjModalData: {},
|
||||
isMulti: true,
|
||||
blocId: 0,
|
||||
blocMstrList: [],
|
||||
readObjList: [],
|
||||
readObj: {},
|
||||
enrgDiv: '',
|
||||
plcKindList: [],
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.v-avatar {
|
||||
border-radius: 21px;
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
.v-virtual-scroll-wrapper {
|
||||
overflow-y: auto;
|
||||
max-height: 210px;
|
||||
}
|
||||
</style>
|
646
components/widget/GasUseRsltWidget.vue
Normal file
646
components/widget/GasUseRsltWidget.vue
Normal file
@ -0,0 +1,646 @@
|
||||
<template>
|
||||
<div class="l-layout">
|
||||
<v-row ref="rowParent">
|
||||
<v-col :cols="12">
|
||||
<v-card class="pa-3 widget-card">
|
||||
<div class="d-flex align-center justify-space-between">
|
||||
<v-card-title class="pa-0">가스 사용량 실적</v-card-title>
|
||||
<v-card-subtitle class="mt-0 pa-0 text-right">
|
||||
<v-icon
|
||||
v-show="widgetPrgmId"
|
||||
class="mr-1"
|
||||
size="25"
|
||||
@click="btnAction('widgetCallPage')"
|
||||
>mdi-note-search</v-icon
|
||||
>
|
||||
<v-icon
|
||||
v-show="widgetPopFg"
|
||||
size="25"
|
||||
@click="btnAction('popWidget')"
|
||||
>mdi-plus-box-multiple</v-icon
|
||||
>
|
||||
</v-card-subtitle>
|
||||
</div>
|
||||
<div class="row wrapper">
|
||||
<div class="col-6">
|
||||
<div class="px-5 pb-1">
|
||||
<div class="text-center">
|
||||
<strong class="custom-title-2-5"
|
||||
>{{ dayUseQty }}
|
||||
<span class="font-weight-regular custom-text-2"
|
||||
>kWh</span
|
||||
></strong
|
||||
>
|
||||
<div class="d-flex align-center justify-center">
|
||||
<span class="body-2 text-color--non-activate"
|
||||
>전주 대비({{ currHour }})</span
|
||||
>
|
||||
<div
|
||||
class="d-flex align-baseline ml-2"
|
||||
:style="{
|
||||
color: isDarkMode
|
||||
? isUseQtyStat
|
||||
? '#f6637b'
|
||||
: '#01ae6a'
|
||||
: isUseQtyStat
|
||||
? '#ff76bb'
|
||||
: '#00c875',
|
||||
}"
|
||||
>
|
||||
<strong class="mr-1 custom-text-1">{{
|
||||
compareUseQty
|
||||
}}</strong>
|
||||
<span class="caption mr-1">kWh</span>
|
||||
<v-icon
|
||||
small
|
||||
:color="
|
||||
isDarkMode
|
||||
? isUseQtyStat
|
||||
? '#f6637b'
|
||||
: '#01ae6a'
|
||||
: isUseQtyStat
|
||||
? '#ff76bb'
|
||||
: '#00c875'
|
||||
"
|
||||
>{{ useQtyStat }}</v-icon
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="px-5 pb-1">
|
||||
<div class="text-center">
|
||||
<strong class="custom-title-2-5"
|
||||
>{{ dayUseCost }}
|
||||
<span class="font-weight-regular custom-text-2"
|
||||
>천원</span
|
||||
></strong
|
||||
>
|
||||
<div class="d-flex align-center justify-center">
|
||||
<span class="body-2 text-color--non-activate"
|
||||
>전주 대비(0시-{{ currHour }})</span
|
||||
>
|
||||
<div
|
||||
class="d-flex align-baseline ml-2"
|
||||
:style="{
|
||||
color: isDarkMode
|
||||
? isUseCostStat
|
||||
? '#f6637b'
|
||||
: '#01ae6a'
|
||||
: isUseCostStat
|
||||
? '#ff76bb'
|
||||
: '#00c875',
|
||||
}"
|
||||
>
|
||||
<strong class="mr-1 custom-text-1">{{
|
||||
compareUseCost
|
||||
}}</strong>
|
||||
<span class="caption mr-1">천원</span>
|
||||
<v-icon
|
||||
small
|
||||
:color="
|
||||
isDarkMode
|
||||
? isUseCostStat
|
||||
? '#f6637b'
|
||||
: '#01ae6a'
|
||||
: isUseCostStat
|
||||
? '#ff76bb'
|
||||
: '#00c875'
|
||||
"
|
||||
>{{ useCostStat }}</v-icon
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex align-center justify-space-between mt-2">
|
||||
<div :style="{ width: '100%', height: '160px' }">
|
||||
<component
|
||||
class="w100 h100"
|
||||
:is="loadChart_01 ? 'Chart' : null"
|
||||
:parentPrgmId="parentPrgmId"
|
||||
:widgetId="'enrgUseRsltWidget'"
|
||||
:widgetData="'enrgUseRsltWidgetData'"
|
||||
:chartName="chart_01"
|
||||
ref="chart_01"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions, mapMutations, mapState } from 'vuex'; // , mapActions
|
||||
import Vue from 'vue';
|
||||
import DateUtility from '~/plugins/dateUtility';
|
||||
import Utility from '~/plugins/utility';
|
||||
import Chart from '~/components/common/Chart';
|
||||
export default {
|
||||
props: {
|
||||
parentPrgmId: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
widgetId: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
widgetPrgmId: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
widgetPopFg: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
widgetReflashMm: {
|
||||
type: Number,
|
||||
require: true,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
DateUtility,
|
||||
Chart,
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
searchParam(state) {
|
||||
return state.pageData[this.parentPrgmId];
|
||||
},
|
||||
isDarkMode: 'isDarkMode',
|
||||
}),
|
||||
},
|
||||
watch: {
|
||||
// rdbEnrgUsage(){
|
||||
// this.getEnrgUsage();
|
||||
// },
|
||||
energyCd() {
|
||||
this.getEnrgUsage();
|
||||
this.getChartData();
|
||||
},
|
||||
},
|
||||
beforeCreate() {
|
||||
this.$store.commit('setWidgetPageData', {
|
||||
prgmId: this.$route.query.prgmId,
|
||||
enrgUseRsltWidget: { enrgUseRsltWidgetData },
|
||||
});
|
||||
},
|
||||
async created() {
|
||||
this.energyList = await this.postApiReturn({
|
||||
apiKey: 'selectEnergy',
|
||||
resKey: 'energyData',
|
||||
sendParam: {
|
||||
useFg: 1,
|
||||
},
|
||||
});
|
||||
|
||||
this.energyList.filter(item => {
|
||||
if (item.readObjCd == 'GAS_LNG') {
|
||||
//가스
|
||||
this.energyCd = item.cd;
|
||||
this.unit = item.unit;
|
||||
}
|
||||
});
|
||||
|
||||
this.search();
|
||||
this.timer = setInterval(this.search, this.widgetReflashMm);
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.clearTimeout(this.timer);
|
||||
},
|
||||
mounted() {},
|
||||
data() {
|
||||
return {
|
||||
// blocNm:'',
|
||||
//바인딩
|
||||
energyCd: '',
|
||||
energyList: [],
|
||||
unit: '',
|
||||
currHour: Utility.setFormatDate(new Date(), 'H') + '시 기준',
|
||||
isUseQtyStat: true,
|
||||
isUseCostStat: true,
|
||||
dayUseQty: 0,
|
||||
compareUseQty: 0,
|
||||
useQtyStat: null,
|
||||
dayUseCost: 0,
|
||||
compareUseCost: 0,
|
||||
useCostStat: null,
|
||||
// 차트
|
||||
chart_01: 'enrgUsageChart',
|
||||
loadChart_01: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
...mapMutations({
|
||||
setPageData: 'setPageData',
|
||||
setWidgetChartOption: 'setWidgetChartOption',
|
||||
openDashboardWidget: 'openDashboardWidget',
|
||||
setWidgetChartYaxisData: 'setWidgetChartYaxisData',
|
||||
}),
|
||||
...mapActions({
|
||||
postApi: 'modules/list/postApi',
|
||||
postApiReturn: 'modules/list/postApiReturn',
|
||||
getEnergyList: 'modules/search/getEnergyList',
|
||||
}),
|
||||
async search() {
|
||||
// this.setBlocNm();
|
||||
await this.getEnrgUsage();
|
||||
await this.getChartData();
|
||||
},
|
||||
async getEnrgUsage() {
|
||||
const res = await this.postApiReturn({
|
||||
apiKey: 'selectUseCostDay',
|
||||
resKey: 'dayUseCostData',
|
||||
sendParam: {
|
||||
readObjId: this.energyCd,
|
||||
},
|
||||
});
|
||||
const res2 = await this.postApiReturn({
|
||||
apiKey: 'selectUseCostPast',
|
||||
resKey: 'pastUseCostData',
|
||||
sendParam: {
|
||||
readObjId: this.energyCd,
|
||||
},
|
||||
});
|
||||
res.forEach((item, idx) => {
|
||||
this.dayUseQty = Utility.setFormatInt(item.qty);
|
||||
this.dayUseCost = Utility.setFormatInt(item.cost);
|
||||
});
|
||||
let dayUseQty,
|
||||
dayUseQtyAvg,
|
||||
dayUseCost,
|
||||
dayUseCostAvg,
|
||||
dayUseMaxQty,
|
||||
dayUseMaxCost = 0;
|
||||
if (res.length > 0) {
|
||||
dayUseQty = res[0].qty;
|
||||
dayUseCost = res[0].cost;
|
||||
}
|
||||
if (res2.length > 0) {
|
||||
dayUseQtyAvg = res2[0].qtyAvg;
|
||||
dayUseCostAvg = res2[0].costAvg;
|
||||
dayUseMaxQty = res2[0].maxQty;
|
||||
dayUseMaxCost = res2[0].maxCost;
|
||||
}
|
||||
this.compareUseQty = Utility.setFormatInt(dayUseQty - dayUseQtyAvg);
|
||||
this.compareUseCost = Utility.setFormatInt(dayUseCost - dayUseCostAvg);
|
||||
this.useQtyStat =
|
||||
dayUseQty > dayUseQtyAvg ? 'mdi-arrow-up' : 'mdi-arrow-down';
|
||||
this.useCostStat =
|
||||
dayUseCost > dayUseCostAvg ? 'mdi-arrow-up' : 'mdi-arrow-down';
|
||||
|
||||
this.isUseQtyStat = this.useQtyStat == 'mdi-arrow-up' ? true : false;
|
||||
this.isUseCostStat = this.useCostStat == 'mdi-arrow-up' ? true : false;
|
||||
},
|
||||
setChartData(data) {
|
||||
let xAxisData = [];
|
||||
let seriesData = [];
|
||||
let legendData = [];
|
||||
let arrDarkColors = ['rgba(1, 174, 106, 0.7)', 'rgba(67, 133, 227, 0.7)'];
|
||||
let arrLightColors = [
|
||||
'rgba(207, 116, 229, 0.7)',
|
||||
'rgba(106, 155, 244, 0.7)',
|
||||
];
|
||||
const arrColors = this.isDarkMode ? arrDarkColors : arrLightColors;
|
||||
// chart x축 data
|
||||
var qtyNumber, qtyStr;
|
||||
for (var i = 0; i < 24; i++) {
|
||||
qtyNumber = i.toString().padStart(2, '0');
|
||||
qtyStr = 'qty' + qtyNumber;
|
||||
xAxisData.push(i + '시');
|
||||
}
|
||||
// chart_data 중 누적 사용량과 누적 금액 구분
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var tempObj = { data: [] };
|
||||
tempObj['type'] = 'line';
|
||||
tempObj['lineStyle'] = { width: 2 };
|
||||
tempObj['smooth'] = true;
|
||||
tempObj['showSymbol'] = false;
|
||||
tempObj['color'] = arrColors[i];
|
||||
if (data[i]['type'] == 'use') {
|
||||
tempObj['name'] = '누적 사용량';
|
||||
legendData.push('누적 사용량');
|
||||
tempObj['areaStyle'] = {
|
||||
opacity: 0.5,
|
||||
color: arrColors[i],
|
||||
};
|
||||
tempObj['yAxisIndex'] = 0;
|
||||
} else if (data[i]['type'] == 'cost') {
|
||||
tempObj['name'] = '누적 금액';
|
||||
legendData.push('누적 금액');
|
||||
tempObj['yAxisIndex'] = 1;
|
||||
} else if (data[i]['type'] == 'week') {
|
||||
tempObj['name'] = '전주 평균 누적 사용량';
|
||||
legendData.push('전주 평균 누적 사용량');
|
||||
tempObj['yAxisIndex'] = 0;
|
||||
}
|
||||
// 0~23시 까지의 데이터 seriesData 넣기
|
||||
for (var j = 0; j < 24; j++) {
|
||||
qtyNumber = j.toString().padStart(2, '0');
|
||||
qtyStr = 'qty' + qtyNumber;
|
||||
if (data[i].hasOwnProperty(qtyStr)) {
|
||||
// tempObj['data'].push(Utility.setFormatIntDecimal(parseFloat(data[i][qtyStr]), 2).replace(',',''));
|
||||
tempObj['data'].push(parseFloat(data[i][qtyStr]));
|
||||
} else {
|
||||
tempObj['data'].push(0);
|
||||
}
|
||||
}
|
||||
seriesData.push(tempObj);
|
||||
}
|
||||
|
||||
const yAxisData = [
|
||||
{
|
||||
type: 'value',
|
||||
name: this.unit,
|
||||
splitLine: {
|
||||
show: false,
|
||||
},
|
||||
nameTextStyle: {
|
||||
fontSize: 12,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#767D83',
|
||||
fontSize: 9,
|
||||
formatter: '{value}',
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'value',
|
||||
name: '원',
|
||||
splitLine: {
|
||||
show: false,
|
||||
},
|
||||
nameTextStyle: {
|
||||
fontSize: 12,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#767D83',
|
||||
fontSize: 9,
|
||||
formatter: '{value}',
|
||||
},
|
||||
},
|
||||
];
|
||||
var chartOption = {
|
||||
series: seriesData,
|
||||
grid: {
|
||||
left: '1%',
|
||||
right: '2%',
|
||||
top: '20%',
|
||||
bottom: '15%',
|
||||
containLabel: true,
|
||||
},
|
||||
legend: {
|
||||
data: legendData,
|
||||
bottom: 'bottom',
|
||||
icon: 'bar',
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
//boundaryGap: false,
|
||||
splitLine: false,
|
||||
data: xAxisData,
|
||||
axisLabel: {
|
||||
fontSize: 9,
|
||||
},
|
||||
},
|
||||
// yAxis: [
|
||||
// {
|
||||
// type: 'value',
|
||||
// name: this.unit,
|
||||
// splitLine: {
|
||||
// show: false
|
||||
// },
|
||||
// nameTextStyle: {
|
||||
// fontSize: 12,
|
||||
// fontWeight:'bold'
|
||||
// },
|
||||
// axisLabel:{
|
||||
// color: "#767D83",
|
||||
// fontSize: 9,
|
||||
// formatter: '{value}'
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// type: 'value',
|
||||
// name: '원',
|
||||
// splitLine: {
|
||||
// show: false
|
||||
// },
|
||||
// nameTextStyle: {
|
||||
// fontSize: 12,
|
||||
// fontWeight:'bold'
|
||||
// },
|
||||
// axisLabel:{
|
||||
// color: "#767D83",
|
||||
// fontSize: 9,
|
||||
// formatter: '{value}'
|
||||
// }
|
||||
// }
|
||||
// ],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
},
|
||||
};
|
||||
|
||||
this.setWidgetChartOption({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetKey: 'enrgUseRsltWidget',
|
||||
widgetData: 'enrgUseRsltWidgetData',
|
||||
chartKey: 'enrgUsageChart',
|
||||
value: chartOption,
|
||||
});
|
||||
this.setWidgetChartYaxisData({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetKey: 'enrgUseRsltWidget',
|
||||
widgetData: 'enrgUseRsltWidgetData',
|
||||
chartKey: 'enrgUsageChart',
|
||||
value: yAxisData,
|
||||
});
|
||||
this.loadChart_01 = true;
|
||||
},
|
||||
async getChartData() {
|
||||
this.loadChart_01 = false;
|
||||
var root_info = null;
|
||||
var res_useage = null;
|
||||
var res_cost = null;
|
||||
var facList = null;
|
||||
var filtered_res = null;
|
||||
var apiParameters = {
|
||||
blocId: 'BL0001',
|
||||
readObjId: this.energyCd,
|
||||
locKind: '',
|
||||
upEccId: '',
|
||||
};
|
||||
var sendParam_chart_data = {
|
||||
blocId: 'BL0001',
|
||||
eccId: [],
|
||||
eccNm: [],
|
||||
fromObjDt: Utility.setFormatDate(new Date(), 'YYYYMMDD'),
|
||||
lockKind: '',
|
||||
readObjId: this.energyCd,
|
||||
toObjDt: Utility.setFormatDate(new Date(), 'YYYYMMDD'),
|
||||
upEccId: '',
|
||||
};
|
||||
var check_flag = true;
|
||||
// 공정/설비 트리리스트 중 에너지원에 따른 최상위 정보 가져오기
|
||||
try {
|
||||
root_info = await this.postApiReturn({
|
||||
apiKey: 'selectFtnPlcListTree',
|
||||
resKey: 'ftnPlcTreeDatas',
|
||||
sendParam: {
|
||||
blocId: 'BL0001',
|
||||
roiId: this.energyCd,
|
||||
eqpmYn: 1,
|
||||
// search:this.searchWord
|
||||
},
|
||||
});
|
||||
filtered_res = root_info.filter(item => item.upEccId == 'ROOT');
|
||||
apiParameters['locKind'] = filtered_res[0].locKind;
|
||||
apiParameters['upEccId'] = filtered_res[0].eccId;
|
||||
sendParam_chart_data['lockKind'] = filtered_res[0].locKind;
|
||||
} catch (error) {
|
||||
root_info = [];
|
||||
filtered_res = [];
|
||||
}
|
||||
|
||||
// 위의 정보로 해당 검침개소 정보 가져오기
|
||||
try {
|
||||
facList = await this.postApiReturn({
|
||||
apiKey: 'selectEnergyUseReadDnPlc',
|
||||
resKey: 'energyUseReadDnPlc',
|
||||
sendParam: apiParameters,
|
||||
});
|
||||
for (var i in facList) {
|
||||
sendParam_chart_data['eccId'].push(facList[i]['eccId']);
|
||||
sendParam_chart_data['eccNm'].push(facList[i]['eccNm']);
|
||||
}
|
||||
// sendParam_chart_data['eccId'].push(facList[0]['eccId']);
|
||||
// sendParam_chart_data['eccNm'].push(facList[0]['eccNm']);
|
||||
sendParam_chart_data['upEccId'] = facList[0]['upEccId'];
|
||||
} catch (error) {
|
||||
check_flag = false;
|
||||
}
|
||||
|
||||
// 위의 정보로 검침개소 시간별 사용량 가져오기
|
||||
var final_chart_data = [];
|
||||
if (check_flag) {
|
||||
try {
|
||||
res_useage = await this.postApiReturn({
|
||||
apiKey: 'selectEnergyUseReadHourAddup',
|
||||
resKey: 'energyUseRead',
|
||||
sendParam: sendParam_chart_data,
|
||||
});
|
||||
|
||||
// root 하위 개소들의 사용량을 sum 함(쿼리에서 SUM 안했을 경우 사용)
|
||||
// var sum_data = {};
|
||||
// for (var i in res_useage){
|
||||
// res_useage[i]['type'] = 'use'
|
||||
// for (var key in res_useage[i]){
|
||||
// if(key.includes('qty')){
|
||||
// if(sum_data[key] == undefined){
|
||||
// sum_data[key] = res_useage[i][key]
|
||||
// }else{
|
||||
// sum_data[key] += res_useage[i][key]
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// // final_chart_data.push(res_useage[i])
|
||||
// }
|
||||
// final_chart_data.push({'type' : 'use', ...sum_data})
|
||||
|
||||
// root 하위 개소들의 사용량을 sum 함(쿼리에서 SUM을 했을 경우 사용)
|
||||
res_useage[0]['type'] = 'use';
|
||||
final_chart_data.push(res_useage[0]);
|
||||
} catch (error) {
|
||||
res_useage = [];
|
||||
}
|
||||
|
||||
try {
|
||||
res_cost = await this.postApiReturn({
|
||||
apiKey: 'selectEnergyUseReadHourCostAddup',
|
||||
resKey: 'energyUseRead',
|
||||
sendParam: sendParam_chart_data,
|
||||
});
|
||||
res_cost[0]['type'] = 'cost';
|
||||
final_chart_data.push(res_cost[0]);
|
||||
} catch (error) {
|
||||
res_cost = [];
|
||||
}
|
||||
} else {
|
||||
res_useage = [];
|
||||
res_cost = [];
|
||||
}
|
||||
// 전주 평균 누적 사용량
|
||||
let res_week_read = [];
|
||||
res_week_read = await this.postApiReturn({
|
||||
apiKey: 'selectEnergyUseReadLastWeekAddup',
|
||||
resKey: 'energyUseRead',
|
||||
sendParam: sendParam_chart_data,
|
||||
});
|
||||
if (res_week_read.length != 0) {
|
||||
res_week_read[0]['type'] = 'week';
|
||||
final_chart_data.push(res_week_read[0]);
|
||||
}
|
||||
// char data 넣기
|
||||
this.$nextTick(() => {
|
||||
this.setChartData(final_chart_data);
|
||||
});
|
||||
},
|
||||
btnAction(action) {
|
||||
switch (action) {
|
||||
case 'popWidget':
|
||||
this.openDashboardWidget({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetId: this.widgetId,
|
||||
});
|
||||
break;
|
||||
case 'widgetCallPage':
|
||||
this.$parent.$parent.$parent.openWidgetPrgm(this.widgetId);
|
||||
break;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const enrgUseRsltWidgetData = {
|
||||
isFind: false,
|
||||
enrgUsageChart: Utility.defaultChartOption(true),
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.v-avatar {
|
||||
border-radius: 21px;
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
.v-virtual-scroll-wrapper {
|
||||
overflow-y: auto;
|
||||
max-height: 210px;
|
||||
}
|
||||
.v-radio > label {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
.v-list-item {
|
||||
min-height: 30px;
|
||||
line-height: 1;
|
||||
}
|
||||
.v-list-item__content > * {
|
||||
line-height: 1;
|
||||
}
|
||||
.v-select__widget > .v-input__control > .v-input__slot {
|
||||
min-width: 60%;
|
||||
}
|
||||
.wrapper {
|
||||
padding: 5px 10px 0px 10px !important;
|
||||
border-bottom: thin solid rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
</style>
|
282
components/widget/GridWidget.vue
Normal file
282
components/widget/GridWidget.vue
Normal file
@ -0,0 +1,282 @@
|
||||
<template>
|
||||
<div class="l-layout">
|
||||
<v-row ref="rowParent">
|
||||
<v-col :cols="12">
|
||||
<v-card class="pa-5 widget-card">
|
||||
<div class="d-flex align-center justify-space-between">
|
||||
<v-card-title class="pa-0">그리드</v-card-title>
|
||||
<v-btn :ripple="false" @click="btnAction('popWidget')">화면</v-btn>
|
||||
</div>
|
||||
<div class="d-flex align-center justify-space-between mt-8">
|
||||
<div class="mr-5" :style="{ width: '240px', height: '170px' }">
|
||||
<component
|
||||
:ref="gridName"
|
||||
:is="loadGrid ? 'Grid' : null"
|
||||
:parentPrgmId="parentPrgmId"
|
||||
:gridName="gridName"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions, mapMutations, mapState } from 'vuex'; // , mapActions
|
||||
import Vue from 'vue';
|
||||
import DateUtility from '~/plugins/dateUtility';
|
||||
import Utility from '~/plugins/utility';
|
||||
import Grid from '~/components/common/Grid';
|
||||
import Chart from '~/components/common/Chart';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
parentPrgmId: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
DateUtility,
|
||||
Grid,
|
||||
Chart,
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
searchParam(state) {
|
||||
return state.pageData[this.parentPrgmId];
|
||||
},
|
||||
isDarkMode: 'isDarkMode',
|
||||
}),
|
||||
},
|
||||
watch: {},
|
||||
beforeCreate() {
|
||||
this.$store.commit('setWidgetPageData', {
|
||||
prgmId: this.$route.query.prgmId,
|
||||
gridWidget: { gridWidgetData },
|
||||
});
|
||||
// console.log("2.vue::beforeCreate");
|
||||
},
|
||||
created() {
|
||||
this.search();
|
||||
},
|
||||
mounted() {},
|
||||
data() {
|
||||
return {
|
||||
loadGrid: false,
|
||||
gridName: 'rowGrid',
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
...mapMutations({
|
||||
setPageData: 'setPageData',
|
||||
setWidgetChartOption: 'setWidgetChartOption',
|
||||
openDashboardWidget: 'openDashboardWidget',
|
||||
}),
|
||||
...mapActions({
|
||||
postApi: 'modules/list/postApi',
|
||||
postApiReturn: 'modules/list/postApiReturn',
|
||||
}),
|
||||
gridInit() {
|
||||
const gridHeight = this.$refs.gridParent.offsetHeight - 36;
|
||||
|
||||
const myOptions = {
|
||||
scrollX: false,
|
||||
};
|
||||
this.setGridOption({
|
||||
gridKey: this.gridName,
|
||||
// value: myOptions
|
||||
value: Object.assign(Utility.defaultGridOption(gridHeight), myOptions),
|
||||
});
|
||||
this.setGridColumn({
|
||||
gridKey: this.gridName,
|
||||
value: myColumns,
|
||||
});
|
||||
|
||||
// this.getRowGridData();
|
||||
|
||||
this.loadGrid = true;
|
||||
},
|
||||
async search() {
|
||||
await this.getRowGridData();
|
||||
await this.setPageData({
|
||||
isFind: false,
|
||||
});
|
||||
},
|
||||
async getUseWithPeak() {
|
||||
this.loadChart_01 = false;
|
||||
const res = await this.postApiReturn({
|
||||
apiKey: 'selectUseWithPeak',
|
||||
resKey: 'peakData',
|
||||
sendParam: {},
|
||||
});
|
||||
|
||||
res.forEach((item, idx) => {
|
||||
this.chargedPower = Utility.setFormatInt(item.peakVal);
|
||||
this.nowPeakVal = Utility.setFormatInt(item.curPeakVal);
|
||||
});
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.setChart01Data(res);
|
||||
});
|
||||
},
|
||||
|
||||
//차트Setting
|
||||
async setChart01Data(data) {
|
||||
this.$store.state.pageData[
|
||||
this.parentPrgmId
|
||||
].peakWidget.peakWidgetData.series = [];
|
||||
if (!data.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const arrDarkColors = {
|
||||
정상: '#01ae6a',
|
||||
주의: '#ffb046',
|
||||
위험: '#f6637b',
|
||||
};
|
||||
const arrLightColors = {
|
||||
정상: '#01ae6a',
|
||||
주의: '#ffb046',
|
||||
위험: '#f6637b',
|
||||
};
|
||||
|
||||
const darkGaugeColors = [
|
||||
[0.125, '#009245'],
|
||||
[0.25, '#39b54a'],
|
||||
[0.375, '#d9e021'],
|
||||
[0.5, '#fcee21'],
|
||||
[0.625, '#fbb03b'],
|
||||
[0.75, '#f7931e'],
|
||||
[0.875, '#f15a24'],
|
||||
[1.0, '#ed1c24'],
|
||||
];
|
||||
const lightGaugeColors = [
|
||||
[0.125, '#58c06f'],
|
||||
[0.25, '#7cd574'],
|
||||
[0.375, '#fbe462'],
|
||||
[0.5, '#ffd771'],
|
||||
[0.625, '#ffad7f'],
|
||||
[0.75, '#ff966e'],
|
||||
[0.875, '#ff706e'],
|
||||
[1.0, '#ff6689'],
|
||||
];
|
||||
|
||||
var chartOption = {
|
||||
series: [
|
||||
{
|
||||
type: 'gauge',
|
||||
startAngle: 180,
|
||||
endAngle: 0,
|
||||
min: 0,
|
||||
max: 100,
|
||||
radius: '100%',
|
||||
splitNumber: 8,
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
width: 30,
|
||||
color: this.isDarkMode ? darkGaugeColors : lightGaugeColors,
|
||||
},
|
||||
},
|
||||
splitLine: {
|
||||
show: false,
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
axisLabel: {
|
||||
show: false,
|
||||
},
|
||||
pointer: {
|
||||
length: '80%',
|
||||
width: 5,
|
||||
itemStyle: {
|
||||
color: this.isDarkMode ? '#fff' : '#333333',
|
||||
},
|
||||
},
|
||||
anchor: {
|
||||
show: true,
|
||||
showAbove: true,
|
||||
size: 10,
|
||||
itemStyle: {
|
||||
borderWidth: 10,
|
||||
borderColor: this.isDarkMode ? '#fff' : '#333333',
|
||||
},
|
||||
},
|
||||
title: {
|
||||
offsetCenter: ['90%', '30%'],
|
||||
fontSize: 20,
|
||||
color: this.isDarkMode
|
||||
? arrDarkColors[data[0].peakStat]
|
||||
: arrLightColors[data[0].peakStat],
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
detail: {
|
||||
fontSize: 20,
|
||||
offsetCenter: ['-75%', '30%'],
|
||||
valueAnimation: true,
|
||||
formatter: function(value) {
|
||||
return '{value|' + value.toFixed(2) + '}{unit|%}';
|
||||
},
|
||||
rich: {
|
||||
value: {
|
||||
fontSize: 20,
|
||||
color: this.isDarkMode ? '#fff' : '#111111',
|
||||
fontWeight: 'bolder',
|
||||
},
|
||||
unit: {
|
||||
fontSize: 14,
|
||||
color: this.isDarkMode ? '#fff' : '#111111',
|
||||
fontWeight: 'bolder',
|
||||
padding: [0, 0, -5, 0],
|
||||
},
|
||||
},
|
||||
},
|
||||
data: [
|
||||
{
|
||||
name: data[0].peakStat,
|
||||
value: data[0].peakRto,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
this.setWidgetChartOption({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetKey: 'peakWidget',
|
||||
widgetData: 'peakWidgetData',
|
||||
chartKey: 'peakGauge',
|
||||
value: chartOption,
|
||||
});
|
||||
|
||||
this.loadChart_01 = true;
|
||||
},
|
||||
btnAction(action) {
|
||||
switch (action) {
|
||||
case 'popWidget':
|
||||
this.openDashboardWidget({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetId: 'PeakWidget',
|
||||
});
|
||||
break;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
const gridWidgetData = {
|
||||
peakGauge: Utility.defaultChartOption(true),
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.v-avatar {
|
||||
border-radius: 21px;
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
.v-virtual-scroll-wrapper {
|
||||
overflow-y: auto;
|
||||
max-height: 210px;
|
||||
}
|
||||
</style>
|
382
components/widget/MainReadReptWidget.vue
Normal file
382
components/widget/MainReadReptWidget.vue
Normal file
@ -0,0 +1,382 @@
|
||||
<template>
|
||||
<div class="l-layout">
|
||||
<v-row ref="rowParent">
|
||||
<v-col :cols="12">
|
||||
<v-card class="pa-3 widget-card">
|
||||
<div class="d-flex align-center justify-space-between">
|
||||
<v-card-title class="pa-0">주요 검침현황</v-card-title>
|
||||
<v-card-subtitle class="mt-0 pa-0">
|
||||
<v-select
|
||||
ref="selectEnergy"
|
||||
v-model="selectValue"
|
||||
:items="this.energyList"
|
||||
item-text="enrgNm"
|
||||
item-value="cd"
|
||||
solo
|
||||
outlined
|
||||
:hide-details="true"
|
||||
append-icon="mdi-chevron-down"
|
||||
class="v-select__custom mr-2"
|
||||
></v-select>
|
||||
<component
|
||||
ref="MainReadReptReadObjMultiPop"
|
||||
:is="'MainReadReptReadObjMultiPop'"
|
||||
:parentPrgmId="parentPrgmId"
|
||||
:eqpmYn="0"
|
||||
:popTitle="'검침대상 목록'"
|
||||
:widgetId="this.widgetId"
|
||||
@chDialogViewmainReadReptWidget="dialogViewChange"
|
||||
/>
|
||||
<v-tooltip bottom>
|
||||
<template v-slot:activator="{ on, attrs }">
|
||||
<v-icon
|
||||
class="mr-1"
|
||||
size="25"
|
||||
v-bind="attrs"
|
||||
v-on="on"
|
||||
@click="readObjDialog"
|
||||
>mdi-tooltip-plus</v-icon
|
||||
>
|
||||
</template>
|
||||
<span>품질</span>
|
||||
</v-tooltip>
|
||||
<v-icon
|
||||
v-show="widgetPrgmId"
|
||||
class="mr-1"
|
||||
size="25"
|
||||
@click="btnAction('widgetCallPage')"
|
||||
>mdi-note-search</v-icon
|
||||
>
|
||||
<v-icon
|
||||
v-show="widgetPopFg"
|
||||
size="25"
|
||||
@click="btnAction('popWidget')"
|
||||
>mdi-plus-box-multiple</v-icon
|
||||
>
|
||||
</v-card-subtitle>
|
||||
</div>
|
||||
<div class="px-2 pt-3">
|
||||
<v-banner single-line :style="{ paddingRight: '10px' }">
|
||||
<v-row justify="space-between" align="center" no-gutters>
|
||||
<v-col cols="auto" align="center">
|
||||
<p class="body-2 mb-0">No</p>
|
||||
</v-col>
|
||||
<v-col cols="4" align="center">
|
||||
검침개소
|
||||
</v-col>
|
||||
<v-col cols="2" align="center">
|
||||
<p class="body-2 mb-0">kW</p>
|
||||
</v-col>
|
||||
<v-col cols="2" align="center">
|
||||
상태
|
||||
</v-col>
|
||||
<v-col
|
||||
cols="2"
|
||||
align="center"
|
||||
v-for="(item, index) in readObjIdList"
|
||||
:key="item.readPlcId"
|
||||
:class="{
|
||||
'v-banner--last': index === readObjIdList.length - 1,
|
||||
}"
|
||||
>
|
||||
{{ item.readObjNm }}
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-banner>
|
||||
<div
|
||||
class="v-virtual-scroll-wrapper"
|
||||
:style="{ paddingRight: '5px' }"
|
||||
>
|
||||
<v-banner
|
||||
single-line
|
||||
v-for="(item, index) in mainReadPlcData"
|
||||
:key="item.readPlcId"
|
||||
:class="{
|
||||
'v-banner--last': index === mainReadPlcData.length - 1,
|
||||
}"
|
||||
>
|
||||
<v-row justify="space-between" align="center" no-gutters>
|
||||
<v-col cols="auto">
|
||||
<p class="body-2 mb-0">{{ item.rowNum }}</p>
|
||||
</v-col>
|
||||
<v-col cols="4">
|
||||
<div
|
||||
class="d-flex align-center"
|
||||
style="white-space: normal"
|
||||
>
|
||||
<p class="body-2 mb-0 ml-2">{{ item.readPlcNm }}</p>
|
||||
</div>
|
||||
</v-col>
|
||||
<v-col cols="2" align="center">
|
||||
<p class="body-2 mb-0">
|
||||
{{
|
||||
String(Math.floor(item.instantVal)).replace(
|
||||
/\B(?=(\d{3})+(?!\d))/g,
|
||||
',',
|
||||
)
|
||||
}}
|
||||
</p>
|
||||
</v-col>
|
||||
<v-col cols="2" align="center">
|
||||
<v-icon
|
||||
:color="
|
||||
isDarkMode
|
||||
? tableDataGetDarkColorByState(item.stat)
|
||||
: tableDataGetLightColorByState(item.stat)
|
||||
"
|
||||
size="8"
|
||||
class="mr-1"
|
||||
>mdi-circle</v-icon
|
||||
>
|
||||
<span class="body-2">{{ item.stat }}</span>
|
||||
</v-col>
|
||||
<v-col
|
||||
cols="2"
|
||||
align="center"
|
||||
v-for="(item2, index) in readObjIdList"
|
||||
:key="item2.readPlcId"
|
||||
:class="{
|
||||
'v-banner--last': index === readObjIdList.length - 1,
|
||||
}"
|
||||
>
|
||||
<span class="body-2">{{ item[item2.readObjId] }}</span>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-banner>
|
||||
</div>
|
||||
</div>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions, mapMutations, mapState } from 'vuex'; // , mapActions
|
||||
import Vue from 'vue';
|
||||
import DateUtility from '~/plugins/dateUtility';
|
||||
import Utility from '~/plugins/utility';
|
||||
import Chart from '~/components/common/Chart';
|
||||
import MainReadReptReadObjMultiPop from '~/components/common/modal/MainReadReptReadObjMultiPop';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
parentPrgmId: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
widgetId: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
widgetPrgmId: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
widgetPopFg: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
widgetReflashMm: {
|
||||
type: Number,
|
||||
require: true,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
DateUtility,
|
||||
Chart,
|
||||
MainReadReptReadObjMultiPop,
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
searchParam(state) {
|
||||
return state.pageData[this.parentPrgmId][this.widgetId][
|
||||
this.widgetId + 'Data'
|
||||
];
|
||||
},
|
||||
isDarkMode: 'isDarkMode',
|
||||
}),
|
||||
selectValue: {
|
||||
get() {
|
||||
return this.energyCd;
|
||||
},
|
||||
set(value) {
|
||||
this.energyCd = value;
|
||||
},
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
energyCd() {
|
||||
this.getMainReadPlcStat();
|
||||
},
|
||||
},
|
||||
beforeCreate() {
|
||||
this.$store.commit('setWidgetPageData', {
|
||||
prgmId: this.$route.query.prgmId,
|
||||
mainReadReptWidget: { mainReadReptWidgetData },
|
||||
});
|
||||
},
|
||||
async created() {
|
||||
this.energyList = await this.postApiReturn({
|
||||
apiKey: 'selectEnergy',
|
||||
resKey: 'energyData',
|
||||
sendParam: {
|
||||
useFg: 1,
|
||||
},
|
||||
});
|
||||
this.energyCd = this.energyList[0].cd;
|
||||
this.search();
|
||||
this.timer = setInterval(this.search, this.widgetReflashMm);
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.clearTimeout(this.timer);
|
||||
},
|
||||
mounted() {},
|
||||
data() {
|
||||
return {
|
||||
blocNm: '',
|
||||
energyCd: '',
|
||||
energyList: [],
|
||||
mainReadPlcData: [],
|
||||
widgetId: 'mainReadReptWidget',
|
||||
dialogView: false,
|
||||
readObjIdList: [],
|
||||
readPlcIdList: [],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
...mapMutations({
|
||||
setPageData: 'setPageData',
|
||||
setWidgetChartOption: 'setWidgetChartOption',
|
||||
openDashboardWidget: 'openDashboardWidget',
|
||||
}),
|
||||
...mapActions({
|
||||
postApi: 'modules/list/postApi',
|
||||
postApiReturn: 'modules/list/postApiReturn',
|
||||
getEnergyList: 'modules/search/getEnergyList',
|
||||
}),
|
||||
setBlocNm() {
|
||||
this.blocNm = this.$store.state.userInfo.blocNm;
|
||||
if (this.blocNm != '') {
|
||||
this.blocNm = '[' + this.blocNm + ']';
|
||||
}
|
||||
},
|
||||
dialogViewChange() {
|
||||
this.getMainReadPlcStat();
|
||||
},
|
||||
async search() {
|
||||
this.setBlocNm();
|
||||
|
||||
await this.getMainReadPlcStat();
|
||||
},
|
||||
async getMainReadPlcStat() {
|
||||
if (
|
||||
this.$store.state.pageData[this.parentPrgmId].mainReadReptWidget
|
||||
.mainReadReptWidgetData.readObjList.length > 0
|
||||
) {
|
||||
this.readObjIdList = this.$store.state.pageData[
|
||||
this.parentPrgmId
|
||||
].mainReadReptWidget.mainReadReptWidgetData.readObjList.map(item => {
|
||||
return { readObjId: item.readObjId, readObjNm: item.readObjNm };
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
this.$store.state.pageData[this.parentPrgmId].mainReadReptWidget
|
||||
.mainReadReptWidgetData.plcKindList.length > 0
|
||||
) {
|
||||
this.readPlcIdList = this.$store.state.pageData[
|
||||
this.parentPrgmId
|
||||
].mainReadReptWidget.mainReadReptWidgetData.plcKindList.map(item => {
|
||||
return item.readPlcId;
|
||||
});
|
||||
}
|
||||
this.mainReadPlcData = await this.postApiReturn({
|
||||
apiKey: 'selectMainReadPlcStat',
|
||||
resKey: 'mainReadPlcData',
|
||||
sendParam: {
|
||||
readObjIdList: this.readObjIdList,
|
||||
readPlcIdList: this.readPlcIdList,
|
||||
},
|
||||
});
|
||||
|
||||
// this.mainReadPlcData = [
|
||||
// {
|
||||
// "rowNum" : 1,
|
||||
// "comId" : "CDR00",
|
||||
// "readPlcId" : "RPC000002",
|
||||
// "readPlcNm" : "[전력] LP-1_A동메인",
|
||||
// "readObjNm" : "Heartbit",
|
||||
// "readObjId" : "ROI000040",
|
||||
// "instantVal" : 11239.0,
|
||||
// "volt" : 228.9,
|
||||
// "ampr" : 55.1,
|
||||
// "ROI000001" : 93613.1,
|
||||
// "ROI000005" : 229.7,
|
||||
// "ROI000006" : 81.8,
|
||||
// "ROI000008" : 1,
|
||||
// "stat" : "가동중"
|
||||
// }
|
||||
// ]
|
||||
},
|
||||
btnAction(action) {
|
||||
switch (action) {
|
||||
case 'popWidget':
|
||||
this.openDashboardWidget({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetId: this.widgetId,
|
||||
});
|
||||
break;
|
||||
case 'widgetCallPage':
|
||||
this.$parent.$parent.$parent.openWidgetPrgm(this.widgetId);
|
||||
break;
|
||||
}
|
||||
},
|
||||
tableDataGetDarkColorByState: state => {
|
||||
return {
|
||||
가동중: '#01ae6a',
|
||||
미사용: '#ffb046',
|
||||
비정상: '#f6637b',
|
||||
}[state];
|
||||
},
|
||||
tableDataGetLightColorByState: state => {
|
||||
return {
|
||||
가동중: '#3cc380',
|
||||
미사용: '#ffb13b',
|
||||
비정상: '#f98694',
|
||||
}[state];
|
||||
},
|
||||
readObjDialog() {
|
||||
this.$store.state.pageData[
|
||||
this.parentPrgmId
|
||||
].mainReadReptWidget.mainReadReptWidgetData.enrgDiv = this.$refs[
|
||||
'selectEnergy'
|
||||
].selectedItems[0].enrgDiv;
|
||||
this.$refs['MainReadReptReadObjMultiPop'].dialog = true;
|
||||
},
|
||||
},
|
||||
};
|
||||
const mainReadReptWidgetData = {
|
||||
readObjModalData: {},
|
||||
isMulti: true,
|
||||
blocId: 0,
|
||||
blocMstrList: [],
|
||||
readObjList: [],
|
||||
energyCd: '',
|
||||
energyList: [],
|
||||
readObj: {},
|
||||
enrgDiv: '',
|
||||
plcKindList: [],
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.v-avatar {
|
||||
border-radius: 21px;
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
.v-virtual-scroll-wrapper {
|
||||
overflow-y: auto;
|
||||
max-height: 210px;
|
||||
}
|
||||
</style>
|
361
components/widget/PeakTrndWidget.vue
Normal file
361
components/widget/PeakTrndWidget.vue
Normal file
@ -0,0 +1,361 @@
|
||||
<template>
|
||||
<div class="l-layout">
|
||||
<v-row ref="rowParent">
|
||||
<v-col :cols="12">
|
||||
<v-card class="pa-3 widget-card">
|
||||
<div class="d-flex align-center justify-space-between">
|
||||
<v-card-title class="pa-0">전력피크 트랜드</v-card-title>
|
||||
<v-card-subtitle class="mt-0 pa-0">
|
||||
<v-icon
|
||||
v-show="widgetPrgmId"
|
||||
class="mr-1"
|
||||
size="25"
|
||||
@click="btnAction('widgetCallPage')"
|
||||
>mdi-note-search</v-icon
|
||||
>
|
||||
<v-icon
|
||||
v-show="widgetPopFg"
|
||||
size="25"
|
||||
@click="btnAction('popWidget')"
|
||||
>mdi-plus-box-multiple</v-icon
|
||||
>
|
||||
</v-card-subtitle>
|
||||
</div>
|
||||
<div class="mt-1" align="right">
|
||||
현재 피크 : {{ nowPeakVal }}kW ({{ peakRto }}%) / 요금적용전력 :
|
||||
{{ chargedPower }}kW
|
||||
</div>
|
||||
<div class="d-flex align-center justify-space-between">
|
||||
<div :style="{ width: '100%', height: '200px' }">
|
||||
<component
|
||||
class="w100 h100"
|
||||
:is="loadChart_01 ? 'Chart' : null"
|
||||
:parentPrgmId="parentPrgmId"
|
||||
:widgetId="'PeakTrndWidget'"
|
||||
:widgetData="'PeakTrndWidgetData'"
|
||||
:chartName="chart_01"
|
||||
ref="chart_01"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions, mapMutations, mapState } from 'vuex'; // , mapActions
|
||||
import Vue from 'vue';
|
||||
import DateUtility from '~/plugins/dateUtility';
|
||||
import Utility from '~/plugins/utility';
|
||||
import Chart from '~/components/common/Chart';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
parentPrgmId: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
widgetId: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
widgetPrgmId: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
widgetPopFg: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
widgetReflashMm: {
|
||||
type: Number,
|
||||
require: true,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
DateUtility,
|
||||
Chart,
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
searchParam(state) {
|
||||
return state.pageData[this.parentPrgmId];
|
||||
},
|
||||
isDarkMode: 'isDarkMode',
|
||||
}),
|
||||
},
|
||||
watch: {},
|
||||
beforeCreate() {
|
||||
this.$store.commit('setWidgetPageData', {
|
||||
prgmId: this.$route.query.prgmId,
|
||||
PeakTrndWidget: { PeakTrndWidgetData },
|
||||
});
|
||||
},
|
||||
async created() {
|
||||
this.search();
|
||||
this.timer = setInterval(this.search, this.widgetReflashMm);
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.clearTimeout(this.timer);
|
||||
},
|
||||
mounted() {},
|
||||
data() {
|
||||
return {
|
||||
blocNm: '',
|
||||
//차트
|
||||
chart_01: 'peakUsage',
|
||||
loadChart_01: false,
|
||||
//바인딩
|
||||
rdbElecQual: 'Kw',
|
||||
chargedPower: 0,
|
||||
nowPeakVal: 0,
|
||||
peakRto: 0,
|
||||
dtToday: Utility.setFormatDate(new Date(), 'YYYY/MM/DD HH'),
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
...mapMutations({
|
||||
setPageData: 'setPageData',
|
||||
setWidgetChartOption: 'setWidgetChartOption',
|
||||
openDashboardWidget: 'openDashboardWidget',
|
||||
}),
|
||||
...mapActions({
|
||||
postApi: 'modules/list/postApi',
|
||||
postApiReturn: 'modules/list/postApiReturn',
|
||||
getEnergyList: 'modules/search/getEnergyList',
|
||||
}),
|
||||
setBlocNm() {
|
||||
this.blocNm = this.$store.state.userInfo.blocNm;
|
||||
if (this.blocNm != '') {
|
||||
this.blocNm = '[' + this.blocNm + ']';
|
||||
}
|
||||
},
|
||||
async search() {
|
||||
this.setBlocNm();
|
||||
await this.getPeakUsage();
|
||||
},
|
||||
async getPeakUsage() {
|
||||
this.loadChart_01 = false;
|
||||
let markAreaData = [];
|
||||
let markColor = {
|
||||
MAX: 'rgba(238, 102, 102, 0.1)',
|
||||
MID: 'rgba(250, 200, 88, 0.1)',
|
||||
MIN: 'rgba(145, 204, 117, 0.1)',
|
||||
};
|
||||
|
||||
// 부하시간 가져오기
|
||||
let res3 = [];
|
||||
res3 = await this.postApiReturn({
|
||||
apiKey: 'selectPeakKine',
|
||||
resKey: 'peakData',
|
||||
sendParam: {
|
||||
readObjId: 'ROI000001',
|
||||
toObjDt: Utility.setFormatDate(new Date(), 'YYYYMMDD'),
|
||||
},
|
||||
});
|
||||
|
||||
markAreaData = res3.map(item => [
|
||||
{
|
||||
name: item.commCdNm,
|
||||
xAxis:
|
||||
parseInt(item.strtTm.split(':')[0].replace(/(^0+)/, '')) == 23
|
||||
? 0
|
||||
: parseInt(item.strtTm.split(':')[0].replace(/(^0+)/, '')),
|
||||
itemStyle: {
|
||||
color: markColor[item.peakKine],
|
||||
},
|
||||
label: {
|
||||
distance: [0],
|
||||
fontSize: 9,
|
||||
fontWeight: 'lighter',
|
||||
color: '#fff',
|
||||
},
|
||||
},
|
||||
{
|
||||
xAxis: parseInt(item.endTm.split(':')[0].replace(/(^0+)/, '')),
|
||||
},
|
||||
]);
|
||||
//전력 조회
|
||||
let res = await this.postApiReturn({
|
||||
apiKey: 'selectPeakTrnd',
|
||||
resKey: 'peakTrndData',
|
||||
sendParam: {
|
||||
blocId: this.$store.state.userInfo.blocId,
|
||||
readObjId: 'ROI000001',
|
||||
toObjDt: Utility.setFormatDate(new Date(), 'YYYYMMDD'),
|
||||
},
|
||||
});
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.setChart01Data(res, markAreaData);
|
||||
});
|
||||
|
||||
// 상단에 표시할 요금전용전력, 현재피크
|
||||
this.sendParamData = {
|
||||
readObjId: 'ROI000001',
|
||||
toObjDt: Utility.setFormatDate(new Date(), 'YYYYMMDD'),
|
||||
cmCycle: 'CYC_HOUR',
|
||||
blocId: this.$store.state.userInfo.blocId,
|
||||
};
|
||||
|
||||
this.getPeakPowTitle();
|
||||
},
|
||||
async getPeakPowTitle() {
|
||||
if (this.sendParamData != undefined) {
|
||||
let res3 = [];
|
||||
res3 = await this.postApiReturn({
|
||||
apiKey: 'selectPeakPowAndChargedPower',
|
||||
resKey: 'peakData',
|
||||
// sendParam: {dateType: this.pageData.cmCycle, date: this.pageData.dtToday}
|
||||
sendParam: this.sendParamData,
|
||||
});
|
||||
|
||||
let res4 = [];
|
||||
res4 = await this.postApiReturn({
|
||||
apiKey: 'selectUseWithPeak',
|
||||
resKey: 'peakData',
|
||||
sendParam: {},
|
||||
});
|
||||
|
||||
res3.forEach(item => {
|
||||
this.chargedPower =
|
||||
item.peakVal == 0 ? 0 : Utility.setFormatInt(item.peakVal);
|
||||
});
|
||||
|
||||
res4.forEach((item, idx) => {
|
||||
this.nowPeakVal =
|
||||
item.curPeakVal == 0 ? 0 : Utility.setFormatInt(item.curPeakVal);
|
||||
this.peakRto =
|
||||
item.peakRto == 0 ? 0 : Utility.setFormatDecimal(item.peakRto, 0);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
//차트Setting
|
||||
async setChart01Data(data, markAreaData) {
|
||||
this.loadChart_01 = false;
|
||||
|
||||
this.$store.state.pageData[
|
||||
this.parentPrgmId
|
||||
].PeakTrndWidget.PeakTrndWidgetData.series = [];
|
||||
if (!data.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
let xAxisData = [];
|
||||
let legendData = [];
|
||||
|
||||
// chart color 집합
|
||||
let colorPalette = {
|
||||
PLCPEAK: '#D73964',
|
||||
PLCMAX: 'rgba(252,151,175,0.7)',
|
||||
};
|
||||
|
||||
let seriesDataList = [];
|
||||
|
||||
let myKey = Object.keys(data[0]);
|
||||
myKey = myKey.filter(v => {
|
||||
return v.search('qty') != -1;
|
||||
});
|
||||
myKey.sort();
|
||||
|
||||
for (var i = 0; i < 24; i++) {
|
||||
xAxisData.push(i + '시');
|
||||
}
|
||||
|
||||
seriesDataList = data.map(item => ({
|
||||
name: item.plcNm,
|
||||
type: item.plcCd == 'PLCMAX' ? 'bar' : 'line',
|
||||
color:
|
||||
item.plcCd == 'PLCPEAK'
|
||||
? colorPalette[item.plcCd]
|
||||
: item.plcCd == 'PLCMAX'
|
||||
? colorPalette[item.plcCd]
|
||||
: colorPalette[item.readObjId],
|
||||
symbol: item.plcCd == 'PLCPEAK' ? 'none' : 'circle',
|
||||
data: myKey.map(key => item[key] || 0),
|
||||
yAxisIndex:
|
||||
item.readObjId == 'ROI000013' || item.readObjId == 'ROI000014'
|
||||
? 1
|
||||
: 0,
|
||||
markArea: item.plcCd == 'PLCMAX' ? { data: markAreaData } : 'none',
|
||||
}));
|
||||
|
||||
var chartOption = {
|
||||
series: seriesDataList,
|
||||
grid: {
|
||||
left: '1%',
|
||||
right: '2%',
|
||||
top: '15%',
|
||||
bottom: '15%',
|
||||
containLabel: true,
|
||||
},
|
||||
legend: {
|
||||
bottom: 'bottom',
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
//boundaryGap: false,
|
||||
splitLine: false,
|
||||
data: xAxisData,
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
name: 'kWh',
|
||||
splitLine: {
|
||||
show: false,
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#767D83',
|
||||
fontSize: 9,
|
||||
formatter: '{value}',
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
},
|
||||
};
|
||||
|
||||
this.setWidgetChartOption({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetKey: 'PeakTrndWidget',
|
||||
widgetData: 'PeakTrndWidgetData',
|
||||
chartKey: 'peakUsage',
|
||||
value: chartOption,
|
||||
});
|
||||
|
||||
this.loadChart_01 = true;
|
||||
},
|
||||
btnAction(action) {
|
||||
switch (action) {
|
||||
case 'popWidget':
|
||||
this.openDashboardWidget({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetId: this.widgetId,
|
||||
});
|
||||
break;
|
||||
case 'widgetCallPage':
|
||||
this.$parent.$parent.$parent.openWidgetPrgm(this.widgetId);
|
||||
break;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
const PeakTrndWidgetData = {
|
||||
peakUsage: Utility.defaultChartOption(true),
|
||||
sendParamData: { readObjId: '' },
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.v-avatar {
|
||||
border-radius: 21px;
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
.v-virtual-scroll-wrapper {
|
||||
overflow-y: auto;
|
||||
max-height: 210px;
|
||||
}
|
||||
</style>
|
524
components/widget/PeakWidget.vue
Normal file
524
components/widget/PeakWidget.vue
Normal file
@ -0,0 +1,524 @@
|
||||
<template>
|
||||
<div class="l-layout">
|
||||
<v-row ref="rowParent">
|
||||
<v-col :cols="12">
|
||||
<v-card class="pa-3 widget-card">
|
||||
<div class="d-flex align-center justify-space-between">
|
||||
<v-card-title class="pa-0">전력피크</v-card-title>
|
||||
<v-card-subtitle class="mt-0 pa-0">
|
||||
<v-icon
|
||||
v-show="widgetPrgmId"
|
||||
class="mr-1"
|
||||
size="25"
|
||||
@click="btnAction('widgetCallPage')"
|
||||
>mdi-note-search</v-icon
|
||||
>
|
||||
<v-icon
|
||||
v-show="widgetPopFg"
|
||||
size="25"
|
||||
@click="btnAction('popWidget')"
|
||||
>mdi-plus-box-multiple</v-icon
|
||||
>
|
||||
</v-card-subtitle>
|
||||
</div>
|
||||
<div class="d-flex align-center justify-space-between mt-1">
|
||||
<div class="mr-2">
|
||||
<div :style="{ width: '220px', height: '170px' }">
|
||||
<component
|
||||
class="w100 h100"
|
||||
:is="loadChart_01 ? 'Chart' : null"
|
||||
:parentPrgmId="parentPrgmId"
|
||||
:widgetId="'peakWidget'"
|
||||
:widgetData="'peakWidgetData'"
|
||||
:chartName="chart_01"
|
||||
ref="chart_01"
|
||||
/>
|
||||
</div>
|
||||
<p class="custom-title-3 text-center">{{ elecContNm }}</p>
|
||||
</div>
|
||||
<div class="container">
|
||||
<v-card-subtitle class="mt-0 mb-1 pa-0 text-right">
|
||||
<span class="subtitle-2 mr-2"
|
||||
>현재온도
|
||||
<span :style="{ color: isDarkMode ? '#2d8cf6' : '#366dbe' }"
|
||||
>{{ curTmpr }} ℃</span
|
||||
></span
|
||||
>
|
||||
{{ blocNm }} {{ dtToday }} 기준
|
||||
</v-card-subtitle>
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
<div class="v-box-widget">
|
||||
<v-icon
|
||||
size="42"
|
||||
:color="isDarkMode ? '#22273c' : '#4a568d'"
|
||||
>$darkDashChargeWidget</v-icon
|
||||
>
|
||||
<div class="text-right">
|
||||
<strong class="custom-title-2"
|
||||
>{{ chargedPower }}
|
||||
<span class="body-2">kW</span></strong
|
||||
>
|
||||
<p class="body-2 mt-1 mb-0 text-color--non-activate">
|
||||
요금 적용전력
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<div class="v-box-widget">
|
||||
<v-icon
|
||||
size="42"
|
||||
:color="isDarkMode ? '#22273c' : '#4a568d'"
|
||||
>$darkDashPeakWidget</v-icon
|
||||
>
|
||||
<div class="text-right">
|
||||
<strong class="custom-title-3"
|
||||
>{{ seasnNm }}/{{ peakNm }}</strong
|
||||
>
|
||||
<p class="body-2 mt-1 mb-0 text-color--non-activate">
|
||||
현재부하
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<div class="v-box-widget">
|
||||
<v-icon
|
||||
size="42"
|
||||
:color="isDarkMode ? '#22273c' : '#4a568d'"
|
||||
>$darkDashChargeWidget</v-icon
|
||||
>
|
||||
<div class="text-right">
|
||||
<strong class="custom-title-2"
|
||||
>{{ unitPrce }} <span class="body-2">원</span></strong
|
||||
>
|
||||
<p class="body-2 mt-1 mb-0 text-color--non-activate">
|
||||
전력 부하단가
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
<div class="v-box-widget">
|
||||
<v-icon
|
||||
size="42"
|
||||
:color="isDarkMode ? '#22273c' : '#4a568d'"
|
||||
>$darkDashPeakWidget</v-icon
|
||||
>
|
||||
<div class="text-right">
|
||||
<strong class="custom-title-2"
|
||||
>{{ curPeakVal }} <span class="body-2">kW</span></strong
|
||||
>
|
||||
<p class="body-2 mt-1 mb-0 text-color--non-activate">
|
||||
현재 피크전력
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<div class="v-box-widget">
|
||||
<v-icon
|
||||
size="42"
|
||||
:color="isDarkMode ? '#22273c' : '#4a568d'"
|
||||
>$darkDashPeakWidget</v-icon
|
||||
>
|
||||
<div class="text-right">
|
||||
<strong class="custom-title-2"
|
||||
>{{ curPeakFcstVal }}
|
||||
<span class="body-2">kW</span></strong
|
||||
>
|
||||
<p class="body-2 mt-1 mb-0 text-color--non-activate">
|
||||
예상 피크전력
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<div
|
||||
id="mmPeakDt"
|
||||
class="v-box-widget"
|
||||
hover-tooltip="123"
|
||||
tooltip-position="top"
|
||||
>
|
||||
<v-icon
|
||||
size="42"
|
||||
:color="isDarkMode ? '#22273c' : '#4a568d'"
|
||||
>$darkDashPeakWidget</v-icon
|
||||
>
|
||||
<div class="text-right">
|
||||
<strong class="custom-title-2"
|
||||
>{{ mmPeakVal }}<span class="body-2">kW</span></strong
|
||||
>
|
||||
<p class="body-2 mt-1 mb-0 text-color--non-activate">
|
||||
당월 최대부하
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions, mapMutations, mapState } from 'vuex'; // , mapActions
|
||||
import Vue from 'vue';
|
||||
import DateUtility from '~/plugins/dateUtility';
|
||||
import Utility from '~/plugins/utility';
|
||||
import Chart from '~/components/common/Chart';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
parentPrgmId: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
widgetId: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
widgetPrgmId: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
widgetPopFg: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
widgetReflashMm: {
|
||||
type: Number,
|
||||
require: true,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
DateUtility,
|
||||
Chart,
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
searchParam(state) {
|
||||
return state.pageData[this.parentPrgmId];
|
||||
},
|
||||
isDarkMode: 'isDarkMode',
|
||||
}),
|
||||
},
|
||||
watch: {},
|
||||
beforeCreate() {
|
||||
this.$store.commit('setWidgetPageData', {
|
||||
prgmId: this.$route.query.prgmId,
|
||||
peakWidget: { peakWidgetData },
|
||||
});
|
||||
// console.log("2.vue::beforeCreate");
|
||||
},
|
||||
created() {
|
||||
this.search();
|
||||
this.timer = setInterval(this.search, this.widgetReflashMm);
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.clearTimeout(this.timer);
|
||||
},
|
||||
mounted() {},
|
||||
data() {
|
||||
return {
|
||||
dtToday: Utility.setFormatDate(new Date(), 'YYYY-MM-DD HH:mm'),
|
||||
dtYr: '1/1~' + Utility.setFormatDate(new Date(), 'M/D'),
|
||||
dtBf:
|
||||
DateUtility.addMonth(-1, 'M', new Date()) +
|
||||
'/1~' +
|
||||
DateUtility.addMonth(-1, 'M/D', new Date()),
|
||||
dtMm:
|
||||
Utility.setFormatDate(new Date(), 'M') +
|
||||
'/1~' +
|
||||
Utility.setFormatDate(new Date(), 'M/D'),
|
||||
currHour: '0시-' + Utility.setFormatDate(new Date(), 'H') + '시',
|
||||
blocNm: '',
|
||||
//차트
|
||||
chart_01: 'peakGauge',
|
||||
loadChart_01: false,
|
||||
//바인딩
|
||||
curTmpr: 0, //현재 외기온도
|
||||
chargedPower: 0, //요금 적용전력
|
||||
curPeakVal: 0, //현재 피크전력
|
||||
curPeakFcstVal: 0, //예상 피크전력
|
||||
elecContNm: '', //전력계약
|
||||
peakNm: '', //현재 부하
|
||||
seasnNm: '', //현재 계절
|
||||
unitPrce: 0, //전력 부하단가
|
||||
mmPeakVal: 0, //당월 최대부하
|
||||
peakDt: '', //당월 최대부하 일시
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
...mapMutations({
|
||||
setPageData: 'setPageData',
|
||||
setWidgetChartOption: 'setWidgetChartOption',
|
||||
openDashboardWidget: 'openDashboardWidget',
|
||||
setWidgetInterval: 'setWidgetInterval',
|
||||
}),
|
||||
...mapActions({
|
||||
postApi: 'modules/list/postApi',
|
||||
postApiReturn: 'modules/list/postApiReturn',
|
||||
}),
|
||||
setBlocNm() {
|
||||
this.blocNm = this.$store.state.userInfo.blocNm;
|
||||
if (this.blocNm != '') {
|
||||
this.blocNm = '[' + this.blocNm + ']';
|
||||
}
|
||||
},
|
||||
async search() {
|
||||
this.setBlocNm();
|
||||
|
||||
this.dtToday = Utility.setFormatDate(new Date(), 'YYYY-MM-DD HH:mm');
|
||||
this.dtYr = '1/1~' + Utility.setFormatDate(new Date(), 'M/D');
|
||||
this.dtBf =
|
||||
DateUtility.addMonth(-1, 'M', new Date()) +
|
||||
'/1~' +
|
||||
DateUtility.addMonth(-1, 'M/D', new Date());
|
||||
this.dtMm =
|
||||
Utility.setFormatDate(new Date(), 'M') +
|
||||
'/1~' +
|
||||
Utility.setFormatDate(new Date(), 'M/D');
|
||||
this.currHour = '0시-' + Utility.setFormatDate(new Date(), 'H') + '시';
|
||||
|
||||
//현재 외기온도
|
||||
await this.getOutside();
|
||||
//피크전력, 예상피크전력
|
||||
await this.getElecPeakRead();
|
||||
//부하단가, 전력부하
|
||||
await this.getElecPowChrg();
|
||||
//당월최대부하
|
||||
await this.getPeakPowMonth();
|
||||
},
|
||||
async getElecPeakRead() {
|
||||
this.loadChart_01 = false;
|
||||
const res = await this.postApiReturn({
|
||||
apiKey: 'selectElecPeakRead',
|
||||
resKey: 'elecPeakReadData',
|
||||
sendParam: {},
|
||||
});
|
||||
|
||||
res.forEach((item, idx) => {
|
||||
this.chargedPower = Utility.setFormatInt(item.peakVal);
|
||||
this.curPeakVal = Utility.setFormatInt(item.curPeakVal);
|
||||
this.curPeakFcstVal = Utility.setFormatInt(item.curPeakFcstVal);
|
||||
});
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.setChart01Data(res);
|
||||
});
|
||||
},
|
||||
async getElecPowChrg() {
|
||||
const res = await this.postApiReturn({
|
||||
apiKey: 'selectElecPowChrg',
|
||||
resKey: 'elecPowChrgData',
|
||||
sendParam: {
|
||||
readDt: Utility.setFormatDate(new Date(), 'YYYYMMDD'),
|
||||
readDtMm: Utility.setFormatDate(new Date(), 'MM'),
|
||||
},
|
||||
});
|
||||
|
||||
res.forEach((item, idx) => {
|
||||
this.elecContNm = item.elecContNm;
|
||||
this.peakNm = item.peakNm;
|
||||
this.seasnNm = item.seasnNm;
|
||||
this.unitPrce = Utility.setFormatInt(item.unitPrce);
|
||||
});
|
||||
},
|
||||
async getOutside() {
|
||||
const res = await this.postApiReturn({
|
||||
apiKey: 'selectOutside',
|
||||
resKey: 'dayOutsideData',
|
||||
sendParam: {},
|
||||
});
|
||||
|
||||
res.forEach((item, idx) => {
|
||||
this.curTmpr = item.val;
|
||||
});
|
||||
},
|
||||
async getPeakPowMonth() {
|
||||
const res = await this.postApiReturn({
|
||||
apiKey: 'selectPeakPowAndChargedPower',
|
||||
resKey: 'peakData',
|
||||
sendParam: {
|
||||
cmCycle: 'CYC_MONTH',
|
||||
fromObjDt: Utility.setFormatDate(new Date(), 'YYYYMM'),
|
||||
toObjDt: Utility.setFormatDate(new Date(), 'YYYYMM'),
|
||||
},
|
||||
});
|
||||
|
||||
res.forEach((item, idx) => {
|
||||
this.peakDt = Utility.setFormatDate(item.date, 'YYYY/MM/DD HH');
|
||||
this.mmPeakVal = item.curPeakVal;
|
||||
});
|
||||
|
||||
if (this.peakDt != '' || this.peakDt != undefined)
|
||||
$('#mmPeakDt').attr('hover-tooltip', this.peakDt);
|
||||
},
|
||||
//차트Setting
|
||||
async setChart01Data(data) {
|
||||
this.$store.state.pageData[
|
||||
this.parentPrgmId
|
||||
].peakWidget.peakWidgetData.series = [];
|
||||
if (!data.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const arrDarkColors = {
|
||||
정상: '#01ae6a',
|
||||
주의: '#ffb046',
|
||||
위험: '#f6637b',
|
||||
};
|
||||
const arrLightColors = {
|
||||
정상: '#01ae6a',
|
||||
주의: '#ffb046',
|
||||
위험: '#f6637b',
|
||||
};
|
||||
|
||||
const darkGaugeColors = [
|
||||
[0.125, '#009245'],
|
||||
[0.25, '#39b54a'],
|
||||
[0.375, '#d9e021'],
|
||||
[0.5, '#fcee21'],
|
||||
[0.625, '#fbb03b'],
|
||||
[0.75, '#f7931e'],
|
||||
[0.875, '#f15a24'],
|
||||
[1.0, '#ed1c24'],
|
||||
];
|
||||
const lightGaugeColors = [
|
||||
[0.125, '#58c06f'],
|
||||
[0.25, '#7cd574'],
|
||||
[0.375, '#fbe462'],
|
||||
[0.5, '#ffd771'],
|
||||
[0.625, '#ffad7f'],
|
||||
[0.75, '#ff966e'],
|
||||
[0.875, '#ff706e'],
|
||||
[1.0, '#ff6689'],
|
||||
];
|
||||
|
||||
var chartOption = {
|
||||
series: [
|
||||
{
|
||||
type: 'gauge',
|
||||
startAngle: 180,
|
||||
endAngle: 0,
|
||||
min: 0,
|
||||
max: 100,
|
||||
radius: '100%',
|
||||
center: ['50%', '60%'],
|
||||
splitNumber: 8,
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
width: 30,
|
||||
color: this.isDarkMode ? darkGaugeColors : lightGaugeColors,
|
||||
},
|
||||
},
|
||||
splitLine: {
|
||||
show: false,
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
axisLabel: {
|
||||
show: false,
|
||||
},
|
||||
pointer: {
|
||||
length: '80%',
|
||||
width: 5,
|
||||
itemStyle: {
|
||||
color: this.isDarkMode ? '#fff' : '#333333',
|
||||
},
|
||||
},
|
||||
anchor: {
|
||||
show: true,
|
||||
showAbove: true,
|
||||
size: 10,
|
||||
itemStyle: {
|
||||
borderWidth: 10,
|
||||
borderColor: this.isDarkMode ? '#fff' : '#333333',
|
||||
},
|
||||
},
|
||||
title: {
|
||||
offsetCenter: ['90%', '30%'],
|
||||
fontSize: 20,
|
||||
color: this.isDarkMode
|
||||
? arrDarkColors[data[0].peakStat]
|
||||
: arrLightColors[data[0].peakStat],
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
detail: {
|
||||
fontSize: 20,
|
||||
offsetCenter: ['-75%', '30%'],
|
||||
valueAnimation: true,
|
||||
formatter: function(value) {
|
||||
return '{value|' + value.toFixed(2) + '}{unit|%}';
|
||||
},
|
||||
rich: {
|
||||
value: {
|
||||
fontSize: 20,
|
||||
color: this.isDarkMode ? '#fff' : '#111111',
|
||||
fontWeight: 'bolder',
|
||||
},
|
||||
unit: {
|
||||
fontSize: 14,
|
||||
color: this.isDarkMode ? '#fff' : '#111111',
|
||||
fontWeight: 'bolder',
|
||||
padding: [0, 0, -5, 0],
|
||||
},
|
||||
},
|
||||
},
|
||||
data: [
|
||||
{
|
||||
name: data[0].peakStat,
|
||||
value: data[0].peakRto,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
this.setWidgetChartOption({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetKey: 'peakWidget',
|
||||
widgetData: 'peakWidgetData',
|
||||
chartKey: 'peakGauge',
|
||||
value: chartOption,
|
||||
});
|
||||
|
||||
this.loadChart_01 = true;
|
||||
},
|
||||
btnAction(action) {
|
||||
switch (action) {
|
||||
case 'popWidget':
|
||||
this.openDashboardWidget({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetId: this.widgetId,
|
||||
});
|
||||
break;
|
||||
case 'widgetCallPage':
|
||||
this.$parent.$parent.$parent.openWidgetPrgm(this.widgetId);
|
||||
break;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
const peakWidgetData = {
|
||||
peakGauge: Utility.defaultChartOption(true),
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.v-avatar {
|
||||
border-radius: 21px;
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
.v-virtual-scroll-wrapper {
|
||||
overflow-y: auto;
|
||||
max-height: 210px;
|
||||
}
|
||||
</style>
|
646
components/widget/StmUseRsltWidget.vue
Normal file
646
components/widget/StmUseRsltWidget.vue
Normal file
@ -0,0 +1,646 @@
|
||||
<template>
|
||||
<div class="l-layout">
|
||||
<v-row ref="rowParent">
|
||||
<v-col :cols="12">
|
||||
<v-card class="pa-3 widget-card">
|
||||
<div class="d-flex align-center justify-space-between">
|
||||
<v-card-title class="pa-0">스팀 사용량 실적</v-card-title>
|
||||
<v-card-subtitle class="mt-0 pa-0 text-right">
|
||||
<v-icon
|
||||
v-show="widgetPrgmId"
|
||||
class="mr-1"
|
||||
size="25"
|
||||
@click="btnAction('widgetCallPage')"
|
||||
>mdi-note-search</v-icon
|
||||
>
|
||||
<v-icon
|
||||
v-show="widgetPopFg"
|
||||
size="25"
|
||||
@click="btnAction('popWidget')"
|
||||
>mdi-plus-box-multiple</v-icon
|
||||
>
|
||||
</v-card-subtitle>
|
||||
</div>
|
||||
<div class="row wrapper">
|
||||
<div class="col-6">
|
||||
<div class="px-5 pb-1">
|
||||
<div class="text-center">
|
||||
<strong class="custom-title-2-5"
|
||||
>{{ dayUseQty }}
|
||||
<span class="font-weight-regular custom-text-2"
|
||||
>kWh</span
|
||||
></strong
|
||||
>
|
||||
<div class="d-flex align-center justify-center">
|
||||
<span class="body-2 text-color--non-activate"
|
||||
>전주 대비({{ currHour }})</span
|
||||
>
|
||||
<div
|
||||
class="d-flex align-baseline ml-2"
|
||||
:style="{
|
||||
color: isDarkMode
|
||||
? isUseQtyStat
|
||||
? '#f6637b'
|
||||
: '#01ae6a'
|
||||
: isUseQtyStat
|
||||
? '#ff76bb'
|
||||
: '#00c875',
|
||||
}"
|
||||
>
|
||||
<strong class="mr-1 custom-text-1">{{
|
||||
compareUseQty
|
||||
}}</strong>
|
||||
<span class="caption mr-1">kWh</span>
|
||||
<v-icon
|
||||
small
|
||||
:color="
|
||||
isDarkMode
|
||||
? isUseQtyStat
|
||||
? '#f6637b'
|
||||
: '#01ae6a'
|
||||
: isUseQtyStat
|
||||
? '#ff76bb'
|
||||
: '#00c875'
|
||||
"
|
||||
>{{ useQtyStat }}</v-icon
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="px-5 pb-1">
|
||||
<div class="text-center">
|
||||
<strong class="custom-title-2-5"
|
||||
>{{ dayUseCost }}
|
||||
<span class="font-weight-regular custom-text-2"
|
||||
>천원</span
|
||||
></strong
|
||||
>
|
||||
<div class="d-flex align-center justify-center">
|
||||
<span class="body-2 text-color--non-activate"
|
||||
>전주 대비(0시-{{ currHour }})</span
|
||||
>
|
||||
<div
|
||||
class="d-flex align-baseline ml-2"
|
||||
:style="{
|
||||
color: isDarkMode
|
||||
? isUseCostStat
|
||||
? '#f6637b'
|
||||
: '#01ae6a'
|
||||
: isUseCostStat
|
||||
? '#ff76bb'
|
||||
: '#00c875',
|
||||
}"
|
||||
>
|
||||
<strong class="mr-1 custom-text-1">{{
|
||||
compareUseCost
|
||||
}}</strong>
|
||||
<span class="caption mr-1">천원</span>
|
||||
<v-icon
|
||||
small
|
||||
:color="
|
||||
isDarkMode
|
||||
? isUseCostStat
|
||||
? '#f6637b'
|
||||
: '#01ae6a'
|
||||
: isUseCostStat
|
||||
? '#ff76bb'
|
||||
: '#00c875'
|
||||
"
|
||||
>{{ useCostStat }}</v-icon
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex align-center justify-space-between mt-2">
|
||||
<div :style="{ width: '100%', height: '160px' }">
|
||||
<component
|
||||
class="w100 h100"
|
||||
:is="loadChart_01 ? 'Chart' : null"
|
||||
:parentPrgmId="parentPrgmId"
|
||||
:widgetId="'enrgUseRsltWidget'"
|
||||
:widgetData="'enrgUseRsltWidgetData'"
|
||||
:chartName="chart_01"
|
||||
ref="chart_01"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions, mapMutations, mapState } from 'vuex'; // , mapActions
|
||||
import Vue from 'vue';
|
||||
import DateUtility from '~/plugins/dateUtility';
|
||||
import Utility from '~/plugins/utility';
|
||||
import Chart from '~/components/common/Chart';
|
||||
export default {
|
||||
props: {
|
||||
parentPrgmId: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
widgetId: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
widgetPrgmId: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
widgetPopFg: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
widgetReflashMm: {
|
||||
type: Number,
|
||||
require: true,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
DateUtility,
|
||||
Chart,
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
searchParam(state) {
|
||||
return state.pageData[this.parentPrgmId];
|
||||
},
|
||||
isDarkMode: 'isDarkMode',
|
||||
}),
|
||||
},
|
||||
watch: {
|
||||
// rdbEnrgUsage(){
|
||||
// this.getEnrgUsage();
|
||||
// },
|
||||
energyCd() {
|
||||
this.getEnrgUsage();
|
||||
this.getChartData();
|
||||
},
|
||||
},
|
||||
beforeCreate() {
|
||||
this.$store.commit('setWidgetPageData', {
|
||||
prgmId: this.$route.query.prgmId,
|
||||
enrgUseRsltWidget: { enrgUseRsltWidgetData },
|
||||
});
|
||||
},
|
||||
async created() {
|
||||
this.energyList = await this.postApiReturn({
|
||||
apiKey: 'selectEnergy',
|
||||
resKey: 'energyData',
|
||||
sendParam: {
|
||||
useFg: 1,
|
||||
},
|
||||
});
|
||||
|
||||
this.energyList.filter(item => {
|
||||
if (item.readObjCd == 'STEAM') {
|
||||
//스팀
|
||||
this.energyCd = item.cd;
|
||||
this.unit = item.unit;
|
||||
}
|
||||
});
|
||||
|
||||
this.search();
|
||||
this.timer = setInterval(this.search, this.widgetReflashMm);
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.clearTimeout(this.timer);
|
||||
},
|
||||
mounted() {},
|
||||
data() {
|
||||
return {
|
||||
// blocNm:'',
|
||||
//바인딩
|
||||
energyCd: '',
|
||||
energyList: [],
|
||||
unit: '',
|
||||
currHour: Utility.setFormatDate(new Date(), 'H') + '시 기준',
|
||||
isUseQtyStat: true,
|
||||
isUseCostStat: true,
|
||||
dayUseQty: 0,
|
||||
compareUseQty: 0,
|
||||
useQtyStat: null,
|
||||
dayUseCost: 0,
|
||||
compareUseCost: 0,
|
||||
useCostStat: null,
|
||||
// 차트
|
||||
chart_01: 'enrgUsageChart',
|
||||
loadChart_01: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
...mapMutations({
|
||||
setPageData: 'setPageData',
|
||||
setWidgetChartOption: 'setWidgetChartOption',
|
||||
openDashboardWidget: 'openDashboardWidget',
|
||||
setWidgetChartYaxisData: 'setWidgetChartYaxisData',
|
||||
}),
|
||||
...mapActions({
|
||||
postApi: 'modules/list/postApi',
|
||||
postApiReturn: 'modules/list/postApiReturn',
|
||||
getEnergyList: 'modules/search/getEnergyList',
|
||||
}),
|
||||
async search() {
|
||||
// this.setBlocNm();
|
||||
await this.getEnrgUsage();
|
||||
await this.getChartData();
|
||||
},
|
||||
async getEnrgUsage() {
|
||||
const res = await this.postApiReturn({
|
||||
apiKey: 'selectUseCostDay',
|
||||
resKey: 'dayUseCostData',
|
||||
sendParam: {
|
||||
readObjId: this.energyCd,
|
||||
},
|
||||
});
|
||||
const res2 = await this.postApiReturn({
|
||||
apiKey: 'selectUseCostPast',
|
||||
resKey: 'pastUseCostData',
|
||||
sendParam: {
|
||||
readObjId: this.energyCd,
|
||||
},
|
||||
});
|
||||
res.forEach((item, idx) => {
|
||||
this.dayUseQty = Utility.setFormatInt(item.qty);
|
||||
this.dayUseCost = Utility.setFormatInt(item.cost);
|
||||
});
|
||||
let dayUseQty,
|
||||
dayUseQtyAvg,
|
||||
dayUseCost,
|
||||
dayUseCostAvg,
|
||||
dayUseMaxQty,
|
||||
dayUseMaxCost = 0;
|
||||
if (res.length > 0) {
|
||||
dayUseQty = res[0].qty;
|
||||
dayUseCost = res[0].cost;
|
||||
}
|
||||
if (res2.length > 0) {
|
||||
dayUseQtyAvg = res2[0].qtyAvg;
|
||||
dayUseCostAvg = res2[0].costAvg;
|
||||
dayUseMaxQty = res2[0].maxQty;
|
||||
dayUseMaxCost = res2[0].maxCost;
|
||||
}
|
||||
this.compareUseQty = Utility.setFormatInt(dayUseQty - dayUseQtyAvg);
|
||||
this.compareUseCost = Utility.setFormatInt(dayUseCost - dayUseCostAvg);
|
||||
this.useQtyStat =
|
||||
dayUseQty > dayUseQtyAvg ? 'mdi-arrow-up' : 'mdi-arrow-down';
|
||||
this.useCostStat =
|
||||
dayUseCost > dayUseCostAvg ? 'mdi-arrow-up' : 'mdi-arrow-down';
|
||||
|
||||
this.isUseQtyStat = this.useQtyStat == 'mdi-arrow-up' ? true : false;
|
||||
this.isUseCostStat = this.useCostStat == 'mdi-arrow-up' ? true : false;
|
||||
},
|
||||
setChartData(data) {
|
||||
let xAxisData = [];
|
||||
let seriesData = [];
|
||||
let legendData = [];
|
||||
let arrDarkColors = ['rgba(1, 174, 106, 0.7)', 'rgba(67, 133, 227, 0.7)'];
|
||||
let arrLightColors = [
|
||||
'rgba(207, 116, 229, 0.7)',
|
||||
'rgba(106, 155, 244, 0.7)',
|
||||
];
|
||||
const arrColors = this.isDarkMode ? arrDarkColors : arrLightColors;
|
||||
// chart x축 data
|
||||
var qtyNumber, qtyStr;
|
||||
for (var i = 0; i < 24; i++) {
|
||||
qtyNumber = i.toString().padStart(2, '0');
|
||||
qtyStr = 'qty' + qtyNumber;
|
||||
xAxisData.push(i + '시');
|
||||
}
|
||||
// chart_data 중 누적 사용량과 누적 금액 구분
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var tempObj = { data: [] };
|
||||
tempObj['type'] = 'line';
|
||||
tempObj['lineStyle'] = { width: 2 };
|
||||
tempObj['smooth'] = true;
|
||||
tempObj['showSymbol'] = false;
|
||||
tempObj['color'] = arrColors[i];
|
||||
if (data[i]['type'] == 'use') {
|
||||
tempObj['name'] = '누적 사용량';
|
||||
legendData.push('누적 사용량');
|
||||
tempObj['areaStyle'] = {
|
||||
opacity: 0.5,
|
||||
color: arrColors[i],
|
||||
};
|
||||
tempObj['yAxisIndex'] = 0;
|
||||
} else if (data[i]['type'] == 'cost') {
|
||||
tempObj['name'] = '누적 금액';
|
||||
legendData.push('누적 금액');
|
||||
tempObj['yAxisIndex'] = 1;
|
||||
} else if (data[i]['type'] == 'week') {
|
||||
tempObj['name'] = '전주 평균 누적 사용량';
|
||||
legendData.push('전주 평균 누적 사용량');
|
||||
tempObj['yAxisIndex'] = 0;
|
||||
}
|
||||
// 0~23시 까지의 데이터 seriesData 넣기
|
||||
for (var j = 0; j < 24; j++) {
|
||||
qtyNumber = j.toString().padStart(2, '0');
|
||||
qtyStr = 'qty' + qtyNumber;
|
||||
if (data[i].hasOwnProperty(qtyStr)) {
|
||||
// tempObj['data'].push(Utility.setFormatIntDecimal(parseFloat(data[i][qtyStr]), 2).replace(',',''));
|
||||
tempObj['data'].push(parseFloat(data[i][qtyStr]));
|
||||
} else {
|
||||
tempObj['data'].push(0);
|
||||
}
|
||||
}
|
||||
seriesData.push(tempObj);
|
||||
}
|
||||
|
||||
const yAxisData = [
|
||||
{
|
||||
type: 'value',
|
||||
name: this.unit,
|
||||
splitLine: {
|
||||
show: false,
|
||||
},
|
||||
nameTextStyle: {
|
||||
fontSize: 12,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#767D83',
|
||||
fontSize: 9,
|
||||
formatter: '{value}',
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'value',
|
||||
name: '원',
|
||||
splitLine: {
|
||||
show: false,
|
||||
},
|
||||
nameTextStyle: {
|
||||
fontSize: 12,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#767D83',
|
||||
fontSize: 9,
|
||||
formatter: '{value}',
|
||||
},
|
||||
},
|
||||
];
|
||||
var chartOption = {
|
||||
series: seriesData,
|
||||
grid: {
|
||||
left: '1%',
|
||||
right: '2%',
|
||||
top: '20%',
|
||||
bottom: '15%',
|
||||
containLabel: true,
|
||||
},
|
||||
legend: {
|
||||
data: legendData,
|
||||
bottom: 'bottom',
|
||||
icon: 'bar',
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
//boundaryGap: false,
|
||||
splitLine: false,
|
||||
data: xAxisData,
|
||||
axisLabel: {
|
||||
fontSize: 9,
|
||||
},
|
||||
},
|
||||
// yAxis: [
|
||||
// {
|
||||
// type: 'value',
|
||||
// name: this.unit,
|
||||
// splitLine: {
|
||||
// show: false
|
||||
// },
|
||||
// nameTextStyle: {
|
||||
// fontSize: 12,
|
||||
// fontWeight:'bold'
|
||||
// },
|
||||
// axisLabel:{
|
||||
// color: "#767D83",
|
||||
// fontSize: 9,
|
||||
// formatter: '{value}'
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// type: 'value',
|
||||
// name: '원',
|
||||
// splitLine: {
|
||||
// show: false
|
||||
// },
|
||||
// nameTextStyle: {
|
||||
// fontSize: 12,
|
||||
// fontWeight:'bold'
|
||||
// },
|
||||
// axisLabel:{
|
||||
// color: "#767D83",
|
||||
// fontSize: 9,
|
||||
// formatter: '{value}'
|
||||
// }
|
||||
// }
|
||||
// ],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
},
|
||||
};
|
||||
|
||||
this.setWidgetChartOption({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetKey: 'enrgUseRsltWidget',
|
||||
widgetData: 'enrgUseRsltWidgetData',
|
||||
chartKey: 'enrgUsageChart',
|
||||
value: chartOption,
|
||||
});
|
||||
this.setWidgetChartYaxisData({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetKey: 'enrgUseRsltWidget',
|
||||
widgetData: 'enrgUseRsltWidgetData',
|
||||
chartKey: 'enrgUsageChart',
|
||||
value: yAxisData,
|
||||
});
|
||||
this.loadChart_01 = true;
|
||||
},
|
||||
async getChartData() {
|
||||
this.loadChart_01 = false;
|
||||
var root_info = null;
|
||||
var res_useage = null;
|
||||
var res_cost = null;
|
||||
var facList = null;
|
||||
var filtered_res = null;
|
||||
var apiParameters = {
|
||||
blocId: 'BL0001',
|
||||
readObjId: this.energyCd,
|
||||
locKind: '',
|
||||
upEccId: '',
|
||||
};
|
||||
var sendParam_chart_data = {
|
||||
blocId: 'BL0001',
|
||||
eccId: [],
|
||||
eccNm: [],
|
||||
fromObjDt: Utility.setFormatDate(new Date(), 'YYYYMMDD'),
|
||||
lockKind: '',
|
||||
readObjId: this.energyCd,
|
||||
toObjDt: Utility.setFormatDate(new Date(), 'YYYYMMDD'),
|
||||
upEccId: '',
|
||||
};
|
||||
var check_flag = true;
|
||||
// 공정/설비 트리리스트 중 에너지원에 따른 최상위 정보 가져오기
|
||||
try {
|
||||
root_info = await this.postApiReturn({
|
||||
apiKey: 'selectFtnPlcListTree',
|
||||
resKey: 'ftnPlcTreeDatas',
|
||||
sendParam: {
|
||||
blocId: 'BL0001',
|
||||
roiId: this.energyCd,
|
||||
eqpmYn: 1,
|
||||
// search:this.searchWord
|
||||
},
|
||||
});
|
||||
filtered_res = root_info.filter(item => item.upEccId == 'ROOT');
|
||||
apiParameters['locKind'] = filtered_res[0].locKind;
|
||||
apiParameters['upEccId'] = filtered_res[0].eccId;
|
||||
sendParam_chart_data['lockKind'] = filtered_res[0].locKind;
|
||||
} catch (error) {
|
||||
root_info = [];
|
||||
filtered_res = [];
|
||||
}
|
||||
|
||||
// 위의 정보로 해당 검침개소 정보 가져오기
|
||||
try {
|
||||
facList = await this.postApiReturn({
|
||||
apiKey: 'selectEnergyUseReadDnPlc',
|
||||
resKey: 'energyUseReadDnPlc',
|
||||
sendParam: apiParameters,
|
||||
});
|
||||
for (var i in facList) {
|
||||
sendParam_chart_data['eccId'].push(facList[i]['eccId']);
|
||||
sendParam_chart_data['eccNm'].push(facList[i]['eccNm']);
|
||||
}
|
||||
// sendParam_chart_data['eccId'].push(facList[0]['eccId']);
|
||||
// sendParam_chart_data['eccNm'].push(facList[0]['eccNm']);
|
||||
sendParam_chart_data['upEccId'] = facList[0]['upEccId'];
|
||||
} catch (error) {
|
||||
check_flag = false;
|
||||
}
|
||||
|
||||
// 위의 정보로 검침개소 시간별 사용량 가져오기
|
||||
var final_chart_data = [];
|
||||
if (check_flag) {
|
||||
try {
|
||||
res_useage = await this.postApiReturn({
|
||||
apiKey: 'selectEnergyUseReadHourAddup',
|
||||
resKey: 'energyUseRead',
|
||||
sendParam: sendParam_chart_data,
|
||||
});
|
||||
|
||||
// root 하위 개소들의 사용량을 sum 함(쿼리에서 SUM 안했을 경우 사용)
|
||||
// var sum_data = {};
|
||||
// for (var i in res_useage){
|
||||
// res_useage[i]['type'] = 'use'
|
||||
// for (var key in res_useage[i]){
|
||||
// if(key.includes('qty')){
|
||||
// if(sum_data[key] == undefined){
|
||||
// sum_data[key] = res_useage[i][key]
|
||||
// }else{
|
||||
// sum_data[key] += res_useage[i][key]
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// // final_chart_data.push(res_useage[i])
|
||||
// }
|
||||
// final_chart_data.push({'type' : 'use', ...sum_data})
|
||||
|
||||
// root 하위 개소들의 사용량을 sum 함(쿼리에서 SUM을 했을 경우 사용)
|
||||
res_useage[0]['type'] = 'use';
|
||||
final_chart_data.push(res_useage[0]);
|
||||
} catch (error) {
|
||||
res_useage = [];
|
||||
}
|
||||
|
||||
try {
|
||||
res_cost = await this.postApiReturn({
|
||||
apiKey: 'selectEnergyUseReadHourCostAddup',
|
||||
resKey: 'energyUseRead',
|
||||
sendParam: sendParam_chart_data,
|
||||
});
|
||||
res_cost[0]['type'] = 'cost';
|
||||
final_chart_data.push(res_cost[0]);
|
||||
} catch (error) {
|
||||
res_cost = [];
|
||||
}
|
||||
} else {
|
||||
res_useage = [];
|
||||
res_cost = [];
|
||||
}
|
||||
// 전주 평균 누적 사용량
|
||||
let res_week_read = [];
|
||||
res_week_read = await this.postApiReturn({
|
||||
apiKey: 'selectEnergyUseReadLastWeekAddup',
|
||||
resKey: 'energyUseRead',
|
||||
sendParam: sendParam_chart_data,
|
||||
});
|
||||
if (res_week_read.length != 0) {
|
||||
res_week_read[0]['type'] = 'week';
|
||||
final_chart_data.push(res_week_read[0]);
|
||||
}
|
||||
// char data 넣기
|
||||
this.$nextTick(() => {
|
||||
this.setChartData(final_chart_data);
|
||||
});
|
||||
},
|
||||
btnAction(action) {
|
||||
switch (action) {
|
||||
case 'popWidget':
|
||||
this.openDashboardWidget({
|
||||
prgmId: this.$route.query.prgmId,
|
||||
widgetId: this.widgetId,
|
||||
});
|
||||
break;
|
||||
case 'widgetCallPage':
|
||||
this.$parent.$parent.$parent.openWidgetPrgm(this.widgetId);
|
||||
break;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const enrgUseRsltWidgetData = {
|
||||
isFind: false,
|
||||
enrgUsageChart: Utility.defaultChartOption(true),
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.v-avatar {
|
||||
border-radius: 21px;
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
.v-virtual-scroll-wrapper {
|
||||
overflow-y: auto;
|
||||
max-height: 210px;
|
||||
}
|
||||
.v-radio > label {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
.v-list-item {
|
||||
min-height: 30px;
|
||||
line-height: 1;
|
||||
}
|
||||
.v-list-item__content > * {
|
||||
line-height: 1;
|
||||
}
|
||||
.v-select__widget > .v-input__control > .v-input__slot {
|
||||
min-width: 60%;
|
||||
}
|
||||
.wrapper {
|
||||
padding: 5px 10px 0px 10px !important;
|
||||
border-bottom: thin solid rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user