Files
sk_fems_ui/pages/ems/base/ReadObjectMngPage.vue
Nguyen Van Luan/(Nguyen Van Luan)/현장대리인/SK ecfbeb3afa fixbug
2025-08-08 19:22:33 +09:00

870 lines
20 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div ref="mainDiv" class="l-layout">
<CommonPageTitle />
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row no-gutters>
<v-col :cols="3">
<component
:is="'selectCodeList'"
:parentPrgmId="myPrgmId"
:label="'검침대상 유형'"
dataKey="readObjKind"
:addAll="true"
:sendParam="{ commGrpCd: 'CM_MTTTP', useFg: '1' }"
:iconShow="true"
customClass="select-large"
/>
</v-col>
<v-col :cols="3">
<component
:is="'selectCodeList'"
:parentPrgmId="myPrgmId"
:label="'사용여부'"
dataKey="useFg"
:sendParam="{ commGrpCd: 'CO_USEFG', useFg: '1' }"
:addAll="true"
:iconShow="true"
customClass="select-large"
/>
</v-col>
<v-col :cols="3">
<InputText
:parentPrgmId="myPrgmId"
label="검침대상명"
valueNm="readObjNm"
:searchOption="true"
:iconShow="true"
customClass="input-large"
/>
</v-col>
<v-col :cols="3" class="d-flex align-end justify-end text-right">
<BtnSearch @click="search" size="large" />
</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 ref="gridParent" class="h100 px-5" style="height:calc(100% - 70px)">
<component
:ref="gridName"
:is="loadGrid ? 'Grid' : null"
:gridName="gridName"
:parentPrgmId="myPrgmId"
@getRowsData="getRowData"
@sendSelectedRowStatInfo="getSelectedRowStatInfo"
:selectedRowDataWatchFlag="true"
/>
</div>
</v-card>
</v-col>
<v-col :cols="7" class="h100">
<v-card class="pb-5">
<v-card-title class="custom-title-4-new" style="min-height:65px;"
>검침대상 상세
</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: 'left',
},
{
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: 'left',
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: [
{ commCd: 'K01', commCdNm: '건물' },
       { commCd: 'K02', commCdNm: '공장' },
        { commCd: 'K03', commCdNm: '학교' },
],
readObjGrp: '',
readObjGrpList: [
{ commCd: 'G01', commCdNm: '그룹 A' },
        { commCd: 'G02', commCdNm: '그룹 B' },
        { commCd: 'G03', commCdNm: '그룹 C' },
],
unitCdList: [
{ commCd: 'U01', commCdNm: 'kWh' },
        { commCd: 'U02', commCdNm: 'MJ' },
        { commCd: 'U03', commCdNm: 'TOE' },
],
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,
labelCols: 12,
textCols: 12,
iconShow: true,
class: 'py-2 pr-2',
required: false,
placeholder: '시스템 자동입력',
},
{
type: 'InputText',
label: '검침 대상 명',
valueNm: 'readObjNm',
disabled: false,
cols: 6,
labelCols: 12,
textCols: 12,
class: 'py-2',
required: true,
iconShow: true,
},
{
type: 'SelectBox',
label: '검침 대상 유형',
valueNm: 'readObjKind',
disabled: false,
cols: 6,
labelCols: 12,
textCols: 12,
class: 'py-2 pr-2',
list: 'readObjKindDetailList',
itemText: 'commCdNm',
itemValue: 'commCd',
iconShow: true,
required: true,
},
{
type: 'SelectBox',
label: '그룹',
valueNm: 'grpCd',
disabled: false,
cols: 6,
labelCols: 12,
textCols: 12,
class: 'py-2',
list: 'readObjGrpList',
itemText: 'commCdNm',
itemValue: 'commCd',
iconShow: true,
required: true,
},
{
type: 'InputText',
label: 'TJ 환산계수',
valueNm: 'tjCvrtCoef',
disabled: false,
cols: 6,
labelCols: 12,
textCols: 12,
class: 'py-2 pr-2',
iconShow: true,
inputType: 'number',
},
{
type: 'InputText',
label: 'TOE 환산계수',
valueNm: 'toeCvrtCoef',
disabled: false,
cols: 6,
labelCols: 12,
textCols: 12,
class: 'py-2',
iconShow: true,
inputType: 'number',
},
{
type: 'InputText',
label: 'CO2 환산계수',
valueNm: 'co2CvrtCoef',
disabled: false,
cols: 6,
labelCols: 12,
textCols: 12,
class: 'py-2 pr-2',
iconShow: true,
inputType: 'number',
},
{
type: 'SelectBox',
label: '단위',
valueNm: 'unitCd',
disabled: false,
cols: 6,
labelCols: 12,
textCols: 12,
class: 'py-2',
list: 'unitCdList',
itemText: 'commCdNm',
itemValue: 'commCd',
iconShow: true,
required: true,
},
{
type: 'CheckBox',
label: '사용 여부',
valueNm: 'useFg',
disabled: false,
cols: 6,
labelCols: 12,
textCols: 12,
class: 'py-2 pr-2',
value: { '1': true, '0': false },
iconShow: true,
required: true,
},
];
</script>
<style lang="scss" scoped>
@import '@/assets/scss/common.scss';
::v-deep {
.tui-grid-layer-state {
top: 40px !important;
}
.tui-grid-layer-selection,
.tui-grid-cell-content-editor{
height: 36px !important;
}
}
</style>