layout01Ran.vue 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951
  1. <template>
  2. <!-- RAN 12x24 지도형 -->
  3. <div class="map--contents--wraper">
  4. <div class="map--contents--wrap">
  5. <div class="header--wrapper">
  6. <div class="titles">
  7. <span>RAN</span>
  8. </div>
  9. <div class="control--wrap">
  10. <v-btn class="custom-btn mini map--btn" :class="{ on: shapeMap }" @click="shapeMap = true">
  11. <i class="icon"></i>지도
  12. </v-btn>
  13. <v-btn class="custom-btn mini card--btn" :class="{ on: !shapeMap }" @click="shapeMap = false">
  14. <i class="icon"></i>카드
  15. </v-btn>
  16. </div>
  17. </div>
  18. <div class="inner--content--wrapper" v-if="shapeMap == true">
  19. <div class="map--wrappers">
  20. <!-- 맵 데이터 -->
  21. <div class="map--text">
  22. <div v-for="(item, idx) in mapDataInfo" :key="idx" class="map--text--inner" :class="item.cls">
  23. <div class="title" @click="fnDetailArea(item, idx)" style="cursor:pointer;">{{item.areaName}} <span>({{item.neInfoList.length}})</span></div>
  24. <div class="status">
  25. <span class="critical" v-show="item.criCnt > 0">{{item.criCnt}}</span>
  26. <span class="major" v-show="item.majCnt > 0">{{item.majCnt}}</span>
  27. <span class="minor" v-show="item.minCnt > 0">{{item.minCnt}}</span>
  28. </div>
  29. </div>
  30. </div>
  31. <!-- 맵 백터 이미지 -->
  32. <!-- 서울 -->
  33. <div class="mapdt seoul" :class="getEventClass(mapDataInfo[0])">
  34. <svg xmlns="http://www.w3.org/2000/svg" width="3.68181rem" height="2.79144rem" viewBox="0 0 60 45" fill="none">
  35. <path d="M24.8178 45.0053L39.0906 43.6408L49.3633 37.6372L55.5451 32.907L59.2724 26.2666H52.636L52.1815 13.2587L45.4542 0.796618L37.1815 0.341797L26.2724 8.34666L15.9087 9.98402L12.8178 19.4443L2.45419 22.2642L0.363281 27.3582L6.5451 29.5413L15.0906 31.9064L13.9996 37.3643L24.8178 45.0053Z" fill="currentColor"/>
  36. </svg>
  37. </div>
  38. <!-- 부산 -->
  39. <div class="mapdt busan" :class="getEventClass(mapDataInfo[1])">
  40. <svg xmlns="http://www.w3.org/2000/svg" width="4.5rem" height="2.68344rem" viewBox="0 0 73 44" fill="none">
  41. <path d="M67.7283 22.4503L71.7283 10.443L72.9101 8.80567L71.8193 7.35024L66.2738 6.34962L59.9102 1.52853L56.9102 0.164062L45.7283 6.62253L42.1829 12.2623L31.2738 9.80628L21.1829 13.7177L2.63742 11.4436L0.910156 22.4503L4.18289 27.9991L9.91015 28.0901L9.27378 34.6395L19.2738 35.913L25.9102 38.9149L36.9102 34.0937L41.3647 43.0992L54.9102 33.457L67.7283 22.4503Z" fill="currentColor"/>
  42. </svg>
  43. </div>
  44. <!-- 대구 -->
  45. <div class="mapdt daegu" :class="getEventClass(mapDataInfo[2])">
  46. <svg xmlns="http://www.w3.org/2000/svg" width="4rem" height="3.95694rem" viewBox="0 0 65 64" fill="none">
  47. <path d="M35.092 56.5014L45.9102 55.046L50.8192 49.6791L44.6374 40.0368L50.2738 34.3061L57.2738 22.7536L64.9102 19.206L64.5465 8.01742L59.7283 0.103516H43.1829L30.3647 12.5656L20.6374 9.01801L10.092 16.75L6.27379 27.1199L19.3647 34.7609H11.6374L6.27379 41.1284L9.63743 49.861H2.81925L0.910156 53.1357L4.72832 60.3219L15.4556 55.8646L17.6374 56.5924L21.8192 63.4147L26.3647 52.9538L35.092 56.5014Z" fill="currentColor"/>
  48. </svg>
  49. </div>
  50. <!-- 인천 -->
  51. <div class="mapdt incheon" :class="getEventClass(mapDataInfo[3])">
  52. <svg xmlns="http://www.w3.org/2000/svg" width="1.73863rem" height="2.22294rem" viewBox="0 0 29 37" fill="none">
  53. <path d="M28.5447 11.7185L22.0902 6.07867L11.272 0.802734L0.726562 3.71359L3.45384 16.2667L12.8175 23.6348L13.0902 31.1848L16.1811 33.5499L23.0902 36.3698L24.6357 23.8167L28.5447 11.7185Z" fill="currentColor"/>
  54. </svg>
  55. </div>
  56. <!-- 강화 -->
  57. <div class="mapdt kanghwa" :class="getEventClass(mapDataInfo[3])">
  58. <svg xmlns="http://www.w3.org/2000/svg" width="1.80113rem" height="2.70619rem" viewBox="0 0 29 44" fill="none">
  59. <path d="M28.908 21.0585L20.7262 0.136719L6.45348 10.9615L5.99893 28.2447L0.0898438 41.3436L20.3626 43.4357L28.908 31.7013V21.0585Z" fill="currentColor"/>
  60. </svg>
  61. </div>
  62. <!-- 광주 -->
  63. <div class="mapdt gwangju" :class="getEventClass(mapDataInfo[4])">
  64. <svg xmlns="http://www.w3.org/2000/svg" width="3.07956rem" height="1.66013rem" viewBox="0 0 50 28" fill="none">
  65. <path d="M45.7262 22.4564L49.3626 14.6335L44.3626 11.1769L39.5444 2.89911L26.4535 1.71658L14.3626 0.625L6.54439 5.17322L5.45348 10.5401L0.0898438 14.6335C0.0898438 14.6335 3.08985 24.1848 3.36257 24.3667C3.6353 24.5486 14.0898 23.9119 15.1808 24.3667C16.2717 24.8215 24.908 27.1866 24.908 27.1866L38.0898 26.2769L45.7262 22.4564Z" fill="currentColor"/>
  66. </svg>
  67. </div>
  68. <!-- 대전 -->
  69. <div class="mapdt daejeon" :class="getEventClass(mapDataInfo[5])">
  70. <svg xmlns="http://www.w3.org/2000/svg" width="2.49431rem" height="3.04194rem" viewBox="0 0 41 50" fill="none">
  71. <path d="M40.3622 41.5497L38.9986 35.2732H35.8168L34.3622 34.5455L31.544 30.8159L31.2713 29.2695L34.0895 18.3538L34.6349 17.7171L35.0895 17.1713L38.7258 15.5339V14.2604H35.9077L34.1804 12.8959L32.7259 7.52906L29.6349 8.98449L27.8168 8.80255L21.1804 3.70854L20.544 2.70796L20.0895 0.888672L16.9986 6.98326L8.81676 16.3526L0.453125 23.084L4.81676 32.8171L9.63494 40.5491L19.3622 42.4593L24.9077 46.4618C24.9077 46.4618 29.4531 49.3727 30.0895 49.5546C30.7258 49.7365 37.8168 45.3702 37.8168 45.3702L40.3622 41.5497Z" fill="currentColor"/>
  72. </svg>
  73. </div>
  74. <!-- 울산 -->
  75. <div class="mapdt ulsan" :class="getEventClass(mapDataInfo[6])">
  76. <svg xmlns="http://www.w3.org/2000/svg" width="3.36363rem" height="3.0985rem" viewBox="0 0 55 50" fill="none">
  77. <path d="M0.363281 22.0602L2.63601 27.882H9.27236L13.4542 37.7061L20.2724 40.9808L26.7269 45.9839L33.0906 46.8025L35.636 49.6224L39.7269 46.4387V37.5242L46.2724 31.1567L50.3633 33.4308L54.1814 12.3271L43.636 6.8692L40.5451 11.4174L38.7269 12.2361L30.7269 10.5987L29.2724 8.8704V0.046875L15.4542 0.956518L10.3633 7.77884L9.27236 8.50655L7.27238 16.9662L0.363281 22.0602Z" fill="currentColor"/>
  78. </svg>
  79. </div>
  80. <!-- 세종 -->
  81. <div class="mapdt sejong" :class="getEventClass(mapDataInfo[7])">
  82. <svg xmlns="http://www.w3.org/2000/svg" width="1.94888rem" height="2.52425rem" viewBox="0 0 32 41" fill="none">
  83. <path d="M26.7262 4.69162H18.908L3.08984 0.234375L0.0898438 4.69162L1.81712 16.426L13.3626 26.3411L15.1808 36.0743L20.9989 40.6225L27.908 32.6177L31.2717 23.7941L26.6353 5.05547L26.7262 4.69162Z" fill="currentColor"/>
  84. </svg>
  85. </div>
  86. <!-- 경기도 -->
  87. <div class="mapdt gyeonggi-do" :class="getEventClass(mapDataInfo[8])">
  88. <svg xmlns="http://www.w3.org/2000/svg" width="8.40906rem" height="10.97256rem" viewBox="0 0 136 177" fill="none">
  89. <path d="M134.273 102.174L135.182 100.9L133.091 99.0808L122.637 98.535L121.364 97.8982L114.455 90.1663L105.637 90.712L103.728 88.8018L104.455 78.2499L101.819 74.7933L101.728 72.7011L105.364 67.5161L105.455 59.9661L106.364 58.4197L114.364 53.7805V45.4118L100.455 35.4057L99.7276 34.1322L99.0004 28.4015L94.9094 25.9455L88.0004 28.1286L86.4549 27.9467L83.4549 26.0364L82.7276 24.1262L84.0004 17.9406L83.1822 17.2129L80.4549 20.6695L77.7276 20.7605L70.9095 13.7562L70.364 12.8466L69.364 7.47969L66.1822 6.84294L64.7276 4.6598L65.7276 0.566406L55.1822 3.84112L53.364 11.2092H48.1822L44.8185 4.20498L40.1822 8.4803L36.0913 9.48091L30.0913 14.8478L29.5458 22.3069L34.364 25.1268L37.9095 22.3978L43.9095 29.1292L41.6367 33.6774L37.0913 31.0395L32.5458 36.0425L37.4549 40.5907L33.2731 47.504L29.5458 43.3196L28.2731 35.2238L16.5458 41.2275L25.7276 48.7775L25.0913 53.1438L19.4549 54.4173L22.2731 66.4246L20.0913 74.4294L17.7276 73.7927L17.8185 67.88L11.7276 60.5119L1.63672 69.3354L5.72763 88.347L17.4549 85.8L31.1822 92.0765L37.8185 97.8073L46.8185 94.8964L50.1822 85.3452L61.6367 83.4349L72.9094 75.2481L84.8185 76.2487L93.0913 91.4398L93.0004 101.537H100.728L96.5458 113.908L89.2731 119.912L77.5458 126.825L60.9095 127.916L46.5458 117.91L48.0913 113.271L42.5458 111.543L36.364 109.542L34.8185 114.272L33.4549 132.283L21.2731 126.279L2.27308 125.097L0.636719 134.102L7.00036 134.557L12.0913 145.473H16.8185L21.0913 141.015L25.5458 142.107L19.9094 148.838L21.8185 162.847L31.9094 173.399L59.1822 165.94L60.9095 166.303L71.6367 176.128L77.364 170.124L77.8185 169.851L84.8185 166.212L93.1822 157.662L95.364 157.389L99.1822 159.663L102.182 160.027L107.728 155.388V150.749L109.546 148.929H115.455L118.637 144.745L119.546 143.562L120.909 139.287L121.455 130.736L121.546 130.1L129.091 112.089L125.455 105.721L126.819 102.992L134.273 102.174Z" fill="currentColor"/>
  90. </svg>
  91. </div>
  92. <!-- 강원 -->
  93. <div class="mapdt kangwon" :class="getEventClass(mapDataInfo[9])">
  94. <svg xmlns="http://www.w3.org/2000/svg" width="13.77275rem" height="12.80894rem" viewBox="0 0 222 205" fill="none">
  95. <path d="M0.726562 36.6586L3.27202 37.1134L4.72657 38.5689L5.81748 44.6635L10.9084 49.8484L13.5448 46.5737L16.1811 46.3918L19.1811 49.1207L19.7266 50.8491L18.4538 56.8527L19.7266 57.6714L26.6357 55.4882L28.0902 55.6702L33.5448 58.9449L34.3629 60.2184L35.1811 66.0401L49.1811 76.2281L49.9084 77.6835V87.9625L48.9993 89.5089L40.9993 94.1481L40.9084 101.243L40.5447 102.244L37.3629 106.792L39.6357 109.703L39.9993 110.976L39.3629 120.073L46.9993 119.618L48.4538 120.255L55.4538 128.078L65.8175 128.624L66.9084 129.078L70.7266 132.353L70.9993 134.809L68.6357 138.084L67.3629 138.812L61.9084 139.448L64.6357 144.269L64.7266 145.907L56.9084 164.463L56.4538 172.923L56.3629 173.378L55.1811 177.017L58.9084 180.018L67.9993 180.564L73.9993 181.656L74.7266 179.836L72.5447 174.833L73.5448 172.377L81.8175 169.285L83.9084 169.921L88.272 176.289L88.5448 176.835L89.272 179.564L91.9993 179.745L101.727 173.651L103.817 173.833L107.454 176.835L117.999 178.745L119.454 180.564V183.748L118.363 185.385L115.09 186.841L118.636 185.931L120.545 186.659L124.727 192.662L133.545 192.026L134.272 192.117L146.09 196.483L146.636 196.756L149.363 199.03L150.09 198.848L150.454 199.94L154.454 203.214L157.454 202.759L157.181 199.485L158.545 197.574L165.817 195.846L167.545 196.392L172.272 201.759L174.636 198.939L175.908 198.302L180.727 198.12L181.908 198.484L186.454 202.123L191.999 199.485H193.636L204.272 204.943L212.454 195.3L213.545 194.664L221.09 193.39L220.09 185.203L204.636 147.726L158.636 70.4973L131.908 0C131.272 0 125.727 3.00182 125.727 3.00182L119.545 23.8327L105.363 35.2032H93.1811L83.5448 31.2008L79.1811 33.02L69.5447 32.6562L59.1811 30.2911L53.9993 32.2923H41.6357L32.3629 31.5646L27.1811 29.7453L12.8175 31.9285L8.18111 26.9254L1.9993 30.9279H2.18111L0.726562 36.6586Z" fill="currentColor"/>
  96. </svg>
  97. </div>
  98. <!-- 충북 -->
  99. <div class="mapdt chungbuk" :class="getEventClass(mapDataInfo[10])">
  100. <svg xmlns="http://www.w3.org/2000/svg" width="8.8125rem" height="9.59675rem" viewBox="0 0 142 155" fill="none">
  101. <path d="M33.7269 147.103L35.9996 147.467L41.2724 153.471L51.4542 152.834L51.636 152.288L57.9087 154.472L61.9996 147.74L64.3633 137.825L65.5451 136.552L70.9087 134.732V128.183L65.636 129.002L64.7269 128.911L53.7269 125.363L52.4542 123.635V119.632L52.7269 118.814L57.0906 110.445L55.3633 89.5231L49.5451 84.611L49.3633 82.064L52.9087 78.0616L54.9997 77.5158L61.1815 80.2447L63.8178 76.97L60.2724 72.3308L60.4542 69.8748L64.2724 66.3272L65.5451 65.7814H75.9087L77.0906 66.2362L79.3633 68.2374L79.636 66.6L76.9996 62.5976L77.0906 60.5055L80.0906 56.8669L82.7269 56.6849L83.5451 57.4127V55.2295L84.0906 53.8651L87.9087 50.3174L90.1815 50.1355L95.7269 54.138L96.9087 52.5915V48.862L99.9997 47.5885L110.272 58.7771L114 55.7753L116.091 55.6843L117.727 56.8669L119.363 52.6825L117 48.2253V46.7698L119.636 39.9475L121.091 38.8559L126.727 38.1282L132.272 30.9421L133.181 30.3053L141.363 27.8493L140.727 27.3944L129.636 23.2101L120.181 23.9378L118.636 23.1191L114.545 17.3884L107.545 19.2986L105.636 18.6619L103.909 16.2968L104.545 13.5679L112 10.2022V9.74736L102.454 8.01903L101.636 7.56421L98.636 5.10818L89.5451 10.8389L88.4542 11.1118L83.9087 10.8389L82.2724 9.47447L81.2724 5.8359L77.8178 0.923828L72.636 2.83407L74.3633 6.74554V8.20097L72.8178 12.1124L70.8178 13.204L63.5451 11.9305L54.1815 11.2938L53.1815 10.9299L49.4542 8.01903L45.8178 12.8401L44.3633 13.5679H39.3633V17.2064L38.7269 18.5709L31.9087 24.3017L30.5451 24.7565L26.3633 24.2107L25.636 23.9378L22.7269 22.2095L15.2724 29.9414L14.8178 30.3053L7.72692 33.8529L2.09056 39.7656L15.8178 57.9585L16.1815 59.05V62.7796L13.5451 64.4169L6.81783 61.2332L0.363281 68.1464L6.63602 93.2526L11.9087 97.255L15.9996 95.3448L18.4542 96.5273L20.0906 102.622H23.4542L25.1815 104.441V108.717L24.1815 110.354L20.2724 112.082L17.9087 121.361L19.636 123.726H23.4542L25.1815 125.09L30.4542 148.741H30.9087L33.7269 147.103Z" fill="currentColor"/>
  102. </svg>
  103. </div>
  104. <!-- 충남 -->
  105. <div class="mapdt chungnam" :class="getEventClass(mapDataInfo[11])">
  106. <svg xmlns="http://www.w3.org/2000/svg" width="9.26706rem" height="8.92588rem" viewBox="0 0 149 144" fill="none">
  107. <path d="M148.726 134.741L146.362 124.098L144.271 126.372C144.271 126.372 135.18 131.193 134.544 131.011C133.908 130.83 128.908 128.374 128.908 128.374L123.362 123.461L111.726 121.642L105.999 112.91L101.18 99.8107L110.271 92.0788L104.544 88.0763L101.999 77.6154L90.544 68.7009L87.6349 53.237L93.2713 44.2315L111.635 49.2346H118.817L120.271 50.3261L126.999 43.8677L129.089 43.5038L134.544 46.0508V45.7779L120.362 26.8573L109.271 16.6693L84.3622 23.4917L77.2713 31.0417L73.4531 16.0326L56.4531 4.38916L52.4531 0.386719L40.6349 0.568658L42.8168 8.20966L40.6349 11.5753L34.8168 1.93312L23.6349 8.75545L32.9986 15.7597L32.8168 21.3995L27.9986 27.4031L23.6349 25.4019L22.4531 10.7567L13.2713 17.579L0.453125 33.9526L1.81676 37.7731L6.63494 35.7718L7.81676 39.1375L7.99858 43.3219L12.1804 42.5032L15.3622 56.5117H18.1804L20.3622 49.3255L23.9986 56.5117L30.1804 55.5111L33.9986 49.1436L36.6349 52.9641L35.8168 83.2552L41.8168 87.2576V91.442H36.4531L37.4531 108.634L31.8168 113.637L32.8168 117.458H39.9986L54.0895 135.651L67.3622 128.464L69.8168 119.641L71.3622 118.367L89.1804 116.73L91.0895 118.004L94.1804 127.737C100.18 128.192 108.089 128.828 109.999 128.919C110.999 128.192 113.635 125.736 115.726 123.643H118.271L124.908 130.284L125.453 131.557V137.288L126.908 136.651L128.635 136.742L131.544 138.652L132.362 140.199V142.2L136.908 143.201L138.908 138.471L140.453 137.379L144.089 137.106L145.544 137.743L145.453 137.288L147.18 135.014H148.726V134.741Z" fill="currentColor"/>
  108. </svg>
  109. </div>
  110. <!-- 전북 -->
  111. <div class="mapdt jeonbuk" :class="getEventClass(mapDataInfo[12])">
  112. <svg xmlns="http://www.w3.org/2000/svg" width="9.71025rem" height="6.85644rem" viewBox="0 0 156 110" fill="none">
  113. <path d="M7.63707 94.6983L7.09162 100.793L10.0916 101.43L17.3643 102.157L27.9098 93.4248L28.6371 85.238L29.8189 83.6916L38.3643 80.7808L40.6371 81.7813L41.728 84.6012L46.8189 84.4193L48.6371 85.6019L51.1825 92.97L52.4553 93.1519L57.5462 84.4193L59.6371 83.6006L65.2734 85.5109L66.3643 87.9669L63.6371 93.6977L64.0007 103.977L66.728 105.432L74.8189 101.066L77.4553 102.703V104.977L78.728 104.522L80.6371 104.977L83.0916 107.524L93.6371 108.343L100.728 104.613L101.455 104.431L112.91 103.795L114.273 104.341L119.819 109.98L125.546 95.2441L123.91 91.3326L122.364 85.0561L119.092 81.1446L118.819 79.3253L128.546 56.9481L128.819 56.4933L139.728 44.2131L141.637 43.6673L145.91 45.2137L154.455 37.0269L155.637 28.7492L153.364 22.4726L142.455 23.2003L141.001 22.5636L136.092 17.0148L134.183 18.1063L133.273 18.3792H131.092L129.637 18.7431L131.273 24.6558L128.183 26.2931L123.455 20.5624L121.91 20.6533L119.819 25.7474L117.728 26.8389L110.273 25.2016L108.819 23.4732V21.0172L107.546 20.1985L104.455 21.654L101.91 20.0166V12.1936L97.0916 7.37255C91.9098 12.4666 91.0916 12.4666 90.4553 12.4666C89.6371 12.4666 76.6371 11.4659 72.728 11.1021L71.1825 9.8286L68.1825 0.277344L53.0007 1.64181L50.6371 10.0105L49.728 11.1021L34.4553 19.3799L33.1825 17.1057L18.728 18.1973L13.728 21.1991L14.3643 23.8371H19.5462L23.9098 30.4775L31.0916 33.1154L43.728 29.7498L43.3643 33.1154L32.0007 35.9353V38.3004L38.8189 43.3035L38.1825 47.4878L32.1825 43.6673H26.1825L17.1825 53.8553L6.54616 59.0403V67.0452L23.9098 68.0458L25.728 70.8656L21.9098 73.5036H14.2734L0.273438 84.1464C1.9098 86.4205 4.63707 90.1501 7.18253 93.6067L7.63707 94.6983Z" fill="currentColor"/>
  114. </svg>
  115. </div>
  116. <!-- 전남 -->
  117. <div class="mapdt jeonnam" :class="getEventClass(mapDataInfo[13])">
  118. <svg xmlns="http://www.w3.org/2000/svg" width="10.01138rem" height="9.18738rem" viewBox="0 0 161 148" fill="none">
  119. <path d="M158.547 94.0205L157.365 89.1084L142.547 89.2904L141.092 84.0144L151.638 79.921L152.729 74.7361L153.365 73.7354L160.729 67.7318L158.547 60.1818L151.365 55.1787L150.547 53.7233V48.3564L147.001 47.6287L145.547 45.9913L144.092 30.2545L143.456 29.9816L143.729 29.3449L137.638 23.1593L127.365 23.796L120.092 27.6165L119.092 27.7985L107.365 26.8888L106.183 26.3431L104.092 24.1599L101.456 25.0695L99.0014 23.3412V21.5219L92.7287 24.8876H91.0014L86.456 22.5225L85.456 20.9761L85.1833 9.33272L85.3651 8.42307L87.456 4.14774L85.1833 3.42004L80.1832 11.8797L78.456 12.7893L74.8196 12.4255L73.2741 11.243L70.8196 4.14774L65.7287 4.32968L64.0014 3.2381L63.0014 0.873047L57.1832 2.87425L56.456 10.6062L55.8196 11.8797L44.0923 21.6129L42.7287 21.9768L34.456 21.1581L29.8196 20.2484L28.3651 18.3382L29.0014 11.243C27.1832 8.78694 24.7287 5.42125 23.0014 2.96521L16.6378 16.9737L7.63778 26.9798L23.456 46.3552L19.456 52.7227L14.456 45.7184L11.5469 47.7197L13.0014 52.7227L7.36506 60.2727L9.27415 66.0944L14.0014 64.0932L15.2741 67.186L11.2741 75.4638L12.7287 82.9229L8.00142 89.3813L10.3651 94.2024L27.8196 97.659L27.5469 102.935H23.3651L12.3651 95.7488L11.1832 97.75L14.8196 105.573L13.5469 108.939L10.1832 106.755L7.54688 92.1102L0.546875 91.2915V107.756L4.72869 114.578L12.8196 116.762L19.1832 129.86V135.045L18.9105 147.871H30.5469L33.7287 136.137L44.0923 133.863L48.456 128.951L49.5469 114.578L52.1832 114.396L52.456 135.773L68.2741 132.953L73.0923 126.768L73.3651 117.125L76.6378 111.94L108.638 97.659L113.456 100.661L110.001 111.395L105.82 103.39L100.456 103.663L98.3651 112.668L95.456 116.398L88.1832 115.761L84.9105 126.95L98.6378 124.675L101.82 129.406L103.274 142.323L117.729 130.861L119.456 121.401L122.365 123.402L129.638 121.674L129.365 113.669L120.001 108.302L120.82 93.0199L129.911 88.1078L136.638 93.5656L134.547 114.578L144.183 117.762L142.911 109.848L148.092 106.483L158.911 108.848L159.274 106.392L156.365 103.026L158.547 94.0205ZM88.9105 64.4571L79.5469 69.2782L65.8196 69.915C65.8196 69.915 56.8196 67.7318 55.8196 67.277C54.7287 66.8222 43.0923 67.186 42.8196 67.0041C42.5469 66.8222 38.3651 54.2691 38.3651 54.2691L43.7287 49.539L45.5469 43.1715L54.9105 37.8045L67.6378 38.7142L82.1832 40.2606L87.7287 49.357L93.5469 54.1781L88.9105 64.4571Z" fill="currentColor"/>
  120. </svg>
  121. </div>
  122. <!-- 경북 -->
  123. <div class="mapdt gyeongbuk" :class="getEventClass(mapDataInfo[14])">
  124. <svg xmlns="http://www.w3.org/2000/svg" width="11.35794rem" height="12.03569rem" viewBox="0 0 182 194" fill="none">
  125. <path d="M180.273 136.292L168.546 147.935L160.273 141.204L160.364 137.111L162.819 132.835L163.001 102.908L172.183 84.7151L172.364 81.4404L170.364 75.6187L174.364 54.7878L172.91 17.4015L165.092 0.664062L158.001 1.75563L149.364 11.9436L147.092 12.3985L136.001 6.66771L130.273 9.4876L128.364 9.21472L123.455 5.3942L120.183 5.48517L116.91 9.30567H114.183L108.819 3.21107L104.092 4.30263L104.364 7.66831L102.91 9.57857L97.3644 10.4882L95.9098 10.1244L91.728 6.66771L81.728 9.57857L76.0916 16.9467L74.9098 17.5834L69.5462 18.3111L67.6371 23.3142L69.9098 27.7714L70.0007 29.2269L67.3644 36.2311L64.6371 37.1407L62.1825 35.5034L58.2735 38.5962L55.728 38.4143L47.4553 29.4088L47.1825 30.3184L44.5462 33.6841L42.0916 34.048L36.2734 29.9546L34.0916 31.9558V37.4137L31.0916 38.7781L28.728 36.595L27.728 37.7775L30.0007 41.2341L30.2734 42.5077L29.5462 48.0565L26.5462 49.148L22.2735 45.4185H13.2734L11.1825 47.4197L14.5462 51.9679V54.1511L10.0916 59.518L8.00071 60.0638L1.72799 57.4258L0.273438 59.0631L5.27344 63.2475L5.90981 64.43L7.72799 86.7163L7.54617 87.6259L3.09163 96.0856V98.2688L12.4553 101.362L19.4553 100.27L21.5462 101.998V112.004L20.2734 113.733L14.6371 115.643L12.4553 124.83L12.2734 125.376L7.27345 133.563L5.18254 134.291L2.72799 133.472L4.36435 137.929L4.45526 138.839L3.18254 147.208L11.3644 155.121L20.1825 154.849L21.8189 155.758L23.6371 158.942H26.3644L28.0007 159.943L34.6371 174.042L34.0007 176.316L29.2734 179.409L29.5462 180.591L49.728 187.323L51.5462 186.595L46.9098 178.226L50.9098 171.768L55.1825 171.859L53.1825 165.037L58.2735 158.123L60.4553 157.85L52.0007 153.211L57.1825 139.93L69.728 130.743L79.728 134.2L92.0916 122.01L111.092 122.192L117.455 132.562L117.91 146.025L109.455 150.118L103.001 160.67L98.3643 165.4L104.183 174.952L97.5462 182.684L85.2734 184.321L78.0007 181.592L74.0007 189.506L73.5462 191.234L74.3644 192.599L79.9098 190.689H81.0007L90.1825 193.236L118.91 187.05L124.092 180.137L125.455 179.409L141.91 178.317L143.819 180.137V189.324L149.273 190.416L152.546 185.504L154.91 184.958L165.91 190.598L166.364 188.141L170.364 181.046L182.001 139.294L180.273 136.292Z" fill="currentColor"/>
  126. </svg>
  127. </div>
  128. <!-- 경남 -->
  129. <div class="mapdt gyeongnam" :class="getEventClass(mapDataInfo[15])">
  130. <svg xmlns="http://www.w3.org/2000/svg" width="9.66475rem" height="9.52281rem" viewBox="0 0 156 153" fill="none">
  131. <path d="M100.729 94.8136L102.82 82.5334L124.183 85.1713L133.183 80.6231L144.365 82.1695L146.092 78.5309L152.456 74.4376L155.183 73.6189L150.365 62.6122L143.183 62.3393L139.638 52.6971L146.729 48.1488L148.911 41.4175L123.456 46.8753H122.638L113.547 44.3284L107.183 46.5115L105.001 45.7838L98.3651 34.7771L83.5469 40.8717L82.2742 40.9627L60.456 33.7765L59.1832 32.412L58.456 28.9554L59.1832 27.0451L63.7287 24.1343L58.2741 12.4908H55.6378L54.0923 11.6722L52.2742 8.48842L43.7287 8.76131L42.3651 8.30648L34.2742 0.392578L25.7287 8.57937L23.9105 8.94325L19.7287 7.48781L9.7287 18.5854L0.819605 39.4163L3.63779 42.8729L4.00142 43.6006L5.63779 50.1501L7.45597 54.2435V55.6079L0.546875 73.255L2.00143 88.2641L5.63779 89.0828L7.09234 90.8111V96.7238L14.0014 101.454L14.7287 102.455L17.456 111.824L16.8196 113.734L9.09234 120.102L8.00143 125.378L13.8196 129.107L16.2741 124.195L29.7287 117.373L37.0014 119.647L43.1832 108.913L46.1832 111.369L43.456 119.374L45.5469 128.47L65.9105 130.381L71.0923 125.832L74.0923 127.834L68.456 132.473L72.1832 136.02L77.2742 133.11L78.7287 135.566L71.5469 143.116L72.6378 145.208L76.1833 145.572L78.6378 152.758L85.7287 149.301L83.3651 140.751L87.0014 131.017L83.9105 131.381L83.5469 123.831L90.6378 117.009V114.28L89.1832 109.55L98.2741 106.548L99.7287 113.097L106.547 108.822L100.547 99.0889L100.729 94.8136Z" fill="currentColor"/>
  132. </svg>
  133. </div>
  134. <!-- 제주 -->
  135. <div class="mapdt jeju" :class="getEventClass(mapDataInfo[16])">
  136. <svg xmlns="http://www.w3.org/2000/svg" width="2.84094rem" height="2.03531rem" viewBox="0 0 46 33" fill="none">
  137. <path d="M41.4545 0.435547L22.8182 4.07412L9.36364 11.3513L1.90909 21.5393L0 33.0008H9.81818L13.2727 28.4525L31.2727 20.9935L41.4545 19.629L45.4545 7.53075L41.4545 0.435547Z" fill="currentColor"/>
  138. </svg>
  139. </div>
  140. </div>
  141. <!-- 우측 레이아웃 -->
  142. <div class="map--sub--info">
  143. <div class="titles">
  144. <h2>전국</h2>
  145. </div>
  146. <div class="status--row">
  147. <ul>
  148. <li>
  149. <div>
  150. <i class="icon"></i>
  151. CRITICAL
  152. </div>
  153. <div class="current--data">{{criTotal}}</div>
  154. </li>
  155. <li>
  156. <div>
  157. <i class="icon"></i>
  158. MAJOR
  159. </div>
  160. <div class="current--data">{{majTotal}}</div>
  161. </li>
  162. <li>
  163. <div>
  164. <i class="icon"></i>
  165. MINOR
  166. </div>
  167. <div class="current--data">{{minTotal}}</div>
  168. </li>
  169. </ul>
  170. </div>
  171. <!-- status--row -->
  172. <!-- 우측 하단 -->
  173. <div class="status--list">
  174. <ul>
  175. <li>
  176. <div class="drp--header type1">
  177. <div class="drp--titles">테넌트 수</div>
  178. <div class="drp--current--data">
  179. <span class="current--value">{{tenantCntObj.tenantTotal}}</span>
  180. <v-btn class="custom-btn mini drop--btn" @click="drpType1();" :style="tenantCntObj.tenantTotal==0? 'visibility:hidden;':''"></v-btn>
  181. </div>
  182. </div>
  183. <div class="drp--content type1">
  184. <ul>
  185. <li v-for="(item, idx) in tenantCntObj.areaInfoList" :key="idx">{{item.areaName}}<span>({{item.tenantList.length}})</span></li>
  186. </ul>
  187. </div>
  188. </li>
  189. <li>
  190. <div class="drp--header type2">
  191. <div class="drp--titles">NE 그룹 수</div>
  192. <div class="drp--current--data">
  193. <span class="current--value">{{getNeGroupCntInfo.length}}</span>
  194. <v-btn class="custom-btn mini drop--btn" @click="drpType2();" :style="getNeGroupCntInfo.length==0? 'visibility:hidden;':''"></v-btn>
  195. </div>
  196. </div>
  197. <div class="drp--content type2">
  198. <ul>
  199. <li v-for="(item, idx) in getNeGroupCntInfo" :key="idx" @click="fnClickNeGroup(item)" style="cursor:pointer;"><div class="li--l">{{item.neGroup}}</div><div class="li--r"><span>NE : {{item.neList.length}}</span><i class="alarm" :class="getNeEventCls(item)"></i></div></li>
  200. </ul>
  201. </div>
  202. </li>
  203. <li>
  204. <div class="drp--header type3">
  205. <div class="drp--titles">NE 수</div>
  206. <div class="drp--current--data">
  207. <span class="current--value">{{getNeCntInfo.length}}</span>
  208. <v-btn class="custom-btn mini drop--btn" @click="drpType3();" :style="getNeCntInfo.length==0? 'visibility:hidden;':''"></v-btn>
  209. </div>
  210. </div>
  211. <div class="drp--content type3">
  212. <ul>
  213. <li v-for="(item, idx) in getNeCntInfo" :key="idx" @click="fnClickNe(item)" style="cursor:pointer;"><div class="li--l">{{item.neName}}</div><div class="li--r">{{item.tenantName}}</div></li>
  214. </ul>
  215. </div>
  216. </li>
  217. </ul>
  218. </div>
  219. </div>
  220. </div>
  221. <!-- RAN 카드형 -->
  222. <div class="inner--content" v-if="shapeMap == false" >
  223. <ul class="ran--card">
  224. <!-- ran--all, ran--blue, ran--red -->
  225. <li v-for="(item, idx) in cardRanInfo" :key="idx" :class="item.cls">
  226. <div class="ran--title">
  227. <span class="ran--area">{{item.areaName}}</span>
  228. <v-btn class="more--btn" flat @click="fnClickCardDetail(item, idx)"></v-btn>
  229. </div>
  230. <div class="ran--stat">
  231. <p>
  232. <span>테넌트 수</span><span>{{item.tenantCnt}}</span>
  233. </p>
  234. <p>
  235. <span>NE그룹 수</span><span>{{item.neGroupCnt}}</span>
  236. </p>
  237. <p>
  238. <span>NE 수</span><span>{{item.neCnt}}</span>
  239. </p>
  240. </div>
  241. </li>
  242. </ul>
  243. </div>
  244. <!-- 그룹 수 상세 모달 -->
  245. <RanMapGroupDetailModal v-if="isShowRanMapDetailModal" :neGroupInfo="propsNeGroupInfo" :centerPosition="centerPosition" @closeModal="isShowRanMapDetailModal = false"/>
  246. <!-- NE 수 상세 모달 -->
  247. <RanMapNeDetailModal v-if="isShowRanMapNeDetailModal" :neInfo="propsNeInfo" :centerPosition="centerPosition" @closeModal="isShowRanMapNeDetailModal = false"/>
  248. <!-- 카드형 UI 현황 모달 -->
  249. <RanCardGroupDetailModal v-if="isShowRanCardGroupDetailModal" :propsObj="propsCardObj" :centerPosition="centerPosition" @closeModal="isShowRanCardGroupDetailModal = false"/>
  250. </div>
  251. <!-- 지역 확대 : S -->
  252. <div class="map--contents--wrap map--t" v-if="isDetailMap">
  253. <div class="header--wrapper">
  254. <div class="titles">
  255. <span>RAN</span>
  256. </div>
  257. <div class="control--wrap">
  258. <v-btn class="custom-btn mini map--btn" :class="{ on: shapeMap }" @click="shapeMap = true">
  259. <i class="icon"></i>지도
  260. </v-btn>
  261. <v-btn class="custom-btn mini card--btn" :class="{ on: !shapeMap }" @click="shapeMap = false">
  262. <i class="icon"></i>카드
  263. </v-btn>
  264. </div>
  265. </div>
  266. <div class="inner--content--wrapper" v-if="shapeMap == true">
  267. <div class="map--wrappers">
  268. <!-- 맵 데이터 -->
  269. <div class="map--text">
  270. <div class="map--text--inner" :class="currMapData.cls">
  271. <div class="title">{{currMapData.areaName}} <span>({{ currMapData.neInfoList.length }})</span></div>
  272. <div class="status">
  273. <span class="critical">{{ currMapData.criCnt }}</span>
  274. <span class="major">{{ currMapData.majCnt }}</span>
  275. <span class="minor">{{ currMapData.minCnt }}</span>
  276. </div>
  277. </div>
  278. </div>
  279. <!-- 맵 백터 이미지 -->
  280. <div class="mapdt" :class="[currMapData.cls, getEventClass(currMapData)]">
  281. <component :is="getCurrMapComponent" />
  282. </div>
  283. </div>
  284. <div class="map--sub--info">
  285. <div class="titles">
  286. <h2><i @click="fnAllAreaClick" style="cursor:pointer;">전국</i><span>{{currMapData.areaName}}</span></h2>
  287. <!-- <v-btn class="custom-btn mini more--plus--btn"></v-btn> -->
  288. </div>
  289. <div class="status--row">
  290. <ul>
  291. <li>
  292. <div>
  293. <i class="icon"></i>
  294. CRITICAL
  295. </div>
  296. <div class="current--data">{{currMapData.criCnt}}</div>
  297. </li>
  298. <li>
  299. <div>
  300. <i class="icon"></i>
  301. MAJOR
  302. </div>
  303. <div class="current--data">{{ currMapData.majCnt }}</div>
  304. </li>
  305. <li>
  306. <div>
  307. <i class="icon"></i>
  308. MINOR
  309. </div>
  310. <div class="current--data">{{ currMapData.minCnt }}</div>
  311. </li>
  312. </ul>
  313. </div><!-- status--row -->
  314. <!-- 우측 하단 -->
  315. <div class="status--list">
  316. <ul>
  317. <li>
  318. <div class="drp--header type1">
  319. <div class="drp--titles">테넌트 수</div>
  320. <div class="drp--current--data">
  321. <span class="current--value">{{tenantCntObjCopy.tenantTotal}}</span>
  322. <!-- 상세 지역의 테넌트 수 드랍버튼 미노출 -->
  323. <v-btn class="custom-btn mini drop--btn" style="background:none; pointer-events:none;"></v-btn>
  324. </div>
  325. </div>
  326. <div class="drp--content type1">
  327. <ul>
  328. <li v-for="(item, idx) in tenantCntObjCopy.areaInfoList" :key="idx">{{item.areaName}}<span>({{item.tenantList.length}})</span></li>
  329. </ul>
  330. </div>
  331. </li>
  332. <li>
  333. <div class="drp--header type2">
  334. <div class="drp--titles">NE 그룹 수</div>
  335. <div class="drp--current--data">
  336. <span class="current--value">{{getAreaNeGroupCntInfo.length}}</span>
  337. <v-btn class="custom-btn mini drop--btn" @click="drpType2();" :style="getAreaNeGroupCntInfo.length == 0 ? 'visibility:hidden;':''"></v-btn>
  338. </div>
  339. </div>
  340. <div class="drp--content type2">
  341. <ul>
  342. <li v-for="(item, idx) in getAreaNeGroupCntInfo" :key="idx" @click="fnClickNeGroup(item)" style="cursor:pointer;"><div class="li--l">{{item.neGroup}}</div><div class="li--r"><span>NE : {{item.neList.length}}</span><i class="alarm" :class="getNeEventCls(item)"></i></div></li>
  343. </ul>
  344. </div>
  345. </li>
  346. <li>
  347. <div class="drp--header type3">
  348. <div class="drp--titles">NE 수</div>
  349. <div class="drp--current--data">
  350. <span class="current--value">{{getAreaNeCntInfo.length}}</span>
  351. <v-btn class="custom-btn mini drop--btn" @click="drpType3();" :style="getAreaNeCntInfo.length == 0 ? 'visibility:hidden;':''"></v-btn>
  352. </div>
  353. </div>
  354. <div class="drp--content type3">
  355. <ul>
  356. <li v-for="(item, idx) in getAreaNeCntInfo" :key="idx" @click="fnClickNe(item)" style="cursor:pointer;"><div class="li--l">{{item.neName}}</div><div class="li--r">{{item.tenantName}}</div></li>
  357. </ul>
  358. </div>
  359. </li>
  360. </ul>
  361. </div>
  362. </div>
  363. </div>
  364. <!-- RAN 카드형 -->
  365. <div class="inner--content" v-if="shapeMap == false" >
  366. <ul class="ran--card">
  367. <!-- ran--all, ran--blue, ran--red -->
  368. <li v-for="(item, idx) in cardRanInfo" :key="idx" :class="item.cls">
  369. <div class="ran--title">
  370. <span class="ran--area">{{item.areaName}}</span>
  371. <v-btn class="more--btn" flat @click="fnClickCardDetail(item, idx)"></v-btn>
  372. </div>
  373. <div class="ran--stat">
  374. <p>
  375. <span>테넌트 수</span><span>{{item.tenantCnt}}</span>
  376. </p>
  377. <p>
  378. <span>NE그룹 수</span><span>{{item.neGroupCnt}}</span>
  379. </p>
  380. <p>
  381. <span>NE 수</span><span>{{item.neCnt}}</span>
  382. </p>
  383. </div>
  384. </li>
  385. </ul>
  386. </div>
  387. </div>
  388. </div>
  389. </template>
  390. <script setup>
  391. /***********************
  392. * import
  393. ************************/
  394. import { useI18n } from "vue-i18n"
  395. import apiUrl from '@/composables/useApi';
  396. import useAxios from '@/composables/useAxios';
  397. import useUtil from '@/composables/useUtil';
  398. import RanMapGroupDetailModal from '@/components/home/dashboard/common/ranMapGroupDetailModal.vue';
  399. import RanMapNeDetailModal from '@/components/home/dashboard/common/ranMapNeDetailModal.vue';
  400. import RanCardGroupDetailModal from '@/components/home/dashboard/common/ranCardGroupDetailModal.vue';
  401. import mapSeoul from "@/components/home/dashboard/common/map/mapSeoul.vue";
  402. import mapBusan from "@/components/home/dashboard/common/map/mapBusan.vue";
  403. import mapDaegu from "@/components/home/dashboard/common/map/mapDaegu.vue";
  404. import mapIncheon from "@/components/home/dashboard/common/map/mapIncheon.vue";
  405. import mapGwangju from "@/components/home/dashboard/common/map/mapGwangju.vue";
  406. import mapDaejeon from "@/components/home/dashboard/common/map/mapDaejeon.vue";
  407. import mapUlsan from "@/components/home/dashboard/common/map/mapUlsan.vue";
  408. import mapSejong from "@/components/home/dashboard/common/map/mapSejong.vue";
  409. import mapGyeonggido from "@/components/home/dashboard/common/map/mapGyeonggido.vue";
  410. import mapKangWon from "@/components/home/dashboard/common/map/mapKangwon.vue";
  411. import mapChungbuk from "@/components/home/dashboard/common/map/mapChungbuk.vue";
  412. import mapChungnam from "@/components/home/dashboard/common/map/mapChungnam.vue";
  413. import mapJeonbuk from "@/components/home/dashboard/common/map/mapJeonbuk.vue";
  414. import mapJeonnam from "@/components/home/dashboard/common/map/mapJeonnam.vue";
  415. import mapGyeongbuk from "@/components/home/dashboard/common/map/mapGyeongbuk.vue";
  416. import mapGyeongnam from "@/components/home/dashboard/common/map/mapGyeongnam.vue";
  417. import mapJeju from "@/components/home/dashboard/common/map/mapJeju.vue";
  418. /***********************
  419. * plugins inject
  420. ************************/
  421. const { $toast, $log, $dayjs, $eventBus } = useNuxtApp()
  422. // props
  423. const props = defineProps({})
  424. // 참조가능 데이터 설정
  425. defineExpose({})
  426. // 발신 이벤트 선언
  427. const emit = defineEmits([""]);
  428. const i18n = useI18n();
  429. /***********************
  430. * data & created
  431. ************************/
  432. const isShowRanMapDetailModal = ref(false)
  433. const isShowRanMapNeDetailModal = ref(false)
  434. const isShowRanCardGroupDetailModal = ref(false)
  435. // 카카오맵 센터좌표
  436. const centerPosition = ref({
  437. lat: 33.450701,
  438. lng: 126.570667
  439. })
  440. const ranInterval = ref(null)
  441. const shapeMap = ref(true) // 지도형, 카드형
  442. const drpType1 = () => toggleActive('type1')
  443. const drpType2 = () => toggleActive('type2')
  444. const drpType3 = () => toggleActive('type3')
  445. const sidoCode = ref([]) // 시도 코드 데이터 (title배열 형태인 이유: 지도는 인덱스1, 테넌트 수: 인덱스0 사용)
  446. const mapDataInfo = ref([]) // 지도 데이터
  447. const criTotal = ref(0) // 전국 CRITICAL TOTAL
  448. const majTotal = ref(0) // 전국 MAJOR TOTAL
  449. const minTotal = ref(0) // 전국 MINOR TOTAL
  450. // 전국 테넌트 수 데이터
  451. const tenantCntObj = ref({
  452. tenantTotal: 0,
  453. areaInfoList: []
  454. })
  455. // 지역 > 테넌트 수 데이터
  456. const tenantCntObjCopy = ref({
  457. tenantTotal: 0,
  458. areaInfoList: []
  459. })
  460. const cardRanInfo = ref([]) // 카드형 데이터
  461. const propsNeGroupInfo = ref({}) // NE그룹상세팝업 정보
  462. const propsNeInfo = ref({}) // NE상세팝업 정보
  463. const propsCardObj = ref({}) // 카드형 상세팝업 정보
  464. const myDatas = ref([]) // 전국 > 테넌트|그룹|NE 객체배열 merge
  465. const areaNewData = ref([]) // 지역 > 테넌트|그룹|NE 객체배열
  466. const currMapData = ref({}) // 현재 상세 지역 데이터
  467. const isDetailMap = ref(false) // 상세 지역 노출여부
  468. // 현재 상세 지역 컴포넌트 조회
  469. const getCurrMapComponent = computed(() => {
  470. let areaCode = currMapData.value.areaCode
  471. if(areaCode == 11) return mapSeoul
  472. else if(areaCode == 21) return mapBusan
  473. else if(areaCode == 22) return mapDaegu
  474. else if(areaCode == 23) return mapIncheon
  475. else if(areaCode == 24) return mapGwangju
  476. else if(areaCode == 25) return mapDaejeon
  477. else if(areaCode == 26) return mapUlsan
  478. else if(areaCode == 29) return mapSejong
  479. else if(areaCode == 31) return mapGyeonggido
  480. else if(areaCode == 32) return mapKangWon
  481. else if(areaCode == 33) return mapChungbuk
  482. else if(areaCode == 34) return mapChungnam
  483. else if(areaCode == 35) return mapJeonbuk
  484. else if(areaCode == 36) return mapJeonnam
  485. else if(areaCode == 37) return mapGyeongbuk
  486. else if(areaCode == 38) return mapGyeongnam
  487. else if(areaCode == 39) return mapJeju
  488. })
  489. // 전국 > NE 그룹 수 데이터
  490. const getNeGroupCntInfo = computed(() => {
  491. let result = []
  492. myDatas.value.forEach((item) => {
  493. item.neGroupList.forEach((item2) => {
  494. result.push(item2)
  495. })
  496. })
  497. return result
  498. })
  499. // 지역 상세 > NE 그룹 수 데이터
  500. const getAreaNeGroupCntInfo = computed(() => {
  501. let result = []
  502. areaNewData.value.forEach((item) => {
  503. item.neGroupList.forEach((item2) => {
  504. result.push(item2)
  505. })
  506. })
  507. return result
  508. })
  509. // NE 그룹 수 > 이벤트 단계 클래스
  510. const getNeEventCls = computed(() => {
  511. return (obj) => {
  512. let eventCls = ''
  513. if(!_isEmpty(obj)) {
  514. if(obj.minCnt > 0) eventCls = 'green'
  515. if(obj.majCnt > 0) eventCls = 'blue'
  516. if(obj.criCnt > 0) eventCls = 'red'
  517. }
  518. return eventCls
  519. }
  520. })
  521. // 전국 NE 수 데이터 배열
  522. const getNeCntInfo = computed(() => {
  523. let result = []
  524. myDatas.value.forEach((tenant) => {
  525. tenant.neGroupList.forEach((group) => {
  526. group.neList.forEach((ne) => {
  527. result.push(ne)
  528. })
  529. })
  530. })
  531. return result
  532. })
  533. // 지역 NE 수 데이터
  534. const getAreaNeCntInfo = computed(() => {
  535. let result = []
  536. areaNewData.value.forEach((tenant) => {
  537. tenant.neGroupList.forEach((group) => {
  538. group.neList.forEach((ne) => {
  539. result.push(ne)
  540. })
  541. })
  542. })
  543. return result
  544. })
  545. // 지도 > 이벤트 상태에 따른 테두리 컬러 클래스 조회
  546. const getEventClass = computed(() => {
  547. return (obj) => {
  548. let eventCls = ''
  549. if(!_isEmpty(obj)) {
  550. if(obj.minCnt > 0) eventCls = 'minor'
  551. if(obj.majCnt > 0) eventCls = 'major'
  552. if(obj.criCnt > 0) eventCls = 'critical'
  553. }
  554. return eventCls
  555. }
  556. })
  557. // 카드형 > 테두리 이벤트 스타일
  558. const getCardEventClass = computed(() => {
  559. return (obj) => {
  560. let eventCls = ''
  561. if(!_isEmpty(obj)) {
  562. if(obj.minCnt > 0) eventCls = ''
  563. if(obj.majCnt > 0) eventCls = ''
  564. if(obj.criCnt > 0) eventCls = 'ran--red'
  565. }
  566. return eventCls
  567. }
  568. })
  569. onMounted(() => {
  570. fnGeoTenantNeInfo()
  571. // fnGeoTenantInfo()
  572. ranInterval.value = setInterval(() => {
  573. fnGeoTenantNeInfo()
  574. }, 1000 * 60 * 5)
  575. })
  576. onUnmounted(() => {
  577. clearInterval(ranInterval.value)
  578. ranInterval.value = null
  579. })
  580. watchEffect(() =>{
  581. fnGetEnumCode(useLangStore().getLang)
  582. })
  583. /**
  584. * ENUM 업데이트
  585. * @param lang
  586. */
  587. function fnGetEnumCode(lang){
  588. let objEnum = useEnumCode.getEnumCode(lang)
  589. // ...objEnum.sidoCode
  590. sidoCode.value = _cloneDeep(objEnum.sidoCode.slice(1))
  591. fnSetInitMapData()
  592. }
  593. /***********************
  594. * Methods
  595. ************************/
  596. // 초기 데이터 세팅
  597. function fnSetInitMapData(){
  598. let tempMapData = []
  599. let tempTenantData = []
  600. let tempCardRanData = [{areaName: '전국현황', areaCode: 0, cls: 'ran--all', criCnt: 0, majCnt: 0, minCnt: 0, tenantCnt: 0, neGroupCnt: 0, neCnt: 0, tenantList:[], neGroupList: []}]
  601. sidoCode.value.forEach((item) => {
  602. let mapDataObj = {}
  603. mapDataObj.areaName = item.title[1]
  604. mapDataObj.cls = item.cls
  605. mapDataObj.areaCode = item.value
  606. mapDataObj.criCnt = 0
  607. mapDataObj.majCnt = 0
  608. mapDataObj.minCnt = 0
  609. mapDataObj.total = 0
  610. mapDataObj.tenantList = []
  611. mapDataObj.neGroupList = []
  612. mapDataObj.neInfoList = []
  613. tempMapData.push(mapDataObj)
  614. let tempTenantObj = {}
  615. tempTenantObj.areaName = item.title[0]
  616. tempTenantObj.areaCode = item.value
  617. tempTenantObj.tenantList = []
  618. tempTenantData.push(tempTenantObj)
  619. let cardRanObj = {}
  620. cardRanObj.areaName = item.title[0]
  621. cardRanObj.areaCode = item.value
  622. cardRanObj.cls = ''
  623. cardRanObj.criCnt = 0
  624. cardRanObj.majCnt = 0
  625. cardRanObj.minCnt = 0
  626. cardRanObj.tenantCnt = 0
  627. cardRanObj.neGroupCnt = 0
  628. cardRanObj.neCnt = 0
  629. cardRanObj.tenantList = []
  630. cardRanObj.neGroupList = []
  631. tempCardRanData.push(cardRanObj)
  632. })
  633. mapDataInfo.value = _cloneDeep(tempMapData)
  634. tenantCntObj.value.areaInfoList = _cloneDeep(tempTenantData)
  635. tenantCntObjCopy.value.areaInfoList = _cloneDeep(tempTenantData)
  636. cardRanInfo.value = _cloneDeep(tempCardRanData)
  637. }
  638. const getCardAllRan = computed(() => {
  639. let result = {
  640. areaName: '전국현황', areaCode: 0, cls: 'ran--all', criCnt: 0, majCnt: 0, minCnt: 0, tenantCnt: 0, neGroupCnt: 0, neCnt: 0, tenantList:[], neGroupList: []
  641. }
  642. cardRanInfo.value.forEach((item, idx) => {
  643. if(idx !== 0) {
  644. result.criCnt += item.criCnt
  645. result.majCnt += item.majCnt
  646. result.minCnt += item.minCnt
  647. result.tenantCnt += item.tenantCnt
  648. result.neGroupCnt += item.neGroupCnt
  649. result.neCnt += item.neCnt
  650. result.tenantList.push(...item.tenantList)
  651. result.neGroupList.push(...item.neGroupList)
  652. }
  653. })
  654. return result
  655. })
  656. /**
  657. * 토글
  658. */
  659. function toggleActive(type) {
  660. const allElements = document.querySelectorAll('.type1, .type2, .type3')
  661. const selectedElements = document.querySelectorAll(`.${type}`)
  662. const isActive = Array.from(selectedElements).some(element => element.classList.contains('active'))
  663. allElements.forEach(element => {
  664. element.classList.remove('active')
  665. })
  666. if(!isActive){
  667. selectedElements.forEach(element => {
  668. element.classList.add('active')
  669. })
  670. }
  671. }
  672. /**
  673. * P5G RAN
  674. */
  675. function fnGeoTenantNeInfo() {
  676. let _req = {
  677. tenantName: useAuthStore().getTenantName//useAuthStore().getTenantName
  678. }
  679. useAxios().post(useApi.tenantNeInfo, _req).then((res) => {
  680. $log.debug("[dashboard][fnGeoTenantNeInfo][success]")
  681. let datas = res.data.data.items
  682. fnMakeNeData(datas)
  683. // 상세 지역 데이터 갱신
  684. fnUpdateDetailArea()
  685. }).catch((error)=>{
  686. $log.debug("[dashboard][fnGeoTenantNeInfo][error]")
  687. useErrorHandler().fnSetCommErrorHandle(error, fnGeoTenantNeInfo)
  688. }).finally(()=>{
  689. $log.debug("[dashboard][fnGeoTenantNeInfo][finished]")
  690. })
  691. }
  692. /**
  693. * 지도 데이터 및 모든 데이터 가공
  694. */
  695. function fnMakeNeData(arr){
  696. // 데이터 초기화
  697. fnSetInitMapData()
  698. let initCriTotal = 0 // 전국 CRIICAL 개수
  699. let initMajTotal = 0 // 전국 MAJOR 개수
  700. let initMinTotal = 0 // 전국 MINOR 개수
  701. let tenantTotal = 0
  702. arr.forEach((item, idx) => {
  703. initCriTotal+=item.criCnt
  704. initMajTotal+=item.majCnt
  705. initMinTotal+=item.minCnt
  706. // 각 NE 데이터의 지역코드에 맞는 배열에 넣기
  707. let findIndex = mapDataInfo.value.findIndex((obj => obj.areaCode === item.areaCode))
  708. if(findIndex !== -1) {
  709. mapDataInfo.value[findIndex].neInfoList.push(item)
  710. mapDataInfo.value[findIndex].criCnt += item.criCnt
  711. mapDataInfo.value[findIndex].majCnt += item.majCnt
  712. mapDataInfo.value[findIndex].minCnt += item.minCnt
  713. if(!mapDataInfo.value[findIndex].tenantList.includes(item.tenantName)){
  714. mapDataInfo.value[findIndex].tenantList.push(item.tenantName)
  715. }
  716. if(!mapDataInfo.value[findIndex].neGroupList.includes(item.neGroup)){
  717. mapDataInfo.value[findIndex].neGroupList.push(item.neGroup)
  718. }
  719. if(!tenantCntObj.value.areaInfoList[findIndex].tenantList.includes(item.tenantName)) {
  720. tenantCntObj.value.areaInfoList[findIndex].tenantList.push(item.tenantName)
  721. tenantTotal++
  722. }
  723. }
  724. // 카드형 데이터 세팅
  725. let cardFindIndex = cardRanInfo.value.findIndex((obj => obj.areaCode === item.areaCode))
  726. if(cardFindIndex !== -1) {
  727. // 테넌트 리스트 세팅
  728. cardRanInfo.value[cardFindIndex].minCnt += item.minCnt
  729. cardRanInfo.value[cardFindIndex].majCnt += item.majCnt
  730. cardRanInfo.value[cardFindIndex].criCnt += item.criCnt
  731. if(!cardRanInfo.value[cardFindIndex].tenantList.includes(item.tenantName)) {
  732. cardRanInfo.value[cardFindIndex].tenantList.push(item.tenantName)
  733. cardRanInfo.value[cardFindIndex].tenantCnt++
  734. }
  735. // 그룹 및 NE 세팅
  736. if(!_isEmpty(_find(cardRanInfo.value[cardFindIndex].neGroupList, {neGroup: item.neGroup}))) {
  737. let groupFindIndex = cardRanInfo.value[cardFindIndex].neGroupList.findIndex((obj => obj.neGroup === item.neGroup))
  738. cardRanInfo.value[cardFindIndex].neGroupList[groupFindIndex].minCnt += item.minCnt
  739. cardRanInfo.value[cardFindIndex].neGroupList[groupFindIndex].majCnt += item.majCnt
  740. cardRanInfo.value[cardFindIndex].neGroupList[groupFindIndex].criCnt += item.criCnt
  741. cardRanInfo.value[cardFindIndex].neGroupList[groupFindIndex].neCnt++
  742. cardRanInfo.value[cardFindIndex].neGroupList[groupFindIndex].tenantName = item.tenantName
  743. cardRanInfo.value[cardFindIndex].neGroupList[groupFindIndex].neList.push(item)
  744. cardRanInfo.value[cardFindIndex].neCnt++
  745. }else{
  746. cardRanInfo.value[cardFindIndex].neGroupList.push({neGroup: item.neGroup, tenantName: item.tenantName, neCnt: 1, minCnt: item.minCnt, majCnt: item.majCnt, criCnt: item.criCnt, neList: [item]})
  747. cardRanInfo.value[cardFindIndex].neGroupCnt++
  748. cardRanInfo.value[cardFindIndex].neCnt++
  749. }
  750. }
  751. })
  752. // 카드형 데이터 > 전국현황 데이터 세팅
  753. cardRanInfo.value[0] = _cloneDeep(getCardAllRan.value)
  754. // 전국 > 이벤트 수
  755. criTotal.value = initCriTotal
  756. majTotal.value = initMajTotal
  757. minTotal.value = initMinTotal
  758. // 전국 > 테넌트 수 TOTAL
  759. tenantCntObj.value.tenantTotal = tenantTotal
  760. // 전국 기준 테넌트-그룹-NE 정보 merge
  761. myDatas.value = _cloneDeep(fnSetTenantGroupNeData(arr))
  762. }
  763. /**
  764. * ran tenant
  765. */
  766. function fnGeoTenantInfo() {
  767. useAxios().post(useApi.geoTenantInfoList).then((res) => {
  768. $log.debug("[dashboard][fnGeoTenantInfo][success]")
  769. let datas = res.data.data.items
  770. }).catch((error)=>{
  771. $log.debug("[dashboard][fnGeoTenantInfo][error]")
  772. useErrorHandler().fnSetCommErrorHandle(error, fnGeoTenantInfo)
  773. }).finally(()=>{
  774. $log.debug("[dashboard][fnGeoTenantInfo][finished]")
  775. })
  776. }
  777. /**
  778. * 지도형 UI ne그룹 클릭
  779. */
  780. function fnClickNeGroup(item) {
  781. propsNeGroupInfo.value = item
  782. isShowRanMapDetailModal.value = true
  783. }
  784. /**
  785. * 지도형 UI NE 클릭
  786. */
  787. function fnClickNe(item) {
  788. propsNeInfo.value = item
  789. isShowRanMapNeDetailModal.value = true
  790. }
  791. /**
  792. * 카드형 UI 상세보기 클릭
  793. */
  794. function fnClickCardDetail(item, cardIndex) {
  795. propsCardObj.value = item
  796. isShowRanCardGroupDetailModal.value = true
  797. }
  798. const currMapIndex = ref(null) // 현재 조회 상세 지역 인덱스
  799. /**
  800. * 지역 클릭
  801. */
  802. function fnDetailArea(mapObj, mapIndex){
  803. currMapIndex.value = mapIndex
  804. // 상세 지역 데이터 설정
  805. currMapData.value = mapObj
  806. fnSetAreaNewData()
  807. isDetailMap.value = true
  808. }
  809. /**
  810. * 상세 지역 조회 상태인 경우
  811. * 전국 NE 데이터 갱신 > 상세 지역 NE 데이터 갱신
  812. */
  813. function fnUpdateDetailArea(){
  814. if(isDetailMap.value) {
  815. if(!useUtil.isNull(currMapIndex.value)) {
  816. currMapData.value = mapDataInfo.value[currMapIndex.value]
  817. fnSetAreaNewData()
  818. }
  819. }
  820. }
  821. /**
  822. * 지역 클릭 상태 - 전국 클릭 > 전국으로 돌아가기
  823. */
  824. function fnAllAreaClick(){
  825. isDetailMap.value = false
  826. currMapIndex.value = null
  827. fnGeoTenantNeInfo()
  828. }
  829. /**
  830. * 지역 클릭 > 지역 데이터 세팅
  831. */
  832. function fnSetAreaNewData(){
  833. let arr = currMapData.value.neInfoList
  834. let tenantTotal = 0
  835. arr.forEach((item, idx) => {
  836. // 각 NE 데이터의 지역코드에 맞는 배열에 넣기
  837. let findIndex = mapDataInfo.value.findIndex((obj => obj.areaCode === item.areaCode))
  838. if(findIndex !== -1) {
  839. if(!tenantCntObjCopy.value.areaInfoList[findIndex].tenantList.includes(item.tenantName)) {
  840. tenantCntObjCopy.value.areaInfoList[findIndex].tenantList.push(item.tenantName)
  841. tenantTotal++
  842. }
  843. }
  844. })
  845. tenantCntObjCopy.value.tenantTotal = tenantTotal
  846. areaNewData.value = _cloneDeep(fnSetTenantGroupNeData(arr))
  847. }
  848. /**
  849. * 테넌트 - 그룹 - NE 데이터 세팅 로직
  850. */
  851. function fnSetTenantGroupNeData(arr){
  852. let result = {}
  853. arr.forEach(item => {
  854. const { tenantName, neGroup } = item
  855. // tenantName이 없으면 초기화
  856. if (!result[tenantName]) {
  857. result[tenantName] = {
  858. tenantName,
  859. neGroupList: {}
  860. }
  861. }
  862. // neGroup이 없으면 초기화
  863. if (!result[tenantName].neGroupList[neGroup]) {
  864. result[tenantName].neGroupList[neGroup] = {
  865. tenantName,
  866. neGroup,
  867. minCnt: 0,
  868. majCnt: 0,
  869. criCnt: 0,
  870. neList: []
  871. }
  872. }
  873. // 카운트 합산
  874. result[tenantName].neGroupList[neGroup].minCnt += item.minCnt
  875. result[tenantName].neGroupList[neGroup].majCnt += item.majCnt
  876. result[tenantName].neGroupList[neGroup].criCnt += item.criCnt
  877. // neList에 NE 데이터 추가
  878. result[tenantName].neGroupList[neGroup].neList.push({
  879. tenantName: item.tenantName,
  880. neGroup: item.neGroup,
  881. neName: item.neName,
  882. neId: item.neId,
  883. neType: item.neType,
  884. upfNum: item.upfNum,
  885. customerType: item.customerType,
  886. neAddress: item.neAddress,
  887. lastUpdateTime: item.lastUpdateTime,
  888. neLocLatitude: item.neLocLatitude,
  889. neLocLongitude: item.neLocLongitude,
  890. familyName: item.familyName,
  891. initTime: item.initTime,
  892. minCnt: item.minCnt,
  893. majCnt: item.majCnt,
  894. criCnt: item.criCnt,
  895. kpi: item.kpi,
  896. cpu: item.cpu,
  897. mem: item.mem,
  898. })
  899. })
  900. // 최종 결과 배열로 변환
  901. return Object.values(result).map(tenant => ({
  902. tenantName: tenant.tenantName,
  903. neGroupList: Object.values(tenant.neGroupList)
  904. }))
  905. }
  906. </script>