Prechádzať zdrojové kódy

제품관리 - 리스트/등록/조회/삭제/수정/검색 완료 - 추후 인플루언서/벤더 권한별 처리 필요

DESKTOP-T61HUSC\user 4 mesiacov pred
rodič
commit
22bc1e7c5f

+ 20 - 4
assets/scss/default.scss

@@ -162,6 +162,10 @@
       }
 
       .item--list--wrap{
+        .no--data{
+          padding-top: 80px;
+          text-align: center;
+        }
         .item--list{
           display: flex;
           gap: 20px;
@@ -172,15 +176,24 @@
             border-radius: 20px;
             border: 1px solid #cccccc;
             padding: 1rem 1rem 2rem 1rem;
-            .item--img{
+            .item--img {
               width: 100%;
               height: 10rem;
-              background-repeat: no-repeat;
-              background-size: 100%;
-              background-position: center;
               background-color: #eee;
               border-radius: 20px;
               margin-bottom: 1.2rem;
+              overflow: hidden;
+              position: relative;
+
+              img {
+                width: 100%;
+                height: 100%;
+                object-fit: cover;
+                object-position: center;
+                position: absolute;
+                top: 0;
+                left: 0;
+              }
             }
             >h3{
               color: #444444;
@@ -251,6 +264,9 @@
             min-width: 50px;
             border: 1px solid #DDD;
             background: #FFF;
+            &.v-btn--disabled{
+              opacity: 0.5;
+            }
             .v-btn__content{
               color: #909090;
               font-size: 16px;

+ 12 - 4
assets/scss/mode-w-m.scss

@@ -36,6 +36,7 @@
       .pro--img{
         width: 96px;
         height: 96px;
+        background-image: url(../img/pf_sample.svg);
         border-radius: 50%;
         background-position: center;
         background-repeat: no-repeat;
@@ -6519,9 +6520,7 @@ z
     width: 100%;
     border-top: 1px solid #3F3F3F;
     .custom-input{
-      *{
-        text-align: center;
-      }
+      
       &.left{
         *{
           text-align: left;
@@ -6558,7 +6557,7 @@ z
     td{
       height: 50px;
       padding: 10px 30px;
-      text-align: center;
+      text-align: left;
       color: #000000;
       vertical-align: middle;
       border-bottom: 1px solid #e2e2e2;
@@ -6578,6 +6577,10 @@ z
             color: #444;
             font-weight: 400;
           }
+          .down--file{
+            color: #444;
+            cursor: pointer;
+          }
       }
       &.bg{
         background-color: #f8f8f8;
@@ -6682,4 +6685,9 @@ z
   .tbl-wrap .ag-checkbox-input-wrapper:after{
     display: none;
   }
+}
+
+.sun-editor{
+  width: 100%;
+  text-align: left;
 }

+ 1 - 1
assets/scss/style.scss

@@ -899,7 +899,7 @@
         height: 3.63rem;
         min-height: 3.63rem;
         padding: 0 1.25rem;
-        border: 0.06rem solid #E9E9E9;
+        border: 0.06rem solid #e0e0e0;
         background: #fff;
         border-radius: 0;
         color: #000;

+ 2 - 2
components/common/header.vue

@@ -1,7 +1,7 @@
 <template>
   <header class="new--header">
     <div class="pro--wrap">
-      <div class="pro--img" style="background-image: url(/assets/img/pf_sample.svg);"></div>
+      <div class="pro--img"></div>
       <div class="pro--id" @click="proOn ? (proOn = false) : (proOn = true)">
         {{ useStoreAuth.getSnsTempData.user.NICK_NAME }} <i class="ico" :class="[proOn ? 'on' : '']">></i>
         <div class="id--box" v-show="proOn">
@@ -62,7 +62,7 @@
         menuId: "menu01",
         parentMenuId: "menu01",
         menuName: "제품 관리",
-        linkType: "/view/item",
+        linkType: "/view/common/item",
       },
       {
         menuId: "menu02",

+ 2 - 2
package-lock.json

@@ -27,6 +27,7 @@
         "chartjs-plugin-datalabels": "^2.2.0",
         "chartjs-plugin-zoom": "^2.0.1",
         "copy-to-clipboard": "^3.3.3",
+        "dayjs": "^1.11.13",
         "hangul-js": "^0.2.6",
         "jodit": "^4.2.47",
         "js-sha256": "^0.11.0",
@@ -5847,8 +5848,7 @@
     "node_modules/dayjs": {
       "version": "1.11.13",
       "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz",
-      "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==",
-      "dev": true
+      "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="
     },
     "node_modules/dayjs-nuxt": {
       "version": "2.1.11",

+ 1 - 0
package.json

@@ -45,6 +45,7 @@
     "chartjs-plugin-datalabels": "^2.2.0",
     "chartjs-plugin-zoom": "^2.0.1",
     "copy-to-clipboard": "^3.3.3",
+    "dayjs": "^1.11.13",
     "hangul-js": "^0.2.6",
     "jodit": "^4.2.47",
     "js-sha256": "^0.11.0",

+ 2 - 2
pages/index.vue

@@ -373,7 +373,7 @@
           useAuthStore().setAccessToken(res.data.accessToken);
           useAuthStore().setRefreshToken(res.data.refreshToken);
           localStorage.setItem("tempAccess", __ID);
-          useUtil.setPageMove("/view/item");
+          useUtil.setPageMove("/view/common/item");
           useStore.menuInfo.menuIndex = "0";
           useStore.menuInfo.menuId = "menu01";
           useStore.menuInfo.pageRtName = "제품 관리";
@@ -468,7 +468,7 @@
           useAuthStore().setAccessToken(accessToken);
           useAuthStore().setRefreshToken(refreshToken);
           localStorage.setItem("tempAccess", result.user);
-          useUtil.setPageMove("/view/item");
+          useUtil.setPageMove("/view/common/item");
           useStore.menuInfo.menuIndex = "0";
           useStore.menuInfo.menuId = "menu02";
           useStore.menuInfo.pageRtName = "이벤트 관리";

+ 733 - 0
pages/view/common/item/add.vue

@@ -0,0 +1,733 @@
+<template>
+  <div>
+    <div class="inner--headers">
+      <h2>{{ pageId }}</h2>
+      <div class="bread--crumbs--wrap">
+        <span>홈</span>
+        <span>제품 관리</span>
+        <span>{{ pageId }}</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="pageType !== 'D'" class="bul">*</span></th>
+                <td v-if="pageType == 'D'">
+                  {{ form.formValue1 }}
+                </td>
+                <td v-else>
+                  <div class="input--wrap">
+                      <v-text-field
+                      maxlength="50"
+                      v-model="form.formValue1"
+                      :rules="[useValid.required('제품명')]"
+                      class="custom-input mini left"
+                      placeholder="제품명을 입력하세요"
+                    ></v-text-field>
+                  </div>
+                </td>
+              </tr>
+              <tr>
+                <th class="bg le">공급가<span v-if="pageType !== 'D'" class="bul">*</span></th>
+                  <td v-if="pageType == 'D'">
+                    {{ form.formValue2 }}
+                  </td>
+                  <td v-else>
+                  <div class="input--wrap">
+                      <v-text-field
+                      maxlength="50"
+                      v-model="form.formValue2"
+                      style="width: 20%"
+                      :rules="[useValid.required('공급가')]"
+                      class="custom-input mini left"
+                      placeholder="공급가를 입력하세요"
+                    ></v-text-field>
+                  </div>
+                </td>
+              </tr>
+              <tr>
+                <th class="bg le">판매가<span v-if="pageType !== 'D'" class="bul">*</span></th>
+                <td v-if="pageType == 'D'">
+                  {{ form.formValue3 }}
+                </td>
+                <td v-else>
+                  <div class="input--wrap">
+                      <v-text-field
+                      maxlength="50"
+                      v-model="form.formValue3"
+                      style="width: 20%"
+                      :rules="[useValid.required('판매가')]"
+                      class="custom-input mini left"
+                      placeholder="판매가를 입력하세요"
+                    ></v-text-field>
+                  </div>
+                </td>
+              </tr>
+              <tr>
+                <th class="bg le">배송비<span v-if="pageType !== 'D'" class="bul">*</span></th>
+                <td v-if="pageType == 'D'">
+                  {{ form.formValue4 }}
+                </td>
+                <td v-else>
+                  <div class="input--wrap">
+                    <v-textarea
+                    v-model="form.formValue4"
+                    class="custom-textarea"
+                    no-resize=""
+                    placeholder="배송비를 입력해주세요"
+                    :rules="[useValid.required('배송비')]"
+                    ></v-textarea>
+                  </div>
+                </td>
+              </tr>
+              <tr>
+                <th class="bg le">썸네일 이미지</th>
+                <td>
+                  <div class="equip--image--wrap">
+                    <!--이미지가 없을 때-->
+                    <div class="equip--image" v-show="!form.formValue5">
+                      <img src="/assets/img/ic_no_img.svg" />
+                    </div>
+                    <!--이미지 첨부했을 때-->
+                    <div class="equip--image" v-show="form.formValue5">
+                      <div class="images-wrapper">
+                        <img id="preview_image" :src="imgTemp" />
+                      </div>
+                    </div>
+                    <div class="equip--image--select" v-if="pageType !== 'D'">
+                      <div class="form--group">
+                        <label
+                          for="fileUpload_pic"
+                          class="file--btn"
+                          @click="fnPicFileUploadOpen()"
+                          >파일 선택</label
+                        >
+                        <v-file-input
+                          v-model="form.formValue5"
+                          id="fileUpload_pic"
+                          ref="fileupload_pic"
+                          accept=".jpg, .jpeg, .png, .gif"
+                          variant="plain"
+                          hide-details
+                          placeholder="선택된 파일 없음"
+                          prepend-icon=""
+                          class="custom-input"
+                          style="max-width: 400px"
+                          height="33px"
+                          :clearable="false"
+                          @change="fnUploadPicFileCheck()"
+                        >
+                          <!-- <template #append>
+                            <div class="v-input__icon v-input__icon--clear">
+                              <button
+                                @click="clearFile"
+                                type="button"
+                                aria-label="clear icon"
+                                tabindex="-1"
+                                class="v-icon notranslate v-icon--link mdi mdi-close"
+                              ></button>
+                            </div>
+                          </template> -->
+                        </v-file-input>
+                      </div>
+                      <p class="equip--image--desc">
+                        (권장 이미지 : gif, jpg, jpeg, png)
+                      </p>
+                    </div>
+                  </div>
+                </td>
+              </tr>
+              <tr>
+                <th class="bg le">소타이틀<span v-if="pageType !== 'D'" class="bul">*</span></th>
+                <td v-if="pageType == 'D'">
+                  {{ form.formValue6 }}
+                </td>
+                <td v-else>
+                  <div class="input--wrap">
+                    <v-text-field
+                    v-model="form.formValue6"
+                    class="custom-input mini"
+                    placeholder="소타이틀을 입력해주세요"
+                    :rules="[useValid.required('소타이틀')]"
+                    ></v-text-field>
+                  </div>
+                </td>
+              </tr>
+              <tr>
+                <th class="bg le">상세 다운로드</th>
+                <td>
+                  <div class="input--wrap" style="width: 50%">
+                    <v-file-input
+                      v-model="form.formValue7"
+                      label="파일은 압축(zip)해서 첨부해 주세요."
+                      accept=".zip"
+                      variant="outlined"
+                      hide-details=""
+                      density="comfortable"
+                    ></v-file-input>
+                    <div class="down--file" @click="fnDownloadFile()">
+                      <span>{{ zipInfo.original_name }}</span>
+                    </div>
+                  </div>
+                </td>
+              </tr>
+              <tr>
+                <th class="bg le">상세 내용<span v-if="pageType !== 'D'" class="bul">*</span></th>
+                <td v-if="pageType == 'D'">
+                  {{ editorContentReq }}
+                </td>
+                <td v-else>
+                  <SunEditorWrapper
+                    ref="sunEditorWrapper"
+                    :initialContent="editorContentReq"
+                  />
+                </td>
+              </tr>
+              <tr>
+                <th class="bg le">상태<span v-if="pageType !== 'D'" class="bul">*</span></th>
+                <td v-if="pageType == 'D'">
+                  {{ form.formValue8 == '0' ? '판매중' : '품절' }}
+                </td>
+                <td v-else>
+                  <div class="input--wrap" style="width: 20%">
+                    <v-select
+                      variant="outlined"
+                      class="custom-select"
+                      v-model="form.formValue8"
+                      :items="form.formValue8Arr"
+                    >
+                    </v-select>
+                  </div>
+                </td>
+              </tr>
+              <tr v-if="pageType !== 'D'">
+                <th class="bg le">노출 상태<span v-if="pageType !== 'D'" class="bul">*</span></th>
+                <td>
+                  <div class="input--wrap" style="width: 20%">
+                    <v-select
+                      variant="outlined"
+                      style="width: 20%"
+                      class="custom-select"
+                      v-model="form.formValue9"
+                      :items="form.formValue9Arr"
+                    >
+                    </v-select>
+                  </div>
+                </td>
+              </tr>
+              <tr>
+                <th class="bg le">업데이트 내역</th>
+                <td v-if="pageType == 'D'">
+                  {{ form.formValue10 }}
+                </td>
+                <td v-else>
+                  <div class="input--wrap">
+                    <v-textarea
+                    v-model="form.formValue10"
+                    class="custom-textarea"
+                    no-resize=""
+                    placeholder="업데이트 내역을 입력해주세요"
+                    ></v-textarea>
+                  </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="listLocated"
+            ><i class="ico"></i>목록</v-btn
+          >
+          <v-btn v-show="pageType == 'U'" class="custom-btn btn-del" @click="fnDelEvt"
+            ><i class="ico"></i>삭제</v-btn
+          >
+        </div>
+        <div class="btn-r">
+          <v-btn v-if="pageType !== 'D'" class="custom-btn btn-blue2" @click="fnBtnEvt"
+            ><i class="ico"></i>저장</v-btn
+          >
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import SunEditorWrapper from "@/components/sunEdt.vue";
+import useAxios from "@/composables/useAxios";
+
+/************************************************************************
+|    레이아웃
+************************************************************************/
+definePageMeta({
+  layout: "default",
+});
+
+/************************************************************************
+|    스토어
+ ************************************************************************/
+const useDtStore = useDetailStore();
+
+/************************************************************************
+|    전역
+ ************************************************************************/
+const { $toast, $log, $dayjs, $eventBus } = useNuxtApp();
+const router = useRouter();
+const pageId = ref("");
+
+const sunEditorWrapper = ref(null); //에디터용 전역
+const updatedContent = ref(null); //에디터용 전역
+const editorContentReq = ref(); //에디터용 전역
+const addForm = ref(null);
+const index = ref(null);
+const imageIndex = ref(0);
+const items = ref([]);
+const quillEditor = ref(null);
+const imgTemp = ref("");
+const zipInfo = ref({
+  file_path: "",
+  original_name: ""
+})
+const rowId = ref();
+const form = ref({
+  formValue1: "",
+  formValue2: "",
+  formValue3: "",
+  formValue4: "",
+  formValue5: null,
+  formValue6: "",
+  formValue7: "",
+  formValue8: "0",
+  formValue8Arr: [
+    { title: "판매중", value: "0" },
+    { title: "품절", value: "1" },
+  ],
+  formValue9: "Y",
+  formValue9Arr: [
+    { title: "노출", value: "Y" },
+    { title: "비노출", value: "N" },
+  ],
+  formValue10: "",
+});
+const apiUrl = ref("");
+
+apiUrl.value = import.meta.env.VITE_APP_API_URL;
+const objProc = ref({
+  validErrorMessage: "",
+});
+
+const pageType = ref("");
+
+/************************************************************************
+|    함수(METHODS)
+************************************************************************/
+
+const listLocated = () => {
+  router.push({
+    path: "/view/common/item",
+  });
+};
+
+const fnPicFileUploadOpen = () => {
+  let fileUpload = document.getElementById("fileupload_pic");
+  if (fileUpload != null) {
+    fileUpload.click();
+  }
+};
+const fnUploadPicFileCheck = () => {
+  if (form.value.formValue5) {
+    // 10Mb 이상은 업로드 불가
+    if (form.value.formValue5.size > 10 * 1024 * 1024) {
+      fnOpenCommPop("10mb 이상은 업로드가 불가합니다.");
+      form.value.formValue5 = null;
+      return;
+    }
+    // 이미지 파일 형식 체크
+    let extension = form.value.formValue5.name.split(".").pop().toLowerCase();
+    if (
+      extension != "jpg" &&
+      extension != "jpeg" &&
+      extension != "png" &&
+      extension != "gif"
+    ) {
+      fnOpenCommPop("파일 형식 또는 확장자가 올바르지 않습니다.");
+      form.value.formValue5 = null;
+      return;
+    }
+
+    objProc.validErrorMessage = "";
+
+    // 이미지 미리보기
+    let previewImage = new Image();
+    let tempImageUrl = window.URL.createObjectURL(form.value.formValue5);
+
+    //console.log(tempImageUrl);
+
+    previewImage.src = tempImageUrl;
+    items.value[0] = tempImageUrl;
+    imgTemp.value = tempImageUrl;
+  }
+};
+const clearFile = () => {
+  form.value.formValue5 = null;
+};
+
+const fnDownloadFile = () => {
+  window.location.href = `https://shopdeli.mycafe24.com/item/download/${zipInfo.value.file_path}`;
+}
+
+/*======================================================================
+|    작성 시퀀스
+| 1. 작성 컨펌
+| 2. 버튼 체크
+| 3. 등록시 -> 등록 API 호출
+======================================================================*/
+
+const fnBtnEvt = async () => {
+  await editorContent();
+
+  nextTick(() => {
+    if (addForm.value && typeof addForm.value.validate === "function") {
+      addForm.value
+        .validate()
+        .then((isValid) => {
+          if (
+            isValid.valid &&
+            updatedContent.value != undefined &&
+            updatedContent.value != null &&
+            updatedContent.value != "<p><br></p>" &&
+            form.value.formValue4 != null
+          ) {
+            if (pageType.value == "I") fnRegEvt();
+            else fnUpdEvt();
+          } else {
+            let param = {
+              id: pageId,
+              title: pageId,
+              content: "필수항목을 입력해주세요.",
+              yes: {
+                text: "확인",
+                isProc: false,
+              }
+            };
+            $eventBus.emit("OPEN_CONFIRM_POP_UP", param);
+          }
+        })
+        .catch((err) => {
+        });
+    } else {
+    }
+  });
+};
+
+const fnOpenCommPop = (__TEXT) => {
+  let param = {
+    id: pageId,
+    title: "알림",
+    content: __TEXT,
+    yes: {
+      text: "확인",
+      isProc: false,
+    },
+  };
+  $eventBus.emit("OPEN_CONFIRM_POP_UP", param);
+};
+
+const fnRegEvt = () => {
+  let param = {
+    id: pageId,
+    title: pageId,
+    content: "등록하시겠습니까?",
+    yes: {
+      text: "등록",
+      isProc: true,
+      event: "FN_INSERT",
+      param: "",
+    },
+    no: {
+      text: "취소",
+      isProc: false,
+    },
+  };
+  $eventBus.emit("OPEN_CONFIRM_POP_UP", param);
+};
+
+const fnUpdEvt = () => {
+  let param = {
+    id: pageId,
+    title: pageId,
+    content: "수정하시겠습니까?",
+    yes: {
+      text: "확인",
+      isProc: true,
+      event: "FN_UPDATE",
+      param: "",
+    },
+    no: {
+      text: "취소",
+      isProc: false,
+    },
+  };
+  $eventBus.emit("OPEN_CONFIRM_POP_UP", param);
+};
+
+const fnInsert = async () => {
+  const formData = new FormData();
+  formData.append('name', form.value.formValue1);
+  formData.append('price1', form.value.formValue2);
+  formData.append('price2', form.value.formValue3);
+  formData.append('deli_fee', form.value.formValue4);
+  formData.append('thumb_file', form.value.formValue5);
+  formData.append('sub_title', form.value.formValue6);
+  formData.append('detail', updatedContent.value);
+  formData.append('zip_file', form.value.formValue7);
+  formData.append('status', form.value.formValue8);
+  formData.append('show_yn', form.value.formValue9);
+  formData.append('add_info', form.value.formValue10);
+  formData.append('company_number', "1");
+
+  useAxios()
+    .post('/item/reg', formData, {
+      headers: {'Content-Type': 'multipart/form-data'},
+    })
+    .then((res) => {
+      router.push("/view/common/item");
+    })
+    .catch((error) => {
+    })
+    .finally(() => {
+    });
+};
+
+const fnUpdate = async () => {
+  let req = {
+    seq: useDtStore.boardInfo.seq,
+  };
+  const formData = new FormData();
+
+  formData.append('name', form.value.formValue1);
+  formData.append('price1', form.value.formValue2);
+  formData.append('price2', form.value.formValue3);
+  formData.append('deli_fee', form.value.formValue4);
+  if (form.value.formValue5 instanceof File) {
+    formData.append('thumb_file', form.value.formValue5);
+  }
+  formData.append('sub_title', form.value.formValue6);
+  formData.append('detail', updatedContent.value);
+  if (form.value.formValue7 instanceof File) {
+    formData.append('zip_file', form.value.formValue7);
+  }
+  formData.append('status', form.value.formValue8);
+  formData.append('show_yn', form.value.formValue9);
+  formData.append('add_info', form.value.formValue10);
+  formData.append('company_number', "1");
+
+  try {
+    const res = await useAxios().post(`/item/update/${req.seq}`, formData, {
+      headers: { 'Content-Type': 'multipart/form-data' },
+    });
+    router.push("/view/common/item");
+  } catch (error) {
+  }
+};
+
+const fnDelEvt = () => {
+  let param = {
+    id: pageId,
+    title: pageId,
+    content: "삭제하시겠습니까?",
+    yes: {
+      text: "확인",
+      isProc: true,
+      event: "FN_DELETE",
+      param: "",
+    },
+    no: {
+      text: "취소",
+      isProc: false,
+    },
+  };
+  $eventBus.emit("OPEN_CONFIRM_POP_UP", param);
+};
+
+const fnDelete = () => {
+  let req = {
+    seq: useDtStore.boardInfo.seq,
+  };
+
+  useAxios()
+    .post(`/item/delete/${req.seq}`)
+    .then((res) => {
+      //router.push("/view/common/item");
+    })
+    .catch((error) => {
+    })
+    .finally(() => {
+    });
+};
+
+const fnDetail = () => {
+  let req = {
+    seq: useDtStore.boardInfo.seq,
+  };
+  useAxios()
+    .get(`/item/detail/${req.seq}`)
+    .then((res) => {
+      form.value.formValue1 = res.data.NAME;
+      form.value.formValue2 = res.data.PRICE1;
+      form.value.formValue3 = res.data.PRICE2;
+      form.value.formValue4 = res.data.DELI_FEE;
+      form.value.formValue5 = res.data.THUMB_FILE;
+      form.value.formValue6 = res.data.SUB_TITLE;
+      zipInfo.value.file_path = res.data.ZIP_FILE;
+      zipInfo.value.original_name = res.data.ZIP_FILE_ORIGIN;
+      //에디터에 컨텐츠 전달
+      editorContentReq.value = res.data.DETAIL;
+      form.value.formValue8 = res.data.STATUS;
+      form.value.formValue9 = res.data.SHOW_YN;
+      form.value.formValue10 = res.data.ADD_INFO;
+      //썸네일 파일이 있으면 넣어줌
+      if(form.value.formValue5){
+        imgTemp.value = `https://shopdeli.mycafe24.com/writable/uploads/item/thumb/${form.value.formValue5}`;
+      }
+    })
+    .catch((error) => {
+    })
+    .finally(() => {
+    });
+};
+
+/*=======================================================================
+| 최종 에디터 이미지 url치환 : S
+/*=======================================================================*/
+
+const editorContent = async () => {
+  const content = sunEditorWrapper.value.getEditorContent();
+  updatedContent.value = await processEditorContent(content);
+  console.log("Updated content:", updatedContent.value);
+};
+
+// Base64 데이터를 Blob으로 변환
+const base64ToBlob = (base64, mimeType) => {
+  const byteString = atob(base64.split(",")[1]);
+  const arrayBuffer = new ArrayBuffer(byteString.length);
+  const uint8Array = new Uint8Array(arrayBuffer);
+
+  for (let i = 0; i < byteString.length; i++) {
+    uint8Array[i] = byteString.charCodeAt(i);
+  }
+
+  return new Blob([uint8Array], { type: mimeType });
+};
+
+// Base64 데이터를 File 객체로 변환
+const base64ToFile = (base64, mimeType, fileName) => {
+  const blob = base64ToBlob(base64, mimeType);
+  return new File([blob], fileName, { type: mimeType });
+};
+
+// 이미지 업로드 처리 (useAxios)
+const uploadImage = async (file) => {
+  const formDataEdt = new FormData();
+  formDataEdt.append("picObj", file);
+
+  return useAxios()
+    .post("/pic/upload", formDataEdt, {
+      headers: { "Content-Type": "multipart/form-data" },
+    })
+    .then((res) => {
+      const filePath = res.data.ogn_name.path.replace(/.*\/files\//, "");
+      const fileName = res.data.ogn_name.file_name;
+      return `${apiUrl.value}/images/${filePath}/${fileName}`; // 최종 URL 반환
+    })
+    .catch((error) => {
+      console.error("Image upload failed:", error);
+      return null;
+    });
+};
+
+// 에디터 내용 처리 및 이미지 업로드
+const processEditorContent = async (content) => {
+  const parser = new DOMParser();
+  const doc = parser.parseFromString(content, "text/html");
+  const images = doc.querySelectorAll("img");
+
+  for (let i = 0; i < images.length; i++) {
+    const img = images[i];
+    const src = img.src;
+
+    if (src.startsWith("data:image")) {
+      // MIME 타입과 파일 이름 추출
+      const mimeType = src.split(";")[0].split(":")[1];
+      const extension = mimeType.split("/")[1];
+      const fileName = `image-${i + 1}.${extension}`;
+
+      // Base64 데이터를 File 객체로 변환
+      const file = base64ToFile(src, mimeType, fileName);
+
+      // 이미지 업로드 및 URL 반환
+      const finalUrl = await uploadImage(file);
+      if (finalUrl) {
+        img.src = finalUrl; // 이미지 src 업데이트
+      }
+    }
+  }
+
+  return doc.body.innerHTML; // 최종 수정된 HTML 반환
+};
+
+/*=======================================================================
+| 최종 에디터 이미지 url치환 : E
+/*=======================================================================*/
+
+/************************************************************************
+|    팝업 이벤트버스 정의
+************************************************************************/
+$eventBus.off("FN_INSERT");
+$eventBus.on("FN_INSERT", () => {
+  fnInsert();
+});
+
+$eventBus.off("FN_UPDATE");
+$eventBus.on("FN_UPDATE", () => {
+  fnUpdate();
+});
+
+$eventBus.off("FN_DELETE");
+$eventBus.on("FN_DELETE", () => {
+  fnDelete();
+});
+
+/************************************************************************
+|    라이프사이클
+************************************************************************/
+onMounted(() => {
+  pageType.value = useDtStore.boardInfo.pageType;
+  
+  if(pageType.value == "I"){
+    pageId.value = "제품 등록"
+  } else if(pageType.value == "U"){
+    pageId.value = "제품 수정"
+  } else  {
+    pageId.value = "제품 상세"
+  }
+
+  //상세 등록 아니 리스트 클릭시 상세 정보로 접근
+  if (pageType.value !== "I") {
+    fnDetail();
+  }
+});
+
+/************************************************************************
+|    WATCH
+************************************************************************/
+</script>

+ 77 - 40
pages/view/influencer/item/index.vue → pages/view/common/item/index.vue

@@ -50,11 +50,15 @@
             ></VueDatePicker>
           </div>
           <div class="month--selector">
-            <v-btn elevation="0">오늘</v-btn>
-            <v-btn class="actv" elevation="0">7일</v-btn>
-            <v-btn elevation="0">1개월</v-btn>
-            <v-btn elevation="0">3개월</v-btn>
-            <v-btn elevation="0">전체</v-btn>
+            <v-btn
+              v-for="option in dateOptions"
+              :key="option.value"
+              :class="{ actv: selectedRange === option.value }"
+              @click="setDateRange(option.value)"
+              elevation="0"
+            >
+              {{ option.label }}
+            </v-btn>
           </div>
         </div>
       </div>
@@ -76,10 +80,13 @@
           >
         </div>
       </div>
-      <div class="item--list--wrap" v-if="itemList.length > 0">
-        <div class="item--list">
+      <div class="item--list--wrap">
+        <div class="no--data" v-if="itemList.length == 0">
+          등록된 제품이 없습니다.
+        </div>
+        <div class="item--list" v-if="itemList.length > 0">
           <div v-for="(items, index) in paginatedItems" :key="index" @click="toItemDetail(items.SEQ)" class="item">
-            <div class="item--img"></div>
+            <div class="item--img"><img v-if="items.THUMB_FILE" :src="`https://shopdeli.mycafe24.com/writable/uploads/item/thumb/${items.THUMB_FILE}`"></div>
             <h3>{{ items.NAME }}</h3>
             <p>공급가: {{ items.PRICE1 }}<br>판매가: {{ items.PRICE2 }}</p>
             <span>등록일: {{ items.REGDATE.slice(0, 10) }}</span>
@@ -95,7 +102,7 @@
             </div>
           </div>
         </div>
-        <div class="item--pagination">
+        <div class="item--pagination" v-if="itemList.length > 0">
           <v-pagination
             v-model="currentPage"
             :length="Math.ceil(itemList.length / itemsPerPage)"
@@ -109,6 +116,7 @@
 <script setup>
 import VueDatePicker from "@vuepic/vue-datepicker";
 import "@vuepic/vue-datepicker/dist/main.css";
+import dayjs from 'dayjs';
   /************************************************************************
 |    레이아웃
 ************************************************************************/
@@ -132,12 +140,21 @@ import "@vuepic/vue-datepicker/dist/main.css";
 |    전역
  ************************************************************************/
   const searchModel = ref("");
+  const selectedRange = ref('all');
+  const itemStartDate = ref("");
   const searchStartDate = ref("");
   const searchEndDate = ref("");
+  const dateOptions = [
+    { label: '오늘', value: 'today' },
+    { label: '7일', value: '7d' },
+    { label: '1개월', value: '1m' },
+    { label: '3개월', value: '3m' },
+    { label: '전체', value: 'all' },
+  ]
   const filter = ref("");
   const filderArr = ref([
-    { title: "선택하세요", value: "" },
-    { title: "제목", value: "title" },
+    { title: "전체", value: "" },
+    { title: "제품명", value: "name" },
   ]);
   const { $toast, $log, $dayjs, $eventBus } = useNuxtApp();
   const router = useRouter();
@@ -167,22 +184,55 @@ import "@vuepic/vue-datepicker/dist/main.css";
     return itemList.value.slice(start, start + itemsPerPage);
   });
 
+  const setDateRange = (range) => {
+    const today = dayjs();
+
+    switch(range) {
+      case 'today' :
+        searchStartDate.value = today.format('YYYY-MM-DD');
+        searchEndDate.value = today.format('YYYY-MM-DD');
+        selectedRange.value = 'today';
+        break;
+      case '7d':
+        searchStartDate.value = today.subtract(7, 'day').format('YYYY-MM-DD');
+        searchEndDate.value = today.format('YYYY-MM-DD');
+        selectedRange.value = '7d';
+        break;
+      case '1m':
+        searchStartDate.value = today.subtract(1, 'month').format('YYYY-MM-DD');
+        searchEndDate.value = today.format('YYYY-MM-DD');
+        selectedRange.value = '1m';
+        break;
+      case '3m':
+        searchStartDate.value = today.subtract(3, 'month').format('YYYY-MM-DD');
+        searchEndDate.value = today.format('YYYY-MM-DD');
+        selectedRange.value = '3m';
+        break;
+      case 'all':
+        searchStartDate.value = itemStartDate.value;
+        searchEndDate.value = today.format('YYYY-MM-DD');
+        selectedRange.value = 'all';
+        break
+    }
+  }
+
   const addLocated = () => {
     router.push({
-      path: "/view/item/add",
+      path: "/view/common/item/add",
     });
+    useDtStore.boardInfo.pageType = "I";
   };
 
-  const detailLocated = (__EVENT) => {
+  const toItemDetail = (__EVENT) => {
     router.push({
-      path: "/view/item/detail",
+      path: "/view/common/item/add",
     });
-    useDtStore.boardInfo.seq = __EVENT.data.SEQ;
+    useDtStore.boardInfo.seq = __EVENT;
+    //제품 등록한 벤더의 경우 U로, 인플루언서의 경우 D로
     useDtStore.boardInfo.pageType = "U";
-    useDtStore.boardInfo.status = __EVENT.data.STATUS;
   };
 
-  const evtListGet = async () => {
+  const itemListGet = async () => {
     let _req = {
       // Y : 노출, N : 비노출
       SHOW_YN: "",
@@ -192,29 +242,24 @@ import "@vuepic/vue-datepicker/dist/main.css";
       .post("/item/list", _req)
       .then((res) => {
         itemList.value = res.data;
+        itemStartDate.value = res.data[res.data.length-1].UDPDATE;
+        searchStartDate.value = itemStartDate.value;
+        searchEndDate.value = dayjs();
       });
   };
 
   const fnSearch = (__KEYWORD, __FILTER) => {
     let _req = {
-      compId: useAuthStore().getCompanyId,
       filter: __FILTER,
       keyword: __KEYWORD,
-      status: "",
-      // _size: 1000,
-      // _index: 0,
-      // admin_name:
-      //   __FILTER == "admin_name" ? __KEYWORD : __FILTER == "" ? __KEYWORD : null,
-      // id: __FILTER == "id" ? __KEYWORD : __FILTER == "" ? __KEYWORD : null,
+      startDate: searchStartDate.value,
+      endDate: searchEndDate.value
     };
 
     useAxios()
-      .post("/evt/search", _req)
+      .post("/item/search", _req)
       .then((res) => {
-        _req._size = res.data.length;
-
-        tblItems.value = res.data;
-        pageObj.value.totalCnt = tblItems.value.length;
+        itemList.value = res.data;
       })
       .catch((error) => {});
   };
@@ -223,16 +268,8 @@ import "@vuepic/vue-datepicker/dist/main.css";
 |    WATCH
 ************************************************************************/
 
-  watch(
-    () => props,
-    () => {
-      searchObj.value = props.propsData;
-      fnGetStat();
-    },
-    { deep: true }
-  );
-
+  
   onMounted(() => {
-    evtListGet();
+    itemListGet();
   });
-</script>
+</script>

+ 0 - 684
pages/view/influencer/item/add.vue

@@ -1,684 +0,0 @@
-<template>
-  <div>
-    <div class="inner--headers">
-      <h2>{{ pageId }}</h2>
-      <div class="bread--crumbs--wrap">
-        <span>홈</span>
-        <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>
-              <tr>
-                <th class="bg le">이벤트 바로가기</th>
-                <td>
-                  <div class="btn--wrap evt--btn" v-if="evtStatus == '1'">
-                    <v-btn class="custom-btn btn-sky" @click="evtLocationAction"
-                      ><i class="ico"></i>이벤트 바로가기</v-btn
-                    >
-                  </div>
-                  <div class="caution--text text-left" v-else>
-                    * 이벤트 진행전에 룰렛페이지 접속이 불가능합니다.
-                  </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 useAuthStore = useAuthStore();
-  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 = {
-      compId: useAuthStore().getCompanyId,
-      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);
-    }
-  };
-
-  const evtLocationAction = () => {
-    window.open("/view/roulette", "_blank");
-  };
-  /************************************************************************
-|    팝업 이벤트버스 정의
-************************************************************************/
-  $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 - 262
pages/view/influencer/item/evtListClosed.vue

@@ -1,262 +0,0 @@
-<template>
-  <div>
-    <div class="inner--headers">
-      <h2>{{ pageId }}</h2>
-      <div class="bread--crumbs--wrap">
-        <span>홈</span>
-        <span>이벤트 관리</span>
-        <span>{{ pageId }}</span>
-      </div>
-    </div>
-
-    <div class="search--modules">
-      <div class="form--cont--filter">
-        <v-select
-          v-model="filter"
-          :items="filterArr"
-          variant="outlined"
-          class="custom-select"
-        >
-        </v-select>
-      </div>
-      <div class="form--cont--text">
-        <v-text-field
-          v-model="searchModel"
-          class="custom-input mini"
-          style="width: 100%"
-          placeholder="검색어를 입력하세요"
-        ></v-text-field>
-      </div>
-      <v-btn
-        class="custom-btn btn-blue mini sch--btn"
-        @click="fnSearch(searchModel, filter)"
-        >검색</v-btn
-      >
-    </div>
-
-    <div class="data--list--wrap">
-      <div class="tbl-wrapper">
-        <div class="tbl-wrap">
-          <!-- ag grid -->
-          <ag-grid-vue
-            style="width: 100%; height: calc(10 * 2.94rem)"
-            class="ag-theme-quartz"
-            :gridOptions="gridOptions"
-            :rowData="tblItems"
-            :paginationPageSize="pageObj.pageSize"
-            :suppressPaginationPanel="true"
-            @grid-ready="onGridReady"
-            @rowClicked="detailLocated"
-          >
-          </ag-grid-vue>
-
-          <!-- 페이징 -->
-          <div class="ag-grid-custom-pagenations">
-            <pagination @chg_page="chgPage" :pageObj="pageObj"></pagination>
-          </div>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script setup>
-  import { AgGridVue } from "ag-grid-vue3";
-  import pagination from "../components/common/pagination.vue";
-  /************************************************************************
-|    레이아웃
-************************************************************************/
-  definePageMeta({
-    layout: "default",
-  });
-  /************************************************************************
-|   PROPS
- ************************************************************************/
-  const props = defineProps({
-    propsData: {
-      type: Object,
-      default: () => {},
-    },
-  });
-  /************************************************************************
-|    스토어
- ************************************************************************/
-  const useDtStore = useDetailStore();
-  /************************************************************************
-|    전역
- ************************************************************************/
-  const searchModel = ref("");
-  const filter = ref("");
-  const filterArr = ref([
-    { title: "선택하세요", value: "" },
-    { title: "제목", value: "title" },
-  ]);
-  const { $toast, $log, $dayjs, $eventBus } = useNuxtApp();
-  const router = useRouter();
-  const pageId = ref("마감된 이벤트");
-  let pageObj = ref({
-    page: 1, // 현재 페이지
-    pageMaxNumSize: 10, // 페이지 숫자 최대 표현 개수
-    pageSize: 10, // 테이블 조회 데이터 개수
-    totalCnt: 0, // 전체 페이지
-  });
-  const tblItems = ref([]); // stat 데이터
-
-  /* eslint-disable */
-  /* prettier-ignore */
-
-  pageObj.value.totalCnt = tblItems.value.length;
-
-  const remToPx = () => parseFloat(getComputedStyle(document.documentElement).fontSize);
-  const rowHeightRem = 2.65; // 원하는 rem 값
-  const rowHeightPx = rowHeightRem * remToPx();
-  const gridApi = shallowRef();
-
-  // gridOption
-  const gridOptions = {
-    columnDefs: [
-      {
-        headerName: "No",
-        valueGetter: (params) => params.api.getDisplayedRowCount() - params.node.rowIndex,
-        sortable: false,
-        width: 70,
-      },
-      { headerName: "제목", field: "TITLE", sortable: false },
-      {
-        headerName: "기간",
-        field: "STARTDATE",
-        sortable: false,
-        cellRenderer: (params) => {
-          const formatDate = (str) => {
-            if (!str) return "";
-            const d = new Date(str);
-            const yyyy = d.getFullYear();
-            const mm = String(d.getMonth() + 1).padStart(2, "0");
-            const dd = String(d.getDate()).padStart(2, "0");
-            return `${yyyy}-${mm}-${dd}`;
-          };
-
-          const start = formatDate(params.data.STARTDATE);
-          const end = formatDate(params.data.ENDDATE);
-
-          return `${start} ~ ${end}`;
-        },
-      },
-      {
-        headerName: "상태",
-        field: "STATUS",
-        sortable: false,
-        width: 70,
-        cellRenderer: (params) => {
-          return params.value == 0 ? "대기중" : params.value == 1 ? "진행중" : "마감";
-        },
-      },
-      { headerName: "등록일", field: "REGDATE", sortable: false, width: 140 },
-      // {
-      //   headerName: "알림 메일 수신 여부",
-      //   field: "mail_recp_yn",
-      //   sortable: false,
-      //   width: 130,
-      // },
-    ],
-    rowData: tblItems.value, // 테이블 데이터
-    autoSizeStrategy: {
-      type: "fitGridWidth", // width맞춤
-    },
-    suppressMovableColumns: true,
-    headerHeight: rowHeightPx,
-    rowHeight: rowHeightPx,
-    pagination: true,
-    suppressPaginationPanel: true, // 하단 default 페이징 컨트롤 숨김
-    //rowSelection: {
-    // checkboxes: true,
-    // headerCheckbox: true,
-    // enableClickSelection: false,
-    // mode: "multiRow",
-    //},
-  };
-
-  /************************************************************************
-|    함수(METHODS)
-************************************************************************/
-  const onGridReady = (__PARAMS) => {
-    gridApi.value = __PARAMS.api;
-  };
-
-  const chgPage = (__PAGE) => {
-    pageObj.value.page = __PAGE;
-    gridApi.value.paginationGoToPage(__PAGE - 1);
-  };
-
-  const addLocated = () => {
-    router.push({
-      path: "/view/event/evtAdd",
-    });
-    useDtStore.boardInfo.pageType = "I";
-  };
-
-  const detailLocated = (__EVENT) => {
-    router.push({
-      path: "/view/event/evtAdd",
-    });
-    useDtStore.boardInfo.seq = __EVENT.data.SEQ;
-    useDtStore.boardInfo.pageType = "U";
-    useDtStore.boardInfo.status = "2";
-  };
-
-  const evtListGet = () => {
-    let _req = {
-      compId: useAuthStore().getCompanyId,
-      status: "2",
-    };
-
-    useAxios()
-      .post("/evt/list", _req)
-      .then((res) => {
-        _req._size = res.data.length;
-        tblItems.value = res.data;
-        pageObj.value.totalCnt = tblItems.value.length;
-      });
-  };
-
-  const fnSearch = (__KEYWORD, __FILTER) => {
-    let _req = {
-      compId: useAuthStore().getCompanyId,
-      filter: __FILTER,
-      keyword: __KEYWORD,
-      status: "2",
-      // _size: 1000,
-      // _index: 0,
-      // admin_name:
-      //   __FILTER == "admin_name" ? __KEYWORD : __FILTER == "" ? __KEYWORD : null,
-      // id: __FILTER == "id" ? __KEYWORD : __FILTER == "" ? __KEYWORD : null,
-    };
-
-    useAxios()
-      .post("/evt/search", _req)
-      .then((res) => {
-        _req._size = res.data.length;
-
-        tblItems.value = res.data;
-        pageObj.value.totalCnt = tblItems.value.length;
-      })
-      .catch((error) => {});
-  };
-
-  /************************************************************************
-|    WATCH
-************************************************************************/
-
-  watch(
-    () => props,
-    () => {
-      searchObj.value = props.propsData;
-      fnGetStat();
-    },
-    { deep: true }
-  );
-
-  onMounted(() => {
-    evtListGet();
-  });
-</script>

+ 0 - 262
pages/view/influencer/item/evtListOngoing.vue

@@ -1,262 +0,0 @@
-<template>
-  <div>
-    <div class="inner--headers">
-      <h2>{{ pageId }}</h2>
-      <div class="bread--crumbs--wrap">
-        <span>홈</span>
-        <span>이벤트 관리</span>
-        <span>{{ pageId }}</span>
-      </div>
-    </div>
-
-    <div class="search--modules">
-      <div class="form--cont--filter">
-        <v-select
-          v-model="filter"
-          :items="filterArr"
-          variant="outlined"
-          class="custom-select"
-        >
-        </v-select>
-      </div>
-      <div class="form--cont--text">
-        <v-text-field
-          v-model="searchModel"
-          class="custom-input mini"
-          style="width: 100%"
-          placeholder="검색어를 입력하세요"
-        ></v-text-field>
-      </div>
-      <v-btn
-        class="custom-btn btn-blue mini sch--btn"
-        @click="fnSearch(searchModel, filter)"
-        >검색</v-btn
-      >
-    </div>
-
-    <div class="data--list--wrap">
-      <div class="tbl-wrapper">
-        <div class="tbl-wrap">
-          <!-- ag grid -->
-          <ag-grid-vue
-            style="width: 100%; height: calc(10 * 2.94rem)"
-            class="ag-theme-quartz"
-            :gridOptions="gridOptions"
-            :rowData="tblItems"
-            :paginationPageSize="pageObj.pageSize"
-            :suppressPaginationPanel="true"
-            @grid-ready="onGridReady"
-            @rowClicked="detailLocated"
-          >
-          </ag-grid-vue>
-
-          <!-- 페이징 -->
-          <div class="ag-grid-custom-pagenations">
-            <pagination @chg_page="chgPage" :pageObj="pageObj"></pagination>
-          </div>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script setup>
-  import { AgGridVue } from "ag-grid-vue3";
-  import pagination from "../components/common/pagination.vue";
-  /************************************************************************
-|    레이아웃
-************************************************************************/
-  definePageMeta({
-    layout: "default",
-  });
-  /************************************************************************
-|   PROPS
- ************************************************************************/
-  const props = defineProps({
-    propsData: {
-      type: Object,
-      default: () => {},
-    },
-  });
-  /************************************************************************
-|    스토어
- ************************************************************************/
-  const useDtStore = useDetailStore();
-  /************************************************************************
-|    전역
- ************************************************************************/
-  const searchModel = ref("");
-  const filter = ref("");
-  const filterArr = ref([
-    { title: "선택하세요", value: "" },
-    { title: "제목", value: "title" },
-  ]);
-  const { $toast, $log, $dayjs, $eventBus } = useNuxtApp();
-  const router = useRouter();
-  const pageId = ref("진행중 이벤트");
-  let pageObj = ref({
-    page: 1, // 현재 페이지
-    pageMaxNumSize: 10, // 페이지 숫자 최대 표현 개수
-    pageSize: 10, // 테이블 조회 데이터 개수
-    totalCnt: 0, // 전체 페이지
-  });
-  const tblItems = ref([]); // stat 데이터
-
-  /* eslint-disable */
-  /* prettier-ignore */
-
-  pageObj.value.totalCnt = tblItems.value.length;
-
-  const remToPx = () => parseFloat(getComputedStyle(document.documentElement).fontSize);
-  const rowHeightRem = 2.65; // 원하는 rem 값
-  const rowHeightPx = rowHeightRem * remToPx();
-  const gridApi = shallowRef();
-
-  // gridOption
-  const gridOptions = {
-    columnDefs: [
-      {
-        headerName: "No",
-        valueGetter: (params) => params.api.getDisplayedRowCount() - params.node.rowIndex,
-        sortable: false,
-        width: 70,
-      },
-      { headerName: "제목", field: "TITLE", sortable: false },
-      {
-        headerName: "기간",
-        field: "STARTDATE",
-        sortable: false,
-        cellRenderer: (params) => {
-          const formatDate = (str) => {
-            if (!str) return "";
-            const d = new Date(str);
-            const yyyy = d.getFullYear();
-            const mm = String(d.getMonth() + 1).padStart(2, "0");
-            const dd = String(d.getDate()).padStart(2, "0");
-            return `${yyyy}-${mm}-${dd}`;
-          };
-
-          const start = formatDate(params.data.STARTDATE);
-          const end = formatDate(params.data.ENDDATE);
-
-          return `${start} ~ ${end}`;
-        },
-      },
-      {
-        headerName: "상태",
-        field: "STATUS",
-        sortable: false,
-        width: 70,
-        cellRenderer: (params) => {
-          return params.value == 0 ? "대기중" : params.value == 1 ? "진행중" : "마감";
-        },
-      },
-      { headerName: "등록일", field: "REGDATE", sortable: false, width: 140 },
-      // {
-      //   headerName: "알림 메일 수신 여부",
-      //   field: "mail_recp_yn",
-      //   sortable: false,
-      //   width: 130,
-      // },
-    ],
-    rowData: tblItems.value, // 테이블 데이터
-    autoSizeStrategy: {
-      type: "fitGridWidth", // width맞춤
-    },
-    suppressMovableColumns: true,
-    headerHeight: rowHeightPx,
-    rowHeight: rowHeightPx,
-    pagination: true,
-    suppressPaginationPanel: true, // 하단 default 페이징 컨트롤 숨김
-    //rowSelection: {
-    // checkboxes: true,
-    // headerCheckbox: true,
-    // enableClickSelection: false,
-    // mode: "multiRow",
-    //},
-  };
-
-  /************************************************************************
-|    함수(METHODS)
-************************************************************************/
-  const onGridReady = (__PARAMS) => {
-    gridApi.value = __PARAMS.api;
-  };
-
-  const chgPage = (__PAGE) => {
-    pageObj.value.page = __PAGE;
-    gridApi.value.paginationGoToPage(__PAGE - 1);
-  };
-
-  const addLocated = () => {
-    router.push({
-      path: "/view/event/evtAdd",
-    });
-    useDtStore.boardInfo.pageType = "I";
-  };
-
-  const detailLocated = (__EVENT) => {
-    router.push({
-      path: "/view/event/evtAdd",
-    });
-    useDtStore.boardInfo.seq = __EVENT.data.SEQ;
-    useDtStore.boardInfo.pageType = "U";
-    useDtStore.boardInfo.status = "1";
-  };
-
-  const evtListGet = () => {
-    let _req = {
-      compId: useAuthStore().getCompanyId,
-      status: "1",
-    };
-
-    useAxios()
-      .post("/evt/list", _req)
-      .then((res) => {
-        _req._size = res.data.length;
-        tblItems.value = res.data;
-        pageObj.value.totalCnt = tblItems.value.length;
-      });
-  };
-
-  const fnSearch = (__KEYWORD, __FILTER) => {
-    let _req = {
-      compId: useAuthStore().getCompanyId,
-      filter: __FILTER,
-      keyword: __KEYWORD,
-      status: "1",
-      // _size: 1000,
-      // _index: 0,
-      // admin_name:
-      //   __FILTER == "admin_name" ? __KEYWORD : __FILTER == "" ? __KEYWORD : null,
-      // id: __FILTER == "id" ? __KEYWORD : __FILTER == "" ? __KEYWORD : null,
-    };
-
-    useAxios()
-      .post("/evt/search", _req)
-      .then((res) => {
-        _req._size = res.data.length;
-
-        tblItems.value = res.data;
-        pageObj.value.totalCnt = tblItems.value.length;
-      })
-      .catch((error) => {});
-  };
-
-  /************************************************************************
-|    WATCH
-************************************************************************/
-
-  watch(
-    () => props,
-    () => {
-      searchObj.value = props.propsData;
-      fnGetStat();
-    },
-    { deep: true }
-  );
-
-  onMounted(() => {
-    evtListGet();
-  });
-</script>

+ 0 - 324
pages/view/influencer/item/evtListPending.vue

@@ -1,324 +0,0 @@
-<template>
-  <div>
-    <div class="inner--headers">
-      <h2>{{ pageId }}</h2>
-      <div class="bread--crumbs--wrap">
-        <span>홈</span>
-        <span>이벤트 관리</span>
-        <span>{{ pageId }}</span>
-      </div>
-    </div>
-
-    <div class="search--modules">
-      <div class="form--cont--filter">
-        <v-select
-          v-model="filter"
-          :items="filterArr"
-          variant="outlined"
-          class="custom-select"
-        >
-        </v-select>
-      </div>
-      <div class="form--cont--text">
-        <v-text-field
-          v-model="searchModel"
-          class="custom-input mini"
-          style="width: 100%"
-          placeholder="검색어를 입력하세요"
-        ></v-text-field>
-      </div>
-      <v-btn
-        class="custom-btn btn-blue mini sch--btn"
-        @click="fnSearch(searchModel, filter)"
-        >검색</v-btn
-      >
-    </div>
-
-    <div class="data--list--wrap">
-      <div class="btn--actions--wrap">
-        <div class="left--sections">
-          <v-btn class="custom-btn mini btn-white" @click="fnDelEvt">선택 삭제</v-btn>
-        </div>
-        <div class="right--sections">
-          <v-btn class="custom-btn mini btn-reg ml--10" @click="addLocated()"
-            ><i class="ico"></i>신규 등록</v-btn
-          >
-        </div>
-      </div>
-
-      <div class="tbl-wrapper">
-        <div class="tbl-wrap">
-          <!-- ag grid -->
-          <ag-grid-vue
-            style="width: 100%; height: calc(10 * 2.94rem)"
-            class="ag-theme-quartz"
-            :gridOptions="gridOptions"
-            :rowData="tblItems"
-            rowSelection="multiple"
-            :paginationPageSize="pageObj.pageSize"
-            :suppressPaginationPanel="true"
-            @grid-ready="onGridReady"
-            @rowClicked="detailLocated"
-          >
-          </ag-grid-vue>
-
-          <!-- 페이징 -->
-          <div class="ag-grid-custom-pagenations">
-            <pagination @chg_page="chgPage" :pageObj="pageObj"></pagination>
-          </div>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script setup>
-  import { AgGridVue } from "ag-grid-vue3";
-  import pagination from "../components/common/pagination.vue";
-  /************************************************************************
-|    레이아웃
-************************************************************************/
-  definePageMeta({
-    layout: "default",
-  });
-  /************************************************************************
-|   PROPS
- ************************************************************************/
-  const props = defineProps({
-    propsData: {
-      type: Object,
-      default: () => {},
-    },
-  });
-  /************************************************************************
-|    스토어
- ************************************************************************/
-  const useDtStore = useDetailStore();
-  /************************************************************************
-|    전역
- ************************************************************************/
-  const searchModel = ref("");
-  const filter = ref("");
-  const filterArr = ref([
-    { title: "선택하세요", value: "" },
-    { title: "제목", value: "title" },
-  ]);
-  const { $toast, $log, $dayjs, $eventBus } = useNuxtApp();
-  const router = useRouter();
-  const pageId = ref("대기중 이벤트");
-  let pageObj = ref({
-    page: 1, // 현재 페이지
-    pageMaxNumSize: 10, // 페이지 숫자 최대 표현 개수
-    pageSize: 10, // 테이블 조회 데이터 개수
-    totalCnt: 0, // 전체 페이지
-  });
-  const tblItems = ref([]); // stat 데이터
-
-  /* eslint-disable */
-  /* prettier-ignore */
-
-  pageObj.value.totalCnt = tblItems.value.length;
-
-  const remToPx = () => parseFloat(getComputedStyle(document.documentElement).fontSize);
-  const rowHeightRem = 2.65; // 원하는 rem 값
-  const rowHeightPx = rowHeightRem * remToPx();
-  const gridApi = shallowRef();
-
-  // gridOption
-  const gridOptions = {
-    columnDefs: [
-      { checkboxSelection: true, headerCheckboxSelection: true, width: 0 },
-      {
-        headerName: "No",
-        valueGetter: (params) => params.api.getDisplayedRowCount() - params.node.rowIndex,
-        sortable: false,
-        width: 70,
-      },
-      { headerName: "제목", field: "TITLE", sortable: false },
-      {
-        headerName: "기간",
-        field: "STARTDATE",
-        sortable: false,
-        cellRenderer: (params) => {
-          const formatDate = (str) => {
-            if (!str) return "";
-            const d = new Date(str);
-            const yyyy = d.getFullYear();
-            const mm = String(d.getMonth() + 1).padStart(2, "0");
-            const dd = String(d.getDate()).padStart(2, "0");
-            return `${yyyy}-${mm}-${dd}`;
-          };
-
-          const start = formatDate(params.data.STARTDATE);
-          const end = formatDate(params.data.ENDDATE);
-
-          return `${start} ~ ${end}`;
-        },
-      },
-      {
-        headerName: "상태",
-        field: "STATUS",
-        sortable: false,
-        width: 70,
-        cellRenderer: (params) => {
-          return params.value == 0 ? "대기중" : params.value == 1 ? "진행중" : "마감";
-        },
-      },
-      { headerName: "등록일", field: "REGDATE", sortable: false, width: 140 },
-      // {
-      //   headerName: "알림 메일 수신 여부",
-      //   field: "mail_recp_yn",
-      //   sortable: false,
-      //   width: 130,
-      // },
-    ],
-    rowData: tblItems.value, // 테이블 데이터
-    autoSizeStrategy: {
-      type: "fitGridWidth", // width맞춤
-    },
-    suppressMovableColumns: true,
-    headerHeight: rowHeightPx,
-    rowHeight: rowHeightPx,
-    pagination: true,
-    suppressPaginationPanel: true, // 하단 default 페이징 컨트롤 숨김
-    //rowSelection: {
-    // checkboxes: true,
-    // headerCheckbox: true,
-    // enableClickSelection: false,
-    // mode: "multiRow",
-    //},
-  };
-
-  /************************************************************************
-|    함수(METHODS)
-************************************************************************/
-  const onGridReady = (__PARAMS) => {
-    gridApi.value = __PARAMS.api;
-  };
-
-  const chgPage = (__PAGE) => {
-    pageObj.value.page = __PAGE;
-    gridApi.value.paginationGoToPage(__PAGE - 1);
-  };
-
-  const addLocated = () => {
-    router.push({
-      path: "/view/event/evtAdd",
-    });
-    useDtStore.boardInfo.pageType = "I";
-  };
-
-  const detailLocated = (__EVENT) => {
-    router.push({
-      path: "/view/event/evtAdd",
-    });
-    useDtStore.boardInfo.seq = __EVENT.data.SEQ;
-    useDtStore.boardInfo.pageType = "U";
-    useDtStore.boardInfo.status = "0";
-  };
-
-  const evtListGet = () => {
-    let _req = {
-      compId: useAuthStore().getCompanyId,
-      status: "0",
-    };
-
-    useAxios()
-      .post("/evt/list", _req)
-      .then((res) => {
-        _req._size = res.data.length;
-        tblItems.value = res.data;
-        pageObj.value.totalCnt = tblItems.value.length;
-      });
-  };
-
-  const fnSearch = (__KEYWORD, __FILTER) => {
-    let _req = {
-      compId: useAuthStore().getCompanyId,
-      filter: __FILTER,
-      keyword: __KEYWORD,
-      status: "0",
-      // _size: 1000,
-      // _index: 0,
-      // admin_name:
-      //   __FILTER == "admin_name" ? __KEYWORD : __FILTER == "" ? __KEYWORD : null,
-      // id: __FILTER == "id" ? __KEYWORD : __FILTER == "" ? __KEYWORD : null,
-    };
-
-    useAxios()
-      .post("/evt/search", _req)
-      .then((res) => {
-        _req._size = res.data.length;
-        tblItems.value = res.data;
-        pageObj.value.totalCnt = tblItems.value.length;
-      })
-      .catch((error) => {});
-  };
-
-  const fnDelete = async (seqArr) => {
-    if (!seqArr.length) return;
-
-    for (const seq of seqArr) {
-      await useAxios().post(`evt/delete/${seq}`);
-    }
-    window.location.reload();
-  };
-
-  const fnDelEvt = () => {
-    const selected = gridApi.value.getSelectedRows();
-    if (selected.length === 0) {
-      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: true,
-          event: "FN_DELETE",
-          param: selected,
-        },
-        no: {
-          text: "취소",
-          isProc: false,
-        },
-      };
-      $eventBus.emit("OPEN_CONFIRM_POP_UP", param);
-    }
-  };
-  /************************************************************************
-|    팝업 이벤트버스 정의
-************************************************************************/
-  $eventBus.off("FN_DELETE");
-  $eventBus.on("FN_DELETE", (selected) => {
-    const seqList = selected.map((row) => row.SEQ);
-    fnDelete(seqList);
-  });
-
-  /************************************************************************
-|    WATCH
-************************************************************************/
-
-  watch(
-    () => props,
-    () => {
-      searchObj.value = props.propsData;
-      fnGetStat();
-    },
-    { deep: true }
-  );
-
-  onMounted(() => {
-    evtListGet();
-  });
-</script>