DESKTOP-T61HUSC\user 5 ヶ月 前
コミット
59982c14a1

+ 1 - 1
.env

@@ -1,6 +1,6 @@
 #import.meta.env로 호출 가능
 VITE_APP_BASE_URL="/"
-VITE_APP_API_URL="https://eventinter.mycafe24.com"
+VITE_APP_API_URL="https://shopdeli.mycafe24.com"
 VITE_APP_API_PORT=8080
 VITE_APP_DEBUG_LEVEL=trace
 VITE_APP_MODE=prod

+ 1 - 1
.env.development

@@ -1,6 +1,6 @@
 #import.meta.env로 호출 가능
 VITE_APP_BASE_URL="/"
-VITE_APP_API_URL="https://eventinter.mycafe24.com"
+VITE_APP_API_URL="https://shopdeli.mycafe24.com"
 VITE_APP_API_PORT=8080
 VITE_APP_DEBUG_LEVEL=trace
 VITE_APP_MODE=development

+ 14 - 8
components/common/header.vue

@@ -2,7 +2,7 @@
   <header class="new--header">
     <h1 class="logo">
       <!-- prettier-ignore  -->
-      {{userCompanyName}} 룰렛 시스템 관리자
+      SHOPDELI
     </h1>
     <nav class="gnb">
       <ul class="depth1">
@@ -61,27 +61,33 @@
       {
         menuId: "menu01",
         parentMenuId: "menu01",
-        menuName: "관리자 관리",
-        linkType: "/view/mng",
+        menuName: "제품 관리",
+        linkType: "/view/item",
       },
       {
         menuId: "menu02",
         parentMenuId: "menu02",
-        menuName: "이벤트 관리",
-        linkType: "/view/event/evtList",
+        menuName: "배송 관리",
+        linkType: "/view/deli",
       },
       {
         menuId: "menu03",
         parentMenuId: "menu03",
-        menuName: "당첨자 관리",
+        menuName: "벤더 관리",
         linkType: "/view/winner",
       },
       {
         menuId: "menu04",
         parentMenuId: "menu04",
-        menuName: "룰렛 타입 관리",
+        menuName: "정산 관리",
         linkType: "/",
-      }
+      },
+      {
+        menuId: "menu05",
+        parentMenuId: "menu05",
+        menuName: "고객센터",
+        linkType: "/",
+    }
     );
 
     arrMenuInfo.value = info;

+ 0 - 94
gitignore

@@ -1,94 +0,0 @@
-# Created by .ignore support plugin (hsz.mobi)
-### Node template
-# Logs
-/logs
-*.log
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-
-# Runtime data
-pids
-*.pid
-*.seed
-*.pid.lock
-
-
-# Directory for instrumented libs generated by jscoverage/JSCover
-lib-cov
-
-# Coverage directory used by tools like istanbul
-coverage
-
-# nyc test coverage
-.nyc_output
-
-# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
-.grunt
-
-# Bower dependency directory (https://bower.io/)
-bower_components
-
-# node-waf configuration
-.lock-wscript
-
-# Compiled binary addons (https://nodejs.org/api/addons.html)
-build/Release
-
-# Dependency directories
-node_modules/
-jspm_packages/
-
-# TypeScript v1 declaration files
-typings/
-
-# Optional npm cache directory
-.npm
-
-# Optional eslint cache
-.eslintcache
-
-# Optional REPL history
-.node_repl_history
-
-# Output of 'npm pack'
-*.tgz
-
-# Yarn Integrity file
-.yarn-integrity
-
-# dotenv environment variables file
-.env
-
-# parcel-bundler cache (https://parceljs.org/)
-.cache
-
-# next.js build output
-.next
-
-# nuxt.js build output
-.nuxt
-
-# Nuxt generate
-dist
-
-# vuepress build output
-.vuepress/dist
-
-# Serverless directories
-.serverless
-
-# IDE / Editor
-.idea
-
-# Service worker
-sw.*
-
-# macOS
-.DS_Store
-
-# Vim swap files
-*.swp
-projectList.vue
-
-*.css

+ 0 - 29
layouts/designdb.vue

@@ -1,29 +0,0 @@
-<template>
-  <v-app class="mode-wrap" :class="[isDarkmode ? 'darkmode' : '']">
-    <div class="container">
-      <dBheader></dBheader>
-      <div class="content footer--none">
-        <NuxtPage />
-      </div>
-      <!-- <footerLayout></footerLayout> -->
-    </div>
-  </v-app>
-</template>
-
-<script setup>
-  import dBheader from '../components/design/dBheader'
-  // import footerLayout from '../components/design/footer'
-  let isDarkmode = ref(false)
-
-  const mode = (e) => {
-    isDarkmode = !(e.value);
-    if(isDarkmode){
-      document.querySelector(".mode-wrap").classList.add("darkmode");
-    }else{
-      document.querySelector(".mode-wrap").classList.remove("darkmode");
-    }
-  }
-</script>
-
-<style lang="scss" scoped>
-</style>

+ 0 - 2
layouts/designdefault.vue

@@ -11,8 +11,6 @@
 </template>
 
 <script setup>
