sk_fems_ui commit

This commit is contained in:
unknown
2025-07-12 15:13:46 +09:00
commit ffdf5ccb66
380 changed files with 137913 additions and 0 deletions

View File

@ -0,0 +1,599 @@
<template>
<div ref="mainDiv" class="l-layout">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="3">
<component
:is="'SelectAddGrp'"
:parentPrgmId="myPrgmId"
:label="'추가 정보 그룹'"
dataKey="searchAddGrp"
:sendParam="{ useFg: '1' }"
:addAll="true"
/>
</v-col>
<v-col :cols="3">
<InputText
:parentPrgmId="myPrgmId"
label="추가 정보명"
valueNm="addInfoNm"
:searchOption="true"
/>
</v-col>
<v-col :cols="3">
<component
:is="'selectCodeList'"
:parentPrgmId="myPrgmId"
:label="'사용여부'"
dataKey="useFg"
:sendParam="{ commGrpCd: 'CO_USEFG', useFg: '1' }"
:addAll="true"
/>
</v-col>
<v-col :cols="3" class="text-right">
<BtnSearch @click="search" />
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents">
<v-col :cols="5" class="h100">
<v-card class="pb-5">
<v-card-title class="d-flex justify-space-between align-end">
<span class="tit ft-size_20 ft-weight_600">추가 정보</span>
<Buttons
:parentPrgmId="myPrgmId"
:bindingData="gridName"
:btnActionsFnc="btnActions"
/>
</v-card-title>
<div class="px-5" style="height:calc(100% - 76px)">
<div ref="gridParent" class="w100 h100">
<component
:ref="gridName"
:is="loadGrid ? 'Grid' : null"
:gridName="gridName"
:parentPrgmId="myPrgmId"
@getRowsData="getRowData"
/>
</div>
</div>
</v-card>
</v-col>
<v-col :cols="7" class="h100">
<v-card class="pb-5">
<div class="d-flex align-center justify-space-between pa-5">
<v-card-title class="pa-0">추가 정보 상세</v-card-title>
</div>
<div class="px-5" style="height:calc(100% - 76px)">
<component
:is="'Form'"
:parentPrgmId="myPrgmId"
:detailList="detailList"
@gridEditingFinish="gridEditingFinish"
/>
</div>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex';
import mixinGlobal from '@/mixin/global.js';
import { resize } from '@/mixin/resize.js';
import BtnSearch from '~/components/common/button/BtnSearch';
import Buttons from '~/components/common/button/Buttons';
import SelectAddGrp from '@/components/common/select/SelectAddGrp';
import InputText from '@/components/common/input/InputText';
import Form from '~/components/common/form/Form';
import Grid from '~/components/common/Grid';
import Utility from '~/plugins/utility';
import SelectUseFg from '@/components/common/select/SelectUseFg';
import selectCodeList from '@/components/common/select/selectCodeList';
let myTitle;
// const myPrgmId = "PRG0059";
let myPrgmId;
export default {
mixins: [mixinGlobal, resize],
async asyncData(context) {
const myState = context.store.state;
// context.store.commit("setActiveMenuInfo", myState.menuData[myPrgmId]);
// myTitle = myState.activeMenuInfo.menuNm;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
console.log('myState.menuData : ', myState.menuData);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
BtnSearch,
Buttons,
SelectAddGrp,
InputText,
Form,
Grid,
SelectUseFg,
selectCodeList,
},
data() {
return {
myPrgmId: myPrgmId,
gridName: 'rowGrid',
loadGrid: false,
tab: null,
detailList: myDetail,
initedFlag: false,
};
},
computed: {
// ...mapState({
// pageData: state => state.pageData[myPrgmId]
// }),
chkIsFind() {
// 조회 플래그
return this.pageData.isFind;
},
chkAddGrp() {
return this.pageData.searchAddGrp;
},
chkUseFg() {
// 사용여부 선택 감지
return this.pageData.useFg;
},
initFlag() {
if (
!this.initedFlag &&
this.pageData.addInfoDataKindList &&
this.pageData.blocMstrList &&
this.pageData.useFgList &&
this.pageData.addInfoDataKindList.length > 0 &&
this.pageData.blocMstrList.length > 0 &&
this.pageData.useFgList.length > 0
) {
return true;
} else {
return false;
}
},
},
watch: {
chkIsFind(val) {
if (val) this.search();
},
chkUseFg() {
this.setPageData({ isFind: true });
},
chkAddGrp() {
this.setPageData({ isFind: true });
},
initFlag(val) {
if (val) {
this.init();
this.initedFlag = true;
}
},
},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
created() {
/////////// 추가 정보 Tab 에서 사용
// 데이터 유형 목록 조회
this.getCodeList({
dataKey: 'addInfoDataKind',
params: { commGrpCd: 'CO_DATA_TYPE', useFg: '1' },
addAll: false,
});
// 추가 정보 목록 조회
this.getAddGrpInfoList({
dataKey: 'addGrp',
params: { useFg: '1' },
addAll: false,
});
},
mounted() {
this.init();
},
beforeDestroy() {
this.initedFlag = false;
this.chkOpenTabList({ key: 'destroy', prgmId: myPrgmId });
},
methods: {
...mapActions({
getCodeList: 'modules/search/getCodeList',
getAddGrpInfoList: 'modules/search/getAddGrpInfoList',
}),
async init() {
await this.gridInit();
},
async gridInit() {
// await this.getCodeList({
// dataKey: "addInfoDataKind",
// params: { commGrpCd: 'CO_DATA_TYPE', useFg: '1'},
// addAll: false
// });
// // 추가 정보 목록 조회
// await this.getAddGrpInfoList({
// dataKey: "addGrp",
// params: { useFg: '1'},
// addAll: false
// });
const gridHeight = this.$refs.gridParent.offsetHeight - 30;
const myOptions = {
columnOptions: {
resizable: true,
},
};
this.setGridOption({
gridKey: this.gridName,
value: Object.assign(Utility.defaultGridOption(gridHeight), myOptions),
});
const _this = this;
const myColumns = [
{
header: '추가 정보 그룹',
name: 'addGrpId',
minWidth: 125,
align: 'left',
formatter({ value }) {
let retVal = '';
const newValue = _this.pageData.addGrpList.filter(
item => item.addGrpId == value,
);
if (newValue.length > 0) {
retVal = newValue[0].addGrpNm;
}
return retVal;
},
},
{
header: '추가 정보 ID',
name: 'addInfoId',
minWidth: 170,
align: 'left',
},
{
header: '추가 정보 명',
name: 'addInfoNm',
minWidth: 170,
align: 'left',
},
{
header: 'Data 형식',
name: 'addInfoDataKind',
minWidth: 85,
align: 'center',
formatter({ value }) {
let retVal = '';
const newValue = _this.pageData.addInfoDataKindList.filter(
item => item.commCd == value,
);
console.log('newValue[데이터 형식] : ', newValue);
if (newValue.length > 0) {
retVal = newValue[0].commCdNm;
}
return retVal;
},
},
{
header: '사용여부',
name: 'useFg',
minWidth: 85,
align: 'center',
formatter({ value }) {
let retVal = '';
value = value === true ? '1' : '0';
const newValue = _this.pageData.useFgList.filter(
item => item.commCd == value,
);
console.log('newValue[사용여부] : ', newValue);
if (newValue.length > 0) {
retVal = newValue[0].commCdNm;
}
return retVal;
},
},
{ header: '등록자NO', name: 'regUserNo', hidden: true },
{ header: '등록일시', name: 'regDttm', hidden: true },
{ header: '수정자NO', name: 'procUserNo', hidden: true },
{ header: '수정일시', name: 'procDttm', hidden: true },
];
this.setGridColumn({
gridKey: this.gridName,
value: myColumns,
});
this.loadGrid = true;
this.search();
},
async search() {
this.loadGrid = false;
await this.getRowGridData();
await this.setPageData({
isFind: false,
});
},
async getRowGridData() {
const res = await this.postApiReturn({
apiKey: 'selectAddInfo',
resKey: 'addInfoData',
sendParam: {
useFg: this.pageData.useFg,
addGrpId: this.pageData.searchAddGrp,
addInfoNmLike: this.pageData.addInfoNm,
},
});
const newRes = res.map(item => {
const newObj = {
...item,
rowStat: null,
useFg: item.useFg === '1' ? true : false, // 화면 개발 편의를 위해 boolean 타입으로 교체, 저장시 "1", "0" 으로 바꿔 보내야 함
};
return newObj;
});
this.setGridData({
gridKey: this.gridName,
value: newRes,
});
this.loadGrid = true;
this.$nextTick(() => {
if (newRes.length > 0) {
this.$refs[this.gridName].focus({
//rowKey: 0,
rowKey:
this.pageData.rowGridSelectKey == '' ||
this.pageData.rowGridSelectKey == null
? 0
: this.pageData.rowGridSelectKey ==
this.$refs[this.gridName].getData().length - 1
? this.pageData.rowGridSelectKey
: 0,
setScroll: true,
});
}
});
},
async getRowData(data) {
if (data.rowStat === 'I') {
this.detailList[0].disabled = false;
this.detailList[1].disabled = false;
} else {
this.detailList[0].disabled = true;
this.detailList[1].disabled = true;
}
this.setPageData({
rowGridSelectKey: data.rowKey,
rowGridSelectData: data,
});
},
gridEditingFinish(data) {
this.$refs[this.gridName].editingFinish(data);
},
async btnActions(action) {
let dataArr = [];
switch (action) {
case 'add':
this.$refs[this.gridName].addRow();
this.detailList[0].disabled = false;
this.detailList[1].disabled = false;
break;
case 'remove':
this.$refs[this.gridName].removeRow();
break;
case 'save':
dataArr = this.$refs[this.gridName].save();
var validCheck = true;
if (dataArr.length > 0) {
dataArr.filter(item => {
if (item.rowStat === 'I') {
if (
item.addGrpId == '' ||
item.addInfoId == '' ||
item.addInfoNm == '' ||
item.addInfoDataKind == ''
) {
alert('필수 입력값을 입력해주세요.');
validCheck = false;
}
} else if (item.rowStat === 'U') {
if (item.addInfoNm == '') {
alert('추가 정보 명을 입력해주세요');
validCheck = false;
}
}
});
if (validCheck) {
const sendParam = {
datas: {
dsAddInfo: dataArr.map(item => ({
...item,
addGrpId: item.addGrpId,
useFg: item.useFg ? '1' : '0',
})),
},
params: {},
};
await this.postUpdateApi({
apiKey: 'saveAddInfo',
sendParam: sendParam,
});
this.$nextTick(() => {
this.setPageData({ isFind: true });
});
}
} else {
alert('저장할 내용이 없습니다.');
}
break;
default:
break;
}
},
},
};
const defaultData = {
/* 검색옵션 */
addInfoNm: '',
useFg: '1',
useFgList: [],
searchAddGrp: '',
searchAddGrpList: [],
addInfoDataKind: '',
addInfoDataKindList: [],
addGrp: '',
addGrpList: [],
// 선택된 그룹코드 상세 데이터
rowGridSelectKey: 0,
rowGridSelectData: null,
isFind: false, // true 경우 조회, 조회버튼도 이 값으로 연동 예정
/* data 세팅 */
// 로컬 gridName 값과 동일한 이름으로 세팅
rowGrid: {
data: [],
column: [], // myColumns,
option: {}, // myOptions
defaultRow: {
addGrpId: '',
addInfoId: '',
addInfoNm: '',
addInfoDataKind: 'NUM',
useFg: '1',
rowStat: null,
},
buttonAuth: {
add: true,
remove: true,
save: true,
excel: false,
},
},
};
const myDetail = [
{
type: 'SelectBox',
label: '추가 정보 그룹',
valueNm: 'addGrpId',
disabled: true,
cols: 6,
class: 'py-2',
list: 'addGrpList',
itemText: 'addGrpNm',
itemValue: 'addGrpId',
required: true,
},
{
type: 'InputText',
label: '추가정보 ID',
valueNm: 'addInfoId',
disabled: true,
cols: 6,
class: 'py-2',
required: true,
},
{
type: 'InputText',
label: '추가 정보 명',
valueNm: 'addInfoNm',
disabled: false,
cols: 6,
class: 'py-2',
required: true,
},
{
type: 'SelectBox',
label: 'Data 형식',
valueNm: 'addInfoDataKind',
disabled: false,
cols: 6,
class: 'py-2',
list: 'addInfoDataKindList',
itemText: 'commCdNm',
itemValue: 'commCd',
required: true,
},
{
type: 'CheckBox',
label: '사용 여부',
valueNm: 'useFg',
disabled: false,
cols: 6,
class: 'py-2',
value: { '1': true, '0': false },
required: true,
},
{
type: 'InputText',
label: '등록자NO',
valueNm: 'regUserNo',
disabled: true,
cols: 6,
class: 'py-2',
placeholder: '시스템 자동입력',
},
{
type: 'InputText',
label: '등록일시',
valueNm: 'regDttm',
disabled: true,
cols: 6,
class: 'py-2',
placeholder: '시스템 자동입력',
},
{
type: 'InputText',
label: '수정자NO',
valueNm: 'procUserNo',
disabled: true,
cols: 6,
class: 'py-2',
placeholder: '시스템 자동입력',
},
{
type: 'InputText',
label: '수정일시',
valueNm: 'procDttm',
disabled: true,
cols: 6,
class: 'py-2',
placeholder: '시스템 자동입력',
},
];
</script>
<style lang="scss">
@import '@/assets/scss/common.scss';
</style>

View File

@ -0,0 +1,719 @@
<template>
<div class="l-layout">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="3">
<v-row class="search-box" align="center" no-gutters>
<v-col :cols="4">
<label for="" class="search-box-label">
<v-icon x-small color="primary" class="mr-1"
>mdi-record-circle</v-icon
>
사업장
</label>
</v-col>
<v-col :cols="7">
<v-select
v-model="blocId"
:items="blocMstrList"
item-text="blocNm"
item-value="blocId"
solo
outlined
:hide-details="true"
append-icon="mdi-chevron-down"
class="v-select__custom"
></v-select>
</v-col>
</v-row>
</v-col>
<v-col :cols="3">
<v-row class="search-box" align="center" no-gutters>
<v-col :cols="4">
<label for="" class="search-box-label">
<v-icon x-small color="primary" class="mr-1"
>mdi-record-circle</v-icon
>
검침대상유형
</label>
</v-col>
<v-col :cols="7">
<v-select
v-model="roiGrpCode"
:items="roiGrpCodeList"
item-text="commCdNm"
item-value="commCd"
solo
outlined
:hide-details="true"
append-icon="mdi-chevron-down"
class="v-select__custom"
></v-select>
</v-col>
</v-row>
</v-col>
<v-col :cols="3">
<v-row class="search-box" align="center" no-gutters>
<v-col :cols="4">
<label for="" class="search-box-label">
<v-icon x-small color="primary" class="mr-1"
>mdi-record-circle</v-icon
>
검침대상
</label>
</v-col>
<v-col :cols="7">
<v-select
v-model="mttCd"
:items="mttCdList"
item-text="mttNm"
item-value="mttCd"
solo
outlined
:hide-details="true"
append-icon="mdi-chevron-down"
class="v-select__custom"
></v-select>
</v-col>
</v-row>
</v-col>
<v-col :cols="3" class="text-right">
<v-btn :ripple="false" class="mr-1" @click="searchGrid2()"
>조회</v-btn
>
<BtnExcelDownload
class="mr-1"
:parentPrgmId="myPrgmId"
:gridName="gridName"
/>
</v-col>
</v-row>
<v-row align="center" no-gutters>
<v-col :cols="3">
<component
ref="fromPicker"
:is="'Datepicker'"
:parentPrgmId="myPrgmId"
:label="'조회기간'"
/>
</v-col>
<v-col :cols="4">
<v-row class="search-box" align="center" no-gutters>
<v-col :cols="3">
<label for="" class="search-box-label">
<v-icon x-small color="primary" class="mr-1"
>mdi-record-circle</v-icon
>정시만조회</label
>
</v-col>
<v-col :cols="1">
<v-checkbox
v-model="timeChkValue"
:color="isDarkMode ? '#fff' : '#4777d9'"
></v-checkbox>
</v-col>
</v-row>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents">
<v-col :cols="3">
<v-card class="pb-5">
<div class="d-flex align-center justify-space-between pa-5">
<v-card-title class="pa-0 custom-title-4"
>검침개소 리스트</v-card-title
>
<div>
<v-btn :ripple="false" icon tile @click="btnTreeExpand()">
<v-icon
size="30"
v-text="treeExpandAll ? 'mdi-chevron-up' : 'mdi-chevron-down'"
></v-icon>
</v-btn>
</div>
</div>
<div style="height:calc(100% - 76px)" class="px-5">
<div ref="treeGridParent" class="w100 h100">
<component
:ref="gridNameTree + myPrgmId"
:is="loadTree ? 'Grid' : null"
:gridName="gridNameTree"
:parentPrgmId="myPrgmId"
@getRowsData="getRowData"
/>
</div>
</div>
</v-card>
</v-col>
<v-col :cols="9">
<v-card class="pb-5">
<div class="d-flex align-center justify-space-between pa-5">
<v-card-title class="pa-0 custom-title-4"
>시간별검침정보</v-card-title
>
<div class="d-flex align-center">
<v-select
v-model="tagId"
:items="tagIdList"
item-text="tagNm"
item-value="tagId"
solo
append-icon="mdi-chevron-down"
class="v-select__custom"
outlined
hide-details
></v-select>
<v-col :cols="1"> </v-col>
<Buttons
:parentPrgmId="myPrgmId"
:bindingData="gridName"
:btnActionsFnc="btnActions"
/>
</div>
</div>
<div style="height:calc(100% - 76px)" class="px-5">
<div ref="gridParent" class="w100 h100">
<component
:ref="gridName"
:is="loadGrid ? 'Grid' : null"
:gridName="gridName"
:parentPrgmId="myPrgmId"
:editorGrid="true"
@updateDataInfo="evtUpdateDataInfo"
/>
</div>
</div>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex';
import mixinGlobal from '@/mixin/global.js';
import Utility from '~/plugins/utility';
import SelectBlocMstr from '@/components/common/select/SelectBlocMstr';
import Datepicker from '~/components/common/Datepicker';
import Grid from '~/components/common/Grid';
import Buttons from '~/components/common/button/Buttons';
import BtnExcelDownload from '~/components/common/button/BtnExcelDownload';
let myTitle;
//const myPrgmId = "PRG0017";
let myPrgmId;
export default {
mixins: [mixinGlobal],
async asyncData(context) {
const myState = context.store.state;
// context.store.commit("setActiveMenuInfo", myState.menuData[myPrgmId]);
// myTitle = myState.activeMenuInfo.menuNm;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
SelectBlocMstr,
Datepicker,
Grid,
Buttons,
BtnExcelDownload,
},
data() {
return {
myPrgmId: myPrgmId,
createdFlag: false,
roiGrpCode: '',
roiGrpCodeList: [],
mttCd: '',
mttCdList: [],
blocId: '',
blocMstrList: [],
selectedRoiId: null,
tagId: '',
tagIdList: [],
timeChkValue: false,
treeExpandAll: true,
loadTree: false,
gridNameTree: 'treeGrid',
loadGrid: false,
gridName: 'rowGrid',
searchFlag: false,
selectedData: null,
};
},
computed: {
...mapState({
isDarkMode: state => state.isDarkMode,
pageData: state => state.pageData[myPrgmId],
}),
chkFromDt() {
// console.log("this", this.pageData)
return this.pageData.fromDt;
},
},
watch: {
async createdFlag(val) {
if (val === true) {
await this.init();
}
},
async searchFlag(val) {
if (val === true) {
await this.search();
}
},
async chkFromDt() {
await this.searchGrid2();
},
blocId() {
if (this.createdFlag === true) {
this.searchFlag = true;
}
},
mttCd(val) {
if (this.createdFlag === true) {
this.searchFlag = true;
}
},
tagId(val) {
if (this.createdFlag === true) {
for (var i = 0; i < this.tagIdList.length; i++) {
if (this.tagIdList[i]['tagId'] == this.tagId) {
this.selectedRoiId = this.tagIdList[i]['readObjId'];
}
}
this.setRowGridData();
}
},
async roiGrpCode(val) {
var idx = 0;
for (var i = 0; i < this.roiGrpCodeList.length; i++) {
if (this.roiGrpCodeList[i]['commCd'] == this.roiGrpCode) {
idx = i;
break;
}
}
this.mttCdList = await this.postApiReturn({
apiKey: 'selectMtt',
resKey: 'mttData',
sendParam: {
mttTp: this.roiGrpCodeList[idx]['commCd'],
mttGrp: this.roiGrpCodeList[idx]['userDefVal1'],
},
});
if (this.mttCdList.length > 0) {
this.mttCd = this.mttCdList[0]['mttCd'];
}
},
async timeChkValue(val) {
await this.searchGrid2();
},
},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
async created() {
this.blocMstrList = await this.postApiReturn({
apiKey: 'selectBlocMstrCodeList',
resKey: 'blocCodeLists',
sendParam: {},
});
this.blocId = this.blocMstrList[0]['blocId'];
this.roiGrpCodeList = await this.postApiReturn({
apiKey: 'selectCodeList',
resKey: 'codeLists',
sendParam: {
commGrpCd: 'CM_MTTTP',
useFg: '1',
},
});
this.roiGrpCode = this.roiGrpCodeList[0]['commCd'];
this.mttCdList = await this.postApiReturn({
apiKey: 'selectMtt',
resKey: 'mttData',
sendParam: {
mttTp: this.roiGrpCodeList[0]['commCd'],
mttGrp: this.roiGrpCodeList[0]['userDefVal1'],
},
});
this.mttCd = this.mttCdList[0]['mttCd'];
this.createdFlag = true;
},
async mounted() {
// await this.init();
},
beforeDestroy() {
this.chkOpenTabList({ key: 'destroy', prgmId: myPrgmId });
},
methods: {
...mapMutations({
setPageData: 'setPageData',
setGridData: 'setGridData',
setGridColumn: 'setGridColumn',
setGridOption: 'setGridOption',
}),
...mapActions({
getCodeList: 'modules/search/getCodeList',
postApi: 'modules/list/postApi',
postUpdateApi: 'modules/list/postUpdateApi',
postApiReturn: 'modules/list/postApiReturn',
setTree: 'modules/list/setTree',
chkOpenTabList: 'chkOpenTabList',
}),
async init() {
this.gridInit();
await this.getTreeData();
},
async search() {
await this.getTreeData();
this.searchFlag = false;
},
async searchGrid2() {
await this.setRowGridData();
},
gridInit() {
const treeGridHeight = this.$refs.treeGridParent.offsetHeight - 35;
const gridHeight = this.$refs.gridParent.offsetHeight - 45;
const myOptionsTree = {
treeColumnOptions: {
name: 'readPlcNm',
},
scrollX: false,
};
const myOptions = {};
this.setGridOption({
gridKey: this.gridName,
value: Object.assign(Utility.defaultGridOption(gridHeight), myOptions),
});
this.setGridOption({
gridKey: this.gridNameTree,
value: Object.assign(
Utility.defaultGridOption(treeGridHeight),
myOptionsTree,
),
});
var columnList = [
{
header: 'TAG 명',
name: 'tagNm',
aling: 'center',
width: 450,
},
{
header: '검침일자',
name: 'readDt',
align: 'center',
formatter({ value }) {
return Utility.setFormatDate(value, 'YYYY-MM-DD');
},
},
{
header: '검침시간',
name: 'readTm',
align: 'center',
},
{
header: '검침값',
name: 'readVal',
align: 'right',
editor: 'text',
excelType: 'number',
excelFormatter: '2',
formatter: numberFormatter,
},
{
header: '배율(%)',
name: 'mgnf',
align: 'center',
},
{
header: '값(검침값*배율)',
name: 'readValMgnf',
align: 'right',
excelType: 'number',
excelFormatter: '2',
formatter: numberFormatter,
},
{
header: '단위',
name: 'unit',
align: 'center',
},
];
this.setGridColumn({
gridKey: this.gridName,
value: columnList,
});
},
async getTreeData() {
this.loadTree = false;
if (this.blocMstrList.length > 0) {
const res = await this.postApiReturn({
apiKey: 'selectReadPlc',
resKey: 'readPlacereg',
sendParam: {
blocId: this.blocId,
fromObjDt: Utility.setFormatDate(
this.pageData.fromDt,
'YYYY-MM-DD',
),
readObjKind: this.roiGrpCode,
readObjId: this.mttCd,
},
});
if (res.length === 0) {
this.tagId = '';
this.tagIdList = [];
this.selectedRoiId = null;
}
this.setGridColumn({
gridKey: this.gridNameTree,
value: [
{
header: '개소',
name: 'readPlcNm',
},
],
});
const setTreeData = await this.setTree({
treeKey: 'READ_PLC_ID',
value: res,
});
await this.setGridData({
gridKey: this.gridNameTree,
value: setTreeData.ROOT,
});
this.loadTree = true;
// gridData 초기화하는 부분
if (
this.$store.state.pageData[this.myPrgmId].treeGrid.data === undefined
) {
this.setGridData({
gridKey: this.gridName,
value: [],
});
}
this.$nextTick(() => {
this.$refs[this.gridNameTree + this.myPrgmId].focus({
rowKey: 0,
columnName: 'readPlcNm',
setScroll: true,
});
});
if (this.$refs[this.gridNameTree + this.myPrgmId] != undefined) {
this.$refs[this.gridNameTree + this.myPrgmId].expandAll();
}
}
},
async setTagIdList(readPlcId) {
this.tagIdList = await this.postApiReturn({
apiKey: 'selectTagNmList',
resKey: 'tagNmListData',
// apiKey : 'selectReadPlcTagRel',
// resKey : 'readPlcTagRelData',
sendParam: {
readPlc: readPlcId,
// 'readPlcId':readPlcId,
useFg: '1',
},
});
if (this.tagIdList.length === 0) {
this.tagId = '';
this.selectedRoiId = null;
this.tagIdList.push({
tagId: '',
tagNm: '',
readPlcId: null,
readObjId: null,
reprTagFg: null,
});
} else if (this.selectedRoiId == null) {
for (var i = 0; i < this.tagIdList.length; i++) {
if (this.tagIdList[i]['reprTagFg'] == 1) {
this.tagId = this.tagIdList[i]['tagId'];
this.selectedRoiId = this.tagIdList[i]['readObjId'];
}
}
if (this.tagId === '') {
this.tagId = this.tagIdList[0]['tagId'];
this.selectedRoiId = this.tagIdList[0]['readObjId'];
}
} else {
for (var i = 0; i < this.tagIdList.length; i++) {
if (this.tagIdList[i]['readObjId'] == this.selectedRoiId) {
this.tagId = this.tagIdList[i]['tagId'];
}
}
if (this.tagId === '') {
this.tagId = this.tagIdList[0]['tagId'];
this.selectedRoiId = this.tagIdList[0]['readObjId'];
}
}
},
async setRowGridData() {
this.loadGrid = false;
var res = [];
res = await this.postApiReturn({
apiKey: 'selectAutoRsltMng',
resKey: 'autoReadRsltData',
sendParam: {
blocId: this.blocId,
fromObjDt: Utility.setFormatDate(this.pageData.fromDt, 'YYYY-MM-DD'),
readObjId: this.mttCd,
mttTp: this.roiGrpCode,
readDt: Utility.setFormatDate(this.pageData.fromDt, 'YYYYMMDD'),
readPlc: this.selectedData.readPlcId,
readPlcNm: this.selectedData.readPlcNm,
tmFg: this.timeChkValue === false ? 0 : 1,
tagId: this.tagId,
},
});
const newRes = res.map(item => {
const newObj = {
...item,
rowStat: null,
};
return newObj;
});
this.setGridData({
gridKey: this.gridName,
value: newRes,
});
this.loadGrid = true;
},
async getRowData(data) {
this.selectedData = data;
await this.setTagIdList(this.selectedData.readPlcId);
await this.setRowGridData();
},
async btnActions(action) {
let dataArr = [];
switch (action) {
case 'add':
this.$refs[this.gridName].addRow();
break;
case 'remove':
this.$refs[this.gridName].removeRow();
break;
case 'save':
this.loadGrid = false;
dataArr = this.$refs[this.gridName].save();
if (dataArr.length > 0) {
const sendParam = {
datas: { dsAutoRsltMng: dataArr },
params: {},
};
await this.postUpdateApi({
apiKey: 'saveAutoRsltMng',
sendParam: sendParam,
});
this.setGridData({
gridKey: this.gridName,
value: [],
});
this.loadGrid = true;
this.searchFlag = true;
} else {
alert('저장할 내용이 없습니다.');
this.loadGrid = true;
}
break;
default:
break;
}
},
evtUpdateDataInfo(data) {
var gridInstance = this.$refs.rowGrid.$el.__vue__.$el.__vue__
.gridInstance;
gridInstance.invoke(
'setValue',
data.rowIdxKey,
'readValMgnf',
(data.value * data.rowData.mgnf) / 100.0,
);
},
btnTreeExpand() {
this.treeExpandAll = !this.treeExpandAll;
if (this.treeExpandAll)
this.$refs['treeGrid' + this.myPrgmId].expandAll();
else this.$refs['treeGrid' + this.myPrgmId].collapseAll();
},
},
};
const defaultData = {
/* 검색옵션 */
cmCycle: 'CYC_HOUR',
fromDt: Utility.setFormatDate(new Date(), 'YYYY/MM/DD'),
treeGrid: {
data: [],
column: [],
option: {},
},
rowGrid: {
data: [],
column: [],
option: {},
defaultRow: {
readDt: null,
readVal: 0,
regDttm: null,
readTm: null,
rowStat: '',
},
buttonAuth: {
save: true,
},
},
xlsFileInfo: {
// 출력하려는 grid 와 같은 이름으로 세팅
rowGrid: {
fileName: null, // 갑이 없으면 해당 페이지 메뉴명
sheetName: null, // 갑이 없으면 'Sheet1'
},
},
};
function numberFormatter({ value }) {
return Utility.setFormatIntDecimal(Number(value), 2);
}
</script>
<style lang="scss">
@import '@/assets/scss/common.scss';
</style>

View File

@ -0,0 +1,516 @@
<template>
<div class="l-layout">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="4">
<component :is="'SelectSysDiv'" :parentPrgmId="myPrgmId" />
</v-col>
<v-col :cols="4">
<component :is="'SelectUseFg'" :parentPrgmId="myPrgmId" />
</v-col>
<v-col :cols="4" class="text-right">
<BtnSearch @click="search" />
</v-col>
</v-row>
<v-row align="center" no-gutters>
<v-col :cols="4">
<InputText
:parentPrgmId="myPrgmId"
label="그룹코드"
valueNm="commGrpCd"
/>
</v-col>
<v-col :cols="4">
<InputText
:parentPrgmId="myPrgmId"
label="그룹코드명"
valueNm="commGrpCdNm"
/>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents">
<v-col :cols="5" class="h100">
<v-card class="py-5 h100">
<v-card-title class="d-flex justify-between">
<span class="tit ft-size_20 ft-weight_600">공통그룹코드</span>
<div>
<v-btn
class="v-btn-radius__20 v-btn-bg__white-blue mr-1"
@click="addRow"
>
<v-icon>mdi-plus</v-icon>
<span>추가</span>
</v-btn>
<v-btn
class="v-btn-radius__20 v-btn-bg__white-blue mr-1"
@click="removeRow"
>
<v-icon>mdi-delete-outline</v-icon>
<span>삭제</span>
</v-btn>
<v-btn class="v-btn-radius__20 v-btn-bg__blue" @click="save">
<v-icon>mdi-content-save</v-icon>
<span>저장</span>
</v-btn>
</div>
</v-card-title>
<v-card-actions>
<div ref="gridParent" class="h100 w100">
<component
ref="myGrid"
:is="loadGrid ? 'Grid' : null"
:gridName="gridName"
:parentPrgmId="myPrgmId"
@getRowsData="getRowData"
/>
</div>
</v-card-actions>
</v-card>
</v-col>
<v-col :cols="7" class="h100">
<v-card class="py-5">
<v-card-title>
<span class="tit ft-size_20 ft-weight_600">설비그룹 상세</span>
</v-card-title>
<v-card-actions class="flex-column">
<v-tabs v-model="tab">
<v-tab v-for="item in items" :key="item.id">
{{ item.name }}
</v-tab>
</v-tabs>
<v-tabs-items v-model="tab" style="height: calc(100% - 65px);">
<v-tab-item v-for="item in items" :key="item.id">
<GrpinfoTab
v-if="item.id == 'grpInfoTab'"
:parentPrgmId="myPrgmId"
/>
<CommCdTab
v-if="item.id == 'commCdTab'"
:parentPrgmId="myPrgmId"
/>
</v-tab-item>
</v-tabs-items>
</v-card-actions>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex';
import mixinGlobal from '@/mixin/global.js';
import { resize } from '@/mixin/resize.js';
import BtnSearch from '~/components/common/button/BtnSearch';
import SelectSysDiv from '@/components/common/select/SelectSysDiv';
import SelectUseFg from '@/components/common/select/SelectUseFg';
import InputText from '@/components/common/input/InputText';
import GrpinfoTab from '@/components/pages/comm/GrpCdInfoTab';
import CommCdTab from '@/components/pages/comm/CommCdTab';
import Grid from '~/components/common/Grid';
let myTitle;
let myPrgmId;
export default {
mixins: [mixinGlobal, resize],
async asyncData(context) {
const myState = context.store.state;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
BtnSearch,
SelectSysDiv,
SelectUseFg,
InputText,
GrpinfoTab,
CommCdTab,
Grid,
},
data() {
return {
myPrgmId: myPrgmId,
gridName: 'rowGrid',
loadGrid: false,
tab: null,
items: [
{ name: '그룹코드정보', id: 'grpInfoTab' },
{ name: '공통코드', id: 'commCdTab' },
],
};
},
computed: {
...mapState({
pageData: state => state.pageData[myPrgmId],
}),
chkIsFind() {
// 조회 플래그
return this.pageData.isFind;
},
chkSysDivCd() {
// 시스템구분 선택 감지
return this.pageData.sysDivCd;
},
chkUseFg() {
// 사용여부 선택 감지
return this.pageData.useFg;
},
selectedCommCdData() {
return this.pageData.selectedCommCdData;
},
modifySysDivCd() {
return this.pageData.modifySysDivCd;
},
modifyUseFg() {
return this.pageData.modifyUseFg;
},
modifyCommGrpCd() {
return this.pageData.modifyCommGrpCd;
},
modifyCommGrpCdNm() {
return this.pageData.modifyCommGrpCdNm;
},
modifyRmrk() {
return this.pageData.rmrk;
},
},
watch: {
chkIsFind(val) {
if (val) this.search();
},
chkSysDivCd() {
this.setPageData({ isFind: true });
},
chkUseFg() {
this.setPageData({ isFind: true });
},
modifyCommGrpCd(val) {
const isSameData = this.compareData('commGrpCd', val);
if (!isSameData) {
const dt = {
name: 'commGrpCd',
value: val,
};
this.$refs.myGrid.externalDataEdit(dt);
}
},
modifyCommGrpCdNm(val) {
const isSameData = this.compareData('commGrpNm', val);
if (!isSameData) {
const dt = {
name: 'commGrpNm',
value: val,
};
this.$refs.myGrid.externalDataEdit(dt);
}
},
modifySysDivCd(val) {
const isSameData = this.compareData('sysDiv', val);
if (!isSameData) {
const dt = {
name: 'sysDiv',
value: val,
};
this.$refs.myGrid.externalDataEdit(dt);
}
},
modifyUseFg(val) {
const isSameData = this.compareData('useFg', val);
if (!isSameData) {
const dt = {
name: 'useFg',
value: val,
};
this.$refs.myGrid.externalDataEdit(dt);
}
},
modifyRmrk(val) {
const isSameData = this.compareData('rmrk', val);
if (!isSameData) {
const dt = {
name: 'rmrk',
value: val,
};
this.$refs.myGrid.externalDataEdit(dt);
}
},
},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
mounted() {
this.init();
},
beforeDestroy() {
this.chkOpenTabList({ key: 'destroy', prgmId: myPrgmId });
},
methods: {
...mapMutations({
setPageData: 'setPageData',
setGridData: 'setGridData',
setGridColumn: 'setGridColumn',
setGridOption: 'setGridOption',
}),
...mapActions({
postApi: 'modules/list/postApi',
postUpdateApi: 'modules/list/postUpdateApi',
postApiReturn: 'modules/list/postApiReturn',
setTree: 'modules/list/setTree',
chkOpenTabList: 'chkOpenTabList',
}),
init() {
this.layoutInit();
this.gridInit();
},
layoutInit() {
const searchFilterHeight = this.$refs.searchFilter.offsetHeight;
this.$refs.contents.style.height = `calc(100% - ${searchFilterHeight}px)`;
},
gridInit() {
const gridHeight = this.$refs.gridParent.offsetHeight - 30;
const myOptions = {
columnOptions: {
resizable: true,
},
bodyHeight: gridHeight,
minBodyHeight: gridHeight,
header: {
height: 28,
},
rowHeight: 29,
minRowHeight: 29,
};
this.setGridOption({
gridKey: this.gridName,
value: myOptions,
});
const _this = this;
const myColumns = [
{
header: '시스템구분',
name: 'sysDiv',
align: 'center',
formatter({ value }) {
const newValue = _this.pageData.sysDivCdList.filter(
item => item.commCd == value,
);
return newValue[0].commCdNm;
},
},
{ header: '그룹코드', name: 'commGrpCd', align: 'center' },
{ header: '그룹코드명', name: 'commGrpNm' },
{
header: '사용여부',
name: 'useFg',
align: 'center',
formatter({ value }) {
const newValue = _this.pageData.useFgList.filter(
item => item.commCd == value,
);
return newValue[0].commCdNm;
},
},
{ header: '비고', name: 'rmrk', hidden: true },
];
this.setGridColumn({
gridKey: this.gridName,
value: myColumns,
});
this.getRowGridData();
this.loadGrid = true;
},
async search() {
await this.getRowGridData();
await this.setPageData({
isFind: false,
});
},
async getRowGridData() {
const res = await this.postApiReturn({
apiKey: 'selectCommGrpCd',
resKey: 'commGrpCdData',
sendParm: {
commGrpCd: this.pageData.commGrpCd,
commGrpNm: this.pageData.commGrpCdNm,
sysDivCd: this.pageData.sysDivCd,
useFg: this.pageData.useFg,
},
});
const newRes = res.map(item => {
const newObj = {
...item,
rowStat: null,
};
return newObj;
});
this.setGridData({
gridKey: this.gridName,
value: newRes,
});
this.$nextTick(() => {
if (newRes.length > 0) {
this.$refs['myGrid'].focus({
rowKey: 0,
columnName: 'sysDiv',
setScroll: true,
});
} else {
this.detailDataInit();
}
});
},
async getRowData(data) {
this.setPageData({
selectedRowKey: data.rowKey,
modifySysDivCd: data.sysDiv,
modifyUseFg: data.useFg,
modifyCommGrpCdNm: data.commGrpNm,
modifyCommGrpCd: data.commGrpCd,
rmrk: data.rmrk,
selectedCommCdData: data,
});
const res = await this.postApiReturn({
apiKey: 'selectCommCd',
resKey: 'commCdData',
sendParm: {
commGrpCd: data.commGrpCd,
},
});
const newRes = res.map(item => {
const newObj = {
...item,
rowStat: null,
};
return newObj;
});
this.setGridData({
gridKey: 'rowDetailGrid',
value: newRes,
});
},
detailDataInit() {
this.setPageData({
selectedCommCdData: null,
selectedRowKey: null,
modifySysDivCd: 'COMM',
modifyUseFg: '1',
modifyCommGrpCdNm: '',
modifyCommGrpCd: '',
rmrk: '',
});
this.setGridData({
gridKey: 'rowDetailGrid',
value: [],
});
},
compareData(type, newDt) {
if (this.selectedCommCdData[type] == newDt) {
return true;
} else {
return false;
}
},
addRow() {
this.$refs.myGrid.addRow();
},
removeRow() {
this.$refs.myGrid.removeRow();
},
async save() {
const dataArr = this.$refs.myGrid.save();
const sendParam = {
datas: { dsGrpCd: dataArr },
params: {},
};
await this.postUpdateApi({
apiKey: 'saveCommGrpCd',
sendParm: sendParam,
});
await this.search();
},
},
};
const defaultData = {
/* 검색옵션 */
sysDivCd: 'COMM',
sysDivCdList: [],
useFg: '1',
useFgList: [],
commGrpCd: '',
commGrpCdNm: '',
/* 그룹코드정보 탭 옵션 */
// 그롭코드정보 탭에서 사용될 사용여부 model 값 셋팅
modifySysDivCd: 'COMM',
modifyUseFg: '1',
modifyCommGrpCdNm: '',
modifyCommGrpCd: '',
rmrk: '',
isFind: false, // true 경우 조회, 조회버튼도 이 값으로 연동 예정
/* data 세팅 */
// 로컬 gridName 값과 동일한 이름으로 세팅
rowGrid: {
data: [],
column: [], // myColumns,
option: {}, // myOptions
defaultRow: {
sysDiv: 'COMM',
commGrpCd: '',
commGrpNm: '',
useFg: '1',
rmrk: '',
rowStat: null,
},
},
rowDetailGrid: {
data: [],
column: [], // myColumns,
option: {}, // myOptions
defaultRow: {
commCd: '',
commCdNm: '',
commCdAbbrnm: '',
sortSeq: '',
useFg: '1',
userDefVal1: '',
userDefVal2: '',
userDefVal3: '',
rowStat: null,
},
},
// 선택된 그룹코드 상세 데이터
selectedRowKey: null,
selectedCommCdData: null,
};
</script>
<style lang="scss">
@import '@/assets/scss/common.scss';
</style>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,682 @@
<template>
<div class="l-layout">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="2">
<!-- 사업장 -->
<component
:is="'SelectBlocMstr'"
ref="SelectBlocMstr"
:parentPrgmId="myPrgmId"
:labelCols="3"
/>
</v-col>
<v-col :cols="2">
<!-- 에너지 -->
<component
:is="'SelectEnergy'"
:parentPrgmId="myPrgmId"
:label="'에너지'"
:labelCols="3"
/>
</v-col>
<v-col :cols="4">
<DatePicker
:parentPrgmId="myPrgmId"
:timePicker="true"
:labelCols="2"
label="조회기간"
/>
</v-col>
<v-col cols="4" class="d-flex justify-end align-center">
<BtnSearch @click="search" class="mr-1" />
<BtnExcelDownload :parentPrgmId="myPrgmId" :gridName="gridName" />
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents">
<v-col :cols="12" lg="3" class="h100">
<v-card class="pb-5">
<div class="d-flex align-center justify-space-between pa-5">
<v-card-title class="pa-0 custom-title-4">검침개소</v-card-title>
<v-btn :ripple="false" icon tile @click="btnTreeExpand()">
<!-- {{ treeExpand }} -->
<v-icon
size="30"
v-text="treeExpandAll ? 'mdi-chevron-up' : 'mdi-chevron-down'"
></v-icon>
</v-btn>
</div>
<div class="h100 px-5" :style="{ height: 'calc(100% - 76px)' }">
<div ref="treeGridParent" class="h100 w100">
<!-- 검침개소 트리 -->
<component
:ref="'treeGrid' + myPrgmId"
:is="loadTree ? 'Grid' : null"
:gridName="gridNameTree"
:parentPrgmId="myPrgmId"
@getRowsData="getRowData"
/>
</div>
</div>
</v-card>
</v-col>
<v-col :cols="12" lg="9" class="h100">
<v-card class="pb-5">
<div class="w100 pa-3">
<v-btn
:ripple="false"
icon
tile
@click="btnLegendSelect()"
style="float:right"
>
<v-icon
size="20"
v-text="
legendSelctedAll
? 'mdi-radiobox-marked'
: 'mdi-radiobox-blank'
"
></v-icon
></v-btn>
</div>
<div style="height: 45%" class="pa-5">
<component
ref="VCharts"
class="w100 h100"
:is="loadChart ? 'Chart' : null"
:parentPrgmId="myPrgmId"
:chartName="'rowGridChart'"
/>
</div>
<div ref="gridParent" style="height: 52%" class="px-5">
<component
id="selectOffcTmDataTable"
:is="loadGrid ? 'Grid' : null"
:gridName="gridName"
:parentPrgmId="myPrgmId"
/>
</div>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script>
import mixinGlobal from '@/mixin/global.js';
import { mapActions, mapMutations } from 'vuex';
// import Search from "~/components/common/search";
import Chart from '~/components/common/Chart';
import Grid from '~/components/common/Grid';
import Utility from '~/plugins/utility';
import SelectBlocMstr from '@/components/common/select/SelectBlocMstrForPop';
import SelectEnergy from '@/components/common/select/SelectEnergyForPop';
import DatePicker from '~/components/common/Datepicker';
import BtnSearch from '~/components/common/button/BtnSearch';
import BtnExcelDownload from '~/components/common/button/BtnExcelDownload';
let myTitle;
// const myPrgmId = "PRG0023";
let myPrgmId;
export default {
mixins: [mixinGlobal],
async asyncData(context) {
const myState = context.store.state;
// context.store.commit("setActiveMenuInfo", myState.menuData[myPrgmId]);
// myTitle = myState.activeMenuInfo.menuNm;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
SelectBlocMstr,
SelectEnergy,
DatePicker,
BtnSearch,
BtnExcelDownload,
// Search,
Chart,
Grid,
},
data() {
return {
myPrgmId: myPrgmId,
gridName: 'rowGrid',
gridNameTree: 'treeGrid',
loadTree: false,
loadGrid: false,
loadChart: false,
treeExpandAll: true,
legendSelctedAll: true,
legendSeletedList: {},
myRowKey: 0,
};
},
computed: {
chkIsFind() {
return this.pageData.isFind;
},
chkRowdata() {
return this.pageData[this.gridName].data;
},
treeExpand() {
return this.treeExpandAll ? '접기' : '펼치기';
},
legendSelcted() {
return this.legendSelctedAll ? '전체선택' : '전체해제';
},
chkBlocCd() {
return this.pageData.blocId;
},
chkEnergyCd() {
return this.pageData.energyCd;
},
initFlag() {
if (
this.pageData.energyList.length > 0 &&
this.pageData.blocMstrList.length > 0
) {
return true;
} else {
return false;
}
},
},
watch: {
chkRowdata(val) {
this.setChartData(val);
},
chkIsFind(val) {
if (val) {
this.search();
}
},
chkBlocCd() {
this.myRowKey = 0;
this.setPageData({ isFind: true });
},
chkEnergyCd() {
this.myRowKey = 0;
this.setPageData({ isFind: true });
},
initFlag(val) {
if (val) {
this.init();
}
},
},
beforeCreate() {
myPrgmId = this.$route.query.prgmId;
this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
// this.$store.commit("setPageData", { searchItems: mySearch() });
},
mounted() {
this.init();
},
methods: {
...mapMutations({
setChartOption: 'setChartOption',
}),
...mapActions({
getHolidayList: 'modules/search/getHolidayList',
}),
init() {
this.gridInit();
this.getTreeData();
},
gridInit() {
const gridHeight = this.$refs.gridParent.offsetHeight - 36;
const treeGridHeight = this.$refs.treeGridParent.offsetHeight - 36;
const myOptions = {
columnOptions: {
resizable: true,
minWidth: 100,
//frozenCount: 2
},
scrollX: false,
};
this.setGridOption({
gridKey: this.gridName,
value: Object.assign(Utility.defaultGridOption(gridHeight), myOptions),
});
// this.setGridColumn({
// gridKey: this.gridName,
// value: myColumns
// });
const myOptionsTree = {
treeColumnOptions: {
name: 'name',
},
scrollX: true,
};
this.setGridOption({
gridKey: this.gridNameTree,
value: Object.assign(
Utility.defaultGridOption(treeGridHeight),
myOptionsTree,
),
});
this.setGridColumn({
gridKey: this.gridNameTree,
value: [{ header: '개소', name: 'name' }],
// value: [{ header: "개소", name: "name", width: "auto"}]
});
},
async search() {
// if (this.pageData.blocCodeLists) await this.getTreeData();
await this.getTreeData();
this.setPageData({
isFind: false,
});
},
// 검침개소 조회
async getTreeData() {
let res = [];
if (
this.pageData.blocMstrList.length > 0 &&
this.pageData.energyList.length > 0
) {
res = await this.postApiReturn({
apiKey: 'selectElecQualityReadPlcTree',
resKey: 'readPlcData',
sendParam: {
// sh_date: this.pageData.sh_date, // "2021-06-16 00:00:00 - 2021-06-17 00:00:00",
// frDttm: this.pageData.frDttm, // "2021-07-01T15:00:00.000Z",
// endDttm: this.pageData.endDttm, // "2021-07-02T14:59:59.000Z",
// 위 값들은 없어도 같은 결과인듯한데 꼭 필요한건지 확인!!!?
// blocId: this.pageData.blocCodeLists, //"BL0001",
blocId: this.pageData.blocMstrList[this.pageData.blocId].blocId,
// mttCd: this.pageData.mttCd, // "MTT00001" // 전력 코드 고정
// readObjId : "ROI000001"
// readObjId : this.pageData.energyCd
readObjId: this.pageData.energyList[this.pageData.energyCd].cd,
},
});
}
let setTreeData = [];
if (res.length > 0) {
const newRes = res.map(item => {
const arr = {
...item,
plcCdNm: item.plcNm,
};
return arr;
});
setTreeData = await this.setTree({
// gridKey: this.gridNameTree,
treeKey: 'PLC_CD',
value: newRes,
}); // 검침개소 트리구조화
this.treeExpandAll = true;
this.loadTree = true;
await this.setGridData({
gridKey: this.gridNameTree,
value: setTreeData.ROOT,
});
// 첫번째 row 선택상태
this.$refs['treeGrid' + this.myPrgmId].focus({
rowKey: this.myRowKey,
columnName: 'name',
setScroll: true,
});
} else {
// this.loadTree = false;
this.$store.state.pageData[this.myPrgmId].treeGrid.data = [];
this.loadTree = true;
}
this.setPageData({ isFind: false });
},
async getRowData(data) {
this.loadGrid = false; // grid refresh
this.loadChart = false;
this.$store.state.pageData[this.myPrgmId].rowGridChart.series = [];
this.myRowKey = data.rowKey;
const myChart = this.$refs.VCharts;
if (myChart != null)
this.legendSeletedList = myChart.onGetLegendSelectedList();
const res = await this.postApiReturn({
apiKey: 'selectOffcTmData',
resKey: ['offcTmDataData', 'tagRoiData'],
sendParam: {
frDttm: this.pageData.fromDt, // "2021-06-16 00:00:00",
endDttm: this.pageData.toDt, // "2021-06-17 00:00:00",
readPlc: data.plcCd,
readPlcNm: data.plcNm,
},
});
// 그리드 컬럼 만들어 주기
let myColumns = [
{ header: '검침개소', name: 'readPlcNm', width: 200 },
{ header: '검침일시', name: 'readDt', width: 200, align: 'center' },
];
const columInfo = res['tagRoiData'].length > 0 ? res['tagRoiData'] : [];
for (const infoItem of columInfo) {
myColumns.push({
header: infoItem.readObjNm + '(' + infoItem.unit + ')',
name: String(infoItem.readObjId).toLowerCase(),
formatter({ value }) {
return Utility.setFormatIntDecimal(value, 2);
},
align: 'right',
width: 100,
excelType: 'number',
// excelFormatter:"2",
});
}
// 그리드 컬럼 설정
this.setGridColumn({
gridKey: this.gridName,
value: myColumns,
});
// 그리드 데이터 설정
const returnList =
res['offcTmDataData'].length > 0 ? res['offcTmDataData'] : [];
this.setGridData({
gridKey: this.gridName,
value: returnList,
});
this.loadGrid = true;
// 컬럼에서 name부분만 추출
let newCol = myColumns.slice(2);
newCol = newCol.map(item => item.name);
this.$nextTick(() => {
this.setChartData(returnList);
});
this.setExlsData(returnList, newCol);
},
setExlsData(list, newCol) {
const rowData = [];
for (const item of list) {
let tempDic = {};
tempDic['readPlcNm'] = item.readPlcNm;
tempDic['readDt'] = item.readDt;
for (var i = 0; i < newCol.length; i++) {
tempDic[newCol[i]] = Utility.setFormatIntDecimal(item[newCol[i]], 2);
}
rowData.push(tempDic);
}
const xlsFileInfo = {
rowGrid: {
rowData,
// rowData: list.map(item => ({
// readPlcNm: item.readPlcNm,
// readDt: item.readDt,
// voltValA: Utility.setFormatDecimal(item.voltValA, 2, true),
// voltValB: Utility.setFormatDecimal(item.voltValB, 2, true),
// voltValC: Utility.setFormatDecimal(item.voltValC, 2, true),
// currValA: Utility.setFormatDecimal(item.currValA, 2, true),
// currValB: Utility.setFormatDecimal(item.currValB, 2, true),
// currValC: Utility.setFormatDecimal(item.currValC, 2, true),
// powFact: Utility.setFormatDecimal(item.powFact, 2, true),
// freq: Utility.setFormatDecimal(item.freq, 2, true),
// instantVal: Utility.setFormatDecimal(item.instantVal, 2, true)
// })),
// 엑셀변환시 데이타 가공이 추가로 필요하게 된다면 여기에 가공된 rowData 를 넣어야 할듯
fileName: null, // 갑이 없으면 해당 페이지 메뉴명
sheetName: null, // 갑이 없으면 'Sheet1'
},
};
this.setPageData({ xlsFileInfo });
},
async setChartData(data) {
this.loadChart = false;
let xAxisData = [];
let seriesData = [];
let chartOption = [];
let legendData = [];
let legendSelectedData = {};
let legendChk = 0;
let tmpList = [];
var myKey = this.pageData[this.gridName].column.filter(v => {
return v.header !== '검침개소';
});
for (var key in this.legendSeletedList) {
if (this.legendSeletedList[key]) legendChk++;
}
//Object.keys(this.legendSeletedList).length
if (legendChk > 0) {
legendSelectedData = this.legendSeletedList;
for (var i = 1; i < myKey.length; i++) {
legendData.push(myKey[i].header);
}
} else {
for (var i = 1; i < myKey.length; i++) {
legendData.push(myKey[i].header);
if (myKey[i].name.toUpperCase() == 'ROI000009') {
legendSelectedData[myKey[i].header] = true;
} else {
legendSelectedData[myKey[i].header] = false;
}
}
}
this.legendData = legendData;
tmpList = myKey.map(item => ({
name: item.header,
type: 'line',
data: data.map(obj => {
var matchKey = Object.keys(obj).filter(v => {
return item.name === v;
});
return obj[matchKey];
}),
}));
xAxisData =
tmpList[0].data.map(item =>
item ? Utility.setFormatDate(item, 'HH:mm') : '',
) || [];
seriesData = tmpList.slice(1, tmpList.length) || [];
chartOption = {
legend: {
type: 'scroll',
pageIconColor: '#18579e',
pageIconInactiveColor: '#ffffff66',
pageTextStyle: { color: '#fff' },
pageIconSize: 18,
pageButtonGap: 10,
left: 10,
right: 10,
data: legendData,
selected: legendSelectedData,
},
};
// console.log("chartOption :: ", chartOption);
this.setChartOption({ chartKey: 'rowGridChart', value: chartOption });
this.setChartXAxisData({ chartKey: 'rowGridChart', value: xAxisData });
this.setChartSeries({ chartKey: 'rowGridChart', value: seriesData });
this.loadChart = true;
},
btnTreeExpand() {
this.treeExpandAll = !this.treeExpandAll;
if (this.treeExpandAll)
this.$refs['treeGrid' + this.myPrgmId].expandAll();
else this.$refs['treeGrid' + this.myPrgmId].collapseAll();
},
btnLegendSelect() {
this.legendSelctedAll = !this.legendSelctedAll;
const myChart = this.$refs.VCharts;
let legendData = [];
let tmpList = [];
var myKey = this.pageData[this.gridName].column.filter(v => {
return v.header !== '검침개소';
});
for (var i = 1; i < myKey.length; i++) {
legendData.push(myKey[i].header);
}
if (this.legendSelctedAll) {
myChart.onLegendSelect(legendData);
} else {
myChart.onLegendUnSelect(legendData);
}
},
},
};
const defaultData = {
/* 검색옵션 */
// searchItems: {
// options: null,
// buttons: null
// },
// 사업장
blocId: '',
blocMstrList: [],
// blocCodeLists: null, // 사업장
// blocCodeListsList: [],
// 에너지
energyCd: 0,
energyList: [],
// energyData: 'ROI000001',
// energyDataList:[],
mttCd: 'MTT00001', // 고정값, => 에너지원 전력코드
// 주기
cmCycle: 'CYC_HOUR',
cmCycleList: [
{ idx: 0, text: '연', value: 'CYC_YEAR' },
{ idx: 1, text: '월', value: 'CYC_MONTH' },
{ idx: 2, text: '일', value: 'CYC_DAY' },
{ idx: 3, text: '시간', value: 'CYC_HOUR' },
],
defaultRange: {
CYC_YEAR: 10,
CYC_MONTH: 12,
CYC_DAY: 30,
CYC_HOUR: 24,
},
fromDt: '',
toDt: '',
// cmCycle: "CYC_HOUR", // 주기
// defaultRange: {
// CYC_HOUR: 24
// },
// fromDt: "",
// toDt: "",
isFind: false, // true 경우 조회, 조회버튼도 이 값으로 연동 예정
// 로컬 gridName 값과 동일한 이름으로 세팅
rowGrid: {
data: [],
column: [],
option: {},
},
// rowGrid 데이타를 가공해서 보여주는 차트 옵션
rowGridChart: Utility.defaultChartOption(true),
legendData: [],
treeGrid: {
data: [],
column: [],
option: {},
},
xlsFileInfo: {
// 출력하려는 grid 와 같은 이름으로 세팅
rowGrid: {
// tableId: "selectOffcTmDataTable",
rowData: [],
// 엑셀변환시 데이타 가공이 추가로 필요하게 된다면 여기에 가공된 rowData 를 넣어야 할듯
fileName: null, // 갑이 없으면 해당 페이지 메뉴명
sheetName: null, // 갑이 없으면 'Sheet1'
},
},
};
// const mySearch = () => {
// return {
// options: {
// cols: 9,
// list: [
// {
// type: "SearchSelect",
// cols: 3,
// class: "py-2",
// label: "사업장",
// labelCols: 4,
// apiKey: "selectBlocMstrCodeList",
// resKey: "blocCodeLists",
// dataCd: "blocId",
// dataNm: "blocNm",
// autoLoad: true
// },
// {
// type: "SearchSelect",
// cols: 3,
// class: "py-2",
// label: "검침대상",
// labelCols: 4,
// apiKey: "selectEnergy",
// resKey: "energyData",
// dataCd: "cd",
// dataNm: "enrgNm",
// autoLoad: true
// },
// {
// type: "DatePicker",
// cols: 6,
// class: "py-2",
// label: "조회기간",
// labelCols: 2,
// timePicker: true,
// autoLoad: true
// }
// ]
// },
// buttons: {
// cols: 2,
// class: "text-right",
// list: [
// {
// type: "BtnSearch"
// },
// {
// type: "BtnExcelDownload",
// bindingData: "rowGrid"
// }
// ]
// }
// };
// };
</script>
<style lang="scss">
@import '@/assets/scss/common.scss';
</style>

View File

@ -0,0 +1,992 @@
<template>
<div class="l-layout">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="3">
<component
:is="'selectCodeList'"
:parentPrgmId="myPrgmId"
:label="'위치 종류'"
dataKey="searchLocKind"
:sendParam="{ commGrpCd: 'EM_LOC_KIND', useFg: '1' }"
:addAll="true"
/>
</v-col>
<v-col :cols="3">
<component
:is="'selectCodeList'"
:parentPrgmId="myPrgmId"
:label="'공정 종류'"
dataKey="searchEccKind"
:sendParam="{ commGrpCd: 'EM_ECC_KIND', useFg: '1' }"
:addAll="true"
/>
</v-col>
<v-col :cols="3">
<!-- 사업장 -->
<div style="visibility:hidden">
<component
:is="'SelectBlocMstr'"
ref="SelectBlocMstr"
:parentPrgmId="myPrgmId"
/>
</div>
</v-col>
<v-col :cols="3" class="text-right">
<BtnSearch @click="search" />
</v-col>
</v-row>
<v-row align="center" no-gutters>
<v-col :cols="3">
<component
:is="'selectCodeList'"
:parentPrgmId="myPrgmId"
:label="'사용여부'"
dataKey="useFg"
:sendParam="{ commGrpCd: 'CO_USEFG', useFg: '1' }"
:addAll="true"
/>
</v-col>
<v-col :cols="6">
<InputText
:parentPrgmId="myPrgmId"
label="공정명"
valueNm="eccNm"
:labelCols="2"
:textCols="9"
:searchOption="true"
/>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents">
<v-col :cols="5" class="h100">
<v-card class="pb-5">
<div class="d-flex align-center justify-space-between pa-5">
<v-card-title class="pa-0 custom-title-4">공정 정보</v-card-title>
<Buttons
:parentPrgmId="myPrgmId"
:bindingData="gridName"
:detailList="detailList"
:btnActionsFnc="btnActions"
/>
</div>
<div class="px-5" style="height:calc(100% - 76px)">
<div ref="gridParent" class="w100 h100">
<component
:ref="gridName"
:is="loadGrid ? 'Grid' : null"
:gridName="gridName"
:parentPrgmId="myPrgmId"
@getRowsData="getRowData"
@sendSelectedRowStatInfo="getSelectedRowStatInfo"
:selectedRowDataWatchFlag="true"
/>
</div>
</div>
</v-card>
</v-col>
<v-col :cols="7" class="h100">
<v-card class="pb-5">
<v-card-title class="custom-title-4" style="min-height:76px;"
>공정 상세
</v-card-title>
<div class="px-5" style="height:calc(100% - 76px)">
<v-tabs v-model="tab">
<v-tab
v-for="item in items"
:key="item.id"
:disabled="item.disabledFlag"
>
{{ item.name }}
</v-tab>
</v-tabs>
<v-tabs-items
v-model="tab"
style="height: calc(100% - 65px);"
class="py-6"
>
<v-tab-item v-for="(item, idx) in items" :key="item.id">
<component
v-if="item.id == 'eccBaseInfoTab'"
:is="'Form'"
:parentPrgmId="myPrgmId"
:detailList="detailList"
@gridEditingFinish="gridEditingFinish"
/>
<EccAddInfoTab
v-if="item.id == 'eccAddInfoTab'"
:parentPrgmId="myPrgmId"
:innerTabGridInfo="{ tab, idx }"
/>
<EccIaoTab
v-if="item.id == 'eccIaoTab'"
:parentPrgmId="myPrgmId"
:innerTabGridInfo="{ tab, idx }"
/>
</v-tab-item>
</v-tabs-items>
</div>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex';
import mixinGlobal from '@/mixin/global.js';
import { resize } from '@/mixin/resize.js';
import BtnSearch from '~/components/common/button/BtnSearch';
import Buttons from '~/components/common/button/Buttons';
import SelectBlocMstr from '@/components/common/select/SelectBlocMstr';
import selectCodeList from '@/components/common/select/selectCodeList';
import SelectReadObj from '@/components/common/select/SelectReadObj';
import InputText from '@/components/common/input/InputText';
import Form from '~/components/common/form/Form';
import EccAddInfoTab from '@/components/pages/ems/EccInfo/EccAddInfoTab';
import EccIaoTab from '@/components/pages/ems/EccInfo/EccIaoTab';
import Grid from '~/components/common/Grid';
import Utility from '~/plugins/utility';
let myTitle;
// const myPrgmId = "PRG0012";
let myPrgmId;
const globalComId = '';
export default {
mixins: [mixinGlobal, resize],
async asyncData(context) {
const myState = context.store.state;
// context.store.commit("setActiveMenuInfo", myState.menuData[myPrgmId]);
// myTitle = myState.activeMenuInfo.menuNm;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
BtnSearch,
Buttons,
SelectBlocMstr,
selectCodeList,
SelectReadObj,
InputText,
Form,
EccAddInfoTab,
EccIaoTab,
Grid,
},
data() {
return {
myPrgmId: myPrgmId,
gridName: 'rowGrid',
loadGrid: false,
tab: null,
items: [
{ name: '공정 정보', id: 'eccBaseInfoTab', disabledFlag: false },
{ name: '공정 추가 정보', id: 'eccAddInfoTab', disabledFlag: false },
{ name: '공정 연결 정보', id: 'eccIaoTab', disabledFlag: false },
],
detailList: myDetail,
loadGrid: false,
};
},
computed: {
// ...mapState({
// pageData: state => state.pageData[myPrgmId]
// }),
chkIsFind() {
// 조회 플래그
return this.pageData.isFind;
},
chkBlocId() {
return this.pageData.blocId;
},
chkLocKind() {
// 시스템구분 선택 감지
return this.pageData.searchLocKind;
},
chkEccKind() {
// 시스템구분 선택 감지
return this.pageData.searchEccKind;
},
chkUseFg() {
// 사용여부 선택 감지
return this.pageData.useFg;
},
},
watch: {
chkIsFind(val) {
if (val) this.search();
},
chkBlocId() {
this.setPageData({ isFind: true });
},
chkLocKind() {
this.setPageData({ isFind: true });
},
chkEccKind() {
this.setPageData({ isFind: true });
},
chkUseFg() {
this.setPageData({ isFind: true });
},
},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
async created() {
//
this.getBlocMstrList({
dataKey: 'blocId',
params: { useFg: '1' },
addAll: false,
});
// 공정 위치 유형 목록 조회
this.getCodeList({
dataKey: 'locKind',
params: { commGrpCd: 'EM_LOC_KIND', useFg: '1' },
addAll: false,
});
// 공정 유형 목록 조회
this.getCodeList({
dataKey: 'eccKind',
params: { commGrpCd: 'EM_ECC_KIND', useFg: '1' },
addAll: false,
});
/////////// 추가 정보 Tab 에서 사용
// 데이터 유형 목록 조회
this.getCodeList({
dataKey: 'addInfoDataKind',
params: { commGrpCd: 'CO_DATA_TYPE', useFg: '1' },
addAll: false,
});
// 추가 정보 목록 조회
this.getAddInfoList({
dataKey: 'addInfo',
params: { addGrpId: 'ECC_INFO', useFg: '1' },
addAll: false,
});
this.getCodeList({
dataKey: 'emMapDiv',
params: { commGrpCd: 'EM_MAP_DIV', useFg: 1 },
addAll: false,
});
this.getCodeList({
dataKey: 'cmInout',
params: { commGrpCd: 'CM_INOUT', useFg: 1 },
addAll: false,
});
let ercList = [];
const res = await this.postApiReturn({
apiKey: 'selectErcInfo',
resKey: 'ercInfoData',
sendParam: {
blocId: this.userInfo.blocId,
},
});
res.forEach(item => {
const it = { text: item.ercNm, value: item.ercId };
ercList.push(it);
});
this.setPageData({ ercNmList: ercList });
},
mounted() {
this.init();
},
beforeDestroy() {
this.chkOpenTabList({ key: 'destroy', prgmId: myPrgmId });
},
methods: {
...mapMutations({
setPageData: 'setPageData',
}),
...mapActions({
getCodeList: 'modules/search/getCodeList',
getBlocMstrList: 'modules/search/getBlocMstrList',
getAddInfoList: 'modules/search/getAddInfoList',
}),
init() {
this.gridInit();
this.setPageData({
blocId: this.userInfo.blocId,
});
},
gridInit() {
const gridHeight = this.$refs.gridParent.offsetHeight - 30;
const gridWidth = this.$refs.gridParent.offsetWidth;
const myOptions = {
columnOptions: {
resizable: true,
},
treeColumnOptions: {
name: 'eccNm',
},
};
this.setGridOption({
gridKey: this.gridName,
value: Object.assign(Utility.defaultGridOption(gridHeight), myOptions),
});
const _this = this;
const myColumns = [
{ header: '회사 ID', name: 'comId', hidden: true },
{
header: '공정 명',
name: 'eccNm',
width: gridWidth * 0.44,
align: 'left',
},
{
header: '공정 ID',
name: 'eccId',
width: 150,
align: 'center',
hidden: true,
},
{
header: '상위 공정 ID',
name: 'upEccId',
width: 150,
align: 'center',
hidden: true,
},
{
header: '상위 공정 명',
name: 'upEccNm',
width: 150,
align: 'center',
hidden: true,
},
{
header: '위치 유형',
name: 'locKind',
width: gridWidth * 0.18,
align: 'left',
formatter({ value }) {
let retVal = '';
const newValue = _this.pageData.locKindList.filter(
item => item.commCd == value,
);
if (newValue.length > 0) {
retVal = newValue[0].commCdNm;
}
return retVal;
},
},
{
header: '공정 유형',
name: 'eccKind',
width: gridWidth * 0.18,
align: 'left',
formatter({ value }) {
let retVal = '';
const newValue = _this.pageData.eccKindList.filter(
item => item.commCd == value,
);
if (newValue.length > 0) {
retVal = newValue[0].commCdNm;
}
return retVal;
},
},
{
header: '사업장',
name: 'blocId',
width: 100,
align: 'center',
hidden: true,
formatter({ value }) {
let retVal = '';
const newValue = _this.pageData.blocIdList.filter(
item => item.blocCd == value,
);
if (newValue.length > 0) {
retVal = newValue[0].blocNm;
}
return retVal;
},
},
{
header: '정렬 순서',
name: 'sortSeq',
width: 80,
align: 'center',
hidden: true,
},
{
header: '공정 여부',
name: 'eccFg',
width: 80,
align: 'center',
hidden: true,
formatter({ value }) {
value = value === true ? '1' : '0';
const newValue = _this.pageData.useFgList.filter(
item => item.commCd == value,
);
return newValue[0].commCdNm;
},
},
{
header: '사용 여부',
name: 'useFg',
width: gridWidth * 0.18,
align: 'center',
formatter({ value }) {
value = value === true ? '1' : '0';
const newValue = _this.pageData.useFgList.filter(
item => item.commCd == value,
);
return newValue[0].commCdNm;
},
},
];
this.setGridColumn({
gridKey: this.gridName,
value: myColumns,
});
this.loadGrid = true;
this.getRowGridData();
},
async search() {
this.loadGrid = false;
await this.getRowGridData();
await this.setPageData({
isFind: false,
});
},
async getRowGridData() {
let res = [];
if (this.pageData.blocMstrList.length > 0) {
res = await this.postApiReturn({
apiKey: 'selectEccBaseInfo',
resKey: 'eccBaseInfoData',
sendParam: {
comId: globalComId,
blocId: this.pageData.blocId,
locKind: this.pageData.searchLocKind,
eccKind: this.pageData.searchEccKind,
useFg: this.pageData.useFg,
eccNmLike: this.pageData.eccNm,
},
});
} else {
this.setPageData({ isFind: false });
}
const newRes = res.map(item => {
const newObj = {
...item,
rowStat: null,
eccIdNm: item.eccId,
upEccId:
item.upEccId == null || item.upEccId == '' ? 'ROOT' : item.upEccId,
blocId: item.blocId,
eccFg: item.eccFg === '1' ? true : false,
useFg: item.useFg === '1' ? true : false, // 화면 개발 편의를 위해 boolean 타입으로 교체, 저장시 "1", "0" 으로 바꿔 보내야 함
};
return newObj;
});
const setTreeData = await this.setTree({
treeKey: 'ECC_ID',
value: newRes,
});
this.loadGrid = true;
this.setGridData({
gridKey: this.gridName,
value: setTreeData.ROOT || [],
// value: newRes
});
this.$nextTick(() => {
if (res.length > 0) {
this.$refs[this.gridName].focus({
// rowKey: 0,
rowKey:
this.pageData.rowGridSelectKey == '' ||
this.pageData.rowGridSelectKey == null
? 0
: this.pageData.rowGridSelectKey ==
this.$refs[this.gridName].getData().length - 1
? this.pageData.rowGridSelectKey
: 0,
columnName: 'eccNm',
setScroll: true,
});
} else {
this.detailDataInit();
}
});
},
async getRowData(data) {
this.setEccAddInfo(data);
this.setEccIao(data);
this.setGridSelectData({
gridKey: 'rowEccIaoGrid',
gridSelect: true,
rowGridSelectKey: '',
rowGridSelectData: Object.assign({}, {}),
});
this.setGridSelectData({
gridKey: this.gridName,
gridSelect: true,
rowGridSelectKey: data.rowKey,
rowGridSelectData: Object.assign({}, data),
});
},
async setEccAddInfo(data) {
this.setPageData({
rowGridSelectKey: data.rowKey,
rowGridSelectData: data,
});
// 검침개소 추가 정보 처리
const res = await this.postApiReturn({
apiKey: 'selectEccAddInfoList',
resKey: 'eccAddInfoData',
sendParam: {
comId: data.comId,
blocId: data.blocId,
eccId: data.eccId,
},
});
const newRes = res.map(item => {
const newObj = {
...item,
comId: item.comId || '',
eccId: item.eccId || '',
addInfoId: item.addInfoId || '',
addInfoDataKind: item.addInfoDataKind || '',
addInfoNumVal: item.addInfoNumVal || '',
addInfoTxtVal: item.addInfoTxtVal || '',
addInfoVal: item.addInfoVal || '',
useFg: item.useFg || '1',
rowStat: null,
};
return newObj;
});
this.setGridData({
gridKey: 'rowDetailGrid',
value: newRes,
});
},
async setEccIao(data) {
this.setPageData({
rowGridSelectKey: data.rowKey,
rowGridSelectData: data,
});
// 검침개소 추가 정보 처리
const res = await this.postApiReturn({
apiKey: 'selectEccIao',
resKey: 'eccIaoData',
sendParam: {
comId: data.comId,
eccId: data.eccId,
},
});
const newRes = res.map(item => {
const newObj = {
...item,
comId: item.comId || '',
eccId: item.eccId || '',
objId: item.objId || '',
ercId: item.ercId || '',
objKind: item.objKind || '',
inProdKind: item.inProdKind || '',
// calcFg: item.calcFg || "",
calcFg: item.calcFg === '1' ? true : false,
distRt: item.distRt || '',
blocId: item.blocId || '',
rowStat: null,
};
return newObj;
});
this.setGridData({
gridKey: 'rowEccIaoGrid',
value: newRes,
});
},
detailDataInit() {
this.setPageData({
rowGridSelectKey: null,
rowGridSelectData: [],
});
this.setGridData({
gridKey: 'rowDetailGrid',
value: [],
});
},
detailEccIaoInit() {
this.setPageData({
rowGridSelectKey: null,
rowGridSelectData: [],
});
this.setGridData({
gridKey: 'rowEccIaoGrid',
value: [],
});
},
getSelectedRowStatInfo(data) {
if (data) {
var rowStat = data.rowStat;
if (rowStat === 'I') {
this.tab = 0;
for (var i = 1; i < this.items.length; i++) {
this.items[i].disabledFlag = true;
}
} else if (rowStat === 'U') {
for (var i = 1; i < this.items.length; i++) {
this.items[i].disabledFlag = false;
}
} else if (rowStat === 'D') {
for (var i = 1; i < this.items.length; i++) {
this.items[i].disabledFlag = false;
}
} else if (rowStat === null) {
for (var i = 1; i < this.items.length; i++) {
this.items[i].disabledFlag = false;
}
}
}
},
async btnActions(action) {
let dataArr = [];
switch (action) {
case 'add':
this.$refs[this.gridName].addTreeRow();
break;
case 'remove':
this.$refs[this.gridName].removeTreeRow();
break;
case 'save':
dataArr = this.$refs[this.gridName].save();
if (dataArr.length > 0) {
var validCheck = true;
dataArr.forEach(item => {
if (item.upEccId == '') item.upEccId = 'ROOT';
if (
item.eccNm == '' ||
item.upEccId == '' ||
item.locKind == ''
) {
validCheck = false;
alert('필수 입력값을 입력해주세요.');
}
});
if (validCheck) {
const sendParam = {
datas: {
dsEccBaseInfo: dataArr.map(item => ({
...item,
blocId: item.blocId,
useFg: item.useFg ? '1' : '0',
eccFg: item.eccFg ? '1' : '0',
sortSeq: parseInt(item.sortSeq),
})),
},
params: {},
};
await this.postUpdateApi({
apiKey: 'saveEccBaseInfo',
sendParam: sendParam,
});
this.$nextTick(() => {
this.setPageData({ isFind: true });
});
}
} else {
alert('저장할 내용이 없습니다.');
}
break;
default:
break;
}
},
gridEditingFinish(data) {
this.$refs[this.gridName].editingFinish(data);
},
},
};
const defaultData = {
/* 검색옵션 */
eccNm: '',
blocId: '',
blocMstrList: [],
blocIdList: [],
searchLocKind: '',
searchLocKindList: [],
searchEccKind: '',
searchEccKindList: [],
locKind: '',
locKindList: [],
eccKind: '',
eccKindList: [],
useFg: '1',
useFgList: [],
ercNm: '',
ercNmList: [],
addInfoDataKind: '',
addInfoDataKindList: [],
addInfo: '',
addInfoList: [],
facInfo: {},
isMulti: false,
// 선택된 그룹코드 상세 데이터
rowGridSelectKey: 0,
rowGridSelectData: null,
isFind: false, // true 경우 조회, 조회버튼도 이 값으로 연동 예정
/* data 세팅 */
// 로컬 gridName 값과 동일한 이름으로 세팅
rowGrid: {
data: [],
column: [], // myColumns,
option: {}, // myOptions
defaultRow: {
comId: '',
eccId: '',
eccNm: '',
upEccId: '',
upEccNm: '',
locKind: '',
eccKind: '',
blocId: null,
eccFg: '0',
sortSeq: '0',
useFg: '1',
rowStat: null,
},
buttonAuth: {
add: true,
remove: true,
save: true,
excel: false,
},
rowGridSelectKey: 0,
rowGridSelectData: null,
},
rowDetailGrid: {
data: [],
column: [], // myColumns,
option: {}, // myOptions
defaultRow: {
comId: '',
eccId: '',
addInfoId: null,
addInfoDataKind: null,
addInfoNumVal: null,
addInfoTxtVal: null,
addInfoVal: null,
useFg: '1',
rowStat: 'I',
},
buttonAuth: {
remove: false,
save: true,
excel: false,
},
rowGridSelectKey: 0,
rowGridSelectData: null,
},
rowEccIaoGrid: {
data: [],
column: [], // myColumns,
option: {}, // myOptions
defaultRow: {
comId: globalComId,
eccId: '',
objId: '',
ercId: null,
objKind: null,
inProdKind: null,
calcFg: null,
distRt: null,
blocId: null,
rowStat: null,
},
buttonAuth: {
add: true,
remove: true,
save: true,
excel: false,
},
rowGridSelectKey: 0,
rowGridSelectData: null,
},
};
const myDetail = [
{
type: 'InputText',
label: '공정 ID',
valueNm: 'eccId',
readonly: true,
cols: 6,
class: 'py-2',
required: false,
placeholder: '시스템 자동입력',
},
{
type: 'InputText',
label: '공정 명',
valueNm: 'eccNm',
disabled: false,
cols: 6,
class: 'py-2',
required: true,
},
// {
// type: "ReadPlcPop",
// label: "상위 검침개소",
// valueNm: "upEccId",
// disabled: false,
// cols: 6,
// class: "py-2",
// required: true
// },
// {
// type: "InputText",
// valueNm: "upEccNm",
// label: "상위 검침개소명",
// readonly: true,
// cols: 6,
// class: "py-2"
// },
// {
// type: "InputText",
// label: "상위 공정 코드",
// valueNm: "upEccId",
// disabled: false,
// cols: 6,
// class: "py-2",
// required: true
// },
{
type: 'FtnPlcFormPop',
valueNm: 'upEccId',
valueNm2: 'upEccNm',
labelContent: '상위 공정',
disabled: false,
required: true,
cols: 6,
class: 'py-2',
labelCols: 4,
textCols: 7,
disableContent: true,
},
{
type: 'InputText',
valueNm: 'upEccNm',
readonly: true,
cols: 5,
class: 'py-2',
},
{
type: 'SelectBox',
label: '위치 유형',
valueNm: 'locKind',
disabled: false,
cols: 6,
class: 'py-2',
list: 'locKindList',
itemText: 'commCdNm',
itemValue: 'commCd',
required: true,
},
{
type: 'SelectBox',
label: '공정 유형',
valueNm: 'eccKind',
disabled: false,
cols: 6,
class: 'py-2',
list: 'eccKindList',
itemText: 'commCdNm',
itemValue: 'commCd',
addNull: true,
},
{
type: 'InputText',
label: '정렬',
valueNm: 'sortSeq',
disabled: false,
cols: 6,
class: 'py-2',
inputType: 'number',
// onkeydown : "if(this.value > 100) this.value = 100;if(this.value < 0) this.value = 0;if(this.value == '') this.value = 0;"
},
{
type: 'SelectBox',
label: '사업장',
valueNm: 'blocId',
disabled: false,
cols: 6,
class: 'py-2',
list: 'blocIdList',
itemText: 'blocNm',
itemValue: 'blocId',
},
{
type: 'CheckBox',
label: '사용 여부',
valueNm: 'useFg',
disabled: false,
cols: 6,
class: 'py-2',
value: { '1': true, '0': false },
required: true,
},
{
type: 'CheckBox',
label: 'ECC 공정 여부',
valueNm: 'eccFg',
disabled: false,
cols: 6,
class: 'py-2',
value: { '1': true, '0': false },
},
];
</script>
<style lang="scss">
@import '@/assets/scss/common.scss';
</style>

View File

@ -0,0 +1,881 @@
<template>
<div class="l-layout">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="3">
<component :is="'SelectBlocMstr'" :parentPrgmId="myPrgmId" />
</v-col>
<v-col :cols="3">
<component
:is="'SelectEnergy'"
:parentPrgmId="myPrgmId"
:label="'검침대상'"
/>
</v-col>
<v-col :cols="3"> </v-col>
<v-col :cols="3" class="text-right">
<v-btn :ripple="false" @click="searchInit">초기화</v-btn>
<v-btn :ripple="false" @click="search">조회</v-btn>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="enrgUseViewFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="3">
<v-row align="center" no-gutters>
<v-col :cols="6">
<div class="v-box " style="width:95%; min-width: 100px">
<div class="text-center" style="width:100%">
<strong class="custom-title-8" style="text-align: center;"
>전력</strong
>
</div>
</div>
</v-col>
<v-col :cols="6">
<div class="v-box " style="width:95%; min-width: 100px">
<div class="text-center" style="width:100%">
<strong class="custom-title-8" style="text-align: center;"
>{{ cumulUsage_elec
}}<span class="body-2"> Kwh</span></strong
>
</div>
</div>
</v-col>
</v-row>
</v-col>
<v-col :cols="3">
<v-row align="center" no-gutters>
<v-col :cols="6">
<div class="v-box " style="width:95%; min-width: 100px">
<div class="text-center" style="width:100%">
<strong class="custom-title-8" style="text-align: center;"
>가스</strong
>
</div>
</div>
</v-col>
<v-col :cols="6">
<div class="v-box " style="width:95%; min-width: 100px">
<div class="text-center" style="width:100%">
<strong class="custom-title-8" style="text-align: center;"
>{{ cumulUsage_gas
}}<span class="body-2"> Kg</span></strong
>
</div>
</div>
</v-col>
</v-row>
</v-col>
<v-col :cols="3">
<v-row align="center" no-gutters>
<v-col :cols="6">
<div class="v-box " style="width:95%; min-width: 100px">
<div class="text-center" style="width:100%">
<strong class="custom-title-8" style="text-align: center;"
>스팀</strong
>
</div>
</div>
</v-col>
<v-col :cols="6">
<div class="v-box " style="width:95%; min-width: 100px">
<div class="text-center" style="width:100%">
<strong class="custom-title-8" style="text-align: center;"
>{{ cumulUsage_stem
}}<span class="body-2"> </span></strong
>
</div>
</div>
</v-col>
</v-row>
</v-col>
<v-col :cols="3">
<v-row align="center" no-gutters>
<v-col :cols="6">
<div class="v-box " style="width:95%; min-width: 100px">
<div class="text-center" style="width:100%">
<strong class="custom-title-8" style="text-align: center;"
>에어</strong
>
</div>
</div>
</v-col>
<v-col :cols="6">
<div class="v-box " style="width:95%; min-width: 100px">
<div class="text-center" style="width:100%">
<strong class="custom-title-8" style="text-align: center;"
>{{ cumulUsage_air
}}<span class="body-2"> Ton</span></strong
>
</div>
</div>
</v-col>
</v-row>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents" :eager="true">
<v-col style="height:100%;" :cols="12">
<v-card class="px-5 py-5">
<div ref="chartParent" id="test2" style="height: 100%;">
<component
class="w100 h100"
:is="loadChart ? 'Chart' : null"
:parentPrgmId="myPrgmId"
:chartName="chartName"
ref="chartName"
/>
</div>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script>
import mixinGlobal from '@/mixin/global.js';
import { mapState, mapMutations, mapActions } from 'vuex';
import Search from '~/components/common/search';
import SelectBlocMstr from '@/components/common/select/SelectBlocMstr';
import SelectEnergy from '@/components/common/select/SelectEnergy';
import Chart from '~/components/common/Chart';
import Utility from '~/plugins/utility';
let myTitle;
let myPrgmId;
export default {
mixins: [mixinGlobal],
async asyncData(context) {
const myState = context.store.state;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
SelectBlocMstr,
SelectEnergy,
Chart,
Search,
},
data() {
return {
myPrgmId: myPrgmId,
loadChart: false,
chartName: 'treemapChart',
// 바인딩 (사용량 표시용)
cumulUsage_elec: 0,
cumulUsage_gas: 0,
cumulUsage_stem: 0,
cumulUsage_air: 0,
cumulAmt_elec: 0,
cumulAmt_gas: 0,
cumulAmt_stem: 0,
cumulAmt_air: 0,
currUsage_elec: 0,
currUsage_gas: 0,
currUsage_stem: 0,
currUsage_air: 0,
};
},
computed: {
...mapState({
isDarkMode: state => state.isDarkMode,
pageData: state => state.pageData[myPrgmId],
}),
chkIsFind() {
// 조회 플래그
return this.pageData.isFind;
},
chkBlocCd() {
// 사업장 코드
return this.pageData.blocId;
},
chkEnergyCd() {
// 에너지 선택 여부 감지
return this.pageData.energyCd;
},
chkDarkMode() {
return this.isDarkMode;
},
},
watch: {
chkIsFind(val) {
if (val) this.search();
},
chkBlocCd() {
this.setPageData({ isFind: true });
},
chkEnergyCd() {
this.setPageData({ isFind: true });
},
chkDarkMode() {
this.setPageData({ isFind: true });
},
},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
created() {
//this.timer= setInterval(this.searchTimer, 10000); //5분 주기마다 갱신
},
mounted() {
this.init();
},
beforeDestroy() {
this.cancelAutoUpdate();
this.chkOpenTabList({ key: 'destroy', prgmId: myPrgmId });
},
methods: {
...mapMutations({
setPageData: 'setPageData',
setChartOption: 'setChartOption',
setChartTitle: 'setChartTitle',
}),
...mapActions({
postApi: 'modules/list/postApi',
postUpdateApi: 'modules/list/postUpdateApi',
postApiReturn: 'modules/list/postApiReturn',
chkOpenTabList: 'chkOpenTabList',
}),
cancelAutoUpdate() {
clearInterval(this.timer);
},
init() {
this.layoutInit();
this.getChartData();
},
layoutInit() {
const searchFilterHeight = this.$refs.searchFilter.offsetHeight;
const enrgUseViewFilterHeight = this.$refs.enrgUseViewFilter.offsetHeight;
this.$refs.contents.style.height = `calc(100% - ${searchFilterHeight}px - ${enrgUseViewFilterHeight}px`;
},
// 에너지 계통 실시간 조회
async getChartData() {
// console.log("getChartData 시작");
this.loadChart = false;
let res = [];
// console.log("this.pageData.blocMstrList.length : ", this.pageData.blocMstrList.length);
// console.log("this.pageData.energyList.length : ", this.pageData.energyList.length);
if (
this.pageData.blocMstrList.length > 0 &&
this.pageData.energyList.length > 0
) {
res = await this.postApiReturn({
apiKey: 'selectEnrgPlantStatusMonitoringInfo',
//resKey:"enrgUseMonitoringInfoData",
resKey: 'enrgPlantStatusMonitoringInfoTreeData',
// sendParm : sendParams
sendParam: {
readObjId: this.pageData.energyList[this.pageData.energyCd].cd,
blocId: this.pageData.blocMstrList[this.pageData.blocId].blocId,
},
});
}
this.setPageData({ isFind: false });
this.setChartData(res);
this.loadChart = true;
this.loadGrid = true;
},
async setChartData(data) {
let makeData = [];
this.pageData.colorInx1st = 0;
this.pageData.colorInx2st = 0;
let datetime = '';
for (var idx in data) {
datetime = '검침 시간 : ' + data[idx].datetime;
if (data[idx].upEccId == 'ROOT') {
for (var idxSub in data[idx]['childeVo']) {
makeData.push(
this.makeData(null, data[idx]['childeVo'][idxSub]).data,
);
}
} else {
makeData.push(this.makeData(null, data[idx]).data);
}
}
const option = {
// color: ['#5470c6',
// '#91cc75',
// '#fac858',
// '#ee6666',
// '#73c0de',
// '#3ba272',
// '#fc8452',
// '#9a60b4',
// '#ea7ccc'],
tooltip: {
// formatter: function (info) {
// var value = info.value;
// var treePathInfo = info.treePathInfo;
// var treePath = [];
// for (var i = 1; i < treePathInfo.length; i++) {
// treePath.push(treePathInfo[i].name);
// }
// return [
// '<div class="tooltip-title">' +
// echarts.format.encodeHTML(treePath.join('/')) +
// '</div>',
// 'Disk Usage: ' + echarts.format.addCommas(value) + ' KB'
// ].join('');
// }
},
series: [
{
name: '전력',
type: 'treemap',
visibleMin: 300,
label: {
show: true,
formatter: '{b}',
},
upperLabel: {
show: true,
height: 30,
},
itemStyle: {
borderColor: '#fff',
},
levels: [
{
itemStyle: {
borderColor: '#777',
borderWidth: 0,
gapWidth: 1,
},
upperLabel: {
show: false,
},
},
{
itemStyle: {
borderColor: '#555',
borderWidth: 5,
gapWidth: 1,
},
emphasis: {
itemStyle: {
borderColor: '#ddd',
},
},
},
{
colorSaturation: [0.35, 0.5],
itemStyle: {
borderWidth: 5,
gapWidth: 1,
borderColorSaturation: 0.6,
},
},
],
data: makeData,
},
],
};
this.setChartOption({ chartKey: this.chartName, value: option });
this.loadChart = true;
},
async setChartSeriesData(data) {
let makeData = [];
this.pageData.colorInx1st = 0;
this.pageData.colorInx2st = 0;
let datetime = '';
for (var idx in data) {
datetime = '검침 시간 : ' + data[idx].datetime;
if (data[idx].upEccId == 'ROOT') {
for (var idxSub in data[idx]['childeVo']) {
makeData.push(
this.makeData(null, data[idx]['childeVo'][idxSub]).data,
);
}
} else {
makeData.push(this.makeData(null, data[idx]).data);
}
}
const seriesData = {
type: 'sunburst',
data: makeData,
radius: [0, '95%'],
sort: undefined,
emphasis: {
focus: 'ancestor',
},
levels: [
{},
{
r0: '15%',
r: '35%',
itemStyle: {
borderWidth: 2,
},
label: {
rotate: 'tangential',
},
},
{
r0: '35%',
r: '70%',
label: {
align: 'right',
},
},
{
r0: '70%',
r: '73%',
label: {
position: 'outside',
padding: 3,
silent: false,
},
itemStyle: {
borderWidth: 3,
},
},
{
r0: '73%',
r: '75%',
label: {
position: 'outside',
padding: 3,
silent: false,
},
itemStyle: {
borderWidth: 3,
},
},
],
};
this.setChartSeries({ chartKey: this.chartName, value: seriesData });
},
search() {
let urlPath = this.$router.currentRoute.fullPath;
let index = urlPath.indexOf('/ems/base/EnrgPlantStatusMonitoringMngPage');
if (index >= 0) {
this.getChartData();
}
},
searchInit() {
this.pageData.upEccId = 'ROOT';
},
async searchTimer() {
let urlPath = this.$router.currentRoute.fullPath;
let index = urlPath.indexOf('/ems/base/EnrgPlantStatusMonitoringMngPage');
if (index >= 0) {
let res = [];
if (
this.pageData.blocMstrList.length > 0 &&
this.pageData.energyList.length > 0
) {
res = await this.postApiReturn({
apiKey: 'selectEnrgUseMonitoringInfo',
//resKey:"enrgUseMonitoringInfoData",
resKey: 'enrgUseMonitoringInfoTreeData',
// sendParm : sendParams
sendParam: {
upReadPlcId: this.pageData.upReadPlcId,
energyCd: this.pageData.energyList[this.pageData.energyCd].cd,
// sh_blocCd:"BL0001"
blocId: this.pageData.blocMstrList[this.pageData.blocId].blocId,
},
});
}
this.setPageData({ isFind: false });
this.setChartSeriesData(res);
this.loadChart = true;
this.loadGrid = true;
}
},
setView(value) {
this.isFind = true;
},
makeData(parentsVo, chlVo) {
let retVal = {};
//console.log("chlVo.has('childeVo') : ", chlVo["childeVo"]);
if (chlVo['childeVo'] != null || chlVo['childeVo'] != undefined) {
// 하위 자료가 있으면
let subSum = 0;
let chartChildren = [];
for (var idx in chlVo['childeVo']) {
let subRet = this.makeData(chlVo, chlVo['childeVo'][idx]);
subSum += subRet.value;
chartChildren.push(subRet.data);
}
if (chlVo.instantVal > subSum) {
//chartChildren.push(this.makeDataOverVal(parentsVo, chlVo, chlVo.instantVal - subSum));
}
// const chartColor = this.getColor();
const chdData = {
value:
chlVo.instantVal == null ||
chlVo.instantVal == 0 ||
chlVo.instantVal < subSum
? subSum
: chlVo.instantVal,
name: chlVo.eccNm,
path: chlVo.eccPath,
children: chartChildren,
};
retVal = {
data: chdData,
value:
chlVo.instantVal == null ||
chlVo.instantVal == 0 ||
chlVo.instantVal < subSum
? subSum
: chlVo.instantVal,
};
} else {
// 하위 자료가 없으면.
// const chartColor = this.getColor();
const chdData = {
value: chlVo.instantVal == null ? 0 : chlVo.instantVal,
name: chlVo.eccNm,
path: chlVo.eccPath,
};
retVal = {
data: chdData,
value: chlVo.instantVal == null ? 0 : chlVo.instantVal,
};
}
return retVal;
},
makeDataOverVal(parentsVo, chlVo, otherVal) {
const chdData = {
name: chlVo.eccNm + '_미검침 사용량',
eccId: chlVo.eccId + '_OTHER',
upEccId: chlVo.upEccId,
value: 1,
itemStyle: {
color: '#FF0000',
curveness: 0.5,
},
tooltip: {
formatter:
chlVo.eccNm +
'_미검침 사용량<br />순시 :' +
Utility.setFormatIntDecimal(otherVal, 2),
},
};
return chdData;
},
getColor() {
let retColor = '';
if (this.pageData.colorInx1st > 4) {
this.pageData.colorInx1st = 0;
this.pageData.colorInx2st += 1;
}
if (this.pageData.colorInx2st > 9) {
this.pageData.colorInx2st = 0;
this.pageData.colorInx1st += 1;
}
if (this.isDarkMode) {
retColor = this.pageData.darkColorSet[this.pageData.colorInx1st][
this.pageData.colorInx2st
];
} else {
retColor = this.pageData.lightColorSet[this.pageData.colorInx1st][
this.pageData.colorInx2st
];
}
this.pageData.colorInx1st += 1;
return retColor;
},
labelGen(value, splitLangth) {
let retVal = '';
let subStrInx = 0;
if (value.length <= splitLangth) {
retVal = value;
} else {
subStrInx = this.sliceByByte(value, splitLangth);
retVal +=
value.substring(0, subStrInx) +
'\n' +
this.labelGen(value.substring(subStrInx + 1), splitLangth);
}
return retVal;
},
labelGen2(value, splitLangth, maxLineLength) {
let retVal = '';
let sumLength = 0;
let subStrInx = 0;
let splitVal = value.split(' ');
for (let idx in splitVal) {
if (splitVal[idx].length >= splitLangth) {
} else {
}
}
return retVal;
},
sliceByByte(str, maxByte) {
let b = 0;
let i = 0;
let c = '';
for (b = i = 0; (c = str.charCodeAt(i)); ) {
b += c >> 7 ? 2 : 1;
if (b > maxByte) {
break;
}
i++;
}
return i;
},
chartDblClick(event) {
//console.log("chartClick : ", event);
if (event.componentType == 'series' && event.data.downPlcCnt > 0) {
this.pageData.upReadPlcId = event.data.readPlcId;
this.pageData.parentsReadPlcId = event.data.upReadPlcId;
}
},
chartClick(evnet) {
//console.log("chartClick : ", evnet);
//console.log(evnet.componentType, evnet.componentIndex, this.pageData.upReadPlcId, this.pageData.parentsReadPlcId);
if (evnet.componentType == 'title' && evnet.componentIndex == 1) {
//console.log("여기 오남 : ", this.pageData.upReadPlcId, this.pageData.parentsReadPlcId);
this.pageData.upReadPlcId = this.pageData.parentsReadPlcId;
//console.log("여기 오남 2 : ", this.pageData.upReadPlcId, this.pageData.parentsReadPlcId);
}
},
},
};
const defaultData = {
/* 검색옵션 */
upReadPlcId: 'ROOT',
parentsReadPlcId: 'ROOT',
energyCd: 'ROI000001',
energyList: [],
blocId: '',
blocMstrList: [],
viewCheck: 'viewAll',
isFind: false, // true 경우 조회, 조회버튼도 이 값으로 연동 예정
colorInx1st: 0,
colorInx2st: 0,
/*chartdata 세팅 */
treemapChart: {
tooltip: {},
series: [
{
name: '전력',
type: 'treemap',
visibleMin: 300,
label: {
show: true,
formatter: '{b}',
},
upperLabel: {
show: true,
height: 30,
},
itemStyle: {
borderColor: '#fff',
},
levels: [
{
itemStyle: {
borderColor: '#777',
borderWidth: 0,
gapWidth: 1,
},
upperLabel: {
show: false,
},
},
{
itemStyle: {
borderColor: '#555',
borderWidth: 5,
gapWidth: 1,
},
emphasis: {
itemStyle: {
borderColor: '#ddd',
},
},
},
{
colorSaturation: [0.35, 0.5],
itemStyle: {
borderWidth: 5,
gapWidth: 1,
borderColorSaturation: 0.6,
},
},
],
data: [],
},
],
},
darkColorSet: [
[
'#01AE6A',
'#04A166',
'#089362',
'#0B865D',
'#0F7959',
'#126C55',
'#165E51',
'#19514D',
'#1D4448',
'#1F3D46',
],
[
'#FFB046',
'#EAA345',
'#D39545',
'#BE8844',
'#A77A44',
'#926D43',
'#7C5F42',
'#665242',
'#4C4141',
'#453D41',
],
[
'#F6637B',
'#E15D75',
'#CC576F',
'#B75269',
'#A24C63',
'#8D465E',
'#784058',
'#633B52',
'#4E354C',
'#433249',
],
[
'#944FE9',
'#894BD8',
'#7E47C7',
'#7344B7',
'#6740A5',
'#5C3C95',
'#513884',
'#463473',
'#3A3162',
'#352F59',
],
[
'#4385E3',
'#407CD3',
'#3D73C2',
'#3A6AB2',
'#3760A2',
'#345792',
'#304E81',
'#2D4571',
'#2A3B61',
'#293758',
],
],
lightColorSet: [
[
'#3CC380',
'#4BC88A',
'#5BCD94',
'#6BD19E',
'#7BD6A9',
'#8ADBB3',
'#99E0BD',
'#A9E5C7',
'#B9E9D1',
'#C9EEDC',
],
[
'#FFB13B',
'#FFB74A',
'#FFBE5B',
'#FFC46A',
'#FFCA7A',
'#FFD089',
'#FFD699',
'#FFDDA9',
'#FFE3B8',
'#FFE9C8',
],
[
'#F98694',
'#F98F9C',
'#FA99A5',
'#FAA3AE',
'#FBADB6',
'#FBB6BF',
'#FCC0C7',
'#FCCAD0',
'#FDD3D8',
'#FDDDE1',
],
[
'#CF74E5',
'#D37FE7',
'#D78AE9',
'#DA95EB',
'#DEA1ED',
'#E2ACEF',
'#E6B7F1',
'#EAC2F4',
'#EECDF6',
'#F2D8F8',
],
[
'#6A9BF4',
'#76A3F5',
'#82ABF6',
'#8EB3F7',
'#9ABBF8',
'#A6C3F8',
'#B1CBF9',
'#BED3FA',
'#C9DBFB',
'#D6E3FC',
],
],
};
</script>
<style lang="scss">
@import '@/assets/scss/common.scss';
</style>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,949 @@
<template>
<div class="l-layout">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="3">
<!-- 사업장 -->
<component
:is="'SelectBlocMstr'"
ref="SelectBlocMstr"
:parentPrgmId="myPrgmId"
/>
</v-col>
<v-col :cols="3">
<component
:is="'selectCodeList'"
:parentPrgmId="myPrgmId"
:label="'에너지원 유형'"
dataKey="searchErcKind"
:sendParam="{ commGrpCd: 'EM_ERCKIND', useFg: '1' }"
:addAll="true"
/>
</v-col>
<v-col :cols="3">
<component
:is="'SelectReadObj'"
:parentPrgmId="myPrgmId"
:label="'검침대상'"
dataKey="searchReadObj"
:sendParam="{ useFg: '1' }"
:addAll="true"
/>
</v-col>
<v-col :cols="3" class="text-right">
<BtnSearch @click="search" />
</v-col>
</v-row>
<v-row align="center" no-gutters>
<v-col :cols="3">
<component
:is="'selectCodeList'"
:parentPrgmId="myPrgmId"
:label="'고지 유형'"
dataKey="searchChrgKind"
:sendParam="{ commGrpCd: 'EM_ENGCHAGKIND', useFg: '1' }"
:addAll="true"
/>
</v-col>
<v-col :cols="3">
<component
:is="'selectCodeList'"
:parentPrgmId="myPrgmId"
:label="'사용여부'"
dataKey="useFg"
:sendParam="{ commGrpCd: 'CO_USEFG', useFg: '1' }"
:addAll="true"
/>
</v-col>
<v-col :cols="3">
<InputText
:parentPrgmId="myPrgmId"
label="에너지원명"
valueNm="ercNm"
:textCols="7"
:labelCols="4"
:searchOption="true"
/>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents" style="height: calc(100vh - 400px)">
<v-col :cols="5" class="h100">
<v-card class="pb-5">
<v-card-title class="d-flex justify-space-between align-end">
<span class="tit ft-size_20 ft-weight_600">에너지원 정보</span>
<Buttons
:parentPrgmId="myPrgmId"
:bindingData="gridName"
:detailList="detailList"
:btnActionsFnc="btnActions"
/>
</v-card-title>
<div class="px-5" style="height:calc(100% - 106px)">
<div ref="gridParent" class="w100 h100">
<component
:ref="gridName"
:is="loadGrid ? 'Grid' : null"
:gridName="gridName"
:parentPrgmId="myPrgmId"
@getRowsData="getRowData"
@sendSelectedRowStatInfo="getSelectedRowStatInfo"
:selectedRowDataWatchFlag="true"
/>
</div>
</div>
</v-card>
</v-col>
<v-col :cols="7" class="h100">
<v-card class="pb-5">
<v-card-title>에너지원 상세</v-card-title>
<div class="px-5" style="height:calc(100% - 70px)">
<v-tabs v-model="tab">
<v-tab
v-for="item in items"
:key="item.id"
:disabled="item.disabledFlag"
>
{{ item.name }}
</v-tab>
</v-tabs>
<v-tabs-items
v-model="tab"
style="height: calc(100% - 65px);"
class="py-6"
>
<v-tab-item v-for="(item, idx) in items" :key="item.id">
<component
v-if="item.id == 'ercInfoTab'"
:is="'Form'"
:parentPrgmId="myPrgmId"
:detailList="detailList"
@gridEditingFinish="gridEditingFinish"
/>
<ErcChrgInfoTab
v-if="item.id == 'ercChrgInfoTab'"
:parentPrgmId="myPrgmId"
:innerTabGridInfo="{ tab, idx }"
/>
</v-tab-item>
</v-tabs-items>
</div>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex';
import mixinGlobal from '@/mixin/global.js';
import { resize } from '@/mixin/resize.js';
import BtnSearch from '~/components/common/button/BtnSearch';
import Buttons from '~/components/common/button/Buttons';
import SelectBlocMstr from '@/components/common/select/SelectBlocMstr';
import selectCodeList from '@/components/common/select/selectCodeList';
import SelectReadObj from '@/components/common/select/SelectReadObj';
import InputText from '@/components/common/input/InputText';
import Form from '~/components/common/form/Form';
import ErcChrgInfoTab from '@/components/pages/ems/ErcChrgInfo/ErcChrgInfoTab';
import Grid from '~/components/common/Grid';
import Utility from '~/plugins/utility';
import DateUtility from '~/plugins/dateUtility';
let myTitle;
// const myPrgmId = "PRG0010";
let myPrgmId;
export default {
mixins: [mixinGlobal, resize],
async asyncData(context) {
const myState = context.store.state;
// context.store.commit("setActiveMenuInfo", myState.menuData[myPrgmId]);
// myTitle = myState.activeMenuInfo.menuNm;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
BtnSearch,
Buttons,
SelectBlocMstr,
selectCodeList,
SelectReadObj,
InputText,
Form,
ErcChrgInfoTab,
Grid,
},
data() {
return {
myPrgmId: myPrgmId,
gridName: 'rowGrid',
loadGrid: false,
tab: null,
items: [
{ name: '에너지원 정보', id: 'ercInfoTab', disabledFlag: false },
{ name: '에너지 요금 정보', id: 'ercChrgInfoTab', disabledFlag: false },
],
detailList: myDetail,
};
},
computed: {
// ...mapState({
// pageData: state => state.pageData[myPrgmId]
// }),
chkIsFind() {
// 조회 플래그
return this.pageData.isFind;
},
chkBlocId() {
return this.pageData.blocId;
},
chkErcKind() {
// 시스템구분 선택 감지
return this.pageData.searchErcKind;
},
chkReadObj() {
return this.pageData.searchReadObj;
},
chkChrgKind() {
return this.pageData.searchChrgKind;
},
chkUseFg() {
// 사용여부 선택 감지
return this.pageData.useFg;
},
},
watch: {
chkIsFind(val) {
if (val) this.search();
},
chkBlocId() {
this.setPageData({ isFind: true });
},
chkErcKind() {
this.setPageData({ isFind: true });
},
chkReadObj() {
this.setPageData({ isFind: true });
},
chkChrgKind() {
this.setPageData({ isFind: true });
},
chkUseFg() {
this.setPageData({ isFind: true });
},
},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
created() {
// 측정 Data 구분 목록 조회
this.getCodeList({
dataKey: 'ercKind',
params: { commGrpCd: 'EM_ERCKIND', useFg: '1' },
addAll: false,
});
// 측정 대상 목록 조회
this.getReadObjInfoList({
dataKey: 'readObj',
params: { useFg: '1' },
addAll: false,
});
// 단위 코드 목록 조회
this.getCodeList({
dataKey: 'chrgKind',
params: { commGrpCd: 'EM_ENGCHAGKIND', useFg: '1' },
addAll: false,
});
/////////// 추가 정보 Tab 에서 사용
// 데이터 유형 목록 조회
this.getCodeList({
dataKey: 'addInfoDataKind',
params: { commGrpCd: 'CO_DATA_TYPE', useFg: '1' },
addAll: false,
});
// 추가 정보 목록 조회
this.getAddInfoList({
dataKey: 'addInfo',
params: { addGrpId: 'TAG_INFO', useFg: '1' },
addAll: false,
});
this.search();
},
mounted() {
this.userComId = this.userInfo.comId;
this.init();
},
beforeDestroy() {
this.chkOpenTabList({ key: 'destroy', prgmId: myPrgmId });
},
methods: {
...mapActions({
getCodeList: 'modules/search/getCodeList',
getBlocMstrList: 'modules/search/getBlocMstrList',
getReadObjInfoList: 'modules/search/getReadObjInfoList',
getAddInfoList: 'modules/search/getAddInfoList',
}),
init() {
this.gridInit();
var date = new Date();
this.pageData.toDt =
String(date.getFullYear()) +
String(date.getMonth() + 1).padStart(2, '0');
this.pageData.fromDt = DateUtility.addMonth(-11, 'YYYYMM', date);
},
gridInit() {
const gridHeight = this.$refs.gridParent.offsetHeight - 30;
const myOptions = {
columnOptions: {
resizable: true,
},
};
this.setGridOption({
gridKey: this.gridName,
value: Object.assign(Utility.defaultGridOption(gridHeight), myOptions),
});
const _this = this;
const myColumns = [
{ header: '회사 ID', name: 'comId', hidden: true },
{ header: '에너지원ID', name: 'ercId', width: 120, align: 'center' },
{ header: '에너지원명', name: 'ercNm', align: 'left' },
{
header: '에너지원 유형',
name: 'ercKind',
align: 'center',
formatter({ value }) {
let retVal = '';
const newValue = _this.pageData.ercKindList.filter(
item => item.commCd == value,
);
if (newValue.length > 0) {
retVal = newValue[0].commCdNm;
}
return retVal;
},
},
{
header: '검침대상',
name: 'readObjId',
align: 'left',
formatter({ value }) {
let retVal = '';
const newValue = _this.pageData.readObjList.filter(
item => item.readObjId == value,
);
if (newValue.length > 0) {
retVal = newValue[0].readObjNm;
}
return retVal;
},
},
{
header: '검침 개소 ID',
name: 'readPlcId',
width: 80,
align: 'center',
hidden: true,
},
{
header: '고지 유형',
name: 'chrgKind',
width: 80,
align: 'center',
hidden: true,
formatter({ value }) {
let retVal = '';
const newValue = _this.pageData.chrgKindList.filter(
item => item.commCd == value,
);
if (newValue.length > 0) {
retVal = newValue[0].commCdNm;
}
return retVal;
},
},
{
header: '기본단가',
name: 'unitPrce',
width: 100,
align: 'right',
hidden: true,
},
{
header: '단가 사용여부',
name: 'prceFg',
width: 100,
align: 'center',
hidden: true,
formatter({ value }) {
const newValue = _this.pageData.useFgList.filter(
item => item.commCd == value,
);
return newValue[0].commCdNm;
},
},
{
header: '피크 전력',
name: 'peakPow',
width: 100,
align: 'right',
hidden: true,
},
{
header: '전력 계약',
name: 'elecContId',
width: 100,
align: 'center',
hidden: true,
},
{
header: '전력 계약',
name: 'elecContNm',
width: 100,
align: 'center',
hidden: true,
},
{
header: '사업장',
name: 'blocId',
width: 100,
align: 'center',
hidden: true,
formatter({ value }) {
let retVal = '';
const newValue = _this.pageData.blocMstrList.filter(
item => item.blocId == value,
);
if (newValue.length > 0) {
retVal = newValue[0].blocNm;
}
return retVal;
},
},
{
header: '사용 여부',
name: 'useFg',
width: 95,
align: 'center',
formatter({ value }) {
value = value === true ? '1' : '0';
const newValue = _this.pageData.useFgList.filter(
item => item.commCd == value,
);
return newValue[0].commCdNm;
},
},
];
this.setGridColumn({
gridKey: this.gridName,
value: myColumns,
});
this.loadGrid = true;
this.getRowGridData();
},
async search() {
this.loadGrid = false;
await this.getRowGridData();
await this.setPageData({
isFind: false,
});
this.loadGrid = true;
},
async getRowGridData() {
let res = [];
if (this.pageData.blocMstrList.length > 0) {
res = await this.postApiReturn({
apiKey: 'selectErcInfo',
resKey: 'ercInfoData',
sendParam: {
blocId: this.pageData.blocMstrList[this.pageData.blocId].blocId,
ercKind: this.pageData.searchErcKind,
readObjId: this.pageData.searchReadObj,
chrgKind: this.pageData.searchChrgKind,
useFg: this.pageData.useFg,
ercNmLike: this.pageData.ercNm,
},
});
} else {
this.setPageData({ isFind: false });
}
const newRes = res.map(item => {
const newObj = {
...item,
rowStat: null,
blocId: item.blocId,
useFg: item.useFg === '1' ? true : false, // 화면 개발 편의를 위해 boolean 타입으로 교체, 저장시 "1", "0" 으로 바꿔 보내야 함
prceFg: item.prceFg === '1' ? true : false, // 화면 개발 편의를 위해 boolean 타입으로 교체, 저장시 "1", "0" 으로 바꿔 보내야 함
};
return newObj;
});
this.loadGrid = true;
this.setGridData({
gridKey: this.gridName,
value: newRes,
});
this.$nextTick(() => {
if (newRes.length > 0) {
this.$refs[this.gridName].focus({
//rowKey: 0,
rowKey:
this.pageData.rowGridSelectKey == '' ||
this.pageData.rowGridSelectKey == null
? 0
: this.pageData.rowGridSelectKey ==
this.$refs[this.gridName].getData().length - 1
? this.pageData.rowGridSelectKey
: 0,
columnName: 'ercId',
setScroll: true,
});
} else {
this.detailDataInit();
}
});
},
async getRowData(data) {
this.setPageData({
rowGridSelectKey: data.rowKey,
rowGridSelectData: data,
});
const res = await this.postApiReturn({
apiKey: 'selectEnrgChrgPrcInfo',
resKey: 'enrgChrgInfoData',
sendParam: {
comId: data.comId,
blocId: data.blocId,
ercId: data.ercId,
startDt: this.pageData.fromDt,
endDt: this.pageData.toDt,
},
});
const newRes = res.map(item => {
const newObj = {
...item,
comId: item.comId || '',
blocId: item.blocId || '',
ercId: item.ercId || '',
objMm: item.objMm || '',
objYm: item.objYm || '',
strtDt: item.strtDt || '',
endDt: item.endDt || '',
notiChrg: item.notiChrg || '',
baseChrg: item.baseChrg || '',
rmrk: item.rmrk || '',
useQty: item.useQty || '',
unitPrce: item.unitPrce || '',
corrCoff: item.corrCoff || '',
heatCoff: item.heatCoff || '',
peakPow: item.peakPow || '',
elecContId: item.elecContId || '',
rowStat: null,
};
return newObj;
});
this.setGridData({
gridKey: 'rowDetailGrid',
value: newRes,
});
},
detailDataInit() {
this.setPageData({
rowGridSelectKey: null,
rowGridSelectData: [],
});
this.setGridData({
gridKey: 'rowDetailGrid',
value: [],
});
},
getSelectedRowStatInfo(data) {
if (data) {
var rowStat = data.rowStat;
if (rowStat === 'I') {
this.tab = 0;
for (var i = 1; i < this.items.length; i++) {
this.items[i].disabledFlag = true;
}
} else if (rowStat === 'U') {
for (var i = 1; i < this.items.length; i++) {
this.items[i].disabledFlag = false;
}
} else if (rowStat === 'D') {
for (var i = 1; i < this.items.length; i++) {
this.items[i].disabledFlag = false;
}
} else if (rowStat === null) {
for (var i = 1; i < this.items.length; i++) {
this.items[i].disabledFlag = false;
}
}
}
},
async btnActions(action) {
let dataArr = [];
switch (action) {
case 'add':
const defaultRow = {
ercId: '',
ercNm: '',
ercKind: this.pageData.ercKind,
readObjId: this.pageData.readObj,
chrgKind: this.pageData.chrgKind,
unitPrce: 0,
peakPow: '',
blocId: this.pageData.blocMstrList[this.pageData.blocId].blocId,
elecContId: '',
elecContNm: '',
readPlcId: '',
readPlcNm: '',
prceFg: '1',
useFg: '1',
};
this.$refs[this.gridName].addRow(defaultRow);
break;
case 'remove':
this.$refs[this.gridName].removeRow();
break;
case 'save':
dataArr = this.$refs[this.gridName].save();
var validCheck = true;
if (dataArr.length > 0) {
dataArr.filter(item => {
if (item.rowStat === 'I') {
if (item.ercNm == '') {
alert('필수 입력값을 입력해주세요.');
validCheck = false;
}
} else if (item.rowStat === 'U') {
if (item.ercNm == '') {
alert('필수 입력값을 입력해주세요.');
validCheck = false;
}
}
});
if (validCheck) {
const sendParam = {
datas: {
dsErcInfo: dataArr.map(item => ({
...item,
blocId: item.blocId,
useFg: item.useFg ? '1' : '0',
prceFg: item.prceFg ? '1' : '0',
})),
},
params: {},
};
await this.postUpdateApi({
apiKey: 'saveErcInfo',
sendParam: sendParam,
});
this.$nextTick(() => {
this.setPageData({ isFind: true });
});
}
} else {
alert('저장할 내용이 없습니다.');
}
break;
default:
break;
}
},
gridEditingFinish(data) {
this.$refs[this.gridName].editingFinish(data);
},
},
};
const defaultData = {
/* 검색옵션 */
ercNm: '',
blocId: '',
blocMstrList: [],
searchErcKind: '',
searchErcKindList: [],
searchReadObj: '',
searchReadObjList: [],
searchChrgKind: '',
searchChrgKindList: [],
ercKind: '',
ercKindList: [],
readObj: '',
readObjList: [],
chrgKind: '',
chrgKindList: [],
useFg: '1',
useFgList: [],
addInfoDataKind: '',
addInfoDataKindList: [],
addInfo: '',
addInfoList: [],
searchElecContKind: '',
searchElecContKindList: [],
searchVoltKind: '',
searchVoltKindList: [],
searchOptKind: '',
searchOptKindList: [],
cmCycle: 'CYC_MONTH',
cmCycleList: [
{ idx: 0, text: '연', value: 'CYC_YEAR' },
{ idx: 1, text: '월', value: 'CYC_MONTH' },
{ idx: 2, text: '일', value: 'CYC_DAY' },
{ idx: 3, text: '시간', value: 'CYC_HOUR' },
],
defaultRange: {
CYC_YEAR: 1,
CYC_MONTH: 12,
CYC_DAY: 30,
CYC_HOUR: 0,
},
fromDt: '',
toDt: '',
// 선택된 그룹코드 상세 데이터
rowGridSelectKey: 0,
rowGridSelectData: null,
isFind: false, // true 경우 조회, 조회버튼도 이 값으로 연동 예정
/* data 세팅 */
// 로컬 gridName 값과 동일한 이름으로 세팅
rowGrid: {
data: [],
column: [], // myColumns,
option: {}, // myOptions
defaultRow: {
comId: '',
ercId: '',
ercNm: null,
ercKind: '',
readObjId: '',
readPlcId: '',
readPlcNm: '',
chrgKind: '',
unitPrce: null,
prceFg: null,
peakPow: null,
elecContId: '',
elecContNm: '',
blocId: null,
useFg: '1',
rowStat: 'I',
},
buttonAuth: {
add: true,
remove: true,
save: true,
excel: false,
},
},
rowDetailGrid: {
data: [],
column: [], // myColumns,
option: {}, // myOptions
defaultRow: {
comId: '',
ercId: '',
objMm: '',
blocId: '',
startDt: null,
endDt: null,
notiChrg: null,
baseChrg: null,
rmrk: null,
useQty: null,
unitPrce: null,
corrCoff: null,
heatCoff: null,
peakPow: null,
elecContId: '',
rowStat: null,
},
buttonAuth: {
remove: true,
save: true,
},
},
rowGridChart: Utility.defaultChartOption({
data: ['기본요금', '고지요금'],
selectedMode: true,
selected: {
기본요금: true,
고지요금: true,
},
}),
};
const myDetail = [
{
type: 'InputText',
label: '에너지원 ID',
valueNm: 'ercId',
readonly: true,
cols: 6,
class: 'py-2',
required: false,
placeholder: '시스템 자동입력',
},
{
type: 'InputText',
label: '에너지원 명',
valueNm: 'ercNm',
disabled: false,
cols: 6,
class: 'py-2',
required: true,
},
{
type: 'SelectBox',
label: '에너지원 유형',
valueNm: 'ercKind',
disabled: false,
cols: 6,
class: 'py-2',
list: 'ercKindList',
itemText: 'commCdNm',
itemValue: 'commCd',
required: true,
},
{
type: 'SelectBox',
label: '검침대상',
valueNm: 'readObjId',
disabled: false,
cols: 6,
class: 'py-2',
list: 'readObjList',
itemText: 'readObjNm',
itemValue: 'readObjId',
required: true,
},
{
type: 'SelectBox',
label: '고지 유형',
valueNm: 'chrgKind',
disabled: false,
cols: 6,
class: 'py-2',
list: 'chrgKindList',
itemText: 'commCdNm',
itemValue: 'commCd',
required: true,
},
{
type: 'InputText',
label: '기본단가',
valueNm: 'unitPrce',
disabled: false,
cols: 6,
class: 'py-2',
},
{
type: 'InputText',
label: '피크 전력',
valueNm: 'peakPow',
disabled: false,
cols: 6,
class: 'py-2',
},
{
type: 'SelectBox',
label: '사업장',
valueNm: 'blocId',
disabled: false,
cols: 6,
class: 'py-2',
list: 'blocMstrList',
itemText: 'blocNm',
itemValue: 'blocId',
required: true,
},
{
type: 'ElecPowChrgPop',
label: '전력 계약',
valueNm: 'elecContId',
disabled: false,
cols: 6,
class: 'py-2',
},
{
type: 'InputText',
valueNm: 'elecContNm',
readonly: true,
cols: 5,
class: 'py-2',
},
{
type: 'ReadPlcPop',
label: '검침개소',
valueNm: 'readPlcId',
disabled: false,
cols: 6,
class: 'py-2',
},
{
type: 'InputText',
valueNm: 'readPlcNm',
readonly: true,
cols: 5,
class: 'py-2',
},
{
type: 'CheckBox',
label: '단가사용 여부',
valueNm: 'prceFg',
disabled: false,
cols: 6,
class: 'py-2',
value: { '1': true, '0': false },
},
{
type: 'CheckBox',
label: '사용 여부',
valueNm: 'useFg',
disabled: false,
cols: 6,
class: 'py-2',
value: { '1': true, '0': false },
required: true,
},
];
</script>
<style lang="scss">
@import '@/assets/scss/common.scss';
</style>

View File

@ -0,0 +1,834 @@
<template>
<div class="l-layout">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="3">
<component :is="'SelectBlocMstr'" :parentPrgmId="myPrgmId" />
</v-col>
<v-col :cols="3">
<component
:is="'SelectEnergy'"
:parentPrgmId="myPrgmId"
:label="'검침대상'"
/>
</v-col>
<v-col :cols="3"> </v-col>
<v-col :cols="3" class="text-right">
<v-btn :ripple="false" @click="searchInit">처음으로</v-btn>
<v-btn :ripple="false" @click="search">조회</v-btn>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents" :eager="true">
<v-col style="height:100%;">
<v-card class="px-5 py-5">
<div ref="chartParent" id="test2" style="height: 100%;">
<component
class="w100 h100"
:is="loadChart ? 'Chart' : null"
:parentPrgmId="myPrgmId"
:chartName="chartName"
ref="treeGridChart"
@dblclick="chartDblClick"
@click="chartClick"
/>
</div>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script>
import mixinGlobal from '@/mixin/global.js';
import { mapState, mapMutations, mapActions } from 'vuex';
import Search from '~/components/common/search';
import SelectBlocMstr from '@/components/common/select/SelectBlocMstr';
import SelectEnergy from '@/components/common/select/SelectEnergy';
import Chart from '~/components/common/Chart';
import Utility from '~/plugins/utility';
let myTitle;
let myPrgmId;
export default {
mixins: [mixinGlobal],
async asyncData(context) {
const myState = context.store.state;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
SelectBlocMstr,
SelectEnergy,
Chart,
Search,
},
data() {
return {
myPrgmId: myPrgmId,
loadChart: false,
chartName: 'sankyChart',
};
},
computed: {
...mapState({
isDarkMode: state => state.isDarkMode,
pageData: state => state.pageData[myPrgmId],
}),
chkIsFind() {
// 조회 플래그
return this.pageData.isFind;
},
chkBlocCd() {
// 사업장 코드
return this.pageData.blocId;
},
chkEnergyCd() {
// 에너지 선택 여부 감지
return this.pageData.energyCd;
},
chkUpReadPlcId() {
return this.pageData.upReadPlcId;
},
chkDarkMode() {
return this.isDarkMode;
},
},
watch: {
chkIsFind(val) {
if (val) this.search();
},
chkBlocCd() {
this.setPageData({ isFind: true });
},
chkEnergyCd() {
this.setPageData({ isFind: true });
},
chkUpReadPlcId() {
this.setPageData({ isFind: true });
},
chkDarkMode() {
this.setPageData({ isFind: true });
},
},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
created() {
this.timer = setInterval(this.searchTimer, 10000); // 10초 주기마다 갱신
},
mounted() {
this.init();
},
beforeDestroy() {
this.cancelAutoUpdate();
this.chkOpenTabList({ key: 'destroy', prgmId: myPrgmId });
},
methods: {
...mapMutations({
setPageData: 'setPageData',
setChartOption: 'setChartOption',
setChartTitle: 'setChartTitle',
}),
...mapActions({
postApi: 'modules/list/postApi',
postUpdateApi: 'modules/list/postUpdateApi',
postApiReturn: 'modules/list/postApiReturn',
chkOpenTabList: 'chkOpenTabList',
}),
cancelAutoUpdate() {
clearInterval(this.timer);
},
init() {
this.layoutInit();
this.getChartData();
},
layoutInit() {
const searchFilterHeight = this.$refs.searchFilter.offsetHeight;
this.$refs.contents.style.height = `calc(100% - ${searchFilterHeight}px)`;
},
// 에너지 계통 실시간 조회
async getChartData() {
this.loadChart = false;
let res = [];
if (
this.pageData.blocMstrList.length > 0 &&
this.pageData.energyList.length > 0
) {
res = await this.postApiReturn({
apiKey: 'selectEnrgSystemMonitoringInfo',
//resKey:"enrgSystemMonitoringInfoData",
resKey: 'enrgSystemMonitoringInfoTreeData',
// sendParm : sendParams
sendParam: {
upReadPlcId: this.pageData.upReadPlcId,
energyCd: this.pageData.energyList[this.pageData.energyCd].cd,
// sh_blocCd:"BL0001"
blocId: this.pageData.blocMstrList[this.pageData.blocId].blocId,
},
});
}
this.setPageData({ isFind: false });
this.setChartData(res);
this.loadChart = true;
this.loadGrid = true;
},
async setChartData(data) {
let makeData = [];
let makeLinks = [];
this.pageData.colorInx1st = 0;
this.pageData.colorInx2st = 0;
let datetime = '';
for (var idx in data) {
datetime = '검침 시간 : ' + data[0].datetime;
if (data[idx].mapUpReadPlcId == 'ROOT') {
for (var idxSub in data[idx]['childeVo']) {
this.makeDataAndLinks(
null,
data[idx]['childeVo'][idxSub],
makeData,
makeLinks,
);
}
} else {
this.makeDataAndLinks(null, data[idx], makeData, makeLinks);
}
}
const title = [
{
text: datetime,
left: '3%',
bottom: '10',
textStyle: {
color: this.isDarkMode
? 'rgba(250,250,250,0.7)'
: 'rgba(0,0,0,0.7)',
},
},
{
text: ' < ',
left: '10',
top: 'center',
textStyle: {
color: this.isDarkMode
? 'rgba(250,250,250,0.7)'
: 'rgba(0,0,0,0.7)',
},
triggerEvent: true,
},
];
const option = {
title: title,
backgroundColor: '#FFFFFF',
series: [
{
type: 'sankey',
left: 50.0,
top: 20.0,
right: 50.0,
bottom: 25.0,
nodeGap: 10,
nodeAlign: 'left',
data: makeData,
links: makeLinks,
lineStyle: {
color: 'source',
curveness: 0.5,
},
triggerEvent: true,
itemStyle: {
//color: '#1f77b4',
//borderColor: '#1f77b4'
},
label: {
color: this.isDarkMode
? 'rgba(250,250,250,0.7)'
: 'rgba(0,0,0,0.7)',
fontFamily: 'Arial',
fontSize: 12,
},
},
],
tooltip: {
trigger: 'item',
},
};
this.setChartOption({ chartKey: this.chartName, value: option });
this.loadChart = true;
},
async setChartSeriesData(data) {
let makeData = [];
let makeLinks = [];
this.pageData.colorInx1st = 0;
this.pageData.colorInx2st = 0;
let datetime = '';
for (var idx in data) {
datetime = '검침 시간 : ' + data[0].datetime;
if (data[idx].upReadPlcId == 'ROOT') {
for (var idxSub in data[idx]['childeVo']) {
this.makeDataAndLinks(
null,
data[idx]['childeVo'][idxSub],
makeData,
makeLinks,
);
}
} else {
this.makeDataAndLinks(null, data[idx], makeData, makeLinks);
}
}
const title = [
{
text: datetime,
left: '3%',
bottom: '10',
textStyle: {
color: this.isDarkMode
? 'rgba(250,250,250,0.7)'
: 'rgba(0,0,0,0.7)',
},
},
{
text: ' < ',
left: '10',
top: 'center',
textStyle: {
color: this.isDarkMode
? 'rgba(250,250,250,0.7)'
: 'rgba(0,0,0,0.7)',
},
triggerEvent: true,
},
];
const seriesData = [
{
type: 'sankey',
left: 50.0,
top: 20.0,
right: 50.0,
bottom: 25.0,
nodeGap: 10,
nodeAlign: 'left',
data: makeData,
links: makeLinks,
lineStyle: {
color: 'source',
curveness: 0.5,
},
triggerEvent: true,
itemStyle: {
//color: '#1f77b4',
//borderColor: '#1f77b4'
},
label: {
color: this.isDarkMode
? 'rgba(250,250,250,0.7)'
: 'rgba(0,0,0,0.7)',
fontFamily: 'Arial',
fontSize: 12,
},
},
];
this.setChartSeries({ chartKey: this.chartName, value: seriesData });
this.setChartTitle({ chartKey: this.chartName, value: title });
},
search() {
let urlPath = this.$router.currentRoute.fullPath;
let index = urlPath.indexOf('/ems/base/EnrgSystemMonitoringMngPage');
if (index >= 0) {
this.getChartData();
}
},
searchInit() {
this.pageData.upReadPlcId = 'ROOT';
},
async searchTimer() {
let urlPath = this.$router.currentRoute.fullPath;
let index = urlPath.indexOf('/ems/base/EnrgSystemMonitoringMngPage');
if (index >= 0) {
let res = [];
if (
this.pageData.blocMstrList.length > 0 &&
this.pageData.energyList.length > 0
) {
res = await this.postApiReturn({
apiKey: 'selectEnrgSystemMonitoringInfo',
//resKey:"enrgSystemMonitoringInfoData",
resKey: 'enrgSystemMonitoringInfoTreeData',
// sendParm : sendParams
sendParam: {
upReadPlcId: this.pageData.upReadPlcId,
energyCd: this.pageData.energyList[this.pageData.energyCd].cd,
// sh_blocCd:"BL0001"
blocId: this.pageData.blocMstrList[this.pageData.blocId].blocId,
},
});
}
this.setPageData({ isFind: false });
this.setChartSeriesData(res);
this.loadChart = true;
this.loadGrid = true;
}
},
setView(value) {
this.isFind = true;
},
makeDataAndLinks(parentsVo, chlVo, data, link) {
let retVal = 0;
//console.log("chlVo.has('childeVo') : ", chlVo["childeVo"]);
if (chlVo['childeVo'] != null || chlVo['childeVo'] != undefined) {
// 하위 자료가 있으면
let subSum = 0;
for (var idx in chlVo['childeVo']) {
let subRet = this.makeDataAndLinks(
chlVo,
chlVo['childeVo'][idx],
data,
link,
);
subSum += subRet;
}
if (chlVo.instantVal > subSum) {
//this.makeDataAndLinksOverVal(parentsVo, chlVo, data, link, chlVo.instantVal - subSum);
}
if (chlVo.instantVal != null && chlVo.instantVal > 0) {
retVal = chlVo.instantVal;
}
const chartColor = this.getColor();
data.push({
name: chlVo.readPlcNm + '(' + chlVo.readPlcId + ')',
readPlcId: chlVo.readPlcId,
upReadPlcId: chlVo.upReadPlcId,
downPlcCnt: chlVo.downPlcCnt,
itemStyle: {
color: chartColor,
borderColor: chartColor,
},
label: {
show: true,
formatter:
chlVo.readPlcNm +
'\n순시 :' +
Utility.setFormatIntDecimal(chlVo.instantVal, 2) +
'\n적산 :' +
Utility.setFormatIntDecimal(chlVo.addupVal, 2),
rich: this.pageData.richData,
},
tooltip: {
formatter:
chlVo.readPlcNm +
'<br />순시 :' +
Utility.setFormatIntDecimal(chlVo.instantVal, 2) +
'<br />적산 :' +
Utility.setFormatIntDecimal(chlVo.addupVal, 2),
// formatter: [
// '{title|{b}}{titlebg|}',
// ' {typeHead|순시 : }{value|' + Utility.setFormatIntDecimal(chlVo.instantVal,2) + '}',
// ' {typeHead|적산 : }{value|' + Utility.setFormatIntDecimal(chlVo.addupVal,2) + '}',
// ].join('\n'),
// backgroundColor: '#eee',
// borderColor: '#777',
// borderWidth: 1,
// borderRadius: 4,
// rich: this.pageData.richData
},
});
if (parentsVo != null) {
console.debug('parentsVo : ', parentsVo);
console.debug('parentsVo.readPlcNm : ', parentsVo.readPlcNm);
link.push({
source: parentsVo.readPlcNm + '(' + parentsVo.readPlcId + ')',
target: chlVo.readPlcNm + '(' + chlVo.readPlcId + ')',
value: chlVo.instantVal,
});
}
} else {
// 하위 자료가 없으면.
let labelFormatter = '';
let labelPosition = 'left';
if (chlVo.maxLvl < 3 || chlVo.maxLvl > chlVo.lvl) {
labelFormatter =
chlVo.readPlcNm +
'\n순시 :' +
Utility.setFormatIntDecimal(chlVo.instantVal, 2) +
'\n적산 :' +
Utility.setFormatIntDecimal(chlVo.addupVal, 2);
} else {
labelFormatter = chlVo.readPlcNm;
}
if (chlVo.maxLvl > chlVo.lvl) {
labelPosition = 'right';
}
const chartColor = this.getColor();
data.push({
name: chlVo.readPlcNm + '(' + chlVo.readPlcId + ')',
readPlcId: chlVo.readPlcId,
upReadPlcId: chlVo.upReadPlcId,
downPlcCnt: chlVo.downPlcCnt,
itemStyle: {
color: chartColor,
borderColor: chartColor,
},
label: {
show: true,
formatter: labelFormatter,
position: labelPosition,
},
tooltip: {
formatter:
chlVo.readPlcNm +
'<br />순시 :' +
Utility.setFormatIntDecimal(chlVo.instantVal, 2) +
'<br />적산 :' +
Utility.setFormatIntDecimal(chlVo.addupVal, 2),
// formatter: [
// '{title|{b}}{titlebg|}',
// ' {typeHead|순시 : }{value|' + Utility.setFormatIntDecimal(chlVo.instantVal,2) + '}',
// ' {typeHead|적산 : }{value|' + Utility.setFormatIntDecimal(chlVo.addupVal,2) + '}',
// ].join('\n'),
// backgroundColor: '#eee',
// borderColor: '#777',
// borderWidth: 1,
// borderRadius: 4,
// rich: this.pageData.richData
},
});
if (parentsVo != null) {
console.debug('parentsVo : ', parentsVo);
console.debug('parentsVo.readPlcNm : ', parentsVo.readPlcNm);
link.push({
source: parentsVo.readPlcNm + '(' + parentsVo.readPlcId + ')',
target: chlVo.readPlcNm + '(' + chlVo.readPlcId + ')',
value: chlVo.instantVal == null ? 0 : chlVo.instantVal,
});
}
retVal = chlVo.instantVal == null ? 0 : chlVo.instantVal;
if (retVal < 0) {
retVal = 0;
}
}
// if(parentsVo == null){
// }else{
// }
return retVal;
},
makeDataAndLinksOverVal(parentsVo, chlVo, data, link, otherVal) {
//console.log("makeDataAndLinksOverVal : ", chlVo, data, link, otherVal);
let labelFormatter = '';
let labelPosition = 'left';
if (chlVo.maxLvl < 3 || chlVo.maxLvl > chlVo.lvl + 1) {
labelFormatter =
chlVo.readPlcNm +
'_미검침 사용량\n순시 :' +
Utility.setFormatIntDecimal(otherVal, 2);
} else {
labelFormatter = chlVo.readPlcNm + '_미검침 사용량';
}
if (chlVo.maxLvl > chlVo.lvl + 1) {
labelPosition = 'right';
}
// const chartColor = this.getColor();
data.push({
name: chlVo.readPlcNm + '_미검침 사용량(' + chlVo.readPlcId + '_OTHER)',
readPlcId: chlVo.readPlcId + '_OTHER',
upReadPlcId: chlVo.upReadPlcId,
downPlcCnt: 0,
itemStyle: {
color: '#FF0000',
borderColor: '#FF0000',
},
label: {
show: true,
formatter: labelFormatter,
position: labelPosition,
},
tooltip: {
formatter:
chlVo.readPlcNm +
'_미검침 사용량<br />순시 :' +
Utility.setFormatIntDecimal(otherVal, 2),
},
});
link.push({
source: chlVo.readPlcNm + '(' + chlVo.readPlcId + ')',
target:
chlVo.readPlcNm + '_미검침 사용량(' + chlVo.readPlcId + '_OTHER)',
value: otherVal,
lineStyle: {
color: '#FF0000',
},
});
},
getColor() {
let retColor = '';
if (this.pageData.colorInx1st > 4) {
this.pageData.colorInx1st = 0;
this.pageData.colorInx2st += 1;
}
if (this.pageData.colorInx2st > 9) {
this.pageData.colorInx2st = 0;
this.pageData.colorInx1st += 1;
}
if (this.isDarkMode) {
retColor = this.pageData.darkColorSet[this.pageData.colorInx1st][
this.pageData.colorInx2st
];
} else {
retColor = this.pageData.lightColorSet[this.pageData.colorInx1st][
this.pageData.colorInx2st
];
}
this.pageData.colorInx1st += 1;
return retColor;
},
chartDblClick(event) {
// console.log("chartDblClick : ", event);
if (event.componentType == 'series' && event.data.downPlcCnt > 0) {
this.pageData.upReadPlcId = event.data.readPlcId;
this.pageData.parentsReadPlcId = event.data.upReadPlcId;
}
},
chartClick(evnet) {
// console.log("chartClick : ", evnet);
//console.log(evnet.componentType, evnet.componentIndex, this.pageData.upReadPlcId, this.pageData.parentsReadPlcId);
if (evnet.componentType == 'title' && evnet.componentIndex == 1) {
// console.log("여기 오남 : ", this.pageData.upReadPlcId, this.pageData.parentsReadPlcId);
this.pageData.upReadPlcId = this.pageData.parentsReadPlcId;
// console.log("여기 오남 2 : ", this.pageData.upReadPlcId, this.pageData.parentsReadPlcId);
}
},
},
};
const defaultData = {
/* 검색옵션 */
upReadPlcId: 'ROOT',
parentsReadPlcId: 'RPC000001',
energyCd: 'ROI000001',
energyList: [],
blocId: '',
blocMstrList: [],
viewCheck: 'viewAll',
isFind: false, // true 경우 조회, 조회버튼도 이 값으로 연동 예정
colorInx1st: 0,
colorInx2st: 0,
/*chartdata 세팅 */
sankyChart: {
tooltip: {
trigger: 'axis',
confine: true,
axisPointer: {
type: 'shadow',
},
},
grid: {
left: '0',
right: '0',
top: '0',
},
legend: null,
series: [],
title: {},
backgroundColor: '',
},
richData: {
title: {
color: '#eee',
align: 'center',
},
titleBg: {
backgroundColor: '#999',
width: '100%',
align: 'right',
height: 25,
borderRadius: [4, 4, 0, 0],
},
typeHead: {
color: '#333',
height: 24,
width: 40,
align: 'left',
},
value: {
color: '#333',
width: 70,
padding: [0, 10, 0, 10],
align: 'right',
},
},
darkColorSet: [
[
'#01AE6A',
'#04A166',
'#089362',
'#0B865D',
'#0F7959',
'#126C55',
'#165E51',
'#19514D',
'#1D4448',
'#1F3D46',
],
[
'#FFB046',
'#EAA345',
'#D39545',
'#BE8844',
'#A77A44',
'#926D43',
'#7C5F42',
'#665242',
'#4C4141',
'#453D41',
],
[
'#F6637B',
'#E15D75',
'#CC576F',
'#B75269',
'#A24C63',
'#8D465E',
'#784058',
'#633B52',
'#4E354C',
'#433249',
],
[
'#944FE9',
'#894BD8',
'#7E47C7',
'#7344B7',
'#6740A5',
'#5C3C95',
'#513884',
'#463473',
'#3A3162',
'#352F59',
],
[
'#4385E3',
'#407CD3',
'#3D73C2',
'#3A6AB2',
'#3760A2',
'#345792',
'#304E81',
'#2D4571',
'#2A3B61',
'#293758',
],
],
lightColorSet: [
[
'#3CC380',
'#4BC88A',
'#5BCD94',
'#6BD19E',
'#7BD6A9',
'#8ADBB3',
'#99E0BD',
'#A9E5C7',
'#B9E9D1',
'#C9EEDC',
],
[
'#FFB13B',
'#FFB74A',
'#FFBE5B',
'#FFC46A',
'#FFCA7A',
'#FFD089',
'#FFD699',
'#FFDDA9',
'#FFE3B8',
'#FFE9C8',
],
[
'#F98694',
'#F98F9C',
'#FA99A5',
'#FAA3AE',
'#FBADB6',
'#FBB6BF',
'#FCC0C7',
'#FCCAD0',
'#FDD3D8',
'#FDDDE1',
],
[
'#CF74E5',
'#D37FE7',
'#D78AE9',
'#DA95EB',
'#DEA1ED',
'#E2ACEF',
'#E6B7F1',
'#EAC2F4',
'#EECDF6',
'#F2D8F8',
],
[
'#6A9BF4',
'#76A3F5',
'#82ABF6',
'#8EB3F7',
'#9ABBF8',
'#A6C3F8',
'#B1CBF9',
'#BED3FA',
'#C9DBFB',
'#D6E3FC',
],
],
};
</script>
<style lang="scss">
@import '@/assets/scss/common.scss';
</style>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,819 @@
<template>
<div class="l-layout">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="2">
<!-- 사업장 -->
<component
:is="'SelectBlocMstr'"
ref="SelectBlocMstr"
:parentPrgmId="myPrgmId"
/>
</v-col>
<v-col :cols="2">
<!-- 에너지 -->
<component
:is="'SelectEnergy'"
:parentPrgmId="myPrgmId"
:label="'에너지'"
/>
</v-col>
<v-col cols="2">
<!-- 주기 -->
<component :is="'SelectCmCycle'" :parentPrgmId="myPrgmId" />
</v-col>
<v-col cols="4">
<!-- 조회기간 -->
<!-- <component :is="swichDatePicker" :parentPrgmId="myPrgmId" /> -->
<DatePicker
:parentPrgmId="myPrgmId"
label="조회기간"
:labelCols="3"
:textCols="9"
/>
</v-col>
<v-col cols="2" class="d-flex justify-end align-center">
<BtnSearch @click="search" class="mr-1" />
<BtnExcelDownload :parentPrgmId="myPrgmId" :gridName="gridName" />
</v-col>
</v-row>
<v-row align="center" no-gutters>
<v-col :cols="4">
<!-- 공정/설비 -->
<component
:is="'FtnPlcMultiPop'"
:parentPrgmId="myPrgmId"
:labelCols="2"
:textCols="10"
/>
</v-col>
<v-col :cols="2">
<v-radio-group v-model="radioButtonData" row hide-details dense>
<v-col :cols="4">
<label for="" class="search-box-label">
<v-icon x-small color="primary" class="mr-1"
>mdi-record-circle</v-icon
>
구분
</label>
</v-col>
<v-radio
label="사용량"
value="0"
on-icon="mdi-record-circle"
:color="isDarkMode ? '#1b74d7' : '#4777d9'"
:ripple="false"
></v-radio>
<v-radio
label="비용"
value="1"
on-icon="mdi-record-circle"
:color="isDarkMode ? '#1b74d7' : '#4777d9'"
:ripple="false"
></v-radio>
</v-radio-group>
</v-col>
<v-col :cols="2">
<v-row class="search-box">
<v-col :cols="6">
<label for="" class="search-box-label">
<v-icon x-small color="primary" class="mr-1"
>mdi-record-circle</v-icon
>
합계
</label>
</v-col>
<v-col :cols="6">
<v-checkbox
v-model="sumChkValue"
:color="isDarkMode ? '#fff' : '#4777d9'"
></v-checkbox>
</v-col>
</v-row>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents" style="height: calc(100vh - 230px)">
<v-col>
<v-card>
<div ref="chartParent" style="height: 50%">
<component
class="w100 h100"
:is="loadChart ? 'Chart' : null"
:parentPrgmId="myPrgmId"
:chartName="'rowGridChart'"
/>
</div>
<!-- <p class="custom-text-2 font-weight-bold text-right text-color--non-activate" v-if="unit"> 단위 : {{unit}}</p> -->
<v-card-title>
<!-- 차트와 그리드 사이 공백을 위한 공간 -->
</v-card-title>
<div ref="gridParent" class="px-5" style="height: 43%">
<component
:is="loadGrid ? 'Grid' : null"
:gridName="gridName"
:parentPrgmId="myPrgmId"
ref="rowGrid"
/>
</div>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex';
import SelectBlocMstr from '@/components/common/select/SelectBlocMstrForPop';
import SelectEnergy from '@/components/common/select/SelectEnergyForPop';
import SelectCmCycle from '@/components/common/select/SelectCmCycle';
import SelectDate from '~/components/common/select/SelectDate';
import SelectDateVc from '~/components/common/select/SelectDateVc';
import FtnPlcMultiPop from '~/components/common/modal/FtnPlcMultiPop2';
import BtnSearch from '~/components/common/button/BtnSearch';
import BtnExcelDownload from '~/components/common/button/BtnExcelDownload';
import Utility from '~/plugins/utility';
import Grid from '~/components/common/Grid';
import Chart from '~/components/common/Chart';
import DatePicker from '~/components/common/Datepicker';
import mixinGlobal from '@/mixin/global.js';
let myTitle;
//const myPrgmId = "PRG0022";
let myPrgmId;
export default {
mixins: [mixinGlobal],
async asyncData(context) {
const myState = context.store.state;
// context.store.commit("setActiveMenuInfo", myState.menuData[myPrgmId]);
// myTitle = myState.activeMenuInfo.menuNm;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
SelectBlocMstr,
SelectEnergy,
SelectCmCycle,
SelectDate,
SelectDateVc,
FtnPlcMultiPop,
BtnSearch,
BtnExcelDownload,
Utility,
Grid,
Chart,
DatePicker,
},
data() {
return {
myPrgmId: myPrgmId,
gridName: 'rowGrid',
loadGrid: false,
loadChart: false,
radioButtonData: '0', // 0: 사용량, 1: 비용
unit: '', // 그리드 우상단 라벨
apiKey: 'selectEnergyUseReadYear',
locKind: 'LOC_COM', // defaultValue
upEccId: 'PLC00001', // defaultValue
qtyLength: [],
};
},
computed: {
...mapState({
pageData: state => state.pageData[myPrgmId],
isDarkMode: state => state.isDarkMode,
}),
swichDatePicker() {
let picker = 'SelectDateVc';
if (
this.pageData.cmCycle == 'CYC_MONTH' ||
this.pageData.cmCycle == 'CYC_YEAR'
) {
picker = 'SelectDate';
}
return picker;
},
sumChkValue: {
get() {
return this.pageData.chkSum;
},
set(value) {
return this.setPageData({ chkSum: value });
},
},
chkIsFind() {
return this.pageData.isFind;
},
myCmCycle() {
return this.pageData.cmCycle;
},
chkBlocCd() {
return this.pageData.blocId;
},
chkEnergyCd() {
return this.pageData.energyCd;
},
chkFacInfo() {
return this.pageData.facInfo;
},
initFlag() {
if (
this.pageData.energyList.length > 0 &&
this.pageData.blocMstrList.length > 0
) {
return true;
} else {
return false;
}
},
},
watch: {
sumChkValue(val) {
this.setPageData({ isFind: true });
},
chkIsFind(val) {
if (val) this.search();
},
myCmCycle: function(val) {},
chkBlocCd() {},
chkEnergyCd() {
this.setUnitLabel();
},
chkFacInfo() {
this.setPageData({ isFind: true });
},
radioButtonData() {
this.setPageData({ isFind: true });
},
initFlag(val) {
if (val) {
this.init();
}
},
},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
created() {},
mounted() {},
methods: {
...mapMutations({
setPageData: 'setPageData',
setGridData: 'setGridData',
setGridColumn: 'setGridColumn',
setGridOption: 'setGridOption',
setChartXAxisData: 'setChartXAxisData',
setChartSeries: 'setChartSeries',
setChartOption: 'setChartOption',
}),
...mapActions({
postApi: 'modules/list/postApi',
postUpdateApi: 'modules/list/postUpdateApi',
postApiReturn: 'modules/list/postApiReturn',
setTree: 'modules/list/setTree',
chkOpenTabList: 'chkOpenTabList',
}),
init() {
this.layoutInit();
this.gridInit();
},
layoutInit() {
const searchFilterHeight = this.$refs.searchFilter.offsetHeight;
this.$refs.contents.style.height = `calc(100% - ${searchFilterHeight}px)`;
},
async search() {
this.setLocalStorage();
await this.getFacList();
},
setLocalStorage() {
if (this.pageData.energyCd !== '' && this.pageData.energyCd != null) {
localStorage.setItem(
myPrgmId + 'SelectedEnergyCd',
this.pageData.energyCd,
);
}
if (this.pageData.blocId !== '' && this.pageData.blocId != null) {
localStorage.setItem(myPrgmId + 'SelectedBlocCd', this.pageData.blocId);
}
},
setUnitLabel() {
this.unit = this.pageData.energyList[this.pageData.energyCd].unit
? this.pageData.energyList[this.pageData.energyCd].unit
: 'kwh';
if (this.apiKey.search('Cost') > 0) {
this.unit = '원';
}
},
setApiKey() {
var apiKeyMapper = {
/*
cycValue + radioButtonData
사용량 API : ~0
비용 API : ~1
*/
CYC_YEAR0: 'selectEnergyUseReadYear',
CYC_MONTH0: 'selectEnergyUseReadMonth',
CYC_DAY0: 'selectEnergyUseReadDay',
CYC_HOUR0: 'selectEnergyUseReadHour',
CYC_YEAR1: 'selectEnergyUseReadYearCost',
CYC_MONTH1: 'selectEnergyUseReadMonthCost',
CYC_DAY1: 'selectEnergyUseReadDayCost',
CYC_HOUR1: 'selectEnergyUseReadHourCost',
};
this.apiKey = apiKeyMapper[this.pageData.cmCycle + this.radioButtonData];
},
gridInit() {
const gridHeight = this.$refs.gridParent.offsetHeight - 46;
const myOptions = {
// scrollX: false,
setScroll: true,
columnOptions: {
//frozenCount:2,
minWidth: 100,
resizable: true,
},
};
this.setGridOption({
gridKey: this.gridName,
value: Object.assign(Utility.defaultGridOption(gridHeight), myOptions),
});
this.getFacList();
},
async getFacList() {
this.loadChart = false;
this.pageData.rowGrid.data = [];
var facList = null;
this.setApiKey();
if (
this.pageData.blocMstrList.length > 0 &&
this.pageData.energyList.length > 0
) {
this.setUnitLabel();
var apiParameters = {
blocId: this.pageData.blocMstrList[this.chkBlocCd].blocId, //"BL0001",
readObjId: this.pageData.energyList[this.chkEnergyCd].cd,
locKind: this.pageData.facInfo.locKind
? this.pageData.facInfo.locKind
: this.locKind,
upEccId: this.pageData.facInfo.eccId
? this.pageData.facInfo.eccId
: this.eccId,
};
facList = await this.postApiReturn({
apiKey: 'selectEnergyUseReadDnPlc',
resKey: 'energyUseReadDnPlc',
sendParam: apiParameters,
});
const isRange =
this.pageData.defaultRange[this.pageData.cmCycle] === 0
? false
: true;
apiParameters['toObjDt'] = isRange
? this.pageData.toDt
: this.pageData.fromDt;
apiParameters['fromObjDt'] = this.pageData.fromDt;
apiParameters['eccId'] = facList.map(item => item.eccId);
apiParameters['eccNm'] = facList.map(item => item.eccNm);
this.setQtyParameters(apiParameters);
await this.getGridData(apiParameters);
} else {
this.setPageData({ isFind: false });
}
this.setPageData({ isFind: false });
},
setQtyParameters(params) {
switch (this.pageData.cmCycle) {
case 'CYC_YEAR':
var qtyNumber;
var year = parseInt(params['fromObjDt']);
for (var i = 0; i < 10; i++) {
qtyNumber = (i + 1).toString().padStart(2, '0');
params['qty' + qtyNumber] = (year++).toString();
}
break;
case 'CYC_MONTH':
var qtyNumber;
var date = new Date(
params['fromObjDt'].substr(0, 4),
params['fromObjDt'].substr(4, 2),
);
date.setMonth(date.getMonth() - 1);
for (var i = 0; i < 12; i++) {
qtyNumber = (i + 1).toString().padStart(2, '0');
params['qtyY' + qtyNumber] = String(date.getFullYear());
params['qtyM' + qtyNumber] = String(date.getMonth() + 1).padStart(
2,
'0',
);
date.setMonth(date.getMonth() + 1);
}
break;
case 'CYC_DAY':
var qtyNumber;
var date = new Date(
params['fromObjDt'].substr(0, 4),
params['fromObjDt'].substr(4, 2),
params['fromObjDt'].substr(6, 2),
);
date.setMonth(date.getMonth() - 1);
for (var i = 0; i < 31; i++) {
qtyNumber = (i + 1).toString().padStart(2, '0');
params['qty' + qtyNumber] =
String(date.getFullYear()) +
String(date.getMonth() + 1).padStart(2, '0') +
String(date.getDate()).padStart(2, '0');
date.setDate(date.getDate() + 1);
}
break;
case 'CYC_HOUR':
break;
}
},
makeColumnList(params) {
var colNameList = [
{ header: '에너지', name: 'readObjNm', align: 'center', width: '200' },
{ header: '구분', name: 'eccNm', align: 'left', width: '200' },
];
switch (this.pageData.cmCycle) {
case 'CYC_YEAR':
var qtyNumber, qtyStr;
for (var i = 0; i < 10; i++) {
qtyNumber = (i + 1).toString().padStart(2, '0');
qtyStr = 'qty' + qtyNumber;
if (
parseInt(params[qtyStr]) >= parseInt(params['fromObjDt']) &&
parseInt(params[qtyStr]) <= parseInt(params['toObjDt'])
) {
colNameList.push({
header: params[qtyStr],
name: qtyStr,
align: 'right',
excelType: 'number',
excelFormatter: '2',
formatter: numberFormatter,
});
}
}
break;
case 'CYC_MONTH':
var qtyNumber;
var qtyY;
var qtyM;
for (var i = 0; i < 12; i++) {
qtyNumber = (i + 1).toString().padStart(2, '0');
qtyStr = 'qty' + qtyNumber;
qtyY = 'qtyY' + qtyNumber;
qtyM = 'qtyM' + qtyNumber;
if (
parseInt(params[qtyY] + params[qtyM]) >=
parseInt(params['fromObjDt']) &&
parseInt(params[qtyY] + params[qtyM]) <=
parseInt(params['toObjDt'])
) {
colNameList.push({
header: params[qtyY] + '/' + params[qtyM],
name: qtyStr,
align: 'right',
excelType: 'number',
excelFormatter: '2',
formatter: numberFormatter,
});
}
}
break;
case 'CYC_DAY':
var qtyNumber, qtyStr;
for (var i = 0; i < 31; i++) {
qtyNumber = (i + 1).toString().padStart(2, '0');
qtyStr = 'qty' + qtyNumber;
if (
parseInt(params[qtyStr]) >= parseInt(params['fromObjDt']) &&
parseInt(params[qtyStr]) <= parseInt(params['toObjDt'])
) {
colNameList.push({
header:
params[qtyStr].substr(4, 2) +
'/' +
params[qtyStr].substr(6, 2),
name: qtyStr,
align: 'right',
excelType: 'number',
excelFormatter: '2',
formatter: numberFormatter,
});
}
}
break;
case 'CYC_HOUR':
var qtyNumber, qtyStr;
for (var i = 0; i < 24; i++) {
qtyNumber = i.toString().padStart(2, '0');
qtyStr = 'qty' + qtyNumber;
colNameList.push({
header: i.toString().padStart(1, '0') + '시',
name: qtyStr,
align: 'right',
excelType: 'number',
excelFormatter: '2',
formatter: numberFormatter,
});
}
break;
}
return colNameList;
},
addChkSumRowData(res) {
var chkSumRowData = {};
var columnListMap = {
CYC_YEAR: [
'qty01',
'qty02',
'qty03',
'qty04',
'qty05',
'qty06',
'qty07',
'qty08',
'qty09',
'qty10',
],
CYC_MONTH: [
'qty01',
'qty02',
'qty03',
'qty04',
'qty05',
'qty06',
'qty07',
'qty08',
'qty09',
'qty10',
'qty11',
'qty12',
],
CYC_DAY: [
'qty01',
'qty02',
'qty03',
'qty04',
'qty05',
'qty06',
'qty07',
'qty08',
'qty09',
'qty10',
'qty11',
'qty12',
'qty13',
'qty14',
'qty15',
'qty16',
'qty17',
'qty18',
'qty19',
'qty20',
'qty21',
'qty22',
'qty23',
'qty24',
'qty25',
'qty26',
'qty27',
'qty28',
'qty29',
'qty30',
'qty31',
],
CYC_HOUR: [
'qty00',
'qty01',
'qty02',
'qty03',
'qty04',
'qty05',
'qty06',
'qty07',
'qty08',
'qty09',
'qty10',
'qty11',
'qty12',
'qty13',
'qty14',
'qty15',
'qty16',
'qty17',
'qty18',
'qty19',
'qty20',
'qty21',
'qty22',
'qty23',
],
};
var columnList = columnListMap[this.myCmCycle];
if (this.sumChkValue && res.length && res.length > 0) {
chkSumRowData['eccNm'] = this.pageData.facInfo.eccNm;
chkSumRowData['eccId'] = this.pageData.facInfo.eccId;
chkSumRowData['readObjNm'] = res[0]['readObjNm'];
chkSumRowData['readObjId'] = res[0]['readObjId'];
chkSumRowData['comId'] = res[0]['comId'];
for (var i = 0; i < columnList.length; i++) {
chkSumRowData[columnList[i]] = 0;
}
for (var i = 0; i < res.length; i++) {
for (var j = 0; j < columnList.length; j++) {
var oldValue =
chkSumRowData[columnList[j]] != undefined
? chkSumRowData[columnList[j]]
: 0;
var newValue =
res[i][columnList[j]] != undefined ? res[i][columnList[j]] : 0;
chkSumRowData[columnList[j]] =
Math.round((oldValue + newValue) * 100) / 100;
}
}
// res.unshift(chkSumRowData);
res.push(chkSumRowData);
}
},
async getGridData(params) {
var res = null;
this.loadGrid = false;
let colNameList = await this.makeColumnList(params);
try {
res = await this.postApiReturn({
apiKey: this.apiKey,
resKey: 'energyUseRead',
sendParam: params,
});
} catch (error) {
res = [];
}
// res = await this.postApiReturn({
// apiKey: this.apiKey,
// resKey: "energyUseRead",
// sendParam: params
// });
// if(res.length < 1){
// for(var i=0;i<params.eccNm.length;i++){
// res.push({
// readObjNm : this.pageData.energyList[this.pageData.energyCd].enrgNm,
// eccNm:params.eccNm[i]
// })
// }
// }
this.addChkSumRowData(res);
if (res.length && res.length > 0) {
Object.assign(res[0], {
_attributes: { rowSpan: { readObjNm: res.length } },
});
}
this.setGridColumn({
gridKey: this.gridName,
value: colNameList,
});
this.setGridData({
gridKey: this.gridName,
value: res,
});
this.loadGrid = true;
this.setPageData({ isFind: false });
this.setChartData(res);
},
setChartData(data) {
this.$store.state.pageData[this.myPrgmId].rowGridChart.series = [];
// if(!data.length){
// return;
// }
let exceptionColumList = ['에너지', '구분'];
let xAxisData = [];
let seriesData = [];
var keyList = this.pageData[this.gridName].column.filter(el => {
return !exceptionColumList.includes(el.header);
});
xAxisData = keyList.map(el => el.header);
seriesData = data.map(item => ({
name: item.eccNm,
type: 'line',
data: keyList.map(obj => item[obj.name] || 0),
}));
var _this = this;
var chartOption = {
grid: {
top: '3%',
// right: '8%',
},
yAxis: {
type: 'value',
nameLocation: 'middle',
nameGap: 45,
name: _this.unit,
},
xAxis: {
data: xAxisData,
},
series: seriesData,
};
this.setChartOption({ chartKey: 'rowGridChart', value: chartOption });
this.loadChart = true;
},
},
};
const defaultData = {
isFind: false,
blocId: '',
blocMstrList: [],
energyCd: '',
energyList: [],
cmCycle: 'CYC_HOUR',
cmCycleList: [
{ idx: 0, text: '연', value: 'CYC_YEAR' },
{ idx: 1, text: '월', value: 'CYC_MONTH' },
{ idx: 2, text: '일', value: 'CYC_DAY' },
{ idx: 3, text: '시간', value: 'CYC_HOUR' },
],
defaultRange: {
CYC_YEAR: 10,
CYC_MONTH: 12,
CYC_DAY: 30,
CYC_HOUR: 0,
},
fromDt: '',
toDt: '',
facInfo: {},
chkSum: false,
rowGrid: {
data: [],
option: {},
column: [],
},
modalData: {},
isMulti: false,
rowGridChart: Utility.defaultChartOption(true),
xlsFileInfo: {
rowGrid: {
fileName: null,
sheetName: null,
},
},
};
function numberFormatter({ value }) {
return Utility.setFormatIntDecimal(value, 2);
}
</script>
<style lang="scss">
@import '@/assets/scss/common.scss';
</style>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,444 @@
<template>
<div ref="mainDiv" class="l-layout">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="5">
<InputText
:parentPrgmId="myPrgmId"
label="설비종류명"
valueNm="eqpmKindNm"
:searchOption="true"
:textCols="9"
:labelCols="3"
/>
</v-col>
<v-col :cols="7" class="text-right">
<BtnSearch @click="search" />
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents">
<v-col :cols="5" class="h100">
<v-card class="pb-5">
<div class="d-flex align-center justify-space-between pa-5">
<v-card-title class="pa-0">설비종류</v-card-title>
<Buttons
:parentPrgmId="myPrgmId"
:bindingData="gridName"
:btnActionsFnc="btnActions"
/>
</div>
<div class="h100 px-5" style="height:calc(100% - 70px)">
<div ref="gridParent" class="w100 h100">
<component
:ref="gridName"
:is="loadGrid ? 'Grid' : null"
:gridName="gridName"
:parentPrgmId="myPrgmId"
@getRowsData="getRowData"
:preventFocusChangeEventFlag="false"
/>
</div>
</div>
</v-card>
</v-col>
<v-col :cols="7" class="h100">
<v-card class="pb-5">
<div class="d-flex align-center justify-space-between pa-5">
<v-card-title class="pa-0">설비종류 상세</v-card-title>
</div>
<div class="px-5" style="height:calc(100% - 76px)">
<component
:is="'Form'"
:parentPrgmId="myPrgmId"
:detailList="detailList"
@gridEditingFinish="gridEditingFinish"
/>
</div>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex';
import { resize } from '@/mixin/resize.js';
import mixinGlobal from '@/mixin/global.js';
import BtnSearch from '~/components/common/button/BtnSearch';
import Buttons from '~/components/common/button/Buttons';
import selectCodeList from '@/components/common/select/selectCodeList';
import InputText from '@/components/common/input/InputText';
import Form from '~/components/common/form/Form';
import Grid from '~/components/common/Grid';
import Utility from '~/plugins/utility';
import SelectBox from '@/components/common/select/SelectBox';
let myTitle;
// const myPrgmId = "PRG0013";
let myPrgmId;
export default {
mixins: [mixinGlobal, resize],
async asyncData(context) {
const myState = context.store.state;
// context.store.commit("setActiveMenuInfo", myState.menuData[myPrgmId]);
// myTitle = myState.activeMenuInfo.menuNm;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
BtnSearch,
Buttons,
selectCodeList,
InputText,
Form,
Grid,
Utility,
SelectBox,
},
data() {
return {
myPrgmId: myPrgmId,
gridName: 'eqpmKindGrid',
loadGrid: false,
tab: null,
detailList: myDetail,
selectValueList01: [],
selectValue01: null,
};
},
computed: {
// ...mapState({
// pageData: state => state.pageData[myPrgmId]
// }),
chkIsFind() {
// 조회 플래그
return this.pageData.isFind;
},
chkUseFg() {
// 사용여부 선택 감지
return this.pageData.useFg;
},
},
watch: {
chkIsFind(val) {
if (val) this.search();
},
chkUseFg() {
this.setPageData({ isFind: true });
},
},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
created() {},
mounted() {
this.gridInit();
// this.init();
},
beforeDestroy() {
this.chkOpenTabList({ key: 'destroy', prgmId: myPrgmId });
},
methods: {
...mapActions({}),
init() {
// this.gridInit();
},
gridInit() {
const gridHeight = this.$refs.gridParent.offsetHeight - 30;
const gridWidth = this.$refs.gridParent.offsetWidth;
const myOptions = {
columnOptions: {
resizable: true,
},
};
this.setGridOption({
gridKey: this.gridName,
value: Object.assign(Utility.defaultGridOption(gridHeight), myOptions),
});
const _this = this;
const myColumns = [
{
header: '설비종류ID',
name: 'eqpmKindId',
width: gridWidth * 0.5,
align: 'center',
},
{
header: '설비종류명',
name: 'eqpmKindNm',
width: gridWidth * 0.5,
align: 'left',
},
{ header: '등록자NO', name: 'regUserNo', hidden: true },
{ header: '등록일시', name: 'regDttm', hidden: true },
{ header: '수정자NO', name: 'procUserNo', hidden: true },
{ header: '수정일시', name: 'procDttm', hidden: true },
];
this.setGridColumn({
gridKey: this.gridName,
value: myColumns,
});
this.loadGrid = true;
this.getRowGridData();
},
async search() {
this.loadGrid = false;
await this.getRowGridData();
await this.setPageData({
isFind: false,
});
},
async getRowGridData() {
const res = await this.postApiReturn({
apiKey: 'selectEqpmKind',
resKey: 'eqpmKindData',
sendParam: {
eqpmKindNm: this.pageData.eqpmKindNm,
},
});
const newRes = res.map(item => {
const newObj = {
...item,
rowStat: null,
};
return newObj;
});
this.setGridData({
gridKey: this.gridName,
value: newRes,
});
this.loadGrid = true;
this.$nextTick(() => {
if (newRes.length > 0) {
this.$refs[this.gridName].focus({
//rowKey: 0,
rowKey:
this.pageData.rowGridSelectKey == '' ||
this.pageData.rowGridSelectKey == null
? 0
: this.pageData.rowGridSelectKey ==
this.$refs[this.gridName].getData().length - 1
? this.pageData.rowGridSelectKey
: 0,
setScroll: true,
});
}
});
},
async getRowData(data) {
this.setPageData({
rowGridSelectKey: data.rowKey,
rowGridSelectData: data,
});
},
gridEditingFinish(data) {
this.$refs[this.gridName].editingFinish(data);
},
async btnActions(action) {
let dataArr = [];
switch (action) {
case 'add':
var defaultRow = {
eqpmKindId: '',
eqpmKindNm: '',
rowStat: null,
};
this.$refs[this.gridName].addRow(defaultRow);
break;
case 'remove':
this.$refs[this.gridName].removeRow();
break;
case 'save':
dataArr = this.$refs[this.gridName].save();
if (dataArr.length > 0) {
var validCheck = true;
dataArr.filter(item => {
if (item.rowStat != 'D') {
// if (confirm('삭제하시겠습니까?')) {
// validCheck = true;
// } else {
// validCheck = false;
// }
// } else {
dataArr.forEach(item => {
if (
// if(item.eqpmGrpId == null || item.eqpmGrpId == ""||
item.eqpmKindNm == '' ||
item.eqpmKindNm == null
) {
validCheck = false;
alert('필수 입력값을 입력해주세요');
} else {
validCheck = true;
}
});
}
});
if (validCheck) {
const sendParam = {
datas: {
dsEqpmKind: dataArr.map(item => ({
...item,
})),
},
params: {},
};
var result = await this.postUpdateApi({
apiKey: 'saveEqpmKind',
sendParam: sendParam,
});
if (result.data.dataset.deleteYn != '') {
alert(result.data.dataset.deleteYn);
} else {
this.$nextTick(() => {
this.setPageData({ isFind: true });
});
}
}
} else {
alert('저장할 내용이 없습니다.');
}
break;
default:
break;
}
},
},
};
const defaultData = {
/* 검색옵션 */
eqpmKindId: '',
eqpmKindNm: '',
// 선택된 그룹코드 상세 데이터
rowGridSelectKey: 0,
rowGridSelectData: null,
isFind: false, // true 경우 조회, 조회버튼도 이 값으로 연동 예정
/* data 세팅 */
// 로컬 gridName 값과 동일한 이름으로 세팅
eqpmKindGrid: {
data: [],
column: [], // myColumns,
option: {}, // myOptions
defaultRow: {
eqpmKindId: '',
eqpmKindNm: null,
rowStat: null,
},
buttonAuth: {
add: true,
remove: true,
save: true,
excel: false,
},
},
};
const myDetail = [
{
type: 'InputText',
label: '설비종류 ID',
valueNm: 'eqpmKindId',
cols: 6,
class: 'py-2',
required: false,
readonly: true,
placeholder: '시스템 자동입력',
},
{
cols: 6,
},
{
type: 'InputText',
label: '설비종류명',
valueNm: 'eqpmKindNm',
disabled: false,
cols: 6,
class: 'py-2',
required: true,
},
{
cols: 6,
},
{
type: 'InputText',
label: '등록자NO',
valueNm: 'regUserNo',
disabled: true,
cols: 6,
class: 'py-2',
placeholder: '시스템 자동입력',
},
{
cols: 6,
},
{
type: 'InputText',
label: '등록일시',
valueNm: 'regDttm',
disabled: true,
cols: 6,
class: 'py-2',
placeholder: '시스템 자동입력',
},
{
cols: 6,
},
{
type: 'InputText',
label: '수정자NO',
valueNm: 'procUserNo',
disabled: true,
cols: 6,
class: 'py-2',
placeholder: '시스템 자동입력',
},
{
cols: 6,
},
{
type: 'InputText',
label: '수정일시',
valueNm: 'procDttm',
disabled: true,
cols: 6,
class: 'py-2',
placeholder: '시스템 자동입력',
},
];
</script>
<style lang="scss">
@import '@/assets/scss/common.scss';
</style>

View File

@ -0,0 +1,560 @@
<template>
<div ref="mainDiv" class="l-layout">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="3">
<component
:is="'selectCodeList'"
:parentPrgmId="myPrgmId"
:label="'사용여부'"
dataKey="useFg"
:sendParam="{ commGrpCd: 'CO_USEFG', useFg: '1' }"
:addAll="true"
/>
</v-col>
<v-col :cols="3">
<component
:is="'SelectBox'"
ref="SelectBox1"
:propsValue="selectValue01"
:itemList="selectValueList01"
:label="'설비종류'"
@update:propsValue="selectValue01 = $event"
/>
</v-col>
<v-col :cols="3">
<InputText
:parentPrgmId="myPrgmId"
label="설비 그룹 명"
valueNm="eqpmGrpNm"
:searchOption="true"
:textCols="8"
:labelCols="4"
/>
</v-col>
<v-col :cols="3" class="text-right">
<BtnSearch @click="search" />
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents">
<v-col :cols="5" class="h100">
<v-card class="pb-5">
<v-card-title class="d-flex justify-space-between align-end">
<span class="tit ft-size_20 ft-weight_600">설비 그룹</span>
<Buttons
:parentPrgmId="myPrgmId"
:bindingData="gridName"
:btnActionsFnc="btnActions"
/>
</v-card-title>
<div class="h100 px-5" style="height:calc(100% - 70px)">
<div ref="gridParent" class="w100 h100">
<component
:ref="gridName"
:is="loadGrid ? 'Grid' : null"
:gridName="gridName"
:parentPrgmId="myPrgmId"
@getRowsData="getRowData"
/>
</div>
</div>
</v-card>
</v-col>
<v-col :cols="7" class="h100">
<v-card class="pb-5">
<div class="d-flex align-center justify-space-between pa-5">
<v-card-title class="pa-0">설비 그룹 상세</v-card-title>
</div>
<div class="px-5" style="height:calc(100% - 76px)">
<component
:is="'Form'"
:parentPrgmId="myPrgmId"
:detailList="detailList"
@gridEditingFinish="gridEditingFinish"
/>
</div>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex';
import mixinGlobal from '@/mixin/global.js';
import { resize } from '@/mixin/resize.js';
import BtnSearch from '~/components/common/button/BtnSearch';
import Buttons from '~/components/common/button/Buttons';
import selectCodeList from '@/components/common/select/selectCodeList';
import InputText from '@/components/common/input/InputText';
import Form from '~/components/common/form/Form';
import Grid from '~/components/common/Grid';
import Utility from '~/plugins/utility';
import SelectBox from '@/components/common/select/SelectBox';
let myTitle;
// const myPrgmId = "PRG0013";
let myPrgmId;
export default {
mixins: [mixinGlobal, resize],
async asyncData(context) {
const myState = context.store.state;
// context.store.commit("setActiveMenuInfo", myState.menuData[myPrgmId]);
// myTitle = myState.activeMenuInfo.menuNm;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
BtnSearch,
Buttons,
selectCodeList,
InputText,
Form,
Grid,
Utility,
SelectBox,
},
data() {
return {
myPrgmId: myPrgmId,
gridName: 'rowGrid',
loadGrid: false,
tab: null,
detailList: myDetail,
selectValueList01: [],
selectValue01: null,
};
},
computed: {
// ...mapState({
// pageData: state => state.pageData[myPrgmId]
// }),
chkIsFind() {
// 조회 플래그
return this.pageData.isFind;
},
chkUseFg() {
// 사용여부 선택 감지
return this.pageData.useFg;
},
loadFlag() {
var init1 = this.pageData.useFgList.length > 0 ? true : false;
return init1;
},
},
watch: {
chkIsFind(val) {
if (val) this.search();
},
chkUseFg() {
this.setPageData({ isFind: true });
},
loadFlag(val) {
if (val) {
this.gridInit();
}
// await this.gridInit();
},
selectValue01(val) {
this.setPageData({ isFind: true });
},
},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
created() {},
mounted() {
this.setSelectValueList01();
// if (this.loadFlag) {
// this.gridInit();
// }
// this.init();
},
beforeDestroy() {
this.chkOpenTabList({ key: 'destroy', prgmId: myPrgmId });
},
methods: {
...mapActions({}),
init() {
// this.gridInit();
},
async setSelectValueList01() {
var res = await this.postApiReturn({
apiKey: 'selectEmsEqpmKindList',
resKey: 'eqpmGrpPysclQtyMngData',
sendParam: {},
});
this.setPageData({
eqpmKindIdList: res,
eqpmKindId: res[0].eqpmKindId,
});
if (res.length > 0) {
this.selectValueList01 = await res.map(item => {
return {
text: item.eqpmKindNm,
value: item.eqpmKindId,
data: {
...item,
},
};
});
this.selectValueList01.unshift({
text: '전체',
value: '',
});
this.selectValue01 = this.selectValueList01[0].value;
} else {
this.selectValueList01 = [];
this.selectValue01 = null;
}
},
gridInit() {
const gridHeight = this.$refs.gridParent.offsetHeight - 70;
const myOptions = {
columnOptions: {
resizable: true,
},
};
this.setGridOption({
gridKey: this.gridName,
value: Object.assign(Utility.defaultGridOption(gridHeight), myOptions),
});
const _this = this;
const myColumns = [
{ header: '회사 ID', name: 'comId', hidden: true },
{
header: '설비 그룹 ID',
name: 'eqpmGrpId',
width: 150,
align: 'left',
},
{
header: '설비 그룹 명',
name: 'eqpmGrpNm',
minwidth: 210,
align: 'left',
},
{
header: '설비종류',
name: 'eqpmKindId',
minWidth: 175,
align: 'left',
formatter({ value }) {
let retVal = '';
const newValue = _this.pageData.eqpmKindIdList.filter(
item => item.eqpmKindId == value,
);
if (newValue.length > 0) {
retVal = newValue[0].eqpmKindNm;
}
return retVal;
},
},
{
header: '사용여부',
name: 'useFg',
width: 100,
align: 'center',
formatter({ value }) {
value = value === true ? '1' : '0';
const newValue = _this.pageData.useFgList.filter(
item => item.commCd == value,
);
return newValue[0].commCdNm;
},
},
{ header: '등록자NO', name: 'regUserNo', hidden: true },
{ header: '등록일시', name: 'regDttm', hidden: true },
{ header: '수정자NO', name: 'procUserNo', hidden: true },
{ header: '수정일시', name: 'procDttm', hidden: true },
];
this.setGridColumn({
gridKey: this.gridName,
value: myColumns,
});
this.loadGrid = true;
this.getRowGridData();
},
async search() {
this.loadGrid = false;
// if (this.loadFlag == false) {
// return;
// }
await this.getRowGridData();
await this.setPageData({
isFind: false,
});
},
async getRowGridData() {
const res = await this.postApiReturn({
apiKey: 'selectEqpmGrp',
resKey: 'eqpmGrpData',
sendParam: {
comId: this.userInfo.comCd,
useFg: this.pageData.useFg,
eqpmGrpNmLike: this.pageData.eqpmGrpNm,
eqpmKindId: this.selectValue01,
},
});
const newRes = res.map(item => {
const newObj = {
...item,
rowStat: null,
useFg: item.useFg === '1' ? true : false, // 화면 개발 편의를 위해 boolean 타입으로 교체, 저장시 "1", "0" 으로 바꿔 보내야 함
};
return newObj;
});
this.setGridData({
gridKey: this.gridName,
value: newRes,
});
this.loadGrid = true;
this.$nextTick(() => {
if (newRes.length > 0) {
this.$refs[this.gridName].focus({
//rowKey: 0,
rowKey:
this.pageData.rowGridSelectKey == '' ||
this.pageData.rowGridSelectKey == null
? 0
: this.pageData.rowGridSelectKey ==
this.$refs[this.gridName].getData().length - 1
? this.pageData.rowGridSelectKey
: 0,
setScroll: true,
});
}
});
},
async getRowData(data) {
this.setPageData({
rowGridSelectKey: data.rowKey,
rowGridSelectData: data,
});
},
gridEditingFinish(data) {
this.$refs[this.gridName].editingFinish(data);
},
async btnActions(action) {
let dataArr = [];
switch (action) {
case 'add':
var defaultRow = {
comId: '',
eqpmGrpId: '',
eqpmGrpNm: null,
eqpmKindId: this.pageData.eqpmKindIdList[0].eqpmKindId,
useFg: '1',
rowStat: null,
};
this.$refs[this.gridName].addRow(defaultRow);
break;
case 'remove':
this.$refs[this.gridName].removeRow();
break;
case 'save':
dataArr = this.$refs[this.gridName].save();
if (dataArr.length > 0) {
var validCheck = true;
dataArr.map(item => {
if (item.rowStat != 'D')
for (var i = 0; i < dataArr.length; i++) {
if (
dataArr[i].eqpmGrpNm == null ||
dataArr[i].eqpmGrpNm == ''
) {
validCheck = false;
alert('필수 입력값을 입력해주세요');
break;
} else {
validCheck = true;
break;
}
}
});
if (validCheck) {
const sendParam = {
datas: {
dsEqpmGrp: dataArr.map(item => ({
...item,
useFg: item.useFg == true ? '1' : '0',
})),
},
params: {},
};
var result = await this.postUpdateApi({
apiKey: 'saveEqpmGrp',
sendParam: sendParam,
});
if (result.data.dataset && result.data.dataset.deleteYn != '') {
alert(result.data.dataset.deleteYn);
} else {
this.$nextTick(() => {
this.setPageData({ isFind: true });
});
}
}
} else {
alert('저장할 내용이 없습니다.');
}
break;
default:
break;
}
},
},
};
const defaultData = {
/* 검색옵션 */
eqpmGrpNm: '',
useFg: '1',
useFgList: [],
eqpmKindIdList: [],
eqpmKindId: '',
// 선택된 그룹코드 상세 데이터
rowGridSelectKey: 0,
rowGridSelectData: null,
isFind: false, // true 경우 조회, 조회버튼도 이 값으로 연동 예정
/* data 세팅 */
// 로컬 gridName 값과 동일한 이름으로 세팅
rowGrid: {
data: [],
column: [], // myColumns,
option: {}, // myOptions
defaultRow: {
comId: '',
eqpmGrpId: '',
eqpmGrpNm: null,
eqpmKindId: '',
useFg: '1',
rowStat: null,
},
buttonAuth: {
add: true,
remove: true,
save: true,
excel: false,
},
},
};
const myDetail = [
{
type: 'InputText',
label: '설비 그룹 ID',
valueNm: 'eqpmGrpId',
disabled: true,
cols: 6,
class: 'py-2',
required: false,
placeholder: '시스템 자동입력',
},
{
type: 'InputText',
label: '설비 그룹 명',
valueNm: 'eqpmGrpNm',
disabled: false,
cols: 6,
class: 'py-2',
required: true,
},
{
type: 'CheckBox',
label: '사용 여부',
valueNm: 'useFg',
disabled: false,
cols: 6,
class: 'py-2',
value: { '1': true, '0': false },
required: true,
},
{
type: 'SelectBox',
label: '설비종류',
valueNm: 'eqpmKindId',
disabled: false,
cols: 6,
class: 'py-2',
list: 'eqpmKindIdList',
itemText: 'eqpmKindNm',
itemValue: 'eqpmKindId',
required: true,
},
{
type: 'InputText',
label: '등록자NO',
valueNm: 'regUserNo',
disabled: true,
cols: 6,
class: 'py-2',
placeholder: '시스템 자동입력',
},
{
type: 'InputText',
label: '등록일시',
valueNm: 'regDttm',
disabled: true,
cols: 6,
class: 'py-2',
placeholder: '시스템 자동입력',
},
{
type: 'InputText',
label: '수정자NO',
valueNm: 'procUserNo',
disabled: true,
cols: 6,
class: 'py-2',
placeholder: '시스템 자동입력',
},
{
type: 'InputText',
label: '수정일시',
valueNm: 'procDttm',
disabled: true,
cols: 6,
class: 'py-2',
placeholder: '시스템 자동입력',
},
];
</script>
<style lang="scss">
@import '@/assets/scss/common.scss';
</style>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,883 @@
<template>
<div ref="mainDiv" class="l-layout">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="3">
<component
:is="'SelectBox'"
ref="SelectBox1"
:propsValue="selectValue01"
:itemList="selectValueList01"
:label="'설비종류'"
@update:propsValue="selectValue01 = $event"
/>
</v-col>
<v-col :cols="3">
<component
:is="'SelectBox'"
ref="SelectBox2"
:propsValue="selectValue02"
:itemList="selectValueList02"
:label="'설비그룹'"
@update:propsValue="selectValue02 = $event"
/>
</v-col>
<v-col :cols="3">
<component
:is="'SelectBox'"
ref="SelectBox3"
:propsValue="selectValue03"
:itemList="selectValueList03"
:label="'가이드지표'"
@update:propsValue="selectValue03 = $event"
/>
</v-col>
<v-col :cols="3" class="text-right">
<BtnSearch @click="search" />
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents">
<v-col :cols="12" style="height: 100%">
<!-- <v-card class="py-5"> -->
<v-row style="height: 50%">
<v-col :cols="12" style="height: 100%">
<v-card class="pb-5">
<div class="d-flex align-center justify-space-between pa-4">
<v-card-title class="pa-0 custom-title-4"
>가이드 정보</v-card-title
>
</div>
<v-row
:cols="12"
class="d-flex align-center justify-space-between pa-3"
>
<!-- 가이드 설비그룹 라인 시작 -->
<v-col :cols="3">
<InputText
:parentPrgmId="myPrgmId"
:labelCols="4"
:textCols="8"
:label="'가이드 ID'"
:valueNm="'gdIdxId'"
:readonly="readonlyFg"
/>
</v-col>
<v-col :cols="3">
<InputText
:parentPrgmId="myPrgmId"
:labelCols="0"
:textCols="4"
:valueNm="'gdIdxNm'"
:readonly="readonlyFg"
/>
</v-col>
<v-col :cols="3">
<InputText
:parentPrgmId="myPrgmId"
:labelCols="4"
:textCols="8"
:label="'설비그룹'"
:valueNm="'eqpmGrpNm'"
:readonly="readonlyFg"
/>
</v-col>
<v-col :cols="3"> </v-col>
<!-- 가이드 설비그룹 라인 -->
<!-- 물리량 라인 시작 -->
<v-col :cols="3">
<InputText
:parentPrgmId="myPrgmId"
:labelCols="4"
:textCols="8"
:label="'물리량1'"
:valueNm="'pysclQtyCdNm1'"
:readonly="readonlyFg"
/>
</v-col>
<v-col :cols="3">
<InputText
:parentPrgmId="myPrgmId"
:labelCols="4"
:textCols="8"
:label="'물리량2'"
:valueNm="'pysclQtyCdNm2'"
:readonly="readonlyFg"
/>
</v-col>
<v-col :cols="3">
<InputText
:parentPrgmId="myPrgmId"
:labelCols="4"
:textCols="8"
:label="'물리량3'"
:valueNm="'pysclQtyCdNm3'"
:readonly="readonlyFg"
/>
</v-col>
<v-col :cols="3">
<InputText
:parentPrgmId="myPrgmId"
:labelCols="4"
:textCols="8"
:label="'물리량4'"
:valueNm="'pysclQtyCdNm4'"
:readonly="readonlyFg"
/>
</v-col>
<!-- 물리량 라인 -->
<!-- 카테고리 라인 시작 -->
<v-col :cols="3">
<InputText
:parentPrgmId="myPrgmId"
:labelCols="4"
:textCols="8"
:label="'카테고리1'"
:valueNm="'ctgr1'"
:readonly="readonlyFg"
/>
</v-col>
<v-col :cols="3">
<InputText
:parentPrgmId="myPrgmId"
:labelCols="4"
:textCols="8"
:label="'카테고리2'"
:valueNm="'ctgr2'"
:readonly="readonlyFg"
/>
</v-col>
<v-col :cols="3">
<InputText
:parentPrgmId="myPrgmId"
:labelCols="4"
:textCols="8"
:label="'주의기준값'"
:valueNm="'careStndVal'"
:readonly="readonlyFg"
/>
</v-col>
<v-col :cols="3">
<InputText
:parentPrgmId="myPrgmId"
:labelCols="4"
:textCols="8"
:label="'경고기준값'"
:valueNm="'warnStndVal'"
:readonly="readonlyFg"
/>
</v-col>
<!-- 카테고리 기준값 라인 -->
<!-- 알람메세지 라인 시작 -->
<v-col :cols="12">
<InputText
:parentPrgmId="myPrgmId"
:labelCols="1"
:textCols="11"
:label="'알람메세지'"
:valueNm="'alrmMsg'"
:readonly="readonlyFg"
/>
</v-col>
<!-- 알람메세지 라인 -->
<!-- 계산코드 라인 시작 -->
<v-col :cols="3">
<InputText
:parentPrgmId="myPrgmId"
:labelCols="4"
:textCols="8"
:label="'계산코드'"
:valueNm="'calcProc'"
:readonly="readonlyFg"
/>
</v-col>
<v-col :cols="3"> </v-col>
<v-col :cols="3"> </v-col>
<v-col :cols="3"> </v-col>
<!-- 계산코드 라인 -->
<!-- 계산설명 라인 시작 -->
<v-col :cols="12">
<InputText
:parentPrgmId="myPrgmId"
:labelCols="1"
:textCols="11"
:label="'계산설명'"
:valueNm="'calcDesc'"
:readonly="readonlyFg"
/>
</v-col>
<!-- 계산설명 라인 -->
</v-row>
</v-card>
</v-col>
</v-row>
<v-row style="height: 50%">
<v-col :cols="6" style="height: 100%">
<v-card class="pb-5">
<div class="d-flex align-center justify-space-between pa-4">
<v-card-title class="pa-0 custom-title-4 "
>설비상세 리스트</v-card-title
>
<Buttons
:parentPrgmId="myPrgmId"
:bindingData="gridName"
:btnActionsFnc="btnActions"
/>
</div>
<div class="h100 px-5" style="height:calc(100% - 70px)">
<div ref="gridParent" class="w100 h100">
<component
:ref="gridName"
:is="loadGrid ? 'Grid' : null"
:gridName="gridName"
:parentPrgmId="myPrgmId"
@getRowsData="getRowData"
/>
</div>
</div>
</v-card>
</v-col>
<v-col :cols="6" style="height: 100%">
<v-card class="pb-5">
<div class="d-flex align-center justify-space-between pa-4">
<v-card-title class="pa-0 custom-title-4"
>설비가이드 기준 정보</v-card-title
>
</div>
<v-row
:cols="12"
class="d-flex align-center justify-space-between pa-3"
>
<!-- 가이드 설비그룹 라인 시작 -->
<v-col :cols="12">
<component
:is="'Form'"
:parentPrgmId="myPrgmId"
:detailList="detailList"
@gridEditingFinish="gridEditingFinish"
/>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<!-- </v-card> -->
</v-col>
</v-row>
</div>
</template>
<script>
import { mapActions } from 'vuex';
import mixinGlobal from '@/mixin/global.js';
import { resize } from '@/mixin/resize.js';
import BtnSearch from '~/components/common/button/BtnSearch';
import Buttons from '~/components/common/button/Buttons';
import SelectBox from '@/components/common/select/SelectBox';
import InputText from '@/components/common/input/InputText';
import Form from '~/components/common/form/Form';
import Grid from '~/components/common/Grid';
import Utility from '~/plugins/utility';
let myTitle;
// const myPrgmId = "PRG0009";
let myPrgmId;
export default {
mixins: [mixinGlobal, resize],
async asyncData(context) {
const myState = context.store.state;
// console.log('asyncData',context.store)
// console.log(context.store.$router.currentRoute.fullPath);
myPrgmId = context.route.query.prgmId;
// context.store.commit('pageInit', { prgmId: myPrgmId, value: payload.defaultData });
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
BtnSearch,
Buttons,
InputText,
Form,
Grid,
SelectBox,
},
data() {
return {
myPrgmId: myPrgmId,
readonlyFg: true,
initedFlag: false,
gridName: 'rowGrid',
loadGrid: false,
detailList: myDetail,
selectValue01: null,
selectValueList01: [],
selectValue02: null,
selectValueList02: [],
selectValue03: null,
selectValueList03: [],
};
},
computed: {
// ...mapState({
// pageData: state => state.pageData[myPrgmId]
// }),
chkIsFind() {
// 조회 플래그
return this.pageData.isFind;
},
},
watch: {
chkIsFind(val) {
if (val) this.search();
},
async selectValue01(val) {
this.setPageData({ eqpmKindId: val });
if (this.initedFlag) await this.getEqpmGrp();
// this.setPageData({ isFind: true });
},
async selectValue02(val) {
this.setPageData({ eqpmGrpId: val });
if (this.initedFlag) await this.getEqpmGdIdx();
// this.setPageData({ isFind: true });
},
async selectValue03(val) {
this.setPageData({ eqpmGdIdx: val });
if (this.initedFlag) this.setPageData({ isFind: true });
},
},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
created() {
// 검침 Data 구분 목록 조회
},
async mounted() {
await this.init();
this.initedFlag = true;
},
beforeDestroy() {
this.chkOpenTabList({ key: 'destroy', prgmId: myPrgmId });
},
methods: {
...mapActions({
getCodeList: 'modules/search/getCodeList',
getBlocMstrList: 'modules/search/getBlocMstrList',
getAddInfoList: 'modules/search/getAddInfoList',
}),
async init() {
await this.getEqpmKind();
await this.getEqpmGrp();
await this.getEqpmGdIdx();
this.gridInit();
},
search() {
this.getGdIdxData();
this.getGridData();
this.setPageData({
isFind: false,
});
},
async getEqpmKind() {
let res = await this.postApiReturn({
apiKey: 'selectEqpmKindCodeList',
resKey: 'eqpmKindCodeLists',
sendParam: {},
});
if (res.length > 0) {
this.selectValueList01 = await res.map(item => {
return {
text: item.eqpmKindNm,
value: item.eqpmKindId,
};
});
this.selectValue01 = this.selectValueList01[0].value;
} else {
this.selectValueList01 = [];
this.selectValue01 = null;
}
this.setPageData({
eqpmKindList: this.selectValueList01,
eqpmKindId: this.selectValue01,
});
},
async getEqpmGrp() {
let res = await this.postApiReturn({
apiKey: 'selectEqpmGrpCodeList',
resKey: 'eqpmGrpCodeLists',
sendParam: { eqpmKindId: this.selectValue01 },
});
if (res.length > 0) {
this.selectValueList02 = await res.map(item => {
return {
text: item.eqpmGrpNm,
value: item.eqpmGrpId,
};
});
this.selectValue02 = this.selectValueList02[0].value;
} else {
this.selectValueList02 = [];
this.selectValue02 = null;
}
this.setPageData({
eqpmGrpList: this.selectValueList02,
eqpmGrpId: this.selectValue02,
});
},
async getEqpmGdIdx() {
let res = await this.postApiReturn({
apiKey: 'selectEqpmGdIdxCodeList',
resKey: 'eqpmGdIdxCodeLists',
sendParam: { eqpmGrpId: this.selectValue02 },
});
if (res.length > 0) {
this.selectValueList03 = await res.map(item => {
return {
text: item.gdIdxId + ': ' + item.gdIdxNm,
value: item.gdIdxId,
};
});
this.selectValue03 = this.selectValueList03[0].value;
} else {
this.selectValueList03 = [];
this.selectValue03 = null;
}
this.setPageData({
eqpmGdIdxList: this.selectValueList03,
eqpmGdIdx: this.selectValue03,
});
},
gridInit() {
const gridHeight = this.$refs.gridParent.offsetHeight - 30;
const myOptions = {
columnOptions: {
resizable: true,
},
};
this.setGridOption({
gridKey: this.gridName,
value: Object.assign(Utility.defaultGridOption(gridHeight), myOptions),
});
const _this = this;
const myColumns = [
// { header: '가이드ID', name: 'gdIdxId', align: 'center', hidden: true},
{ header: '설비', name: 'eqpmId', align: 'left' },
{
header: 'origin설비',
name: 'originEqpmId',
align: 'center',
hidden: true,
},
{ header: '설비명', name: 'eqpmNm', align: 'left' },
{ header: '주의기준', name: 'careStndVal', align: 'right' },
{ header: '심각기준', name: 'warnStndVal', align: 'right' },
];
this.setGridColumn({
gridKey: this.gridName,
value: myColumns,
});
this.loadGrid = true;
this.search();
},
async getGdIdxData() {
let res = [];
if (this.selectValue01 && this.selectValue02 && this.selectValue03) {
res = await this.postApiReturn({
apiKey: 'selectEqpmGdIdxData',
resKey: 'eqpmGdIdxData',
sendParam: {
eqpmGrpId: this.selectValue02,
gdIdxId: this.selectValue03,
},
});
} else {
if (this.initedFlag) {
alert('조회 조건을 확인해 주세요.');
}
}
this.setGuideInfo(res);
},
setGuideInfo(res) {
if (res.length == 0) {
this.setPageData({
gdIdxId: '',
gdIdxNm: '',
eqpmGrpNm: '',
upTotMeth: '',
unit: '',
pysclQtyCdNm1: '',
pysclQtyCdNm2: '',
pysclQtyCdNm3: '',
pysclQtyCdNm4: '',
pysclQtyId1: '',
pysclQtyId2: '',
pysclQtyId3: '',
pysclQtyId4: '',
ctgr1: '',
ctgr2: '',
careStndVal: '',
warnStndVal: '',
gdMeth: '',
alrmMsg: '',
calcProc: '',
calcDesc: '',
});
} else {
this.setPageData({
gdIdxId: res[0].gdIdxId,
gdIdxNm: res[0].gdIdxNm,
eqpmGrpNm: res[0].eqpmGrpNm,
upTotMeth: res[0].upTotMeth,
unit: res[0].unit,
pysclQtyCdNm1: res[0].pysclQtyCdNm1,
pysclQtyCdNm2: res[0].pysclQtyCdNm2,
pysclQtyCdNm3: res[0].pysclQtyCdNm3,
pysclQtyCdNm4: res[0].pysclQtyCdNm4,
pysclQtyId1: res[0].pysclQtyId1,
pysclQtyId2: res[0].pysclQtyId2,
pysclQtyId3: res[0].pysclQtyId3,
pysclQtyId4: res[0].pysclQtyId4,
ctgr1: res[0].ctgr1,
ctgr2: res[0].ctgr2,
careStndVal: res[0].careStndVal,
warnStndVal: res[0].warnStndVal,
gdMeth: res[0].geMeth,
alrmMsg: res[0].alrmMsg,
calcProc: res[0].calcProc,
calcDesc: res[0].calcDesc,
});
}
},
async getGridData() {
this.loadGrid = false;
let res = [];
if (this.selectValue01 && this.selectValue02 && this.selectValue03) {
res = await this.postApiReturn({
apiKey: 'selectEqpmGdDetl',
resKey: 'eqpmGdDetlData',
sendParam: {
gdIdxId: this.selectValue03,
},
});
}
// grid에서 eqpmId를 기억해서 popup에서 중복되는 값을 제거하는데 사용하기위해 저장 - 시작
let eqpmIdList = res.map(item => {
return item.eqpmId;
});
this.setPageData({ nowGridEqpmIdList: eqpmIdList });
// grid에서 eqpmId를 기억해서 popup에서 중복되는 값을 제거하는데 사용하기위해 저장 - 끝
const newRes = res.map(item => {
const newObj = {
...item,
rowStat: null,
};
return newObj;
});
this.setGridData({
gridKey: this.gridName,
value: newRes,
});
this.loadGrid = true;
this.$nextTick(() => {
if (newRes.length > 0) {
try {
this.$refs[this.gridName].focus({
//rowKey: 0,
rowKey:
this.pageData.rowGridSelectKey == '' ||
this.pageData.rowGridSelectKey == null
? 0
: this.pageData.rowGridSelectKey ==
this.$refs[this.gridName].getData().length - 1
? this.pageData.rowGridSelectKey
: 0,
columnNmae: 'eqpmId',
setScroll: true,
});
} catch (error) {}
} else {
this.detailDataInit();
}
});
},
async getRowData(data) {
// this.setReadObjAddInfo(data);
this.setPageData({
rowGridSelectKey: data.rowKey,
rowGridSelectData: data,
});
},
gridEditingFinish(data) {
this.$refs[this.gridName].editingFinish(data);
},
detailDataInit() {
this.setPageData({
rowGridSelectKey: null,
rowGridSelectData: [],
});
this.setGridData({
gridKey: 'rowGrid',
value: [],
});
},
async btnActions(action) {
let dataArr = [];
switch (action) {
case 'add':
if (this.pageData.eqpmGdIdx == null) {
alert(
'조회된 가이드 정보가 없습니다.\n설비그룹의 가이드 지표를 먼저 추가해 주세요',
);
break;
}
// console.log("this.pageData : ", this.pageData.readObjGrp);
const defaultRow = {
gdIdxId: this.pageData.eqpmGdIdx,
eqpmId: '',
eqpmNm: '',
careStndVal: null,
warnStndVal: null,
rowStat: 'I',
};
this.$refs[this.gridName].addRow(defaultRow);
break;
case 'remove':
//if (confirm('삭제 하시겠습니까?')) {
this.$refs[this.gridName].removeRow();
this.setPageData({ rowGridSelectData: null });
//}
break;
case 'save':
dataArr = this.$refs[this.gridName].save();
var validCheck = true;
let chkEqpmIdList = [];
if (dataArr.length > 0) {
dataArr.filter(item => {
// 미입력시 0으로 입력 되는 거 방지
if (item.careStndVal == '') {
item.careStndVal = null;
}
if (item.warnStndVal == '') {
item.warnStndVal = null;
}
if (item.eqpmId == '') {
item.eqpmId = null;
}
if (item.rowStat === 'I') {
if (
item.eqpmId == null ||
item.eqpmId == '' ||
((item.careStndVal == null || item.careStndVal == '') &&
(item.warnStndVal == null || item.warnStndVal == ''))
) {
alert('필수 입력값을 입력해주세요.');
validCheck = false;
}
if (chkEqpmIdList.includes(item.eqpmId)) {
alert('특정 가이드지표에 대한 설비는 중복될 수 없습니다.');
validCheck = false;
} else {
chkEqpmIdList.push(item.eqpmId);
}
} else if (item.rowStat === 'U') {
if (
item.eqpmId == null ||
item.eqpmId == '' ||
((item.careStndVal == null || item.careStndVal == '') &&
(item.warnStndVal == null || item.warnStndVal == ''))
) {
alert('필수 입력값을 입력해주세요.');
validCheck = false;
}
}
});
if (validCheck) {
const sendParam = {
datas: {
dsEqpmGdDetlInfo: dataArr.map(item => ({
...item,
})),
},
params: {},
};
await this.postUpdateApi({
apiKey: 'saveEqpmGdDetl',
sendParam: sendParam,
});
this.$nextTick(() => {
this.setPageData({ isFind: true });
});
}
} else {
alert('저장할 내용이 없습니다.');
}
break;
default:
break;
}
},
// click2(val){
// console.log('wpfkqfdfafasd', val);
// }
},
};
const defaultData = {
/* 검색옵션 */
eqpmKindList: [],
eqpmKindId: '',
eqpmGrpList: [],
eqpmGrpId: '',
eqpmGdIdxList: [],
eqpmGdIdx: '',
// 가이드 정보
gdIdxId: '',
gdIdxNm: '',
eqpmGrpNm: '',
upTotMeth: '',
unit: '',
pysclQtyCdNm1: '',
pysclQtyCdNm2: '',
pysclQtyCdNm3: '',
pysclQtyCdNm4: '',
pysclQtyId1: '',
pysclQtyId2: '',
pysclQtyId3: '',
pysclQtyId4: '',
ctgr1: '',
ctgr2: '',
careStndVal: '',
warnStndVal: '',
gdMeth: '',
alrmMsg: '',
calcProc: '',
calcDesc: '',
// Popup과 설비가이드 기준 정보(grid) databinding에 사용 될 변수
eqpmId: '',
eqpmNm: '',
nowGridEqpmIdList: [],
// 선택된 그룹코드 상세 데이터
rowGridSelectKey: 0,
rowGridSelectData: null,
isFind: false, // true 경우 조회, 조회버튼도 이 값으로 연동 예정
/* data 세팅 */
// 로컬 gridName 값과 동일한 이름으로 세팅
rowGrid: {
data: [],
column: [], // myColumns,
option: {}, // myOptions
defaultRow: {
gdIdxId: '',
eqpmId: '',
eqpmNm: '',
careStndVal: null,
warnStndVal: null,
rowStat: null,
},
buttonAuth: {
add: true,
remove: true,
save: true,
excel: false,
},
},
};
const myDetail = [
{
type: 'EqpmBaseInfoPop',
label: '설비',
valueNm: 'eqpmId',
valueNm2: 'eqpmNm',
cols: 6,
class: 'py-2',
required: true,
openMode: 'GRP',
},
{
type: 'InputText',
// label: '검침 대상 명',
valueNm: 'eqpmNm',
readonly: true,
// disabled: true,
cols: 6,
class: 'py-2',
required: true,
},
{
type: 'InputText',
label: '주의기준값',
valueNm: 'careStndVal',
disabled: false,
cols: 6,
class: 'py-2',
inputType: 'number',
required: true,
},
{
// 공백 처리
type: 'Label',
cols: 6,
class: 'py-2',
disabled: false,
},
{
type: 'InputText',
label: '경고기준값',
valueNm: 'warnStndVal',
disabled: false,
cols: 6,
class: 'py-2',
inputType: 'number',
required: true,
},
{
// 공백 처리
type: 'Label',
cols: 6,
class: 'py-2',
disabled: false,
},
{
// 공백 처리
type: 'Label',
cols: 12,
class: 'py-2',
label: "* '주의기준값' 또는 '경고기준값' 중 하나는 필수로 입력해 주세요.",
disabled: false,
},
];
</script>
<style lang="scss">
@import '@/assets/scss/common.scss';
</style>

View File

@ -0,0 +1,545 @@
<template>
<div class="l-layout">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="4">
<component
:is="'SelectBlocMstr'"
ref="SelectBlocMstr"
:parentPrgmId="myPrgmId"
:labelCols="4"
:textCols="7"
/>
</v-col>
<v-col :cols="4">
<DatePicker
:parentPrgmId="myPrgmId"
label="조회기간"
:labelCols="4"
:textCols="7"
/>
</v-col>
<v-col cols="4" class="d-flex justify-end align-center">
<BtnSearch @click="search" class="mr-1" />
<BtnExcelDownload :parentPrgmId="myPrgmId" :gridName="gridName" />
</v-col>
</v-row>
<v-row align="center" no-gutters>
<v-col :cols="4">
<component
:is="'FtnPlcMultiPop'"
:parentPrgmId="myPrgmId"
:labelCols="4"
:textCols="7"
/>
</v-col>
<v-col :cols="4" hidden>
<component
:is="'SelectEnergy'"
:parentPrgmId="myPrgmId"
:label="'에너지'"
/>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents">
<v-col style="height: 100%">
<v-card class="pa-5">
<div ref="chartParent" style="height: 40vh">
<component
class="w100 h100"
:is="loadChart ? 'Chart' : null"
:parentPrgmId="myPrgmId"
:chartName="'rowGridChart'"
ref="rowGridChart"
/>
</div>
<div style="height: 30px"></div>
<div ref="gridParent" class="pd-2" style="height: 20vh">
<component
:is="loadGrid ? 'Grid' : null"
:gridName="gridName"
:parentPrgmId="myPrgmId"
ref="rowGrid"
/>
</div>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex';
import mixinGlobal from '@/mixin/global.js';
import SelectBlocMstr from '@/components/common/select/SelectBlocMstrForPop';
import SelectEnergy from '@/components/common/select/SelectEnergyForPop';
import DatePicker from '~/components/common/Datepicker';
import FtnPlcMultiPop from '~/components/common/modal/FtnPlcMultiPop2';
import BtnSearch from '~/components/common/button/BtnSearch';
import BtnExcelDownload from '~/components/common/button/BtnExcelDownload';
import Utility from '~/plugins/utility';
import Grid from '~/components/common/Grid';
import Chart from '~/components/common/Chart';
let myTitle;
let myPrgmId;
export default {
mixins: [mixinGlobal],
async asyncData(context) {
const myState = context.store.state;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
SelectBlocMstr,
SelectEnergy,
DatePicker,
FtnPlcMultiPop,
BtnSearch,
BtnExcelDownload,
Utility,
Grid,
Chart,
},
data() {
return {
myPrgmId: myPrgmId,
gridName: 'rowGrid',
loadGrid: false,
loadChart: false,
};
},
computed: {
...mapState({
pageData: state => state.pageData[myPrgmId],
}),
chkIsFind() {
return this.pageData.isFind;
},
chkFacInfo() {
return this.pageData.facInfo;
},
},
watch: {
chkIsFind(val) {
if (val) this.search();
},
chkFacInfo() {
this.setPageData({ isFind: true });
},
},
beforeCreate() {
myPrgmId = this.$route.query.prgmId;
this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
mounted() {
this.init();
},
methods: {
...mapMutations({
setPageData: 'setPageData',
setGridData: 'setGridData',
setGridColumn: 'setGridColumn',
setGridOption: 'setGridOption',
setChartXAxisData: 'setChartXAxisData',
setChartYAxisData: 'setChartYAxisData',
setChartSeries: 'setChartSeries',
setChartOption: 'setChartOption',
}),
...mapActions({
postApi: 'modules/list/postApi',
postUpdateApi: 'modules/list/postUpdateApi',
postApiReturn: 'modules/list/postApiReturn',
chkOpenTabList: 'chkOpenTabList',
}),
async init() {
await this.makeGrid();
},
async search() {
await this.makeGrid();
},
async makeGrid() {
this.loadGrid = false;
const gridHeight = this.$refs.gridParent.offsetHeight - 36;
const myOptions = {
scrollX: false,
};
this.setGridOption({
gridKey: this.gridName,
value: Object.assign(Utility.defaultGridOption(gridHeight), myOptions),
});
var res = await this.makeResponse();
var columnList = [
{ header: '회사번호', name: 'comId', align: 'center', hidden: true },
{ header: 'no', name: 'no', align: 'center' },
{ header: '일자', name: 'totDttm', align: 'center' },
{
header: '경부하',
name: 'minQty',
align: 'right',
excelType: 'number',
excelFormatter: '2',
formatter: numberFormatter,
},
{
header: '경부하-비율(%)',
name: 'minRto',
align: 'right',
excelType: 'number',
excelFormatter: '2',
formatter: numberFormatter,
},
{
header: '중부하',
name: 'midQty',
align: 'right',
excelType: 'number',
excelFormatter: '2',
formatter: numberFormatter,
},
{
header: '중부하-비율(%)',
name: 'midRto',
align: 'right',
excelType: 'number',
excelFormatter: '2',
formatter: numberFormatter,
},
{
header: '최대부하',
name: 'maxQty',
align: 'right',
excelType: 'number',
excelFormatter: '2',
formatter: numberFormatter,
},
{
header: '최대부하-비율(%)',
name: 'maxRto',
align: 'right',
excelType: 'number',
excelFormatter: '2',
formatter: numberFormatter,
},
{
header: '총사용량',
name: 'totQty',
align: 'right',
excelType: 'number',
excelFormatter: '2',
formatter: numberFormatter,
},
{
header: '비용',
name: 'cost',
align: 'right',
excelType: 'number',
excelFormatter: '2',
formatter: numberFormatter,
},
];
this.setGridColumn({
gridKey: this.gridName,
value: columnList,
});
this.setGridData({
gridKey: this.gridName,
value: res,
});
await this.makeChart(res);
this.loadGrid = true;
this.setPageData({ isFind: false });
},
async makeChart(data) {
this.$store.state.pageData[this.myPrgmId].rowGridChart.series = [];
this.loadChart = false;
// if(!data.length){
// return;
// }
var xAxisData = [];
var seriesData = [];
var xAxisData = data.map(el => el.totDttm.substring(5, 10));
seriesData.push({
name: '경부하',
type: 'bar',
stack: 'stack1',
data: data.map(el => el.minQty),
yAxisIndex: 0,
});
seriesData.push({
name: '중부하',
type: 'bar',
stack: 'stack1',
data: data.map(el => el.midQty),
yAxisIndex: 0,
});
seriesData.push({
name: '최대부하',
type: 'bar',
stack: 'stack1',
data: data.map(el => el.maxQty),
yAxisIndex: 0,
});
seriesData.push({
name: '비용',
type: 'line',
data: data.map(el => el.cost),
yAxisIndex: 1,
});
var chartOption = {
grid: {
top: '3%',
},
yAxis: [
{
type: 'value',
name: 'kwh',
position: 'left',
axisLine: {
show: true,
},
},
{
type: 'value',
name: '원',
position: 'right',
axisLine: {
show: true,
},
},
],
xAxis: {
type: 'category',
data: xAxisData,
},
series: seriesData,
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
},
},
};
this.setChartOption({ chartKey: 'rowGridChart', value: chartOption });
this.setChartYAxisData({
chartKey: 'rowGridChart',
value: [
{
type: 'value',
name: 'kwh',
position: 'left',
axisLine: {
show: false,
},
nameLocation: 'middle',
nameGap: 50,
splitLine: {
show: true,
},
},
{
type: 'value',
name: '원',
position: 'right',
axisLine: {
show: false,
},
nameLocation: 'middle',
nameGap: 70,
splitLine: {
show: true,
},
},
],
});
this.loadChart = true;
},
makeSendParam() {
var param = {
fromDt:
this.pageData.fromDt.substring(0, 4) +
'-' +
this.pageData.fromDt.substring(4, 6) +
'-' +
this.pageData.fromDt.substring(6, 8),
toDt:
this.pageData.toDt.substring(0, 4) +
'-' +
this.pageData.toDt.substring(4, 6) +
'-' +
this.pageData.toDt.substring(6, 8),
eccId: this.pageData.facInfo.eccId,
};
return param;
},
async makeResponse() {
var resultColumnList = [
'comId',
'cost',
'maxQty',
'maxRto',
'midQty',
'midRto',
'minQty',
'minRto',
'totDttm',
'totQty',
];
var res = await this.postApiReturn({
apiKey: 'selectLoadElecPowCmpr',
resKey: 'loadElecPowCmpr',
sendParam: this.makeSendParam(),
});
if (!res.length || res.length < 1) {
return res;
}
for (var i = 0; i < res.length; i++) {
res[i]['totDttm'] = res[i]['totDttm'].replaceAll('-', '/');
}
var fromDt = new Date(
this.pageData.fromDt.substring(0, 4),
this.pageData.fromDt.substring(4, 6),
this.pageData.fromDt.substring(6, 8),
);
var toDt = new Date(
this.pageData.toDt.substring(0, 4),
this.pageData.toDt.substring(4, 6),
this.pageData.toDt.substring(6, 8),
);
var diffDay = (toDt.getTime() - fromDt.getTime()) / (1000 * 60 * 60 * 24);
for (var i = 0; i < diffDay + 1; i++) {
var tempDt = new Date(
this.pageData.fromDt.substring(0, 4),
this.pageData.fromDt.substring(4, 6) - 1,
this.pageData.fromDt.substring(6, 8),
);
tempDt.setDate(tempDt.getDate() + i);
tempDt =
tempDt.getFullYear() +
'/' +
(tempDt.getMonth() + 1).toString().padStart(2, '0') +
'/' +
tempDt
.getDate()
.toString()
.padStart(2, '0');
if (res[i] == undefined || res[i]['totDttm'] != tempDt) {
res.splice(i, 0, {
totDttm: tempDt,
comId: '',
cost: 0,
totQty: 0,
maxQty: 0,
maxRto: 0,
midQty: 0,
midRto: 0,
minQty: 0,
minRto: 0,
});
}
}
for (var i = 0; i < res.length; i++) {
for (var j = 0; j < resultColumnList.length; j++) {
res[i]['no'] = i + 1;
if (res[i][resultColumnList[j]] === undefined) {
res[i][resultColumnList[j]] = 0;
}
}
}
return res;
},
},
};
var dt1 = new Date();
var dt2 = new Date(dt1.setMonth(dt1.getMonth() - 1));
const defaultData = {
isFind: false,
blocId: '',
blocMstrList: [],
energyCd: '',
energyList: [],
cmCycle: 'CYC_DAY',
cmCycleList: [
{ idx: 0, text: '연', value: 'CYC_YEAR' },
{ idx: 1, text: '월', value: 'CYC_MONTH' },
{ idx: 2, text: '일', value: 'CYC_DAY' },
{ idx: 3, text: '시간', value: 'CYC_HOUR' },
],
defaultRange: {
CYC_YEAR: 10,
CYC_MONTH: 12,
CYC_DAY: 30,
CYC_HOUR: 0,
},
fromDt: Utility.setFormatDate(dt2, 'YYYYMMDD'),
toDt: Utility.setFormatDate(new Date(), 'YYYYMMDD'),
isMulti: false,
modalData: {},
facInfo: {},
rowGrid: {
data: [],
option: {},
column: [],
},
rowGridChart: Utility.defaultChartOption(true),
xlsFileInfo: {
rowGrid: {
fileName: null,
sheetName: null,
},
},
};
function numberFormatter({ value }) {
return Utility.setFormatIntDecimal(value, 2);
}
</script>
<style lang="scss">
@import '@/assets/scss/common.scss';
</style>

View File

@ -0,0 +1,591 @@
<template>
<div class="l-layout">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="4">
<component :is="'SelectSysDiv'" :parentPrgmId="myPrgmId" />
</v-col>
<v-col :cols="4">
<component :is="'SelectUseFg'" :parentPrgmId="myPrgmId" />
</v-col>
<v-col :cols="4" class="text-right">
<BtnSearch @click="search" />
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents" :eager="true">
<v-col :cols="5" class="h100">
<v-card class="pb-5 h100">
<v-card-title>메뉴 리스트</v-card-title>
<div class="px-5 h100">
<div ref="treeGridParent" class="w100 h100">
<component
ref="myGrid"
:is="loadTree ? 'Grid' : null"
:gridName="gridNameTree"
:parentPrgmId="myPrgmId"
@getRowsData="getRowData"
/>
</div>
</div>
</v-card>
</v-col>
<v-col :cols="7" class="h100">
<v-card class="py-5 h100">
<v-card-title class="d-flex justify-between">
<span class="tit ft-size_20 ft-weight_600">메뉴 상세</span>
<div>
<v-btn
class="v-btn-radius__20 v-btn-bg__white-blue mr-1"
@click="addRow"
>
<v-icon>mdi-plus</v-icon>
<span>추가</span>
</v-btn>
<v-btn
class="v-btn-radius__20 v-btn-bg__white-blue mr-1"
@click="removeRow"
>
<v-icon>mdi-delete-outline</v-icon>
<span>삭제</span>
</v-btn>
<v-btn class="v-btn-radius__20 v-btn-bg__blue mr-1" @click="save">
<v-icon>mdi-content-save</v-icon>
<span>저장</span>
</v-btn>
<BtnExcelDownload
style="vertical-align: middle;"
class="d-inline-flex"
:parentPrgmId="myPrgmId"
:gridName="gridNameTree"
/>
</div>
</v-card-title>
<v-card-actions>
<v-row>
<v-col :cols="12" class="py-2">
<InputText
:parentPrgmId="myPrgmId"
label="상위메뉴코드"
valueNm="modifyupMenuId"
/>
</v-col>
<v-col :cols="12" class="py-2">
<InputText
:parentPrgmId="myPrgmId"
label="메뉴코드"
valueNm="menuId"
:disabled="true"
/>
</v-col>
<v-col :cols="12" class="py-2">
<InputText
:parentPrgmId="myPrgmId"
label="메뉴명"
valueNm="modifyMenuNm"
/>
</v-col>
<v-col :cols="12" class="py-2">
<InputText
:parentPrgmId="myPrgmId"
label="프로그램ID"
valueNm="modifyprgmId"
/>
</v-col>
<v-col :cols="12" class="py-2">
<component
:is="'SelectSysDiv'"
diffModel="modifySysDivCd"
:parentPrgmId="myPrgmId"
/>
</v-col>
<v-col :cols="12" class="py-2">
<component
:is="'SelectUseFg'"
diffModel="modifyUseFg"
:parentPrgmId="myPrgmId"
/>
</v-col>
<v-col :cols="12" class="py-2">
<InputText
:parentPrgmId="myPrgmId"
label="정렬순서"
valueNm="modifysortSeq"
/>
</v-col>
<v-col :cols="12" class="py-2">
<InputText
:parentPrgmId="myPrgmId"
label="등록지NO"
valueNm="regUserNo"
:disabled="true"
/>
</v-col>
<v-col :cols="12" class="py-2">
<InputText
:parentPrgmId="myPrgmId"
label="등록일시"
valueNm="regDttm"
:disabled="true"
/>
</v-col>
<v-col :cols="12" class="py-2">
<InputText
:parentPrgmId="myPrgmId"
label="수정지NO"
valueNm="procUserNo"
:disabled="true"
/>
</v-col>
<v-col :cols="12" class="py-2">
<InputText
:parentPrgmId="myPrgmId"
label="수정일시"
valueNm="procDttm"
:disabled="true"
/>
</v-col>
</v-row>
</v-card-actions>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex';
import mixinGlobal from '@/mixin/global.js';
import { resize } from '@/mixin/resize.js';
import BtnSearch from '~/components/common/button/BtnSearch';
import SelectSysDiv from '@/components/common/select/SelectSysDiv';
import SelectUseFg from '@/components/common/select/SelectUseFg';
import InputText from '@/components/common/input/InputText';
import Grid from '~/components/common/Grid';
import BtnExcelDownload from '~/components/common/button/BtnExcelDownload';
import Utility from '~/plugins/utility';
let myTitle;
let myPrgmId;
export default {
mixins: [mixinGlobal, resize],
asyncData(context) {
const myState = context.store.state;
context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
BtnSearch,
SelectSysDiv,
SelectUseFg,
InputText,
Grid,
BtnExcelDownload,
},
data() {
return {
myPrgmId: myPrgmId,
gridNameTree: 'treeGrid',
loadTree: false,
myRowKey: 0,
};
},
computed: {
...mapState({
pageData: state => state.pageData[myPrgmId],
}),
chkIsFind() {
// 조회 플래그
return this.pageData.isFind;
},
chkSysDivCd() {
// 시스템구분 선택 감지
return this.pageData.sysDivCd;
},
chkUseFg() {
// 사용여부 선택 감지
return this.pageData.useFg;
},
selectedCommCdData() {
return this.pageData.selectedCommCdData;
},
modifyupMenuId() {
return this.pageData.modifyupMenuId;
},
modifyMenuNm() {
return this.pageData.modifyMenuNm;
},
modifyprgmId() {
return this.pageData.modifyprgmId;
},
modifysortSeq() {
return this.pageData.modifysortSeq;
},
modifySysDivCd() {
return this.pageData.modifySysDivCd;
},
modifyUseFg() {
return this.pageData.modifyUseFg;
},
},
watch: {
chkIsFind(val) {
if (val) this.search();
},
chkSysDivCd() {
this.setPageData({ isFind: true });
},
chkUseFg() {
this.setPageData({ isFind: true });
},
modifyupMenuId(val) {
const isSameData = this.compareData('upMenuId', val);
if (!isSameData) {
const dt = {
name: 'upMenuId',
value: val,
};
this.$refs.myGrid.externalDataEdit(dt);
}
},
modifyMenuNm(val) {
const isSameData = this.compareData('MenuNm', val);
if (!isSameData) {
const dt = {
name: 'MenuNm',
value: val,
};
this.$refs.myGrid.externalDataEdit(dt);
}
},
modifyprgmId(val) {
const isSameData = this.compareData('prgmId', val);
if (!isSameData) {
const dt = {
name: 'prgmId',
value: val,
};
this.$refs.myGrid.externalDataEdit(dt);
}
},
modifysortSeq(val) {
const isSameData = this.compareData('sortSeq', val);
if (!isSameData) {
const dt = {
name: 'sortSeq',
value: val,
};
this.$refs.myGrid.externalDataEdit(dt);
}
},
modifySysDivCd(val) {
const isSameData = this.compareData('sysDivCd', val);
if (!isSameData) {
const dt = {
name: 'sysDivCd',
value: val,
};
this.$refs.myGrid.externalDataEdit(dt);
}
},
modifyUseFg(val) {
const isSameData = this.compareData('useFg', val);
if (!isSameData) {
const dt = {
name: 'useFg',
value: val,
};
this.$refs.myGrid.externalDataEdit(dt);
}
},
},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
mounted() {
this.init();
},
beforeDestroy() {
this.chkOpenTabList({ key: 'destroy', prgmId: myPrgmId });
},
methods: {
...mapMutations({
setPageData: 'setPageData',
setGridData: 'setGridData',
setGridColumn: 'setGridColumn',
setGridOption: 'setGridOption',
}),
...mapActions({
postApi: 'modules/list/postApi',
postUpdateApi: 'modules/list/postUpdateApi',
postApiReturn: 'modules/list/postApiReturn',
setTree: 'modules/list/setTree',
chkOpenTabList: 'chkOpenTabList',
}),
init() {
this.layoutInit();
this.gridInit();
},
layoutInit() {
const searchFilterHeight = this.$refs.searchFilter.offsetHeight;
this.$refs.contents.style.height = `calc(100% - ${searchFilterHeight}px)`;
},
gridInit() {
const treeGridHeight = this.$refs.treeGridParent.offsetHeight - 36;
const myOptionsTree = {
rowHeaders: ['checkbox'],
treeColumnOptions: {
name: 'menuNm',
},
scrollX: false,
};
this.setGridOption({
gridKey: this.gridNameTree,
// value: myOptionsTree
value: Object.assign(
Utility.defaultGridOption(treeGridHeight),
myOptionsTree,
),
});
this.setGridColumn({
gridKey: this.gridNameTree,
value: [
{
header: '메뉴명',
name: 'menuNm',
align: 'center',
},
{
header: '메뉴ID',
name: 'menuId',
hidden: true,
},
{
header: '상위메뉴ID',
name: 'upMenuId',
hidden: true,
},
{
header: '정렬순서',
name: 'sortSeq',
hidden: true,
},
{
header: '사용여부',
name: 'useFg',
hidden: true,
},
{
header: '회사코드',
name: 'comId',
hidden: true,
},
{
header: '시스템구분',
name: 'sysDivCd',
hidden: true,
},
{
header: '등록자NO',
name: 'regUserNo',
hidden: true,
},
{
header: '등록일시',
name: 'regDttm',
hidden: true,
},
{
header: '수정자NO',
name: 'procUserNo',
hidden: true,
},
{
header: '수정일시',
name: 'procDttm',
hidden: true,
},
],
});
this.getTreeData();
},
//메뉴 리스트
async getTreeData() {
const res = await this.postApiReturn({
apiKey: 'selectMenu',
resKey: 'menuData',
sendParm: {
comId: this.pageData.comId,
sysDivCd: this.pageData.sysDivCd,
useFg: this.pageData.useFg,
},
});
res[0].upMenuId = 'ROOT';
// res[0].parentId= 'ROOT';
const setTreeData = await this.setTree({
treeKey: 'MENU_ID',
value: res,
});
this.loadTree = true;
await this.setGridData({
gridKey: this.gridNameTree,
value: setTreeData.ROOT,
});
// this.$refs.myGrid.focus({
// rowKey:this.myRowKey,
// columnName: "menuNm",
// setScroll: true
// });
this.$nextTick(() => {
if (setTreeData.length > 0) {
this.$refs['myGrid'].focus({
rowKey: this.myRowKey,
columnName: 'menuNm',
setScroll: true,
});
}
});
this.setPageData({ isFind: false });
},
async getRowData(data) {
this.myRowKey = data.rowKey;
this.setPageData({
selectedCommCdData: data,
modifyupMenuId: data.menuId,
modifyMenuNm: data.menuNm,
modifyprgmId: data.prgmId,
modifysortSeq: data.sortSeq,
modifySysDivCd: data.sysDivCd,
modifyUseFg: data.useFg,
procDttm: data.procDttm,
procUserNo: data.procUserNo,
regUserNo: data.regUserNo,
regDttm: data.regDttm,
menuId: data.menuId,
});
},
async search() {
await this.getTreeData();
await this.setPageData({
isFind: false,
});
},
compareData(type, newDt) {
if (this.selectedCommCdData[type] == newDt) {
return true;
} else {
return false;
}
},
addRow() {
this.$refs.myGrid.gridInstance.invoke(
'appendRow',
{
menuId: '',
menuNm: '',
prgmId: '',
sortSeq: '',
sysDivCd: '',
useFg: '',
procDttm: '',
procUserNo: '',
regUserNo: '',
regDttm: '',
},
{ focus: true },
);
// this.$refs.myGrid.addRow();
// var rowData = {menuId: "", menuNm : "", prgmId:"", sortSeq:"", sysDivCd:"", useFg:"",procDttm:"",procUserNo:"",regUserNo:"",regDttm:""}
// this.$refs.myGrid.appendRow(rowData, {
// at:1,
// extendPrevRowSpan:true,
// focus:true
// });
},
removeRow() {
this.$refs.myGrid.removeRow();
},
async save() {
const dataArr = this.$refs.myGrid.save();
const sendParam = {
datas: { dsMenu: dataArr },
params: {},
};
await this.postUpdateApi({
apiKey: 'saveMenu',
sendParm: sendParam,
});
await this.search();
},
},
};
const defaultData = {
/* 검색옵션 */
comId: this.comId,
sysDivCd: '',
sysDivCdList: [],
useFg: '',
useFgList: [],
menuId: '',
modifySysDivCd: 'COMM',
modifyUseFg: '1',
regUserNo: '',
regDttm: '',
procUserNo: '',
procDttm: '',
modifyupMenuId: '',
modifyMenuNm: '',
modifyprgmId: '',
modifysortSeq: '',
isFind: false, // true 경우 조회, 조회버튼도 이 값으로 연동 예정
/* data 세팅 */
treeGrid: {
data: [],
column: [],
option: {},
defaultRow: {
menuId: '',
menuNm: '',
upMenuId: '',
prgmId: '',
sortSeq: '',
useFg: '',
comId: '',
sysDivCd: '',
regUserNo: '',
regDttm: '',
procUserNo: '',
procDttm: '',
rowStat: null,
},
},
};
</script>
<style lang="scss">
@import '@/assets/scss/common.scss';
</style>

View File

@ -0,0 +1,817 @@
<template>
<div class="l-layout">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row class="search-box" align="center" no-gutters>
<v-col :cols="1">
<label for="" class="search-box-label">
<v-icon x-small color="primary" class="mr-1"
>mdi-record-circle</v-icon
>
기간
</label>
</v-col>
<v-col :cols="2">
<v-text-field
id="startpicker"
ref="startpicker"
v-model="targetDateTimeObject.value"
:class="'v-input__custom'"
readonly
outlined
:hide-details="true"
>
<template #append>
<v-icon size="20">$icoCalendar</v-icon>
</template>
<template #append-outer>
<div
ref="startpicker-container"
id="startpicker-container"
></div>
</template>
</v-text-field>
</v-col>
<v-spacer></v-spacer>
<v-col :cols="2" class="d-flex justify-end align-center">
<BtnSearch @click="search" class="mr-1" />
<div id="btnExeclDownload">
<v-btn :ripple="false" @click="downloadExcelFile">액셀</v-btn>
</div>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents">
<v-col :cols="12" style="height: 100%">
<v-card class="pb-5">
<v-row class="pa-5">
<v-col :cols="12">
<v-icon x-small color="primary" class="mr-1"
>mdi-record-circle</v-icon
>
<span class="custom-title-4">권역 종합</span>
</v-col>
</v-row>
<v-row>
<v-col :cols="12">
<div
ref="gridParent01"
class="px-5"
:style="{ height: 'calc(25vh - 90px)' }"
>
<component
:is="loadGrid01 ? 'Grid' : null"
:gridName="gridName01"
:parentPrgmId="myPrgmId"
ref="rowGrid01"
/>
</div>
</v-col>
</v-row>
<v-row class="pa-5">
<v-col :cols="12">
<v-icon x-small color="primary" class="mr-1"
>mdi-record-circle</v-icon
>
<span class="custom-title-4">에너지원별 종합</span>
</v-col>
</v-row>
<v-row>
<v-col :cols="12">
<div
ref="gridParent02"
class="px-5"
:style="{ height: 'calc(25vh - 90px)' }"
>
<component
:is="loadGrid02 ? 'Grid' : null"
:gridName="gridName02"
:parentPrgmId="myPrgmId"
ref="rowGrid02"
/>
</div>
</v-col>
</v-row>
<v-row class="pa-5">
<v-col :cols="12">
<v-icon x-small color="primary" class="mr-1"
>mdi-record-circle</v-icon
>
<span class="custom-title-4">조직별 종합</span>
</v-col>
</v-row>
<v-row>
<v-col :cols="12">
<div
ref="gridParent03"
class="px-5"
:style="{ height: 'calc(25vh - 90px)' }"
>
<component
:is="loadGrid03 ? 'Grid' : null"
:gridName="gridName03"
:parentPrgmId="myPrgmId"
ref="rowGrid03"
/>
</div>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex';
import mixinGlobal from '@/mixin/global.js';
import SelectDate from '~/components/common/select/SelectDate';
import SelectDateVc from '~/components/common/select/SelectDateVc';
import FtnPlcMultiPop from '~/components/common/modal/FtnPlcMultiPop';
import TuiDatepicker from 'tui-date-picker';
import BtnSearch from '~/components/common/button/BtnSearch';
import BtnExcelDownload from '~/components/common/button/BtnExcelDownload';
import Utility from '~/plugins/utility';
import Grid from '~/components/common/Grid';
import XLSX from 'xlsx';
let myTitle;
let myPrgmId;
export default {
mixins: [mixinGlobal],
async asyncData(context) {
const myState = context.store.state;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
SelectDate,
SelectDateVc,
FtnPlcMultiPop,
BtnSearch,
BtnExcelDownload,
Utility,
Grid,
},
data() {
return {
myPrgmId: myPrgmId,
targetDateTimeObject: {
value: new Date().toISOString().substr(0, 7),
},
startDatepickerInstance: null,
loadGrid01: false,
loadGrid02: false,
loadGrid03: false,
gridName01: 'rowGrid01',
gridName02: 'rowGrid02',
gridName03: 'rowGrid03',
};
},
computed: {
...mapState({
pageData: state => state.pageData[myPrgmId],
}),
chkIsFind() {
return this.pageData.isFind;
},
},
watch: {
chkIsFind(val) {
if (val) this.search();
},
'targetDateTimeObject.value': function() {
this.setPageData({ isFind: true });
},
},
beforeCreate() {
myPrgmId = this.$route.query.prgmId;
this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
mounted() {
this.init();
},
methods: {
...mapMutations({
setPageData: 'setPageData',
setGridData: 'setGridData',
setGridColumn: 'setGridColumn',
setGridOption: 'setGridOption',
}),
...mapActions({
postApi: 'modules/list/postApi',
postUpdateApi: 'modules/list/postUpdateApi',
postApiReturn: 'modules/list/postApiReturn',
chkOpenTabList: 'chkOpenTabList',
}),
async init() {
await this.gridInit();
this.tuiCalendarInit();
},
tuiCalendarInit() {
const startContainer = document.getElementById('startpicker-container');
const startTarget = document.getElementById('startpicker');
this.startDatepickerInstance = new TuiDatepicker(startContainer, {
date: new Date(),
language: 'ko',
type: 'month',
input: {
element: startTarget,
format: 'YYYY-MM', //"YYYY-MM-DD" //this.format
},
timePicker: false,
});
this.startDatepickerInstance.on('change', () => this.getStartDt());
},
getStartDt() {
const dt = this.startDatepickerInstance.getDate();
this.targetDateTimeObject.value = String(dt.toISOString()).substr(0, 7);
},
async gridInit() {
const gridHeight01 = this.$refs.gridParent01.offsetHeight - 36;
const gridHeight02 = this.$refs.gridParent02.offsetHeight - 36;
const gridHeight03 = this.$refs.gridParent03.offsetHeight - 36;
const myOptions = {
scrollX: false,
};
this.setGridOption({
gridKey: this.gridName01,
value: Object.assign(
Utility.defaultGridOption(gridHeight01),
myOptions,
),
});
this.setGridOption({
gridKey: this.gridName02,
value: Object.assign(
Utility.defaultGridOption(gridHeight02),
myOptions,
),
});
this.setGridOption({
gridKey: this.gridName03,
value: Object.assign(
Utility.defaultGridOption(gridHeight03),
myOptions,
),
});
var params = this.makeParams();
await this.getGridData01(params);
await this.getGridData02(params);
await this.getGridData03(params);
},
makeParams() {
var params = {};
params['year'] = this.targetDateTimeObject.value.substr(0, 4);
params['month'] = this.targetDateTimeObject.value.substr(5, 2);
params['lang'] = 'ko_KR';
params['blocId'] = this.userInfo.blocId;
params['blocPlcCd'] = 'PLC00002';
return params;
},
async getGridData01(params) {
var res = null;
var columnList = [
{ header: '에너지', name: 'mttNm', align: 'left' },
{
header: '계획 사용량',
name: 'planQty',
align: 'right',
formatter: numberFormatter,
},
{
header: '실적 사용량',
name: 'useQty',
align: 'right',
formatter: numberFormatter,
},
{
header: '전년동월대비 증감률',
name: 'preYyQtyRate',
align: 'right',
formatter: numberFormatter,
},
{
header: '전월대비 증감률',
name: 'preMmQtyRate',
align: 'right',
formatter: numberFormatter,
},
{
header: '비용(원)',
name: 'useCost',
align: 'right',
formatter: numberFormatter,
},
{
header: '전년동월대비 비용 증감률',
name: 'preYyCostRate',
align: 'right',
formatter: numberFormatter,
},
{
header: '전월대비 비용 증감률',
name: 'preMmCostRate',
align: 'right',
formatter: numberFormatter,
},
{
header: 'TOE',
name: 'toe',
align: 'right',
formatter: numberFormatter,
},
{
header: 'tCO2',
name: 'tco2',
align: 'right',
formatter: numberFormatter,
},
];
this.loadGrid01 = false;
res = await this.postApiReturn({
apiKey: 'selectMonthReportFactory',
resKey: 'monthReportFactory',
sendParam: params,
});
this.setGridColumn({
gridKey: this.gridName01,
value: columnList,
});
this.setGridData({
gridKey: this.gridName01,
value: res,
});
this.loadGrid01 = true;
this.setPageData({ isFind: false });
},
async getGridData02(params) {
var res = null;
var columnList = [
{ header: '에너지', name: 'mttNm', align: 'left' },
{ header: '상위공정', name: 'eccNm', align: 'left' },
{
header: '계획 사용량',
name: 'planQty',
align: 'right',
formatter: numberFormatter,
},
{
header: '실적 사용량',
name: 'useQty',
align: 'right',
formatter: numberFormatter,
},
{
header: '전년동월대비 증감률',
name: 'preYyQtyRate',
align: 'right',
formatter: numberFormatter,
},
{
header: '전월대비 증감률',
name: 'preMmQtyRate',
align: 'right',
formatter: numberFormatter,
},
{
header: '비용(원)',
name: 'useCost',
align: 'right',
formatter: numberFormatter,
},
{
header: '전년동월대비 비용 증감률',
name: 'preYyCostRate',
align: 'right',
formatter: numberFormatter,
},
{
header: '전월대비 비용 증감률',
name: 'preMmCostRate',
align: 'right',
formatter: numberFormatter,
},
{
header: 'TOE',
name: 'toe',
align: 'right',
formatter: numberFormatter,
},
{
header: 'tCO2',
name: 'tco2',
align: 'right',
formatter: numberFormatter,
},
];
this.loadGrid02 = false;
res = await this.postApiReturn({
apiKey: 'selectMonthReportEnergy',
resKey: 'monthReportEnergy',
sendParam: params,
});
setRowSpanAttribute(res, 'mttNm');
this.setGridColumn({
gridKey: this.gridName02,
value: columnList,
});
this.setGridData({
gridKey: this.gridName02,
value: res,
});
this.loadGrid02 = true;
this.setPageData({ isFind: false });
},
async getGridData03(params) {
var res = null;
var columnList = [
{ header: '상위공정', name: 'upPlcNm', align: 'left' },
{ header: '공정', name: 'eccNm', align: 'left' },
{ header: '에너지', name: 'mttNm', align: 'left' },
{
header: '계획 사용량',
name: 'planQty',
align: 'right',
formatter: numberFormatter,
},
{
header: '실적 사용량',
name: 'useQty',
align: 'right',
formatter: numberFormatter,
},
{
header: '전년동월대비 증감률',
name: 'preYyQtyRate',
align: 'right',
formatter: numberFormatter,
},
{
header: '전월대비 증감률',
name: 'preMmQtyRate',
align: 'right',
formatter: numberFormatter,
},
{
header: '비용(원)',
name: 'useCost',
align: 'right',
formatter: numberFormatter,
},
{
header: '전년동월대비 비용 증감률',
name: 'preYyCostRate',
align: 'right',
formatter: numberFormatter,
},
{
header: '전월대비 비용 증감률',
name: 'preMmCostRate',
align: 'right',
formatter: numberFormatter,
},
{
header: 'TOE',
name: 'toe',
align: 'right',
formatter: numberFormatter,
},
{
header: 'tCO2',
name: 'tco2',
align: 'right',
formatter: numberFormatter,
},
];
this.loadGrid03 = false;
res = await this.postApiReturn({
apiKey: 'selectMonthReportDept',
resKey: 'monthReportDept',
sendParam: params,
});
setRowSpanAttribute(res, 'upPlcNm');
// setRowSpanAttribute(res, 'mttNm', ['upPlcNm', 'mttNm']);
this.setGridColumn({
gridKey: this.gridName03,
value: columnList,
});
this.setGridData({
gridKey: this.gridName03,
value: res,
});
this.loadGrid03 = true;
this.setPageData({ isFind: false });
},
async search() {
var params = this.makeParams();
await this.getGridData01(params);
await this.getGridData02(params);
await this.getGridData03(params);
},
downloadExcelFile() {
this.makeExcelFile('rowGrid01', '권역 종합.xlsx');
this.makeExcelFile('rowGrid02', '에너지원별 종합.xlsx');
this.makeExcelFile('rowGrid03', '조직별 종합.xlsx');
},
makeExcelFile(gridName, fileName) {
var xlsData = this.makeExcelData(gridName);
var workBook = XLSX.utils.book_new();
var excelData = XLSX.utils.json_to_sheet(xlsData);
var sheetName = fileName;
XLSX.utils.book_append_sheet(workBook, excelData, sheetName);
XLSX.writeFile(workBook, fileName);
},
makeExcelData(gridName) {
var xlsData = null;
var xlsHeader = this.pageData[gridName].column;
var xlsRowData = this.pageData[gridName].data;
var tmpData = [];
var tmpMap = {};
xlsRowData.map(item => {
xlsHeader.map(v => {
// return Object.assign(tmpMap, { [v.header]: item[v.name] || 0 });
var value = item[v.name];
if (value == undefined) {
value = 0;
}
if (typeof value === 'number') {
value = parseFloat(
Utility.setFormatIntDecimal(value, 2).replace(',', ''),
);
}
return Object.assign(tmpMap, { [v.header]: value || 0.0 });
});
tmpData = tmpData.concat(tmpMap);
tmpMap = {};
});
xlsData = tmpData;
return xlsData;
},
},
};
const defaultData = {
isFind: false,
rowGrid01: {
data: [],
option: {},
column: [],
},
rowGrid02: {
data: [],
option: {},
column: [],
},
rowGrid03: {
data: [],
option: {},
column: [],
},
};
function setRowSpanAttribute(res, targetAttributeName, targetAttributeList) {
if (!(res.length && res.length >= 2)) {
return;
}
if (targetAttributeList == undefined) {
var valueList = [];
var rowSpanValueList = [];
var currentIdx = 0;
for (var i = 0; i < res.length; i++) {
valueList.push(res[i][targetAttributeName]);
}
rowSpanValueList[0] = [valueList[0], 1, currentIdx];
for (var i = 1; i < valueList.length; i++) {
currentIdx += 1;
if (valueList[i] === rowSpanValueList[rowSpanValueList.length - 1][0]) {
rowSpanValueList[rowSpanValueList.length - 1][1] += 1;
} else {
rowSpanValueList[rowSpanValueList.length] = [
valueList[i],
1,
currentIdx,
];
}
}
for (var i = 0; i < rowSpanValueList.length; i++) {
if (rowSpanValueList[i][1] === 1) {
continue;
}
res[rowSpanValueList[i][2]]['_attributes'] = { rowSpan: new Object() };
res[rowSpanValueList[i][2]]['_attributes']['rowSpan'][
targetAttributeName
] = rowSpanValueList[i][1];
}
} else {
// targetAttributeList 전달 ...
var valueList = [];
var rowSpanValueList = [];
var currentIdx = 0;
for (var i = 0; i < res.length; i++) {
var tempList = [];
for (var j = 0; j < targetAttributeList.length; j++) {
tempList.push(res[i][targetAttributeList[j]]);
}
valueList.push(tempList);
}
rowSpanValueList[0] = [valueList[0], 1, currentIdx];
for (var i = 1; i < valueList.length; i++) {
currentIdx += 1;
if (
comepareValueWithTargetAttributeList(
valueList[i],
rowSpanValueList[rowSpanValueList.length - 1][0],
)
) {
rowSpanValueList[rowSpanValueList.length - 1][1] += 1;
} else {
rowSpanValueList[rowSpanValueList.length] = [
valueList[i],
1,
currentIdx,
];
}
}
for (var i = 0; i < rowSpanValueList.length; i++) {
if (rowSpanValueList[i][1] === 1) {
continue;
}
res[rowSpanValueList[i][2]]['_attributes'] = { rowSpan: new Object() };
res[rowSpanValueList[i][2]]['_attributes']['rowSpan'][
targetAttributeName
] = rowSpanValueList[i][1];
}
}
function comepareValueWithTargetAttributeList(valueList_01, valueList_02) {
for (var i = 0; i < valueList_01.length; i++) {
if (valueList_01[i] != valueList_02[i]) {
return false;
}
}
return true;
}
}
function setRowSpanAttribute_old(
res,
targetAttributeName,
targetAttributeList,
) {
if (!(res.length && res.length >= 2)) {
return;
}
if (targetAttributeList == undefined) {
var currentCnt = 1;
var currentIdx = 0;
var currentValue = res[0][targetAttributeName];
for (var i = 1; i < res.length - 1; i++) {
if (res[i][targetAttributeName] != currentValue) {
if (res[currentIdx]['_attributes'] == undefined) {
res[currentIdx]['_attributes'] = { rowSpan: new Object() };
}
res[currentIdx]['_attributes']['rowSpan'][
targetAttributeName
] = currentCnt;
currentValue = res[i][targetAttributeName];
currentCnt = 1;
currentIdx = i;
} else if (
res[i][targetAttributeName] == currentValue &&
i == res.length - 2
) {
currentCnt = currentCnt + 1;
if (res[currentIdx]['_attributes'] == undefined) {
res[currentIdx]['_attributes'] = { rowSpan: new Object() };
}
res[currentIdx]['_attributes']['rowSpan'][
targetAttributeName
] = currentCnt;
} else {
currentCnt = currentCnt + 1;
}
}
} else {
var currentCnt = 1;
var currentIdx = 0;
for (var i = 1; i < res.length - 1; i++) {
if (!compareValue(res, targetAttributeList, currentIdx, i)) {
if (res[currentIdx]['_attributes'] == undefined) {
res[currentIdx]['_attributes'] = { rowSpan: new Object() };
}
if (currentCnt != 1) {
res[currentIdx]['_attributes']['rowSpan'][
targetAttributeName
] = currentCnt;
}
currentCnt = 1;
currentIdx = i;
} else if (
compareValue(res, targetAttributeList, currentIdx, i) &&
i == res.length - 2
) {
currentCnt = currentCnt + 1;
if (res[currentIdx]['_attributes'] == undefined) {
res[currentIdx]['_attributes'] = { rowSpan: new Object() };
}
if (currentCnt != 1) {
res[currentIdx]['_attributes']['rowSpan'][
targetAttributeName
] = currentCnt;
}
} else {
currentCnt = currentCnt + 1;
}
}
}
function compareValue(res, targetAttributeList, currentIdx, targetIdx) {
for (var i = 0; i < targetAttributeList.length; i++) {
if (
res[currentIdx][targetAttributeList[i]] !=
res[targetIdx][targetAttributeList[i]]
) {
return false;
}
}
return true;
}
}
function numberFormatter({ value }) {
return Utility.setFormatIntDecimal(value, 2);
}
</script>
<style lang="scss" scoped>
#startpicker-container,
#endpicker-container {
position: relative;
z-index: 20;
}
.v-input__custom {
flex: 0 0 auto;
&.half {
width: calc(50% - 20px);
}
}
::v-deep {
.tui-timepicker-row {
display: flex;
justify-content: space-around;
background-color: #edf4fc;
.tui-timepicker-column.tui-timepicker-colon {
color: #000 !important;
}
}
}
</style>

View File

@ -0,0 +1,517 @@
<template>
<div class="l-layout">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="2">
<component
:is="'SelectBlocMstr'"
ref="SelectBlocMstr"
:parentPrgmId="myPrgmId"
/>
</v-col>
<!-- <v-col :cols="2">
<component
label="검침개소"
:is="'PastRsltDataReadPop'"
:parentPrgmId="myPrgmId"
/>
</v-col> -->
<!-- <v-col :cols="2">
<component
:is="'SelectTagNmList'"
ref="SelectTagNmList"
:parentPrgmId="myPrgmId"
/>
</v-col> -->
<v-col :cols="3">
<!-- <component
:is="'PastRsltDataReadTagPop'"
:parentPrgmId="myPrgmId"
:label="'TAG'"
/> -->
<component
:is="'EvtObjPop'"
:parentPrgmId="myPrgmId"
:item="evtObjPopItem"
/>
</v-col>
<v-col :cols="4">
<component
:is="'Datepicker'"
:parentPrgmId="myPrgmId"
:label="'조회기간'"
:labelCols="2"
/>
</v-col>
<v-col :cols="3" class="text-right">
<!-- 조회버튼 -->
<BtnSearch @click="search" />
<BtnExcelDownload
style="vertical-align: middle;"
class="d-inline-flex"
:parentPrgmId="myPrgmId"
:gridName="gridName"
/>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents">
<v-col :cols="12" style="height: 100%" class="h100">
<v-card class="px-5 py-5 h100">
<div ref="gridParent" class="h100 px-5" style="height: 100%">
<component
ref="myGrid"
:is="loadGrid ? 'Grid' : null"
:gridName="gridName"
:parentPrgmId="myPrgmId"
/>
</div>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex';
import BtnSearch from '~/components/common/button/BtnSearch';
import Grid from '~/components/common/Grid';
import mixinGlobal from '@/mixin/global.js';
import { resize } from '@/mixin/resize.js';
import SelectBlocMstr from '@/components/common/select/SelectBlocMstr';
import Utility from '~/plugins/utility';
import Datepicker from '~/components/common/PastRsltDatePicker';
import PastRsltDataReadPop from '~/components/common/modal/PastRsltDataReadPop';
import PastRsltDataReadTagPop from '~/components/common/modal/PastRsltDataReadTagPop';
import SelectTagNmList from '~/components/common/select/SelectTagNmList';
import BtnExcelDownload from '~/components/common/button/BtnExcelDownload';
// import TotUseQtyCmprPageVue from './TotUseQtyCmprPage.vue';
import DateUtility from '~/plugins/dateUtility';
// import Search from "~/components/common/search";
import EvtObjPop from '~/components/common/modal/EvtObjPop';
let myTitle;
// const myPrgmId = "PRG0052";
let myPrgmId;
export default {
mixins: [mixinGlobal, resize],
async asyncData(context) {
const myState = context.store.state;
// context.store.commit("setActiveMenuInfo", myState.menuData[myPrgmId]);
// myTitle = myState.activeMenuInfo.menuNm;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
BtnSearch,
Datepicker,
SelectBlocMstr,
SelectTagNmList,
BtnExcelDownload,
Grid,
PastRsltDataReadPop,
PastRsltDataReadTagPop,
EvtObjPop,
},
data() {
return {
myPrgmId: myPrgmId,
loadGrid: false,
gridName: 'rowGrid',
myRowKey: 0,
initFlag: false,
evtObjPopItem: {
labelContent: 'TAG',
modalTitle: 'TAG 리스트',
valueNm: 'tagId',
valueNm2: 'tagNm',
disabled: false,
labelCols: 2,
textCols: 9,
class: 'py-2',
required: false,
formFg: false,
},
};
},
computed: {
...mapState({
pageData: state => state.pageData[myPrgmId],
}),
chkIsFind() {
return this.pageData.isFind;
},
chkTagId() {
return this.pageData.tagList === undefined ? null : this.pageData.tagId;
},
// chkTagList() {
// return this.pageData.tagList;
// },
chkTagNm() {
return this.pageData.tagData.tagNm;
},
chkReadPlcId() {
return this.pageData.readPlcId;
},
},
watch: {
chkIsFind(val) {
if (val) this.search();
},
chkTagId(val) {
if (this.initFlag && val != null) {
this.search();
}
},
// chkTagList() {
// if(this.initFlag){
// this.search();
// }
// },
chkTagNm() {
if (this.initFlag) {
this.search();
}
},
chkReadPlcId() {
this.setPageData({
sendTagParam: { readPlc: this.pageData.readPlcId.readPlcId },
});
},
},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
created() {},
async mounted() {
await this.setFromDt();
await this.init();
this.initFlag = true;
},
beforeDestroy() {
this.chkOpenTabList({ key: 'destroy', prgmId: myPrgmId });
},
methods: {
...mapMutations({
setPageData: 'setPageData',
setGridData: 'setGridData',
setGridColumn: 'setGridColumn',
setGridOption: 'setGridOption',
}),
...mapActions({
postApi: 'modules/list/postApi',
postUpdateApi: 'modules/list/postUpdateApi',
postApiReturn: 'modules/list/postApiReturn',
chkOpenTabList: 'chkOpenTabList',
}),
async search() {
// this.gridInit();
if (this.initFlag) {
if (this.pageData.tagId == '' || this.pageData.tagId == null) {
alert('TAG를 선택해 주세요');
} else {
this.getRowGridData();
}
}
this.setPageData({
isFind: false,
});
},
async init() {
//this.layoutInit();
this.gridInit();
this.pageData.blocId = this.userInfo.blocId;
},
layoutInit() {
const searchFilterHeight = this.$refs.searchFilter.offsetHeight;
this.$refs.contents.style.height = `calc(100% - ${searchFilterHeight}px)`;
},
async setFromDt() {
this.pageData.fromDt = Utility.setBeforetDate(
this.pageData,
this.pageData.toDt,
'YYYYMMDD',
);
// this.pageData.toDt = Utility.setAftertDate(this.pageData, this.pageData.fromDt, "YYYYMMDD");
},
gridInit() {
this.loadGrid = false;
const gridHeight = this.$refs.gridParent.offsetHeight - 30;
const myOptions = {
columnOptions: {
resizable: true,
},
};
this.setGridOption({
gridKey: this.gridName,
value: Object.assign(Utility.defaultGridOption(gridHeight), myOptions),
});
let myColumns = [
{
header: 'TAG ID',
name: 'tagId',
align: 'left',
minWidth: 500,
},
{
header: 'TAG명',
name: 'tagNm',
align: 'left',
},
{
header: '대상일시',
name: 'readDttm',
align: 'center',
width: 200,
},
{
header: '값',
name: 'readVal',
align: 'right',
width: 100,
excelType: 'number',
excelFormatter: '2',
formatter({ value }) {
return Utility.setFormatIntDecimal(value, 2);
},
},
{
header: '취득일시',
name: 'regDttm',
align: 'center',
width: 200,
},
{
header: '적재일시',
name: 'procDttm',
align: 'center',
width: 200,
},
];
this.setGridColumn({
gridKey: this.gridName,
value: myColumns,
});
this.loadGrid = true;
},
async getRowGridData() {
this.loadGrid = false;
let res = [];
let yearQuarterData = [];
yearQuarterData = this.yearQuarterMaker([
this.pageData.fromDt,
this.pageData.toDt,
]);
// if(this.pageData.tagList.length > 0){
// const sendParams= {
// fromDt: this.pageData.fromDt,
// toDt: this.pageData.toDt,
// yearQuarterList: yearQuarter,
// }
// if(this.pageData.tagList[this.pageData.tagId].tagId == '' || this.pageData.tagList[this.pageData.tagId].tagId == null){
// sendParams['readPlcId']= this.pageData.readPlcId.readPlcId
// }else{
// sendParams['tagId']= this.pageData.tagList[this.pageData.tagId].tagId
// }
// res = await this.postApiReturn({
// apiKey: "selectTagRawDataByQuarter",
// resKey: "pastRsltReadData",
// sendParam: sendParams
// });
// this.setGridData({
// gridKey: this.gridName,
// value: res
// })
// }
// 기존 소스
if (this.pageData.tagData.tagNm != '') {
const sendParams = {
fromDt: this.pageData.fromDt,
toDt: this.pageData.toDt,
yearQuarterList: yearQuarterData['yearQuarterList'],
};
sendParams['tagId'] = this.pageData.tagData.tagId;
//
if (yearQuarterData['newToDt'] != undefined) {
sendParams['toDt'] = yearQuarterData['newToDt'];
sendParams['newFromDt'] = yearQuarterData['newFromDt'];
sendParams['rawTableToDt'] = yearQuarterData['rawTableToDt'];
} else if (yearQuarterData['rawTableToDt'] != undefined) {
sendParams['newFromDt'] = yearQuarterData['newFromDt'];
sendParams['rawTableToDt'] = yearQuarterData['rawTableToDt'];
}
res = await this.postApiReturn({
apiKey: 'selectTagRawDataByQuarter',
resKey: 'pastRsltReadData',
sendParam: sendParams,
});
this.setGridData({
gridKey: this.gridName,
value: res,
});
} else {
// 바뀐 popup에 맞춘 소스
const sendParams = {
fromDt: this.pageData.fromDt,
toDt: this.pageData.toDt,
yearQuarterList: yearQuarterData['yearQuarterList'],
};
sendParams['tagId'] = this.pageData.tagId;
//
if (yearQuarterData['newToDt'] != undefined) {
sendParams['toDt'] = yearQuarterData['newToDt'];
sendParams['newFromDt'] = yearQuarterData['newFromDt'];
sendParams['rawTableToDt'] = yearQuarterData['rawTableToDt'];
} else if (yearQuarterData['rawTableToDt'] != undefined) {
sendParams['newFromDt'] = yearQuarterData['newFromDt'];
sendParams['rawTableToDt'] = yearQuarterData['rawTableToDt'];
}
res = await this.postApiReturn({
apiKey: 'selectTagRawDataByQuarter',
resKey: 'pastRsltReadData',
sendParam: sendParams,
});
this.setGridData({
gridKey: this.gridName,
value: res,
});
}
this.loadGrid = true;
},
yearQuarterMaker(dateList) {
//1번 조건: 오늘 날짜 기준 최근 4개월까지는 raw_data 테이블 조회
//2번 조건: 그 이후의 경우는 raw_data2022Y2Q 같은 backup 테이블 조회
//3번 조건: 1+2번 조건
let finalResult = {};
let newFromDt = '';
let newToDt = '';
let today = Utility.setFormatDate(new Date(), 'YYYYMMDDHHmmss');
let checkPoint = 0;
let diffTime = DateUtility.diff(dateList[0], today, 'd');
if (diffTime >= 120) {
newFromDt = DateUtility.addDate(-119, 'YYYYMMDD', dateList[1]);
newToDt = DateUtility.addDate(-120, 'YYYYMMDD', today);
checkPoint = DateUtility.diff(newToDt, dateList[1], 'd');
// 오늘날짜로부터 4개월 보다 많은 경우(raw_data + raw_data_backup 테이블)
if (checkPoint > 0) {
finalResult['newToDt'] = newToDt;
finalResult['newFromDt'] = newFromDt;
finalResult['rawTableToDt'] = dateList[1];
}
// console.log('newFromDt', dateList[0], newToDt, newFromDt, dateList[1]);
//1번 조건: 최근 4개월이내의 경우(raw_data만 조회)
} else {
finalResult['newFromDt'] = dateList[0];
finalResult['rawTableToDt'] = dateList[1];
finalResult['yearQuarterList'] = [];
return finalResult;
}
//2번 조건: 최근 4개월을 벗어나는 경우(raw_data_backup 테이블 조회)
let result = [];
let quarterNum;
//2022Y3Q 같은 형태로 만들기
for (let date of [dateList[0], newToDt]) {
quarterNum = 'Y1Q';
let year = date.substring(0, 4);
let qNum = parseInt(date.substring(4, 6).replace(/(^0+)/, ''));
if (qNum > 3) quarterNum = 'Y2Q';
if (qNum > 6) quarterNum = 'Y3Q';
if (qNum > 9) quarterNum = 'Y4Q';
result.push(year + quarterNum);
}
if (result.length > 1) {
let fromYear = parseInt(result[0].substring(0, 4));
let fromQuarter = parseInt(result[0].substring(5, 6));
let toYear = parseInt(result[1].substring(0, 4));
let toQuarter = parseInt(result[1].substring(5, 6));
let endPoint = toYear + 'Y' + toQuarter + 'Q';
let diffYear = toYear - fromYear;
for (var i = 0; i <= diffYear; i++) {
if (fromQuarter + 1 >= 4) {
fromYear = fromYear + 1;
fromQuarter = 0;
}
let newYearQuarter = fromYear + 'Y' + (fromQuarter + i + 1) + 'Q';
if (endPoint == newYearQuarter) {
break;
} else {
result.splice(i + 1, 0, newYearQuarter);
}
}
}
finalResult['yearQuarterList'] = result;
return finalResult;
},
},
};
const defaultData = {
sendTagParam: { readPlc: '' },
tagData: { tagNm: '' },
/* 검색옵션 */
blocId: '',
blocMstrList: [],
tagId: '',
tagNm: '',
tagList: [],
isFind: false,
modalData: {},
cmCycle: 'CYC_DAY', // 주기
readPlcId: '',
defaultRange: {
CYC_DAY: 30,
},
fromDt: '', // 조회 시작일
toDt: Utility.setFormatDate(new Date(), 'YYYYMMDD'), // 조회 종료일,
rowGrid: {
data: [],
column: [],
option: {},
defaultRow: {},
},
xlsFileInfo: {
// 출력하려는 grid 와 같은 이름으로 세팅
rowGrid: {
fileName: null, // 갑이 없으면 해당 페이지 메뉴명
sheetName: null, // 갑이 없으면 'Sheet1'
},
},
};
</script>
<style lang="scss">
@import '@/assets/scss/common.scss';
</style>

View File

@ -0,0 +1,815 @@
<template>
<div ref="mainDiv" class="l-layout">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="3">
<component
:is="'selectCodeList'"
:parentPrgmId="myPrgmId"
:label="'검침대상 유형'"
dataKey="readObjKind"
:addAll="true"
:sendParam="{ commGrpCd: 'CM_MTTTP', useFg: '1' }"
/>
</v-col>
<v-col :cols="3">
<component
:is="'selectCodeList'"
:parentPrgmId="myPrgmId"
:label="'사용여부'"
dataKey="useFg"
:sendParam="{ commGrpCd: 'CO_USEFG', useFg: '1' }"
:addAll="true"
/>
</v-col>
<v-col :cols="3">
<InputText
:parentPrgmId="myPrgmId"
label="검침대상명"
valueNm="readObjNm"
:searchOption="true"
/>
</v-col>
<v-col :cols="3" class="text-right">
<BtnSearch @click="search" />
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents">
<v-col :cols="5" class="h100">
<v-card class="pb-5">
<div class="d-flex align-center justify-space-between pa-5">
<v-card-title class="pa-0 custom-title-4"
>검침 대상 정보</v-card-title
>
<Buttons
:parentPrgmId="myPrgmId"
:bindingData="gridName"
:detailList="detailList"
:btnActionsFnc="btnActions"
/>
</div>
<div class="h100 px-5" style="height:calc(100% - 70px)">
<div ref="gridParent" class="w100 h100">
<component
:ref="gridName"
:is="loadGrid ? 'Grid' : null"
:gridName="gridName"
:parentPrgmId="myPrgmId"
@getRowsData="getRowData"
@sendSelectedRowStatInfo="getSelectedRowStatInfo"
:selectedRowDataWatchFlag="true"
/>
</div>
</div>
</v-card>
</v-col>
<v-col :cols="7" class="h100">
<v-card class="pb-5">
<v-card-title class="custom-title-4" style="min-height:76px;"
>검침대상 상세
</v-card-title>
<div class="px-5" style="height:calc(100% - 76px)">
<v-tabs v-model="tab">
<v-tab
v-for="item in items"
:key="item.id"
:disabled="item.disabledFlag"
>
{{ item.name }}
</v-tab>
</v-tabs>
<v-tabs-items
v-model="tab"
style="height: calc(100% - 65px);"
class="py-6"
>
<v-tab-item v-for="(item, idx) in items" :key="item.id">
<component
v-if="item.id == 'readObjBaseInfoTab'"
:is="'Form'"
:parentPrgmId="myPrgmId"
:detailList="detailList"
@gridEditingFinish="gridEditingFinish"
/>
<readObjAddInfoTab
v-if="item.id == 'readObjAddInfoTab'"
:parentPrgmId="myPrgmId"
:innerTabGridInfo="{ tab, idx }"
/>
</v-tab-item>
</v-tabs-items>
</div>
</v-card>
</v-col>
<!--
<v-col :cols="7" class="h100">
<v-card class="py-5">
<div class="d-flex align-center justify-space-between pa-5">
<v-card-title class="pa-0">검침 대상 정보 상세</v-card-title>
<div>
<Buttons
:parentPrgmId="myPrgmId"
:bindingData="gridName"
:btnActionsFnc="btnActions"
/>
</div>
</div>
<div class="px-5" style="height:calc(100% - 76px)">
<component
:is="'Form'"
:parentPrgmId="myPrgmId"
:detailList="detailList"
@gridEditingFinish="gridEditingFinish"
/>
</div>
</v-card>
</v-col>
-->
</v-row>
</div>
</template>
<script>
import { mapActions } from 'vuex';
import mixinGlobal from '@/mixin/global.js';
import { resize } from '@/mixin/resize.js';
import BtnSearch from '~/components/common/button/BtnSearch';
import Buttons from '~/components/common/button/Buttons';
import SelectBlocMstr from '@/components/common/select/SelectBlocMstr';
import selectCodeList from '@/components/common/select/selectCodeList';
import InputText from '@/components/common/input/InputText';
import Form from '~/components/common/form/Form';
import ReadObjAddInfoTab from '@/components/pages/ems/ReadObjInfo/ReadObjAddInfoTab';
import Grid from '~/components/common/Grid';
import Utility from '~/plugins/utility';
let myTitle;
// const myPrgmId = "PRG0009";
let myPrgmId;
export default {
mixins: [mixinGlobal, resize],
async asyncData(context) {
const myState = context.store.state;
// context.store.commit("setActiveMenuInfo", myState.menuData[myPrgmId]);
// myTitle = myState.activeMenuInfo.menuNm;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
BtnSearch,
Buttons,
SelectBlocMstr,
selectCodeList,
InputText,
Form,
ReadObjAddInfoTab,
Grid,
},
data() {
return {
myPrgmId: myPrgmId,
gridName: 'rowGrid',
loadGrid: false,
tab: null,
items: [
{
name: '검침 대상 정보',
id: 'readObjBaseInfoTab',
disabledFlag: false,
},
{
name: '검침 대상 추가 정보',
id: 'readObjAddInfoTab',
disabledFlag: false,
},
],
detailList: myDetail,
};
},
computed: {
// ...mapState({
// pageData: state => state.pageData[myPrgmId]
// }),
chkIsFind() {
// 조회 플래그
return this.pageData.isFind;
},
chkReadObjKind() {
// 시스템구분 선택 감지
return this.pageData.readObjKind;
},
chkUseFg() {
// 사용여부 선택 감지
return this.pageData.useFg;
},
},
watch: {
chkIsFind(val) {
if (val) this.search();
},
chkReadObjKind() {
this.setPageData({ isFind: true });
},
chkUseFg() {
this.setPageData({ isFind: true });
},
},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
created() {
// 검침 Data 구분 목록 조회
this.getCodeList({
dataKey: 'readObjGrp',
params: { commGrpCd: 'EM_READ_OBJ_GRP', useFg: '1' },
addAll: false,
});
// 검침 Data 구분 목록 조회
this.getCodeList({
dataKey: 'readObjKindDetail',
params: { commGrpCd: 'CM_MTTTP', useFg: '1' },
addAll: false,
});
// 단위 코드 목록 조회
this.getCodeList({
dataKey: 'unitCd',
params: { commGrpCd: 'CM_UNIT', useFg: '1' },
addAll: false,
});
/////////// 추가 정보 Tab 에서 사용
// 데이터 유형 목록 조회
this.getCodeList({
dataKey: 'addInfoDataKind',
params: { commGrpCd: 'CO_DATA_TYPE', useFg: '1' },
addAll: false,
});
// 추가 정보 목록 조회
this.getAddInfoList({
dataKey: 'addInfo',
params: { addGrpId: 'READ_OBJ_INFO', useFg: '1' },
addAll: false,
});
},
mounted() {
this.init();
},
beforeDestroy() {
this.chkOpenTabList({ key: 'destroy', prgmId: myPrgmId });
},
methods: {
...mapActions({
getCodeList: 'modules/search/getCodeList',
getBlocMstrList: 'modules/search/getBlocMstrList',
getAddInfoList: 'modules/search/getAddInfoList',
}),
init() {
this.gridInit();
},
search() {
this.getRowGridData();
this.setPageData({
isFind: false,
});
},
gridInit() {
const gridHeight = this.$refs.gridParent.offsetHeight - 30;
const myOptions = {
columnOptions: {
resizable: true,
},
};
this.setGridOption({
gridKey: this.gridName,
value: Object.assign(Utility.defaultGridOption(gridHeight), myOptions),
});
const _this = this;
const myColumns = [
{ header: '회사 ID', name: 'comId', hidden: true },
{
header: '검침 대상 ID',
name: 'readObjId',
width: 130,
align: 'center',
},
{
header: '검침 대상 명',
name: 'readObjNm',
align: 'left',
},
{
header: '검침 값 유형',
name: 'readObjKind',
width: 110,
align: 'left',
formatter({ value }) {
let retVal = '';
const newValue = _this.pageData.readObjKindDetailList.filter(
item => item.commCd == value,
);
if (newValue.length > 0) {
retVal = newValue[0].commCdNm;
}
return retVal;
},
},
{
header: '그룹',
name: 'grpCd',
width: 110,
align: 'left',
formatter({ value }) {
let retVal = '';
const newValue = _this.pageData.readObjGrpList.filter(
item => item.commCd == value,
);
if (newValue.length > 0) {
retVal = newValue[0].commCdNm;
}
return retVal;
},
},
{
header: 'TJ 환산계수',
name: 'tjCvrtCoef',
width: 80,
align: 'center',
hidden: true,
},
{
header: 'TOE 환산계수',
name: 'toeCvrtCoef',
width: 80,
align: 'center',
hidden: true,
},
{
header: 'CO2 환산계수',
name: 'co2CvrtCoef',
width: 100,
align: 'right',
hidden: true,
},
{
header: '단위 코드',
name: 'unitCd',
width: 80,
align: 'center',
hidden: true,
},
{
header: '사용여부',
name: 'useFg',
align: 'center',
width: 100,
formatter({ value }) {
value = value === true ? '1' : '0';
const newValue = _this.pageData.useFgList.filter(
item => item.commCd == value,
);
return newValue[0].commCdNm;
},
},
{ header: '등록자NO', name: 'regUserNo', hidden: true },
{ header: '등록일시', name: 'regDttm', hidden: true },
{ header: '수정자NO', name: 'procUserNo', hidden: true },
{ header: '수정일시', name: 'procDttm', hidden: true },
];
this.setGridColumn({
gridKey: this.gridName,
value: myColumns,
});
this.loadGrid = true;
this.search();
},
async getRowGridData() {
let res = [];
res = await this.postApiReturn({
apiKey: 'selectReadObjBaseInfo',
resKey: 'readObjBaseInfoData',
sendParam: {
readObjKind: this.pageData.readObjKind,
useFg: this.pageData.useFg,
readObjNmLike: this.pageData.readObjNm,
},
});
const newRes = res.map(item => {
const newObj = {
...item,
rowStat: null,
useFg: item.useFg === '1' ? true : false, // 화면 개발 편의를 위해 boolean 타입으로 교체, 저장시 "1", "0" 으로 바꿔 보내야 함
};
return newObj;
});
this.setGridData({
gridKey: this.gridName,
value: newRes,
});
this.$nextTick(() => {
if (newRes.length > 0) {
try {
this.$refs[this.gridName].focus({
//rowKey: 0,
rowKey:
this.pageData.rowGridSelectKey == '' ||
this.pageData.rowGridSelectKey == null
? 0
: this.pageData.rowGridSelectKey ==
this.$refs[this.gridName].getData().length - 1
? this.pageData.rowGridSelectKey
: 0,
columnNmae: 'readObjId',
setScroll: true,
});
} catch (error) {}
} else {
this.detailDataInit();
}
});
},
async getRowData(data) {
this.setReadObjAddInfo(data);
this.setPageData({
rowGridSelectKey: data.rowKey,
rowGridSelectData: data,
});
},
async setReadObjAddInfo(data) {
// 검침 대상 추가 정보 처리
const res = await this.postApiReturn({
apiKey: 'selectReadObjAddInfoList',
resKey: 'readObjAddInfoData',
sendParam: {
comId: data.comId,
blocId: data.blocId,
readObjId: data.readObjId,
},
});
const newRes = res.map(item => {
const newObj = {
...item,
comId: item.comId || '',
readObjId: item.readObjId || '',
addInfoId: item.addInfoId || '',
addInfoDataKind: item.addInfoDataKind || '',
addInfoNumVal: item.addInfoNumVal || '',
addInfoTxtVal: item.addInfoTxtVal || '',
addInfoVal: item.addInfoVal || '',
useFg: item.useFg || '1',
rowStat: null,
};
return newObj;
});
this.setGridData({
gridKey: 'rowDetailGrid',
value: newRes,
});
},
gridEditingFinish(data) {
this.$refs[this.gridName].editingFinish(data);
},
detailDataInit() {
this.setPageData({
rowGridSelectKey: null,
rowGridSelectData: [],
});
this.setGridData({
gridKey: 'rowDetailGrid',
value: [],
});
},
getSelectedRowStatInfo(data) {
if (data) {
var rowStat = data.rowStat;
if (rowStat === 'I') {
this.tab = 0;
for (var i = 1; i < this.items.length; i++) {
this.items[i].disabledFlag = true;
}
} else if (rowStat === 'U') {
for (var i = 1; i < this.items.length; i++) {
this.items[i].disabledFlag = false;
}
} else if (rowStat === 'D') {
for (var i = 1; i < this.items.length; i++) {
this.items[i].disabledFlag = false;
}
} else if (rowStat === null) {
for (var i = 1; i < this.items.length; i++) {
this.items[i].disabledFlag = false;
}
}
}
},
async btnActions(action) {
let dataArr = [];
switch (action) {
case 'add':
// console.log("this.pageData : ", this.pageData.readObjGrp);
const defaultRow = {
readObjId: '',
readObjNm: '',
readObjKind: this.pageData.readObjKindDetail,
grpCd: this.pageData.readObjGrp,
tjCvrtCoef: '',
toeCvrtCoef: '',
co2CvrtCoef: '',
unitCd: this.pageData.unitCd,
useFg: '1',
};
this.$refs[this.gridName].addRow(defaultRow);
break;
case 'remove':
this.$refs[this.gridName].removeRow();
break;
case 'save':
dataArr = this.$refs[this.gridName].save();
var validCheck = true;
var gridInstance = this.$refs[this.gridName].gridInstance;
var gridData = gridInstance.invoke('getData');
var duplicationCheckList = [
{
cd: 'readObjNm',
nm: '검침 대상 명',
},
];
if (dataArr.length > 0) {
dataArr.filter(item => {
if (item.rowStat === 'I') {
if (item.readObjNm == '') {
alert('필수 입력값을 입력해주세요.');
validCheck = false;
}
} else if (item.rowStat === 'U') {
if (item.readObjNm == '') {
alert('필수 입력값을 입력해주세요.');
validCheck = false;
}
}
console.log('gridData : ', gridData);
if (!this.duplicationCheck(gridData, duplicationCheckList)) {
validCheck = false;
}
});
if (validCheck) {
const sendParam = {
datas: {
dsReadObjBaseInfo: dataArr.map(item => ({
...item,
useFg: item.useFg ? '1' : '0',
})),
},
params: {},
};
await this.postUpdateApi({
apiKey: 'saveReadObjBaseInfo',
sendParam: sendParam,
});
this.$nextTick(() => {
this.setPageData({ isFind: true });
});
}
} else {
alert('저장할 내용이 없습니다.');
}
break;
default:
break;
}
},
duplicationCheck(data, keyList) {
var result = true;
outer: for (var i = 0; i < keyList.length; i++) {
var checkSet = new Set();
for (var j = 0; j < data.length; j++) {
if (checkSet.has(data[j][keyList[i]['cd']])) {
result = false;
alert(keyList[i]['nm'] + '값이 중복되었습니다.');
break outer;
} else {
checkSet.add(data[j][keyList[i]['cd']]);
}
}
}
return result;
},
},
};
const defaultData = {
/* 검색옵션 */
readObjNm: '',
readObjKind: '',
readObjKindList: [],
readObjKindDetail: '',
readObjKindDetailList: [],
readObjGrp: '',
readObjGrpList: [],
unitCdList: [],
useFg: '1',
useFgList: [],
commGrpCd: '',
commGrpCdNm: '',
addInfoDataKind: '',
addInfoDataKindList: [],
addInfo: '',
addInfoList: [],
// 선택된 그룹코드 상세 데이터
rowGridSelectKey: 0,
rowGridSelectData: null,
isFind: false, // true 경우 조회, 조회버튼도 이 값으로 연동 예정
/* data 세팅 */
// 로컬 gridName 값과 동일한 이름으로 세팅
rowGrid: {
data: [],
column: [], // myColumns,
option: {}, // myOptions
defaultRow: {
comId: '',
readObjId: '',
blocId: null,
readObjNm: null,
readObjKind: '',
grpCd: '',
tjCvrtCoef: null,
toeCvrtCoef: null,
co2CvrtCoef: null,
unitCd: '',
useFg: '1',
// rowStat: null
rowStat: 'I',
regDttm: '',
regUserNo: '',
procDttm: '',
procUserNo: '',
},
buttonAuth: {
add: true,
remove: true,
save: true,
excel: false,
},
},
rowDetailGrid: {
data: [],
column: [], // myColumns,
option: {}, // myOptions
defaultRow: {
comId: '',
readObjId: '',
addInfoId: null,
addInfoDataKind: null,
addInfoNumVal: null,
addInfoTxtVal: null,
addInfoVal: null,
useFg: '1',
rowStat: null,
},
buttonAuth: {
remove: false,
save: true,
excel: false,
},
},
};
const myDetail = [
{
type: 'InputText',
label: '검침 대상 ID',
valueNm: 'readObjId',
readonly: true,
cols: 6,
class: 'py-2',
required: false,
placeholder: '시스템 자동입력',
},
{
type: 'InputText',
label: '검침 대상 명',
valueNm: 'readObjNm',
disabled: false,
cols: 6,
class: 'py-2',
required: true,
},
{
type: 'SelectBox',
label: '검침 대상 유형',
valueNm: 'readObjKind',
disabled: false,
cols: 6,
class: 'py-2',
list: 'readObjKindDetailList',
itemText: 'commCdNm',
itemValue: 'commCd',
required: true,
},
{
type: 'SelectBox',
label: '그룹',
valueNm: 'grpCd',
disabled: false,
cols: 6,
class: 'py-2',
list: 'readObjGrpList',
itemText: 'commCdNm',
itemValue: 'commCd',
required: true,
},
{
type: 'InputText',
label: 'TJ 환산계수',
valueNm: 'tjCvrtCoef',
disabled: false,
cols: 6,
class: 'py-2',
inputType: 'number',
},
{
type: 'InputText',
label: 'TOE 환산계수',
valueNm: 'toeCvrtCoef',
disabled: false,
cols: 6,
class: 'py-2',
inputType: 'number',
},
{
type: 'InputText',
label: 'CO2 환산계수',
valueNm: 'co2CvrtCoef',
disabled: false,
cols: 6,
class: 'py-2',
inputType: 'number',
},
{
type: 'SelectBox',
label: '단위',
valueNm: 'unitCd',
disabled: false,
cols: 6,
class: 'py-2',
list: 'unitCdList',
itemText: 'commCdNm',
itemValue: 'commCd',
required: true,
},
{
type: 'CheckBox',
label: '사용 여부',
valueNm: 'useFg',
disabled: false,
cols: 6,
class: 'py-2',
value: { '1': true, '0': false },
required: true,
},
];
</script>
<style lang="scss">
@import '@/assets/scss/common.scss';
</style>

View File

@ -0,0 +1,399 @@
<template>
<div class="l-layout">
<v-row ref="searchFilter">
<!-- 조회조견 -->
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="3">
<component
:is="'SelectBlocMstr'"
ref="SelectBlocMstr"
:parentPrgmId="myPrgmId"
/>
</v-col>
<v-col :cols="3">
<component
:is="'selectCodeList'"
:parentPrgmId="myPrgmId"
:label="'검침대상유형'"
dataKey="commCd"
:sendParam="{ commGrpCd: 'CM_MTTTP', useFg: '1' }"
/>
</v-col>
<v-col :cols="3">
<component
:is="'SelectMttList'"
ref="SelectMttList"
:parentPrgmId="myPrgmId"
:label="'검침대상'"
dataKey="readObjId"
/>
</v-col>
<v-col :cols="3" class="text-right">
<v-btn :ripple="false" @click="search">조회</v-btn>
<BtnExcelDownload
class="mr-1"
:parentPrgmId="myPrgmId"
:gridName="gridName"
/>
</v-col>
</v-row>
<v-row align="center" no-gutters>
<v-col :cols="3">
<component
ref="fromPicker"
:is="'Datepicker'"
:parentPrgmId="myPrgmId"
:label="'조회기간'"
/>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents">
<!-- 일일검침정보 목록-->
<v-col :cols="12" class="h100">
<v-card class="pb-5">
<div class="d-flex align-center justify-space-between pa-5">
<v-card-title class="custom-title-4 pa-0"
>일일검침정보</v-card-title
>
<div class="d-flex align-center">
<v-btn
:ripple="false"
@click="saveReadResultCloseMngMM()"
class="mr-1"
>월마감</v-btn
>
<v-btn :ripple="false" @click="saveReadResultCloseMng('N')"
>일마감</v-btn
>
</div>
</div>
<div class="px-5" style="height:calc(100% - 76px)">
<div ref="gridParent" class="h100 w100">
<component
:is="loadGrid ? 'Grid' : null"
:ref="gridName"
:parentPrgmId="myPrgmId"
:gridName="gridName"
/>
</div>
</div>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script>
import mixinGlobal from '@/mixin/global.js';
import { resize } from '@/mixin/resize.js';
import { mapState, mapMutations, mapActions } from 'vuex';
import Search from '~/components/common/search';
import Grid from '~/components/common/Grid';
import Utility from '~/plugins/utility';
import SelectBlocMstr from '@/components/common/select/SelectBlocMstr';
import selectCodeList from '@/components/common/select/selectCodeList';
import SelectMttList from '@/components/common/select/SelectMttList';
import Datepicker from '~/components/common/Datepicker';
import BtnExcelDownload from '~/components/common/button/BtnExcelDownload';
let myTitle;
// const myPrgmId = "PRG0018";
let myPrgmId;
export default {
mixins: [mixinGlobal, resize],
async asyncData(context) {
const myState = context.store.state;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
SelectBlocMstr,
selectCodeList,
SelectMttList,
BtnExcelDownload,
Datepicker,
Search,
Grid,
},
data() {
return {
myPrgmId: myPrgmId,
gridName: 'rowGrid',
loadGrid: false,
};
},
computed: {
...mapState({
isDarkMode: state => state.isDarkMode,
pageData: state => state.pageData[myPrgmId],
}),
chkIsFind() {
// 조회 플래그
return this.pageData.isFind;
},
chkBlocId() {
// 사업장 코드
return this.pageData.blocId;
},
chkCommCd() {
this.setPageData({ sendMttParam: { mttTp: this.pageData.commCd } });
return this.pageData.commCd;
},
chkReadObjId() {
return this.pageData.readObjId;
},
},
watch: {
chkIsFind(val) {
if (val) this.search();
},
chkBlocId() {
this.setPageData({ isFind: true });
},
chkPlcKind() {
this.setPageData({ isFind: true });
},
chkCommCd() {},
async chkReadObjId(val) {
// console.log("sendMttParam",this.pageData.sendMttParam.mttTp);
// if(this.pageData.sendMttParam.mttTp){
// await this.getRowGridData();
// }
this.setPageData({ isFind: true });
},
},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
mounted() {
this.init();
},
created() {},
methods: {
...mapMutations({
setPageData: 'setPageData',
setGridData: 'setGridData',
setGridColumn: 'setGridColumn',
setGridOption: 'setGridOption',
}),
...mapActions({
postApi: 'modules/list/postApi',
postUpdateApi: 'modules/list/postUpdateApi',
postApiReturn: 'modules/list/postApiReturn',
setTree: 'modules/list/setTree',
chkOpenTabList: 'chkOpenTabList',
}),
init() {
this.gridInit();
},
gridInit() {
const gridHeight = this.$refs.gridParent.offsetHeight - 30;
const myOptions = {
columnOptions: {
resizable: true,
},
};
this.setGridOption({
gridKey: this.gridName,
value: Object.assign(Utility.defaultGridOption(gridHeight), myOptions),
});
this.setGridColumn({
gridKey: this.gridName,
value: myColumns,
});
this.loadGrid = true;
},
async search() {
await this.getRowGridData();
},
async getRowGridData() {
if (
this.pageData.blocMstrList.length > 0 &&
this.pageData.commCdList.length > 0 &&
this.pageData.readObjIdList.length > 0
) {
const res = await this.postApiReturn({
apiKey: 'selectReadResultCloseMng',
resKey: 'cdKindData',
sendParam: {
blocId: this.pageData.blocMstrList[this.pageData.blocId].blocId, // 사업장
mttCd: this.pageData.commCd, // 검침대상유형
mttTp: this.pageData.readObjId, // 검침대상
readDt: this.pageData.fromDt, // 조회기간
},
});
this.setGridData({
gridKey: this.gridName,
value: res.map(item => ({
...item,
mgnf: item.mgnf || 0,
})),
});
}
this.setPageData({ isFind: false });
},
//전월 or 일 마감--------------------------------------------------------------------------------------------
async saveReadResultCloseMng(mnthYn) {
const result = confirm('마감시 기존자료는 삭제됩니다. \n계속하겠습니까?');
if (await result) {
const sendParam = {
datas: {},
params: {
mnthYn: mnthYn,
procIp: '0.0.0.0',
readDt: this.pageData.fromDt,
},
};
await this.postUpdateApi({
apiKey: 'saveReadResultCloseMngSP',
sendParam: sendParam,
});
this.setPageData({ isFind: true });
}
},
async saveReadResultCloseMngMM() {
const result = confirm('마감시 기존자료는 삭제됩니다. \n계속하겠습니까?');
if (await result) {
const sendParam = {
datas: {},
params: {
procIp: '0.0.0.0',
readDt: this.pageData.fromDt,
},
};
await this.postUpdateApi({
apiKey: 'saveReadResultCloseMngSPMM',
sendParam: sendParam,
});
this.setPageData({ isFind: true });
}
},
},
};
const defaultData = {
/* 검색옵션 */
mttTp: '',
mttTpList: [],
sendMttParam: {},
readPlc: '',
readObjId: '',
readObjIdList: [],
commCd: '',
commCdList: [],
cmCycle: 'CYC_HOUR',
blocId: '',
blocMstrList: [],
fromDt: Utility.setFormatDate(new Date(), 'YYYYMMDD'),
isFind: false,
/* data 세팅 - sms 목록 */
rowGrid: {
data: [],
column: [],
option: {},
},
defaultRange: {
CYC_HOUR: 0,
},
xlsFileInfo: {
// 출력하려는 grid 와 같은 이름으로 세팅
rowGrid: {
// 엑셀변환시 데이타 가공이 추가로 필요하게 된다면 여기에 가공된 rowData 를 넣어야 할듯
fileName: null, // 갑이 없으면 해당 페이지 메뉴명
sheetName: null, // 갑이 없으면 'Sheet1'
},
},
};
const myColumns = [
{
header: '태그',
name: 'readPlcNm',
width: 300,
},
{
header: '배율',
name: 'distRt',
align: 'right',
formatter({ value }) {
if (value === null) {
return '';
} else {
return value;
}
},
},
{
header: '설비비',
name: 'eccNm',
formatter({ value }) {
if (value === null) {
return '';
} else {
return value;
}
},
},
{
header: '설비배분비율',
name: 'eccDistRt',
align: 'right',
formatter({ value }) {
if (value === null) {
return '';
} else {
return value;
}
},
},
{
header: '금일데이터',
name: 'totVal',
align: 'right',
excelType: 'number',
excelFormatter: '2',
formatter({ value }) {
return Utility.setFormatIntDecimal(value, 2);
},
},
{
header: '최종마감시각',
name: 'procDttm',
align: 'center',
formatter({ value }) {
if (value === null) {
return '';
} else {
return value;
}
},
},
];
</script>
<style lang="scss">
@import '@/assets/scss/common.scss';
</style>

View File

@ -0,0 +1,617 @@
<template>
<div class="l-layout">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="3">
<component :is="'SelectBlocMstr'" :parentPrgmId="myPrgmId" />
</v-col>
<v-col :cols="3">
<component
:is="'SelectEnergy'"
:parentPrgmId="myPrgmId"
:label="'검침대상'"
/>
</v-col>
<v-col :cols="3">
<component :is="'RadioView'" :parentPrgmId="myPrgmId" />
</v-col>
<v-col :cols="3" class="text-right">
<BtnSearch @click="search" />
<BtnExcelDownload
style="vertical-align: middle;"
class="d-inline-flex"
:parentPrgmId="myPrgmId"
:gridName="gridNameTree"
/>
</v-col>
</v-row>
<v-row align="center" no-gutters>
<v-col :cols="3">
<component
:is="'DatePicker'"
:label="'기간'"
:parentPrgmId="myPrgmId"
/>
</v-col>
<v-col :cols="4">
<component
:is="'RadioCmCycle'"
:label="'주기'"
:parentPrgmId="myPrgmId"
:labelCols="3"
/>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents" :eager="true">
<v-col style="height:100%;">
<v-card class="px-5 py-5">
<div ref="chartParent" id="test2" style="height: 56%;">
<component
class="w100 h100"
:is="loadChart ? 'Chart' : null"
:parentPrgmId="myPrgmId"
:chartName="chartName"
ref="treeGridChart"
/>
</div>
<div ref="treeGridParent" id="test" style="height: 44%;">
<component
:ref="gridNameTree"
:is="loadTree ? 'Grid' : null"
:gridName="gridNameTree"
:parentPrgmId="myPrgmId"
@getRowsData="getRowData"
/>
</div>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex';
import BtnSearch from '~/components/common/button/BtnSearch';
import SelectBlocMstr from '@/components/common/select/SelectBlocMstr';
import SelectEnergy from '@/components/common/select/SelectEnergy';
import DatePicker from '@/components/common/Datepicker';
import RadioCmCycle from '@/components/common/RadioCmCycle';
import RadioView from '@/components/common/RadioView';
import InputText from '@/components/common/input/InputText';
import Grid from '~/components/common/Grid';
import BtnExcelDownload from '~/components/common/button/BtnExcelDownload';
import Chart from '~/components/common/Chart';
import Utility from '~/plugins/utility';
import dateUtility from '~/plugins/dateUtility';
let myTitle;
//const myPrgmId = "PRG0024";
let myPrgmId;
export default {
async asyncData(context) {
const myState = context.store.state;
// context.store.commit("setActiveMenuInfo", myState.menuData[myPrgmId]);
// myTitle = myState.activeMenuInfo.menuNm;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
BtnSearch,
SelectBlocMstr,
SelectEnergy,
DatePicker,
RadioCmCycle,
RadioView,
InputText,
Grid,
Chart,
BtnExcelDownload,
},
data() {
return {
myPrgmId: myPrgmId,
loadTree: false,
loadChart: false,
gridNameTree: 'treeGrid',
chartName: 'treeGridChart',
defaultRowKey: 1,
selRowKey: null,
};
},
computed: {
...mapState({
pageData: state => state.pageData[myPrgmId],
}),
chkIsFind() {
// 조회 플래그
return this.pageData.isFind;
},
chkViewCheck() {
return this.pageData.viewCheck;
},
chkBlocCd() {
// 사업장 코드
return this.pageData.blocId;
},
chkCmCycle() {
return this.pageData.cmCycle;
},
chkEnergyCd() {
// 에너지 선택 여부 감지
return this.pageData.energyCd;
},
selectedCommCdData() {
return this.pageData.selectedCommCdData;
},
},
watch: {
chkIsFind(val) {
if (val) this.search();
},
chkBlocCd() {
this.setPageData({ isFind: true });
},
chkViewCheck() {
this.setView(this.pageData.viewCheck);
},
chkEnergyCd() {
this.setPageData({ isFind: true });
},
},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
mounted() {
this.init();
},
beforeDestroy() {
this.chkOpenTabList({ key: 'destroy', prgmId: myPrgmId });
},
methods: {
...mapMutations({
setPageData: 'setPageData',
setGridData: 'setGridData',
setGridColumn: 'setGridColumn',
setGridOption: 'setGridOption',
setChartOption: 'setChartOption',
}),
...mapActions({
postApi: 'modules/list/postApi',
postUpdateApi: 'modules/list/postUpdateApi',
postApiReturn: 'modules/list/postApiReturn',
setTree: 'modules/list/setTree',
chkOpenTabList: 'chkOpenTabList',
}),
init() {
this.layoutInit();
this.gridInit();
},
layoutInit() {
const searchFilterHeight = this.$refs.searchFilter.offsetHeight;
this.$refs.contents.style.height = `calc(100% - ${searchFilterHeight}px)`;
},
gridInit() {
const treeGridHeight = this.$refs.treeGridParent.offsetHeight - 36;
const myOptionsTree = {
treeColumnOptions: {
name: 'readPlcNm',
},
columnOptions: {
//frozenCount : 1,
minWidth: 100,
resizable: true,
},
scrollX: true,
};
this.setGridOption({
gridKey: this.gridNameTree,
// value: myOptionsTree
value: Object.assign(
Utility.defaultGridOption(treeGridHeight),
myOptionsTree,
),
});
this.getTreeData();
},
//메뉴 리스트
async getTreeData() {
this.loadTree = false;
if (
this.pageData.energyList.length > 0 &&
this.pageData.blocMstrList.length > 0
) {
const res = await this.postApiReturn({
apiKey: 'selectReadResultRet',
resKey: 'readPlcData',
// sendParm : sendParams
sendParam: {
sh_readObjId: this.pageData.energyList[this.chkEnergyCd].cd,
// sh_mttTp: "MTT00001",
sh_searchType:
this.pageData.cmCycle == 'CYC_YEAR'
? 'month'
: this.pageData.cmCycle == 'CYC_MONTH'
? 'day'
: 'time',
sh_date:
this.pageData.cmCycle == 'CYC_YEAR'
? this.pageData.fromDt
: this.pageData.cmCycle == 'CYC_MONTH'
? Utility.setFormatDate(this.pageData.fromDt, 'YYYY/MM')
: Utility.setFormatDate(this.pageData.fromDt, 'YYYY/MM/DD'),
// sh_blocCd:"BL0001"
sh_blocId: this.pageData.blocMstrList[this.pageData.blocId].blocId,
},
});
let columnList = [
{
header: '개소',
name: 'readPlcNm',
width: 300,
},
{
header: 'readPlc',
name: 'readPlc',
hidden: true,
},
{
header: 'upReadPlc',
name: 'upReadPlc',
hidden: true,
},
];
switch (this.pageData.cmCycle) {
case 'CYC_YEAR':
for (var i = 1; i < 13; i++) {
var tempObj = {
header:
Utility.setFormatDate(this.pageData.fromDt, 'YYYY') +
'/' +
String(i).padStart(2, '0'),
name: 'qty' + String(i - 1).padStart(2, '0'),
formatter({ value }) {
return Utility.setFormatIntDecimal(value, 2);
},
align: 'right',
excelType: 'number',
excelFormatter: '2',
};
columnList.push(tempObj);
}
break;
case 'CYC_MONTH':
for (
var i = 1;
i <= dateUtility.getLastDay('D', this.pageData.fromDt);
i++
) {
var tempObj = {
header:
Utility.setFormatDate(this.pageData.fromDt, 'MM') +
'/' +
String(i).padStart(2, '0'),
name: 'qty' + String(i - 1).padStart(2, '0'),
formatter({ value }) {
return Utility.setFormatIntDecimal(value, 2);
},
align: 'right',
excelType: 'number',
excelFormatter: '2',
};
columnList.push(tempObj);
}
break;
case 'CYC_DAY':
for (var i = 0; i < 24; i++) {
var tempObj = {
header: String(i).padStart(1, '0') + '시',
name: 'qty' + String(i).padStart(2, '0'),
formatter({ value }) {
return Utility.setFormatIntDecimal(value, 2);
},
align: 'right',
excelType: 'number',
excelFormatter: '2',
};
columnList.push(tempObj);
}
break;
}
this.setGridColumn({
gridKey: this.gridNameTree,
value: columnList,
});
const setTreeData = await this.setTree({
gridKey: this.gridNameTree,
treeKey: 'READ_PLC',
isId: true,
value: res.map(item => ({
...item,
readPlc: item.readPlcId,
})),
});
this.xlsDataBind(res);
await this.setGridData({
gridKey: this.gridNameTree,
value: setTreeData.ROOT,
});
// setTreeData["ROOT"][0]['_attributes'] = {expanded : true};
// this.$refs["treeGrid"].expandAll();
this.loadTree = true;
this.$nextTick(() => {
if (setTreeData != null) {
this.$refs[this.gridNameTree].focus({
// rowKey: this.chkRowGridSelectKey || 0,
rowKey:
this.selRowKey != null ? this.selRowKey : this.defaultRowKey,
setScroll: true,
});
}
});
this.setChartData([]);
this.loadChart = true;
}
},
async setChartData(data) {
let xAxisData = [];
let seriesData = [];
let tmpList = [];
let series = {};
let exceptionColumList = ['개소', 'readPlc', 'upReadPlc'];
const myKey = this.pageData[this.gridNameTree].column.filter(v => {
return !exceptionColumList.includes(v.header);
});
tmpList = Object.values(data);
tmpList.shift();
series.name = tmpList.shift();
series.type = 'bar';
series.data = tmpList;
xAxisData = myKey.map(obj => obj.header);
seriesData.push(series);
var option = {
xAxis: {
data: xAxisData,
},
yAxis: {
type: 'value',
name: this.pageData.energyList[this.pageData.energyCd].unit,
nameLocation: 'middle',
nameGap: 40,
},
legend: {
xtStyle: {
color: '#95A0A9',
fontSize: 10,
},
},
series: seriesData,
};
this.setChartOption({ chartKey: this.chartName, value: option });
},
async getRowData(data) {
this.loadChart = false;
this.selRowKey = data.rowKey;
let length =
this.pageData.cmCycle == 'CYC_YEAR'
? 12
: this.pageData.cmCycle == 'CYC_MONTH'
? 31
: 24;
var pageDataObj = {
readPlc: data.readPlc,
readPlcNm: data.readPlcNm,
};
for (var i = 0; i < length; i++) {
if (data['qty' + String(i).padStart(2, '0')] == null) {
data['qty' + String(i).padStart(2, '0')] = 0;
}
pageDataObj['qty' + String(i).padStart(2, '0')] =
data['qty' + String(i).padStart(2, '0')];
}
this.setChartData(pageDataObj);
this.loadChart = true;
},
async setView(value) {
switch (value) {
case 'viewAll':
this.loadTree = false;
this.loadChart = false;
this.$refs.treeGridParent.style.height = '44%';
this.$refs.chartParent.style.height = '56%';
this.gridInit();
this.loadChart = true;
break;
case 'viewGrid':
this.loadChart = false;
this.$refs.chartParent.style.height = '0%';
this.$refs.treeGridParent.style.height = '100%';
this.gridInit();
break;
case 'viewChart':
this.loadTree = false;
this.loadChart = true;
this.$refs.chartParent.style.height = '100%';
this.$refs.treeGridParent.style.height = '0%';
break;
}
this.isFind = true;
},
async search() {
await this.getTreeData();
await this.setPageData({
isFind: false,
});
},
xlsDataBind(res) {
const xlsRowData = res.map(item => {
const obj = {
...item,
useFg: item.useFg == '1' ? '사용' : '사용안함',
prgmTpCd: item.prgmTpCd == '1' ? '프로그램' : '팝업',
};
return obj;
});
this.setPageData({
xlsFileInfo: {
[this.gridNameTree]: {
rowData: xlsRowData,
},
},
});
},
},
};
const defaultData = {
/* 검색옵션 */
readPlc: '',
energyCd: 'MTT00001',
energyList: [],
blocId: null,
blocMstrList: [],
defaultRange: {
CYC_YEAR: 0,
CYC_MONTH: 0,
CYC_DAY: 0,
},
cmCycle: 'CYC_DAY',
viewCheck: 'viewAll',
fromDt: Utility.setFormatDate(new Date(), 'YYYYMMDD'), // 조회 시작일
// cmCycleList:[],
isFind: false, // true 경우 조회, 조회버튼도 이 값으로 연동 예정
/* data 세팅 */
treeGrid: {
data: [],
column: [],
option: {},
},
/*chartdata 세팅 */
treeGridChart: Utility.defaultChartOption(true),
xlsFileInfo: {
// 출력하려는 grid 와 같은 이름으로 세팅
treeGrid: {
fileName: null, // 갑이 없으면 해당 페이지 메뉴명
sheetName: null, // 갑이 없으면 'Sheet1'
},
},
};
</script>
<style lang="scss">
@import '@/assets/scss/common.scss';
</style>
//
<style scoped lang="scss">
// ::v-deep {
// .tui-grid {
// &-row-odd,
// &-row-even {
// .tui-grid-cell {
// .tui-grid-tree-depth i {
// width: 10px !important;
// height: 6px !important;
// background: url("@/assets/images/ico_grid_open.png")
// no-repeat
// center /
// 100%
// auto !important;
// }
// &.tui-grid-cell-has-tree {
// .tui-grid-tree-extra-content + .tui-grid-cell-content {
// position: relative;
// &:before {
// content: "";
// width: 10px !important;
// height: 8px !important;
// display: inline-block;
// margin-right: 6px;
// background: url("@/assets/images/ico_grid_list.png")
// no-repeat
// center /
// 100%
// auto !important;
// vertical-align: middle;
// }
// }
// [class*="tui-grid-tree-button-"] + .tui-grid-cell-content {
// &:before {
// content: none;
// }
// }
// }
// }
// &:hover {
// .tui-grid-cell {
// background-color: #1a4e87;
// .tui-grid-tree-depth i {
// background-image: url("@/assets/images/ico_grid_open_active.png") !important;
// }
// .tui-grid-cell-content {
// color: map-deep-get($config, "dark", "activate");
// &:before {
// background-image: url("@/assets/images/ico_grid_list_active.png") !important;
// }
// }
// }
// }
// }
// &-cell-current-row {
// .tui-grid-cell {
// .tui-grid-tree-depth i {
// background-image: url("@/assets/images/ico_grid_open_active.png") !important;
// }
// .tui-grid-cell-content {
// color: map-deep-get($config, "dark", "activate");
// &:before {
// background-image: url("@/assets/images/ico_grid_list_active.png") !important;
// }
// }
// }
// }
// }
// }
//
</style>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,895 @@
<template>
<div class="l-layout">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="3">
<component
:is="'SelectBlocMstr'"
ref="SelectBlocMstr"
:parentPrgmId="myPrgmId"
/>
</v-col>
<v-col :cols="3">
<component
:is="'SelectEnergy'"
:parentPrgmId="myPrgmId"
:label="'에너지'"
/>
</v-col>
<v-col :cols="3">
<component :is="'SelectCmCycle2'" :parentPrgmId="myPrgmId" />
</v-col>
<v-col cols="3" class="d-flex justify-end align-center">
<BtnSearch @click="search" class="mr-1" />
<BtnExcelDownload :parentPrgmId="myPrgmId" :gridName="gridName" />
</v-col>
</v-row>
<v-row align="center" no-gutters>
<v-col cols="3">
<v-row class="search-box" align="center" no-gutters>
<v-col cols="4">
<label for="" class="search-box-label">
<v-icon x-small color="primary" class="mr-1"
>mdi-record-circle</v-icon
>
기준일
</label>
</v-col>
<v-col cols="7">
<v-text-field
id="startpicker"
ref="startpicker"
v-model="fromDtValue"
:class="'v-input__custom'"
readonly
outlined
:hide-details="true"
>
<template #append>
<v-icon size="20">$icoCalendar</v-icon>
</template>
<template #append-outer>
<div
ref="startpicker-container"
id="startpicker-container"
></div>
</template>
</v-text-field>
</v-col>
</v-row>
</v-col>
<v-col cols="3">
<v-row class="search-box">
<v-col cols="4">
<label for="" class="search-box-label">
<v-icon x-small color="primary" class="mr-1"
>mdi-record-circle</v-icon
>
비교일
</label>
</v-col>
<v-col cols="7">
<v-text-field
id="endpicker"
ref="endpicker"
v-model="toDtValue"
:class="'v-input__custom'"
readonly
outlined
:hide-details="true"
>
<template #append>
<v-icon size="20">$icoCalendar</v-icon>
</template>
<template #append-outer>
<div
ref="endpicker-container"
id="endpicker-container"
></div>
</template>
</v-text-field>
</v-col>
</v-row>
</v-col>
<v-col cols="6">
<component
:is="'SelectReadPlcPop'"
:parentPrgmId="myPrgmId"
:label="'비교대상'"
:textFieldLength="6"
/>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents">
<v-col :cols="12" style="height: 60%;">
<v-card class="pa-5">
<component
class="w100 h100"
:is="loadChart ? 'Chart' : null"
:parentPrgmId="myPrgmId"
:chartName="'rowGridChart'"
ref="rowGridChart"
/>
</v-card>
</v-col>
<v-col :cols="12" style="height: 40%;">
<v-card class="pb-5">
<v-card-title class="justify-end caption text-color--non-activate"
>단위 : {{ unit }}</v-card-title
>
<div ref="gridParent" class="px-5" style="height: calc(100% - 70px)">
<component
:is="loadGrid ? 'Grid' : null"
:gridName="gridName"
:parentPrgmId="myPrgmId"
ref="rowGrid"
/>
</div>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex';
import Grid from '~/components/common/Grid';
// import SelectBlocMstr from "@/components/common/select/SelectBlocMstr";
// import SelectEnergy from "@/components/common/select/SelectEnergy";
import SelectBlocMstr from '@/components/common/select/SelectBlocMstrForPop';
import SelectEnergy from '@/components/common/select/SelectEnergyForPop';
import SelectCmCycle from '@/components/common/select/SelectCmCycle';
import SelectCmCycle2 from '@/components/common/select/SelectCmCycle2';
import BtnSearch from '~/components/common/button/BtnSearch';
import BtnExcelDownload from '~/components/common/button/BtnExcelDownload';
import Utility from '~/plugins/utility';
import TuiDatepicker from 'tui-date-picker';
import SelectReadPlcPop from '~/components/common/modal/OutSideWeatherPlcMultiPop';
import Chart from '~/components/common/Chart';
let myTitle;
let myPrgmId;
export default {
async asyncData(context) {
const myState = context.store.state;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
Grid,
SelectBlocMstr,
SelectEnergy,
SelectCmCycle,
SelectCmCycle2,
BtnSearch,
BtnExcelDownload,
Utility,
TuiDatepicker,
SelectReadPlcPop,
Chart,
},
data() {
return {
myPrgmId: myPrgmId,
gridName: 'rowGrid',
loadGrid: false,
loadChart: false,
unit: '',
apiKey: 'selectSameReadPlcMonth',
startDatepickerInstance: null,
endDatepickerInstance: null,
startDtValue: null,
endDtValue: null,
timePicker: false,
datePickerSearchFlag: 3,
};
},
created() {
const today = Utility.setFormatDate('today', 'YYYY-MM-DD');
},
computed: {
...mapState({
pageData: state => state.pageData[myPrgmId],
}),
chkIsFind() {
// 조회 플래그
return this.pageData.isFind;
},
// chkCmCycle(){
myCmCycle() {
return this.pageData.cmCycle;
},
chkBlocCd() {
// 사업장 선택 감지
return this.pageData.blocId;
},
chkEnergyCd() {
// 에너지 선택 감지
return this.pageData.energyCd;
},
chkFacInfo() {
// 공정/설비 변경 감지
return this.pageData.facInfo;
},
// datepicker_computed[시작]
myOptions() {
let returnObj = {};
switch (this.myCmCycle) {
case 'CYC_MONTH':
returnObj = {
type: 'year',
viewFormat: 'YYYY',
pickerFormat: 'YYYY',
sendFormat: 'YYYY',
};
break;
case 'CYC_WEEK':
returnObj = {
type: 'date',
viewFormat: 'YYYY-MM-DD',
pickerFormat: 'YYYY-MM-dd',
sendFormat: 'YYYYMMDD',
};
break;
case 'CYC_DAY':
returnObj = {
type: 'month',
viewFormat: 'YYYY-MM',
pickerFormat: 'yyyy-MM',
sendFormat: 'YYYYMM',
};
break;
case 'CYC_HOUR':
returnObj = {
type: 'date',
viewFormat: 'YYYY-MM-DD' + (this.timePicker ? ' HH:mm:ss' : ''),
pickerFormat: 'yyyy-MM-dd' + (this.timePicker ? ' HH:mm A' : ''),
sendFormat: this.timePicker ? 'YYYY-MM-DD HH:mm:ss' : 'YYYYMMDD',
};
// returnObj = { type: "day", format: "YYYY-MM-DD HH:mm:ss" };
break;
default:
break;
}
return returnObj;
},
fromDtValue() {
return this.startDtValue;
},
toDtValue() {
return this.endDtValue;
},
// datepicker_computed[끝]
initFlag() {
if (
this.pageData.energyList.length > 0 &&
this.pageData.blocMstrList.length > 0
) {
return true;
} else {
return false;
}
},
},
watch: {
chkIsFind(val) {
if (val) this.search();
},
myCmCycle: function() {
this.datePickerSearchFlag = 2;
var day1 = new Date();
var day2 = new Date();
if (this.myCmCycle == 'CYC_MONTH') {
day2.setFullYear(day1.getFullYear() - 1);
} else if (this.myCmCycle == 'CYC_WEEK') {
day2.setDate(day1.getDate() - 7);
} else if (this.myCmCycle == 'CYC_DAY') {
day2.setMonth(day1.getMonth() - 1);
} else if (this.myCmCycle == 'CYC_HOUR') {
day2.setDate(day1.getDate() - 1);
}
this.startDtValue = setDateWithFormat(day1, this.myOptions.type);
this.endDtValue = setDateWithFormat(day2, this.myOptions.type);
this.startDatepickerInstance.setDate(this.startDtValue);
this.endDatepickerInstance.setDate(this.endDtValue);
this.startDatepickerInstance.setDate(new Date(this.fromDtValue));
this.endDatepickerInstance.setDate(new Date(this.toDtValue));
this.startDatepickerInstance.setType(this.myOptions.type);
this.endDatepickerInstance.setType(this.myOptions.type);
// this.setPageData({ isFind: true });
},
chkBlocCd() {
// this.setPageData({ isFind: true });
},
chkEnergyCd() {
// this.setPageData({ isFind: true });
this.initUnit();
},
chkFacInfo() {
if (this.initFlag == true) {
this.setPageData({ isFind: true });
}
// this.setPageData({ isFind: true });
},
// datepicker_watch[시작]
fromDtValue(newVal, oldVal) {
this.datePickerSearchFlag--;
if (this.datePickerSearchFlag == 0) {
this.datePickerSearchFlag = 1;
this.setPageData({ isFind: true });
}
},
toDtValue(newVal, oldVal) {
this.datePickerSearchFlag--;
if (this.datePickerSearchFlag == 0) {
this.datePickerSearchFlag = 1;
this.setPageData({ isFind: true });
}
},
// datepicker_watch[끝]
initFlag(val) {
if (val) {
this.init();
}
},
},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
created() {},
mounted() {
this.tuiCalendarInit();
// this.init();
},
methods: {
...mapMutations({
setPageData: 'setPageData',
setGridData: 'setGridData',
setGridColumn: 'setGridColumn',
setGridOption: 'setGridOption',
setChartXAxisData: 'setChartXAxisData',
setChartSeries: 'setChartSeries',
setChartOption: 'setChartOption',
}),
...mapActions({
postApi: 'modules/list/postApi',
postUpdateApi: 'modules/list/postUpdateApi',
postApiReturn: 'modules/list/postApiReturn',
setTree: 'modules/list/setTree',
chkOpenTabList: 'chkOpenTabList',
}),
init() {
this.layoutInit();
this.gridInit();
},
setLocalStorage() {
if (this.pageData.energyCd !== '' && this.pageData.energyCd != null) {
localStorage.setItem(
myPrgmId + 'SelectedEnergyCd',
this.pageData.energyCd,
);
}
if (this.pageData.blocId !== '' && this.pageData.blocId != null) {
localStorage.setItem(myPrgmId + 'SelectedBlocCd', this.pageData.blocId);
}
},
tuiCalendarInit() {
const startContainer = document.getElementById('startpicker-container');
const startTarget = document.getElementById('startpicker');
const endContainer = document.getElementById('endpicker-container');
const endTarget = document.getElementById('endpicker');
// datepicker 초기값 생성
var day1 = new Date();
var day2 = new Date();
day2.setFullYear(day1.getFullYear() - 1);
this.startDtValue = setDateWithFormat(day1, 'year');
this.endDtValue = setDateWithFormat(day2, 'year');
this.pageData.cmCycle = 'CYC_MONTH';
// datepicker 초기값 생성 끝
// datepicker 생성
this.startDatepickerInstance = new TuiDatepicker(startContainer, {
date: day1,
language: 'ko',
type: this.myOptions.type,
input: {
element: startTarget,
format: this.myOptions.pickerFormat,
},
timePicker: this.timePicker,
});
// datepicker 생성
this.endDatepickerInstance = new TuiDatepicker(endContainer, {
date: day2,
language: 'ko',
type: this.myOptions.type,
input: {
element: endTarget,
format: this.myOptions.pickerFormat,
},
timePicker: this.timePicker,
});
// datepicker 생성 끝
// datepicker 변경시 이벤트 추가
this.startDatepickerInstance.on('change', () => this.getStartDt());
this.endDatepickerInstance.on('change', () => this.getEndDt());
},
layoutInit() {
const searchFilterHeight = this.$refs.searchFilter.offsetHeight;
this.$refs.contents.style.height = `calc(100% - ${searchFilterHeight}px)`;
},
async search() {
this.setLocalStorage();
await this.getGridDatas();
},
async initUnit() {
this.unit = this.pageData.energyList[this.pageData.energyCd].unit;
},
async gridInit() {
const gridHeight = this.$refs.gridParent.offsetHeight - 36;
const myOptions = {};
this.setGridOption({
gridKey: this.gridName,
value: Object.assign(Utility.defaultGridOption(gridHeight), myOptions),
});
await this.getGridDatas();
this.initUnit();
},
async getGridDatas() {
this.loadChart = false;
this.pageData.rowGrid.data = [];
var res = [];
var apiKeymapper = {
CYC_MONTH: 'selectSameReadPlcMonth',
CYC_WEEK: 'selectSameReadPlcWeek',
CYC_DAY: 'selectSameReadPlcDay',
CYC_HOUR: 'selectSameReadPlcTime',
};
this.apiKey = apiKeymapper[this.pageData.cmCycle];
if (
this.pageData.blocMstrList.length > 0 &&
this.pageData.energyList.length > 0
) {
const selectFacInfo = this.pageData.facInfo;
const sendParams = {
blocId: this.pageData.blocMstrList[this.chkBlocCd].blocId, //"BL0001",
readPlc: selectFacInfo.readPlc,
readPlcNm: selectFacInfo.readPlcNm,
sh_baseDt: this.fromDtValue.replaceAll('-', ''),
sh_compareDt: this.toDtValue.replaceAll('-', ''),
};
this.loadGrid = false;
res = await this.postApiReturn({
apiKey: this.apiKey,
resKey: 'sameReadPlcData',
sendParam: sendParams,
});
} else {
this.setPageData({ isFind: false });
}
let myColumns = [{ header: '구분', name: 'readPlcNm', align: 'center' }];
let timeList = [
{
header: '연도',
name: 'date',
align: 'center',
formatter({ value }) {
if (String(value).length == 4) {
return value + '년';
} else {
return value;
}
},
},
{
header: '주차',
name: 'week',
align: 'center',
formatter({ value }) {
return value;
},
},
{
header: '월',
name: 'date',
align: 'center',
formatter({ value }) {
if (String(value).length == 6) {
return value.substr(0, 4) + '/' + value.substr(4, 2);
} else {
return value;
}
},
},
{
header: '일',
name: 'date',
align: 'center',
formatter({ value }) {
if (String(value).length == 8) {
return (
value.substr(0, 4) +
'/' +
value.substr(4, 2) +
'/' +
value.substr(6, 2)
);
} else {
return value;
}
},
},
];
switch (this.pageData.cmCycle) {
case 'CYC_MONTH':
myColumns.push(timeList[0]);
for (var i = 1; i < 13; i++) {
var tempObject = {
header: i + '월',
name: 'corrVal' + String(i).padStart(2, '0'),
// width : 150,
align: 'right',
formatter: numberFormatter,
};
myColumns.push(tempObject);
}
break;
case 'CYC_WEEK':
myColumns.push(timeList[1]);
var headerList = [
'일요일',
'월요일',
'화요일',
'수요일',
'목요일',
'금요일',
'토요일',
];
for (var i = 1; i < 8; i++) {
var tempObject = {
header: headerList[i - 1],
name: 'corrVal' + String(i).padStart(2, '0'),
// width : 150,
align: 'right',
formatter: numberFormatter,
};
myColumns.push(tempObject);
}
break;
case 'CYC_DAY':
myColumns.push(timeList[2]);
for (var i = 1; i < 32; i++) {
var tempObject = {
header: i + '일',
name: 'corrVal' + String(i).padStart(2, '0'),
// width : 150,
align: 'right',
formatter: numberFormatter,
};
myColumns.push(tempObject);
}
break;
case 'CYC_HOUR':
myColumns.push(timeList[3]);
for (var i = 0; i < 24; i++) {
var tempObject = {
header: i + '시',
name: 'corrVal' + String(i).padStart(2, '0'),
// width : 70,
align: 'right',
formatter: numberFormatter,
};
myColumns.push(tempObject);
}
break;
}
myColumns.push({
header: '합계',
name: 'corrVal',
width: 50,
align: 'right',
});
if (res.length >= 1) {
// 기준일 <-> 비교일 순서 보정[시작]
var tempRes = [...res];
var tempIdx;
res = [];
for (var i = 0; i < tempRes.length ? tempRes.length : 0; i++) {
if (tempRes[i].date == this.toDtValue.replaceAll('-', '')) {
res.push({ ...tempRes[i] });
} else {
tempIdx = i;
}
}
if (typeof tempIdx == 'number') {
res.push({ ...tempRes[tempIdx] });
}
// 기준일 <-> 비교일 순서 보정[끝]
var sumData = {
readPlcNm: res[0].readPlcNm,
};
var columnList = Object.keys(res[0]);
columnList = columnList.filter(item => item.startsWith('corrVal'));
switch (this.pageData.cmCycle) {
case 'CYC_MONTH':
sumData[timeList[0].name] = '차이(기준-비교)';
break;
case 'CYC_WEEK':
sumData[timeList[1].name] = '차이(기준-비교)';
break;
case 'CYC_DAY':
sumData[timeList[2].name] = '차이(기준-비교)';
break;
case 'CYC_HOUR':
sumData[timeList[3].name] = '차이(기준-비교)';
break;
}
if (res.length >= 2) {
for (var i = 0; i < columnList.length; i++) {
sumData[columnList[i]] = res[0][columnList[i]];
}
for (var i = 0; i < columnList.length; i++) {
sumData[columnList[i]] =
Math.round(
(sumData[columnList[i]] - res[1][columnList[i]]) * 100,
) / 100;
}
} else {
for (var i = 0; i < columnList.length; i++) {
sumData[columnList[i]] = res[0][columnList[i]];
}
}
res.push(sumData);
Object.assign(res[0], {
_attributes: { rowSpan: { readPlcNm: res.length } },
});
}
this.setGridColumn({
gridKey: this.gridName,
value: myColumns,
});
this.setGridData({
gridKey: this.gridName,
value: res,
});
this.loadGrid = true;
this.setPageData({ isFind: false });
this.setChartData(res);
},
async setChartData(data) {
let copiedData = [...data];
let xAxisData = [];
let seriesData = [];
this.$store.state.pageData[this.myPrgmId].rowGridChart.series = [];
if (!data.length) {
return;
}
let tmpLsit = [];
let exceptionColumList = [
'구분',
'연도',
'월',
'주차',
'월',
'일',
'합계',
];
const myKey = this.pageData[this.gridName].column.filter(v => {
return !exceptionColumList.includes(v.header);
});
copiedData.pop();
tmpLsit = copiedData.map(item => ({
// name: item.plcNm,
name: item.date,
type: 'line',
data: myKey.map(obj => item[obj.name] || 0),
}));
xAxisData = myKey.map(obj => obj.header);
seriesData = tmpLsit;
// this.setChartXAxisData({ chartKey: "rowGridChart", value: xAxisData });
// this.setChartSeries({ chartKey: "rowGridChart", value: seriesData });
var chartOption = {
legend: {
top: 'center',
left: 'right',
orient: 'vertical',
textStyle: {
color: '#95A0A9',
fontSize: 10,
},
},
grid: {
top: '3%',
right: '8%',
},
yAxis: {
type: 'value',
nameLocation: 'middle',
nameGap: 40,
name: this.unit,
},
xAxis: {
data: xAxisData,
},
series: seriesData,
};
this.setChartOption({ chartKey: 'rowGridChart', value: chartOption });
this.loadChart = true;
},
getStartDt() {
const dt = this.startDatepickerInstance.getDate();
this.startDtValue = setDateWithFormat(dt, this.myOptions.type);
},
getEndDt() {
const dt = this.endDatepickerInstance.getDate();
this.endDtValue = setDateWithFormat(dt, this.myOptions.type);
},
},
};
const defaultData = {
/* 검색옵션 */
isMulti: false,
isFind: false,
blocId: null,
blocMstrList: [],
energyCd: null,
energyList: [],
cmCycle: 'CYC_MONTH', // 주기
cmCycleList: [
{ idx: 0, text: '월', value: 'CYC_MONTH' },
{ idx: 1, text: '주', value: 'CYC_WEEK' },
{ idx: 2, text: '일', value: 'CYC_DAY' },
{ idx: 3, text: '시간', value: 'CYC_HOUR' },
],
defaultRange: {
CYC_MONTH: 12,
CYC_WEEK: 7,
CYC_DAY: 31,
CYC_HOUR: 0,
},
fromDt: '',
toDt: '',
dateFormat: {
CYC_MONTH: 'YYYY',
CYC_WEEK: 'YYYY-MM-DD',
CYC_DAY: 'YYYY-MM',
CYC_HOUR: 'YYYY-MM-DD',
},
tableId: null,
gridId: null,
facInfo: {},
modalData: {},
rowGrid: {
data: [],
option: {}, // myOptions
column: [], // myColumns,
},
rowGridChart: Utility.defaultChartOption(true),
xlsFileInfo: {
rowGrid: {
fileName: null,
sheetName: null,
},
},
};
function setDateWithFormat(date, format) {
var formattedDate = null;
if (typeof date == 'string') {
formattedDate = date;
} else if (typeof date == 'object') {
formattedDate = String(date.toISOString());
}
if (format == 'year') {
formattedDate = formattedDate.substr(0, 4);
} else if (format == 'month') {
formattedDate = formattedDate.substr(0, 7);
} else if (format == 'date') {
formattedDate = formattedDate.substr(0, 10);
}
return formattedDate;
}
function numberFormatter({ value }) {
return Utility.setFormatIntDecimal(value, 2);
}
function myLogger(msg, caller) {
if (caller) {
}
if (msg.title) {
}
if (msg.content) {
}
if (typeof msg === 'string') {
}
}
</script>
<style lang="scss" scoped>
#startpicker-container,
#endpicker-container {
position: relative;
z-index: 20;
}
.v-input__custom {
flex: 0 0 auto;
&.half {
width: calc(50% - 20px);
}
}
::v-deep {
.tui-timepicker-row {
display: flex;
justify-content: space-around;
background-color: #edf4fc;
.tui-timepicker-column.tui-timepicker-colon {
color: #000 !important;
}
}
}
</style>

View File

@ -0,0 +1,694 @@
<template>
<div class="l-layout">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="3">
<component
:is="'SelectBlocMstr'"
ref="SelectBlocMstr"
:parentPrgmId="myPrgmId"
/>
</v-col>
<v-col :cols="3">
<component
label="에너지"
:is="'SelectEnergy'"
:parentPrgmId="myPrgmId"
/>
</v-col>
<v-col :cols="3">
<!-- 구분(사용량, 비용) -->
<component :is="'RadioUseCost'" :parentPrgmId="myPrgmId" />
</v-col>
<v-col :cols="3" class="text-right">
<BtnSearch @click="search" />
<BtnExcelDownload
style="vertical-align: middle;"
class="d-inline-flex"
:parentPrgmId="myPrgmId"
:gridName="gridName"
/>
</v-col>
</v-row>
<v-row align="center" no-gutters>
<v-col :cols="3">
<component :is="'SelectCmCycle'" :parentPrgmId="myPrgmId" />
</v-col>
<v-col :cols="3">
<!-- 조회기간 -->
<DatePicker :parentPrgmId="myPrgmId" :label="'조회기간'" />
</v-col>
<v-col :cols="4">
<!-- 공정/설비 -->
<component
label="비교대상"
:is="'FtnPlcMultiPop'"
:parentPrgmId="myPrgmId"
:labelCols="3"
:textCols="9"
/>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents" style="height: calc(100vh - 230px)">
<v-col>
<v-card>
<div ref="chartParent" style="height: 65%">
<component
class="w100 h100"
ref="chart1"
:is="loadChart1 ? 'Chart' : null"
:chartName="chartName"
:parentPrgmId="myPrgmId"
/>
</div>
<v-card-title>
<!-- 차트와 그리드 사이 공백을 위한 공간 -->
</v-card-title>
<div ref="gridParent" class="px-5" style="height: 28%">
<component
class="w100 h100"
ref="grid1"
:is="loadGrid1 ? 'Grid' : null"
:gridName="gridName"
:parentPrgmId="myPrgmId"
/>
</div>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex';
import BtnSearch from '~/components/common/button/BtnSearch';
import BtnExcelDownload from '~/components/common/button/BtnExcelDownload';
import SelectEnergy from '@/components/common/select/SelectEnergyForPop';
import SelectBlocMstr from '@/components/common/select/SelectBlocMstrForPop';
import SelectCmCycle from '@/components/common/select/SelectCmCycle';
import SelectDate from '~/components/common/select/SelectDate';
import SelectDateVc from '~/components/common/select/SelectDateVc';
import DatePicker from '~/components/common/Datepicker';
import FtnPlcMultiPop from '~/components/common/modal/FtnPlcMultiPop2';
import InputText from '@/components/common/input/InputText';
import RadioUseCost from '~/components/common/RadioUseCost';
import Utility from '~/plugins/utility';
import dateUtility from '~/plugins/dateUtility';
import Grid from '~/components/common/Grid';
import Chart from '~/components/common/Chart';
let myTitle;
let myPrgmId;
export default {
async asyncData(context) {
const myState = context.store.state;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
BtnSearch,
BtnExcelDownload,
SelectBlocMstr,
SelectEnergy,
SelectCmCycle,
SelectDate,
SelectDateVc,
RadioUseCost,
DatePicker,
FtnPlcMultiPop,
InputText,
Utility,
dateUtility,
Grid,
Chart,
},
data() {
return {
myPrgmId: myPrgmId,
myGrid: null,
gridName: 'grid1',
chartName: 'chart1',
loadGrid1: false,
loadChart1: false,
apiKey: 'selectSameTermReadHour',
unit: '',
};
},
computed: {
...mapState({
pageData: state => state.pageData[myPrgmId],
}),
rdbUseCost: {
get() {
return this.pageData[this.parentPrgmId].rdbUseCost;
},
set(value) {
return this.setPageData({ rdbUseCost: value });
},
},
chkIsFind() {
// 조회 플래그
return this.pageData.isFind;
},
chkBlocCd() {
// 사업장 선택 감지
return this.pageData.blocId;
},
chkEnergyCd() {
// 에너지 선택 감지
return this.pageData.energyCd;
},
chkFacInfo() {
// 공정/설비 변경 감지
return this.pageData.facInfoList;
},
chkCmCycle() {
// 주기 변경 감지
return this.pageData.cmCycle;
},
chkRadio() {
// 구분: 사용량, 비용 선택 감지
return this.pageData.rdbUseCost;
},
initFlag() {
if (
this.pageData.energyList.length > 0 &&
this.pageData.blocMstrList.length > 0
) {
return true;
} else {
return false;
}
},
},
watch: {
chkIsFind(val) {
if (val) this.search();
},
chkBlocCd() {
//지우지말자
},
chkEnergyCd() {
this.initUnit();
},
chkFacInfo() {
this.setPageData({ isFind: true });
},
chkRadio() {
this.initUnit();
this.setPageData({ isFind: true });
},
initFlag(val) {
if (val) {
this.init();
}
},
},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
mounted() {},
methods: {
...mapMutations({
setPageData: 'setPageData',
setGridData: 'setGridData',
setGridColumn: 'setGridColumn',
setGridOption: 'setGridOption',
setChartXAxisData: 'setChartXAxisData',
setChartSeries: 'setChartSeries',
setChartOption: 'setChartOption',
}),
...mapActions({
postApi: 'modules/list/postApi',
postUpdateApi: 'modules/list/postUpdateApi',
postApiReturn: 'modules/list/postApiReturn',
setTree: 'modules/list/setTree',
chkOpenTabList: 'chkOpenTabList',
}),
init() {
this.layoutInit();
this.gridInit();
},
layoutInit() {
const searchFilterHeight = this.$refs.searchFilter.offsetHeight;
this.$refs.contents.style.height = `calc(100% - ${searchFilterHeight}px)`;
},
async search() {
await this.getRowGridData();
if (this.pageData.energyCd !== '' && this.pageData.energyCd != null) {
localStorage.setItem(
myPrgmId + 'SelectedEnergyCd',
this.pageData.energyCd,
);
}
if (this.pageData.blocId !== '' && this.pageData.blocId != null) {
localStorage.setItem(myPrgmId + 'SelectedBlocCd', this.pageData.blocId);
}
},
initUnit() {
this.unit =
this.pageData.energyList.length > 0 && this.pageData.rdbUseCost == 'use'
? this.pageData.energyList[this.pageData.energyCd].unit
: '원';
},
gridInit() {
setTimeout(() => {
const gridHeight = this.$refs.gridParent.offsetHeight - 46;
const myOptions = {
setScroll: true,
columnOptions: {
//frozenCount: 3,
minWidth: 100,
resizable: true,
},
};
this.setGridOption({
gridKey: this.gridName,
value: Object.assign(
Utility.defaultGridOption(gridHeight),
myOptions,
),
});
this.getRowGridData();
this.initUnit();
});
},
async getRowGridData() {
this.loadGrid1 = false;
this.loadChart1 = false;
this.pageData.grid1.data = [];
var url = {};
if (this.pageData.cmCycle == 'CYC_YEAR') {
url =
this.pageData.rdbUseCost == 'use'
? 'selectSameTermReadYear'
: 'selectSameTermReadYearCost';
} else if (this.pageData.cmCycle == 'CYC_MONTH') {
url =
this.pageData.rdbUseCost == 'use'
? 'selectSameTermReadMonth'
: 'selectSameTermReadMonthCost';
} else if (this.pageData.cmCycle == 'CYC_DAY') {
url =
this.pageData.rdbUseCost == 'use'
? 'selectSameTermReadDay'
: 'selectSameTermReadDayCost';
} else {
url =
this.pageData.rdbUseCost == 'use'
? 'selectSameTermReadHour'
: 'selectSameTermReadHourCost';
}
this.apiKey = url;
var temp = [],
temp2 = [],
res = [];
const facInfoList = this.pageData.facInfoList;
if (facInfoList.length > 0) {
for (var i = 0; i < facInfoList.length; i++) {
temp.push(facInfoList[i].eccId);
temp2.push(facInfoList[i].eccNm);
}
}
let myColumns = [
{ header: '번호', name: 'rowNum', align: 'center', width: 50 },
{ header: '에너지', name: 'readObjNm', align: 'center', width: 100 },
{ header: '구분', name: 'eccNm', align: 'left', width: 150 },
];
switch (this.pageData.cmCycle) {
case 'CYC_YEAR':
var dateDiff =
dateUtility.diff(this.pageData.fromDt, this.pageData.toDt, 'y') + 1;
for (var i = 0; i < 10; i++) {
if (i < dateDiff) {
var tempObject = {
header: dateUtility.addYear(i, 'YYYY', this.pageData.fromDt),
name: 'qty' + String(i).padStart(2, '0'),
align: 'right',
width: 100,
excelType: 'number',
excelFormatter: '2',
formatter({ value }) {
return Utility.setFormatIntDecimal(value, 2);
},
};
myColumns.push(tempObject);
}
}
break;
case 'CYC_MONTH':
var dateDiff =
dateUtility.diff(this.pageData.fromDt, this.pageData.toDt, 'm') + 2;
for (var i = 1; i < 13; i++) {
if (i < dateDiff) {
var tempObject = {
header: dateUtility.addMonth(
i - 1,
'YYYY/MM',
this.pageData.fromDt,
),
name: 'qty' + String(i).padStart(2, '0'),
align: 'right',
width: 100,
excelType: 'number',
excelFormatter: '2',
formatter({ value }) {
return Utility.setFormatIntDecimal(value, 2);
},
};
myColumns.push(tempObject);
}
}
break;
case 'CYC_DAY':
var dateDiff =
dateUtility.diff(this.pageData.fromDt, this.pageData.toDt) + 2;
for (var i = 1; i < 32; i++) {
if (i < dateDiff) {
var tempObject = {
header: dateUtility.addDate(
i - 1,
'MM/DD',
this.pageData.fromDt,
),
name: 'qty' + String(i).padStart(2, '0'),
align: 'right',
width: 100,
excelType: 'number',
excelFormatter: '2',
formatter({ value }) {
return Utility.setFormatIntDecimal(value, 2);
},
};
myColumns.push(tempObject);
}
}
break;
case 'CYC_HOUR':
for (var i = 0; i < 24; i++) {
var tempObject = {
header: i + '시',
name: 'qty' + String(i).padStart(2, '0'),
align: 'right',
width: 100,
excelType: 'number',
excelFormatter: '2',
formatter({ value }) {
return Utility.setFormatIntDecimal(value, 2);
},
};
myColumns.push(tempObject);
}
break;
}
var qtyList = [];
for (i = 0; i < myColumns.length - 3; i++) {
if (this.pageData.cmCycle == 'CYC_YEAR') {
var val = parseInt(this.pageData.fromDt) + i;
var val2 = 'QTY' + String(i).padStart(2, '0');
qtyList.push({ qty: val, as: val2 });
} else if (this.pageData.cmCycle == 'CYC_MONTH') {
var val =
this.pageData.fromDt.substr(0, 4) +
'-' +
this.pageData.fromDt.substr(4, 2);
var val1 = new Date(val);
val1.setMonth(val1.getMonth() + i);
var val2 = val1
.toISOString()
.replaceAll('-', '')
.substr(0, 4);
var val3 = val1
.toISOString()
.replaceAll('-', '')
.substr(4, 2);
var val4 = 'QTY' + String(i + 1).padStart(2, '0');
qtyList.push({ qtyY: val2, qtyM: val3, as: val4 });
} else if (this.pageData.cmCycle == 'CYC_DAY') {
var val =
this.pageData.fromDt.substr(0, 4) +
'-' +
this.pageData.fromDt.substr(4, 2) +
'-' +
this.pageData.fromDt.substr(6, 2);
var val1 = new Date(val);
val1.setDate(val1.getDate() + i);
var val2 =
val1
.toISOString()
.replaceAll('-', '')
.substr(0, 4) +
val1
.toISOString()
.replaceAll('-', '')
.substr(4, 2) +
val1
.toISOString()
.replaceAll('-', '')
.substr(6, 2);
var val3 = 'QTY' + String(i + 1).padStart(2, '0');
qtyList.push({ qty: val2, as: val3 });
} else {
qtyList = [];
}
}
if (
this.pageData.blocMstrList.length > 0 &&
this.pageData.energyList.length > 0
) {
const sendParams = {
blocId: this.pageData.blocMstrList[this.chkBlocCd].blocId,
sh_blocCd:
this.pageData.cmCycle == 'CYC_DAY'
? this.pageData.blocMstrList[this.chkBlocCd].blocId
: null,
cbEnrgCd: this.pageData.energyList[this.chkEnergyCd].cd,
readObjId: this.pageData.energyList[this.chkEnergyCd].cd,
cmCycle:
this.pageData.cmCycle == 'CYC_YEAR'
? 'year'
: this.pageData.cmCycle == 'CYC_MONTH'
? 'month'
: this.pageData.cmCycle == 'CYC_DAY'
? 'day'
: 'hour',
eqpmId: temp,
eqpmNm: temp2,
menuList: temp.join(),
qtyList: qtyList,
fromObjDt:
this.pageData.cmCycle == 'CYC_HOUR'
? this.pageData.fromDt.substr(0, 4) +
'-' +
this.pageData.fromDt.substr(4, 2) +
'-' +
this.pageData.fromDt.substr(6, 2)
: this.pageData.fromDt,
sh_startDt:
this.pageData.cmCycle == 'CYC_DAY'
? this.pageData.fromDt.substr(0, 4) +
'-' +
this.pageData.fromDt.substr(4, 2) +
'-' +
this.pageData.fromDt.substr(6, 2)
: null,
toObjDt:
this.pageData.cmCycle == 'CYC_HOUR'
? this.pageData.fromDt
: this.pageData.toDt,
sh_endDt:
this.pageData.cmCycle == 'CYC_DAY'
? this.pageData.toDt.substr(0, 4) +
'-' +
this.pageData.toDt.substr(4, 2) +
'-' +
this.pageData.toDt.substr(6, 2)
: null,
};
if (this.pageData.facInfoList.length > 0) {
res = await this.postApiReturn({
apiKey: this.apiKey,
resKey: 'sameTermReadDataList',
sendParam: sendParams,
});
}
} else {
this.setPageData({ isFind: false });
}
for (i = 0; i < res.length; i++) {
Object.assign(res[i], {
_attributes: { rowSpan: { readObjNm: res.length } },
});
}
this.setGridColumn({
gridKey: this.gridName,
value: myColumns,
});
this.setGridData({
gridKey: this.gridName,
value: res,
});
this.loadGrid1 = true;
this.setPageData({ isFind: false });
this.$nextTick(() => {
if (this.loadGrid1) {
this.setChartData(res);
}
});
},
async setChartData(data) {
let xAxisData = [];
let seriesData = [];
let seriesDataList = [];
const myKey = this.pageData[this.gridName].column.filter(v => {
return (
v.header !== '번호' && v.header !== '에너지' && v.header !== '구분'
);
});
seriesDataList = data.map(item => ({
name: item.eccNm,
type: 'line',
data: myKey.map(obj => item[obj.name] || 0),
}));
xAxisData = myKey.map(obj => obj.header);
seriesData = seriesDataList;
function setChartOption(chartName, unitVal) {
var option = {
grid: {},
xAxis: {
type: 'category',
data: xAxisData,
},
yAxis: {
type: 'value',
nameLocation: 'middle',
nameGap: 50,
name: unitVal,
axisLabel: {
textStyle: {
fontSize: 10,
},
},
},
legend: {},
series: seriesData,
};
return option;
}
this.setChartOption({
chartKey: 'chart1',
value: setChartOption('chart1', this.unit),
});
this.loadChart1 = true;
},
},
};
const defaultData = {
/* 검색옵션 */
isFind: false, // true 경우 조회, 조회버튼도 이 값으로 연동 예정
blocId: null, // 사업장
blocMstrList: [],
energyCd: '',
energyList: [],
rdbUseCost: 'use',
cmCycle: 'CYC_HOUR', // 주기
cmCycleList: [
{ idx: 0, text: '연', value: 'CYC_YEAR' },
{ idx: 1, text: '월', value: 'CYC_MONTH' },
{ idx: 2, text: '일', value: 'CYC_DAY' },
{ idx: 3, text: '시간', value: 'CYC_HOUR' },
],
defaultRange: {
CYC_YEAR: 10,
CYC_MONTH: 12,
CYC_DAY: 30,
CYC_HOUR: 0,
},
// popup 설정
isMulti: true, //checkBox
facInfo: {},
facInfoList: [], // 선택된 공정/설비 데이타 리스트
modalData: {}, // 모달 관련 데이타 저장소
fromDt: '',
toDt: '',
/* Grid data 세팅 */
// 로컬 gridName 값과 동일한 이름으로 세팅
grid1: {
data: [],
column: [], // myColumns,
option: {}, // myOptions
defaultRow: {},
},
// chart 설정
chart1: Utility.defaultChartOption(true),
// 선택된 그룹코드 상세 데이터
xlsFileInfo: {
// 출력하려는 grid 와 같은 이름으로 세팅
grid1: {
fileName: null, // 갑이 없으면 해당 페이지 메뉴명
sheetName: null, // 갑이 없으면 'Sheet1'
},
},
};
</script>
<style lang="scss">
@import '@/assets/scss/common.scss';
</style>

View File

@ -0,0 +1,666 @@
<template>
<div class="l-layout">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="3">
<!-- 사업장 -->
<component
:is="'SelectBlocMstr'"
:parentPrgmId="myPrgmId"
valueNm="blocNm"
/>
</v-col>
<v-col :cols="3">
<!-- 에너지 -->
<component
:is="'SelectEnergy'"
:parentPrgmId="myPrgmId"
:label="'에너지'"
/>
</v-col>
<v-col :cols="3">
<!-- 주기 -->
<component :is="'SelectCmCycle'" :parentPrgmId="myPrgmId" />
</v-col>
<v-col :cols="3" class="text-right">
<!-- 조회버튼 -->
<BtnSearch @click="search" />
<BtnExcelDownload
style="vertical-align: middle;"
class="d-inline-flex"
:parentPrgmId="myPrgmId"
:gridName="grid_01"
/>
</v-col>
</v-row>
<v-row align="center" no-gutters>
<v-col :cols="3">
<!-- 조회기간 -->
<!-- <component :is="swichDatePicker" :parentPrgmId="myPrgmId" /> -->
<component
:is="'Datepicker'"
:parentPrgmId="myPrgmId"
:label="'조회기간'"
/>
</v-col>
<v-col :cols="7">
<!-- 공정/설비 -->
<component
:is="'OutSideWeatherPlcPop'"
:parentPrgmId="myPrgmId"
/>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents">
<v-col :cols="12" style="height: 65%">
<v-card class="pa-5">
<component
class="w100 h100"
:is="loadChart_01 ? 'Chart' : null"
:parentPrgmId="myPrgmId"
:chartName="chart_01"
ref="chart_01"
/>
</v-card>
</v-col>
<v-col :cols="12" style="height: 35%">
<v-card class="pb-5">
<v-card-title class="justify-end caption text-color--non-activate"
>단위 : {{ unit }}
</v-card-title>
<div ref="gridParent" class="px-5" style="height: calc(100% - 70px)">
<component
ref="grid_01"
:is="loadGrid_01 ? 'Grid' : null"
:gridName="grid_01"
:parentPrgmId="myPrgmId"
/>
</div>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex';
import mixinGlobal from '@/mixin/global';
import SelectCmCycle from '@/components/common/select/SelectCmCycle';
import SelectEnergy from '@/components/common/select/SelectEnergyForPop';
import SelectBlocMstr from '@/components/common/select/SelectBlocMstrForPop';
import OutSideWeatherPlcPop from '~/components/common/modal/OutSideWeatherPlcMultiPop';
import BtnSearch from '~/components/common/button/BtnSearch';
import Grid from '~/components/common/Grid';
import Datepicker from '~/components/common/Datepicker';
import BtnExcelDownload from '~/components/common/button/BtnExcelDownload';
import Chart from '~/components/common/Chart';
import SelectMttGrp from '@/components/common/select/SelectMttGrp';
import SelectUseFg from '@/components/common/select/SelectUseFg';
import SelectUnit from '@/components/common/select/SelectUnit';
import SelectEqpmGrpKind from '@/components/common/select/SelectEqpmGrpKind';
import InputText from '@/components/common/input/InputText';
import InputTextPassword from '@/components/common/input/InputTextPassword';
import InputRmrk from '@/components/common/input/InputRmrk';
import Utility from '~/plugins/utility';
import DateUtility from '~/plugins/dateUtility';
// import ChangePassword from "~/components/common/modal/ChangePassword";
let myTitle;
let myPrgmId;
export default {
async asyncData(context) {
const myState = context.store.state;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
mixins: [mixinGlobal],
components: {
Grid,
SelectEnergy,
SelectCmCycle,
SelectBlocMstr,
BtnSearch,
OutSideWeatherPlcPop,
BtnExcelDownload,
Chart,
Datepicker,
SelectMttGrp,
SelectUseFg,
SelectUnit,
SelectEqpmGrpKind,
InputText,
InputTextPassword,
InputRmrk,
// ChangePassword
},
data() {
return {
myPrgmId: myPrgmId,
grid_01: 'readPlcGrid', // defaultData랑 맞춰야 됨
chart_01: 'readPlcChart',
loadGrid_01: false,
loadChart_01: false,
apiKey: 'selectSameTermReadPlcHour',
unit: '',
};
},
computed: {
...mapState({
pageData: state => state.pageData[myPrgmId],
}),
swichDatePicker() {
let picker = 'SelectDateVc';
if (
this.pageData.cmCycle == 'CYC_MONTH' ||
this.pageData.cmCycle == 'CYC_YEAR'
) {
picker = 'SelectDate';
}
return picker;
},
chkIsFind() {
// 조회 플래그
return this.pageData.isFind;
},
chkBlocCd: function() {
// 사업장 선택 감지
//this.selectBoxEvt();
return this.pageData.blocId;
},
chkEnergyCd() {
// 에너지 선택 감지
//this.selectBoxEvt();
return this.pageData.energyCd;
},
chkFacInfo() {
// 공정/설비 변경 감지
return this.pageData.facInfoList;
},
initFlag() {
if (
this.pageData.energyList.length > 0 &&
this.pageData.blocMstrList.length > 0
) {
return true;
} else {
return false;
}
},
},
watch: {
chkIsFind(val) {
if (val) this.search();
},
chkBlocCd() {
//this.setPageData({ isFind: true });
},
chkEnergyCd() {
this.initUnit();
//this.setPageData({ isFind: true });
},
chkFacInfo() {
this.setPageData({ isFind: true });
},
initFlag(val) {
if (val) {
this.init();
}
},
},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
// this.pageData.facInfoList = localStorage.getItem(myPrgmId + "CheckedRow") !=null ? JSON.parse(localStorage.getItem(myPrgmId + "CheckedRow")) : [] // 선택된 공정/설비 데이타 리스트
},
mounted() {
//this.init();
},
beforeDestroy() {
this.chkOpenTabList({ key: 'destroy', prgmId: myPrgmId });
},
methods: {
...mapMutations({
setPageData: 'setPageData',
setGridData: 'setGridData',
setGridColumn: 'setGridColumn',
setGridOption: 'setGridOption',
setChartOption: 'setChartOption',
}),
...mapActions({
postApi: 'modules/list/postApi',
postUpdateApi: 'modules/list/postUpdateApi',
postApiReturn: 'modules/list/postApiReturn',
setTree: 'modules/list/setTree',
chkOpenTabList: 'chkOpenTabList',
}),
async init() {
// await this.layoutInit();
await this.gridInit();
},
async initUnit() {
this.unit = this.pageData.energyList[this.pageData.energyCd].unit;
},
async gridInit() {
const gridHeight = this.$refs.gridParent.offsetHeight - 36;
const isRange =
this.pageData.defaultRange[this.pageData.cmCycle] === 0 ? false : true;
// const gridHeight = this.$refs.contents.offsetHeight - 30;
const myOptions = {
scrollX: false,
};
this.setGridOption({
gridKey: this.grid_01,
value: Object.assign(Utility.defaultGridOption(gridHeight), myOptions),
});
await this.getRowGridData();
},
async search() {
await this.setPageData({
isFind: false,
});
await this.getRowGridData();
if (this.pageData.energyCd !== '' && this.pageData.energyCd != null) {
localStorage.setItem(
myPrgmId + 'SelectedEnergyCd',
this.pageData.energyCd,
);
}
if (this.pageData.blocId !== '' && this.pageData.blocId != null) {
localStorage.setItem(myPrgmId + 'SelectedBlocCd', this.pageData.blocId);
}
// await this.getRowGridData2(); // tab2
},
async getRowGridData() {
this.loadGrid_01 = false;
this.loadChart_01 = false;
let diffTime;
var apiKeymapper = {
CYC_YEAR: 'selectSameTermReadPlcYear',
CYC_MONTH: 'selectSameTermReadPlcMonth',
CYC_DAY: 'selectSameTermReadPlcDay',
CYC_HOUR: 'selectSameTermReadPlcHour',
};
this.apiKey = apiKeymapper[this.pageData.cmCycle];
// readPlcList setting
const readPlcCdList = [];
const facInfoList = this.pageData.facInfoList;
if (facInfoList.length > 0) {
for (const item of facInfoList) {
readPlcCdList.push(item.readPlc);
}
}
var sendParams = {};
if (
this.pageData.blocMstrList.length > 0 &&
this.pageData.energyList.length > 0
) {
sendParams = {
blocId: this.pageData.blocMstrList[this.pageData.blocId].blocId,
endDt: this.pageData.toDt,
frDt: this.pageData.fromDt,
readPlcList: readPlcCdList,
};
}
let myColumns = [
{ header: '번호', name: 'rowNum', align: 'center' },
{ header: '구분', name: 'readPlcNm', align: 'left' },
{ header: '검침개소', name: 'readPlc', align: 'left', hidden: true },
{ header: '에너지', name: 'mttCd', align: 'left', hidden: true },
{ header: '공통코드', name: 'comId', align: 'left', hidden: true },
];
// 주기별 qty 파라미터 및 gridHeader 세팅
switch (this.pageData.cmCycle) {
case 'CYC_YEAR':
// diffTime = this.calDiffTime();
diffTime =
DateUtility.diff(this.pageData.fromDt, this.pageData.toDt, 'y') + 1;
for (var i = 0; i < 10; i++) {
let qtyKey;
qtyKey = 'qty' + String(i + 1).padStart(2, '0');
sendParams[qtyKey] = parseInt(parseInt(this.pageData.fromDt) + i);
if (i < diffTime) {
myColumns.push({
header: parseInt(parseInt(this.pageData.fromDt) + i),
name: qtyKey,
align: 'center',
formatter({ value }) {
return Utility.setFormatIntDecimal(value, 2);
},
});
}
}
break;
case 'CYC_MONTH':
diffTime =
DateUtility.diff(this.pageData.fromDt, this.pageData.toDt, 'm') + 1;
for (var i = 0; i < 12; i++) {
let qtyKey;
let tDate;
let tDateVal;
qtyKey = 'qty' + String(i + 1).padStart(2, '0');
tDate = DateUtility.addMonth(i, 'YYYYMM', this.pageData.fromDt);
tDateVal = DateUtility.getDate(tDate);
sendParams[qtyKey] = parseInt(tDate);
if (i < diffTime) {
myColumns.push({
header:
String(tDateVal['$y']) +
'/' +
String(tDateVal['$M'] + 1).padStart(2, '0'),
name: qtyKey,
align: 'center',
formatter({ value }) {
return Utility.setFormatIntDecimal(value, 2);
},
});
}
}
break;
case 'CYC_DAY':
diffTime =
DateUtility.diff(this.pageData.fromDt, this.pageData.toDt, 'd') + 1;
for (var i = 0; i < 31; i++) {
let qtyKey;
let tDate;
let tDateVal;
qtyKey = 'qty' + String(i + 1).padStart(2, '0');
tDate = DateUtility.addDate(i, 'YYYYMMDD', this.pageData.fromDt);
tDateVal = DateUtility.getDate(tDate);
sendParams[qtyKey] = parseInt(tDate);
if (i < diffTime) {
myColumns.push({
header:
String(tDateVal['$M'] + 1).padStart(2, '0') +
'/' +
String(tDateVal['$D']).padStart(2, '0'),
name: qtyKey,
align: 'center',
width: 100,
formatter({ value }) {
return Utility.setFormatIntDecimal(value, 2);
},
});
}
}
break;
case 'CYC_HOUR':
for (var i = 0; i < 24; i++) {
let qtyKey;
qtyKey = 'qty' + String(i + 1).padStart(2, '0');
sendParams['endDt'] = sendParams['frDt'];
myColumns.push({
header: i + '시',
name: qtyKey,
align: 'center',
formatter({ value }) {
return Utility.setFormatIntDecimal(value, 2);
},
});
}
break;
}
let res = [];
if (sendParams.endDt != undefined && sendParams.readPlcList.length > 0) {
res = await this.postApiReturn({
apiKey: this.apiKey,
resKey: 'ddlyReadRsltData',
sendParam: sendParams,
});
} else {
this.setPageData({ isFind: false });
//alert("검침개소 정보가 없습니다.");
}
// const newRes = res.map(item => {
// const newObj = {
// ...item,
// rowStat: null
// };
// return newObj;
// });
this.setGridColumn({
gridKey: this.grid_01,
value: myColumns,
});
this.setGridData({
gridKey: this.grid_01,
value: res,
});
this.loadGrid_01 = true;
this.setPageData({ isFind: false });
this.$nextTick(() => {
if (this.loadGrid_01) {
this.setChartData(res);
}
});
},
async setChartData(data) {
let xAxisData = [];
let seriesData = [];
let seriesDataList = [];
const myKey = this.pageData[this.grid_01].column.filter(v => {
return (
v.header !== '구분' &&
v.header !== '번호' &&
v.header !== '에너지' &&
v.header !== '공통코드' &&
v.header !== '검침개소'
);
});
seriesDataList = data.map(item => ({
name: item.readPlcNm,
type: 'line',
data: myKey.map(obj => item[obj.name] || 0),
}));
xAxisData = myKey.map(obj => obj.header);
seriesData = seriesDataList;
let option = {
grid: {
right: '10%',
},
xAxis: {
type: 'category',
data: xAxisData,
},
legend: {
top: 'center',
left: 'right',
orient: 'vertical',
},
series: seriesData,
};
this.setChartOption({ chartKey: 'readPlcChart', value: option });
this.loadChart_01 = true;
},
// compareData(type, newData) {
// if (this.selectedUserData[type] == newData) {
// return true;
// } else {
// return false;
// }
// },
calDiffTime() {
var toDate;
var fromDate;
if (this.pageData.cmCycle == 'CYC_YEAR') {
return (
parseInt(this.pageData.toDt) - parseInt(this.pageData.fromDt) + 1
);
} else if (this.pageData.cmCycle == 'CYC_MONTH') {
var toDate = new Date(
this.pageData.toDt.substr(0, 4),
this.pageData.toDt.substr(4, 2),
);
var fromDate = new Date(
this.pageData.fromDt.substr(0, 4),
this.pageData.fromDt.substr(4, 2),
);
} else if (this.pageData.cmCycle == 'CYC_DAY') {
var toDate = new Date(
this.pageData.toDt.substr(0, 4),
this.pageData.toDt.substr(4, 2),
this.pageData.toDt.substr(6, 2),
);
var fromDate = new Date(
this.pageData.fromDt.substr(0, 4),
this.pageData.fromDt.substr(4, 2),
this.pageData.fromDt.substr(6, 2),
);
}
toDate.setMonth(toDate.getMonth() - 1);
fromDate.setMonth(fromDate.getMonth() - 1);
var diff = toDate - fromDate;
var cDay = 24 * 60 * 60 * 1000;
var cMonth = cDay * 30;
//var cYear = cMonth * 12;
var typeMapper = {
CYC_MONTH: cMonth,
CYC_DAY: cDay,
};
return parseInt(diff / typeMapper[this.pageData.cmCycle]) + 1;
},
// // 확인하기1
// selectBoxEvt() {
// localStorage.removeItem("SameTermReadPlcCheckedRow");
// this.pageData.facInfoList = [];
// }
},
};
const defaultData = {
/* 검색옵션 */
isFind: false,
blocId: '', // 사업장
//blocId: "BL0001", // 사업장
blocMstrList: [],
energyCd: null, // 에너지
//energyCd: "MTT00001", // 에너지
energyList: [],
cmCycle: 'CYC_HOUR', // 주기
cmCycleList: [
{ idx: 0, text: '연', value: 'CYC_YEAR' },
{ idx: 1, text: '월', value: 'CYC_MONTH' },
{ idx: 2, text: '일', value: 'CYC_DAY' },
{ idx: 3, text: '시간', value: 'CYC_HOUR' },
],
// 각 주기에 따른 기간 max
defaultRange: {
CYC_YEAR: 10,
CYC_MONTH: 12,
CYC_DAY: 30,
CYC_HOUR: 0,
},
// fromDt: "", // 조회 시작일
fromDt: Utility.setFormatDate(new Date(), 'YYYYMMDD'), // 조회 시작일
toDt: '', // 조회 종료일,
// popup 설정
isMulti: true, //checkBox
facInfo: {}, // 선택된 공정/설비 데이타
facInfoList: [], // 선택된 공정/설비 데이타 리스트
modalData: {}, // 모달 관련 데이타 저장소
//
//localStorageKey: "SameTermReadPlcCheckedRow",
/* data 세팅 */
readPlcGrid: {
data: [],
column: [], // myColumns,
option: {}, // myOptions
defaultRow: {},
},
// chart 설정
readPlcChart: Utility.defaultChartOption(true),
xlsFileInfo: {
// 출력하려는 grid 와 같은 이름으로 세팅
readPlcGrid: {
fileName: null, // 갑이 없으면 해당 페이지 메뉴명
sheetName: null, // 갑이 없으면 'Sheet1'
},
},
// selectedRowKey:null,
// selectedUserData: null,
};
function numberFormatter({ value }) {
if (value == null) {
return 0;
} else {
return value;
}
}
function makeDateVal(date, cmCycle) {
let result = '';
var newDate = DateUtility.getDate(date);
result = newDate['$y'];
if (cmCycle == 'CYC_YEAR') return result;
result = result + '-' + String(newDate['$M'] + 1).padStart(2, '0');
if (cmCycle == 'CYC_MONTH') return result;
result = result + '-' + String(newDate['$D']).padStart(2, '0');
return result;
}
</script>
<style lang="scss">
@import '@/assets/scss/common.scss';
</style>

View File

@ -0,0 +1,477 @@
<template>
<div class="l-layout">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="2">
<component
:is="'SelectBlocMstr'"
ref="SelectBlocMstr"
:parentPrgmId="myPrgmId"
/>
</v-col>
<v-col :cols="3">
<component
:is="'selectCodeList'"
:parentPrgmId="myPrgmId"
:label="'검침대상 유형'"
dataKey="readObjKind"
:addAll="true"
:sendParam="{ commGrpCd: 'CM_MTTTP', useFg: '1' }"
/>
</v-col>
<v-col :cols="4">
<component
:is="'RadioStandard'"
:parentPrgmId="myPrgmId"
label="기준"
:labelCols="2"
:textCols="10"
/>
</v-col>
<v-col :cols="3" class="text-right">
<BtnSearch @click="search" />
<BtnExcelDownload
style="vertical-align: middle;"
class="d-inline-flex"
:parentPrgmId="myPrgmId"
:gridName="gridName"
/>
</v-col>
</v-row>
<v-row aling="center" no-gutters>
<v-col :cols="4">
<v-row class="search-box" align="center" no-gutters>
<v-col :cols="2">
<label for="" class="search-box-label">
<v-icon x-small color="primary" class="mr-1"
>mdi-record-circle</v-icon
>
검색어
</label>
</v-col>
<v-col :cols="10">
<v-text-field
append-icon="mdi-magnify"
class="v-input__custom"
outlined
:placeholder="placeholderValue"
:hide-details="true"
v-model="searchWord"
@keyup.enter="typeEnterKey"
></v-text-field>
</v-col>
</v-row>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents">
<v-col :cols="12">
<v-card class="px-5 py-5">
<div ref="gridParent" id="test2" style="height:100%;">
<component
class="w100 h100"
ref="myGrid"
:is="loadGrid ? 'Grid' : null"
:gridName="gridName"
:parentPrgmId="myPrgmId"
/>
</div>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex';
import BtnSearch from '~/components/common/button/BtnSearch';
import BtnExcelDownload from '~/components/common/button/BtnExcelDownload';
import Grid from '~/components/common/Grid';
import mixinGlobal from '@/mixin/global.js';
import SelectBlocMstr from '@/components/common/select/SelectBlocMstr';
import Utility from '~/plugins/utility';
import RadioStandard from '~/components/common/RadioStandard';
import selectCodeList from '@/components/common/select/selectCodeList';
let myTitle;
// const myPrgmId = "PRG0054";
let myPrgmId;
export default {
mixins: [mixinGlobal],
async asyncData(context) {
const myState = context.store.state;
// context.store.commit("setActiveMenuInfo", myState.menuData[myPrgmId]);
// myTitle = myState.activeMenuInfo.menuNm;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
BtnSearch,
SelectBlocMstr,
RadioStandard,
selectCodeList,
Grid,
BtnExcelDownload,
},
data() {
return {
myPrgmId: myPrgmId,
loadGrid: false,
gridName: 'rowGrid',
myRowKey: 0,
searchWord: '',
apiKey: '',
placeholderValue: '',
};
},
computed: {
...mapState({
pageData: state => state.pageData[myPrgmId],
}),
chkIsFind() {
return this.pageData.isFind;
},
chkBloc() {
return this.pageData.blocId;
},
chkStandard() {
return this.pageData.rdbStandard;
},
chkReadObjKind() {
return this.pageData.readObjKind;
},
},
watch: {
chkIsFind(val) {
if (val) this.search();
},
chkBloc() {
this.setPageData({ isFind: true });
},
chkStandard() {
this.searchWord = '';
this.setPageData({ isFind: true });
},
chkReadObjKind() {
this.setPageData({ isFind: true });
},
},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
created() {
//공정 유형 조회
this.getCodeList({
dataKey: 'eccKind',
params: { commGrpCd: 'EM_ECC_KIND', useFg: '1' },
addAll: false,
});
//개소 종류 조회
this.getCodeList({
dataKey: 'plcKind',
params: { commGrpCd: 'CM_CHKKIND', useFg: '1' },
addAll: false,
});
//READ_DATA_TYPE 조회
this.getCodeList({
dataKey: 'readDataTypeCd',
params: { commGrpCd: 'EM_READ_DATA_TYPE', useFg: '1' },
addAll: false,
});
//사용여부 조회
this.getCodeList({
dataKey: 'eccFg',
params: { commGrpCd: 'CO_USEFG', useFg: '1' },
addAll: false,
});
},
mounted() {},
beforeDestroy() {
this.chkOpenTabList({ key: 'destroy', prgmId: myPrgmId });
},
methods: {
...mapMutations({
setPageData: 'setPageData',
setGridData: 'setGridData',
setGridColumn: 'setGridColumn',
setGridOption: 'setGridOption',
}),
...mapActions({
getCodeList: 'modules/search/getCodeList',
postApi: 'modules/list/postApi',
postUpdateApi: 'modules/list/postUpdateApi',
postApiReturn: 'modules/list/postApiReturn',
chkOpenTabList: 'chkOpenTabList',
}),
async search() {
await this.getRowGridData();
await this.setPageData({
isFind: false,
});
},
typeEnterKey() {
this.getRowGridData();
},
init() {
this.layoutInit();
this.gridInit();
this.pageData.blocId = this.userInfo.blocId;
},
layoutInit() {
const searchFilterHeight = this.$refs.searchFilter.offsetHeight;
this.$refs.contents.style.height = `calc(100% - ${searchFilterHeight}px)`;
},
gridInit() {
const gridHeight = this.$refs.gridParent.offsetHeight - 30;
const myOptions = {
columnOptions: {
resizable: true,
},
header: {
height: 60,
complexColumns: [
{
header: '태그',
name: 'tagColumns',
childNames: [
'tagNm',
'readDataTypeCd',
'readObjNm',
'mgnf',
'distRt',
],
},
{
header: '검침개소',
name: 'readPlcColumns',
childNames: ['readPlcNm', 'plcKind', 'distRt2'],
},
{
header: '공정',
name: 'eccColumns',
childNames: ['eccNm', 'eccKind', 'eccFg'],
},
{
header: '설비',
name: 'eqpmColumns',
childNames: ['1', '2', '3'],
},
],
},
};
this.setGridOption({
gridKey: this.gridName,
value: Object.assign(Utility.defaultGridOption(gridHeight), myOptions),
});
this.getRowGridData();
},
async getRowGridData() {
this.loadGrid = false;
const _this = this;
let myColumns = [
{
header: '태그명',
name: 'tagNm',
align: 'left',
width: 'auto',
},
{
header: '타입',
name: 'readDataTypeCd',
align: 'center',
formatter({ value }) {
let retVal = '';
const newVal = _this.pageData.readDataTypeCdList.filter(
item => item.commCd == value,
);
if (newVal.length > 0) {
retVal = newVal[0].commCdNm;
}
return retVal;
},
},
{
header: '검침대상',
name: 'readObjNm',
align: 'center',
},
{
header: '배부율',
name: 'mgnf',
align: 'center',
},
{
header: '매핑배율',
name: 'distRt',
align: 'center',
},
{
header: '개소명',
name: 'readPlcNm',
align: 'left',
width: 'auto',
},
{
header: '개소유형',
name: 'plcKind',
align: 'center',
formatter({ value }) {
let retVal = '';
const newVal = _this.pageData.plcKindList.filter(
item => item.commCd == value,
);
if (newVal.length > 0) {
retVal = newVal[0].commCdNm;
}
return retVal;
},
},
{
header: '매핑배율',
name: 'distRt2',
align: 'center',
},
{
header: '공정명',
name: 'eccNm',
align: 'left',
width: 'auto',
},
{
header: '공정타입',
name: 'eccKind',
align: 'center',
formatter({ value }) {
let retVal = '';
const newVal = _this.pageData.eccKindList.filter(
item => item.commCd == value,
);
if (newVal.length > 0) {
retVal = newVal[0].commCdNm;
}
return retVal;
},
},
{
header: 'ECC여부',
name: 'eccFg',
align: 'center',
formatter({ value }) {
let retVal = '';
const newVal = _this.pageData.eccFgList.filter(
item => item.commCd == value,
);
if (newVal.length > 0) {
retVal = newVal[0].commCdNm;
}
return retVal;
},
},
];
var apiKeyMapper = {
tag: 'selectStndInfoReadTag',
readPlc: 'selectStndInfoReadReadPlc',
ecc: 'selectStndInfoReadEcc',
eqpm: 'selectStndInfoReadEqpm',
};
this.apiKey = apiKeyMapper[this.pageData.rdbStandard];
let res = [];
res = await this.postApiReturn({
apiKey: this.apiKey,
resKey: 'stndInfoReadData',
sendParam: {
search: this.searchWord,
// blocId: this.pageData.blocId,
blocId: this.pageData.blocMstrList[this.pageData.blocId].blocId,
readObjKind: this.pageData.readObjKind,
},
});
this.setGridColumn({
gridKey: this.gridName,
value: myColumns,
});
this.setGridData({
gridKey: this.gridName,
value: res,
});
let placeObj = {
tag: '태그명 검색',
readPlc: '검침개소명 검색',
ecc: '공정명 검색',
eqpm: '설비명 검색',
};
this.$nextTick(() => {
this.placeholderValue = placeObj[this.pageData.rdbStandard];
});
this.loadGrid = true;
this.setPageData({ isFind: false });
},
},
};
const defaultData = {
/* 검색옵션 */
isFind: false,
blocId: '',
blocMstrList: [],
rdbStandard: 'tag',
plcKind: '',
plcKindList: [],
eccKind: '',
readObjKind: '',
readObjKindList: [],
eccFg: '',
eccFgList: [],
eccKindList: [],
readDataTypeCd: '',
readDataTypeCdList: [],
rowGrid: {
data: [],
column: [],
option: {},
defaultRow: {},
},
xlsFileInfo: {
// 출력하려는 grid 와 같은 이름으로 세팅
rowGrid: {
fileName: null, // 갑이 없으면 해당 페이지 메뉴명
sheetName: null, // 갑이 없으면 'Sheet1'
},
},
};
</script>
<style lang="scss">
@import '@/assets/scss/common.scss';
</style>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,107 @@
<template>
<div class="w100 h100">
<iframe
src="/webHmi/home"
name="hmi"
width="100%"
height="100%"
frameborder="0"
></iframe>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex';
import Utility from '~/plugins/utility';
let myTitle;
// const myPrgmId = "PRG4107";
let myPrgmId;
export default {
async asyncData(context) {
const myState = context.store.state;
// context.store.commit("setActiveMenuInfo", myState.menuData[myPrgmId]);
// myTitle = myState.activeMenuInfo.menuNm;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
Utility,
},
data() {
return {
myPrgmId: myPrgmId,
};
},
computed: {
...mapState({
pageData: state => state.pageData[myPrgmId],
}),
},
watch: {},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
async created() {},
async mounted() {},
methods: {
...mapMutations({
setPageData: 'setPageData',
setGridData: 'setGridData',
setGridColumn: 'setGridColumn',
setGridOption: 'setGridOption',
setChartOption: 'setChartOption',
}),
...mapActions({
postApi: 'modules/list/postApi',
postUpdateApi: 'modules/list/postUpdateApi',
postApiReturn: 'modules/list/postApiReturn',
chkOpenTabList: 'chkOpenTabList',
}),
},
};
const defaultData = {
isFind: false,
};
const myDetail = [];
</script>
<style lang="scss">
.swiper-wrapper {
box-sizing: inherit !important;
}
.swiper-pagination-horizontal {
bottom: 10px;
left: 0;
width: 100%;
}
.swiper-pagination-bullet {
width: 15px;
height: 15px;
margin: 0 var(--swiper-pagination-bullet-horizontal-gap, 5px);
background: #fff;
}
.swiper-pagination-bullet-active {
opacity: 1;
background: #196dcb;
}
// .swiper-position{
// position: fixed;
// }
</style>

View File

@ -0,0 +1,807 @@
<template>
<div class="l-layout">
<!-- Dataset 페이지 시작 -->
<div v-if="pageActionFlag == 'list'" class="h100">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="4">
<InputText
:parentPrgmId="myPrgmId"
label="DataSet 명"
valueNm="dataSetNm"
:labelCols="4"
:textCols="8"
:searchOption="true"
/>
</v-col>
<v-col :cols="3">
<component
:is="'selectCodeList'"
:parentPrgmId="myPrgmId"
:label="'사용여부'"
dataKey="useFg"
:sendParam="{ commGrpCd: 'CO_USEFG', useFg: '1' }"
:addAll="true"
/>
</v-col>
<v-col :cols="3">
<!-- 사업장 -->
<component
:is="'SelectBlocMstr'"
ref="SelectBlocMstr"
:parentPrgmId="myPrgmId"
/>
</v-col>
<v-col :cols="2" class="text-right">
<v-btn
@click="jamoviClickEvent('view')"
:ripple="false"
class="mr-1"
>Jamovi</v-btn
>
<BtnSearch @click="search" />
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents">
<v-col :cols="5" class="h100">
<v-card class="pb-5">
<div class="d-flex align-center justify-space-between pa-5">
<v-card-title class="pa-0 custom-title-4"
>Data Set 리스트</v-card-title
>
<Buttons
:parentPrgmId="myPrgmId"
:bindingData="gridName"
:detailList="detailList"
:btnActionsFnc="btnActions"
/>
</div>
<div class="px-5" style="height:calc(100% - 76px)">
<div ref="gridParent" class="w100 h100">
<component
:ref="gridName"
:is="loadGrid ? 'Grid' : null"
:gridName="gridName"
:parentPrgmId="myPrgmId"
@getRowsData="getRowData"
@sendSelectedRowStatInfo="getSelectedRowStatInfo"
:selectedRowDataWatchFlag="true"
/>
</div>
</div>
</v-card>
</v-col>
<v-col :cols="7" class="h100">
<v-card class="pb-5">
<v-card-title class="custom-title-4" style="min-height:76px;"
>Data Set 상세
</v-card-title>
<div class="px-5" style="height:calc(100% - 76px)">
<v-tabs v-model="tab">
<v-tab v-for="item in items" :key="item.id">
{{ item.name }}
</v-tab>
</v-tabs>
<v-tabs-items
v-model="tab"
style="height: calc(100% - 65px);"
class="py-6"
>
<v-tab-item v-for="(item, idx) in items" :key="item.id">
<component
v-if="item.id == 'dataSetInfoTab'"
:is="'Form'"
:parentPrgmId="myPrgmId"
:detailList="detailList"
:bindingData="gridName"
@gridEditingFinish="gridEditingFinish"
/>
<DataSetTagRelTab
v-if="item.id == 'dataSetTagRelTab'"
:parentPrgmId="myPrgmId"
:innerTabGridInfo="{ tab, idx }"
@jamoviClickEvent="jamoviClickEvent"
/>
</v-tab-item>
</v-tabs-items>
</div>
</v-card>
</v-col>
</v-row>
</div>
<!-- Dataset 페이지 -->
<!-- Jamovi 페이지 시작 -->
<div v-if="pageActionFlag == 'view'" class="h100">
<v-row align="center" no-gutters>
<v-col :cols="12">
<v-card>
<div class="d-flex align-center justify-space-between pa-5">
<v-card-title class="pa-0">모델링 Data Set</v-card-title>
<div class="d-flex align-center">
<v-btn
@click="jamoviClickEvent('list')"
:ripple="false"
class="mr-1"
>관리 화면으로</v-btn
>
</div>
</div>
</v-card>
</v-col>
</v-row>
<v-row>
<v-col :cols="12">
<v-card>
<div class="w100 h100">
<iframe
name="iframeJamovi"
id="iframeJamoviViewComponent"
width="100%"
height="100%"
:src="smgHtmlPath"
frameborder="0"
ref="iframeDom"
@load="iframeIsLoaded"
></iframe>
</div>
</v-card>
</v-col>
</v-row>
</div>
<!-- Jamovi 페이지 -->
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex';
import mixinGlobal from '@/mixin/global.js';
import { resize } from '@/mixin/resize.js';
import BtnSearch from '~/components/common/button/BtnSearch';
import Buttons from '~/components/common/button/Buttons';
import SelectBlocMstr from '@/components/common/select/SelectBlocMstr';
import selectCodeList from '@/components/common/select/selectCodeList';
import InputText from '@/components/common/input/InputText';
import Form from '~/components/common/form/Form';
import DataSetTagRelTab from '@/components/pages/ems/DataSetInfo/DataSetTagRelTab';
import Grid from '~/components/common/Grid';
import Utility from '~/plugins/utility';
import DateUtility from '~/plugins/dateUtility';
let myTitle;
let myPrgmId;
let smgHtmlPath;
let isJamoviInit = false;
let jamoviOpenDocKey = '';
const globalComId = '';
export default {
mixins: [mixinGlobal, resize],
async asyncData(context) {
const myState = context.store.state;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
smgHtmlPath: smgHtmlPath,
closable: true,
smgHtmlPath:
'http://172.28.103.246:41337/?access_key=20d6a0e0768f4ca093c113827ed1ad83',
},
components: {
BtnSearch,
Buttons,
SelectBlocMstr,
selectCodeList,
InputText,
Form,
DataSetTagRelTab,
Grid,
},
data() {
return {
myPrgmId: myPrgmId,
pageActionFlag: 'list',
gridName: 'rowGrid',
smgHtmlPath:
'http://172.28.103.246:41337/?access_key=20d6a0e0768f4ca093c113827ed1ad83', // jamoviOpenDocKey,
loadGrid: false,
tab: null,
items: [
{
name: 'Data Set 정보',
id: 'dataSetInfoTab',
disabledFlag: false,
},
{
name: 'Data Set TAG 연결',
id: 'dataSetTagRelTab',
disabledFlag: false,
},
],
detailList: myDetail,
defaultUseFg: 1,
};
},
computed: {
chkIsFind() {
// 조회 플래그
return this.pageData.isFind;
},
chkBlocCd() {
return this.pageData.blocId;
},
chkUseFg() {
// 사용여부 선택 감지
return this.pageData.useFgList === undefined ? -1 : this.pageData.useFg;
},
},
watch: {
chkIsFind(val) {
if (val) this.search();
},
chkBlocCd() {
this.setPageData({ isFind: true });
},
chkUseFg() {
this.setPageData({ isFind: true });
},
},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
created() {
var data = this.$route.params;
this.routeData = {
fromDt: data.fromDt,
};
// 모델 데이터 유형
this.getCodeList({
dataKey: 'mdlDataTypeCd',
params: { commGrpCd: 'MDL_DATA_TYPE_CD', useFg: '1' },
addAll: false,
});
},
mounted() {
this.init();
},
beforeDestroy() {
this.chkOpenTabList({ key: 'destroy', prgmId: myPrgmId });
},
methods: {
...mapActions({
getCodeList: 'modules/search/getCodeList',
getBlocMstrList: 'modules/search/getBlocMstrList',
getJamoviUrlReturn: 'modules/list/getJamoviUrlReturn',
}),
init() {
this.setFromDt();
this.initData();
this.gridInit();
},
async initData() {},
setFromDt() {
this.pageData.fromDt = Utility.setBeforetDate(
this.pageData,
this.pageData.toDt,
'YYYYMMDD',
);
// this.pageData.toDt = Utility.setAftertDate(this.pageData, this.pageData.fromDt, "YYYYMMDD");
},
gridInit() {
const gridHeight = this.$refs.gridParent.offsetHeight - 30;
const gridWidth = this.$refs.gridParent.offsetWidth;
const myOptions = {
columnOptions: {
resizable: true,
},
};
this.setGridOption({
gridKey: this.gridName,
value: Object.assign(Utility.defaultGridOption(gridHeight), myOptions),
});
const _this = this;
const myColumns = [
{
header: '모델링 DataSet ID',
name: 'dataSetId',
align: 'center',
width: 180,
},
{
header: 'DataSet 명',
name: 'dataSetNm',
align: 'left',
width: 200,
},
{
header: '사업장',
name: 'blocId',
align: 'center',
formatter({ value }) {
let retVal = '';
const newValue = _this.pageData.blocIdList.filter(
item => item.blocId == value,
);
if (newValue.length > 0) {
retVal = newValue[0].blocNm;
}
return retVal;
},
hidden: true,
},
{
header: '사용 여부',
name: 'useFg',
width: 100,
align: 'center',
formatter({ value }) {
value = value === true ? '1' : '0';
const newValue = _this.pageData.useFgList.filter(
item => item.commCd == value,
);
return newValue[0].commCdNm;
},
},
{ header: '비고', name: 'rmrk', align: 'left' },
];
this.setGridColumn({
gridKey: this.gridName,
value: myColumns,
});
this.loadGrid = true;
this.getRowGridData();
},
async search() {
// this.loadTree = false;
this.loadGrid = false;
await this.getRowGridData();
await this.setPageData({
isFind: false,
});
},
async getRowGridData() {
let res = [];
var useFg =
this.pageData.useFgList.length > 0
? this.pageData.useFg
: this.defaultUseFg;
if (this.pageData.blocMstrList.length > 0) {
res = await this.postApiReturn({
apiKey: 'selectDataSetInfo',
resKey: 'dataSetInfoData',
sendParam: {
comId: globalComId,
useFg: useFg,
dataSetNmLike: this.pageData.dataSetNm,
},
});
} else {
this.setPageData({ isFind: false });
}
const newRes = res.map(item => {
const newObj = {
...item,
rowStat: null,
dataSetId: item.dataSetId,
dataSetNm: item.dataSetNm,
useFg: item.useFg === '1' ? true : false, // 화면 개발 편의를 위해 boolean 타입으로 교체, 저장시 "1", "0" 으로 바꿔 보내야 함
};
return newObj;
});
this.loadGrid = true;
this.setGridData({
gridKey: this.gridName,
value: newRes,
});
this.$nextTick(() => {
if (newRes.length > 0) {
this.$refs[this.gridName].focus({
rowKey:
this.pageData.rowGridSelectKey == '' ||
this.pageData.rowGridSelectKey == null
? 0
: this.pageData.rowGridSelectKey ==
this.$refs[this.gridName].getData().length - 1
? this.pageData.rowGridSelectKey
: 0,
columnName: 'dataSetNm',
setScroll: true,
});
} else {
this.detailDataInit();
}
});
},
async getRowData(data, gridName) {
this.setPageData({
rowGridSelectKey: data.rowKey,
rowGridSelectData: data,
});
this.setDataSetTagRelInfo(data);
this.setGridSelectData({
gridKey: gridName,
gridSelect: true,
rowGridSelectKey: data.rowKey,
rowGridSelectData: Object.assign({}, data),
});
this.setGridSelectData({
gridKey: 'rowDataSetTagRelGrid',
gridSelect: true,
rowGridSelectKey: '',
rowGridSelectData: Object.assign({}, {}),
});
},
async setDataSetTagRelInfo(data) {
this.setPageData({
rowGridSelectKey: data.rowKey,
rowGridSelectData: data,
});
// 검침개소 추가 정보 처리
const res = await this.postApiReturn({
apiKey: 'selectMdlDataSetTagRelInfo',
resKey: 'dataSetTagRelData',
sendParam: {
comId: data.comId,
dataSetId: data.dataSetId,
},
});
console.debug('res', res);
const newRes = res.map(item => {
const newObj = {
...item,
comId: item.comId || '',
dataSetId: item.dataSetId || '',
dataSetNm: item.dataSetNm || '',
tagId: item.tagId || '',
tagNm: item.tagNm || '',
rmrk: item.rmrk || '',
useFg: item.useFg === '1' ? true : false,
rowStat: null,
};
return newObj;
});
this.setGridData({
gridKey: 'rowDataSetTagRelGrid',
value: newRes,
});
},
detailDataInit() {
this.setPageData({
rowGridSelectKey: null,
rowGridSelectData: [],
});
this.setGridData({
gridKey: 'rowDetailGrid',
value: [],
});
},
detailDataSetTagRelInit() {
this.setPageData({
rowGridSelectKey: null,
rowGridSelectData: [],
});
this.setGridData({
gridKey: 'rowDataSetTagRelGrid',
value: [],
});
},
getSelectedRowStatInfo(data) {
if (data) {
var rowStat = data.rowStat;
if (rowStat === 'I') {
this.tab = 0;
for (var i = 1; i < this.items.length; i++) {
this.items[i].disabledFlag = true;
}
} else if (rowStat === 'U') {
for (var i = 1; i < this.items.length; i++) {
this.items[i].disabledFlag = false;
}
} else if (rowStat === 'D') {
for (var i = 1; i < this.items.length; i++) {
this.items[i].disabledFlag = false;
}
} else if (rowStat === null) {
for (var i = 1; i < this.items.length; i++) {
this.items[i].disabledFlag = false;
}
}
}
},
async btnActions(action) {
let dataArr = [];
switch (action) {
case 'add':
const defaultRow = {
comId: this.userInfo.comId,
dataSetId: '',
dataSetNm: '',
useFg: '1',
};
this.$refs[this.gridName].addTreeRow(defaultRow);
break;
case 'remove':
this.$refs[this.gridName].removeTreeRow();
break;
case 'save':
dataArr = this.$refs[this.gridName].save();
var validCheck = true;
if (dataArr.length > 0) {
dataArr.filter(item => {
if (item.rowStat === 'I') {
if (item.dataSetNm == '') {
alert('필수 입력값을 입력해주세요.');
validCheck = false;
}
} else if (item.rowStat === 'U') {
if (item.dataSetNm == '') {
alert('필수 입력값을 입력해주세요.');
validCheck = false;
}
}
});
if (validCheck) {
const sendParam = {
datas: {
dsMdlDataSetInfo: dataArr.map(item => ({
...item,
comId: globalComId,
useFg: item.useFg ? '1' : '0',
})),
},
params: {},
};
await this.postUpdateApi({
apiKey: 'saveMdlDataSetInfo',
sendParam: sendParam,
});
this.$nextTick(() => {
this.setPageData({ isFind: true });
});
}
} else {
alert('저장할 내용이 없습니다.');
}
break;
default:
break;
}
},
gridEditingFinish(data, bindingData) {
switch (bindingData) {
case this.gridName:
this.$refs[bindingData].editingFinish(data);
break;
default:
this.$refs[bindingData][0].editingFinish(data);
break;
}
},
async jamoviClickEvent(action, payload) {
switch (action) {
case 'view':
jamoviOpenDocKey = '';
this.pageActionFlag = 'view';
break; // 리스트 페이지 상세보기 버튼
case 'view1':
console.log('view1', payload);
console.log(
'view1 fromDt : ',
this.pageData.fromDt,
', toDt : ',
this.pageData.toDt,
);
const res = await this.postApiReturn({
apiKey: 'selectJamoviOpen',
resKey: 'jamoviOpenData',
sendParam: {
comId: payload.comId,
dataSetId: payload.dataSetId,
sterm: DateUtility.format(this.pageData.fromDt, 'YYYY-MM-DD'),
eterm: DateUtility.format(this.pageData.toDt, 'YYYY-MM-DD'),
term: this.pageData.mdlDataTerm,
},
});
console.log('jamoviClickEvent : ', res);
if (res.status && res.status == 'OK') {
console.log('jamoviClickEvent Ok : ', stat, url);
let stat = res.status;
let url = res.url;
jamoviOpenDocKey = url;
this.pageActionFlag = 'view';
} else {
alert(
'RTDB로 부터 Data Load중 오류가 발생하였습니다.\n검색기간을 확인하시고 다시 요청 바랍니다.',
);
}
break; // 리스트 페이지 상세보기 버튼
case 'list':
this.pageActionFlag = 'list';
isJamoviInit = false;
break; // 리스트 페이지 상세보기 버튼
}
},
iframeIsLoaded() {
// smgHtmlPath
console.log('iframe loaded', jamoviOpenDocKey);
console.log('iframe iframeJamovi', this.$refs.iframeDom.src);
let url = '';
if (!isJamoviInit) {
console.log('iframe loaded2');
isJamoviInit = true;
this.$refs.iframeDom.src =
// 'http://jamovi.kfems.co.kr:41337/' +
'http://172.28.103.246:41337/' +
(jamoviOpenDocKey || '?access_key=20d6a0e0768f4ca093c113827ed1ad83');
console.log('iframe iframeJamovi', this.$refs.iframeDom.src);
}
},
},
};
const defaultData = {
/* 검색옵션 */
comId: globalComId,
dataSetId: '',
dataSetNm: '',
blocId: '',
blocMstrList: [],
blocIdList: [],
useFg: '1',
useFgList: [],
commGrpCd: '',
commGrpCdNm: '',
mdlDataTerm: '',
mdlDataTermList: [],
mdlDataTypeCd: '',
mdlDataTypeCdList: [],
facInfo: {},
isMulti: false,
// 선택된 그룹코드 상세 데이터
rowGridSelectKey: 0,
rowGridSelectData: null,
isFind: false, // true 경우 조회, 조회버튼도 이 값으로 연동 예정
cmCycle: 'CYC_DAY', // 주기
defaultRange: {
CYC_DAY: 30,
},
fromDt: '',
toDt: Utility.setFormatDate(new Date(), 'YYYYMMDD'),
smgHtmlPath:
'http://172.28.103.246:41337/?access_key=20d6a0e0768f4ca093c113827ed1ad83',
/* data 세팅 */
// 로컬 gridName 값과 동일한 이름으로 세팅
rowGrid: {
data: [],
column: [], // myColumns,
option: {}, // myOptions
defaultRow: {
comId: globalComId,
dataSetId: '',
dataSetNm: '',
blocId: null,
useFg: '1',
rowStat: 'I',
},
buttonAuth: {
add: true,
remove: true,
save: true,
excel: false,
},
rowGridSelectKey: 0,
rowGridSelectData: null,
},
rowDataSetTagRelGrid: {
data: [],
column: [], // myColumns,
option: {}, // myOptions
defaultRow: {
comId: '',
dataSetId: '',
dataSetNm: '',
tagId: '',
tagNm: '',
mdlDataTypeCd: 'SUM',
useFg: '1',
rmrk: null,
rowStat: null,
},
buttonAuth: {
add: true,
remove: true,
save: true,
excel: false,
},
rowGridSelectKey: 0,
rowGridSelectData: null,
},
};
const myDetail = [
{
type: 'InputText',
label: 'Data Set ID',
valueNm: 'dataSetId',
readonly: true,
cols: 6,
class: 'py-2',
required: false,
placeholder: '시스템 자동입력',
},
{
type: 'InputText',
label: 'Data Set 명',
valueNm: 'dataSetNm',
disabled: false,
cols: 6,
class: 'py-2',
required: true,
},
{
type: 'CheckBox',
label: '사용 여부',
valueNm: 'useFg',
disabled: false,
cols: 6,
class: 'py-2',
value: { '1': true, '0': false },
required: true,
},
{
type: 'TextArea',
label: '비고',
valueNm: 'rmrk',
disabled: false,
cols: 12,
textCols: 9,
rows: 2,
class: 'py-2',
required: false,
},
];
</script>
<style lang="scss">
@import '@/assets/scss/common.scss';
</style>

View File

@ -0,0 +1,809 @@
<template>
<div class="l-layout">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="3">
<!-- 설비종류 -->
<component
:is="'SelectBox'"
:propsValue="selectValue02"
:itemList="selectValueList02"
:label="'FAB'"
@update:propsValue="selectValue02 = $event"
/>
</v-col>
<v-col :cols="3">
<!-- 설비종류 -->
<component
:is="'SelectBox'"
:propsValue="selectValue01"
:itemList="selectValueList01"
:label="'설비종류'"
@update:propsValue="selectValue01 = $event"
/>
</v-col>
<v-col :cols="3">
<!-- 설비종류 -->
<component
:is="'SelectBox'"
:propsValue="selectValue03"
:itemList="selectValueList03"
:label="'설비그룹'"
@update:propsValue="selectValue03 = $event"
/>
</v-col>
<v-col :cols="2">
<!-- 평가 -->
<component
:is="'SelectBox'"
:propsValue="selectValue06"
:itemList="selectValueList06"
:label="'평가'"
@update:propsValue="selectValue06 = $event"
/>
</v-col>
<v-col :cols="1" class="text-right">
<!-- 조회버튼 -->
<BtnSearch @click="search" />
</v-col>
</v-row>
<v-row align="center" no-gutters>
<v-col :cols="3">
<!-- 설비종류 -->
<component
ref="EqpmSelectPop"
:is="'EqpmSelectPop'"
:label="'설비'"
:valueNm="'eqpmNm'"
:parentPrgmId="myPrgmId"
:eqpmGrpDisabled="true"
:fabDisabled="true"
:textCols="8"
:isMulti="true"
/>
</v-col>
<v-col :cols="3">
<!-- 설비종류 -->
<component
:is="'SelectBox'"
ref="SelectBox1"
:propsValue="selectValue05"
:itemList="selectValueList05"
:label="'가이드명'"
@update:propsValue="selectValue05 = $event"
/>
</v-col>
<v-col :cols="4">
<!-- 대상일 -->
<component
:is="'Datepicker'"
:parentPrgmId="myPrgmId"
:label="'대상일'"
:labelCols="3"
/>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents">
<v-col :cols="12" style="height: 100%">
<v-card class="pb-5">
<div class="d-flex align-center justify-space-between pa-5">
<v-card-title class="pa-0">설비별 현황 리스트</v-card-title>
</div>
<div class="px-5" style="height:calc(100% - 76px)">
<div ref="gridParent" class="w100 h100">
<component
:ref="gridName"
:is="loadGrid ? 'Grid' : null"
:gridName="gridName"
:parentPrgmId="myPrgmId"
:columnClickEventFlag="true"
@columnClick="columnClick"
/>
</div>
</div>
</v-card>
</v-col>
</v-row>
<component
ref="EnrgEffcEqpmDetailPop"
:is="'EnrgEffcEqpmDetailPop'"
:parentPrgmId="myPrgmId"
/>
<component
ref="EnrgEffcGdIdxDetPop"
:is="'EnrgEffcGdIdxDetPop'"
:parentPrgmId="myPrgmId"
/>
</div>
</template>
<script>
import mixinGlobal from '@/mixin/global.js';
import { resize } from '@/mixin/resize.js';
import { mapActions } from 'vuex';
import BtnSearch from '~/components/common/button/BtnSearch';
import Buttons from '~/components/common/button/Buttons';
import SelectBox from '@/components/common/select/SelectBox';
import Grid from '~/components/common/Grid';
import Utility from '~/plugins/utility';
import Datepicker from '~/components/common/Datepicker';
import EqpmSelectPop from '~/components/common/modal/EqpmSelectPop';
import EnrgEffcEqpmDetailPop from '~/components/common/modal/EnrgEffcEqpmDetailPop';
import EnrgEffcGdIdxDetPop from '~/components/common/modal/EnrgEffcGdIdxDetPop';
let myTitle;
let myPrgmId;
let paramsKey;
// let params;
// let routeCheck = false;
export default {
mixins: [mixinGlobal, resize],
async asyncData(context) {
const myState = context.store.state;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
Utility,
Grid,
SelectBox,
Buttons,
BtnSearch,
Datepicker,
EnrgEffcEqpmDetailPop,
EqpmSelectPop,
EnrgEffcGdIdxDetPop,
},
data() {
return {
myPrgmId: myPrgmId,
selectValue01: null,
selectValue02: null,
selectValue03: null,
selectValue04: { eqpmId: [] },
selectValue05: null,
selectValue06: null,
selectValueList01: [],
selectValueList02: [],
selectValueList03: [],
selectValueList04: [],
selectValueList05: [],
selectValueList06: [],
initedFlag: false,
loadGrid: false,
gridName: 'rowGrid',
popDialog: false,
eqpmFlag: false,
eqpmKindFlag: false,
eqpmGrpFlag: false,
eqpmGdIdxFlag: false,
fabFlag: false,
routeData: {},
};
},
computed: {
chkIsFind() {
// 조회 플래그
return this.pageData.isFind;
},
fabId() {
return this.pageData.fabId;
},
fabNm() {
return this.pageData.fabNm;
},
eqpmKindId() {
return this.pageData.eqpmKindId;
},
eqpmGrpId() {
return this.pageData.eqpmGrpId;
},
eqpmGrpNm() {
return this.pageData.eqpmGrpNm;
},
fromDt() {
return this.pageData.fromDt;
},
checkedRows() {
return this.pageData.checkedRows;
},
eqpmInfo() {
return this.pageData.eqpmInfo;
},
},
watch: {
$route(to, from) {
// routeCheck=true;
if (to.query.prgmId == myPrgmId) {
if (paramsKey != to.params.key) {
if (to.params.key == undefined) {
} else {
// params=to.params;
paramsKey = to.params.Key;
document.getElementById('refresh').click();
}
}
}
},
chkIsFind(val) {
if (val) this.search();
},
fabId(val) {},
fabNm(val) {},
eqpmKindId(val) {},
eqpmGrpId(val) {},
eqpmGrpNm(val) {},
fromDt(val) {},
async selectValue02(val) {
if (this.initedFlag) {
this.setPageData({
fabId: val,
eqpmId: [],
eqpmNm: null,
eqpmIdList: [],
// isFind:true
});
this.selectValue04 = { eqpmId: [] };
// await this.getEqpm();
// if(this.eqpmFlag){
// this.setPageData({ isFind: true });
// this.eqpmFlag=false;
// }
}
},
async selectValue01(val) {
if (this.initedFlag) {
this.setPageData({
eqpmKindId: val,
eqpmGrpId: null,
eqpmId: [],
eqpmNm: null,
eqpmIdList: [],
});
this.selectValue04 = { eqpmId: [] };
await this.getEqpmGrp();
// await this.getEqpm(this.selectValueList03);
}
},
async selectValue03(val) {
if (this.initedFlag) {
this.setPageData({
eqpmGrpId: val,
eqpmId: [],
eqpmNm: null,
eqpmIdList: [],
});
this.selectValue04 = { eqpmId: [] };
// await this.getEqpm();
// if(this.eqpmFlag){
// this.setPageData({ isFind: true });
this.eqpmGrpFlag = true;
// }
// await this.getEqpm();
await this.getGdIdx();
}
},
async selectValue06(val) {
if (this.initedFlag) {
this.setPageData({
eqpmGrpId: null,
eqpmId: [],
eqpmNm: null,
eqpmIdList: [],
isFind: true,
});
}
},
checkedRows(val) {
if (this.initedFlag) {
var temp = this.pageData.checkedRows.map(item => {
return item.eqpmId;
});
this.selectValue04 = { eqpmId: temp };
}
},
eqpmInfo(val) {
if (this.initedFlag) {
this.setPageData({ eqpmId: val.eqpmId, eqpmNm: val.eqpmNm });
}
},
// async selectValue04(val) {
// if (this.initedFlag) {
// console.log("val : ",val)
// this.setPageData({ isFind: true });
// }
// },
selectValue04: {
deep: true,
handler(newVal, oldVal) {
this.setPageData({ isFind: true });
},
},
async selectValue05(val) {
if (this.initedFlag) {
this.setPageData({ isFind: true });
}
},
},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
created() {
var data = this.$route.params;
// this.setPageData({
// eqpmGrpId : data.eqpmGrpId,
// eqpmGrpNm : data.eqpmGrpNm,
// fabId : data.fabId,
// fabNm : data.fabNm,
// eqpmKindId : data.eqpmKindId,
// fromDt : data.fromDt
// });
this.routeData = {
eqpmGrpId: data.eqpmGrpId,
eqpmGrpNm: data.eqpmGrpNm,
fabId: data.fabId,
fabNm: data.fabNm,
eqpmKindId: data.eqpmKindId,
fromDt: data.fromDt,
okFg:data.okFg
};
},
async mounted() {
await this.init();
this.initedFlag = true;
this.routeData = {};
},
beforeDestroy() {
// routeCheck=false;
this.chkOpenTabList({ key: 'destroy', prgmId: myPrgmId });
},
methods: {
...mapActions({
getCodeList: 'modules/search/getCodeList',
getBlocMstrList: 'modules/search/getBlocMstrList',
}),
async init() {
await this.getFab();
await this.getEqpmKind();
await this.getEqpmGrp();
// await this.getEqpm();
await this.getGdIdx();
await this.getOkFg();
if (this.routeData.fromDt != null) {
this.setPageData({
fromDt: this.routeData.fromDt,
});
} else {
this.setFromDt();
}
await this.gridInit();
},
async search() {
await this.getRowGridData();
this.setPageData({
isFind: false,
});
},
setFromDt() {
this.pageData.fromDt = Utility.setBeforetDate(
this.pageData,
this.pageData.toDt,
'YYYYMMDD',
);
// this.pageData.toDt = Utility.setAftertDate(this.pageData, this.pageData.fromDt, "YYYYMMDD");
},
async getEqpmKind() {
let res = await this.postApiReturn({
apiKey: 'selectEqpmKindCodeList',
resKey: 'eqpmKindCodeLists',
sendParam: {},
});
if (res.length > 0) {
this.selectValueList01 = await res.map(item => {
return {
text: item.eqpmKindNm,
value: item.eqpmKindId,
};
});
this.selectValueList01.unshift({
text: '전체',
value: null,
});
if (
this.routeData.eqpmKindId == null ||
this.routeData.eqpmKindId == ''
) {
this.selectValue01 = this.selectValueList01[0].value;
} else if (
this.routeData.eqpmKindId != null ||
this.routeData.eqpmKindId != ''
) {
this.selectValue01 = this.routeData.eqpmKindId;
}
} else {
this.selectValueList01 = [];
this.selectValue01 = null;
}
this.setPageData({
eqpmKindList: this.selectValueList01,
eqpmKindId: this.selectValue01,
});
},
async getFab() {
let res = await this.postApiReturn({
apiKey: 'selectFabCodeList',
resKey: 'fabCodeLists',
sendParam: {},
});
if (res.length > 0) {
this.selectValueList02 = await res.map(item => {
return {
text: item.eccNm,
value: item.eccId,
};
});
this.selectValueList02.unshift({
text: '전체',
value: null,
});
if (this.routeData.fabId != null && this.routeData.fabId != '') {
this.selectValue02 = this.routeData.fabId;
} else if (this.routeData.fabId == null || this.routeData.fabId == '') {
this.selectValue02 = this.selectValueList02[0].value;
}
} else {
this.selectValueList02 = [];
this.selectValue02 = null;
}
this.setPageData({
fabIdList: this.selectValueList02,
fabId: this.selectValue02,
});
},
async getEqpmGrp() {
//설비그룹
let res = await this.postApiReturn({
apiKey: 'selectEqpmGrpCodeList',
resKey: 'eqpmGrpCodeLists',
sendParam: { eqpmKindId: this.selectValue01 },
});
if (res.length > 0) {
this.selectValueList03 = await res.map(item => {
return {
text: item.eqpmGrpNm,
value: item.eqpmGrpId,
};
});
this.selectValueList03.unshift({
text: '전체',
value: null,
});
if (
this.routeData.eqpmGrpId != null &&
this.routeData.eqpmGrpId != ''
) {
this.selectValue03 = this.routeData.eqpmGrpId;
} else if (
this.routeData.eqpmGrpId == null ||
this.routeData.eqpmGrpId == ''
) {
this.selectValue03 = this.selectValueList03[0].value;
}
} else {
this.selectValueList03 = [];
this.selectValue03 = null;
}
this.setPageData({
eqpmGrpId : this.selectValue03,
eqpmGrpIdList : this.selectValueList03
})
},
async getEqpm(data) {},
async getGdIdx() {
let res = await this.postApiReturn({
apiKey: 'selectEqpmGdIdxCodeList',
resKey: 'eqpmGdIdxCodeLists',
sendParam: {
eqpmGrpId: this.selectValue03,
},
});
if (res.length > 0) {
this.selectValueList05 = await res.map(item => {
return {
text: item.gdIdxNm,
value: item.gdIdxId,
};
});
this.selectValueList05.unshift({
text: '전체',
value: null,
});
this.selectValue05 = this.selectValueList05[0].value;
} else {
this.selectValueList05 = [];
this.selectValue05 = null;
}
this.setPageData({
gdIdxIdList: this.selectValueList05,
gdIdxId: this.selectValue05,
});
},
async getOkFg() {
this.selectValueList06 = [
{
text: '전체',
value: null,
},
{
text: 'OK',
value: 'OK',
},
{
text: 'NG',
value: 'NG',
},
];
if(this.routeData.okFg == null || this.routeData.okFg == '' ){
this.selectValue06 = this.selectValueList06[0].value;
}else if(this.routeData.okFg != null || this.routeData.okFg != '' ){
this.selectValue06 = this.routeData.okFg;
}
this.setPageData({
okFg: this.selectValue06,
okFgList: this.selectValueList06,
});
},
async gridInit() {
const gridHeight = this.$refs.gridParent.offsetHeight - 30;
// const gridWidth = this.$refs.gridParent.offsetWidth / 2;
const myOptions = {
columnOptions: {
resizable: true,
},
rowHeaders: ['rowNum'],
// heightResizable: true,
// rowHeight:'auto'
};
this.setGridOption({
gridKey: this.gridName,
value: Object.assign(Utility.defaultGridOption(gridHeight), myOptions),
});
const _this = this;
const myColumns = [
{
header: 'FAB',
name: 'fabNm',
align: 'left',
width: 80,
},
{
header: '설비그룹',
name: 'eqpmGrpNm',
width: 130,
},
{
header: '설비id',
name: 'eqpmId',
hidden: true,
},
{
header: '설비명',
name: 'eqpmNm',
width: 130,
},
{
header: '가이드명',
name: 'gdIdxId',
hidden: true,
// formatter({ value }) {
// let retVal = '';
// const newValue = _this.pageData.gdIdxIdList.filter(
// item => item.value == value,
// );
// if (newValue.length > 0) {
// retVal = newValue[0].text;
// }
// //빈값일때 전체방지
// if (value == '' || value == null) {
// retVal = '';
// }
// return retVal;
// },
},
{
header: '가이드명',
name: 'gdIdxNm',
width: 200,
},
{
header: '주의',
name: 'careStndVal',
align: 'right',
width: 80,
},
{
header: '경고',
name: 'warnStndVal',
align: 'right',
width: 80,
},
{
header: '가이드값',
name: 'totVal',
align: 'right',
width: 120,
},
{
header: '평가',
name: 'okFg',
align: 'center',
width: 80,
},
{
header: '절감가이드 방법',
name: 'gdMeth',
},
{
header: 'NG발생건수',
name: 'ngCnt',
align: 'right',
width: 80,
},
];
this.setGridColumn({
gridKey: this.gridName,
value: myColumns,
});
// this.loadGrid = true;
this.getRowGridData();
},
async getRowGridData() {
this.loadGrid = false;
var res = await this.postApiReturn({
apiKey: 'selectEnrgEffcEqpmDetlMntr',
resKey: 'eqpmDetlData',
sendParam: {
eqpmId: this.selectValue04.eqpmId,
eqpmGrpId: this.selectValue03,
fromDt: this.pageData.fromDt,
toDt: this.pageData.toDt,
gdIdxId: this.selectValue05,
fabId: this.selectValue02,
eqpmKindId: this.selectValue01,
okFg: this.selectValue06,
},
});
this.setGridData({
gridKey: this.gridName,
value: res,
});
this.loadGrid = true;
},
columnClick(e) {
var data = this.$refs[this.gridName].gridInstance.invoke(
'getRow',
e.rowKey,
);
if (e.columnName == 'ngCnt' && e.targetType == 'cell') {
// if(e.columnName == 'ngCnt' && data.ngCnt > 0){
this.$refs['EnrgEffcEqpmDetailPop'].popCheck = true;
this.setPageData({
rowGridSelectKey: e.rowKey,
rowGridSelectData: {
...data,
fromDt: this.pageData.fromDt,
toDt: this.pageData.toDt,
},
});
}
if (e.columnName == 'gdIdxNm' && e.targetType == 'cell') {
// if(e.columnName == 'ngCnt' && data.ngCnt > 0){
this.$refs['EnrgEffcGdIdxDetPop'].popCheck = true;
this.setPageData({
rowGridSelectKey: e.rowKey,
rowGridSelectData: {
...data,
fromDt: this.pageData.fromDt,
toDt: this.pageData.toDt,
},
});
}
},
},
};
const defaultData = {
isFind: false,
fabId: '',
fabIdList: [],
fabNm: '',
eccId: '',
eqpmInfo: null,
eccIdList: [],
eqpmGrpNm: '',
eqpmGrpId: null,
eqpmGrpList: [],
eqpmId: [],
eqpmNm: null,
eqpmIdList: [],
eqpmNm: '',
eqpmKindId: '',
gdIdxId: '',
gdIdxIdList: [],
checkedRows: [],
cmCycle: 'CYC_DAY', // 주기
defaultRange: {
CYC_DAY: 30,
},
calcProc: null,
calcDesc: null,
fromDt: '',
toDt: Utility.setFormatDate(new Date(), 'YYYYMMDD'),
modalData: {},
// 선택된 그룹코드 상세 데이터
rowGridSelectKey: 0,
rowGridSelectData: null,
rowGrid: {
data: [],
column: [],
option: {},
defaultRow: {
fabNm: '',
eqpmGrpNm: '',
eqpmId: null,
gdIdxId: '',
careStndVal: '',
warnStndVal: '',
totVal: '',
okFg: '',
gdMeth: '',
ngCnt: '',
rowStat: null,
},
buttonAuth: {
add: false,
remove: false,
save: false,
excel: false,
},
},
};
</script>

View File

@ -0,0 +1,421 @@
<template>
<div class="l-layout">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="3">
<!-- 설비종류 -->
<component
:is="'SelectBox'"
ref="SelectBox1"
:propsValue="selectValue01"
:itemList="selectValueList01"
:label="'설비종류'"
@update:propsValue="selectValue01 = $event"
/>
</v-col>
<v-col :cols="3">
<!-- 대상일 -->
<component
:is="'Datepicker'"
:parentPrgmId="myPrgmId"
:label="'대상일'"
:labelCols="3"
/>
</v-col>
<v-col :cols="6" class="text-right">
<!-- 조회버튼 -->
<BtnSearch @click="search" />
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents">
<v-col
:cols="6"
v-for="(item, index) in selectData"
:key="item.eqpmGrpId"
style="height: 50%"
>
<!-- <v-card class="pa-5" @click="barClick($event,'card')"> -->
<v-card class="pa-5">
<div class="d-flex align-center justify-space-between">
<v-card-title class="pa-0">{{ item.eqpmGrpNm }}</v-card-title>
</div>
<div ref="chartParent" style="height: 90%">
<component
:id="chartNameList[index]"
class="w100 h100 totChart"
:is="loadChartList[index] ? 'Chart' : null"
:parentPrgmId="myPrgmId"
:chartName="chartNameList[index]"
:ref="chartNameList[index]"
@click="barClick($event, chartNameList[index])"
/>
</div>
</v-card>
</v-col>
<!-- <v-col :cols="12" style="height: 35%">
<v-card class="pa-5">
<div ref="gridParent">
<component
ref="grid_01"
:is="loadGrid_01 ? 'Grid' : null"
:gridName="grid_01"
:parentPrgmId="myPrgmId"
/>
</div>
</v-card>
</v-col> -->
</v-row>
</div>
</template>
<script>
import { mapActions, mapMutations } from 'vuex';
import vue from 'vue';
import mixinGlobal from '@/mixin/global.js';
import { resize } from '@/mixin/resize.js';
import Datepicker from '~/components/common/Datepicker';
import Grid from '~/components/common/Grid';
import SelectBox from '@/components/common/select/SelectBox';
import BtnSearch from '~/components/common/button/BtnSearch';
import Buttons from '~/components/common/button/Buttons';
import Utility from '~/plugins/utility';
import Chart from '~/components/common/Chart';
let myTitle;
let myPrgmId;
export default {
mixins: [mixinGlobal, resize],
async asyncData(context) {
const myState = context.store.state;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
Datepicker,
Grid,
SelectBox,
BtnSearch,
Buttons,
Utility,
Chart,
},
data() {
return {
myPrgmId: myPrgmId,
selectValue01: null,
selectValueList01: [],
loadChartList: [],
chartNameList: [],
selectData: [],
url: '',
objList: {},
};
},
computed: {
chkIsFind() {
// 조회 플래그
return this.pageData.isFind;
},
fromDt() {
return this.pageData.fromDt;
},
},
watch: {
chkIsFind(val) {
if (val) this.search();
},
selectValue01(val) {
this.chartNameList = [];
this.search();
},
fromDt(val) {
this.chartNameList = [];
},
},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
created() {},
async mounted() {
await this.init();
// document.getElementById('totChart').on('click', function(params){
// });
},
beforeDestroy() {
this.chkOpenTabList({ key: 'destroy', prgmId: myPrgmId });
},
methods: {
...mapMutations({
setChartOption: 'setChartOption',
setPageData: 'setPageData',
}),
...mapActions({
getCodeList: 'modules/search/getCodeList',
getBlocMstrList: 'modules/search/getBlocMstrList',
getAddInfoList: 'modules/search/getAddInfoList',
}),
async init() {
await this.getEqpmKind();
await this.getData();
// await this.getChartData();
// await this.setChartData(data);
},
async search() {
// this.getRowGridData();
await this.getData();
this.setPageData({
isFind: false,
});
},
async getEqpmKind() {
let res = await this.postApiReturn({
apiKey: 'selectEqpmKindCodeList',
resKey: 'eqpmKindCodeLists',
sendParam: {},
});
if (res.length > 0) {
this.selectValueList01 = await res.map(item => {
return {
text: item.eqpmKindNm,
value: item.eqpmKindId,
};
});
this.selectValue01 = this.selectValueList01[0].value;
} else {
this.selectValueList01 = [];
this.selectValue01 = null;
}
this.setPageData({
eqpmKindList: this.selectValueList01,
eqpmKindId: this.selectValue01,
});
},
gridInit() {},
getRowGridData() {},
async getData() {
let res = await this.postApiReturn({
apiKey: 'selectEnrgEffcTotSumm',
resKey: 'totSummData',
sendParam: {
fromDt: this.pageData.fromDt,
eqpmKindId: this.selectValue01,
},
});
await this.getChartData(res);
this.selectData = res.filter((item, i) => {
return (
res.findIndex((item2, j) => {
return item.eqpmGrpId === item2.eqpmGrpId;
}) === i
);
});
},
barClick(event, chartName) {
var data = {};
if (chartName == 'card') {
data.fromDt = null;
data.eqpmGrpId = null;
data.eqpmGrpNm = null;
data.fabId = null;
data.fabNm = null;
data.okFg = null;
data.eqpmKindNm = null;
} else {
var chartData = this.objList[chartName];
data.fromDt = this.pageData.fromDt;
data.eqpmGrpId = chartData[event.dataIndex].eqpmGrpId;
data.eqpmGrpNm = chartData[event.dataIndex].eqpmGrpNm;
data.fabId = chartData[event.dataIndex].fabId;
data.fabNm = chartData[event.dataIndex].fabNm;
data.okFg = event.seriesName;
data.eqpmKindId = this.selectValue01;
}
this.$router.push({
name: 'ems-effc-EnrgEffcEqpmDetlMntrPage',
params: {
...data,
key: 'data_' + Math.random(),
},
query: {
prgmId: 'PRG0084',
// key : "data_"+Math.random()
},
});
},
async getChartData(data) {
var chartDataObj = {};
this.objList = {};
// let res = await this.postApiReturn({
// apiKey : 'selectEnrgEffcTotSumm',
// resKey : 'totSummData',
// sendParam:{
// fromDt : this.pageData.fromDt,
// eqpmKindId : this.pageData.eqpmKindId,
// }
// });
data.map(item => {
if (chartDataObj[item.eqpmGrpId] != null) {
chartDataObj[item.eqpmGrpId].push(item);
} else {
chartDataObj[item.eqpmGrpId] = [item];
}
});
// chartDataObj.keys()[0]
var i = 0;
for (var x of Object.keys(chartDataObj)) {
this.loadChartList.push(false);
i++;
this.objList['chart_0' + i] = chartDataObj[x];
this.chartNameList.push('chart_0' + i);
this.setPageData({
[this.chartNameList[i - 1]]: Utility.defaultChartOption(true),
});
this.setChartData(chartDataObj[x], i);
}
// this.setChartData(chartDataObj[Object.keys(chartDataObj)[0]]);
},
async setChartData(data, number) {
this.loadChartList[number - 1] = false;
let xAxisData = [];
let seriesData = [];
var emphasisStyle = {
itemStyle: {
shadowBlur: 10,
shadowColor: 'rgba(0,0,0,0.3)',
},
};
// console.log("data : ", data);
data.map(item => {
xAxisData.push(item.fabNm);
});
seriesData.push({
name: 'OK',
type: 'bar',
stack: 'one',
barWidth: '40',
emphasis: emphasisStyle,
data: data.map(obj => obj['okCnt']),
});
seriesData.push({
name: 'NG',
type: 'bar',
stack: 'one',
barWidth: '40',
emphasis: emphasisStyle,
data: data.map(obj => obj['ngCnt']),
});
var dataZoom = [];
if (xAxisData.length > 7) {
dataZoom = [
{
type: 'inside',
disabled: false,
start: 0,
end: parseInt(700 / xAxisData.length) - 1,
},
{
show: true,
moveOnMouseMove: true,
start: 0,
end: parseInt(700 / xAxisData.length) - 1,
},
];
} else {
dataZoom = [
{
type: 'inside',
disabled: true,
start: 0,
end: parseInt(700 / xAxisData.length) - 1,
},
{
show: false,
moveOnMouseMove: false,
start: 0,
end: parseInt(700 / xAxisData.length) - 1,
},
];
}
// console.log("xAxisData : ", xAxisData);
// console.log("seriesData : ", seriesData);
var chartOption = {
legend: {
top: xAxisData.length > 7 ? 'top' : 'bottom',
},
grid: {
top: '10%',
bottom: '16%',
},
yAxis: {},
xAxis: {
data: xAxisData,
},
series: seriesData,
tooltip: {},
dataZoom: dataZoom,
};
await this.$nextTick();
this.setChartOption({
chartKey: this.chartNameList[number - 1],
value: chartOption,
});
this.loadChartList[number - 1] = true;
},
},
};
const defaultData = {
isFind: false,
eqpmKindList: [],
eqpmKindId: '',
cmCycle: 'CYC_DAY', // 주기
defaultRange: {
CYC_DAY: 0,
},
fromDt: Utility.setFormatDate(new Date(), 'YYYYMMDD'), // 조회 시작일
};
</script>
<style lang="scss" scoped>
@import '@/assets/scss/common.scss';
// .echarts::v-deep > div > canvas:hover {
// cursor: pointer;
// }
// ::v-deep{
// .echarts:hover > div:nth-child(1){
// cursor:pointer !important;
// }
// }
</style>

View File

@ -0,0 +1,574 @@
<template>
<div class="l-layout">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="3">
<!-- 차트목록 -->
<component
:is="'SelectBox'"
ref="SelectBox"
:propsValue="selectValue01"
:itemList="selectValueList01"
:label="'차트'"
@update:propsValue="selectValue01 = $event"
/>
</v-col>
<v-col :cols="4">
<!-- 대상일 -->
<component
:is="'Datepicker'"
:parentPrgmId="myPrgmId"
:label="'대상일'"
:labelCols="3"
/>
</v-col>
<v-col :cols="5" class="text-right">
<!-- 조회버튼 -->
<BtnSearch @click="search" />
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents">
<v-col :cols="12" style="height: 100%">
<v-card class="pb-5">
<div class="d-flex align-center justify-space-between pa-5">
<v-card-title class="pa-0">에너지 현황</v-card-title>
</div>
<v-row>
<!-- <div style="text-align:center;"> -->
<v-col class="arrowCols" :cols="3" style="text-align:center;">
<div class="arrowText">고압반</div>
</v-col>
<!-- <span class="mdi mdi-arrow-right-bold" size="mdi-48px"></span> -->
<!-- <i class="mdi mdi-arrow-right-bold"></i> -->
<!-- <span style="width:1000px;">&#10230;</span> -->
<v-col class="iconArrowCols" :cols="6">
<div class="arrow-right"></div>
<!-- <img class="icon_arrow" src="@/assets/images/icon/ico-enrgMap.png"/> -->
</v-col>
<v-col class="arrowCols" :cols="3" style="text-align:center;">
<div class="arrowText">분전반</div>
</v-col>
<!-- </div> -->
</v-row>
<div class="px-5" style="height:80%">
<div ref="chartParent" class="w100 h100">
<component
:ref="chartName"
class="w100 h100"
:is="loadChart ? 'Chart' : null"
:parentPrgmId="myPrgmId"
:chartName="chartName"
/>
</div>
</div>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script>
import mixinGlobal from '@/mixin/global.js';
import { resize } from '@/mixin/resize.js';
import Datepicker from '~/components/common/Datepicker';
import { mapState, mapActions, mapMutations } from 'vuex';
import BtnSearch from '~/components/common/button/BtnSearch';
import Utility from '~/plugins/utility';
import SelectBox from '@/components/common/select/SelectBox';
import DateUtility from '~/plugins/dateUtility';
import Chart from '~/components/common/Chart';
let myTitle;
let myPrgmId;
export default {
mixins: [mixinGlobal, resize],
async asyncData(context) {
const myState = context.store.state;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
Datepicker,
BtnSearch,
Utility,
DateUtility,
Chart,
SelectBox,
},
data() {
return {
myPrgmId: myPrgmId,
selectValueList01: [],
selectValue01: null,
loadChart: false,
chartName: 'sankeyChart',
loadChart: false,
};
},
computed: {
...mapState({
isDarkMode: state => state.isDarkMode,
}),
chkIsFind() {
// 조회 플래그
return this.pageData.isFind;
},
chkToDt() {
return this.pageData.toDt;
},
chkFromDt() {
return this.pageData.fromDt;
},
},
watch: {
chkIsFind(val) {
if (val) this.search();
},
chkToDt(val) {
var diff = DateUtility.diff(
Utility.setFormatDate(new Date(), 'YYYY-MM-DD'),
this.pageData.toDt,
'd',
);
if (diff > 0) {
this.setPageData({
toDt: new Date(),
isCheck: true,
});
}
},
chkFromDt(val) {
var diff = DateUtility.diff(
Utility.setFormatDate(new Date(), 'YYYY-MM-DD'),
this.pageData.fromDt,
'd',
);
if (diff > 0) {
this.setPageData({
fromDt: new Date(),
isCheck: true,
});
}
},
},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
async created() {},
async mounted() {
this.init();
// document.querySelector('.icon_arrow').style.width = document.querySelector('.iconArrowCols').clientWidth-20 + "px";
},
beforeDestroy() {
this.chkOpenTabList({ key: 'destroy', prgmId: myPrgmId });
},
methods: {
...mapMutations({
setChartOption: 'setChartOption',
setPageData: 'setPageData',
}),
...mapActions({
getCodeList: 'modules/search/getCodeList',
}),
async init() {
await this.getEnrgMapChartList();
this.setFromDt();
},
async search() {
await this.getChartData();
this.setPageData({
isFind: false,
});
},
setFromDt() {
this.pageData.fromDt = Utility.setBeforetDate(
this.pageData,
this.pageData.toDt,
'YYYYMMDD',
);
},
async getEnrgMapChartList() {
let res = await this.postApiReturn({
apiKey: 'selectEnrgMapChartList',
resKey: 'enrgMapChartList',
sendParam: {},
});
if (res.length > 0) {
this.selectValueList01 = await res.map(item => {
return {
text: item.sankeyChartNm,
value: item.sankeyChartSno.toString(),
};
});
this.selectValue01 = this.selectValueList01[0].value;
} else {
this.selectValueList01 = [];
this.selectValue01 = null;
}
this.setPageData({
sankeyChartList: this.selectValueList01,
sankeyChartSno: this.selectValue01,
});
},
async getChartData() {
let res = await this.postApiReturn({
apiKey: 'selectChartNode',
resKey: 'enrgMapChartNodeList',
sendParam: {
sankeyChartSno: this.selectValue01,
},
});
let res2 = await this.postApiReturn({
apiKey: 'selectSankeyTag',
resKey: 'sankeyTagList',
sendParam: {
sankeyChartSno: this.selectValue01,
},
});
var taglist = res2.map(item => {
return item['hmiTagNm'];
});
var tempSObj = {};
var tempEObj = {};
tempSObj['eterm'] = Utility.setFormatDate(
this.pageData.fromDt,
'YYYY-MM-DD 00:29:59',
);
tempSObj['sterm'] = Utility.setFormatDate(
DateUtility.addDate(-1, 'YYYY/MM/DD', this.pageData.fromDt),
'YYYY-MM-DD 23:59:59',
);
tempSObj['interval'] = '1';
tempSObj['vals'] = ['MIN'];
tempSObj['t'] = '2022-06-03 05:22:50';
tempSObj['term'] = 'MIN10';
tempSObj['tags'] = taglist;
tempSObj['url'] = 'http://58.232.11.31:1567/RTDBweapi/aggdata2.do';
var today = Utility.setFormatDate(new Date(), 'YYYYMMDD');
var eterm = Utility.setFormatDate(this.pageData.toDt, 'YYYYMMDD');
tempEObj['eterm'] = Utility.setFormatDate(
this.pageData.toDt,
'YYYY-MM-DD 23:59:59',
);
tempEObj['sterm'] =
today == eterm
? Utility.setFormatDate(this.pageData.toDt, 'YYYY-MM-DD 00:00:00')
: Utility.setFormatDate(this.pageData.toDt, 'YYYY-MM-DD 23:29:59');
tempEObj['interval'] = '1';
tempEObj['vals'] = ['MIN'];
tempEObj['t'] = '2022-06-03 05:22:50';
tempEObj['term'] = 'MIN10';
tempEObj['tags'] = taglist;
tempEObj['url'] = 'http://58.232.11.31:1567/RTDBweapi/aggdata2.do';
var startRes = await this.postApiReturn({
apiKey: 'selectEnrgMapInfo',
resKey: 'enrgMapInfoData',
sendParam: tempSObj,
});
var endRes = await this.postApiReturn({
apiKey: 'selectEnrgMapInfo',
resKey: 'enrgMapInfoData',
sendParam: tempEObj,
});
var resultRes = [];
var tempTags = [];
var allResCheck = false;
for (var i = 0; i < taglist.length; i++) {
if (
startRes.tags[i]['d'].length > 0 &&
endRes.tags[i]['d'].length > 0
) {
resultRes.push(
Utility.setFormatDecimal(
endRes.tags[i]['M'] - startRes.tags[i]['N'],
2,
),
);
} else {
resultRes.push(0);
tempTags.push({ index: i, tag: startRes.tags[i].tag });
}
}
if (tempTags.length > 0) {
allResCheck = true;
console.log('allResCheck... true');
}
if (allResCheck) {
tempSObj['tags'] = tempTags.map(item => {
return item.tag;
});
tempSObj['sterm'] = Utility.setFormatDate(
DateUtility.addDate(-1, 'YYYY/MM/DD', this.pageData.fromDt),
'YYYY-MM-DD 23:59:59',
);
tempSObj['eterm'] = Utility.setFormatDate(
this.pageData.toDt,
'YYYY-MM-DD 23:29:59',
);
var allRes = await this.postApiReturn({
apiKey: 'selectEnrgMapInfo',
resKey: 'enrgMapInfoData',
sendParam: tempSObj,
});
var cnt = 0;
allRes.tags.map(item => {
resultRes[tempTags[cnt++].index] = Utility.setFormatDecimal(
item['M'] - item['N'],
2,
);
});
}
this.setChartData(res, res2, resultRes);
},
async setChartData(nodeList, data, value) {
this.loadChart = false;
let makeData = [];
let makeLinks = [];
this.makeDataAndLink(nodeList, data, value, makeLinks, makeData);
//label에서 보여줄 total 값
var totalVal = 0;
makeLinks.map(item => {
if (item.source == makeData[0].name) {
totalVal += item.value;
}
});
//label , tooltip 셋팅
for (var i = 0; i < makeData.length; i++) {
makeData[i]['label'] = {
show: true,
formatter: function(obj) {
var retVal = makeLinks.filter(n => {
return n.target == obj.name;
});
return (
obj.name +
'\n' +
(obj.name == makeData[0].name
? Utility.setFormatIntDecimal(totalVal, 2)
: Utility.setFormatIntDecimal(retVal[0].value, 2))
);
},
};
makeData[i]['tooltip'] = {
formatter: function(obj) {
var retVal = makeLinks.filter(n => {
return n.target == obj.name;
});
return (
obj.name +
'\n' +
(obj.name == makeData[0].name
? Utility.setFormatIntDecimal(totalVal, 2)
: Utility.setFormatIntDecimal(retVal[0].value, 2)
)
.toString()
.bold()
);
},
};
}
const chartOption = {
backgroundColor: '#FFFFFF',
series: [
{
layoutIterations: 0,
type: 'sankey',
left: 25.0,
top: 20.0,
right: 120,
bottom: 50.0,
// nodeWidth:10,
nodeGap: 10,
nodeAlign: 'left',
data: makeData,
links: makeLinks,
lineStyle: {
color: 'source',
curveness: 0.5,
},
// triggerEvent: true,
itemStyle: {
//color: '#1f77b4',
//borderColor: '#1f77b4'
},
label: {
color: this.isDarkMode
? 'rgba(250,250,250,0.7)'
: 'rgba(0,0,0,0.7)',
fontFamily: 'Arial',
fontSize: 12,
},
},
],
tooltip: {
trigger: 'item',
},
};
this.setChartOption({ chartKey: this.chartName, value: chartOption });
this.loadChart = true;
},
makeDataAndLink(nodeList, data, value, makeLinks, makeData) {
var makeTempData = [];
var tempMakeLinks = [];
nodeList.map(item => {
makeTempData.push({
name: item.nodeName,
});
});
var cnt = 0;
data.map(item => {
tempMakeLinks.push({
source: item.sourceName,
target: item.tartgetName,
value: parseFloat(value[cnt++]),
});
});
// var resultArr = parentList.filter((item, index)=>{
// console.log("index :",parentList.indexOf(item))
// console.log("##",parentList.indexOf(item) === index)
// return parentList.indexOf(item) === index;
// });
//1차 정렬
tempMakeLinks.sort(function(a, b) {
if (a.source == b.source) {
return b.value - a.value;
}
});
tempMakeLinks.filter(item => {
if (item.source == makeTempData[0].name) {
makeLinks.push(item);
}
});
//2차 정렬
makeSort(makeLinks, tempMakeLinks);
makeLinks.map(item => {
makeData.push({ name: item.target });
});
makeData.unshift(makeTempData[0]);
//
function makeSort(list, b) {
for (var i = 0; i < list.length; i++) {
b.filter(item => {
if (item.source == list[i].target) {
makeLinks.push(item);
}
});
}
}
},
},
};
const defaultData = {
isFind: false,
cmCycle: 'CYC_DAY', // 주기
defaultRange: {
CYC_DAY: 30,
},
fromDt: '',
toDt: Utility.setFormatDate(new Date(), 'YYYYMMDD'),
sankeyChartList: [],
sankeyChartSno: null,
sankeyChart: {
tooltip: {
trigger: 'axis',
confine: true,
axisPointer: {
type: 'shadow',
},
},
grid: {
left: '0',
right: '0',
top: '0',
},
legend: null,
series: [],
title: {},
backgroundColor: '',
},
};
</script>
<style lang="scss">
// .icon-arrow {
// display:inline-block;
// position: relative;
// height: 60px;
// // top: 20px;
// // left: 0;
// }
// .arrowText{
// // align-items: center;
// display: inline-block;
// flex-wrap: wrap;
// font-size: 1.25rem;
// font-weight: 700;
// letter-spacing: 0.0125em;
// line-height: 1.5;
// word-break: break-all;
// position: relative;
// line-height:60px;
// }
.arrow-right {
width: 100%;
height: 35px;
display: flex;
}
.arrow-right:before {
content: '';
background: #594dff;
width: 100%;
clip-path: polygon(
0 10px,
calc(100% - 15px) 10px,
calc(100% - 15px) 0,
100% 50%,
calc(100% - 15px) 100%,
calc(100% - 15px) calc(100% - 10px),
0 calc(100% - 10px)
);
}
</style>

View File

@ -0,0 +1,901 @@
<template>
<div class="l-layout">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="3">
<!-- 설비종류 -->
<component
:is="'SelectBox'"
:propsValue="selectValue01"
:itemList="selectValueList01"
:label="'설비종류'"
@update:propsValue="selectValue01 = $event"
/>
</v-col>
<v-col :cols="3">
<!-- 설비그룹 -->
<component
:is="'SelectBox'"
:propsValue="selectValue02"
:itemList="selectValueList02"
:label="'설비그룹'"
@update:propsValue="selectValue02 = $event"
/>
</v-col>
<v-col :cols="3">
<!-- FAB -->
<component
ref="fabSelect"
:is="'SelectBoxMulti'"
:propsValue="selectValue03"
:itemList="selectValueList03"
:label="'FAB'"
:multiple="fabMultiple"
@update:propsValue="selectValue03 = $event"
/>
</v-col>
<v-col :cols="3" class="text-right">
<!-- 조회버튼 -->
<v-btn class="d-inline-flex" @click="createExcel()">엑셀</v-btn>
<BtnSearch @click="search" />
</v-col>
</v-row>
<v-row align="center" no-gutters>
<v-col :cols="3">
<!-- 효율지표 -->
<component
ref="effcIdxSelect"
:is="'SelectBoxMulti'"
:propsValue="selectValue04"
:itemList="selectValueList04"
:label="'효율지표'"
:multiple="effcIdxMultiple"
@update:propsValue="selectValue04 = $event"
/>
</v-col>
<v-col :cols="4">
<!-- 대상일 -->
<component
:is="'Datepicker'"
:parentPrgmId="myPrgmId"
:label="'대상일'"
:labelCols="3"
/>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents">
<v-col :cols="12" style="height: 50%">
<v-card class="pb-5 v-card v-sheet theme--dark">
<div class="d-flex align-center justify-space-between pa-5">
<v-card-title class="pa-0">설비그룹 효율지표 Trend</v-card-title>
</div>
<div ref="chartParent" style="height: 80%">
<component
:ref="chartName01"
class="w100 h100"
:is="loadChart01 ? 'Chart' : null"
:parentPrgmId="myPrgmId"
:chartName="chartName01"
/>
</div>
</v-card>
</v-col>
<v-col :cols="12" style="height: 50%">
<v-card class="pb-5 v-card v-sheet theme--dark">
<div class="d-flex align-center justify-space-between pa-5">
<v-row>
<v-col :cols="3">
<v-card-title class="pa-0">설비별 효율지표 Trend</v-card-title>
</v-col>
<v-col :cols="5"></v-col>
<v-col :cols="3">
<component
class="text-right"
ref="EqpmSelectPop"
:is="'EqpmSelectPop'"
:label="'설비'"
:labelCols="1"
:textCols="10"
:valueNm="'eqpmId'"
:parentPrgmId="myPrgmId"
:eqpmGrpDisabled="true"
:fabDisabled="true"
:iconShow="false"
:isMulti="true"
/>
</v-col>
<v-col :cols="1">
<v-btn @click="getEqpmData()">조회</v-btn>
</v-col>
</v-row>
</div>
<div ref="chartParent" style="height: 80%">
<component
class="w100 h100"
:is="loadChart02 ? 'Chart' : null"
:parentPrgmId="myPrgmId"
:chartName="chartName02"
:ref="chartName02"
/>
</div>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script>
import mixinGlobal from '@/mixin/global.js';
import { resize } from '@/mixin/resize.js';
import { mapActions, mapMutations } from 'vuex';
import BtnSearch from '~/components/common/button/BtnSearch';
import Buttons from '~/components/common/button/Buttons';
import SelectBox from '@/components/common/select/SelectBox';
import SelectBoxMulti from '@/components/common/select/SelectBoxMulti';
import Utility from '~/plugins/utility';
import Datepicker from '~/components/common/Datepicker';
import BtnExcelDownload from '~/components/common/button/BtnExcelDownload';
import Chart from '~/components/common/Chart';
import EqpmSelectPop from '~/components/common/modal/EqpmSelectPop';
import DateUtility from '~/plugins/dateUtility';
import XLSX from 'xlsx';
let myTitle;
let myPrgmId;
export default {
mixins: [mixinGlobal, resize],
async asyncData(context) {
const myState = context.store.state;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
BtnSearch,
Buttons,
SelectBox,
Utility,
Datepicker,
BtnExcelDownload,
Chart,
SelectBoxMulti,
EqpmSelectPop,
DateUtility,
XLSX,
},
data() {
return {
myPrgmId: myPrgmId,
selectValue01: null,
selectValue02: null,
selectValue03: [],
selectValue04: [],
selectValueList01: [],
selectValueList02: [],
selectValueList03: [],
selectValueList04: [],
gridName: 'eqpmGrdGrid',
loadChart01: false,
loadChart02: false,
chartName01: 'eqpmGrpChart',
chartName02: 'eqpmChart',
fabMultiple: true,
effcIdxMultiple: true,
xlsData: [],
xlsHeader: [],
eqpmGrpObj: {},
eqpmKindObj: {},
};
},
computed: {
chkIsFind() {
// 조회 플래그
return this.pageData.isFind;
},
chkIsFind2() {
// 설비팝업 조회 플래그
return this.pageData.isFind2;
},
chkFromDt() {
return this.pageData.fromDt;
},
chkToDt() {
return this.pageData.toDt;
},
},
watch: {
chkIsFind(val) {
if (val) this.search();
},
chkIsFind2(val) {
// 설비팝업 조회 플래그
if (val) this.getEqpmData();
},
async selectValue01(val) {
if (this.initedFlag) {
this.setPageData({
eqpmKindId: val,
eqpmGrpId: '',
});
await this.getEqpmGrp();
}
},
async selectValue02(val) {
if (this.initedFlag) {
this.setPageData({
eqpmGrpId: val,
eqpmId: [],
eqpmIdList: [],
});
this.setPageData({ isFind: true });
}
},
async selectValue03(val) {
if (this.selectValue04.length > 1) {
if (this.selectValue03.length > 1) {
this.selectValue03.shift();
}
}
if (this.selectValue03.length != 0) {
if (this.initedFlag) {
this.setPageData({
fabId: val,
eqpmId: [],
eqpmIdList: [],
});
this.setPageData({ isFind: true });
}
}
},
async selectValue04(val) {
if (this.selectValue03.length > 1) {
if (this.selectValue04.length > 1) {
this.selectValue04.shift();
}
}
if (this.selectValue04.length == 0) {
return;
}
if (this.initedFlag) {
this.setPageData({ isFind: true });
}
},
chkToDt(val) {
var diff = DateUtility.diff(
this.pageData.fromDt,
this.pageData.toDt,
'd',
);
if (diff < 6 && diff > 0) {
this.setPageData({
toDt: DateUtility.addDate(6, 'd', this.pageData.fromDt),
isCheck: true,
});
}
},
chkFromDt(val) {
var diff = DateUtility.diff(
this.pageData.fromDt,
this.pageData.toDt,
'd',
);
if (diff < 6 && diff > 0) {
this.setPageData({
fromDt: DateUtility.addDate(-6, 'd', this.pageData.toDt),
isCheck: true,
});
}
},
},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
created() {},
async mounted() {
await this.init();
this.initedFlag = true;
},
beforeDestroy() {
this.chkOpenTabList({ key: 'destroy', prgmId: myPrgmId });
},
methods: {
...mapMutations({
setChartOption: 'setChartOption',
setChartDataZoom: 'setChartDataZoom',
setPageData: 'setPageData',
setChartXAxisData: 'setChartXAxisData',
setChartYAxisData: 'setChartYAxisData',
setChartSeries: 'setChartSeries',
}),
...mapActions({
getCodeList: 'modules/search/getCodeList',
}),
async init() {
await this.getFab();
await this.getEqpmKind();
await this.getEqpmGrp();
await this.getEffcIdx();
this.setFromDt();
// await this.getData();
},
async search() {
// await this.getRowGridData();
if (this.selectValue03.length > 0 && this.selectValue04.length > 0) {
await this.getEqpmGrpData();
await this.getEqpmData();
}
this.setPageData({
isFind: false,
});
},
setFromDt() {
this.pageData.fromDt = Utility.setBeforetDate(
this.pageData,
this.pageData.toDt,
'YYYYMMDD',
);
// this.setPageData({
// toDt : DateUtility.addDate(6, 'd', this.pageData.fromDt)
// })
// this.pageData.toDt = Utility.setAftertDate(this.pageData, this.pageData.fromDt, "YYYYMMDD");
},
async getEqpmKind() {
let res = await this.postApiReturn({
apiKey: 'selectEqpmKindCodeList',
resKey: 'eqpmKindCodeLists',
sendParam: {},
});
var tmpData = {};
if (res.length > 0) {
this.selectValueList01 = await res.map(item => {
tmpData[item.eqpmKindId] = item.eqpmKindNm;
return {
text: item.eqpmKindNm,
value: item.eqpmKindId,
};
});
this.selectValue01 = this.selectValueList01[0].value;
} else {
this.selectValueList01 = [];
this.selectValue01 = null;
}
this.eqpmKindObj = tmpData;
this.setPageData({
eqpmKindList: this.selectValueList01,
eqpmKindId: this.selectValue01,
});
},
async getFab() {
let res = await this.postApiReturn({
apiKey: 'selectFabCodeList',
resKey: 'fabCodeLists',
sendParam: {},
});
if (res.length > 0) {
this.selectValueList03 = await res.map(item => {
return {
text: item.eccNm,
value: item.eccId,
};
});
// if(this.pageData.eccId != null && this.pageData.eccId != ''){
// this.selectValue02 = this.pageData.eccId;
// }else if(this.pageData.eccId == null || this.pageData.eccId == ''){
this.selectValue03.push(this.selectValueList03[0].value);
// }
} else {
this.selectValueList03 = [];
this.selectValue03 = [];
}
this.setPageData({
fabIdList: this.selectValueList03,
fabId: this.selectValue03,
});
},
async getEqpmGrp() {
let res = await this.postApiReturn({
apiKey: 'selectEqpmGrpCodeList',
resKey: 'eqpmGrpCodeLists',
sendParam: { eqpmKindId: this.selectValue01 },
});
var tmpData = {};
if (res.length > 0) {
this.selectValueList02 = await res.map(item => {
tmpData[item.eqpmGrpId] = item.eqpmGrpNm;
return {
text: item.eqpmGrpNm,
value: item.eqpmGrpId,
};
});
// this.selectValue02 = this.pageData.eqpmGrpId;
// }else if(this.pageData.eqpmGrpId == null || this.pageData.eqpmGrpId == ''){
this.selectValue02 = this.selectValueList02[0].value;
// }
} else {
this.selectValueList02 = [];
this.selectValue02 = null;
}
this.eqpmGrpObj = tmpData;
this.setPageData({
eqpmGrpList: this.selectValueList02,
eqpmGrpId: this.selectValue02,
});
},
async getEffcIdx() {
let res = await this.postApiReturn({
apiKey: 'selectEffcIdxCodeList',
resKey: 'effcIdxCodeList',
sendParam: {},
});
if (res.length > 0) {
this.selectValueList04 = await res.map(item => {
return {
text: item.effcIdxNm,
value: item.effcIdxId,
};
});
this.selectValue04.push(this.selectValueList04[0].value);
} else {
this.selectValueList04 = [];
this.selectValue02 = [];
}
this.setPageData({
effcIdxIdList: this.selectValueList02,
effcIdxId: this.selectValue02,
});
},
async getEqpmGrpData() {
//설비그룹 trend
let res = await this.postApiReturn({
apiKey: 'selectEffcIdxEgrpTrend',
resKey: 'egrpTrendData',
sendParam: {
fabId: this.selectValue03,
eqpmGrpId: this.selectValue02,
effcIdxId: this.selectValue04,
fromDt: this.pageData.fromDt,
toDt: this.pageData.toDt,
},
});
this.setPageData({
chartData01: res,
});
this.setChartData(res);
},
async getEqpmData() {
//설비별 Trend
let res = await this.postApiReturn({
apiKey: 'selectEffcIdxEqpmTrend',
resKey: 'eqpmTrendData',
sendParam: {
fabId: this.selectValue03,
eqpmGrpId: this.selectValue02,
effcIdxId: this.selectValue04,
fromDt: this.pageData.fromDt,
toDt: this.pageData.toDt,
eqpmId: this.pageData.eqpmId,
},
});
this.setPageData({
chartData02: res,
isFind2: false,
});
this.setChartData2(res);
},
setExcelData(data, type) {
var xlsRowData = [];
var xlsHeader = [];
var diff = DateUtility.diff(
this.pageData.fromDt,
this.pageData.toDt,
'd',
);
var totVal = [];
xlsRowData = data;
if (type == 'eqpmGrp') {
xlsHeader.push({
header: '설비종류',
name: 'eqpmKindNm',
});
xlsHeader.push({
header: '설비그룹',
name: 'eqpmGrpNm',
});
xlsHeader.push({
header: 'FAB',
name: 'fabNm',
});
xlsHeader.push({
header: '효율지표',
name: 'effcIdxNm',
});
} else if (type == 'eqpm') {
xlsHeader.push({
header: '설비종류',
name: 'eqpmKindNm',
});
xlsHeader.push({
header: '설비그룹',
name: 'eqpmGrpNm',
});
xlsHeader.push({
header: '설비',
name: 'eqpmNm',
});
xlsHeader.push({
header: '효율지표',
name: 'effcIdxNm',
});
}
for (var i = 0; i < diff + 1; i++) {
var date = DateUtility.addDate(i, 'YYYY/MM/DD', this.pageData.fromDt);
xlsHeader.push({
header: date,
name: date,
});
totVal.push(0);
}
var exceptionColumList = [
'effcIdxNm',
'fabNm',
'eqpmKindNm',
'eqpmGrpNm',
'eqpmNm',
];
let myKey = xlsHeader.map(item => {
return item.name;
});
myKey = myKey.filter(v => {
return !exceptionColumList.includes(v);
});
let tmpData = [];
let tmpMap = {};
let excelMap = {};
if (type == 'eqpmGrp') {
xlsRowData.map(item => {
if (tmpMap[item.fabEffcNm] == null) {
tmpMap[item.fabEffcNm] = {
...item,
totVal: [...totVal],
};
}
});
xlsRowData.map(item => {
if (tmpMap[item.fabEffcNm] != undefined) {
tmpMap[item.fabEffcNm]['totVal'][
myKey.indexOf(Utility.setFormatDate(item.totDttm, 'YYYY/MM/DD'))
] = item.totVal;
}
});
} else if (type == 'eqpm') {
xlsRowData.map(item => {
if (tmpMap[item.eqpmEffcNm] == null) {
tmpMap[item.eqpmEffcNm] = {
...item,
totVal: [...totVal],
};
}
});
xlsRowData.map(item => {
if (tmpMap[item.eqpmEffcNm] != undefined) {
tmpMap[item.eqpmEffcNm]['totVal'][
myKey.indexOf(Utility.setFormatDate(item.totDttm, 'YYYY/MM/DD'))
] = item.totVal;
}
});
}
var tmpMapKey = Object.keys(tmpMap);
for (var i = 0; i < tmpMapKey.length; i++) {
excelMap['설비종류'] = this.eqpmKindObj[this.selectValue01];
excelMap['설비그룹'] = this.eqpmGrpObj[this.selectValue02];
if (type == 'eqpmGrp') {
excelMap['FAB'] = tmpMap[tmpMapKey[i]].fabNm;
} else if (type == 'eqpm') {
excelMap['설비'] = tmpMap[tmpMapKey[i]].eqpmNm;
}
excelMap['효율지표'] = tmpMap[tmpMapKey[i]].effcIdxNm;
var count = 0;
tmpMap[tmpMapKey[i]].totVal.map(v => {
excelMap[myKey[count]] = v;
count++;
});
tmpData.push(excelMap);
excelMap = {};
}
var newXlsHeader = [];
xlsHeader.map(v => {
newXlsHeader.push(String(v.header));
});
return { data: tmpData, header: newXlsHeader };
},
createExcel() {
let fileName = '에너지보고서';
const workBook = XLSX.utils.book_new(); // 새 시트 생성
var chartData = this.setExcelData(this.pageData.chartData01, 'eqpmGrp');
let excelData = XLSX.utils.json_to_sheet(chartData.data, {
header: chartData.header,
});
XLSX.utils.book_append_sheet(
workBook,
excelData,
'설비그룹_효율지표Trend',
); // 시트 명명, 데이터 지정
chartData = this.setExcelData(this.pageData.chartData02, 'eqpm');
excelData = XLSX.utils.json_to_sheet(chartData.data, {
header: chartData.header,
});
XLSX.utils.book_append_sheet(workBook, excelData, '설비별_효율지표Trend'); // 시트 명명, 데이터 지정
XLSX.writeFile(
workBook,
`${fileName ? fileName : this.menuNm.replace(/(\s*)/g, '')}.xlsx`,
); // 엑셀파일 만듬
},
async setChartData(data) {
this.loadChart01 = false;
let xAxisData = [];
let seriesData = [];
var diff = DateUtility.diff(
this.pageData.fromDt,
this.pageData.toDt,
'd',
);
var totVal = [];
for (var i = 0; i < diff + 1; i++) {
xAxisData.push(DateUtility.addDate(i, 'DD', this.pageData.fromDt));
totVal.push(0);
}
var tempData = {};
data.map(item => {
if (tempData[item.fabEffcNm] == null) {
tempData[item.fabEffcNm] = {
...item,
totVal: [...totVal],
};
}
});
data.map(item => {
if (tempData[item.fabEffcNm] != undefined) {
tempData[item.fabEffcNm]['totVal'][
xAxisData.indexOf(Utility.setFormatDate(item.totDttm, 'DD'))
] = item.totVal;
}
});
var keys = Object.keys(tempData);
for (var i = 0; i < keys.length; i++) {
seriesData.push({
name: tempData[keys[i]].fabEffcNm,
type: 'line',
data: tempData[keys[i]].totVal,
});
}
var dataZoom = [];
if (xAxisData.length > 7) {
dataZoom = [
{
type: 'inside',
disabled: false,
start: 0,
end: parseInt(700 / xAxisData.length) - 1,
},
{
show: true,
moveOnMouseMove: true,
start: 0,
end: parseInt(700 / xAxisData.length) - 1,
},
];
} else {
dataZoom = [
{
type: 'inside',
disabled: true,
start: 0,
end: parseInt(700 / xAxisData.length) - 1,
},
{
show: false,
moveOnMouseMove: false,
start: 0,
end: parseInt(700 / xAxisData.length) - 1,
},
];
}
var chartOption = {
legend: {
top: 'top',
},
grid: {
top: '10%',
bottom: '20%',
},
yAxis: {},
xAxis: {
data: xAxisData,
},
series: seriesData,
tooltip: {},
dataZoom: dataZoom,
};
this.setChartOption({ chartKey: this.chartName01, value: chartOption });
// this.setChartYAxisData({ chartKey: this.chartName01, value: yAxisData });
// this.setChartXAxisData({ chartKey: this.chartName01, value: xAxisData });
// this.setChartSeries({ chartKey: this.chartName01, value: seriesData });
this.$nextTick(() => {
this.loadChart01 = true;
});
},
async setChartData2(data) {
this.loadChart02 = false;
let xAxisData = [];
let seriesData = [];
var diff = DateUtility.diff(
this.pageData.fromDt,
this.pageData.toDt,
'd',
);
var totVal = [];
for (var i = 0; i < diff + 1; i++) {
xAxisData.push(DateUtility.addDate(i, 'DD', this.pageData.fromDt));
totVal.push(0);
}
var tempData = {};
data.map(item => {
if (tempData[item.eqpmEffcNm] == null) {
tempData[item.eqpmEffcNm] = {
...item,
totVal: [...totVal],
};
}
});
data.map(item => {
if (tempData[item.eqpmEffcNm] != undefined) {
tempData[item.eqpmEffcNm]['totVal'][
xAxisData.indexOf(Utility.setFormatDate(item.totDttm, 'DD'))
] = item.totVal;
}
});
var keys = Object.keys(tempData);
for (var i = 0; i < keys.length; i++) {
seriesData.push({
name: tempData[keys[i]].eqpmEffcNm,
type: 'line',
data: tempData[keys[i]].totVal,
});
}
var dataZoom = [];
if (xAxisData.length > 7) {
dataZoom = [
{
type: 'inside',
disabled: false,
start: 0,
end: parseInt(700 / xAxisData.length) - 1,
},
{
show: true,
moveOnMouseMove: true,
start: 0,
end: parseInt(700 / xAxisData.length) - 1,
},
];
} else {
dataZoom = [
{
type: 'inside',
disabled: true,
start: 0,
end: parseInt(700 / xAxisData.length) - 1,
},
{
show: false,
moveOnMouseMove: false,
start: 0,
end: parseInt(700 / xAxisData.length) - 1,
},
];
}
var chartOption = {
legend: {
top: 'top',
},
grid: {
top: '10%',
bottom: '20%',
},
yAxis: {},
xAxis: {
data: xAxisData,
},
series: seriesData,
tooltip: {},
dataZoom: dataZoom,
};
this.setChartOption({ chartKey: this.chartName02, value: chartOption });
// this.setChartDataZoom({chartKey : this.chartName02,value: dataZoom});
this.$nextTick(() => {
this.loadChart02 = true;
});
},
},
};
const defaultData = {
isFind: false,
isFind2: false,
fabId: [],
fabIdList: [],
fabNm: '',
chartData01: [],
chartData02: [],
// eccId:'',
// eccIdList:[],
eqpmGrpNm: '',
eqpmGrpId: '',
eqpmGrpList: [],
eqpmId: [],
eqpmIdList: [],
eqpmNm: '',
eqpmKindId: '',
effcIdxId: '',
cmCycle: 'CYC_DAY', // 주기
defaultRange: {
CYC_DAY: 30,
},
fromDt: '',
toDt: Utility.setFormatDate(new Date(), 'YYYYMMDD'),
modalData: {},
eqpmGrpChart: Utility.defaultChartOption(true),
eqpmChart: Utility.defaultChartOption(true),
};
</script>

View File

@ -0,0 +1,927 @@
<template>
<div ref="mainDiv" class="l-layout">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="2">
<component
:is="'SelectBox'"
ref="SelectBox1"
:propsValue="selectValue01"
:itemList="selectValueList01"
:label="'FAB'"
@update:propsValue="selectValue01 = $event"
/>
</v-col>
<v-col :cols="2">
<component
:is="'SelectBox'"
ref="SelectBox2"
:propsValue="selectValue02"
:itemList="selectValueList02"
:label="'설비종류'"
@update:propsValue="selectValue02 = $event"
/>
</v-col>
<v-col :cols="2">
<component
:is="'SelectBox'"
ref="SelectBox3"
:propsValue="selectValue03"
:itemList="selectValueList03"
:label="'설비그룹'"
@update:propsValue="selectValue03 = $event"
/>
</v-col>
<v-col :cols="2">
<component
:is="'SelectBox'"
ref="SelectBox4"
:propsValue="selectValue04"
:itemList="selectValueList04"
:label="'설비'"
@update:propsValue="selectValue04 = $event"
/>
</v-col>
<v-col :cols="1">
<component
:is="'SelectCmCycle'"
:parentPrgmId="myPrgmId"
:labelCols="5"
:textCols="7"
:label="'구분'"
/>
</v-col>
<v-col :cols="2">
<component
:is="'DatePicker'"
:label="'대상년월'"
:parentPrgmId="myPrgmId"
:isRangeOption="false"
/>
</v-col>
<v-col :cols="1" class="text-right">
<v-btn :ripple="false" @click="search()">조회</v-btn>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents" style="height: calc(100vh - 230px)">
<v-col :cols="12" style="height: 100%;">
<v-row class="pa-1" style="height:33%; width:100%">
<v-card class="pa-1" style="height: 100%; width:100%">
<div style="height: 100%">
<div style="height:25%">
<v-card-title
class="d-flex align-center justify-space-between pa-5"
>
<span class="tit ft-size_20 ft-weight_600"
>주요가이드 지표</span
>
</v-card-title>
</div>
<div style="height:75%; ">
<v-row style="height:100%; overflow: auto;">
<v-col
:cols="3"
style="height:100%;"
v-for="(value, key, index) in contentData01"
:key="'key1' + index"
>
<div
class="v-box"
style="height: 100%; padding:3px; margin:2px"
>
<v-col :cols="12" style="height:100%">
<div style="height:20%">
{{ value['gdIdxNm'] }}
</div>
<div style="height:80%">
<component
class="w100 h100"
:is="loadChart ? 'Chart' : null"
:parentPrgmId="myPrgmId"
:chartName="'chartGroup01_' + value['gdIdxId']"
:ref="'chartGroup01_' + value['gdIdxId']"
/>
</div>
</v-col>
</div>
</v-col>
</v-row>
</div>
</div>
</v-card>
</v-row>
<v-row class="pa-1" style="height:33%; width:100%">
<v-card class="pa-1" style="height: 100%; width:100%">
<div style="height : 25%">
<v-card-title
class="d-flex align-center justify-space-between pa-5"
>
<span class="tit ft-size_20 ft-weight_600"
>가이드 알람정보</span
>
</v-card-title>
</div>
<div ref="gridParent01" style="height : 75%">
<component
:ref="gridName01"
:is="loadGrid01 ? 'Grid' : null"
:gridName="gridName01"
:parentPrgmId="myPrgmId"
/>
</div>
</v-card>
</v-row>
<v-row class="pa-1" style="height:34%; width:100%">
<div style="height: 100%; width:100%">
<v-row style="height: 100%">
<v-col :cols="5" class="">
<v-card class="pa-1" style="height: 100%; width:100%">
<div style="height: 25%">
<v-card-title
class="d-flex align-center justify-space-between pa-5"
>
<span class="tit ft-size_20 ft-weight_600"
>설비 상세 정보</span
>
</v-card-title>
</div>
<div ref="gridParent02" style="height: 75%">
<component
:ref="gridName02"
:is="loadGrid02 ? 'Grid' : null"
:gridName="gridName02"
:parentPrgmId="myPrgmId"
@getRowsData="getRowData02"
/>
</div>
</v-card>
</v-col>
<v-col :cols="7" class="">
<v-card class="pa-1" style="height: 100%; width:100%">
<div style="height: 25%">
<v-card-title
class="d-flex align-center justify-space-between pa-5"
>
<span class="tit ft-size_20 ft-weight_600"
>시간별 TREND 정보</span
>
</v-card-title>
</div>
<div ref="trendChartParent" style="height: 75%">
<component
class="w100 h100"
:is="loadTrendChart ? 'Chart' : null"
:parentPrgmId="myPrgmId"
:chartName="'trendChart'"
/>
</div>
</v-card>
</v-col>
</v-row>
</div>
</v-row>
</v-col>
</v-row>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex';
import mixinGlobal from '@/mixin/global.js';
import { resize } from '@/mixin/resize.js';
import Utility from '~/plugins/utility';
import SelectBox from '@/components/common/select/SelectBox';
import SelectCmCycle from '@/components/common/select/SelectCmCycle';
import DatePicker from '@/components/common/Datepicker';
import Grid from '~/components/common/Grid';
import Chart from '~/components/common/Chart';
let myTitle;
let myPrgmId;
let paramKey;
export default {
mixins: [mixinGlobal, resize],
async asyncData(context) {
const myState = context.store.state;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
Utility,
SelectBox,
SelectCmCycle,
DatePicker,
Grid,
Chart,
},
data() {
return {
myPrgmId: myPrgmId,
initedFlag: false,
queryParams: null,
selectValueList01: [],
selectValueList02: [],
selectValueList03: [],
selectValueList04: [],
selectValue01: null,
selectValue02: null,
selectValue03: null,
selectValue04: null,
contentData01: {},
loadGrid01: false,
loadGrid02: false,
gridName01: 'grid01',
gridName02: 'grid02',
loadTrendChart: false,
};
},
computed: {
...mapState({
pageData: state => state.pageData[myPrgmId],
}),
fromDt() {
return this.pageData.fromDt;
},
},
watch: {
async $route(to, from) {
if (to.query.prgmId == myPrgmId) {
if (to.params.key) {
document.getElementById('refresh').click();
}
}
},
async selectValue01(value) {
if (this.initedFlag) {
// await this.search();
await this.getSelectValueList04();
}
},
async selectValue02(value) {
if (this.initedFlag) {
await this.getSelectValueList03();
}
},
async selectValue03(value) {
if (this.initedFlag) {
await this.getSelectValueList04();
}
},
async selectValue04(value) {
if (this.initedFlag) {
await this.search();
}
},
async fromDt(value) {
if (this.initedFlag) {
await this.search();
}
},
},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
created() {},
mounted() {
this.init();
},
beforeDestroy() {
this.initedFlag = false;
this.chkOpenTabList({ key: 'destroy', prgmId: myPrgmId });
},
methods: {
...mapMutations({
setChartOption: 'setChartOption',
}),
async init() {
await this.getSelectValueList();
await this.setQueryParams();
await this.search();
this.initedFlag = true;
},
async setQueryParams() {
this.queryParams = null;
if (paramKey == this.$route.params.key) {
return;
}
if (this.$route.params.key) {
paramKey = this.$route.params.key;
this.queryParams = this.$route.params;
}
if (this.queryParams && typeof this.queryParams == 'object') {
this.setPageData({
dateInitedFlag: true,
});
this.selectValue01 = this.queryParams['fabId'];
this.selectValue02 = this.queryParams['eqpmKindId'];
await this.getSelectValueList03();
this.selectValue03 = this.queryParams['eqpmGrpId'];
await this.getSelectValueList04();
this.selectValue04 = this.queryParams['eqpmId'];
this.setPageData({
fromDt: this.queryParams['fromDt'],
cmCycle: this.queryParams['cmCycle'],
});
}
},
async getSelectValueList() {
await this.getSelectValueList01();
await this.getSelectValueList02();
await this.getSelectValueList03();
await this.getSelectValueList04();
},
async getSelectValueList01() {
let res = await this.postApiReturn({
apiKey: 'selectFabCodeList',
resKey: 'fabCodeLists',
sendParam: {},
});
if (res.length > 0) {
this.selectValueList01 = await res.map(item => {
return {
text: item.eccNm,
value: item.eccId,
};
});
this.selectValue01 = this.selectValueList01[0].value;
} else {
this.selectValueList01 = [];
this.selectValue01 = null;
}
},
async getSelectValueList02() {
var res = await this.postApiReturn({
apiKey: 'selectEmsEqpmKindList',
resKey: 'eqpmGrpPysclQtyMngData',
sendParam: {},
});
if (res.length > 0) {
this.selectValueList02 = await res.map(item => {
return {
text: item.eqpmKindNm,
value: item.eqpmKindId,
data: {
...item,
},
};
});
this.selectValue02 = this.selectValueList02[0].value;
} else {
this.selectValueList02 = [];
this.selectValue02 = null;
}
},
async getSelectValueList03() {
var res = await this.postApiReturn({
apiKey: 'selectEmsEqpmGrpList',
resKey: 'eqpmGrpPysclQtyMngData',
sendParam: {
eqpmKindId: this.selectValue02,
},
});
if (res.length > 0) {
this.selectValueList03 = await res.map(item => {
return {
text: item.eqpmGrpNm,
value: item.eqpmGrpId,
data: {
...item,
},
};
});
this.selectValue03 = this.selectValueList03[0].value;
} else {
this.selectValueList03 = [];
this.selectValue03 = null;
}
},
async getSelectValueList04() {
var res = await this.postApiReturn({
apiKey: 'selectFabEqpmList',
resKey: 'enrgUseEqpmDetlMntrData',
sendParam: {
fabId: this.selectValue01,
eqpmGrpId: this.selectValue03,
},
});
if (res.length > 0) {
this.selectValueList04 = await res.map(item => {
return {
text: item.eqpmNm,
value: item.eqpmId,
data: {
...item,
},
};
});
this.selectValue04 = this.selectValueList04[0].value;
} else {
this.selectValueList04 = [];
this.selectValue04 = null;
}
},
async search() {
// console.log('search ...');
// console.log('selectValue01 : ', this.selectValue01);
// console.log('selectValue02 : ', this.selectValue02);
// console.log('selectValue03 : ', this.selectValue03);
// console.log('selectValue04 : ', this.selectValue04);
// console.log('cmCycle : ', this.pageData.cmCycle);
// console.log('fromDt : ', this.fromDt);
await this.setContentData();
this.setPageData({
dateInitedFlag: false,
});
},
async setContentData() {
await this.setContentData01();
await this.setContentData02();
await this.setContentData03();
// await this.setContentData04();
},
async setContentData01() {
var apiKey = null;
var res = null;
this.contentData01 = {};
if (this.pageData.cmCycle == 'CYC_DAY') {
apiKey = 'selectDailyEnrgUseMainGuideIdx';
} else if (this.pageData.cmCycle == 'CYC_MONTH') {
apiKey = 'selectMonthlyEnrgUseMainGuideIdx';
}
res = await this.postApiReturn({
apiKey: apiKey,
resKey: 'enrgUseEqpmDetlMntrData',
sendParam: {
eqpmGrpId: this.selectValue03,
eqpmId: this.selectValue04,
fromDt: this.fromDt,
},
});
this.contentData01 = await this.makeContentData01(res);
this.setChartGroup01(this.contentData01);
},
async setContentData02() {
const _this = this;
const myOptions = {
columnOptions: {
resizable: true,
},
};
const gridHeight = this.$refs.mainDiv.offsetHeight * 0.17;
var columnList = [
{ header: 'NO', name: 'no', width: 40, align: 'center' },
{ header: 'gdIdxId', name: 'gdIdxId', hidden: true },
{ header: 'totDttm', name: 'totDttm', hidden: true },
{ header: '발생일', name: 'totDt', width: 150, align: 'center' },
{ header: '발생시간대', name: 'totTm', width: 100, align: 'center' },
{ header: '가이드지표명', name: 'gdIdxNm', width: 200 },
{ header: '가이드값', name: 'totVal', hidden: true },
{ header: '주의값', name: 'caseStndVal', hidden: true },
{ header: '경고값', name: 'warnStndVal', hidden: true },
{ header: '알람종류', name: 'alrmKind', hidden: true },
{ header: '알람내용', name: 'alrmMsg' },
];
var res = [];
var newRes = [];
this.loadGrid01 = false;
res = await this.postApiReturn({
apiKey: 'selectEnrgUseGuideAlarmInfo',
resKey: 'enrgUseEqpmDetlMntrData',
sendParam: {
cmCycle: this.pageData.cmCycle,
eqpmId: this.selectValue04,
fromDt: this.fromDt,
alrmKind: ['WARN', 'CARE'],
},
});
for (var i = 0; i < res.length; i++) {
newRes.push({
...res[i],
no: i + 1,
});
}
this.setGridOption({
gridKey: this.gridName01,
value: Object.assign(Utility.defaultGridOption(gridHeight), myOptions),
});
this.setGridColumn({
gridKey: this.gridName01,
value: columnList,
});
this.setGridData({
gridKey: this.gridName01,
value: newRes,
});
this.loadGrid01 = true;
},
async setContentData03() {
const _this = this;
const myOptions = {
columnOptions: {
resizable: true,
},
};
const gridHeight = this.$refs.mainDiv.offsetHeight * 0.17;
var columnList = [
{ header: 'NO', name: 'no', align: 'center', width: 40 },
{ header: '물리량ID', name: 'pysclQtyId', width: 100, align: 'center' },
{ header: '물리량코드', name: 'pysclQtyCd' },
{ header: '물리량명', name: 'pysclQtyNm', width: 190 },
{ header: '물리량타입', name: 'pysclQtyTp', width: 100 },
];
var res = [];
var newRes = [];
this.loadGrid02 = false;
res = await this.postApiReturn({
apiKey: 'selectEnrgUseEqpmDescInfo',
resKey: 'enrgUseEqpmDetlMntrData',
sendParam: {
eqpmGrpId: this.selectValue03,
},
});
for (var i = 0; i < res.length; i++) {
newRes.push({
...res[i],
no: i + 1,
});
}
this.setGridOption({
gridKey: this.gridName02,
value: Object.assign(Utility.defaultGridOption(gridHeight), myOptions),
});
this.setGridColumn({
gridKey: this.gridName02,
value: columnList,
});
this.setGridData({
gridKey: this.gridName02,
value: newRes,
});
this.loadGrid02 = true;
await this.$nextTick();
this.$refs[this.gridName02].focus({
rowKey: 0,
columnName: 'no',
setScroll: true,
});
},
async setContentData04(selectedData) {
var res = null;
var _this = this;
var xAxisData = null;
var seriesData = null;
var sliderHandleSize = 100;
this.loadTrendChart = false;
xAxisData = this.makeTrendChartXaxisData();
if (this.pageData.cmCycle == 'CYC_MONTH') {
sliderHandleSize = ((24 / xAxisData.length) * 100 * 24) / 25;
}
res = await this.postApiReturn({
apiKey: 'selectEnrgUseHourlyTrendInfo',
resKey: 'enrgUseEqpmDetlMntrData',
sendParam: {
pysclQtyId: selectedData.pysclQtyId,
eqpmId: this.selectValue04,
fromDt: this.fromDt,
cmCycle: this.pageData.cmCycle,
},
});
seriesData = new Array(xAxisData.length).fill(NaN);
for (var i = 0; i < res.length; i++) {
if (this.pageData.cmCycle == 'CYC_MONTH') {
seriesData[res[i]['monthCnt']] = res[i]['totVal'];
} else if (this.pageData.cmCycle == 'CYC_DAY') {
seriesData[res[i]['dayCnt']] = res[i]['totVal'];
}
}
var chartOption = {
grid: {
top: '3%',
bottom: '25%',
},
tooltip: {
axisPointer: {
label: {
formatter: function(value) {
value = value.value;
return (
value.substring(5, 7) +
'월 ' +
value.substring(8, 10) +
'일 ' +
value.substring(11, 13) +
'시'
);
},
},
},
},
xAxis: {
data: xAxisData,
axisLabel: {
formatter: function(value) {
return value.substring(11, 13) + '시';
},
},
axisTick: {
interval: 23,
},
},
yAxis: {
type: 'value',
},
series: [
{
type: 'line',
data: seriesData,
},
],
dataZoom: [
{
type: 'slider',
// zoomLock: true,
zoomLock: false,
brushSelect: false,
start: 0, // 0-100 %
end: sliderHandleSize, // 0-100 %
},
{
type: 'inside',
zoomOnMouseWheel: false,
moveOnMouseMove: false,
moveOnMouseWheel: true,
},
],
};
this.setChartOption({ chartKey: 'trendChart', value: chartOption });
this.loadTrendChart = true;
},
async getRowData02(selectedData) {
await this.setContentData04(selectedData);
},
async makeContentData01(data) {
var result = {};
for (var i = 0; i < data.length; i++) {
if (!result.hasOwnProperty(data[i]['gdIdxId'])) {
result[data[i]['gdIdxId']] = {
gdIdxId: data[i]['gdIdxId'],
gdIdxNm: data[i]['gdIdxNm'],
data: [],
};
result[data[i]['gdIdxId']]['data'].push({
...data[i],
});
} else {
result[data[i]['gdIdxId']]['data'].push({
...data[i],
});
}
}
var idxData = await this.postApiReturn({
apiKey: 'selectEnrgUseMainIdxDesc',
resKey: 'eqpmIndMntrData',
sendParam: {
eqpmGrpId: this.selectValue03,
},
});
for (var i = 0; i < idxData.length; i++) {
if (!result.hasOwnProperty(idxData[i]['gdIdxId'])) {
result[idxData[i]['gdIdxId']] = {
gdIdxId: idxData[i]['gdIdxId'],
gdIdxNm: idxData[i]['gdIdxNm'],
data: [],
};
}
}
return result;
},
async setChartGroup01(data) {
this.loadChart = false;
await this.$nextTick();
this.initChartGroup01(data);
this.setChartGroup01Data(data);
this.loadChart = true;
},
initChartGroup01(data) {
var dataKeyList = Object.keys(data);
var currentChartData = null;
var chartKey = null;
for (var i = 0; i < dataKeyList.length; i++) {
currentChartData = data[dataKeyList[i]];
chartKey = 'chartGroup01_' + currentChartData['gdIdxId'];
this.setPageData({
[chartKey]: this.getGroup01ChartOption(),
});
}
},
setChartGroup01Data(data) {
var dataKeyList = Object.keys(data);
var currentChartData = null;
var chartKey = null;
var xAxisData = null;
var seriesData = null;
xAxisData = this.makeChartGroup01XaxisData();
for (var i = 0; i < dataKeyList.length; i++) {
seriesData = new Array(xAxisData.length).fill(NaN);
currentChartData = data[dataKeyList[i]];
chartKey = 'chartGroup01_' + currentChartData['gdIdxId'];
for (var j = 0; j < currentChartData['data'].length; j++) {
seriesData[currentChartData['data'][j]['dataNum']] =
currentChartData['data'][j]['totVal'];
}
this.$store.state.pageData[myPrgmId][chartKey]['xAxis'][
'data'
] = xAxisData;
this.$store.state.pageData[myPrgmId][chartKey]['series'][0][
'data'
] = seriesData;
}
},
getGroup01ChartOption() {
var chartOption = Utility.defaultChartOption(true);
chartOption['series'][0]['type'] = 'line';
chartOption['grid']['bottom'] = '3%';
// console.log('chartOption : ', chartOption);
return chartOption;
},
makeChartGroup01XaxisData() {
var result = [];
var paramsDt = this.fromDt;
if (this.pageData.cmCycle == 'CYC_MONTH') {
var tempDate = new Date(
paramsDt.substring(0, 4) +
'-' +
paramsDt.substring(4, 6) +
'-01 00:00',
);
var lastDayOfMonth = getLastDayOfMonth(tempDate);
for (var i = 1; i <= lastDayOfMonth; i++) {
result.push(i);
}
} else if (this.pageData.cmCycle == 'CYC_DAY') {
for (var i = 0; i < 24; i++) {
result.push(i);
}
}
return result;
},
makeTrendChartXaxisData() {
var result = [];
var paramsDt = this.fromDt;
var timezoneOffset = new Date().getTimezoneOffset() * 60000;
if (this.pageData.cmCycle == 'CYC_MONTH') {
var tempDate = new Date(
paramsDt.substring(0, 4) +
'-' +
paramsDt.substring(4, 6) +
'-01 00:00',
);
var lastDayOfMonth = getLastDayOfMonth(tempDate);
tempDate = new Date(tempDate - timezoneOffset);
result.push(tempDate.toISOString());
for (var i = 0; i < 24 * lastDayOfMonth - 1; i++) {
tempDate = addHours(1, tempDate);
result.push(tempDate.toISOString());
}
} else if (this.pageData.cmCycle == 'CYC_DAY') {
var tempDate = new Date(
paramsDt.substring(0, 4) +
'-' +
paramsDt.substring(4, 6) +
'-' +
paramsDt.substring(6, 8) +
' 00:00',
);
tempDate = new Date(tempDate - timezoneOffset);
result.push(tempDate.toISOString());
for (var i = 0; i < 23; i++) {
tempDate = addHours(1, tempDate);
result.push(tempDate.toISOString());
}
}
return result;
},
},
};
function addHours(h, date) {
date.setTime(date.getTime() + h * 60 * 60 * 1000);
return date;
}
function getLastDayOfMonth(date) {
return new Date(
new Date(date.getFullYear(), date.getMonth() + 1, 1) - 1,
).getDate();
}
const defaultData = {
dateInitedFlag: false,
cmCycle: 'CYC_MONTH',
cmCycleList: [
{ idx: 0, text: '월', value: 'CYC_MONTH' },
{ idx: 1, text: '일', value: 'CYC_DAY' },
],
defaultRange: {
CYC_MONTH: 1,
CYC_DAY: 1,
},
fromDt: Utility.setFormatDate(new Date(), 'YYYYMM'), // 조회 시작일
grid01: {
data: [],
column: [],
option: {},
},
grid02: {
data: [],
column: [],
option: {},
},
trendChart: Utility.defaultChartOption(true),
};
</script>

View File

@ -0,0 +1,907 @@
<template>
<div ref="mainDiv" class="l-layout">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="2">
<DatePicker :parentPrgmId="myPrgmId" :label="'조회연도'" />
</v-col>
<v-col :cols="3">
<component
:is="'SelectBox'"
ref="SelectBox1"
:propsValue="selectValue01"
:itemList="selectValueList01"
:label="'FAB'"
@update:propsValue="selectValue01 = $event"
/>
</v-col>
<v-col :cols="3">
<component
:is="'SelectBox'"
ref="SelectBox2"
:propsValue="selectValue02"
:itemList="selectValueList02"
:label="'설비종류'"
@update:propsValue="selectValue02 = $event"
/>
</v-col>
<v-col :cols="3">
<component
:is="'SelectBox'"
ref="SelectBox3"
:propsValue="selectValue03"
:itemList="selectValueList03"
:label="'설비그룹'"
@update:propsValue="selectValue03 = $event"
/>
</v-col>
<v-col :cols="1" class="text-right">
<BtnSearch @click="search" />
<component
ref="EnrgUsePlanModiPop"
:is="'EnrgUsePlanModiPop'"
:label="'test'"
:parentPrgmId="myPrgmId"
@gridEditingFinish="gridEditingFinish"
/>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents">
<v-col :cols="12" style="height: 100%">
<v-card class="pb-5 h100">
<div class="d-flex align-center justify-space-between pa-4">
<v-card-title class="pa-0 custom-title-4"
>설비별 에너지 계획 리스트</v-card-title
>
<Buttons
:parentPrgmId="myPrgmId"
:bindingData="gridName"
:btnActionsFnc="btnActions"
/>
</div>
<div class="h100 px-5" style="height:calc(100% - 70px)">
<div ref="gridParent" class="w100 h100">
<component
:ref="gridName"
:is="loadGrid ? 'Grid' : null"
:gridName="gridName"
:parentPrgmId="myPrgmId"
:editorGrid="true"
@getRowsData="getRowData"
/>
</div>
</div>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script>
import { mapState, mapActions } from 'vuex';
import mixinGlobal from '@/mixin/global.js';
import { resize } from '@/mixin/resize.js';
import SelectBox from '@/components/common/select/SelectBox';
import BtnSearch from '~/components/common/button/BtnSearch';
import DatePicker from '~/components/common/Datepicker';
import Grid from '~/components/common/Grid';
import Utility from '~/plugins/utility';
import Buttons from '~/components/common/button/Buttons';
import EnrgUsePlanModiPop from '~/components/common/modal/EnrgUsePlanModiPop';
import DateUtility from '~/plugins/dateUtility';
let myTitle;
let myPrgmId;
let stateOfDarkMode;
export default {
mixins: [mixinGlobal, resize],
async asyncData(context) {
const myState = context.store.state;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
stateOfDarkMode = await myState.isDarkMode;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
BtnSearch,
SelectBox,
DatePicker,
Grid,
Buttons,
EnrgUsePlanModiPop,
},
data() {
return {
myPrgmId: myPrgmId,
darkModeFg: stateOfDarkMode,
btnStyleDict: null,
initedFlag: false,
loadGrid: false,
gridName: 'grid01',
selectValue01: null,
selectValueList01: [],
selectValue02: null,
selectValueList02: [],
selectValue03: null,
selectValueList03: [],
fromDt: new Date().getFullYear(),
rowKey: null,
edtingFinishFlag: 'Y',
// gridName: 'rowGrid',
};
},
computed: {
// ...mapState({
// pageData: state => state.pageData[myPrgmId]
// }),
...mapState({
isDarkMode: state => state.isDarkMode,
}),
chkIsDarkMode() {
return this.isDarkMode;
},
chkIsFind() {
// 조회 플래그
return this.pageData.isFind;
},
chkFromDt() {
return this.pageData.fromDt;
},
},
watch: {
chkIsDarkMode(val) {
this.darkModeFg = val;
// this.btnStyleDict = val;
},
chkFromDt(val) {
this.fromDt = val;
},
chkIsFind(val) {
if (val) this.search();
},
async selectValue01(val) {
if (this.initedFlag) {
this.setPageData({ isFind: true });
}
},
async selectValue02(val) {
if (this.initedFlag) {
this.setPageData({ eqpmKindId: val });
await this.getEqpmGrp();
}
},
async selectValue03(val) {
if (this.initedFlag) {
this.setPageData({ isFind: true });
}
},
},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
created() {},
async mounted() {
await this.init();
this.initedFlag = true;
},
beforeDestroy() {
this.chkOpenTabList({ key: 'destroy', prgmId: myPrgmId });
},
methods: {
...mapActions({
getCodeList: 'modules/search/getCodeList',
getBlocMstrList: 'modules/search/getBlocMstrList',
getAddInfoList: 'modules/search/getAddInfoList',
}),
async init() {
await this.getFab();
await this.getEqpmKind();
await this.getEqpmGrp();
await this.gridInit();
},
search() {
// this.gridInit();
this.getGridData();
this.setPageData({
isFind: false,
});
},
async getFab() {
let res = await this.postApiReturn({
apiKey: 'selectFabCodeList',
resKey: 'fabCodeLists',
sendParam: {},
// sendParam: {level:3},
});
if (res.length > 0) {
this.selectValueList01 = await res.map(item => {
return {
text: item.eccNm,
value: item.eccId,
};
});
// this.selectValueList01.unshift({
// text: '전체',
// value: null,
// });
this.selectValue01 = this.selectValueList01[0].value;
} else {
this.selectValueList01 = [];
this.selectValue01 = null;
}
this.setPageData({
eccIdList: this.selectValueList01,
eccId: this.selectValue01,
});
},
async getEqpmKind() {
let res = await this.postApiReturn({
apiKey: 'selectEqpmKindCodeList',
resKey: 'eqpmKindCodeLists',
sendParam: {},
});
if (res.length > 0) {
this.selectValueList02 = await res.map(item => {
return {
text: item.eqpmKindNm,
value: item.eqpmKindId,
};
});
this.selectValue02 = this.selectValueList02[0].value;
} else {
this.selectValueList02 = [];
this.selectValue02 = null;
}
this.setPageData({
eqpmKindList: this.selectValueList02,
eqpmKindId: this.selectValue02,
});
},
async getEqpmGrp() {
let res = await this.postApiReturn({
apiKey: 'selectEqpmGrpCodeList',
resKey: 'eqpmGrpCodeLists',
sendParam: { eqpmKindId: this.selectValue02 },
});
if (res.length > 0) {
this.selectValueList03 = await res.map(item => {
return {
text: item.eqpmGrpNm,
value: item.eqpmGrpId,
};
});
this.selectValue03 = this.selectValueList03[0].value;
} else {
this.selectValueList03 = [];
this.selectValue03 = null;
}
this.setPageData({
eqpmGrpList: this.selectValueList03,
eqpmGrpId: this.selectValue03,
});
},
gridInit() {
this.loadGrid = false;
let _this = this;
const gridHeight = this.$refs.gridParent.offsetHeight - 50;
let yyyyCol = this.pageData.fromDt + '년';
let childCols1 = [];
let myComplexColumns = [
{
header: yyyyCol,
name: 'yyyyCol',
childNames: childCols1,
},
{
header: '설비명',
name: 'fakeEqpmNm',
childNames: ['eqpmNm', 'btnCol'],
hideChildHeaders: true,
},
];
let myOptions = {
columnOptions: {
resizable: true,
},
header: {
height: 65,
complexColumns: myComplexColumns,
},
};
class CustumButton {
constructor(props) {
// v-btn v-btn--is-elevated v-btn--has-bg theme--dark v-size--default
const el = document.createElement('button');
const { grid, rowKey, columnInfo } = props;
$(el).addClass('tui-grid-cell-content');
// $(el).css('text-align', 'center');
el.classList.add('v-btn');
// el.style.width = '80%';
// el.style.height = '80%';
// el.style.boxShadow = '0px 0px 0px 2px #cbced6';
// el.style.background = 'linear-gradient(to bottom, #242940 5%, #476e9e 100%)';
// el.style.backgroundColor = '#144985';
el.style.borderRadius = '7px';
el.style.border = '1px solid #4e6096';
// el.style.display = 'inline-block';
// el.style.cursor = 'pointer';
el.style.color = '#ffffff';
// el.style.fontFamily = 'Arial';
el.style.padding = '6% 3%';
// el.style.textDecoration = 'none';
// el.style.textShadow = '0px 1px 0px #283966';
el.innerText = columnInfo.renderer.options.value;
this.el = el;
this.disabled = columnInfo.renderer.options.disabled || false;
if (!this.disabled) {
// hover 기능 구현
this.el.addEventListener('mouseover', function(event) {
// console.log('darkModeFg', _this.darkModeFg);
// console.log('event',event.fromElement);
// console.log('event',document.defaultView.getComputedStyle(el).getPropertyValue('background-color'));
// rgb(85, 130, 220) // light
// el.style.backgroundColor = '#26578F'; // rgb(20, 73, 133) // dark
// let btnColor = _this.darkModeFg? {mouseOver: '#26578F', mouseOut: '#144985'} : {mouseOver: 'rgb(85, 130, 220)', mouseOut: 'rgb(71, 119, 217)'};
// el.style.backgroundColor = btnColor['mouseOver'];
});
this.el.addEventListener('mouseout', function(event) {
// rgb(71, 119, 217) // light
// el.style.backgroundColor = '#144985'; // dark
// console.log('event',event.fromElement);
// let btnColor = _this.darkModeFg? {mouseOver: '#26578F', mouseOut: '#144985'} : {mouseOver: 'rgb(85, 130, 220)', mouseOut: 'rgb(71, 119, 217)'};
// el.style.backgroundColor = btnColor['mouseOut'];
});
// click 이벤트
this.el.addEventListener('click', function(event) {
let gridData = grid.store.data.rawData;
let rowNum = gridData[rowKey].rowNum;
let selectedGridData = gridData.filter(item => {
return item.rowNum === rowNum && item.gubun == '2PLAN';
});
// this.popupDialogFg = true;
_this.setPageData({ eqpmNm: selectedGridData[0].eqpmNm });
_this.setPageData({ popupDialogFg: true });
});
}
}
getElement() {
return this.el;
}
getValue() {
// return this.el.value;
}
mounted() {
// this.el.focus();
}
}
let myColumns = [
{
header: '설비그룹ID',
name: 'eqpmGrpId',
width: 50,
align: 'left',
hidden: true,
},
{
header: '설비ID',
name: 'eqpmId',
width: 50,
align: 'left',
hidden: true,
},
{
header: 'NO',
name: 'rowNum',
width: 40,
align: 'center',
// hidden: true,
},
{
header: 'FAB',
name: 'fab',
width: 100,
align: 'left',
// hidden: true,
},
{
header: '공정명',
name: 'eccNm',
width: 100,
align: 'left',
hidden: true,
},
{
header: '설비그룹',
name: 'eqpmGrpNm',
minwidh: 200,
align: 'left',
// hidden: true,
},
{
header: '설비명',
name: 'eqpmNm',
minWidth: 200,
align: 'left',
// hidden: true,
},
{
header: '',
name: 'btnCol',
width: 70,
align: 'center',
renderer: {
type: CustumButton,
options: {
value: '계획수정',
},
},
// ,editor: {
// type: CustomEditor,
// align: "center"
// }
},
{
header: '구분',
name: 'gubun',
width: 80,
align: 'left',
// hidden: true,
formatter({ value }) {
let retVal = '';
if (value == '1RSLT') {
retVal = '전년실적';
} else if (value == '2PLAN') {
retVal = '계획';
} else {
retVal = value;
}
return retVal;
},
},
{
header: 'rowStat',
name: 'rowStat',
hidden: true,
},
{
header: 'readObjId',
name: 'readObjId',
hidden: true,
},
];
for (var i = 1; i <= 12; i++) {
let qty = 'qty' + i.toString().padStart(2, '0');
myColumns.push({
header: i.toString() + '월',
name: qty,
width: 73,
align: 'right',
editor: 'text',
formatter: this.numberFormatter,
});
childCols1.push(qty);
}
this.setGridColumn({
gridKey: this.gridName,
value: myColumns,
});
this.setGridOption({
gridKey: this.gridName,
value: Object.assign(Utility.defaultGridOption(gridHeight), myOptions),
});
this.$nextTick(() => {
this.loadGrid = true;
this.getGridData();
});
},
async getRowData(data) {
this.rowKey = data.rowKey;
this.edtingFinishFlag = 'Y';
// 선택한 row의 계획data만 pageData에 저장
let gridData = this.$refs.grid01.getData();
let selectedGridData = gridData.filter(item => {
return item.rowNum == data.rowNum;
});
await this.$nextTick(() => {});
this.setPageData({
rowGrid2SelectData: selectedGridData,
});
this.setPageData({
rowGridSelectKey: data.rowKey,
rowGridSelectData: data,
});
// this.setPageData({
// rowGridSelectKey: selectedGridData[1].rowKey,
// rowGridSelectData: selectedGridData[1],
// });
},
async getGridData() {
let res = [];
res = await this.postApiReturn({
apiKey: 'selectEnrgUsePlanData',
resKey: 'enrgUsePlanDatas',
sendParam: {
fromDt: this.fromDt,
pastDt: parseInt(this.fromDt) - 1,
eqpmGrpId: this.selectValue03,
eccId: this.selectValue01,
},
});
let fabText = this.pageData.eccIdList.filter(item => {
return item.value == this.selectValue01;
})[0]['text'];
let newRes = res.map(item => {
const newObj = {
...item,
rowStat: null,
fab: fabText,
};
return newObj;
});
function setRowSpanAttribute(
separateColStandardList,
res,
targetAttributeName,
rowSpanList,
) {
if (!(res.length && res.length >= 2)) {
return;
}
var valueList = [];
var rowSpanValueList = [];
var currentIdx = 0;
for (var i = 0; i < res.length; i++) {
valueList.push(res[i][targetAttributeName]);
}
function makeCurrentSeparateVal(idx, separateColStandardList) {
let returnVal = '';
for (var i = 0; i < separateColStandardList.length; i++) {
returnVal += res[idx][separateColStandardList[i]];
}
return returnVal;
}
let beforeSeparateVal = makeCurrentSeparateVal(
0,
separateColStandardList,
);
rowSpanValueList[0] = [valueList[0], 1, currentIdx];
for (var i = 1; i < valueList.length; i++) {
currentIdx += 1;
let currentSeparateVal = makeCurrentSeparateVal(
i,
separateColStandardList,
);
if (
currentSeparateVal == beforeSeparateVal &&
valueList[i] == rowSpanValueList[rowSpanValueList.length - 1][0]
) {
rowSpanValueList[rowSpanValueList.length - 1][1] += 1;
} else {
rowSpanValueList[rowSpanValueList.length] = [
valueList[i],
1,
currentIdx,
];
beforeSeparateVal = currentSeparateVal;
}
}
for (var i = 0; i < rowSpanValueList.length; i++) {
if (rowSpanValueList[i][1] === 1) {
continue;
}
if (res[rowSpanValueList[i][2]]['_attributes'] == undefined) {
res[rowSpanValueList[i][2]]['_attributes'] = {
rowSpan: new Object(),
};
//추가용
res[rowSpanValueList[i][2]]['_attributes']['className'] = {
column: new Object(),
};
for (var j = 0; j < rowSpanList.length; j++) {
res[rowSpanValueList[i][2]]['_attributes']['className']['column'][
rowSpanList[j]
] = ['colrowspan'];
}
//추가용
}
res[rowSpanValueList[i][2]]['_attributes']['rowSpan'][
targetAttributeName
] = rowSpanValueList[i][1];
res[rowSpanValueList[i][2]]['_attributes']['className']['column'][
targetAttributeName
].push(['rowrowspan']);
}
}
let rowSpanList = ['rowNum', 'fab', 'eqpmGrpNm', 'eqpmNm', 'btnCol'];
setRowSpanAttribute(['eqpmId'], newRes, 'rowNum', rowSpanList);
setRowSpanAttribute(['rowNum'], newRes, 'fab', rowSpanList);
setRowSpanAttribute(['rowNum'], newRes, 'eqpmGrpNm', rowSpanList);
setRowSpanAttribute(['rowNum'], newRes, 'eqpmNm', rowSpanList);
setRowSpanAttribute(['rowNum'], newRes, 'btnCol', rowSpanList);
this.setGridData({
gridKey: this.gridName,
value: newRes,
});
this.$nextTick(() => {
this.setRowDisabled();
});
// let temp = newRes.filter(item => {
// return item.gubun=='1RSLT'
// })
// console.log('temp', temp);
// for(var i=0; i<temp.length; i++){
// console.log(temp.rowKey);
// }
},
numberFormatter({ value }) {
// return Utility.setFormatIntDecimal(value, 0);
if (value === undefined || value === null || value === '') {
return '';
}
var newValue = value.toString().split('.');
// 숫자와 문자가 섞여있을 경우 구분하는 로직 추가
var regex = /[^0-9]/g; // 숫자가 아닌 문자열을 선택하는 정규식
for (var i = 0; i < newValue.length; i++) {
if (regex.test(newValue[i])) {
newValue[i] = newValue[i].toString().replace(regex, '');
}
}
if (parseInt(newValue[1]) >= 5) {
return (parseInt(newValue[0]) + 1)
.toString()
.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
} else {
return newValue[0].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
// return (
// newValue[0].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') +
// (newValue[1] ? '.' + newValue[1] : '')
// );
},
async btnActions(action) {
let dataArr = [];
switch (action) {
case 'save':
if (this.edtingFinishFlag == 'Y') {
await this.$refs[this.gridName].editingFinish({
rowKey: this.rowKey,
});
}
// let temp = this.$refs[this.gridName].getData();
dataArr = this.$refs[this.gridName].save();
var validCheck = true;
if (dataArr.length > 0) {
dataArr.filter(item => {
if (item.eqpmGrpId == '' || item.eqpmId == null) {
alert('필수 입력값을 입력해주세요.');
validCheck = false;
}
});
let dataList = [];
for (var i = 0; i < dataArr.length; i++) {
if (dataArr[i]['gubun'] == '2PLAN') {
for (var j = 1; j <= 12; j++) {
let temp = {};
let qty = 'qty' + j.toString().padStart(2, '0');
temp['eqpmId'] = dataArr[i]['eqpmId'];
temp['readObjId'] = dataArr[i]['readObjId'];
temp['objMm'] =
this.pageData.fromDt + j.toString().padStart(2, '0');
temp['rowStat'] = dataArr[i]['rowStat'];
temp['planVal'] =
dataArr[i][qty] == ''
? null
: parseInt(dataArr[i][qty]) == 0
? 0
: dataArr[i][qty];
dataList.push(temp);
}
}
}
// console.log('dataList', dataList);
// // dataArr[i]
// }
if (validCheck) {
const sendParam = {
datas: {
dsEmsEqpmMmPlanDatas: dataList,
},
params: {},
};
await this.postUpdateApi({
apiKey: 'saveEmsEqpmMmPlanDatas',
sendParam: sendParam,
});
this.$nextTick(() => {
// this.setPageData({ isFind: true });
this.search();
});
}
} else {
alert('저장할 내용이 없습니다.');
}
break;
default:
break;
}
},
gridEditingFinish(data) {
this.$refs[this.gridName].editingFinish(data);
},
setRowDisabled() {
let gridData = this.$refs[this.gridName].getData();
let rowKeyList = gridData
.filter(item => {
return item.gubun == '1RSLT';
})
.map(item => item.rowKey);
for (var i = 0; i < rowKeyList.length; i++) {
this.$refs[this.gridName].disableRow(rowKeyList[i]);
}
if (gridData.length > 0) {
try {
this.$refs[this.gridName].focus({
//rowKey: 0,
rowKey: 0,
setScroll: true,
});
} catch (error) {
console.log('error[nextTick grid] : ', error);
}
}
},
},
};
const dt = new Date();
const yyyy = dt.getFullYear();
const defaultData = {
isFind: false, // true 경우 조회
/* 검색옵션 */
cmCycle: 'CYC_YEAR', // DatePicker 옵션
fromDt: `${yyyy}`, // DatePicker 옵션
eccIdList: [], // FAB
eccId: '', // FAB
eqpmKindList: [], // 설비종류
eqpmKindId: '', // 설비종류
eqpmGrpList: [], // 설비그룹
eqpmGrpId: '', // 설비그룹
// Grid에서 선택된 데이터
rowGridSelectKey: 0,
rowGridSelectData: null,
rowGrid2SelectData: [
{
gubun: '',
eccNm: '',
eqpmGrpId: '',
eqpmGrpNm: '',
eqpmId: '',
eqpmNm: '',
qty01: '',
qty02: '',
qty03: '',
qty04: '',
qty05: '',
qty06: '',
qty07: '',
qty08: '',
qty09: '',
qty10: '',
qty11: '',
qty12: '',
btnCol: '',
rowStat: null,
},
],
// popup dialog flag
popupDialogFg: false,
eqpmNm: '',
//grid 설정
grid01: {
data: [],
column: [],
option: { header: { complexColumns: [] } },
defaultRow: {
gubun: '',
eccNm: '',
eqpmGrpId: '',
eqpmGrpNm: '',
eqpmId: '',
eqpmNm: '',
qty01: '',
qty02: '',
qty03: '',
qty04: '',
qty05: '',
qty06: '',
qty07: '',
qty08: '',
qty09: '',
qty10: '',
qty11: '',
qty12: '',
btnCol: '',
rowStat: null,
},
buttonAuth: {
add: false,
remove: false,
save: true,
excel: false,
},
},
};
</script>
<style lang="scss">
// @import '@/assets/scss/common.scss';
@import '@/assets/scss/var.scss';
@each $theme in dark, light {
.v-application.#{$theme}-mode {
.tui-grid {
&-row-odd,
&-row-even {
&:hover > .colrowspan {
background-color: map-deep-get(
$config,
#{$theme},
'tui-grid-cell-backgroundColor'
) !important;
.tui-grid-cell-content {
color: map-deep-get($config, #{$theme}, 'activate') !important;
}
}
}
&-cell {
&.row-selected.colrowspan {
background-color: map-deep-get(
$config,
#{$theme},
'tui-grid-cell-backgroundColor'
) !important;
.tui-grid-cell-content {
color: map-deep-get($config, #{$theme}, 'activate') !important;
}
}
}
}
}
}
</style>

View File

@ -0,0 +1,558 @@
<template>
<div ref="mainDiv" class="l-layout">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="3">
<component
:is="'SelectBox'"
ref="SelectBox1"
:propsValue="selectValue01"
:itemList="selectValueList01"
:label="'설비종류'"
@update:propsValue="selectValue01 = $event"
/>
</v-col>
<v-col :cols="3">
<component
:is="'DatePicker'"
:label="'대상연월'"
:parentPrgmId="myPrgmId"
/>
</v-col>
<v-col :cols="3"> </v-col>
<v-col :cols="3" class="text-right">
<v-btn v-show="false" :ripple="false" @click="test()">TEST</v-btn>
<v-btn :ripple="false" @click="search()">조회</v-btn>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents" style="overflow: auto;">
<v-col>
<v-card class="pb-5 px-2">
<div
v-for="(value, key, index) in contentData"
:key="'key1_' + index"
>
<v-card-title
class="d-flex align-center justify-space-between pa-3"
>
<span class="tit ft-size_20 ft-weight_600">{{
value.eqpmGrpNm
}}</span>
</v-card-title>
<v-row>
<v-col
:cols="3"
v-for="(item, i) in value.chartData"
:key="'key2_' + i"
>
<div
class="v-box"
style="height : 330px"
:ref="item.eqpmGrpId + '_' + item.fabId"
@click="chartClickEvent(item, $event)"
>
<v-col :cols="12" style="height:100%">
<div style="height: 10%">
<strong>{{ item.fabNm }}</strong>
</div>
<div style="height: 5%"></div>
<div style="height: 10%; text-align:center">
<v-row>
<v-col :cols="1"> </v-col>
<v-col :cols="4">
일에너지 :
</v-col>
<v-col :cols="4" style="text-align:right">
{{ item.dayVal }}
</v-col>
<v-col :cols="2" style="text-align:left">
MWh
</v-col>
<v-col :cols="1"> </v-col>
</v-row>
</div>
<div style="height: 10%; text-align:center">
<v-row>
<v-col :cols="1"> </v-col>
<v-col :cols="4">
월에너지 :
</v-col>
<v-col :cols="4" style="text-align:right">
{{ item.mnthVal }}
</v-col>
<v-col :cols="2" style="text-align:left">
MWh
</v-col>
<v-col :cols="1"> </v-col>
</v-row>
</div>
<div style="height: 5%"></div>
<div style="height: 10%; text-align:center">
에너지사용효율
</div>
<div style="height: 50%">
<component
class="w100 h100"
:is="loadChart ? 'Chart' : null"
:parentPrgmId="myPrgmId"
:chartName="
'chart_' + item.eqpmGrpId + '_' + item.fabId
"
:ref="'chart_' + item.eqpmGrpId + '_' + item.fabId"
/>
</div>
</v-col>
</div>
</v-col>
</v-row>
</div>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex';
import mixinGlobal from '@/mixin/global.js';
import { resize } from '@/mixin/resize.js';
import Utility from '~/plugins/utility';
import SelectBox from '@/components/common/select/SelectBox';
import BtnSearch from '~/components/common/button/BtnSearch';
import DatePicker from '@/components/common/Datepicker';
import Chart from '~/components/common/Chart';
let myTitle;
let myPrgmId;
export default {
mixins: [mixinGlobal, resize],
async asyncData(context) {
const myState = context.store.state;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
Utility,
SelectBox,
BtnSearch,
DatePicker,
Chart,
},
data() {
return {
myPrgmId: myPrgmId,
initedFlag: false,
selectValueList01: [], // 설비종류 리스트
selectValue01: null,
contentData: {},
loadChart: false,
testFlag: false,
};
},
computed: {
...mapState({
pageData: state => state.pageData[myPrgmId],
}),
fromDt() {
return this.pageData.fromDt;
},
},
watch: {
async selectValue01(value) {
if (this.initedFlag) {
await this.search();
}
},
async fromDt(value) {
if (this.initedFlag) {
await this.search();
}
},
},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
created() {},
mounted() {
this.init();
},
beforeDestroy() {
this.initedFlag = false;
this.chkOpenTabList({ key: 'destroy', prgmId: myPrgmId });
},
methods: {
...mapMutations({
setChartOption: 'setChartOption',
}),
async test() {
this.testFlag = !this.testFlag;
await this.search();
},
async init() {
await this.getSelectValueList01();
await this.search();
this.initedFlag = true;
},
async search() {
var enrgUseTotSummData = await this.getEnrgUseTotSummData();
var data = this.replaceUndefined(enrgUseTotSummData);
var dataGroupByEqpmGrpId = this.groupByEqpmGrpId(data);
this.contentData = dataGroupByEqpmGrpId;
this.setContent(this.contentData);
},
async getSelectValueList01() {
var res = await this.postApiReturn({
apiKey: 'selectEmsEqpmKindList',
resKey: 'eqpmGrpPysclQtyMngData',
sendParam: {},
});
if (res.length > 0) {
this.selectValueList01 = await res.map(item => {
return {
text: item.eqpmKindNm,
value: item.eqpmKindId,
data: {
...item,
},
};
});
this.selectValue01 = this.selectValueList01[0].value;
} else {
this.selectValueList01 = [];
this.selectValue01 = null;
}
},
async getEnrgUseTotSummData() {
var res = await this.postApiReturn({
apiKey: 'selectEnrgUseTotSumm',
resKey: 'data',
sendParam: {
fromDt: this.pageData.fromDt,
eqpmKind: this.selectValue01,
},
});
if (this.testFlag == true) {
res = [
{
eqpmGrpNm: '냉동기저온',
fabId: 'ECC000003',
eqpmGrpId: 'EQG000001',
fabNm: '삼천1공장',
dayVal: 252.55,
mnthVal: 4800.12,
planVal: 4400,
effcRt: 87.5,
},
{
eqpmGrpNm: '냉동기저온',
fabId: 'ECC000008',
eqpmGrpId: 'EQG000001',
fabNm: '삼천2공장',
dayVal: 353.46,
mnthVal: 2000.12,
planVal: 1800,
effcRt: 86,
},
{
eqpmGrpNm: '냉동기저온',
fabId: 'ECC000009',
eqpmGrpId: 'EQG000001',
fabNm: '삼천3공장',
dayVal: 353.46,
mnthVal: 2000.12,
planVal: 1800,
effcRt: 86,
},
{
eqpmGrpNm: '냉동기저온',
fabId: 'ECC000010',
eqpmGrpId: 'EQG000001',
fabNm: '삼천4공장',
dayVal: 553.46,
mnthVal: 3000.12,
planVal: 2800,
effcRt: 90,
},
{
eqpmGrpNm: '냉동기저온',
fabId: 'ECC000011',
eqpmGrpId: 'EQG000001',
fabNm: '삼천5공장',
dayVal: 453.46,
mnthVal: 3000.12,
planVal: 2800,
effcRt: 86,
},
{
eqpmGrpNm: '냉동기고온',
fabId: 'ECC000008',
eqpmGrpId: 'EQG000002',
fabNm: '삼천2공장',
dayVal: 444,
mnthVal: 8888.888,
planVal: 6000,
effcRt: 72.44,
},
{
eqpmGrpNm: 'test1',
fabId: 'ECC000008',
eqpmGrpId: 'EQG000007',
fabNm: '삼천2공장',
dayVal: 455,
mnthVal: 9999.999,
planVal: 5000,
effcRt: 50.555,
},
];
}
return res;
},
groupByEqpmGrpId(data) {
var result = {};
for (var i = 0; i < data.length; i++) {
if (!result.hasOwnProperty(data[i]['eqpmGrpId'])) {
var tempObject = {};
tempObject.eqpmGrpId = data[i]['eqpmGrpId'];
tempObject.eqpmGrpNm = data[i]['eqpmGrpNm'];
tempObject.chartData = [];
tempObject.chartData.push({
...data[i],
});
result[data[i]['eqpmGrpId']] = tempObject;
} else {
result[data[i]['eqpmGrpId']].chartData.push({
...data[i],
});
}
}
return result;
},
replaceUndefined(data) {
var dataKeyList = ['dayVal', 'mnthVal', 'planVal', 'effcRt'];
var replaceValList = [0, 0, 0, 0];
// var replaceValList = [666666.66, 252.35, '', 50];
for (var i = 0; i < data.length; i++) {
for (var j = 0; j < dataKeyList.length; j++) {
if (data[i][dataKeyList[j]] == undefined) {
data[i][dataKeyList[j]] = replaceValList[j];
}
}
}
return data;
},
async setContent(data) {
this.initChart(data);
this.loadChart = false;
await this.$nextTick();
this.setChartData(data);
this.loadChart = true;
},
initChart(data) {
var dataKeyList = Object.keys(data);
var currentChartData = null;
var chartKey = null;
for (var i = 0; i < dataKeyList.length; i++) {
for (var j = 0; j < data[dataKeyList[i]].chartData.length; j++) {
currentChartData = data[dataKeyList[i]].chartData[j];
chartKey =
'chart_' +
currentChartData['eqpmGrpId'] +
'_' +
currentChartData['fabId'];
this.setPageData({
[chartKey]: this.getGuageChartOption(),
});
}
}
},
async setChartData(data) {
var dataKeyList = Object.keys(data);
var currentChartData = null;
var chartKey = null;
var chartOption = null;
for (var i = 0; i < dataKeyList.length; i++) {
for (var j = 0; j < data[dataKeyList[i]].chartData.length; j++) {
currentChartData = data[dataKeyList[i]].chartData[j];
chartKey =
'chart_' +
currentChartData['eqpmGrpId'] +
'_' +
currentChartData['fabId'];
chartOption = this.getGuageChartOption();
chartOption['series'][0]['data'][0].value =
currentChartData['effcRt'];
this.$store.state.pageData[myPrgmId][chartKey] = chartOption;
}
}
},
getGuageChartOption() {
// const gaugeColors = [
// [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 gaugeColors = [
[0, '#ed1c24'],
[0.6, '#ed1c24'],
[0.8, '#f7931e'],
[1.0, '#009245'],
];
var guageChartOption = {
grid: {
top: '30%',
bottom: 0,
},
series: [
{
type: 'gauge',
center: ['50%', '80%'],
radius: '100%',
startAngle: 180,
endAngle: 0,
min: 0,
max: 100,
splitNumber: 10,
itemStyle: {
// color: '#FFAB91'
color: 'auto',
// color:gaugeColors
},
progress: {
// show: true,
show: false,
width: 20,
},
pointer: {
// show: false
show: true,
itemStyle: {
// color: '#FFAB91',
color: 'auto',
},
},
axisLine: {
lineStyle: {
width: 20,
color: gaugeColors,
},
},
axisTick: {
distance: -35,
splitNumber: 5,
lineStyle: {
width: 2,
color: '#999',
},
},
splitLine: {
distance: -42,
length: 14,
lineStyle: {
width: 3,
color: '#999',
},
},
axisLabel: {
distance: -10,
color: '#999',
fontSize: 10,
},
anchor: {
show: false,
},
title: {
show: false,
},
detail: {
valueAnimation: true,
width: '60%',
lineHeight: 25,
borderRadius: 8,
// offsetCenter: [0, '-15%'],
offsetCenter: [0, '33%'],
fontSize: 17,
fontWeight: 'bolder',
formatter: '{value} %',
color: 'auto',
},
data: [
{
value: NaN,
},
],
},
],
};
return guageChartOption;
},
chartClickEvent(argData, $event) {
var data = {
...argData,
fromDt: this.pageData.fromDt,
};
var key = 'tick_' + Math.random();
this.$router.push({
name: 'ems-effc-EqpmIndMntrPage',
query: {
prgmId: 'PRG0081',
// tick:key
},
params: {
...data,
key: key,
},
});
},
},
};
const defaultData = {
cmCycle: 'CYC_MONTH',
fromDt: Utility.setFormatDate(new Date(), 'YYYYMM'), // 조회 시작일
};
</script>

View File

@ -0,0 +1,710 @@
<template>
<div ref="mainDiv" class="l-layout">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="2">
<component
:is="'SelectBox'"
ref="SelectBox1"
:propsValue="selectValue01"
:itemList="selectValueList01"
:label="'FAB'"
@update:propsValue="selectValue01 = $event"
/>
</v-col>
<v-col :cols="2">
<component
:is="'SelectBox'"
ref="SelectBox2"
:propsValue="selectValue02"
:itemList="selectValueList02"
:label="'설비종류'"
@update:propsValue="selectValue02 = $event"
/>
</v-col>
<v-col :cols="2">
<component
:is="'SelectBox'"
ref="SelectBox3"
:propsValue="selectValue03"
:itemList="selectValueList03"
:label="'설비그룹'"
@update:propsValue="selectValue03 = $event"
/>
</v-col>
<v-col :cols="2">
<component
:is="'SelectCmCycle'"
:parentPrgmId="myPrgmId"
:label="'구분'"
/>
</v-col>
<v-col :cols="2">
<component
:is="'DatePicker'"
:label="'대상년월'"
:parentPrgmId="myPrgmId"
:isRangeOption="false"
/>
</v-col>
<v-col :cols="2" class="text-right">
<v-btn :ripple="false" @click="search()">조회</v-btn>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents" style="height: calc(100vh - 230px)">
<v-col :cols="12" class="h100">
<v-card class="pb-5 px-2">
<v-card-title class="d-flex align-center justify-space-between pa-5">
<span class="tit ft-size_20 ft-weight_600">설비별 현황 리스트</span>
</v-card-title>
<div class="px-5" style="height:calc(100% - 106px)">
<div ref="gridParent" class="w100 h100">
<component
:ref="gridName"
:is="loadGrid ? 'Grid' : null"
:gridName="gridName"
:parentPrgmId="myPrgmId"
@dblClick="gridDoubleClickEvent"
/>
<!--
<component
:ref="gridName"
:is="loadGrid ? 'Grid' : null"
:gridName="gridName"
:parentPrgmId="myPrgmId"
:mouseoverEvent="gridMouseoverEvent"
:mouseoutEvent="gridMouseoutEvent"
@dblClick="gridDoubleClickEvent"
/>
-->
</div>
</div>
</v-card>
</v-col>
</v-row>
<!--<v-tooltip
top
v-model="tooltipData.show"
:position-x="tooltipData.x"
:position-y="tooltipData.y"
:z-index="1000"
>
{{tooltipData.content}}
</v-tooltip> -->
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex';
import mixinGlobal from '@/mixin/global.js';
import { resize } from '@/mixin/resize.js';
import Utility from '~/plugins/utility';
import SelectBox from '@/components/common/select/SelectBox';
import SelectCmCycle from '@/components/common/select/SelectCmCycle';
import DatePicker from '@/components/common/Datepicker';
import Grid from '~/components/common/Grid';
let myTitle;
let myPrgmId;
let paramKey;
export default {
mixins: [mixinGlobal, resize],
async asyncData(context) {
const myState = context.store.state;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
Utility,
SelectBox,
SelectCmCycle,
DatePicker,
Grid,
},
data() {
return {
myPrgmId: myPrgmId,
initedFlag: false,
queryParams: null,
selectValueList01: [],
selectValueList02: [],
selectValueList03: [],
selectValue01: null,
selectValue02: null,
selectValue03: null,
loadGrid: false,
gridName: 'grid01',
enrgUseMainIdxDesc: [],
// tooltipData: {
// show: false,
// x: 0,
// y: 0,
// content: null,
// },
// tooltipTranscationFlag: false,
};
},
computed: {
...mapState({
pageData: state => state.pageData[myPrgmId],
}),
fromDt() {
return this.pageData.fromDt;
},
},
watch: {
async $route(to, from) {
if (to.query.prgmId == myPrgmId) {
if (to.params.key) {
document.getElementById('refresh').click();
}
}
},
async selectValue01(value) {
if (this.initedFlag) {
await this.search();
}
},
async selectValue02(value) {
if (this.initedFlag) {
await this.getSelectValueList03();
}
},
async selectValue03(value) {
if (this.initedFlag) {
await this.search();
}
},
async fromDt(value) {
if (this.initedFlag) {
await this.search();
}
},
},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
created() {},
mounted() {
this.init();
},
beforeDestroy() {
this.initedFlag = false;
this.chkOpenTabList({ key: 'destroy', prgmId: myPrgmId });
},
methods: {
async init() {
await this.getSelectValueList();
await this.setQueryParams();
this.gridInit();
await this.getGridData();
this.initedFlag = true;
},
async setQueryParams() {
this.queryParams = null;
if (paramKey == this.$route.params.key) {
return;
}
if (this.$route.params.key) {
paramKey = this.$route.params.key;
this.queryParams = this.$route.params;
}
if (this.queryParams && typeof this.queryParams == 'object') {
this.selectValue01 = this.queryParams['fabId'];
this.selectValue02 = this.queryParams['eqpmKindId'];
await this.getSelectValueList03();
this.selectValue03 = this.queryParams['eqpmGrpId'];
}
},
async getSelectValueList() {
await this.getSelectValueList01();
await this.getSelectValueList02();
await this.getSelectValueList03();
},
async getSelectValueList01() {
let res = await this.postApiReturn({
apiKey: 'selectFabCodeList',
resKey: 'fabCodeLists',
sendParam: {},
});
if (res.length > 0) {
this.selectValueList01 = await res.map(item => {
return {
text: item.eccNm,
value: item.eccId,
};
});
this.selectValue01 = this.selectValueList01[0].value;
} else {
this.selectValueList01 = [];
this.selectValue01 = null;
}
},
async getSelectValueList02() {
var res = await this.postApiReturn({
apiKey: 'selectEmsEqpmKindList',
resKey: 'eqpmGrpPysclQtyMngData',
sendParam: {},
});
if (res.length > 0) {
this.selectValueList02 = await res.map(item => {
return {
text: item.eqpmKindNm,
value: item.eqpmKindId,
data: {
...item,
},
};
});
this.selectValue02 = this.selectValueList02[0].value;
} else {
this.selectValueList02 = [];
this.selectValue02 = null;
}
},
async getSelectValueList03() {
var res = await this.postApiReturn({
apiKey: 'selectEmsEqpmGrpList',
resKey: 'eqpmGrpPysclQtyMngData',
sendParam: {
eqpmKindId: this.selectValue02,
},
});
if (res.length > 0) {
this.selectValueList03 = await res.map(item => {
return {
text: item.eqpmGrpNm,
value: item.eqpmGrpId,
data: {
...item,
},
};
});
this.selectValue03 = this.selectValueList03[0].value;
} else {
this.selectValueList03 = [];
this.selectValue03 = null;
}
},
gridInit() {
const gridHeight = this.$refs.gridParent.offsetHeight - 30;
const _this = this;
var columnList = [
{ header: 'NO', name: 'no', align: 'center', width: 80 },
{ header: 'fabId', name: 'fabId', hidden: true },
{ header: 'FAB', name: 'fabNm', align: 'left' },
{ header: 'eqpmGrpId', name: 'eqpmGrpId', hidden: true },
{ header: '설비그룹', name: 'eqpmGrpNm', align: 'left', width: 200 },
{ header: 'eqpmId', name: 'eqpmId', hidden: true },
{ header: '설비명', name: 'eqpmNm', align: 'left', width: 200 },
{
header: '계획량',
name: 'planVal',
align: 'right',
minWidth: 110,
formatter: numberFormatter,
},
{
header: '사용량',
name: 'usedVal',
align: 'right',
minWidth: 110,
formatter: numberFormatter,
},
{
header: 'KPI',
name: 'effcRt',
align: 'right',
formatter: numberFormatter,
},
{
header: '지표1',
name: 'gd01',
align: 'right',
formatter: numberFormatter,
},
{
header: '지표2',
name: 'gd02',
align: 'right',
formatter: numberFormatter,
},
{
header: '지표3',
name: 'gd03',
align: 'right',
formatter: numberFormatter,
},
{
header: '지표4',
name: 'gd04',
align: 'right',
formatter: numberFormatter,
},
{
header: '지표5',
name: 'gd05',
align: 'right',
formatter: numberFormatter,
},
{
header: '지표6',
name: 'gd06',
align: 'right',
formatter: numberFormatter,
},
{
header: '지표7',
name: 'gd07',
align: 'right',
formatter: numberFormatter,
},
{
header: '지표8',
name: 'gd08',
align: 'right',
formatter: numberFormatter,
},
{
header: '지표9',
name: 'gd09',
align: 'right',
formatter: numberFormatter,
},
{
header: '지표10',
name: 'gd10',
align: 'right',
formatter: numberFormatter,
},
];
const myOptions = {
columnOptions: {
resizable: true,
},
header: {
height: 65,
complexColumns: [
{
header: '주요지표',
name: 'complexColumn01',
childNames: [
'gd01',
'gd02',
'gd03',
'gd04',
'gd05',
'gd06',
'gd07',
'gd08',
'gd09',
'gd10',
],
},
],
},
};
this.setGridOption({
gridKey: this.gridName,
value: Object.assign(Utility.defaultGridOption(gridHeight), myOptions),
});
this.setGridColumn({
gridKey: this.gridName,
value: columnList,
});
},
async getGridData() {
this.loadGrid = false;
this.enrgUseMainIdxDesc = [];
var apiKey = null;
var params = {
fabId: this.selectValue01,
eqpmKindId: this.selectValue02,
eqpmGrpId: this.selectValue03,
fromDt: this.pageData.fromDt,
};
if (this.pageData.cmCycle == 'CYC_DAY') {
params['fromDtMm'] = String(this.pageData.fromDt).substring(0, 6);
apiKey = 'selectDailyEnrgUseMainIdx';
} else if (this.pageData.cmCycle == 'CYC_MONTH') {
apiKey = 'selectMonthlyEnrgUseMainIdx';
}
var res = await this.postApiReturn({
apiKey: apiKey,
resKey: 'eqpmIndMntrData',
sendParam: params,
});
this.enrgUseMainIdxDesc = await this.postApiReturn({
apiKey: 'selectEnrgUseMainIdxDesc',
resKey: 'eqpmIndMntrData',
sendParam: {
eqpmGrpId: this.selectValue03,
},
});
var newRes = [];
for (var i = 0; i < res.length; i++) {
newRes.push({
...res[i],
no: i + 1,
});
}
this.setGridData({
gridKey: this.gridName,
value: newRes,
});
this.loadGrid = true;
this.makeTooltip();
},
async search() {
await this.getGridData();
},
async makeTooltip() {
var gdIdxList = [
'gd01',
'gd02',
'gd03',
'gd04',
'gd05',
'gd06',
'gd07',
'gd08',
'gd09',
'gd10',
];
var elementList = [];
await new Promise(resolve => setTimeout(resolve, 1000));
for (var i = 0; i < gdIdxList.length; i++) {
var selector =
'.tui-grid-cell-header[data-column-name="' + gdIdxList[i] + '"]';
var tempElement = document.querySelector(selector);
elementList.push(tempElement);
}
console.log('this.enrgUseMainIdxDesc : ', this.enrgUseMainIdxDesc);
for (var i = 0; i < elementList.length; i++) {
var tooltipElement = document.createElement('div');
var tooltipContent = '';
if (this.enrgUseMainIdxDesc[i]) {
tooltipContent = this.enrgUseMainIdxDesc[i].gdIdxNm;
} else {
tooltipContent = '지표에 대한 정보가 없습니다.';
}
// textContent 세팅
tooltipElement.textContent = tooltipContent;
// id값 설정
elementList[i].id = 'tooltipTargetElement_' + i;
tooltipElement.id = 'tooltipElement_' + i;
// element 추가
elementList[i].append(tooltipElement);
}
},
// gridMouseoverEvent(e) {
// if (e.targetType == 'columnHeader') {
// if (String(e.columnName).search('gd') >= 0) {
// this.tooltipTranscationFlag = true;
// this.tooltipData.content = null;
// var element = document.querySelector(
// '.tui-grid-cell-header[data-column-name="' + e.columnName + '"]',
// );
// var boundingClientRect = element.getBoundingClientRect();
// this.tooltipData.x =
// (boundingClientRect.right + boundingClientRect.left) / 2;
// this.tooltipData.y = boundingClientRect.top;
// for (var i = 0; i < this.enrgUseMainIdxDesc.length; i++) {
// if (
// this.enrgUseMainIdxDesc[i].gdSeq ==
// String(e.columnName).toUpperCase()
// ) {
// this.tooltipData.content = this.enrgUseMainIdxDesc[i].gdIdxNm;
// }
// }
// if (this.tooltipData.content == null) {
// this.tooltipData.content = '지표에 대한 정보가 없습니다.';
// }
// this.tooltipData.show = true;
// this.tooltipTranscationFlag = false;
// }
// }
// },
// gridMouseoutEvent(e) {
// if (
// e.targetType == 'columnHeader' &&
// this.tooltipTranscationFlag === false
// ) {
// this.tooltipData.show = false;
// }
// },
gridDoubleClickEvent(_, event, gridName) {
var gridInstance = this.$refs[this.gridName].gridInstance;
var eventRowData = gridInstance.invoke('getRow', event.rowKey);
var data = {
cmCycle: this.pageData.cmCycle,
fromDt: this.pageData.fromDt,
fabId: this.selectValue01,
eqpmKindId: this.selectValue02,
eqpmGrpId: this.selectValue03,
eqpmId: eventRowData.eqpmId,
};
var key = 'tick_' + Math.random();
this.$router.push({
name: 'ems-effc-EnrgUseEqpmDetlMntrPage',
query: {
prgmId: 'PRG0082',
// tick:key
},
params: {
...data,
key: key,
},
});
},
},
};
const defaultData = {
cmCycle: 'CYC_MONTH',
cmCycleList: [
{ idx: 0, text: '월', value: 'CYC_MONTH' },
{ idx: 1, text: '일', value: 'CYC_DAY' },
],
defaultRange: {
CYC_MONTH: 1,
CYC_DAY: 1,
},
fromDt: Utility.setFormatDate(new Date(), 'YYYYMM'), // 조회 시작일
grid01: {
data: [],
column: [],
option: {},
},
};
function numberFormatter({ value }) {
if (typeof value == 'number' || typeof value == 'string') {
// return Math.round(Number(value) * 100) / 100;
// return Utility.setFormatIntDecimal(Number(value), 2);
// return Math.ceil(Number(value));
var tempValue = Utility.setFormatIntDecimal(Number(value), 2);
if (tempValue[tempValue.length - 1] == '0') {
tempValue = tempValue.slice(0, -1);
}
if (
tempValue[tempValue.length - 1] == '0' &&
tempValue[tempValue.length - 2] == '.'
) {
tempValue = tempValue.slice(0, -2);
}
return tempValue;
} else {
return '';
}
}
</script>
<style lang="scss">
@for $i from 0 through 9 {
#gridParent > * {
// .tui-grid-content-area{
background-color: red;
color: red;
overflow: visible;
position: relative;
}
#tooltipTargetElement_#{$i} {
overflow: visible;
position: relative; // 테스트3번쨰
white-space: nowrap; // 테스트3번쨰
}
#tooltipElement_#{$i} {
display: none;
overflow: visible;
position: relative;
}
#tooltipTargetElement_#{$i}:hover #tooltipElement_#{$i} {
display: block;
position: absolute;
min-width: 100%;
bottom: 30px;
z-index: 1000000000;
align: 'center';
color: #f2f2f2;
background-color: #7f7f7f;
// width : 77px;
width: 200%;
left: -50%;
border-radius: 3px;
word-break: keep-all;
white-space: pre-wrap;
}
.tui-grid-rside-area {
display: none;
overflow: visible;
overflow-x: visible;
overflow-y: visible;
}
.tui-grid-header-area {
border-style: solid;
border-width: 0 0 1px;
position: relative;
overflow: visible;
overflow-x: visible;
overflow-y: visible;
}
}
</style>

View File

@ -0,0 +1,581 @@
<template>
<div ref="mainDiv" class="l-layout">
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="center" no-gutters>
<v-col :cols="2">
<component
:is="'SelectBox'"
ref="SelectBox1"
:propsValue="selectValue01"
:itemList="selectValueList01"
:label="'Fab'"
@update:propsValue="selectValue01 = $event"
/>
</v-col>
<v-col :cols="2">
<component
:is="'SelectBox'"
ref="SelectBox2"
:propsValue="selectValue02"
:itemList="selectValueList02"
:label="'설비종류'"
@update:propsValue="selectValue02 = $event"
/>
</v-col>
<v-col :cols="2">
<component
:is="'SelectBox'"
ref="SelectBox3"
:propsValue="selectValue03"
:itemList="selectValueList03"
:label="'설비그룹'"
@update:propsValue="selectValue03 = $event"
/>
</v-col>
<v-col :cols="2">
<component
:is="'SelectCmCycle'"
:parentPrgmId="myPrgmId"
:label="'구분'"
/>
</v-col>
<v-col :cols="2">
<component
:is="'DatePicker'"
:label="'대상년월'"
:parentPrgmId="myPrgmId"
:isRangeOption="false"
/>
</v-col>
<v-col :cols="2" class="text-right">
<v-btn :ripple="false" @click="search()">조회</v-btn>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-row ref="contents" style="height: calc(100vh - 230px)">
<v-col :cols="12" class="">
<v-card class="pb-5 px-2">
<v-card-title class="d-flex align-center justify-space-between pa-5">
<span class="tit ft-size_20 ft-weight_600">설비별 현황 리스트</span>
</v-card-title>
<div class="px-5" style="height:calc(100% - 106px)">
<div ref="gridParent" class="w100 h100">
<component
:ref="gridName"
:is="loadGrid ? 'Grid' : null"
:gridName="gridName"
:parentPrgmId="myPrgmId"
@dblClick="gridDoubleClickEvent"
/>
<!--
<component
:ref="gridName"
:is="loadGrid ? 'Grid' : null"
:gridName="gridName"
:parentPrgmId="myPrgmId"
:mouseoverEvent="gridMouseoverEvent"
:mouseoutEvent="gridMouseoutEvent"
@dblClick="gridDoubleClickEvent"
/>
-->
</div>
</div>
</v-card>
</v-col>
</v-row>
<!--<v-tooltip
top
v-model="tooltipData.show"
:position-x="tooltipData.x"
:position-y="tooltipData.y"
:z-index="1000"
>
{{tooltipData.content}}
</v-tooltip> -->
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex';
import mixinGlobal from '@/mixin/global.js';
import Utility from '~/plugins/utility';
import SelectBox from '@/components/common/select/SelectBox';
import SelectCmCycle from '@/components/common/select/SelectCmCycle';
import DatePicker from '@/components/common/Datepicker';
import Grid from '~/components/common/Grid';
let myTitle;
let myPrgmId;
let paramKey;
export default {
mixins: [mixinGlobal],
async asyncData(context) {
const myState = context.store.state;
myPrgmId = context.route.query.prgmId;
await context.store.commit('setActiveMenuInfo', myState.menuData[myPrgmId]);
myTitle = await myState.activeMenuInfo.menuNm;
},
meta: {
title: () => {
return myTitle;
},
prgmId: myPrgmId,
closable: true,
},
components: {
Utility,
SelectBox,
SelectCmCycle,
DatePicker,
Grid,
},
data() {
return {
myPrgmId: myPrgmId,
initedFlag:false,
queryParams: null,
selectValueList01: [],
selectValueList02: [],
selectValueList03: [],
selectValue01:null,
selectValue02:null,
selectValue03:null,
loadGrid:false,
gridName:'grid01',
enrgUseMainIdxDesc:[],
// tooltipData:{
// show:false,
// x:0,
// y:0,
// content:null
// },
};
},
computed:{
...mapState({
pageData: state => state.pageData[myPrgmId],
}),
fromDt(){
return this.pageData.fromDt;
}
},
watch:{
async $route(to, from){
if(to.query.prgmId == myPrgmId){
if(to.params.key){
document.getElementById('refresh').click();
}
}
},
async selectValue01(value){
if(this.initedFlag){
await this.search();
}
},
async selectValue02(value){
if(this.initedFlag){
await this.getSelectValueList03();
}
},
async selectValue03(value){
if(this.initedFlag){
await this.search();
}
},
async fromDt(value){
if(this.initedFlag){
await this.search();
}
}
},
async beforeCreate() {
myPrgmId = this.$route.query.prgmId;
await this.$store.dispatch('chkOpenTabList', {
key: 'create',
prgmId: myPrgmId,
defaultData: defaultData,
});
},
created() {},
mounted() {
this.init();
},
beforeDestroy() {
this.initedFlag = false;
this.chkOpenTabList({ key: 'destroy', prgmId: myPrgmId });
},
methods: {
async init(){
await this.getSelectValueList();
await this.setQueryParams();
this.gridInit();
await this.getGridData();
this.initedFlag = true;
},
async setQueryParams(){
this.queryParams = null;
if(paramKey==this.$route.params.key){
return;
}
if(this.$route.params.key){
paramKey = this.$route.params.key;
this.queryParams = this.$route.params;
}
if(this.queryParams && typeof(this.queryParams)=='object'){
this.selectValue01 = this.queryParams['fabId'];
this.selectValue02 = this.queryParams['eqpmKindId'];
await this.getSelectValueList03();
this.selectValue03 = this.queryParams['eqpmGrpId'];
}
},
async getSelectValueList(){
await this.getSelectValueList01();
await this.getSelectValueList02();
await this.getSelectValueList03();
},
async getSelectValueList01(){
let res = await this.postApiReturn({
apiKey: 'selectFabCodeList',
resKey: 'fabCodeLists',
sendParam: {},
});
if (res.length > 0) {
this.selectValueList01 = await res.map(item => {
return {
text: item.eccNm,
value: item.eccId,
};
});
this.selectValue01 = this.selectValueList01[0].value;
} else {
this.selectValueList01 = [];
this.selectValue01 = null;
}
},
async getSelectValueList02(){
var res = await this.postApiReturn({
apiKey: 'selectEmsEqpmKindList',
resKey: 'eqpmGrpPysclQtyMngData',
sendParam: {},
});
if (res.length > 0) {
this.selectValueList02 = await res.map(item => {
return {
text: item.eqpmKindNm,
value: item.eqpmKindId,
data: {
...item,
},
};
});
this.selectValue02 = this.selectValueList02[0].value;
} else {
this.selectValueList02 = [];
this.selectValue02 = null;
}
},
async getSelectValueList03(){
var res = await this.postApiReturn({
apiKey: 'selectEmsEqpmGrpList',
resKey: 'eqpmGrpPysclQtyMngData',
sendParam: {
eqpmKindId: this.selectValue02,
},
});
if (res.length > 0) {
this.selectValueList03 = await res.map(item => {
return {
text: item.eqpmGrpNm,
value: item.eqpmGrpId,
data: {
...item,
},
};
});
this.selectValue03 = this.selectValueList03[0].value;
} else {
this.selectValueList03 = [];
this.selectValue03 = null;
}
},
gridInit(){
const gridHeight = this.$refs.gridParent.offsetHeight - 30;
const _this = this;
var columnList = [
{header:'NO', name:'no', align:'center'},
{header:'fabId', name:'fabId', hidden:true},
{header:'FAB', name:'fabNm', align:'left'},
{header:'eqpmGrpId', name:'eqpmGrpId', hidden:true},
{header:'설비그룹', name:'eqpmGrpNm', align:'left'},
{header:'eqpmId', name:'eqpmId', hidden:true},
{header:'설비명', name:'eqpmNm', align:'left'},
{header:'계획량', name:'planVal', align:'right'},
{header:'사용량', name:'usedVal', align:'right'},
{header:'KPI', name:'effcRt', align:'right'},
{header:'지표1', name:'gd01', align:'right'},
{header:'지표2', name:'gd02', align:'right'},
{header:'지표3', name:'gd03', align:'right'},
{header:'지표4', name:'gd04', align:'right'},
{header:'지표5', name:'gd05', align:'right'},
{header:'지표6', name:'gd06', align:'right'},
{header:'지표7', name:'gd07', align:'right'},
{header:'지표8', name:'gd08', align:'right'},
{header:'지표9', name:'gd09', align:'right'},
{header:'지표10', name:'gd10', align:'right'},
];
const myOptions = {
columnOptions: {
resizable: true,
},
header:{
height:65,
complexColumns:[
{
header:'주요지표',
name:'complexColumn01',
childNames:[
'gd01',
'gd02',
'gd03',
'gd04',
'gd05',
'gd06',
'gd07',
'gd08',
'gd09',
'gd10',
]
}
]
}
};
this.setGridOption({
gridKey: this.gridName,
value: Object.assign(Utility.defaultGridOption(gridHeight), myOptions),
});
this.setGridColumn({
gridKey: this.gridName,
value: columnList,
});
},
async getGridData(){
this.loadGrid = false;
this.enrgUseMainIdxDesc = [];
var apiKey = null;
var params = {
fabId:this.selectValue01,
eqpmKindId:this.selectValue02,
eqpmGrpId:this.selectValue03,
fromDt:this.pageData.fromDt
};
if(this.pageData.cmCycle=='CYC_DAY'){
params['fromDtMm'] = String(this.pageData.fromDt).substring(0, 6);
apiKey = 'selectDailyEnrgUseMainIdx';
}else if(this.pageData.cmCycle=='CYC_MONTH'){
apiKey = 'selectMonthlyEnrgUseMainIdx';
}
var res = await this.postApiReturn({
apiKey: apiKey,
resKey: 'eqpmIndMntrData',
sendParam: params,
});
this.enrgUseMainIdxDesc = await this.getEnrgUseMainIdxDesc();
// this.enrgUseMainIdxDesc = await this.postApiReturn({
// apiKey: 'selectEnrgUseMainIdxDesc',
// resKey: 'eqpmIndMntrData',
// sendParam: {
// eqpmGrpId:this.selectValue03
// },
// });
var newRes = [];
for(var i=0; i<res.length; i++){
newRes.push({
...res[i],
'no':(i+1)
});
}
this.setGridData({
gridKey: this.gridName,
value: newRes,
});
this.loadGrid = true;
this.makeTooltip();
},
async getEnrgUseMainIdxDesc(){
var res = await this.postApiReturn({
apiKey: 'selectEnrgUseMainIdxDesc',
resKey: 'eqpmIndMntrData',
sendParam: {
eqpmGrpId:this.selectValue03
},
});
while(res.length < 10){
res.push({
});
}
return res;
},
async search(){
await this.getGridData();
},
async makeTooltip(){
var gdIdxList = ['gd01', 'gd02', 'gd03', 'gd04', 'gd05', 'gd06', 'gd07', 'gd08', 'gd09', 'gd10'];
var elementList = [];
await new Promise(resolve => setTimeout(resolve, 1000));
for(var i=0; i<gdIdxList.length; i++){
var selector = '.tui-grid-cell-header[data-column-name="'+gdIdxList[i]+'"]';
var tempElement = document.querySelector(selector);
elementList.push(tempElement);
}
for(var i=0; i<elementList.length; i++){
var columnElement = document.createElement('span');
var tooltipElement = document.createElement('div');
// var tooltipContent = this.enrgUseMainIdxDesc[i].gdIdxNm != undefined ? this.enrgUseMainIdxDesc[i].gdIdxNm : '지표에 대한 정보가 없습니다.';
var tooltipContent = this.enrgUseMainIdxDesc[i].gdIdxNm != undefined ? this.enrgUseMainIdxDesc[i].gdIdxNm : '지표';
console.log('this.enrgUseMainIdxDesc : ', this.enrgUseMainIdxDesc);
console.log('tooltipContent[' + i + '] : ', tooltipContent );
// textContent 세팅
columnElement.textContent = elementList[i].textContent;
elementList[i].textContent = '';
tooltipElement.textContent = tooltipContent;
// tooltipElement.textContent = this.enrgUseMainIdxDesc[i].gdIdxNm;
// id값 설정
columnElement.id = 'tooltipTargetElement_'+i;
tooltipElement.id = 'tooltipElement_'+i;
// element 추가
elementList[i].append(columnElement);
elementList[i].append(tooltipElement);
}
},
// gridMouseoverEvent(e){
// if(e.targetType=='columnHeader'){
// if(String(e.columnName).search('gd')>=0){
// this.tooltipData.content = null;
// var element = document.querySelector('.tui-grid-cell-header[data-column-name="'+e.columnName+'"]');
// var boundingClientRect = element.getBoundingClientRect();
// this.tooltipData.x = (boundingClientRect.right + boundingClientRect.left)/2;
// this.tooltipData.y = boundingClientRect.top;
// for(var i=0; i<this.enrgUseMainIdxDesc.length; i++){
// if(this.enrgUseMainIdxDesc[i].gdSeq == String(e.columnName).toUpperCase()){
// this.tooltipData.content = this.enrgUseMainIdxDesc[i].gdIdxNm;
// }
// }
// if(this.tooltipData.content==null){
// this.tooltipData.content = '지표에 대한 정보가 없습니다.';
// }
// this.tooltipData.show = true;
// }
// }
// },
// gridMouseoutEvent(e){
// if(e.targetType=='columnHeader'){
// this.tooltipData.show = false;
// }
// },
gridDoubleClickEvent(_, event, gridName){
var gridInstance = this.$refs[this.gridName].gridInstance;
var eventRowData = gridInstance.invoke('getRow', event.rowKey);
var data = {
cmCycle : this.pageData.cmCycle,
fromDt : this.pageData.fromDt,
fabId:this.selectValue01,
eqpmKindId:this.selectValue02,
eqpmGrpId:this.selectValue03,
eqpmId:eventRowData.eqpmId
};
var key = 'tick_' + Math.random();
this.$router.push({
name:'ems-effc-EnrgUseEqpmDetlMntrPage',
query:{
prgmId:'PRG0082',
// tick:key
},
params:{
...data,
key:key
}
})
}
}
};
const defaultData = {
cmCycle:'CYC_MONTH',
cmCycleList: [
{ idx: 0, text: '월', value: 'CYC_MONTH' },
{ idx: 1, text: '일', value: 'CYC_DAY' },
],
defaultRange: {
CYC_MONTH: 1,
CYC_DAY: 1,
},
fromDt: Utility.setFormatDate(new Date(), 'YYYYMM'), // 조회 시작일
grid01:{
data: [],
column: [],
option: {},
}
}
</script>
<style lang="scss">
// #tooltipTargetElement_0:hover + #tooltipElement_0{
// display : block
// }
// #tooltipElement_0{
// display : none
// }
@for $i from 0 through 9{
#tooltipTargetElement_#{$i}:hover + #tooltipElement_#{$i}{
display : block
}
#tooltipElement_#{$i}{
display : none
}
}
</style>

File diff suppressed because it is too large Load Diff