| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331 |
- <template>
- <div class="core--component--wrap core--tp">
- <!--현황 정보 영역 -->
- <div>
- <div class="inner--header--wrap">
- <h2 class="inner--component--title none--after">
- CORE
- </h2>
- <span class="inner--component--date">{{ current }}</span>
- </div>
- <div class="inner--content">
- <div class="oper--stat">
- <div class="card--title">
- <h3>운영 현황</h3>
- <p>Total : <span>{{ objCount.total }}</span></p>
- </div>
- <div class="card--cont">
- <div class="card">
- <div class="card--count">
- NE 수 : <span>{{ objCount.customer0 }}</span>
- </div>
- <div class="card--txt">
- 대내 <span>{{ objCount.customer0 }}</span>
- </div>
- </div>
- <div class="card">
- <div class="card--count">
- NE 수 : <span>{{ objCount.customer1 }}</span>
- </div>
- <div class="card--txt">
- 대외 <span>{{ objCount.customer1 }}</span>
- </div>
- </div>
- <div class="card">
- <div class="card--count">
- NE 수 : <span>{{ objCount.customer2 }}</span>
- </div>
- <div class="card--txt">
- 공공 <span>{{ objCount.customer2 }}</span>
- </div>
- </div>
- </div>
- </div>
- <!-- <div class="oper--stat">
- <div class="card--title">
- <h3>장비 상태</h3>
- <p>Total : <span>0</span></p>
- </div>
- <div class="card--alarm">
- <div class="card">
- <div class="ico" />
- <div class="alarm--txt">
- <p>알람 수신</p>
- <span>0</span>
- </div>
- </div>
- <div class="card no--alarm">
- <div class="ico" />
- <div class="alarm--txt">
- <p>알람 미수신</p>
- <span>0</span>
- </div>
- </div>
- </div>
- </div> -->
- <div class="link--stat discon">
- <div class="card--title">
- <h3>연동 상태</h3>
- </div>
- <div class="card--cont">
- <div class="ico" />
- <p>Disconnected</p>
- <span>{{ objCount.disconnected }}</span>
- </div>
- </div>
- </div>
- </div>
- <!-- 위젯 영역 -->
- <WidgetM
- v-if="isLoaded && widgetSize === 'M'"
- :items="coreItems"
- :total-cnt="objCount.total"
- />
- <WidgetS
- v-if="isLoaded && widgetSize === 'S'"
- :items="coreItems"
- :total-cnt="objCount.total"
- />
- </div>
- </template>
- <script setup>
- /***********************
- * import
- ************************/
- import { useI18n } from "vue-i18n"
- import apiUrl from '@/composables/useApi';
- import useAxios from '@/composables/useAxios';
- import useUtil from '@/composables/useUtil';
- import dayjs from "#build/dayjs.imports.mjs";
- import WidgetM from "@/components/home/dashboard/layout03/core/layout03CoreWidgetM.vue"
- import WidgetS from "@/components/home/dashboard/layout03/core/layout03CoreWidgetS.vue"
- import testJson from "../../test.json"
- /***********************
- * plugins inject
- ************************/
- const { $toast, $log, $dayjs, $eventBus } = useNuxtApp()
- // props
- const props = defineProps({
- config: {
- type: Object,
- default: () => {}
- },
- intervalTime: {
- type: Number,
- default: 5000
- }
- })
- // 참조가능 데이터 설정
- defineExpose({})
- // 발신 이벤트 선언
- const emit = defineEmits([""]);
- const i18n = useI18n();
- /***********************
- * data & created
- ************************/
- // TenantName
- const tenantName = computed(() => useAuthStore().getTenantName);
- // 설정된 위젯 사이즈 : M or S
- const widgetSize = computed(() => props.config?.widgetSize || 'M');
- // Swiper 표시 slide 갯수
- const slideItemSize = computed(() => widgetSize.value == 'M' ? 4 : 8)
-
- // 현재 일시
- const current = ref(dayjs().format('YYYY-MM-DD HH:mm:ss'));
- // 카운트 정보
- const objCount = ref({
- total: 0,
- customer0: 0,
- customer1: 0,
- customer2: 0,
- disconnected: 0,
- })
- // 코어 리스트
- const coreItems = ref([]);
- // 데이터 조회 여부
- const isLoaded = ref(false);
-
- /***********************
- * Methods
- ************************/
- /**
- * 리셋
- */
- const fnReset = () => {
- objCount.value.total = 0;
- objCount.value.customer0 = 0;
- objCount.value.customer1 = 0;
- objCount.value.customer2 = 0;
- objCount.value.disconnected = 0;
- current.value = dayjs().format('YYYY-MM-DD HH:mm:ss');
- }
- /**
- * 코어 리스트 조회
- */
- function fnGetCoreList() {
- const params = {
- tenantName: tenantName.value,
- }
- isLoaded.value = false;
- useAxios().post(apiUrl.getCoreInfoList, params).then((res) => {
- const {resCode, resMsg, data} = res.data;
- if(resCode == 200) {
- // 테스트를 위한 테스트 코드 (삭제 필수)
- // fnParseData([...(data?.items || []), ...testJson.core.data.items])
- fnParseData(data.items || [])
- $log.debug("[dashboard][fnGetCoreList][success]")
- } else {
- $log.debug("[dashboard][fnGetCoreList][error]", `[${resCode}] ${resMsg}`);
- }
- }).catch((error)=>{
- // 테스트를 위한 테스트 코드 (삭제 필수)
- // fnParseData([...testJson.core.data.items])
- $log.debug("[dashboard][fnGetCoreList][error]", error)
- useErrorHandler().fnSetCommErrorHandle(error, fnGetCoreList)
- }).finally(()=>{
- $log.debug("[dashboard][fnGetCoreList][finished]")
- isLoaded.value = true;
- })
- }
- /**
- * 데이터 가공
- */
- function fnParseData(items = []) {
- coreItems.value = [];
- if(!items || items.length < 1) {
- objCount.value.total = 0;
- objCount.value.customer0 = 0;
- objCount.value.customer1 = 0;
- objCount.value.customer2 = 0;
- objCount.value.disconnected = 0;
- return;
- }
- let temp = [];
- // 정렬 적용
- temp = items.sort((a, b) => {
- // 위험도순
- return a.criCnt < b.criCnt ? 1 : a.criCnt > b.criCnt ? -1 : (a.majCnt < b.majCnt ? 1 : a.majCnt > b.majCnt ? -1 : (a.minCnt < b.minCnt ? 1 : a.minCnt > b.minCnt ? -1 : 0));
- })
- // 데이터 가공
- temp = temp.map((item) => {
- //카운트 셋팅
- const { customerType } = item;
- objCount.value.total = objCount.value.total+1;
- if(customerType == 0) objCount.value.customer0 = objCount.value.customer0 + 1;
- else if(customerType == 1) objCount.value.customer1 = objCount.value.customer1 + 1;
- else if(customerType == 2) objCount.value.customer2 = objCount.value.customer2 + 1;
- // KPI 정보 셋팅 - TODO: CPU, MEM 외의 값이 추가되면 여기에 추가
- const { cpu, mem } = item;
- const kpiItems = [];
- if(cpu) {
- const objCpu = typeof cpu === 'string' ? JSON.parse(cpu) : cpu;
- if(objCpu && objCpu[`AVG_CPU_L(%)`]){
- kpiItems.push({label: 'CPU', val: objCpu[`AVG_CPU_L(%)`] || 0})
- item.cpu = objCpu;
- }
- }
- if(mem) {
- const objMem = typeof mem === 'string' ? JSON.parse(mem) : mem ;
- if(objMem && objMem['AVG_MEM_L(%)']){
- kpiItems.push({label: 'MEMORY', val: objMem['AVG_MEM_L(%)'] || 0})
- item.mem = objMem;
- }
- }
- // disconected 셋팅
- const { emsStatus, mcmStatus, psmStatus } = item;
- const connect = {
- isConnected: false,
- reason: [],
- }
- if([emsStatus, mcmStatus, psmStatus].every((status) => status == 0)) {
- connect.isConnected = true;
- } else {
- // disconnected 카운트 셋팅
- objCount.value.disconnected = objCount.value.disconnected + 1;
- connect.isConnected = false;
- if(emsStatus != 0 ) connect.reason.push(`emsSatats: ${emsStatus}`);
- if(mcmStatus != 0 ) connect.reason.push(`mcmStatus: ${mcmStatus}`);
- if(psmStatus != 0 ) connect.reason.push(`psmStatus: ${psmStatus}`);
- }
- // 심각도 level 셋팅
- const { criCnt ,majCnt, minCnt } = item;
- let level = '';
- if(criCnt > 0) level = 'CRITICAL';
- else if(majCnt > 0) level = 'MAJOR';
- else if(minCnt > 0) level = 'MINOR';
- return {
- ...item,
- kpiItems, // kpi 정보
- connect, // 연결 상태
- level, // 심각도 레벨
- }
- });
-
- coreItems.value = splitIntoChunk(temp, slideItemSize.value)
- }
-
- /** Array Spliter */
- function splitIntoChunk(arr, chunk) {
- // 빈 배열 생성
- const result = [];
-
- for (let index=0; index < arr.length; index += chunk) {
- // slice() 메서드를 사용하여 특정 길이만큼 배열을 분리함
- const tempArray = arr.slice(index, index + chunk);
- // 빈 배열에 특정 길이만큼 분리된 배열을 추가
- result.push(tempArray);
- }
-
- return result;
- }
- onMounted(() => fnGetCoreList())
- // 위젯사이즈 변경 watch
- watch(() => widgetSize.value, () => {
- fnReset();
- fnGetCoreList();
- }, {deep: true})
- </script>
|