Sfoglia il codice sorgente

개별배송/공동구매 타입추가

DESKTOP-T61HUSC\user 4 mesi fa
parent
commit
75156b15ff

+ 123 - 118
backend/app/Controllers/Item.php

@@ -1,11 +1,11 @@
 <?php
 
-  namespace App\Controllers;
+namespace App\Controllers;
 
-  use CodeIgniter\RESTful\ResourceController;
+use CodeIgniter\RESTful\ResourceController;
 
-  class Item extends ResourceController
-  {
+class Item extends ResourceController
+{
     //이벤트 리스트
     public function itemlist()
     {
@@ -63,7 +63,7 @@
         $keyword = isset($request['keyword']) ? $request['keyword'] : null;
         $startDate = $request['startDate'] ?? null;
         $endDate = $request['endDate'] ?? null;
-        $showYN = $request['showYN'] ?? null; 
+        $showYN = $request['showYN'] ?? null;
         $itemType = isset($request['TYPE']) ? $request['TYPE'] : null;
         $memberType = isset($request['MEMBER_TYPE']) ? $request['MEMBER_TYPE'] : null;
         $companyNumber = isset($request['COMPANY_NUMBER']) ? $request['COMPANY_NUMBER'] : null;
@@ -75,7 +75,7 @@
 
         // 평문 검색 (LIKE 연산 사용)
         $builder = $db->table('ITEM_LIST');
-        
+
         // 사용자 타입별 필터링
         if ($memberType === 'VENDOR' && !empty($companyNumber)) {
             // 벤더사의 경우: 자사 제품만 검색
@@ -89,7 +89,7 @@
             $builder->where('VIP.STATUS', 'APPROVED');
             $builder->where('VIP.IS_ACTIVE', 'Y');
         }
-        
+
         if (!empty($keyword)) {
             if (empty($filter)) {
                 // 필터를 선택 안했으면 전체 검색
@@ -130,123 +130,128 @@
     //아이템 등록
     public function itemRegister()
     {
-      $db = \Config\Database::connect();
-      $request = \Config\Services::request();
-      $regdate = date('Y-m-d H:i:s');
-      $thumb = $request->getFile('thumb_file');
-      $zip = $request->getFile('zip_file');
-      $zipOrigin = $zip ? $zip->getClientName() : null;
-
-      // 기본 유효성 검사
-      if (
-          !$request->getPost('name') ||
-          !$request->getPost('price1') ||
-          !$request->getPost('price2') ||
-          !$request->getPost('deli_fee') ||
-          !$request->getPost('sub_title') ||
-          !$request->getPost('detail') ||
-          !$request->getPost('company_number')
-      ) {
-          return $this->respond([
-              'status' => 'fail',
-              'message' => '필수 값이 누락됐습니다.'
-          ], 400);
-      }
-
-      $db->transBegin(); // 트랜잭션 시작
-
-      try {
-        // 썸네일 파일 처리
-        $thumbFileName = null;
-        if ($thumb && $thumb->isValid() && !$thumb->hasMoved()) {
-          $thumbFileName = $thumb->getRandomName(); // 랜덤파일명 생성
-          $thumb->move(WRITEPATH . 'uploads/item/thumb/', $thumbFileName); // 저장
-        }
-        // 상세 zip 파일 처리
-        $zipFileName = null;
-        if ($zip && $zip->isValid() && !$zip->hasMoved()) {
-          $zipFileName = $zip->getRandomName();
-          $zip->move(WRITEPATH . 'uploads/item/detail/', $zipFileName);
+        $db = \Config\Database::connect();
+        $request = \Config\Services::request();
+        $regdate = date('Y-m-d H:i:s');
+        $thumb = $request->getFile('thumb_file');
+        $zip = $request->getFile('zip_file');
+        $zipOrigin = $zip ? $zip->getClientName() : null;
+
+        // 기본 유효성 검사
+        if (
+            !$request->getPost('name') ||
+            !$request->getPost('price1') ||
+            !$request->getPost('price2') ||
+            !$request->getPost('deli_fee') ||
+            !$request->getPost('sub_title') ||
+            !$request->getPost('detail') ||
+            !$request->getPost('company_number')
+        ) {
+            return $this->respond([
+                'status' => 'fail',
+                'message' => '필수 값이 누락됐습니다.'
+            ], 400);
         }
-        // 1. ITEM_LIST에 아이템 정보 등록
-        $itemData = [
-            'NAME' => $request->getPost('name'),
-            'PRICE1' => $request->getPost('price1'),
-            'PRICE2' => $request->getPost('price2'),
-            'DELI_FEE' => $request->getPost('deli_fee'),
-            'SUB_TITLE' => $request->getPost('sub_title'),
-            'DETAIL' => $request->getPost('detail'),
-            'STATUS' => $request->getPost('status'),
-            'SHOW_YN' => $request->getPost('show_yn'),
-            'ADD_INFO' => $request->getPost('add_info') ?? 0,
-            'COMPANY_NUMBER' => $request->getPost('company_number'),
-            'REGDATE' => $regdate,
-            'UDPDATE' => $regdate,
-            'THUMB_FILE' => $thumbFileName, // 파일명 저장
-            'ZIP_FILE' => $zipFileName, // 파일명 저장
-            'ZIP_FILE_ORIGIN' => $zipOrigin, // 원본 파일명 저장
-        ];
 
-        $insertResult = $db->table('ITEM_LIST')->insert($itemData);
-          if (!$insertResult) {
-              $error = $db->error();
-              return $this->respond([
-                  'status' => 'fail',
-                  'message' => 'Insert 실패: ' . $error['message']
-              ], 500);
-          }
-        $itemSeq = $db->insertID(); // 생성된 이벤트 SEQ값
+        $db->transBegin(); // 트랜잭션 시작
+
+        try {
+            // 썸네일 파일 처리
+            $thumbFileName = null;
+            if ($thumb && $thumb->isValid() && !$thumb->hasMoved()) {
+                $thumbFileName = $thumb->getRandomName(); // 랜덤파일명 생성
+                $thumb->move(WRITEPATH . 'uploads/item/thumb/', $thumbFileName); // 저장
+            }
+            // 상세 zip 파일 처리
+            $zipFileName = null;
+            if ($zip && $zip->isValid() && !$zip->hasMoved()) {
+                $zipFileName = $zip->getRandomName();
+                $zip->move(WRITEPATH . 'uploads/item/detail/', $zipFileName);
+            }
+            // 1. ITEM_LIST에 아이템 정보 등록
+            $itemData = [
+                'NAME' => $request->getPost('name'),
+                'PRICE1' => $request->getPost('price1'),
+                'PRICE2' => $request->getPost('price2'),
+                'DELI_FEE' => $request->getPost('deli_fee'),
+                'SUB_TITLE' => $request->getPost('sub_title'),
+                'DETAIL' => $request->getPost('detail'),
+                'STATUS' => $request->getPost('status'),
+                'SHOW_YN' => $request->getPost('show_yn'),
+                'ADD_INFO' => $request->getPost('add_info') ?? 0,
+                'CONTACT_INF' => $request->getPost('contact_inf') ?? 0,
+                'ORDER_LINK' => $request->getPost('order_link') ?? 0,
+                'ORDER_START_DATE' => $request->getPost('order_start_date') ?? 0,
+                'ORDER_END_DATE' => $request->getPost('order_end_date') ?? 0,
+                'COMPANY_NUMBER' => $request->getPost('company_number'),
+                'REGDATE' => $regdate,
+                'UDPDATE' => $regdate,
+                'TYPE' => $request->getPost('item_type'),
+                'THUMB_FILE' => $thumbFileName, // 파일명 저장
+                'ZIP_FILE' => $zipFileName, // 파일명 저장
+                'ZIP_FILE_ORIGIN' => $zipOrigin, // 원본 파일명 저장
+            ];
+
+            $insertResult = $db->table('ITEM_LIST')->insert($itemData);
+            if (!$insertResult) {
+                $error = $db->error();
+                return $this->respond([
+                    'status' => 'fail',
+                    'message' => 'Insert 실패: ' . $error['message']
+                ], 500);
+            }
+            $itemSeq = $db->insertID(); // 생성된 이벤트 SEQ값
 
 
 
-        $db->transCommit();
-        return $this->respond([
-          'status' => 'success',
-          'item_seq' => $itemSeq
-        ], 201);
-      } catch (\Exception $e) {
-          $db->transRollback();
-          return $this->respond([
-              'status' => 'fail',
-              'message' => 'DB 오류: ' . $e->getMessage()
-          ], 500);
-      }
+            $db->transCommit();
+            return $this->respond([
+                'status' => 'success',
+                'item_seq' => $itemSeq
+            ], 201);
+        } catch (\Exception $e) {
+            $db->transRollback();
+            return $this->respond([
+                'status' => 'fail',
+                'message' => 'DB 오류: ' . $e->getMessage()
+            ], 500);
+        }
     }
 
     //아이템 상세
     public function itemDetail($seq)
     {
-      // DB 객체 얻기
-      $db = \Config\Database::connect();
-
-      $builder = $db->table('ITEM_LIST');
-      $item = $builder->where('seq', $seq)->get()->getRowArray();
-
-      if($item){
-          return $this->respond($item, 200);
-      } else {
-          return $this->respond([
-              'status' => 'fail',
-              'message' => '유효하지 않은 seq입니다.'
-          ], 404);
-      }
+        // DB 객체 얻기
+        $db = \Config\Database::connect();
+
+        $builder = $db->table('ITEM_LIST');
+        $item = $builder->where('seq', $seq)->get()->getRowArray();
+
+        if($item){
+            return $this->respond($item, 200);
+        } else {
+            return $this->respond([
+                'status' => 'fail',
+                'message' => '유효하지 않은 seq입니다.'
+            ], 404);
+        }
     }
 
     //상세 다운로드
     public function file($fileName)
-      {
-          helper('filesystem');
+    {
+        helper('filesystem');
 
-          $path = WRITEPATH . 'uploads/item/detail/' . $fileName;
+        $path = WRITEPATH . 'uploads/item/detail/' . $fileName;
 
-          if (!file_exists($path)) {
-              return $this->failNotFound('파일을 찾을 수 없습니다.');
-          }
+        if (!file_exists($path)) {
+            return $this->failNotFound('파일을 찾을 수 없습니다.');
+        }
 
-          return $this->response
-              ->download($path, null)
-              ->setFileName($fileName);
-      }
+        return $this->response
+            ->download($path, null)
+            ->setFileName($fileName);
+    }
 
     //아이템 수정
     public function ItemUpdate($seq)
@@ -337,19 +342,19 @@
     //아이템 삭제
     public function itemDelete($seq)
     {
-      $db = \Config\Database::connect();
-      $db->transBegin();
+        $db = \Config\Database::connect();
+        $db->transBegin();
 
-      //아이템 삭제
-      $deleted = $db->table('ITEM_LIST')
+        //아이템 삭제
+        $deleted = $db->table('ITEM_LIST')
             ->where('SEQ', $seq)
             ->update(['DEL_YN' => 'Y']);
 
-      if ($db->transStatus() === false || !$deleted) {
-          $db->transRollback();
-          return $this->respond(['status' => 'fail', 'message' => '이벤트 삭제 중 오류가 발생했습니다.']);
-      }
-      $db->transCommit();
-      return $this->respond(['status' => 'success', 'message' => '이벤트가 삭제되었습니다.'], 200);
+        if ($db->transStatus() === false || !$deleted) {
+            $db->transRollback();
+            return $this->respond(['status' => 'fail', 'message' => '이벤트 삭제 중 오류가 발생했습니다.']);
+        }
+        $db->transCommit();
+        return $this->respond(['status' => 'success', 'message' => '이벤트가 삭제되었습니다.'], 200);
     }
-  }
+}

+ 99 - 5
pages/view/common/item/add.vue

@@ -34,6 +34,49 @@
                   </div>
                 </td>
               </tr>
+              <tr  v-if="itemType == 'G'">
+                <th class="bg le">인플루언서<span v-if="pageType !== 'D'" class="bul">*</span></th>
+                <td>
+                  <v-text-field
+                    maxlength="50"
+                    v-model="form.contact_inf"
+                    style="width: 20%"
+                    :rules="[useValid.required('인플루언서')]"
+                    readonly=""
+                    class="custom-input mini left"
+                    placeholder="인플루언서를 입력하세요"
+                  ></v-text-field>
+                </td>
+              </tr>
+              <tr v-if="itemType == 'G'">
+                <th class="bg le">공동구매 기간<span v-if="pageType !== 'D'" class="bul">*</span></th>
+                <td>
+                  <div class="search--inner">
+                    <div class="calendar-wrap ml--0">
+                      <div class="calendar">
+                        <VueDatePicker
+                          :format="datePickerFormat"
+                          v-model="orderStartDate"
+                          placeholder="날짜를 선택하세요"
+                          :auto-apply="true"
+                          week-start="0"
+                        ></VueDatePicker>
+                      </div>
+                      <span class="text">~</span>
+                      <div class="calendar">
+                        <VueDatePicker
+                          v-model="orderEndDate"
+                          :format="datePickerFormat"
+                          placeholder="날짜를 선택하세요"
+                          :auto-apply="true"
+                          week-start="0"
+                          :min-date="orderStartDate"
+                        ></VueDatePicker>
+                      </div>
+                    </div>
+                  </div>
+                </td>
+              </tr>
               <tr>
                 <th class="bg le">공급가<span v-if="pageType !== 'D'" class="bul">*</span></th>
                   <td v-if="pageType == 'D'">
@@ -87,6 +130,20 @@
                   </div>
                 </td>
               </tr>
+              <tr v-if="itemType == 'G'">
+                <th class="bg le">공동구매 링크</th>
+                <td>
+                  <div class="input--wrap">
+                      <v-text-field
+                      maxlength="50"
+                      v-model="form.order_link"
+                      style="width: 100%"
+                      class="custom-input mini left"
+                      placeholder="공동구매 링크를 입력하세요"
+                    ></v-text-field>
+                  </div>
+                </td>
+              </tr>
               <tr>
                 <th class="bg le">썸네일 이미지</th>
                 <td>
@@ -265,7 +322,8 @@
 <script setup>
 import SunEditorWrapper from "@/components/sunEdt.vue";
 import useAxios from "@/composables/useAxios";
-
+import VueDatePicker from "@vuepic/vue-datepicker";
+import "@vuepic/vue-datepicker/dist/main.css";
 /************************************************************************
 |    레이아웃
 ************************************************************************/
@@ -285,7 +343,10 @@ const useAtStore = useAuthStore();
 const { $toast, $log, $dayjs, $eventBus } = useNuxtApp();
 const router = useRouter();
 const pageId = ref("");
-
+const itemType = useDtStore.boardInfo.itemType;
+const orderStartDate = ref("");
+const orderEndDate = ref("");
+const datePickerFormat = "yyyy-MM-dd";
 const sunEditorWrapper = ref(null); //에디터용 전역
 const updatedContent = ref(null); //에디터용 전역
 const editorContentReq = ref(); //에디터용 전역
@@ -319,6 +380,8 @@ const form = ref({
     { title: "비노출", value: "N" },
   ],
   formValue10: "",
+  contact_inf: "18",
+  order_link: "",
 });
 const apiUrl = ref("");
 
@@ -495,6 +558,11 @@ const fnInsert = async () => {
   formData.append('status', form.value.formValue8);
   formData.append('show_yn', form.value.formValue9);
   formData.append('add_info', form.value.formValue10);
+  formData.append('order_link', form.value.order_link);
+  formData.append('order_start_date', form.value.order_start_date);
+  formData.append('order_end_date', form.value.order_end_date);
+  formData.append('item_type', itemType);
+  formData.append('contact_inf', 18);
   // 벤더사의 COMPANY_NUMBER 사용
   const memberCompanyNumber = useAtStore.auth.companyNumber || "1";
   formData.append('company_number', memberCompanyNumber);
@@ -720,11 +788,23 @@ onMounted(() => {
   pageType.value = useDtStore.boardInfo.pageType;
   
   if(pageType.value == "I"){
-    pageId.value = "제품 등록"
+    if(itemType == "G"){
+      pageId.value = "공동구매 제품 등록"
+    } else {
+      pageId.value = "제품 등록"
+    }
   } else if(pageType.value == "U"){
-    pageId.value = "제품 수정"
+    if(itemType == "G"){
+      pageId.value = "공동구매 제품 수정"
+    } else {
+      pageId.value = "제품 수정"
+    }
   } else  {
-    pageId.value = "제품 상세"
+    if(itemType == "G"){
+      pageId.value = "공동구매 제품 상세"
+    } else {
+      pageId.value = "제품 상세"
+    }
   }
 
   //상세 등록 아니 리스트 클릭시 상세 정보로 접근
@@ -736,4 +816,18 @@ onMounted(() => {
 /************************************************************************
 |    WATCH
 ************************************************************************/
+
+// 시작일이 변경될 때, 종료일이 시작일보다 이전이면 종료일을 시작일과 같게 설정
+watch(orderStartDate, (newStartDate) => {
+  if (newStartDate && orderEndDate.value && orderEndDate.value < newStartDate) {
+    orderEndDate.value = newStartDate;
+  }
+});
+
+// 종료일이 변경될 때, 종료일이 시작일보다 이전이면 시작일과 같게 설정
+watch(orderEndDate, (newEndDate) => {
+  if (newEndDate && orderStartDate.value && newEndDate < orderStartDate.value) {
+    orderEndDate.value = orderStartDate.value;
+  }
+});
 </script>

+ 10 - 3
pages/view/common/item/index.vue

@@ -72,10 +72,10 @@
     <div class="data--list--wrap">
       <div class="btn--actions--wrap">
         <div class="left--sections">
-          <v-btn class="custom-btn btn-pink bdrs--10"
+          <v-btn class="custom-btn bdrs--10" :class="itemType == 'E' ? 'btn-pink' : 'btn-white'" @click="itemType = 'E'"
             ><i class="ico"></i>개별 배송</v-btn
           >
-          <v-btn class="custom-btn bdrs--10 btn-white" @click="deliLocated()"
+          <v-btn class="custom-btn bdrs--10" :class="itemType == 'E' ? 'btn-white' : 'btn-pink'" @click="itemType = 'G'"
             ><i class="ico"></i>공동구매 배송</v-btn
           >
         </div>
@@ -157,6 +157,7 @@ import dayjs from 'dayjs';
   /************************************************************************
 |    전역
  ************************************************************************/
+  const itemType = ref("E");
   const memberType = useAtStore.auth.memberType;
   const searchModel = ref("");
   const selectedRange = ref('all');
@@ -242,6 +243,7 @@ import dayjs from 'dayjs';
       path: "/view/common/item/add",
     });
     useDtStore.boardInfo.pageType = "I";
+    useDtStore.boardInfo.itemType = itemType.value;
   };
 
   const toItemDetail = (__EVENT) => {
@@ -249,6 +251,7 @@ import dayjs from 'dayjs';
       path: "/view/common/item/add",
     });
     useDtStore.boardInfo.seq = __EVENT;
+    useDtStore.boardInfo.itemType = itemType;
     //제품 등록한 벤더의 경우 U로, 인플루언서의 경우 D로
     memberType == 'INFLUENCER' ? useDtStore.boardInfo.pageType = "D" : useDtStore.boardInfo.pageType = "U";
   };
@@ -257,7 +260,7 @@ import dayjs from 'dayjs';
     let _req = {
       // Y : 노출, N : 비노출
       SHOW_YN: "",
-      TYPE: "E"
+      TYPE: itemType.value,
     };
 
     if (memberType === "INFLUENCER") {
@@ -332,6 +335,10 @@ import dayjs from 'dayjs';
 |    WATCH
 ************************************************************************/
 
+  watch(itemType, () => {
+    itemListGet();
+  });
+
   
   onMounted(() => {
     itemListGet();

+ 1 - 0
stores/detail.js

@@ -10,6 +10,7 @@ export const useDetailStore = defineStore('detailStore', () => {
     seq : '',
     pageType : '',
     status: '',
+    itemType: '',
   })
 
   const adminInfo = ref({