-  import headerLayout from '../components/design/header'
-  import footerLayout from '../components/design/footer'
   let isDarkmode = ref(false)
 
   const mode = (e) => {

+ 0 - 700
pages/roulette/index.vue

@@ -1,700 +0,0 @@
-<template>
-  <div class="roulette--container--wrappers">
-    <div class="roulette--wrapper">
-      <div class="title">
-        <div>미리 포인트로 즐기는 행운의 찬스!</div>
-        <div class="main-title"><span>룰렛</span><span>을 돌려라!</span></div>
-      </div>
-
-      <div class="roulette-container-wrap">
-        <div class="roulette-container">
-          <div class="pointer"></div>
-          <div ref="wheelRef" class="wheel"></div>
-          <div ref="textLayerRef" class="text-layer"></div>
-
-          <button
-            id="agreeButton"
-            type="button"
-            class="center-button"
-            @click="activeLayer(1)"
-          ></button>
-
-          <!-- <button
-            id="spinButton"
-            type="button"
-            class="center-button"
-            @click="trySpinRoulette"
-          ></button> -->
-        </div>
-      </div>
-      <div class="bottom-text">100% 당첨! 룰렛 돌리기</div>
-      <div class="sub-text">미리톡에서 추후 시 500P 사용하면 보너 2개!</div>
-
-      <div class="buttons">
-        <button type="button" class="button secondary">응모권 확인하기</button>
-        <button type="button" class="button primary">나의 포인트 전환</button>
-      </div>
-
-      <div class="probability-display">
-        <div>당첨 확률: <span id="probabilityDisplay">0.2</span>%</div>
-      </div>
-    </div>
-
-    <!-- 레이어 입력 폼 -->
-    <div
-      id="randomBoxAuth-layer01"
-      class="layer-popup bottom-sheet-wrap event"
-      role="dialog"
-      aria-hidden="false"
-      tabindex="0"
-      style="z-index: 101"
-      :class="{ show: activeLayer1 }"
-    >
-      <div class="layer-popup-item evt-reservation jan-roulette-pop">
-        <div class="popup-header">
-          <strong class="txt-main">룰렛 이벤트 신청</strong>
-        </div>
-        <div class="popup-body">
-          <div class="page-desc">
-            <h2>
-              이벤트 신청을 위해서 본인 인증이 필요합니다.<br />본인 인증을 진행해 주세요.
-            </h2>
-            <!--                <p>이벤트 기간 내 가입한 010 신규가입자도 룰렛 이벤트에 참여 가능합니다.</p>-->
-          </div>
-          <!--            <div class="box-btn">-->
-          <!--                <button class="btns md-ripples ripples-light gtm-tracking" type="button" data-gtm-tracking-category="랜덤박스 팝업_PC" data-gtm-tracking-action="본인인증 시도_PC" data-gtm-tracking-label="인증하기 버튼" id="randomBoxAuthBtn">본인 인증 하기</button>-->
-          <!--                <button id="randomBoxChkBtn" class="btns md-ripples ripples-light" type="button" disabled="" style="display: none;">인증 완료</button>-->
-          <!--            </div>-->
-          <div class="phone-certification mt45">
-            <h2>신청자 정보</h2>
-            <div class="box-input mt--45">
-              <label for="userName" class="input-label">이름</label>
-              <div class="input-wrap">
-                <input
-                  id="userName"
-                  type="text"
-                  placeholder="이름을 입력해주세요."
-                  class="input-default is-delete"
-                />
-              </div>
-            </div>
-            <div class="box-input mt45">
-              <label for="userPhone" class="input-label">휴대폰 번호</label>
-              <div class="input-wrap">
-                <input
-                  id="userPhone"
-                  type="text"
-                  placeholder="휴대폰 번호를 입력해주세요."
-                  class="input-default is-delete"
-                />
-              </div>
-              <input id="randomBoxInput3" type="hidden" disabled="" value="" />
-            </div>
-
-            <div class="rq-form">
-              <div class="agree-wrap">
-                <!-- 전체 동의 -->
-                <div class="btn-box btn-check btn-text-line">
-                  <input
-                    type="checkbox"
-                    id="agreeAll"
-                    v-model="agreeAll"
-                    @change="onAgreeAllChange"
-                  />
-                  <label for="agreeAll">
-                    <span class="ico-check"></span>전체 동의 (필수)
-                  </label>
-                </div>
-                <div class="agree-group">
-                  <div class="btn-box btn-check">
-                    <input
-                      type="checkbox"
-                      class="agreeReq"
-                      id="randomBoxAgree1"
-                      v-model="agree1"
-                      @change="onAgreeChange"
-                    />
-                    <label for="randomBoxAgree1">
-                      <span class="ico-check"></span>이벤트 참여 및 전화 상담을 위한
-                      개인정보 수집 및 이용 동의 (필수)
-                    </label>
-                    <a @click="activeLayer(2)" class="ico-arrow-right agreeActions"
-                      >더보기</a
-                    >
-                  </div>
-                  <div class="btn-box btn-check">
-                    <input
-                      type="checkbox"
-                      class="agreeReq"
-                      id="randomBoxAgree2"
-                      v-model="agree2"
-                      @change="onAgreeChange"
-                    />
-                    <label for="randomBoxAgree2">
-                      <span class="ico-check"></span>고객 혜택 정보 및 광고 수신 동의
-                      (필수)
-                    </label>
-                    <a @click="activeLayer(2)" class="ico-arrow-right agreeActions"
-                      >더보기</a
-                    >
-                  </div>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-        <div class="popup-footer">
-          <div class="btn-group">
-            <button
-              class="btns w-sm lightgray md-ripples ripples-dark popup-close"
-              type="button"
-            >
-              취소
-            </button>
-            <button
-              id="randomBoxAplyBtn"
-              class="btns w-sm md-ripples ripples-light gtm-tracking"
-              data-gtm-tracking-category="랜덤박스 팝업_PC"
-              data-gtm-tracking-action="랜덤박스 열기_PC"
-              data-gtm-tracking-label="박스열기 버튼"
-              type="button"
-              @click="trySpinRoulette(useSeq)"
-            >
-              룰렛 돌리기
-            </button>
-          </div>
-          <button
-            @click="activeLayer1 = !activeLayer1"
-            type="button"
-            id="layer-close01"
-            class="btn-close-x popup-close"
-          >
-            <svg
-              xmlns="http://www.w3.org/2000/svg"
-              width="37.657"
-              height="37.657"
-              viewBox="0 0 37.657 37.657"
-            >
-              <path
-                data-name="선 392"
-                transform="translate(2.828 2.828)"
-                style="fill: none; stroke: #000; stroke-linecap: round; stroke-width: 4px"
-                d="m0 0 32 32"
-              />
-              <path
-                data-name="선 393"
-                transform="translate(2.828 2.828)"
-                style="fill: none; stroke: #000; stroke-linecap: round; stroke-width: 4px"
-                d="M32 0 0 32"
-              />
-            </svg>
-          </button>
-        </div>
-      </div>
-    </div>
-
-    <div
-      id="randomBoxAgree-layer02"
-      class="layer-popup bottom-sheet-wrap terms"
-      role="dialog"
-      aria-hidden="false"
-      tabindex="0"
-      style="z-index: 101"
-      :class="{ show: activeLayer2 }"
-    >
-      <div class="layer-popup-item">
-        <div class="popup-header">
-          <strong class="txt-main">약관 및 동의 내용 보기</strong>
-        </div>
-        <div class="popup-body">
-          <div class="agree-cont">
-            <div class="agree-box">
-              <p>
-                귀사가 고객 혜택정보 및 광고 수신동의(필수) 항목에서 수집한 개인정보,
-                고객세분화정보,<br />
-                선호도 및 라이프스타일 정보, 전산조회이력정보 및 상담이력정보, 고객 간
-                관계에 관한 예측 정보 및 이 정보들에 대한 통계·분석데이터를 해지 시까지
-                수집·이용·분석하여 각종 서비스<br />
-                ·상품(주)미디어로그가 제공하는 이동통신, 금융서비스, 결합·제휴상품,
-                스토리지 등<br />
-                데이터·콘텐츠서비스, 부가서비스, 전자상거래서비스, 위치정보서비스,
-                it솔루션, Smart health서비스, 신규서비스·상품 포함), 제휴사와 결합된
-                서비스 및 제휴사의 서비스에 대하여 홍보, 가입권유, 프로모션, 생활정보,
-                멤버십정보, 이벤트, 해외로밍 안내(공항 또는 항만 위치 시 로밍 이용방법,
-                진행중인 이벤트 등 안내) 및 설문조사 목적으로 수집·이용·활용하는 것,
-                본인에게 혜택정보, 광고정보를 각종 통신방식[전화, SMS, LMS, MMS, WAP
-                Push,이메일, 우편, APP안내 및 팝업, APP PUSH]으로 전송하는 것에
-                동의합니다.
-              </p>
-            </div>
-          </div>
-        </div>
-        <div class="popup-footer">
-          <!-- <div class="btn-group">
-            <button
-              class="btns w-sm lightgray md-ripples ripples-dark popup-close"
-              type="button"
-            >
-              취소
-            </button>
-            <button class="btns w-sm md-ripples ripples-light popup-close" type="button">
-              확인
-            </button>
-          </div> -->
-          <button
-            @click="activeLayer2 = !activeLayer2"
-            class="btn-close-x popup-close"
-            id="layer-close02"
-            type="button"
-          >
-            <svg
-              xmlns="http://www.w3.org/2000/svg"
-              width="37.657"
-              height="37.657"
-              viewBox="0 0 37.657 37.657"
-            >
-              <path
-                data-name="선 392"
-                transform="translate(2.828 2.828)"
-                style="fill: none; stroke: #000; stroke-linecap: round; stroke-width: 4px"
-                d="m0 0 32 32"
-              />
-              <path
-                data-name="선 393"
-                transform="translate(2.828 2.828)"
-                style="fill: none; stroke: #000; stroke-linecap: round; stroke-width: 4px"
-                d="M32 0 0 32"
-              />
-            </svg>
-          </button>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script setup>
-  import { ref, onMounted, nextTick } from "vue";
-  import { useRoute } from "vue-router";
-
-  definePageMeta({
-    layout: "roulette",
-  });
-
-  /************************************************************************
-|    전역
-************************************************************************/
-
-  const pageId = ref("ROULETTE");
-  const { $eventBus } = useNuxtApp();
-  const winProbability = ref(100.0);
-  const savedName = ref("");
-  const savedPhone = ref("");
-  const isSpinning = ref(false);
-  const activeLayer1 = ref(false);
-  const activeLayer2 = ref(false);
-
-  const wheelRef = ref(null);
-  const textLayerRef = ref(null);
-
-  const agreeAll = ref(false);
-  const agree1 = ref(false);
-  const agree2 = ref(false);
-
-  const route = useRoute();
-  const useSeq = ref(route.query.seq || route.params.seq || ""); // 쿼리 또는 params에서 seq 추출
-  const compId = ref(route.query.id || route.params.id || ""); // 쿼리 또는 params에서 id 추출
-  /************************************************************************
-|    스토어
-************************************************************************/
-  const useDtStore = useDetailStore();
-
-  /************************************************************************
-|    함수
-************************************************************************/
-  const setWinProbability = (probability) => {
-    winProbability.value = Math.max(0, Math.min(100, parseFloat(probability)));
-    return winProbability.value;
-  };
-
-  const activeLayer = (idx) => {
-    if (idx === 1) {
-      activeLayer1.value = !activeLayer1.value;
-    } else if (idx === 2) {
-      activeLayer2.value = !activeLayer2.value;
-    }
-  };
-
-  const createRoulette = (numSections, itemName) => {
-    nextTick(() => {
-      const $wheel = wheelRef.value;
-      const $textLayer = textLayerRef.value;
-      if (!$wheel || !$textLayer) return;
-
-      // 초기화
-      $wheel.style.background = "";
-      $textLayer.innerHTML = "";
-      const items = ["당첨", "꽝", "꽝", "꽝", "꽝", "꽝", "꽝", "꽝"];
-      const sectionCount = numSections;
-      const sectionAngle = 360 / sectionCount;
-      const colors = ["#f5c4c3", "#fdf195", "#F0FFF0"];
-
-      // conic-gradient
-      let conicGradient = "conic-gradient(";
-      for (let i = 0; i < sectionCount; i++) {
-        const startAngle = i * sectionAngle;
-        const endAngle = (i + 1) * sectionAngle;
-        const color = colors[i % 3];
-        conicGradient += `${color} ${startAngle}deg ${endAngle}deg`;
-        if (i < sectionCount - 1) conicGradient += ", ";
-      }
-      conicGradient += ")";
-      $wheel.style.background = conicGradient;
-
-      // 룰렛 크기 계산
-      const wheelRect = $wheel.getBoundingClientRect();
-      const radius = wheelRect.width / 2;
-
-      for (let i = 0; i < sectionCount; i++) {
-        const textDiv = document.createElement("div");
-        textDiv.className = "section-text";
-        textDiv.innerText = items[i % items.length];
-        const angle = i * sectionAngle + sectionAngle / 2;
-        const distance = radius * 0.75;
-        const radians = angle * (Math.PI / 180);
-        const centerX = radius;
-        const centerY = radius;
-        const x = centerX + Math.sin(radians) * distance;
-        const y = centerY - Math.cos(radians) * distance;
-        textDiv.style.position = "absolute";
-        textDiv.style.left = `${x}px`;
-        textDiv.style.top = `${y}px`;
-        textDiv.style.transform = `rotate(${angle}deg)`;
-        $textLayer.appendChild(textDiv);
-      }
-
-      // 당첨 섹션 강조
-      const winSectionIndex = 4;
-      const $winText = $textLayer.children[winSectionIndex];
-      if ($winText) {
-        $winText.style.color = "#E91E63";
-        $winText.style.fontWeight = "bolder";
-      }
-    });
-  };
-
-  const handleWin = (name, phone, EVT_SEQ) => {
-    //참여자 정보
-    let __req = {
-      name: name,
-      phone: phone,
-      seq: EVT_SEQ,
-      ignore_auth: 1,
-    };
-
-    useAxios()
-      .post("/winner/reg", __req)
-      .then((res) => {
-        if (res.data.rank > 0) {
-          let param = {
-            id: pageId,
-            title: "시스템 메시지",
-            content: `축하합니다.<br/>${res.data.rank}등에 당첨되었습니다!`,
-            yes: {
-              text: "확인",
-              isProc: false,
-            },
-            no: {
-              text: "취소",
-              isProc: false,
-            },
-            reload: true,
-          };
-          $eventBus.emit("OPEN_CONFIRM_POP_UP", param);
-        } else {
-          let param = {
-            id: pageId,
-            title: "시스템 메시지",
-            content: `당첨에 실패하였습니다.<br/>다음 기회에 도전해보세요!`,
-            yes: {
-              text: "확인",
-              isProc: false,
-            },
-            no: {
-              text: "취소",
-              isProc: false,
-            },
-            reload: true,
-          };
-          $eventBus.emit("OPEN_CONFIRM_POP_UP", param);
-        }
-      })
-      .catch((error) => {})
-      .finally(() => {});
-  };
-
-  const spinRoulette = (name, phone, EVT_SEQ) => {
-    if (isSpinning.value) return;
-    isSpinning.value = true;
-
-    const spinDuration = 5000;
-    const spinRounds = 5; // 룰렛 회전 횟수
-    const sectionCount = 8; // 룰렛 섹션 개수
-    const sectionAngle = 360 / sectionCount;
-    const winSectionIndex = 0; //당첨 섹션 인덱스 : crateRoulette()에서 설정한 인덱스와 동일해야 함
-    const winSectionStart = winSectionIndex * sectionAngle; // 당첨 섹션 시작 각도
-    const winSectionEnd = (winSectionIndex + 1) * sectionAngle; // 당첨 섹션 끝 각도
-
-    const isWin = Math.random() * 100 < winProbability.value;
-    let stopAngle;
-    if (isWin) {
-      stopAngle = winSectionStart + Math.random() * (winSectionEnd - winSectionStart);
-    } else {
-      const loseSections = [];
-      for (let i = 0; i < sectionCount; i++) {
-        if (i !== winSectionIndex) loseSections.push(i);
-      }
-      const loseIndex = loseSections[Math.floor(Math.random() * loseSections.length)];
-      const loseStart = loseIndex * sectionAngle;
-      const loseEnd = (loseIndex + 1) * sectionAngle;
-      stopAngle = loseStart + Math.random() * (loseEnd - loseStart);
-    }
-
-    const rotationAmount = spinRounds * 360 + (360 - stopAngle);
-
-    nextTick(() => {
-      const $wheel = wheelRef.value;
-      const $textLayer = textLayerRef.value;
-      if (!$wheel || !$textLayer) return;
-
-      $wheel.style.transition = "none";
-      $wheel.style.transform = "rotate(0deg)";
-      $textLayer.style.transition = "none";
-      $textLayer.style.transform = "rotate(0deg)";
-      void $wheel.offsetWidth;
-      $wheel.style.transition = `transform ${spinDuration}ms cubic-bezier(0.2, 0.8, 0.3, 0.9)`;
-      $wheel.style.transform = `rotate(${rotationAmount}deg)`;
-      $textLayer.style.transition = `transform ${spinDuration}ms cubic-bezier(0.2, 0.8, 0.3, 0.9)`;
-      $textLayer.style.transform = `rotate(${rotationAmount}deg)`;
-
-      setTimeout(() => {
-        isSpinning.value = false;
-        const finalAngle = (360 - (rotationAmount % 360)) % 360;
-        const sectionIndex = Math.floor(finalAngle / sectionAngle);
-
-        //console.log(sectionIndex, winSectionIndex);
-        if (sectionIndex === winSectionIndex) {
-          handleWin(name, phone, EVT_SEQ);
-        } else {
-          handleWin(name, phone, EVT_SEQ);
-        }
-      }, spinDuration);
-    });
-  };
-
-  const trySpinRoulette = async (EVT_SEQ) => {
-    const name = document.getElementById("userName").value.trim();
-    const phone = document.getElementById("userPhone").value.trim();
-
-    if (!name) {
-      let param = {
-        id: pageId,
-        title: "시스템 메시지",
-        content: "이름을 입력하세요.",
-        yes: {
-          text: "확인",
-          isProc: false,
-        },
-        no: {
-          text: "취소",
-          isProc: false,
-        },
-      };
-      $eventBus.emit("OPEN_CONFIRM_POP_UP", param);
-      document.getElementById("userName").focus();
-      return;
-    }
-    if (!phone) {
-      let param = {
-        id: pageId,
-        title: "시스템 메시지",
-        content: "휴대폰 번호를 입력하세요.",
-        yes: {
-          text: "확인",
-          isProc: false,
-        },
-        no: {
-          text: "취소",
-          isProc: false,
-        },
-      };
-      $eventBus.emit("OPEN_CONFIRM_POP_UP", param);
-      document.getElementById("userPhone").focus();
-      return;
-    }
-
-    const phoneRegex = /^010-\d{4}-\d{4}$/;
-    if (!phoneRegex.test(phone)) {
-      let param = {
-        id: pageId,
-        title: "시스템 메시지",
-        content: "휴대폰 번호를 형식에 맞게 입력하세요. 예시: 010-1234-5678",
-        yes: {
-          text: "확인",
-          isProc: false,
-        },
-        no: {
-          text: "취소",
-          isProc: false,
-        },
-      };
-      $eventBus.emit("OPEN_CONFIRM_POP_UP", param);
-      document.getElementById("userPhone").focus();
-      return;
-    }
-
-    if (!agreeAll.value) {
-      let param = {
-        id: pageId,
-        title: "시스템 메시지",
-        content:
-          "이벤트 참여 및 전화 상담을 위한 개인정보 수집 및\n이용 동의 (필수) 에 동의해주세요.",
-        yes: {
-          text: "확인",
-          isProc: false,
-        },
-        no: {
-          text: "취소",
-          isProc: false,
-        },
-      };
-      $eventBus.emit("OPEN_CONFIRM_POP_UP", param);
-
-      return;
-    }
-
-    savedName.value = name;
-    savedPhone.value = phone;
-
-    activeLayer1.value = !activeLayer1.value;
-
-    const isMatched = await matchedUser(savedName.value, savedPhone.value, EVT_SEQ);
-    if (!isMatched) {
-      spinRoulette(savedName.value, savedPhone.value, EVT_SEQ);
-    }
-  };
-
-  const rouletteCnt = (EVT_SEQ) => {
-    let __req = {
-      seq: EVT_SEQ,
-      ignore_auth: 1,
-    };
-    useAxios()
-      .post("/winner/itemcount", __req)
-      .then((res) => {
-        //createRoulette(res.data.count, res.data.items);
-        /*
-          TODO :
-          룰렛 생성 어떤 형태로 진행할지 기획 조율 필요
-        */
-        createRoulette(8, res.data.items);
-      })
-      .catch((error) => {})
-      .finally(() => {});
-  };
-  // 전체 동의 체크 시 하위 동의도 같이 변경
-  const onAgreeAllChange = () => {
-    agree1.value = agreeAll.value;
-    agree2.value = agreeAll.value;
-  };
-
-  // 하위 동의 체크 시 전체 동의 상태도 동기화
-  const onAgreeChange = () => {
-    agreeAll.value = agree1.value && agree2.value;
-  };
-
-  const winnerCheck = (EVT_SEQ) => {
-    let params = {
-      seq: EVT_SEQ,
-      ignore_auth: 1,
-    };
-    useAxios()
-      .post("/winner/winnerchk", params)
-      .then((res) => {
-        //console.log(res.data.status);
-        rouletteCnt(EVT_SEQ);
-        if (res.data.status == "closed") {
-          setWinProbability(0);
-        } else {
-          setWinProbability(100); // 당첨 확률 몇 퍼센트로 할지 관리자 설정값으로 진행할지 여부 확인 필요
-        }
-      })
-      .catch((error) => {
-        //$log.debug("[equipMgmtReg][fnGetTenantList][error]");
-        //useErrorHandler().fnSetCommErrorHandle(error, fnGetTenantList);
-      })
-      .finally(() => {
-        //$log.debug("[equipMgmtReg][fnGetTenantList][finished]");
-        //objSlt.value.tenantNameList = _cloneDeep(temp);
-      });
-  };
-
-  const matchedUser = async (name, phone, EVT_SEQ) => {
-    let __req = {
-      name,
-      phone,
-      seq: EVT_SEQ,
-      ignore_auth: 1,
-    };
-    try {
-      const res = await useAxios().post("/winner/matcheduser", __req);
-      if (res.data.result == "matched") {
-        let param = {
-          id: pageId,
-          title: "시스템 메시지",
-          content: `이미 참여하신 사용자입니다.<br/>다음 기회에 도전해보세요!`,
-          yes: { text: "확인", isProc: false },
-          no: { text: "취소", isProc: false },
-          reload: true,
-        };
-        $eventBus.emit("OPEN_CONFIRM_POP_UP", param);
-        return true; // 이미 참여자
-      } else if (res.data.result == "phonesame") {
-        let param = {
-          id: pageId,
-          title: "시스템 메시지",
-          content: `이미 참여한 사용자의 휴대폰 번호와 동일합니다.<br/>다음 기회에 도전해보세요!`,
-          yes: { text: "확인", isProc: false },
-          no: { text: "취소", isProc: false },
-          reload: true,
-        };
-        $eventBus.emit("OPEN_CONFIRM_POP_UP", param);
-        return true; // 이미 참여자
-      }
-      return false; // 참여자 아님
-    } catch (e) {
-      return false;
-    }
-  };
-
-  /************************************************************************
-|    라이프 사이클
-************************************************************************/
-  onMounted(() => {
-    // useSeq.value가 비어있지 않을 때만 winnerCheck 호출
-    if (!useSeq.value || !compId.value) {
-      $eventBus.emit("OPEN_CONFIRM_POP_UP", {
-        id: "ROULETTE",
-        title: "시스템 메시지",
-        content: "이벤트 식별값(id/seq)이 없습니다.",
-        yes: { text: "확인", isProc: false },
-        no: { text: "취소", isProc: false },
-      });
-      return;
-    }
-    winnerCheck(useSeq.value);
-    /*
-      TODO :
-    */
-  });
-</script>

