| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356 |
- <template>
- <!-- CORE 개별 상세 팝업 : S -->
- <v-dialog
- v-model="isCoreDetailModal"
- persistent
- width="62.5rem"
- >
- <div class="v-common-dialog-wrapper custom-dialog alert">
- <div class="modal-tit">
- <strong>{{ coreInfo?.neName }}</strong>
- <button
- class="btn-close"
- @click="fnClose()"
- />
- </div>
-
- <div class="v-common-dialog-content pa-0">
- <div class="core--list--component">
- <h2>시스템 정보 및 KPI</h2>
- <!--
- contents critical, major, minor, normal 추가하여 사용
- -->
- <ul class="system--info">
- <li>
- <span class="titles">NE 유형</span>
- <span class="">{{ coreInfo?.neType }}</span>
- </li>
- <li>
- <span class="titles">고객 유형</span>
- <span class="">{{ coreInfo?.customerTypeName }}</span>
- </li>
- </ul>
- <ul class="system--info">
- <li>
- <span class="titles">STATUS</span>
- <span
- class="contents"
- :class="getBodyStatusClass(coreInfo?.connect)"
- >
- {{ coreInfo?.connect?.isConnected ? 'ACTIVE' : coreInfo?.connect?.reason.join(',') }}
- </span>
- </li>
- <li v-if="coreInfo?.kpiItems && coreInfo?.kpiItems.length > 0">
- <span class="titles">{{ coreInfo?.kpiItems[0].label }}</span>
- <span
- class="contents"
- :class="getBodyLevelClass(coreInfo?.kpiItems[0].val)"
- >{{ toRoundFix(coreInfo?.kpiItems[0].val, 2) }}%</span>
- </li>
- </ul>
- <ul
- v-if="coreInfo?.kpiItems && coreInfo?.kpiItems.length > 1"
- class="system--info"
- >
- <li v-if="coreInfo?.kpiItems && coreInfo?.kpiItems.length > 1">
- <span class="titles">{{ coreInfo?.kpiItems[1].label }}</span>
- <span
- class="contents"
- :class="getBodyLevelClass(coreInfo?.kpiItems[1].val)"
- >{{ toRoundFix(coreInfo?.kpiItems[1].val, 2) }}%</span>
- </li>
- <li v-if="coreInfo?.kpiItems && coreInfo?.kpiItems.length > 2">
- <span class="titles">{{ coreInfo?.kpiItems[2].label }}</span>
- <span
- class="contents"
- :class="getBodyLevelClass(coreInfo?.kpiItems[2].val)"
- >{{ toRoundFix(coreInfo?.kpiItems[2].val, 2) }}%</span>
- </li>
- </ul>
- <ul
- v-if="coreInfo?.kpiItems && coreInfo?.kpiItems.length > 3"
- class="system--info"
- >
- <li v-if="coreInfo?.kpiItems && coreInfo?.kpiItems.length > 3">
- <span class="titles">{{ coreInfo?.kpiItems[3].label }}</span>
- <span
- class="contents"
- :class="getBodyLevelClass(coreInfo?.kpiItems[3].val)"
- >{{ toRoundFix(coreInfo?.kpiItems[3].val, 2) }}%</span>
- </li>
- <li v-if="coreInfo?.kpiItems && coreInfo?.kpiItems.length > 4">
- <span class="titles">{{ coreInfo?.kpiItems[4].label }}</span>
- <span
- class="contents"
- :class="getBodyLevelClass(coreInfo?.kpiItems[4].val)"
- >{{ toRoundFix(coreInfo?.kpiItems[4].val, 2) }}%</span>
- </li>
- </ul>
- </div>
- <div class="core--list--component--grid">
- <div class="title">
- <h2>장애 이력 ({{ objCount.total }})</h2>
- <div class="status">
- <ul>
- <li class="critical">
- <span>CRITICAL</span>:<span>{{ objCount.critical }}</span>
- </li>
- <li class="minor">
- <span>MAJOR</span>:<span>{{ objCount.major }}</span>
- </li>
- <li class="major">
- <span>MINOR</span>:<span>{{ objCount.minor }}</span>
- </li>
- </ul>
- </div>
- </div>
- <div class="tbl-wrapper">
- <div class="tbl-wrap">
- <!-- ag grid -->
- <ag-grid-vue
- style="width:100%; height:calc(10 * 2.76rem);"
- class="ag-theme-quartz"
- :grid-options="gridOptions"
- :row-data="eventItems"
- :suppress-pagination-panel="true"
- @grid-ready="fnOnGridReady"
- />
- </div>
- </div>
- </div>
- </div>
- <div
- class="btn-wrap nw--btn--wrap"
- style="padding-top:1.88rem"
- >
- <div />
- <div class="inner--btn--wrap">
- <v-btn
- class="custom-btn btn-gray mini"
- @click="fnClose()"
- >
- <i class="ico" />
- 닫기
- </v-btn>
- </div>
- </div>
- </div>
- </v-dialog>
- <!-- CORE 개별 상세 팝업 : E -->
- </template>
- <script setup>
- import { useI18n } from "vue-i18n"
- import useAxios from '@/composables/useAxios';
- import useUtil from '@/composables/useUtil';
- import useErrorHandler from '@/composables/useErrorHandler';
- import useEnumCodeKr from '@/composables/useEnumCodeKr';
- import apiUrl from '@/composables/useApi';
- import dayjs from "#build/dayjs.imports.mjs";
- import "ag-grid-community/styles/ag-grid.css";
- import "ag-grid-community/styles/ag-theme-quartz.css";
- import { AgGridVue } from "ag-grid-vue3";
- import testJson from '@/components/home/dashboard/test.json'
- /***********************
- * plugins inject
- ************************/
- const { $toast, $log, $dayjs, $eventBus } = useNuxtApp()
- // props
- const props = defineProps({
- isCoreDetailModal: {
- type: Boolean,
- default: false
- },
- })
-
- // 참조가능 데이터 설정
- defineExpose({
- fnInit,
- })
- // 발신 이벤트 선언
- const emit = defineEmits(["closeModal"]);
- const i18n = useI18n();
- /***********************
- * data & created
- ************************/
- // 모달 open 여부 from props
- const isCoreDetailModal = computed(() => props.isCoreDetailModal);
- // TenantName
- const tenantName = computed(() => useAuthStore().getTenantName);
- // 심각도 리스트
- const severityList = computed(() => useLangStore().getLang === 'kr' ? useEnumCodeKr.severity : useEnumCodeEn.severity)
- // 알람그룹 리스트
- const alarmGroupList = computed(() => useLangStore().getLang === 'kr' ? useEnumCodeKr.alarmGroup : useEnumCodeEn.alarmGroup)
- // 선택된 Core 정보
- const coreInfo = ref({});
- // 카운트
- const objCount = ref({
- total: 0,
- critical: 0,
- major: 0,
- minor: 0,
- })
- // 장애 이력 list
- const eventItems = ref([]);
- const remToPx = () => parseFloat(getComputedStyle(document.documentElement).fontSize);
- const rowHeightRem = 2.5; // 원하는 rem 값
- const rowHeightPx = rowHeightRem * remToPx();
- // gird API
- const gridApi = shallowRef();
- // gridOption
- const gridOptions = {
- columnDefs: [
- { headerName: 'No', valueGetter: "node.rowIndex + 1", maxWidth: 75},
- { headerName: 'Code',field: 'eventCode', maxWidth: 150},
- { headerName: '심각도', field: 'severity', maxWidth: 150, cellRenderer: fnSeverityCellRenderer},
- { headerName: '알람 그룹', field: 'alarmGroup', cellRenderer: fnAlarmGroupCellRenderer},
- { headerName: '위치', field: 'location', },
- { headerName: '알림 원인', field: 'probcause', },
- { headerName: '알람 시간', field: 'alarmTimeStr', cellRenderer: fnAlarmTimeCellRenderer},
- ],
- rowData: eventItems.value, // 테이블 데이터
- suppressMovableColumns: true,
- autoSizeStrategy: {
- type: "fitGridWidth", // width맞춤
- },
- headerHeight : rowHeightPx,
- rowHeight: rowHeightPx,
- suppressPaginationPanel: true, // 하단 default 페이징 컨트롤 숨김
- suppressRowClickSelection: true, // 행 클릭 체크박스 무시
- localeText: {
- noRowsToShow: i18n.t('common.noData')
- },
- defaultColDef: {
- lockVisible: true, // 열을 그리드 밖으로 꺼내지 않음
- },
- }
- /***********************
- * Methods
- ************************/
- /** 모달 시작 */
- function fnInit(item) {
- coreInfo.value = item;
- console.log(coreInfo.value)
- }
- /** 모달 닫기 */
- function fnClose(isReload = false) {
- emit('closeModal', {isReload: isReload})
- fnReset();
- }
- /** 초기화 */
- function fnReset() {
- // coreInfo.value = {};
- objCount.value.total = 0;
- objCount.value.critical = 0;
- objCount.value.major = 0;
- objCount.value.minor = 0;
- // eventItems.value=[];
- }
- /** 장애이력 조회 */
- function fnGetEventList() {
- const params = {
- tenantName: coreInfo.value?.tenantName || tenantName.value,
- neName: coreInfo.value?.neName || '',
- }
- useAxios().post(apiUrl.getCoreEventList, params).then((res) => {
- const {resCode, resMsg, data} = res.data;
- if(resCode == 200) {
- // fnParseData(testJson.coreEvent);
- fnParseData(data || {})
- $log.debug("[dashboard][fnGetEventList][success]")
- } else {
- $log.debug("[dashboard][fnGetEventList][error]", `[${resCode}] ${resMsg}`);
- }
- }).catch((error)=>{
- $log.debug("[dashboard][fnGetEventList][error]", error)
- useErrorHandler().fnSetCommErrorHandle(error, fnGetEventList)
- }).finally(()=>{
- $log.debug("[dashboard][fnGetEventList][finished]")
- })
- }
- /** 데이터 가공 */
- function fnParseData(data = {}) {
- // 카운트 셋팅
- objCount.value.critical = data?.criCnt || 0;
- objCount.value.major = data?.majCnt|| 0;
- objCount.value.minor = data?.minCnt || 0;
- objCount.value.total = data?.criCnt + data?.majCnt + data?.minCnt
- if(data.items) {
- eventItems.value = data?.items?.map((item) => {
- return {
- ...item,
- }
- })
- } else {
- eventItems.value = [];
- }
- }
-
- const toRoundFix = (data, digit) => parseFloat(data).toFixed(digit);
- // 세부 데이터 상태값
- const getBodyLevelClass = (val) => {
- if(val >= 95) return 'critical'; // red
- else if(val >= 90) return 'major'; // blue
- else if(val >= 85) return 'minor'; // gray
- else return 'normal'; // green
- }
- // 세부 데이터 STATUS 상태값
- const getBodyStatusClass = (connect) => {
- if(connect?.isConnected) return 'normal';
- else return 'critical';
- }
- /** Grid 관련 */
- // Grid 데이터 바인딩
- function fnOnGridReady(params){
- gridApi.value = params.api
- fnGetEventList();
- }
- // 심각도
- function fnSeverityCellRenderer(params) {
- const { data } = params;
- const { severity } = data;
- const severityLabel = severityList.value.find((s) => s.value == severity);
- const severityObj = {
- label: severityLabel.title.toUpperCase(),
- class: severityLabel.title.toLowerCase(),
- }
- return `<span class="status--ele ${severityObj.class}">${severityObj.label}</span>`
- }
- // 알람그룹
- function fnAlarmGroupCellRenderer(params) {
- const { data } = params;
- const { alarmGroup } = data;
- return alarmGroupList.value.find((a) => a.value == alarmGroup)?.title || '';
- }
- // 알람시간
- function fnAlarmTimeCellRenderer(params) {
- const { data } = params;
- const { alarmTime } = data;
- return dayjs(alarmTime).format('YYYY-MM-DD HH:mm:ss');
- }
- </script>
|