Files
sk_fems_ui/pages/ems/effc/EnrgUsePlanPage.vue
Nguyen Van Luan/(Nguyen Van Luan)/현장대리인/SK 5735777bb1 fixbug
2025-08-04 18:53:30 +09:00

858 lines
21 KiB
Vue

<template>
<div ref="mainDiv" class="l-layout">
<CommonPageTitle />
<v-row ref="searchFilter">
<v-col :cols="12">
<v-card class="searchFilter">
<v-row align="end" no-gutters>
<v-col :cols="2.5">
<DatePicker :parentPrgmId="myPrgmId" :label="'조회연도'" customClass="datepicker-large"/>
</v-col>
<v-col :cols="2.5">
<component :is="'SelectBox'" ref="SelectBox1" :propsValue="selectValue01" :itemList="selectValueList01"
:label="'FAB'" @update:propsValue="selectValue01 = $event" :iconShow="true" customClass="select-large" />
</v-col>
<v-col :cols="2.5">
<component :is="'SelectBox'" ref="SelectBox2" :propsValue="selectValue02" :itemList="selectValueList02"
:label="'설비종류'" @update:propsValue="selectValue02 = $event" :iconShow="true" customClass="select-large"/>
</v-col>
<v-col :cols="2.5">
<component :is="'SelectBox'" ref="SelectBox3" :propsValue="selectValue03" :itemList="selectValueList03"
:label="'설비그룹'" @update:propsValue="selectValue03 = $event" :iconShow="true" customClass="select-large" />
</v-col>
<BtnSearch size="large" @click="search" />
<!-- <v-col>
</v-col> -->
</v-row>
<component ref="EnrgUsePlanModiPop" :is="'EnrgUsePlanModiPop'" :label="'test'" :parentPrgmId="myPrgmId"
@gridEditingFinish="gridEditingFinish" />
</v-card>
</v-col>
</v-row>
<v-row ref="contents">
<v-col :cols="12" >
<v-card class="pb-5">
<div class="d-flex align-center justify-space-between py-4 px-4">
<v-card-title class="pa-0 custom-title-4">설비별 에너지 계획 리스트</v-card-title>
<Buttons :parentPrgmId="myPrgmId" :bindingData="gridName" :btnActionsFnc="btnActions" />
</div>
<div ref="gridParent" class="px-5" style="min-height: 60vh;">
<component :ref="gridName" :is="loadGrid ? 'Grid' : null" :gridName="gridName" :parentPrgmId="myPrgmId"
:editorGrid="true" @getRowsData="getRowData" />
</div>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script>
import { mapState, mapActions, mapMutations } 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 CustomButton {
constructor(props) {
const { grid, rowKey, columnInfo } = props;
const gridData = grid.store.data.rawData;
const value = gridData[rowKey][columnInfo.name];
this.disabled = columnInfo.renderer.options.disabled || false;
const elDiv = document.createElement('div');
elDiv.innerHTML = `<span>${value}</span>`;
$(elDiv).addClass('tui-grid-cell-content d-flex justify-space-between');
const el2 = document.createElement('button');
$(el2).addClass('edit-btn blue--text');
el2.innerText = '편집하다';
elDiv.appendChild(el2);
this.el = elDiv;
if (!this.disabled) {
// 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: 'right',
// 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,
// formatter: ({ value, row }) => {
// return `
// <span>${value}</span>
// <button class="edit-btn" data-row='${JSON.stringify(row)}'>Edit</button>
// `;
// }
renderer: {
type: CustomButton,
options: {
value: '계획수정',
},
},
},
{
header: '',
name: 'btnCol',
width: 70,
align: 'center',
hidden: true,
renderer: {
type: CustomButton,
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" scoped>
// @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>