+ 0 - 627
pages/view/event/evtAdd_bk250520.vue

@@ -1,627 +0,0 @@
-<template>
-  <div>
-    <div class="inner--headers">
-      <h2>{{ pageId }}</h2>
-      <div class="bread--crumbs--wrap">
-        <span>홈</span>
-        <span>{{ pageId }}</span>
-        <span v-if="pageIdSub">{{ pageIdSub }}</span>
-      </div>
-    </div>
-    <div class="data--list--wrap">
-      <div class="table--wrap">
-        <v-form ref="addForm">
-          <table>
-            <colgroup>
-              <col width="20%" />
-              <col width="80%" />
-            </colgroup>
-            <tbody>
-              <tr>
-                <th class="bg le">이벤트명<span v-if="!isDisabled" class="bul">*</span></th>
-                <td class="le" v-if="isDisabled">
-                  {{ form.formValue1 }}
-                </td>
-                <td v-else>
-                  <v-text-field
-                    maxlength="50"
-                    v-model="form.formValue1"
-                    style="width: 100%"
-                    :rules="[useValid.required('이벤트명')]"
-                    class="custom-input mini left"
-                    placeholder="이벤트명을 입력하세요"
-                  ></v-text-field>
-                </td>
-              </tr>
-              <tr>
-                <th class="bg le">
-                  이벤트 기간<span v-if="!isDisabled" class="bul">*</span>
-                </th>
-                <td v-if="!isDisabled">
-                  <div class="calendar-wrap ml--0">
-                    <div class="calendar">
-                      <VueDatePicker
-                        :format="datePickerFormat"
-                        v-model="form.formValue2"
-                        placeholder="날짜를 선택하세요"
-                        :auto-apply="true"
-                        :readonly="isDisabled"
-                        week-start="0"
-                      ></VueDatePicker>
-                    </div>
-                    <span class="text">~</span>
-                    <div class="calendar">
-                      <VueDatePicker
-                        :format="datePickerFormat"
-                        v-model="form.formValue3"
-                        placeholder="날짜를 선택하세요"
-                        :auto-apply="true"
-                        week-start="0"
-                        :readonly="isDisabled"
-                      ></VueDatePicker>
-                    </div>
-                    <div class="btn--wrap evt--btn ml--10">
-                      <v-btn v-show="pageType == 'U' && evtStatus == '0'" class="custom-btn btn-sky" @click="fnStUpdEvt"
-                        ><i class="ico"></i>이벤트 진행</v-btn
-                      >
-                      <v-btn v-show="pageType == 'U' && evtStatus == '1'" class="custom-btn btn-red" @click="fnStUpdEvt"
-                        ><i class="ico"></i>이벤트 마감</v-btn
-                      >
-                    </div>
-                  </div>
-                </td>
-                <td v-else>
-                  <div class="calendar-wrap ml--0">
-                    {{ form.formValue2 }} ~ {{ form.formValue3 }}
-                    <div class="btn--wrap evt--btn ml--10">
-                      <v-btn v-show="pageType == 'U' && evtStatus == '0'" class="custom-btn btn-sky" @click="fnStUpdEvt"
-                        ><i class="ico"></i>이벤트 진행</v-btn
-                      >
-                      <v-btn v-show="pageType == 'U' && evtStatus == '1'" class="custom-btn btn-red" @click="fnStUpdEvt"
-                        ><i class="ico"></i>이벤트 마감</v-btn
-                      >
-                    </div>
-                  </div>
-                </td>
-              </tr>
-              <tr v-for="(item, index) in itemsForm.items" :key="index">
-                <th class="bg le">
-                  아이템 등록
-                  <span v-if="itemsForm.items.length > 0"> {{ index + 1 }} </span>
-                  <span v-if="!isDisabled && index < 2" class="bul">*</span>
-                </th>
-                <td v-if="!isDisabled">
-                  <div class="input--wrap">
-                    <v-text-field
-                      maxlength="50"
-                      v-model="item.name"
-                      style="width: 30%"
-                      class="custom-input mini left"
-                      placeholder="아이템명을 입력하세요"
-                      :rules="[useValid.required('아이템명')]"
-                      :readonly="isDisabled"
-                    ></v-text-field>
-                    <v-text-field
-                      v-model="item.qty"
-                      placeholder="당첨 수량을 입력하세요"
-                      style="width: 20%"
-                      class="custom-input mini left"
-                      :rules="[useValid.required('당첨 수량')]"
-                      maxlength="10"
-                      @input="(e) => formatNumber(e, item, 'qty')"
-                      :readonly="isDisabled"
-                    />
-                    <v-text-field
-                      v-model="item.rate"
-                      placeholder="당첨 확률을 입력하세요"
-                      style="width: 15%"
-                      :rules="[useValid.required('당첨 확률')]"
-                      class="custom-input mini left"
-                      maxlength="7"
-                      @input="(e) => formatFloat(e, item, 'rate')"
-                      :readonly="isDisabled"
-                    />
-                    <span class="text">
-                      %
-                    </span>
-                    <v-btn
-                      icon="mdi-minus"
-                      color="red"
-                      size="small"
-                      :disabled="itemsForm.items.length <= 2  || isDisabled "
-                      @click="removeItem(index)"
-                    ></v-btn>
-                    <v-btn
-                      icon="mdi-plus"
-                      color="primary"
-                      size="small"
-                      :disabled="itemsForm.items.length >= 15 || isDisabled"
-                      v-if="index === itemsForm.items.length - 1"
-                      @click="addItem"
-                    ></v-btn>
-                  </div>
-                </td>
-                <td v-else>
-                  <div class="input--wrap">
-                    {{ item.name }}
-                    / 당첨 수량 : {{ item.qty }}
-                    / 당첨 확률 : {{ item.rate }} %
-                  </div>
-                </td>
-              </tr>
-              <tr>
-                <th class="bg le">문자 메시지<span v-if="!isDisabled" class="bul">*</span></th>
-                <td>
-                  <div class="btn--wrap evt--btn">
-                    <v-btn class="custom-btn btn-sky" @click="messageFormOpen()"
-                      ><i class="ico"></i>문자 메시지 입력</v-btn
-                    >
-                      <v-dialog v-model="messageForm" persistent width="50rem">
-                        <div class="v-common-dialog-wrapper custom-dialog">
-                          <div class="modal-tit">
-                            <strong>문자 메시지 입력</strong>
-                            <button class="btn-close" @click="messageForm = false"></button>
-                          </div>
-                          <div class="v-common-dialog-content">
-                            <div class="ms--pop">
-                              <div class="ms--input--wrap">
-                                <v-textarea
-                                  row-height="15"
-                                  v-model="form.formValue4Temp"
-                                  hide-details=""
-                                  rows="15"
-                                  :readonly="isDisabled"
-                                  variant="outlined"
-                                  no-resize
-                                >
-                                </v-textarea>
-                              </div>
-                              <div class="ms--desc--wrap">
-                                <p>
-                                  <strong>코드명</strong>
-                                  코드명은 자동으로 노출됩니다.
-                                  <br>
-                                  {이벤트명} : 등록된 이벤트명이 노출됩니다.<br>
-                                  {상품명} : 등록된 상품이 노출됩니다.<br>
-                                  {당첨일} : 당첨된 날짜가 노출됩니다.
-                                </p>
-                              </div>
-                            </div>
-                          </div>
-                          <div class="btn-wrap">
-                            <v-btn class="custom-btn btn-white mini" v-if="!isDisabled" @click="messageForm = false"><i class="ico"></i>취소</v-btn>
-                            <v-btn class="custom-btn btn-blue mini" v-if="!isDisabled" @click="messageFormUpt()"><i class="ico"></i>저장</v-btn>
-                          </div>
-                        </div>
-                      </v-dialog>
-                  </div>
-                </td>
-              </tr>
-            </tbody>
-          </table>
-        </v-form>
-      </div>
-      <div class="view-btm-btn">
-        <div class="btn-l">
-          <v-btn class="custom-btn btn-list" @click="router.back()"
-            ><i class="ico"></i>목록</v-btn
-          >
-        </div>
-        <div class="btn-r">
-          <v-btn v-if="pageType == 'I'" class="custom-btn btn-blue2" @click="fnRegCheck"
-            ><i class="ico"></i>저장</v-btn
-          >
-          <v-btn v-else-if="pageType == 'U' && evtStatus == '0'" class="custom-btn btn-blue2" @click="fnRegCheck"
-            ><i class="ico"></i>수정</v-btn
-          >
-          <v-btn v-else class="custom-btn btn-blue2" @click="router.push('/view/event/evtList')"
-            >참여자 보기</v-btn
-          >
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script setup>
-import VueDatePicker from "@vuepic/vue-datepicker";
-import "@vuepic/vue-datepicker/dist/main.css";
-import { reactive } from 'vue';
-/************************************************************************
-|    레이아웃
-************************************************************************/
-definePageMeta({
-  layout: "default",
-});
-
-/************************************************************************
-|   PROPS
- ************************************************************************/
-const props = defineProps({
-  propsData: {
-    type: Object,
-    default: () => {},
-  },
-});
-
-/************************************************************************
-|    스토어
- ************************************************************************/
-const useDtStore = useDetailStore();
-/************************************************************************
-|    전역
- ************************************************************************/
-const { $toast, $log, $dayjs, $eventBus } = useNuxtApp();
-const router = useRouter();
-const pageType = useDtStore.boardInfo.pageType;
-const evtStatus = useDtStore.boardInfo.status;
-const pageId = pageType == 'U' ? evtStatus == '1' ? '진행중 이벤트' : (evtStatus == '2' ? '마감된 이벤트' : '이벤트 수정') : '이벤트 등록';
-const isDisabled = pageType == 'I' ? false : evtStatus !== '0' ? true : false;
-const pageIdSub = ref();
-const addForm = ref(null);
-const datePickerFormat = "yyyy-MM-dd";
-const messageForm = ref(false);
-const form = ref({
-  formValue1: "",
-  formValue2: "",
-  formValue3: "",
-  formValue4: "안녕하세요. 고객님!\n{이벤트명}\n{상품명} 당첨을 축하드립니다. \n당첨일자 : {당첨일}\n\n*이 메시지는 고객님이 참여한 이벤트 당첨으로 지급된 안내 메시지입니다.\n\n문의 : 고객센터 1234-1234\n\n감사합니다.",
-  formValue4Temp: ""
-});
-const itemsForm = reactive({
-  items: [
-    {
-      name: '',
-      qty: '',
-      rate: ''
-    },
-    {
-      name: '',
-      qty: '',
-      rate: ''
-    }
-  ]
-})
-
-/* eslint-disable */
-/* prettier-ignore */
-
-/************************************************************************
-|    함수(METHODS)
-************************************************************************/
-
-const addItem = () => {
-  if (itemsForm.items.length < 15) {
-    itemsForm.items.push({ name: '', qty: '', rate: '' })
-  }
-}
-
-const removeItem = (index) => {
-  if (itemsForm.items.length > 1) {
-    itemsForm.items.splice(index, 1)
-  }
-}
-
-const formatNumber = (event, row, field) => {
-  let input = event.target.value.replace(/[^0-9]/g, '');
-  let formattedInput = input ? new Intl.NumberFormat().format(input) : '';
-  row[field] = formattedInput;
-}
-
-const formatFloat = (event, row, field) => {
-  let input = event.target.value;
-
-  // 숫자만 추출
-  input = input.replace(/[^0-9]/g, '');
-
-  // 입력값이 없으면 빈값 처리
-  if (!input) {
-    row[field] = '';
-    return;
-  }
-
-  // 2자리까진 그대로, 3자리 이상이면 소수점 자동 삽입
-  let result = '';
-  if (input.length <= 2) {
-    result = input;
-  } else {
-    const intPart = input.slice(0, 2);
-    const decimalPart = input.slice(2, 5); // 소수점 이하 최대 3자리
-    result = `${intPart}.${decimalPart}`;
-  }
-
-  // 숫자로 변환해서 100 초과면 강제로 100으로 고정
-  const num = parseFloat(result);
-  if (!isNaN(num) && num > 100) {
-    result = '100';
-  }
-
-  // 최종 결과 저장
-  row[field] = result;
-};
-
-const messageFormOpen = () => {
-  messageForm.value = true;
-  form.value.formValue4Temp = form.value.formValue4;
-}
-
-const messageFormUpt = () => {
-  if(form.value.formValue4Temp){
-    form.value.formValue4 = form.value.formValue4Temp;
-    messageForm.value = false;
-  } else {
-    let param = {
-      id: pageId,
-      title: "문자 메시지 입력",
-      content: "문자 메시지를 입력해주세요.",
-      yes: {
-        text: "확인",
-        isProc: false,
-      },
-    };
-    $eventBus.emit("OPEN_CONFIRM_POP_UP", param);
-  }
-}
-
-const formatDate = (date) => {
-  const d = new Date(date);
-  const year = d.getFullYear();
-  const month = ("0" + (d.getMonth() + 1)).slice(-2);
-  const day = ("0" + d.getDate()).slice(-2);
-  return `${year}-${month}-${day}`;
-};
-
-const fnRegCheck = () => {
-  nextTick(() => {
-    if (addForm.value && typeof addForm.value.validate === "function") {
-      addForm.value
-        .validate()
-        .then((isValid) => {
-          if (isValid.valid) {
-            if (pageType == "I") {
-              // 등록시 이벤트 기간만 별도로 필수 체크
-              if(form.value.formValue2 && form.value.formValue3){
-                fnRegEvt();
-              } else {
-                let param = {
-                id: pageId,
-                title: "이벤트 등록",
-                content: "이벤트 기간을 선택해주세요.",
-                yes: {
-                  text: "확인",
-                  isProc: false,
-                },
-              };
-                $eventBus.emit("OPEN_CONFIRM_POP_UP", param);
-              }
-            } else {
-              fnUpdEvt();
-            }
-          } else {
-            if (pageType == "I") {
-              let param = {
-                id: pageId,
-                title: "이벤트 등록",
-                content: "필수항목을 입력해주세요.",
-                yes: {
-                  text: "확인",
-                  isProc: false,
-                },
-              };
-              $eventBus.emit("OPEN_CONFIRM_POP_UP", param);
-            } else {
-              let param = {
-                id: pageId,
-                title: "이벤트 수정",
-                content: "필수항목을 입력해주세요.",
-                yes: {
-                  text: "확인",
-                  isProc: false,
-                },
-              };
-              $eventBus.emit("OPEN_CONFIRM_POP_UP", param);
-            }
-          }
-        })
-        .catch((err) => {
-          console.error("벨리데이션 에러", err);
-        });
-    } else {
-      console.error("항목 누락체크[fnRegCheck]]");
-    }
-  });
-};
-
-const fnRegEvt = () => {
-  let param = {
-    id: pageId,
-    title: "이벤트 등록",
-    content: "등록하시겠습니까?",
-    yes: {
-      text: "등록",
-      isProc: true,
-      event: "FN_INSERT",
-      param: "",
-    },
-    no: {
-      text: "취소",
-      isProc: false,
-    },
-  };
-  $eventBus.emit("OPEN_CONFIRM_POP_UP", param);
-};
-
-const fnInsert = () => {
-  let params = {
-    title: form.value.formValue1,
-    startdate: form.value.formValue2,
-    enddate: form.value.formValue3,
-    item: itemsForm.items.map(item => ({
-      name: item.name,
-      qty: item.qty.replace(/,/g, ''), 
-      rate: item.rate
-    }))
-  };
-
-  useAxios()
-    .post("/evt/reg", params)
-    .then((res) => {
-      router.push("/view/event/evtList");
-    })
-    .catch((error) => {
-    })
-    .finally(() => {
-    });
-};
-
-const fnUpdate = () => {
-  let _req = {
-    seq: useDtStore.boardInfo.seq,
-    title: form.value.formValue1,
-    startdate: form.value.formValue2,
-    enddate: form.value.formValue3,
-    item: itemsForm.items.map(item => ({
-      name: item.name,
-      qty: item.qty.replace(/,/g, ''), 
-      rate: item.rate
-    }))
-  };
-
-  useAxios()
-    .post("/evt/update", _req)
-    .then((res) => {
-      router.push({
-        path: "/view/event/evtList",
-      });
-    })
-    .catch((error) => {});
-};
-
-const fnDetail = () => {
-  let _req = {
-    seq: useDtStore.boardInfo.seq,
-  };
-  useAxios()
-    .get(`evt/detail/${_req.seq}`)
-    .then((res) => {
-      form.value.formValue1 = res.data.title
-      form.value.formValue2 = new Date(res.data.startdate);
-      form.value.formValue3 = new Date(res.data.enddate);
-      //form.value.formValue4 = 
-
-      itemsForm.items.splice(0, itemsForm.items.length, ...res.data.items.map(item => ({
-        name: item.name || '',
-        qty: item.qty ? new Intl.NumberFormat().format(item.qty) : '',
-        rate: item.rate || ''
-      })));
-    })
-    .catch((error) => {});
-};
-const fnStUpdate = () => {
-  let _req = {
-    seq: useDtStore.boardInfo.seq,
-  };
-
-  useAxios()
-    .post(`/evt/stupdate/${_req.seq}`)
-    .then((res) => {
-      router.push({
-        path: "/view/event/evtList",
-      });
-    })
-    .catch((error) => {});
-};
-const fnUpdEvt = () => {
-  let param = {
-    id: pageId,
-    title: "이벤트 수정",
-    content: "수정하시겠습니까?",
-    yes: {
-      text: "확인",
-      isProc: true,
-      event: "FN_UPDATE",
-      param: "",
-    },
-    no: {
-      text: "취소",
-      isProc: false,
-    },
-  };
-  $eventBus.emit("OPEN_CONFIRM_POP_UP", param);
-};
-
-const fnStUpdEvt = () => {
-  if(evtStatus == 0){
-    let param = {
-      id: pageId,
-      title: "이벤트 진행",
-      content: "이벤트를 진행하시겠습니까?",
-      yes: {
-        text: "확인",
-        isProc: true,
-        event: "FN_STUPDATE",
-        param: "",
-      },
-      no: {
-        text: "취소",
-        isProc: false,
-      },
-    };
-    $eventBus.emit("OPEN_CONFIRM_POP_UP", param);
-  } else if(evtStatus == 1){
-    let param = {
-      id: pageId,
-      title: "이벤트 마감",
-      content: "이벤트를 마감하시겠습니까?",
-      yes: {
-        text: "확인",
-        isProc: true,
-        event: "FN_STUPDATE",
-        param: "",
-      },
-      no: {
-        text: "취소",
-        isProc: false,
-      },
-    };
-    $eventBus.emit("OPEN_CONFIRM_POP_UP", param);
-  }
-};
-
-
-
-/************************************************************************
-|    팝업 이벤트버스 정의
-************************************************************************/
-$eventBus.off("FN_STUPDATE");
-$eventBus.on("FN_STUPDATE", () => {
-  fnStUpdate();
-});
-$eventBus.off("FN_UPDATE");
-$eventBus.on("FN_UPDATE", () => {
-  fnUpdate();
-});
-$eventBus.off("FN_INSERT");
-$eventBus.on("FN_INSERT", () => {
-  fnInsert();
-});
-
-/************************************************************************
-|    WATCH
-************************************************************************/
-watch(
-  [() => form.value.formValue2, () => form.value.formValue3],
-  ([newVal2, newVal3]) => {
-    if (newVal2) {
-      form.value.formValue2 = formatDate(newVal2);
-    }
-    if (newVal3) {
-      form.value.formValue3 = formatDate(newVal3);
-    }
-  }
-);
-
-onMounted(() => {
-  if(pageType == 'U') fnDetail();
-});
-</script>

+ 0 - 0
pages/view/event/evtAdd.vue → pages/view/item/evtAdd.vue


+ 0 - 0
pages/view/event/evtList.vue → pages/view/item/evtList.vue


+ 0 - 0
pages/view/event/evtListClosed.vue → pages/view/item/evtListClosed.vue


+ 0 - 0
pages/view/event/evtListOngoing.vue → pages/view/item/evtListOngoing.vue


+ 0 - 0
pages/view/event/evtListPending.vue → pages/view/item/evtListPending.vue


+ 0 - 1300
pages/view/login/index.vue

@@ -1,1300 +0,0 @@
-<template>
-  <div class="login-wrap">
-    <!-- header -->
-    <div class="login--header">
-      <div class="login--header--l">
-        <div class="logo">
-          <!-- prettier-ignore  -->
-          룰렛
-        </div>
-      </div>
-      <div class="login--header--r"></div>
-    </div>
-    <!-- login -->
-    <div class="login-box">
-      <div class="login-l">
-        <div class="login-l-center">
-          <span class="logo">
-            <!-- prettier-ignore  -->
-            룰렛
-          </span>
-          <p>We Make Scalable Mobility Life</p>
-        </div>
-      </div>
-      <div class="login-r">
-        <div class="tit-login">
-          <strong>로그인</strong>
-        </div>
-        <div class="login-input-wrap">
-          <div
-            class="txt-field-box"
-            :class="!loginForm.validCheck.input.userId ? 'error' : ''"
-          >
-            <v-text-field
-              v-model="loginForm.userId"
-              placeholder="아이디를 입력해주세요"
-              class="custom-input"
-              @keyup.enter="loginAction(loginForm.userId, loginForm.passwd)"
-              @input="setInputField('main_userId')"
-            ></v-text-field>
-            <i class="ico"></i>
-          </div>
-          <div
-            class="txt-field-box"
-            :class="!loginForm.validCheck.input.passwd ? 'error' : ''"
-          >
-            <v-text-field
-              v-model="loginForm.passwd"
-              :type="visible ? 'text' : 'password'"
-              placeholder="비밀번호를 입력해주세요"
-              class="custom-input"
-              id="password"
-              @keyup.enter="loginAction(loginForm.userId, loginForm.passwd)"
-              @input="setInputField('main_passwd')"
-            ></v-text-field>
-            <i
-              class="ico-eye"
-              @click.stop="toggleVisibility"
-              :class="visible ? 'eye-on' : 'eye-off'"
-            ></i>
-            <i class="ico"></i>
-          </div>
-          <!-- <p class="error-txt" v-if="!loginForm.validCheck.inputErrorCheck">
-            {{ loginForm.validCheck.passwd }}
-          </p> -->
-        </div>
-
-        <div class="login-btn-wrap">
-          <v-btn
-            class="custom-btn btn-blue"
-            @keyup.enter="loginAction(loginForm.userId, loginForm.passwd)"
-            @click="loginAction(loginForm.userId, loginForm.passwd)"
-            >로그인</v-btn
-          >
-        </div>
-      </div>
-    </div>
-
-    <!-- footer -->
-    <div class="login-footer">
-      <div class="login--footer--l">
-        <p>COPYRIGHT@2018 룰렛 INC. ALL RIGHTS RESERVED.</p>
-        <p>마포구 합정동&nbsp; |&nbsp;TEL&nbsp;02-1234-5678</p>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script setup>
-  /************************
-   *    import
-   ************************/
-  import PrivacyPop from "@/components/login/privacyPop.vue";
-  import AgrNPop from "@/components/terms/agreeNListPop.vue";
-  import apiUrl from "@/composables/useApi";
-  import QRCode from "qrcode";
-  import { useI18n } from "vue-i18n";
-
-  /************************
-   *    layout setting
-   ************************/
-  definePageMeta({
-    layout: "loginlayout",
-  });
-
-  /************************
-   *    plugins inject
-   ************************/
-  const { $dayjs, $log, $eventBus, $toast, $userAgent } = useNuxtApp();
-
-  const useStore = useDetailStore();
-  /************************
-   *    data & created
-   ************************/
-  // 현재 입력 중인 필드를 설정하는 함수
-  const setInputField = (name) => {
-    fnValidCheck(name);
-  };
-  const pageId = "login";
-  const i18n = useI18n();
-  // 다국어
-  let listObj = ref({
-    langTypeList: {},
-  });
-  // 로그인 정보
-  const loginForm = ref({
-    userId: "",
-    passwd: "",
-    otpNum: "",
-    username: "",
-    authType: "GOOGLE",
-    userAgent: "",
-    validCheck: {
-      input: {
-        userId: true,
-        passwd: true,
-      },
-      otp: {
-        otpNum: true,
-      },
-      inputErrorCheck: true,
-      inputValidTxt: "",
-      otpValidTxt: "",
-      loginValidCheck: false,
-      btnTxt: "",
-      btnTxtType: "",
-    },
-  });
-  // 구글 OTP 1차 팝업
-  const authPop1 = ref({
-    popYn: false,
-    certifyYN: false,
-    userId: "",
-    passwd: "",
-    otpNum: "",
-    validOtpKey: true,
-    validOtpTxt: "",
-    btnTxt: "",
-    btnTxtType: "",
-    applyBtn: false,
-    succOtpYn: false,
-    businessName: "",
-    agreeChk1: false,
-    agreeChk2: false,
-    validCheck: {
-      userId: true,
-      passwd: true,
-    },
-    validTxt: "",
-    errorCheck: false,
-  });
-  // 구글 OTP 2차 팝업
-  const authPop2 = ref({
-    popYn: false,
-    otpNum: "",
-    validOtpKey: true,
-    validOtpTxt: "",
-    errorCheck: false,
-  });
-  // 아이디 찾기
-  const findId = ref({
-    popYn: false,
-    //tenantName: '',
-    email: "",
-    otpNum: "",
-    validCheck: {
-      input: {
-        //tenantName: true,
-        email: true,
-      },
-      otp: {
-        otpNum: true,
-      },
-      inputErrorCheck: true,
-      inputValidTxt: "",
-      otpValidTxt: "",
-      findIdValidCheck: false,
-    },
-    btnTxt: "",
-  });
-  // 비밀번호 초기화
-  const resetPw = ref({
-    popYn: false,
-    userId: "",
-    email: "",
-    otpNum: "",
-    validCheck: {
-      input: {
-        userId: true,
-        email: true,
-      },
-      otp: {
-        otpNum: true,
-      },
-      inputErrorCheck: true,
-      inputValidTxt: "",
-      otpValidTxt: "",
-      resetPwValidCheck: false,
-    },
-    btnTxt: "",
-  });
-  // 초기 패스워드 변경
-  const initPw = ref({
-    popYn: false,
-    passwd: "",
-    passwd2: "",
-    validCheck: {
-      passwd: true,
-      passwd2: true,
-    },
-    passwdCheck: false,
-    errorTxt: "",
-  });
-
-  const selectPlaceholder = ref("");
-  const initAuthPop1 = ref({});
-  const initAuthPop2 = ref({});
-  const initFindId = ref({});
-  const initResetPw = ref({});
-  const initInitPw = ref({});
-  const googleOtpQrCode = ref("");
-  const googleOtpSecretKey = ref("");
-  const loginInfo = ref({});
-  const checkbox = ref(false);
-  const langType = ref("");
-  const toggleVisibility = () => {
-    visible.value = !visible.value;
-  };
-  const visible = ref(false);
-  const isAgrNPop = ref(false);
-  const isShowAgrNPop = ref(false);
-  let saveId = localStorage.getItem("saveId");
-  if (saveId) {
-    checkbox.value = true;
-    loginForm.value.userId = saveId;
-  }
-
-  // 개인정보처리방침 이용약관 팝업
-  const privacyPop = ref(false);
-  const privacyDetail = ref({
-    kr: {
-      title: "",
-      contents: "",
-    },
-    en: {
-      title: "",
-      contents: "",
-    },
-  });
-  const systemInfo = ref({
-    mode: "",
-  });
-
-  const loginAction = (__ID, __PASS) => {
-    let _req = {
-      id: __ID,
-      password: __PASS,
-    };
-
-    useAxios()
-      .post("/roulette/login", _req)
-      .then((res) => {
-        if (res.data) {
-          useAuthStore().setAccessToken(res.data.accessToken);
-          useAuthStore().setRefreshToken(res.data.refreshToken);
-          localStorage.setItem("tempAccess", __ID);
-          useUtil.setPageMove("/view/event/evtList");
-          useStore.menuInfo.menuIndex = "0";
-          useStore.menuInfo.menuId = "menu02";
-          useStore.menuInfo.pageRtName = "이벤트 관리";
-          useStore.menuInfo.pageStatus = null;
-        }
-      })
-      .catch((error) => {
-        console.log(error.status);
-        if (error.status) {
-          fnLoginSet("아이디 또는 패스워드가 잘못됐습니다. 관리자에게 문의바랍니다.");
-        }
-
-        $log.debug("[login][fnIdPwCheck][error]");
-      })
-      .finally(() => {
-        $log.debug("[login][fnIdPwCheck][finished]");
-      });
-  };
-
-  // onMounted
-  onMounted(() => {
-    loginForm.value.userAgent = $userAgent;
-    if (loginForm.value.authType === "GOOGLE") {
-      selectPlaceholder.value = i18n.t("login.googleOTPNum");
-    } else if (loginForm.value.authType === "EMAIL") {
-      selectPlaceholder.value = i18n.t("login.emailAuthNum");
-    } else {
-      selectPlaceholder.value = i18n.t("login.smsAuthNum");
-    }
-
-    let saveId = localStorage.getItem("saveId");
-    if (saveId) {
-      checkbox.value = true;
-      loginForm.value.username = saveId;
-    }
-  });
-
-  watchEffect(() => {
-    // 감시하고자 하는 데이터를 해당 블럭내에서 사용하면 호출된다.
-    // getLang.value를 감시하는 상태
-    fnGetEnumCode(useLangStore().getLang);
-  });
-
-  $eventBus.off("SET_SUCCESS_POPUP");
-  $eventBus.on("SET_SUCCESS_POPUP", () => {
-    // 안내 팝업 확인 클릭 팝업 초기화처리
-    fnOtpPopClose("findId");
-    fnOtpPopClose("resetPw");
-  });
-
-  $eventBus.off("PASSWD_CHANGE");
-  $eventBus.on("PASSWD_CHANGE", () => {
-    fnPasswdChange();
-  });
-
-  $eventBus.off("INIT_PASSWORD");
-  $eventBus.on("INIT_PASSWORD", () => {
-    initPw.value.popYn = true;
-  });
-
-  $eventBus.off("SET_LOGIN");
-  $eventBus.on("SET_LOGIN", () => {
-    fnLogin();
-  });
-  /************************
-   *    Methods
-   ************************/
-  // created
-  loginForm.value.btnTxtType = "S";
-  authPop1.value.btnTxtType = "S";
-  loginForm.value.btnTxt = i18n.t("login.authNumSend");
-  authPop1.value.btnTxt = i18n.t("common.sendAuthNumber");
-  findId.value.btnTxt = i18n.t("common.sendAuthNumber");
-  resetPw.value.btnTxt = i18n.t("common.sendAuthNumber");
-
-  initAuthPop1.value = _cloneDeep(authPop1.value);
-  initAuthPop2.value = _cloneDeep(authPop2.value);
-  initFindId.value = _cloneDeep(findId.value);
-  initResetPw.value = _cloneDeep(resetPw.value);
-  initInitPw.value = _cloneDeep(initPw.value);
-
-  /**
-   * @SCRIPT
-   * 다국어 기능 | 한글 영문 변경 이벤트
-   */
-  function fnLangChange() {
-    useLangStore().setLang(langType.value);
-  }
-
-  function fnGetEnumCode(lang) {
-    lang = useUtil.nvl(lang, "kr");
-    langType.value = lang;
-    let objEnum = useEnumCode.getEnumCode(lang);
-    listObj.value.langTypeList = objEnum.langType;
-    i18n.locale.value = lang;
-  }
-
-  /**
-   * @SCRIPT
-   * 라디오버튼 변경 이벤트 (버튼별 문구)
-   */
-  function fnChangeAuth() {
-    if (loginForm.value.authType === "GOOGLE") {
-      selectPlaceholder.value = i18n.t("login.googleOTPNum");
-    } else if (loginForm.value.authType === "EMAIL") {
-      selectPlaceholder.value = i18n.t("login.emailAuthNum");
-    } else {
-      selectPlaceholder.value = i18n.t("login.smsAuthNum");
-    }
-    loginForm.value.btnTxt = i18n.t("login.authNumSend");
-    loginForm.value.btnTxtType = "S";
-
-    if (!loginForm.value.validCheck.otp.otpNum) {
-      fnValidCheck("main_otpNum");
-    }
-  }
-
-  /**
-   * @SCRIPT
-   * 구글OTP 인증 버튼 클릭 이벤트
-   * @param {*} type
-   */
-  function fnAuthCheck(type) {
-    let issuer = ""; // 회사명
-    let account = ""; // 아이디
-    let otpUrl = ""; // 큐알코드 생성 URL
-    let _req = {
-      username: authPop1.value.userId,
-      password: btoa(authPop1.value.passwd),
-      mfaType: "SMS",
-      otpNum: authPop1.value.otpNum,
-    };
-
-    if (type === "optApply1") {
-      fnValidCheck("createOtp_userId");
-      fnValidCheck("createOtp_passwd");
-      if (authPop1.value.errorCheck) {
-        fnAuth("POPUP");
-      }
-    } else if (type === "optApply2") {
-      //OTP 인증 팝업2
-      useAxios()
-        .post(apiUrl.googleSecretKey, _req)
-        .then((res) => {
-          googleOtpSecretKey.value = res.data.data.secretKey;
-          // 시크릿 키를 이용한 큐알코드 생성
-          issuer = "[P5G]" + authPop1.value.businessName;
-          account = authPop1.value.userId;
-          otpUrl =
-            "otpauth://totp/" +
-            encodeURIComponent(issuer + ":" + account).replace(/\+/g, "%20") +
-            "?secret=" +
-            encodeURIComponent(googleOtpSecretKey.value).replace(/\+/g, "%20") +
-            "&issuer=" +
-            encodeURIComponent(issuer).replace(/\+/g, "%20");
-          fnCreateQrCode(otpUrl);
-
-          $toast.success("인증처리가 완료되었습니다.");
-          authPop1.value.applyBtn = false;
-          authPop1.value.agreeChk1 = true;
-          authPop1.value.succOtpYn = true;
-          $log.debug("[login][fnAuthCheck][success]");
-        })
-        .catch((error) => {
-          $log.debug("[login][fnAuthCheck][error]");
-          let errorData = error.response.data;
-          errorData.type = "fnAuthCheck";
-          fnLoginFail(errorData);
-        })
-        .finally(() => {
-          $log.debug("[login][fnAuthCheck][finished]");
-        });
-    } else if (type === "optApply2Yn") {
-      authPop1.value.popYn = false;
-      authPop2.value.popYn = true;
-    } else if (type === "findId") {
-      //fnValidCheck('findId_tenantName')
-      fnValidCheck("findId_email");
-      if (findId.value.validCheck.inputErrorCheck) {
-        fnIdPwCheck(type);
-      }
-    } else if (type === "resetPw") {
-      fnValidCheck("resetPw_userId");
-      fnValidCheck("resetPw_email");
-      if (resetPw.value.validCheck.inputErrorCheck) {
-        fnIdPwCheck(type);
-      }
-    } else if (type === "createOtp_otpNum") {
-      // 구글OTP등록화면에서 인증번호 받기
-      fnAuthSend(authPop1.value.btnTxtType, "createOtp_otpNum");
-    } else {
-      fnValidCheck("main_userId");
-      fnValidCheck("main_passwd");
-      if (loginForm.value.validCheck.inputErrorCheck) {
-        fnAuth(type);
-      }
-    }
-  }
-
-  /**
-   * @SCRIPT
-   * 큐알코드 생성
-   * @param {*} otpUrl
-   */
-  async function fnCreateQrCode(otpUrl) {
-    googleOtpQrCode.value = await QRCode.toDataURL(otpUrl);
-  }
-
-  /**
-   * @SCRIPT
-   * 로그인 실패관련 토스트 & confirm 처리
-   */
-  function fnLoginFail(dataObj) {
-    let errorMessage = "";
-    let type = dataObj.type;
-    if (dataObj.code === "2001" || dataObj.code === "2002") {
-      let valieTxt = "";
-      if (!useUtil.isNull(dataObj.reason)) {
-        if (dataObj.reason < "4") {
-          valieTxt += i18n.t("login.valid.isNullPw");
-        } else {
-          // 4회 이상 비밀번호 실패
-          fnLoginFailConfirm(dataObj);
-        }
-      } else {
-        valieTxt += i18n.t("login.valid.isNullId");
-      }
-      console.log("비밀번호 초기화 팝업:::" + resetPw.value.popYn);
-      console.log("아이디찾기 팝업:::" + findId.value.popYn);
-      console.log("OTP생성 팝업:::" + authPop1.value.popYn);
-      if (resetPw.value.popYn) {
-        resetPw.value.validCheck.inputErrorCheck = false;
-        resetPw.value.validCheck.inputValidTxt = valieTxt;
-      } else if (findId.value.popYn) {
-        findId.value.validCheck.inputErrorCheck = false;
-        findId.value.validCheck.inputValidTxt = valieTxt;
-      } else if (authPop1.value.popYn) {
-        authPop1.value.errorCheck = false;
-        authPop1.value.validTxt = valieTxt;
-      } else {
-        loginForm.value.validCheck.inputErrorCheck = false;
-        loginForm.value.validCheck.inputValidTxt = valieTxt;
-      }
-    } else if (dataObj.code === "2003") {
-      let otpTxt = "";
-      if (loginForm.value.authType === "GOOGLE") {
-        otpTxt += i18n.t("login.valid.isNullOtp");
-      } else if (loginForm.value.authType === "EMAIL") {
-        otpTxt += i18n.t("login.valid.isNullEmail");
-      } else {
-        otpTxt += i18n.t("login.valid.isNullSms");
-      }
-      if (resetPw.value.popYn) {
-        resetPw.value.validCheck.otp.otpNum = false;
-        resetPw.value.validCheck.otpValidTxt = i18n.t("login.valid.isNullEmail");
-      } else if (findId.value.popYn) {
-        findId.value.validCheck.otp.otpNum = false;
-        findId.value.validCheck.otpValidTxt = i18n.t("login.valid.isNullEmail");
-      } else if (authPop1.value.popYn) {
-        authPop1.value.validOtpKey = false;
-        authPop1.value.validOtpTxt = i18n.t("login.valid.isNullSms");
-      } else {
-        loginForm.value.validCheck.otp.otpNum = false;
-        loginForm.value.validCheck.otpValidTxt = otpTxt;
-      }
-    } else if (
-      dataObj.code === "2004" ||
-      dataObj.code === "2005" ||
-      dataObj.code === "2006" ||
-      dataObj.code === "2007" ||
-      dataObj.code === "2010"
-    ) {
-      // 2004: 접속허용IP아님 , 2005: 사업자 접속불가 상태, 2006: 사업자 계약 만료, 2007: 접속 계정 수 초과, 2010: 계정 잠김 (비밀번호 틀림 N 회) 5회 이상 비밀번호 실패
-      fnLoginFailConfirm(dataObj);
-    }
-    if (!useUtil.isNull(errorMessage)) {
-      // 토스트 함수 (success, info, error, warn, dark)
-      if (type === "findId" || type === "resetPw")
-        errorMessage += i18n.t("login.failMessage.2001");
-      else errorMessage += i18n.t("login.valid.isNull");
-      nextTick().then(() => {
-        $toast.error(errorMessage);
-      });
-    }
-  }
-
-  /**
-   * @SCRIPT
-   * 로그인 실패관련 토스트 & confirm 처리
-   */
-  function fnLoginFailConfirm(dataObj) {
-    let confirmMessage = "";
-    if (dataObj.code === "2002") confirmMessage = i18n.t("login.failMessage.2002");
-    else if (dataObj.code === "2004") confirmMessage = i18n.t("login.failMessage.2004");
-    else if (dataObj.code === "2005") confirmMessage = i18n.t("login.failMessage.2005");
-    else if (dataObj.code === "2006") confirmMessage = i18n.t("login.failMessage.2006");
-    else if (dataObj.code === "2007") confirmMessage = i18n.t("login.failMessage.2007");
-    else if (dataObj.code === "2010") confirmMessage = i18n.t("login.failMessage.2010");
-
-    let param = {
-      id: pageId,
-      title: i18n.t("common.popTitle"),
-      content: confirmMessage,
-      yes: {
-        text: i18n.t("common.confirm"),
-        isProc: true,
-        event: "",
-        param: {},
-      },
-    };
-    $eventBus.emit("OPEN_CONFIRM_POP_UP", param);
-  }
-
-  /**
-   * @SCRIPT
-   * 아이디 저장 체크 이벤트
-   */
-  function fnSaveId() {
-    if (checkbox.value) {
-      // 체크 시 저장
-      localStorage.setItem("saveId", loginForm.value.userId);
-    } else {
-      // 미체크 시 삭제
-      localStorage.removeItem("saveId");
-    }
-  }
-
-  /**
-   * @API
-   * 아이디 찾기에서 사업자명 & 이메일 주소 체크 API
-   * 비밀번호 초기화에서 사용자계정 & 이메일 주소 체크 API
-   */
-  function fnIdPwCheck(type) {
-    let _req = {};
-    if (type === "findId") {
-      //_req.tenantName = findId.value.tenantName,
-      _req.email = findId.value.email;
-    } else {
-      (_req.accountId = resetPw.value.userId), (_req.email = resetPw.value.email);
-    }
-
-    useAxios()
-      .post(apiUrl.findCheck, _req)
-      .then((res) => {
-        if (type === "findId") {
-          findId.value.btnTxt = i18n.t("common.sendReAuthNumber");
-        } else {
-          resetPw.value.btnTxt = i18n.t("common.sendReAuthNumber");
-        }
-
-        $toast.success(i18n.t("login.sendEmail"));
-        $log.debug("[login][fnIdPwCheck][success]");
-      })
-      .catch((error) => {
-        let errorData = error.response.data;
-        errorData.type = type;
-        fnLoginFail(errorData);
-        $log.debug("[login][fnIdPwCheck][error]");
-      })
-      .finally(() => {
-        $log.debug("[login][fnIdPwCheck][finished]");
-      });
-  }
-
-  /**
-   * @API
-   * 가입된 아이디 비밀번호 체크 API
-   */
-  function fnAuth(type) {
-    let _req = {};
-
-    if (type === "POPUP") {
-      _req.username = authPop1.value.userId;
-      _req.password = btoa(authPop1.value.passwd);
-    } else {
-      _req.username = loginForm.value.userId;
-      _req.password = btoa(loginForm.value.passwd);
-    }
-    // 아이디&비밀번호 validation체크 정상일 경우 아이디 비밀번호를 체크 하는 API를 진행한다.
-    useAxios()
-      .post(apiUrl.idPwCheck, _req)
-      .then((res) => {
-        if (type === "GOOGLE") {
-          fnLogin();
-        } else if (type === "POPUP") {
-          // if(useUtil.isNull(res.data.data.tenantName)) {
-          //   authPop1.value.businessName = ''
-          // } else {
-          //   authPop1.value.businessName = res.data.data.tenantName
-          // }
-
-          // 아이디 비밀번호 입력 영역 비활성화
-          authPop1.value.certifyYN = true;
-          //authPop1.value.agreeChk1 = true
-        } else {
-          // 아이디&비밀번호가 존재하여 이메일 발송을 진행합니다.
-          fnAuthSend(loginForm.value.btnTxtType, "loginForm");
-        }
-        $log.debug("[login][fnAuth][success]");
-      })
-      .catch((error) => {
-        let errorData = error.response.data;
-        errorData.type = type;
-        fnLoginFail(errorData);
-        $log.debug("[login][fnAuth][error]");
-      })
-      .finally(() => {
-        $log.debug("[login][fnAuth][finished]");
-      });
-  }
-
-  /**
-   * @API
-   * 가입된 아이디 비밀번호 체크가 정상 일 경우 인증번호 발송
-   * 이메일(EMAIL) & 문자(SMS)
-   */
-  function fnAuthSend(type, form) {
-    let _req = {};
-    if (form === "loginForm") {
-      (_req.username = loginForm.value.userId),
-        (_req.password = btoa(loginForm.value.passwd)),
-        (_req.mfaType = loginForm.value.authType);
-    } else {
-      (_req.username = authPop1.value.userId),
-        (_req.password = btoa(authPop1.value.passwd)),
-        (_req.mfaType = "SMS");
-    }
-    useAxios()
-      .post(apiUrl.otpSend, _req)
-      .then((res) => {
-        if (form === "loginForm") {
-          loginForm.value.btnTxt = i18n.t("login.authNumReSend");
-          loginForm.value.btnTxtType = "R";
-        } else {
-          authPop1.value.btnTxt = i18n.t("login.authNumReSend");
-          authPop1.value.btnTxtType = "R";
-        }
-
-        if (type === "S") {
-          if (form === "loginForm") {
-            if (loginForm.value.authType === "EMAIL") {
-              $toast.success(i18n.t("login.sendEmail"));
-            } else {
-              $toast.success(i18n.t("login.sendSms"));
-            }
-          } else {
-            $toast.success(i18n.t("login.sendSms"));
-          }
-        } else {
-          if (form === "loginForm") {
-            if (loginForm.value.authType === "EMAIL") {
-              $toast.success(i18n.t("login.sendReEmail"));
-            } else {
-              $toast.success(i18n.t("login.sendReSms"));
-            }
-          } else {
-            $toast.success(i18n.t("login.sendReSms"));
-          }
-        }
-        $log.debug("[login][fnAuthSend][success]");
-      })
-      .catch((error) => {
-        $log.debug("[login][fnAuthSend][error]");
-        // 에러 메시지 체크 팝업으로 변경
-        let param = {
-          id: pageId,
-          title: i18n.t("common.popTitle"),
-          content: i18n.t("login.sendFail"),
-          yes: {
-            text: i18n.t("common.confirm"),
-            isProc: true,
-            event: "",
-            param: {},
-          },
-        };
-        $eventBus.emit("OPEN_CONFIRM_POP_UP", param);
-        // let errorMessage = i18n.t('login.sendFail')
-        // errorMessage += error.response.data.message
-        // $toast.error(errorMessage)
-      })
-      .finally(() => {
-        $log.debug("[login][fnAuthSend][finished]");
-      });
-  }
-
-  const fnLoginSet = (__MSG) => {
-    let param = {
-      id: pageId,
-      title: "로그인",
-      content: __MSG,
-      yes: {
-        text: "확인",
-        isProc: true,
-        event: "FN_LOGIN",
-        param: "",
-      },
-      no: {
-        text: "취소",
-        isProc: false,
-      },
-    };
-    $eventBus.emit("OPEN_CONFIRM_POP_UP", param);
-  };
-  /**
-   * @API
-   * 최종 로그인 버튼 클릭 시 API
-   */
-  function fnLogin(__USERID, __USERPASS) {
-    // 파라미터 전달 값 [아이디, 비밀번호, otpNum, 브라우저정보]
-    //userId: loginForm.value.userId,
-    // let _req = {
-    //   username: loginForm.value.userId,
-    //   password: btoa(loginForm.value.passwd),
-    // };
-
-    localStorage.setItem("tempAccess", __USERID);
-
-    if (__USERID == "admin" && __USERPASS == "1234") {
-      useUtil.setPageMove("/view/media/newsList");
-    } else {
-      fnLoginSet("비밀번호가 맞지 않습니다. 확인해주세요.");
-    }
-    // useAxios()
-    //   .post(apiUrl.otpCheck, _req)
-    //   .then((res) => {
-    //     loginInfo.value = res.data.data;
-    //     useAuthStore().setAccessToken(loginInfo.value.accessToken);
-    //     useAuthStore().setRefreshToken(loginInfo.value.refreshToken);
-
-    //     // OTP key체크 성공 후 개인정보에 대한 API를 호출 한다.
-    //     fnServiceModeCheck();
-    //     $log.debug("[login][fnLogin][success]");
-    //   })
-    //   .catch((error) => {
-    //     $log.debug("[login][fnLogin][error]");
-    //     let errorData = error.response.data;
-    //     errorData.type = "fnLogin";
-    //     fnLoginFail(errorData);
-    //   })
-    //   .finally(() => {
-    //     $log.debug("[login][fnLogin][finished]");
-    //   });
-  }
-
-  /**
-   * @API
-   * 최종 로그인 전 점검공지에 대한 정보를 가져온다.
-   */
-  function fnServiceModeCheck() {
-    useAxios()
-      .get(useApi.getServiceMode)
-      .then((res) => {
-        $log.debug("[login][fnServiceModeCheck][success]");
-        let data = res.data.data;
-        systemInfo.value.mode = data.mode;
-        fnMyInfo();
-      })
-      .catch((error) => {
-        $log.debug("[login][fnServiceModeCheck][error]");
-        useErrorHandler().fnSetCommErrorHandle(error);
-      })
-      .finally(() => {
-        $log.debug("[login][fnServiceModeCheck][finished]");
-      });
-  }
-  /**
-   * @API
-   * 최종 로그인 버튼 클릭 후 성공 시 토큰값을 통해 개인정보 API 호출
-   */
-  function fnMyInfo() {
-    useAxios()
-      .get(apiUrl.myInfo)
-      .then((res) => {
-        let dataObj = {};
-        dataObj = res.data.data;
-        dataObj.accessToken = useAuthStore().getAccessToken;
-        dataObj.refreshToken = useAuthStore().getRefreshToken;
-        useAuthStore().setServiceMode(systemInfo.value.mode);
-
-        useAuthStore().setAuth(dataObj);
-        // 아이디 저장 여부 체크
-        fnSaveId();
-        let accountValue = useAuthStore().getAccountRole.charAt(0).toUpperCase();
-        // 첫화면 redirect_page URL로 설정
-        // 초기 비밀번호 사용
-        if (useAuthStore().getFirstLoginYn === "Y") {
-          // 최초로그인
-          initPw.value.popYn = true;
-        } else if (useAuthStore().getPwExpiredYN === "Y") {
-          // 비밀번호 3개월 만료
-          let param = {
-            id: pageId,
-            title: i18n.t("common.popTitle"),
-            content: i18n.t("login.failMessage.2009"),
-            yes: {
-              text: i18n.t("common.confirm"),
-              isProc: true,
-              event: "INIT_PASSWORD", // 확인 클릭 시 비밀번호 변경 팝업 활성화
-              param: {},
-            },
-            no: {
-              text: i18n.t("common.skip"),
-              isProc: true,
-              event: "SET_LOGIN", // 건너뛰기 클릭 시 로그인 처리
-              param: {},
-            },
-          };
-          $eventBus.emit("OPEN_CONFIRM_POP_UP", param);
-        } else if (useAuthStore().getTermsArgYN === "N") {
-          // 필수약관동의여부
-          isShowAgrNPop.value = true;
-          nextTick().then(() => {
-            isAgrNPop.value = true;
-          });
-        } else {
-          if (systemInfo.value.mode === "INACTIVE") {
-            // 점검모드일 경우 점검모드 페이지로 이동
-            if (accountValue === "S") {
-              useUtil.setPageMove("/view/home/dashboard");
-            } else {
-              useUtil.setPageMove("/view/home/serviceMode");
-            }
-          } else {
-            if (accountValue === "A" || accountValue === "S") {
-              useUtil.setPageMove("/view/home/dashboard");
-            } else {
-              useUtil.setPageMove("/view/home/tenantDashboard");
-            }
-          }
-        }
-        $log.debug("[login][fnMyInfo][success]");
-      })
-      .catch((error) => {
-        $log.debug("[login][fnMyInfo][error]");
-        useErrorHandler().fnSetCommErrorHandle(error);
-      })
-      .finally(() => {
-        $log.debug("[login][fnMyInfo][finished]");
-      });
-  }
-
-  /**
-   * @API
-   * 최초 비밀번호 변경 API 호출
-   */
-  function fnPasswdChange() {
-    let _req = {
-      newPassword: btoa(initPw.value.passwd2),
-    };
-
-    useAxios()
-      .post(apiUrl.myInfoUpdate, _req)
-      .then((res) => {
-        localStorage.removeItem("authStore");
-        // 세션 초기화 및 로그인 화면 이동
-        useUtil.setPageMove("/");
-        $log.debug("[login][fnPasswdChange][success]");
-      })
-      .catch((error) => {
-        $log.debug("[login][fnPasswdChange][error]");
-        let errorData = error.response.data;
-        errorData.type = "fnPasswdChange";
-        fnLoginFail(errorData);
-      })
-      .finally(() => {
-        $log.debug("[login][fnPasswdChange][finished]");
-      });
-  }
-
-  /**
-   * @API
-   * 로그인 FOOTER 약관 조회 API
-   */
-  function fnPrivacy(type) {
-    let _req = {
-      termsType: useUtil.nvl(type, null),
-    };
-    useAxios()
-      .get(apiUrl.loginTerms, { params: _req })
-      .then((res) => {
-        let dataObj = res.data.data;
-        privacyDetail.value.kr.title = dataObj.termsTitle;
-        privacyDetail.value.kr.contents = dataObj.termsCont;
-
-        privacyDetail.value.en.title = dataObj.termsTitleEn;
-        privacyDetail.value.en.contents = dataObj.termsContEn;
-        privacyPop.value = true;
-      })
-      .catch((error) => {
-        $log.debug("[login][fnPrivacy][error]");
-        useErrorHandler().fnSetCommErrorHandle(error, fnPrivacy);
-      })
-      .finally(() => {
-        $log.debug("[login][fnPrivacy][finished]");
-      });
-  }
-  /**
-   * @SCRIPT
-   * 아이디 & 비밀번호 & otp 값의 유효성 검사 체크 및 로그인 버튼 활성화 이벤트
-   */
-  function fnValidCheck(input) {
-    if (_includes(input, "main_")) {
-      let commonValidCheck = {
-        inputCheck: false,
-        otpCheck: false,
-      };
-      if (input === "main_userId") {
-        if (
-          useUtil.isNull(loginForm.value.userId) ||
-          !/^[a-zA-Z0-9._-]{1,20}$/.test(loginForm.value.userId)
-        ) {
-          loginForm.value.validCheck.input.userId = false;
-          loginForm.value.validCheck.inputValidTxt = i18n.t("login.valid.isNull");
-        } else {
-          loginForm.value.validCheck.input.userId = true;
-          if (!useUtil.isNull(loginForm.value.passwd)) {
-            fnValidCheck("main_passwd");
-          }
-        }
-      } else if (input === "main_passwd") {
-        if (
-          useUtil.isNull(loginForm.value.passwd) ||
-          !/^(?=.*[a-zA-Z])(?=.*[!@#$%^*+=-])(?=.*[0-9]).{8,30}$/i.test(
-            loginForm.value.passwd
-          )
-        ) {
-          //if(useUtil.isNull(loginForm.value.passwd)) {
-          loginForm.value.validCheck.input.passwd = false;
-          loginForm.value.validCheck.inputValidTxt = i18n.t("login.valid.isNull");
-        } else {
-          loginForm.value.validCheck.input.passwd = true;
-        }
-      } else if (input === "main_otpNum") {
-        loginForm.value.otpNum = useValid.p5gNumCheck(loginForm.value.otpNum, "otp");
-
-        if (
-          useUtil.isNull(loginForm.value.otpNum) ||
-          loginForm.value.otpNum.length <= 5
-        ) {
-          loginForm.value.validCheck.otp.otpNum = false;
-          if (loginForm.value.authType === "GOOGLE") {
-            loginForm.value.validCheck.otpValidTxt = i18n.t("login.valid.isNullOtp");
-          } else if (loginForm.value.authType === "EMAIL") {
-            loginForm.value.validCheck.otpValidTxt = i18n.t("login.valid.isNullEmail");
-          } else {
-            loginForm.value.validCheck.otpValidTxt = i18n.t("login.valid.isNullSms");
-          }
-        } else {
-          loginForm.value.validCheck.otp.otpNum = true;
-        }
-      }
-      loginForm.value.validCheck.inputErrorCheck = _every(
-        loginForm.value.validCheck.input,
-        (value) => value === true
-      );
-      // 전체 항목에 대한 validation이 정상일 경우 login버튼 활성화
-      if (
-        !useUtil.isNull(loginForm.value.userId) &&
-        !useUtil.isNull(loginForm.value.passwd) &&
-        !useUtil.isNull(loginForm.value.otpNum)
-      ) {
-        commonValidCheck.inputCheck = _every(
-          loginForm.value.validCheck.input,
-          (value) => value === true
-        );
-        commonValidCheck.otpCheck = _every(
-          loginForm.value.validCheck.otp,
-          (value) => value === true
-        );
-      }
-      loginForm.value.validCheck.loginValidCheck = _every(
-        commonValidCheck,
-        (value) => value === true
-      );
-    } else if (_includes(input, "createOtp_")) {
-      if (input === "createOtp_userId") {
-        if (
-          useUtil.isNull(authPop1.value.userId) ||
-          !/^[a-zA-Z0-9._-]{1,20}$/.test(authPop1.value.userId)
-        ) {
-          authPop1.value.validCheck.userId = false;
-          authPop1.value.validTxt = i18n.t("login.valid.isNull");
-        } else {
-          authPop1.value.validCheck.userId = true;
-          if (!useUtil.isNull(authPop1.value.passwd)) {
-            fnValidCheck("createOtp_passwd");
-          }
-        }
-      } else if (input === "createOtp_passwd") {
-        if (
-          useUtil.isNull(authPop1.value.passwd) ||
-          !/^(?=.*[a-zA-Z])(?=.*[!@#$%^*+=-])(?=.*[0-9]).{8,30}$/i.test(
-            authPop1.value.passwd
-          )
-        ) {
-          //if(useUtil.isNull(authPop1.value.passwd)) {
-          authPop1.value.validCheck.passwd = false;
-          authPop1.value.validTxt = i18n.t("login.valid.isNull");
-        } else {
-          authPop1.value.validCheck.passwd = true;
-        }
-      } else if (input === "createOtp_otpNum1") {
-        authPop1.value.otpNum = useValid.p5gNumCheck(authPop1.value.otpNum, "otp");
-        if (useUtil.isNull(authPop1.value.otpNum) || authPop1.value.otpNum.length <= 5) {
-          authPop1.value.validOtpKey = false;
-          authPop1.value.errorCheck = false;
-          authPop1.value.validOtpTxt = i18n.t("login.valid.isNullSms");
-        } else {
-          authPop1.value.validOtpKey = true;
-          authPop1.value.errorCheck = true;
-          authPop1.value.applyBtn = true;
-        }
-      } else if (input === "createOtp_otpNum") {
-        authPop2.value.otpNum = useValid.p5gNumCheck(authPop2.value.otpNum, "otp");
-
-        if (useUtil.isNull(authPop2.value.otpNum) || authPop2.value.otpNum.length <= 5) {
-          authPop2.value.validOtpKey = false;
-          authPop2.value.errorCheck = false;
-          if (loginForm.value.authType === "GOOGLE") {
-            authPop2.value.validOtpTxt = i18n.t("login.valid.isNullOtp");
-          } else if (loginForm.value.authType === "EMAIL") {
-            authPop2.value.validOtpTxt = i18n.t("login.valid.isNullEmail");
-          } else {
-            authPop2.value.validOtpTxt = i18n.t("login.valid.isNullSms");
-          }
-        } else {
-          authPop2.value.validOtpKey = true;
-          authPop2.value.errorCheck = true;
-        }
-      }
-      authPop1.value.errorCheck = _every(
-        authPop1.value.validCheck,
-        (value) => value === true
-      );
-    } else if (_includes(input, "findId_")) {
-      let validAllCheck = {
-        inputCheck: false,
-        otpCheck: false,
-      };
-      // if(input === 'findId_tenantName') {
-      //   if(useUtil.isNull(findId.value.tenantName)) {
-      //     findId.value.validCheck.input.tenantName = false
-      //     findId.value.validCheck.inputValidTxt = i18n.t('login.findId.valid.isNullTenantName')
-      //   } else {
-      //     findId.value.validCheck.input.tenantName = true
-      //     if(!useUtil.isNull(findId.value.email)) {
-      //       fnValidCheck('findId_email')
-      //     }
-      //   }
-      // } else
-      if (input === "findId_email") {
-        if (useUtil.isNull(findId.value.email)) {
-          findId.value.validCheck.input.email = false;
-          findId.value.validCheck.inputValidTxt = i18n.t(
-            "login.findId.valid.isNullEmail"
-          );
-        } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(findId.value.email)) {
-          findId.value.validCheck.input.email = false;
-          findId.value.validCheck.inputValidTxt = i18n.t(
-            "login.findId.valid.isTypeEmail"
-          );
-        } else {
-          findId.value.validCheck.input.email = true;
-        }
-      } else if (input === "findId_otpNum") {
-        findId.value.otpNum = useValid.p5gNumCheck(findId.value.otpNum, "otp");
-
-        if (useUtil.isNull(findId.value.otpNum) || findId.value.otpNum.length <= 5) {
-          findId.value.validCheck.otp.otpNum = false;
-          findId.value.validCheck.otpValidTxt = i18n.t("login.findId.valid.isNullOtp");
-        } else {
-          findId.value.validCheck.otp.otpNum = true;
-        }
-      }
-      // tenantName & email validation check
-      findId.value.validCheck.inputErrorCheck = _every(
-        findId.value.validCheck.input,
-        (value) => value === true
-      );
-      //!useUtil.isNull(findId.value.tenantName) &&
-      if (!useUtil.isNull(findId.value.email) && !useUtil.isNull(findId.value.otpNum)) {
-        validAllCheck.inputCheck = findId.value.validCheck.inputErrorCheck;
-        validAllCheck.otpCheck = findId.value.validCheck.otp.otpNum;
-      }
-      findId.value.validCheck.findIdValidCheck = _every(
-        validAllCheck,
-        (value) => value === true
-      );
-    } else if (_includes(input, "resetPw_")) {
-      let validAllCheck = {
-        inputCheck: false,
-        otpCheck: false,
-      };
-
-      if (input === "resetPw_userId") {
-        if (useUtil.isNull(resetPw.value.userId)) {
-          resetPw.value.validCheck.input.userId = false;
-          resetPw.value.validCheck.inputValidTxt = i18n.t(
-            "login.resetPasswd.valid.isNullUserId"
-          );
-        } else {
-          resetPw.value.validCheck.input.userId = true;
-          if (!useUtil.isNull(resetPw.value.email)) {
-            fnValidCheck("resetPw_email");
-          }
-        }
-      } else if (input === "resetPw_email") {
-        if (useUtil.isNull(resetPw.value.email)) {
-          resetPw.value.validCheck.input.email = false;
-          resetPw.value.validCheck.inputValidTxt = i18n.t(
-            "login.resetPasswd.valid.isNullEmail"
-          );
-        } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(resetPw.value.email)) {
-          resetPw.value.validCheck.input.email = false;
-          resetPw.value.validCheck.inputValidTxt = i18n.t(
-            "login.resetPasswd.valid.isTypeEmail"
-          );
-        } else {
-          resetPw.value.validCheck.input.email = true;
-        }
-      } else if (input === "resetPw_otpNum") {
-        resetPw.value.otpNum = useValid.p5gNumCheck(resetPw.value.otpNum, "otp");
-
-        if (useUtil.isNull(resetPw.value.otpNum) || resetPw.value.otpNum.length <= 5) {
-          resetPw.value.validCheck.otp.otpNum = false;
-          resetPw.value.validCheck.otpValidTxt = i18n.t(
-            "login.resetPasswd.valid.isNullOtp"
-          );
-        } else {
-          resetPw.value.validCheck.otp.otpNum = true;
-        }
-      }
-      // tenantName & email validation check
-      resetPw.value.validCheck.inputErrorCheck = _every(
-        resetPw.value.validCheck.input,
-        (value) => value === true
-      );
-
-      if (
-        !useUtil.isNull(resetPw.value.userId) &&
-        !useUtil.isNull(resetPw.value.email) &&
-        !useUtil.isNull(resetPw.value.otpNum)
-      ) {
-        validAllCheck.inputCheck = resetPw.value.validCheck.inputErrorCheck;
-        validAllCheck.otpCheck = resetPw.value.validCheck.otp.otpNum;
-      }
-      resetPw.value.validCheck.resetPwValidCheck = _every(
-        validAllCheck,
-        (value) => value === true
-      );
-    } else {
-      if (input === "initPw_passwd") {
-        let digits1 = useAuthStore().getAuth.phoneNumber.replace(/\D/g, "");
-        let digits2 = initPw.value.passwd.replace(/\D/g, "");
-        let lastEightDigits1 = digits1.slice(-8);
-        let lastEightDigits2 = digits2.slice(-8);
-
-        if (useUtil.isNull(initPw.value.passwd)) {
-          initPw.value.validCheck.passwd = false;
-          initPw.value.errorTxt = i18n.t("login.valid.isNullNewPassword");
-        } else if (_includes(initPw.value.passwd, useAuthStore().getAuth.accountId)) {
-          // 아이디는 비밀번호로 사용할 수 없습니다.
-          initPw.value.validCheck.passwd = false;
-          initPw.value.errorTxt = i18n.t(
-            "common.header.myInfoUpdateModal.valid.includeId"
-          );
-        } else if (lastEightDigits1 === lastEightDigits2) {
-          // 연락처와 유사한 비밀번호는 사용할 수 없습니다.
-          initPw.value.validCheck.passwd = false;
-          initPw.value.errorTxt = i18n.t(
-            "common.header.myInfoUpdateModal.valid.includePhone"
-          );
-        } else if (/(.)\1{2,}/.test(initPw.value.passwd)) {
-          // 3자리 이상 연속 숫자, 문자는 사용 불가합니다.
-          initPw.value.validCheck.passwd = false;
-          initPw.value.errorTxt = i18n.t(
-            "common.header.myInfoUpdateModal.valid.continuousUse"
-          );
-        } else if (
-          !/^(?=.*[a-zA-Z])(?=.*[!@#$%^*+=-])(?=.*[0-9]).{8,30}$/i.test(
-            initPw.value.passwd
-          )
-        ) {
-          // 비밀번호는 문자,숫자,특수문자 조합 8~30자리로입력
-          initPw.value.validCheck.passwd = false;
-          initPw.value.errorTxt = i18n.t(
-            "common.header.myInfoUpdateModal.valid.validPassword"
-          );
-        } else {
-          initPw.value.validCheck.passwd = true;
-          if (!useUtil.isNull(initPw.value.passwd2)) {
-            fnValidCheck("initPw_passwd2");
-          }
-        }
-      } else {
-        if (initPw.value.passwd != initPw.value.passwd2) {
-          // 신규비밀번호가 일치 하지 않습니다.
-          initPw.value.validCheck.passwd2 = false;
-          initPw.value.errorTxt = i18n.t(
-            "common.header.myInfoUpdateModal.valid.missmatchPassword"
-          );
-        } else {
-          initPw.value.validCheck.passwd2 = true;
-        }
-      }
-      if (!useUtil.isNull(initPw.value.passwd) && !useUtil.isNull(initPw.value.passwd2)) {
-        initPw.value.passwdCheck = _every(
-          initPw.value.validCheck,
-          (value) => value === true
-        );
-      }
-    }
-  }
-</script>