Explorar el Código

+ 업데이트

송용우 hace 4 meses
padre
commit
f2d2e882d7
Se han modificado 2 ficheros con 198 adiciones y 41 borrados
  1. 91 25
      backend/app/Controllers/Deli.php
  2. 107 16
      pages/view/common/deli/detail.vue

+ 91 - 25
backend/app/Controllers/Deli.php

@@ -110,6 +110,7 @@ class Deli extends ResourceController
         $itemSeq = isset($request['item_seq']) ? $request['item_seq'] : null;
         $infSeq = isset($request['inf_seq']) ? $request['inf_seq'] : null;
         $deliveryList = $request['deliveryList'] ?? [];
+        $useOrderDateMatching = isset($request['useOrderDateMatching']) ? $request['useOrderDateMatching'] : false;
 
         // 🔍 먼저 전체 유효성 검사
         foreach ($deliveryList as $index => $delivery) {
@@ -121,32 +122,97 @@ class Deli extends ResourceController
             }
         }
 
-        // ✅ 유효성 통과 후 삭제 + 삽입
-        $db->table('ITEM_ORDER_LIST')
-            ->where('ITEM_SEQ', $itemSeq)
-            ->where('INF_SEQ', $infSeq)
-            ->delete();
-
-        foreach ($deliveryList as $delivery) {
-            $data = [
-                'ITEM_SEQ' => $itemSeq,
-                'INF_SEQ' => $infSeq,
-                'BUYER_NAME' => $delivery['buyerName'],
-                'ADDRESS' => $delivery['address'],
-                'PHONE' => $delivery['phone'],
-                'EMAIL' => $delivery['email'],
-                'QTY' => $delivery['qty'],
-                'TOTAL' => $delivery['total'],
-                'DELI_COMP' => $delivery['deliComp'] ?? '',
-                'DELI_NUMB' => $delivery['deliNumb'] ?? '',
-                'ORDER_DATE' => date('Y-m-d H:i:s', strtotime($delivery['orderDate'])),
-                'REG_DATE' => date('Y-m-d'),
-            ];
-
-            $db->table('ITEM_ORDER_LIST')->insert($data);
-        }
+        $db->transBegin();
+        $insertCount = 0;
+        $updateCount = 0;
+
+        try {
+            if ($useOrderDateMatching) {
+                // 주문일 기준 매칭 방식 (신규 로직)
+                foreach ($deliveryList as $delivery) {
+                    $orderDate = date('Y-m-d', strtotime($delivery['orderDate']));
+                    
+                    // 기존 데이터 확인 (구매자명, 연락처, 주문일로 매칭)
+                    $existingOrder = $db->table('ITEM_ORDER_LIST')
+                        ->where('ITEM_SEQ', $itemSeq)
+                        ->where('INF_SEQ', $infSeq)
+                        ->where('BUYER_NAME', $delivery['buyerName'])
+                        ->where('PHONE', $delivery['phone'])
+                        ->where('DATE(ORDER_DATE)', $orderDate)
+                        ->get()
+                        ->getRowArray();
+
+                    $data = [
+                        'ITEM_SEQ' => $itemSeq,
+                        'INF_SEQ' => $infSeq,
+                        'BUYER_NAME' => $delivery['buyerName'],
+                        'ADDRESS' => $delivery['address'],
+                        'PHONE' => $delivery['phone'],
+                        'EMAIL' => $delivery['email'],
+                        'QTY' => $delivery['qty'],
+                        'TOTAL' => $delivery['total'],
+                        'DELI_COMP' => $delivery['deliComp'] ?? '',
+                        'DELI_NUMB' => $delivery['deliNumb'] ?? '',
+                        'ORDER_DATE' => date('Y-m-d H:i:s', strtotime($delivery['orderDate'])),
+                        'REG_DATE' => date('Y-m-d'),
+                    ];
+
+                    if ($existingOrder) {
+                        // 기존 주문 업데이트
+                        $db->table('ITEM_ORDER_LIST')
+                            ->where('SEQ', $existingOrder['SEQ'])
+                            ->update($data);
+                        $updateCount++;
+                    } else {
+                        // 신규 주문 삽입
+                        $db->table('ITEM_ORDER_LIST')->insert($data);
+                        $insertCount++;
+                    }
+                }
+            } else {
+                // 기존 방식 (전체 삭제 후 재등록)
+                $db->table('ITEM_ORDER_LIST')
+                    ->where('ITEM_SEQ', $itemSeq)
+                    ->where('INF_SEQ', $infSeq)
+                    ->delete();
+
+                foreach ($deliveryList as $delivery) {
+                    $data = [
+                        'ITEM_SEQ' => $itemSeq,
+                        'INF_SEQ' => $infSeq,
+                        'BUYER_NAME' => $delivery['buyerName'],
+                        'ADDRESS' => $delivery['address'],
+                        'PHONE' => $delivery['phone'],
+                        'EMAIL' => $delivery['email'],
+                        'QTY' => $delivery['qty'],
+                        'TOTAL' => $delivery['total'],
+                        'DELI_COMP' => $delivery['deliComp'] ?? '',
+                        'DELI_NUMB' => $delivery['deliNumb'] ?? '',
+                        'ORDER_DATE' => date('Y-m-d H:i:s', strtotime($delivery['orderDate'])),
+                        'REG_DATE' => date('Y-m-d'),
+                    ];
+
+                    $db->table('ITEM_ORDER_LIST')->insert($data);
+                    $insertCount++;
+                }
+            }
 
-        return $this->respond(['message' => '배송 데이터가 성공적으로 저장되었습니다.'], 200);
+            $db->transCommit();
+            
+            if ($useOrderDateMatching) {
+                return $this->respond([
+                    'message' => '배송 데이터가 성공적으로 저장되었습니다.',
+                    'insert_count' => $insertCount,
+                    'update_count' => $updateCount
+                ], 200);
+            } else {
+                return $this->respond(['message' => '배송 데이터가 성공적으로 저장되었습니다.'], 200);
+            }
+
+        } catch (\Exception $e) {
+            $db->transRollback();
+            return $this->fail('배송 데이터 저장 중 오류가 발생했습니다: ' . $e->getMessage(), 500);
+        }
     }
 
     //벤더사용 배송정보 업데이트

+ 107 - 16
pages/view/common/deli/detail.vue

@@ -144,6 +144,7 @@
   });
   const imgTemp = ref("");
   const tblItems = ref([]); // stat 데이터
+  const isExcelProcessed = ref(false); // 엑셀 업로드로 데이터가 처리되었는지 여부
   const form = ref({
     formValue1: "",
     formValue2: "",
@@ -330,6 +331,7 @@
     // 맨 앞에 추가 (unshift 사용)
     tblItems.value.unshift(newRow);
     pageObj.value.totalCnt = tblItems.value.length;
+    isExcelProcessed.value = false; // 수동 추가이므로 엑셀 처리 아님
 
     // ag-grid 데이터 갱신
     if (gridApi.value) {
@@ -502,13 +504,14 @@
           return;
         }
 
-        // 기존 주문 데이터와 매칭 검증
-        const matchResults = await validateAndMatchOrders(mappedData);
-        const { matchedData, unmatchedData, errors } = matchResults;
+        // 기존 데이터와 엑셀 데이터를 주문일 기준으로 분리 처리
+        const processResult = await processInfluencerExcelData(mappedData);
+        const { updatedData, newData, errors } = processResult;
 
-        // 매칭된 데이터만 그리드에 추가
-        tblItems.value = [...matchedData];
+        // 업데이트된 기존 데이터 + 신규 데이터를 합쳐서 그리드에 설정
+        tblItems.value = [...updatedData, ...newData];
         pageObj.value.totalCnt = tblItems.value.length;
+        isExcelProcessed.value = true; // 엑셀 처리 완료 표시
 
         // ag-grid 데이터 갱신
         if (gridApi.value) {
@@ -516,20 +519,29 @@
         }
 
         // 결과에 따른 사용자 피드백
-        if (matchedData.length > 0 && unmatchedData.length === 0) {
-          $toast.success(
-            `${matchedData.length}건의 데이터가 성공적으로 업로드되었습니다.`
-          );
-        } else if (matchedData.length > 0 && unmatchedData.length > 0) {
-          $toast.warning(
-            `${matchedData.length}건 업로드 완료, ${unmatchedData.length}건 매칭 실패`
-          );
-          showUnmatchedDataModal(unmatchedData, errors);
+        const totalProcessed = updatedData.length + newData.length;
+        if (totalProcessed > 0) {
+          if (updatedData.length > 0 && newData.length > 0) {
+            $toast.success(
+              `총 ${totalProcessed}건 처리완료 (업데이트: ${updatedData.length}건, 신규: ${newData.length}건)`
+            );
+          } else if (updatedData.length > 0) {
+            $toast.success(
+              `${updatedData.length}건의 기존 주문이 업데이트되었습니다.`
+            );
+          } else {
+            $toast.success(
+              `${newData.length}건의 신규 주문이 추가되었습니다.`
+            );
+          }
         } else {
           $toast.error(
-            "매칭된 주문 데이터가 없습니다. 구매자명과 연락처를 확인해주세요."
+            "처리된 데이터가 없습니다. 엑셀 데이터를 확인해주세요."
           );
-          showUnmatchedDataModal(unmatchedData, errors);
+        }
+
+        if (errors.length > 0) {
+          console.warn("처리 중 발생한 오류들:", errors);
         }
       } catch (error) {
         console.error("엑셀 파일 처리 중 오류:", error);
@@ -721,6 +733,83 @@
     }
   };
 
+  const processInfluencerExcelData = async (uploadData) => {
+    const updatedData = [];
+    const newData = [];
+    const errors = [];
+
+    // 기존 데이터를 맵으로 변환 (구매자명 + 연락처 키로 매핑)
+    const existingDataMap = new Map();
+    tblItems.value.forEach(item => {
+      const key = `${item.BUYER_NAME?.trim()}_${item.PHONE?.replace(/\s/g, '').replace(/-/g, '')}`;
+      existingDataMap.set(key, item);
+    });
+
+    uploadData.forEach((excelItem, index) => {
+      try {
+        // 엑셀 데이터의 키 생성
+        const key = `${excelItem.BUYER_NAME?.trim()}_${excelItem.PHONE?.replace(/\s/g, '').replace(/-/g, '')}`;
+        const existingItem = existingDataMap.get(key);
+
+        if (existingItem) {
+          // 기존 데이터가 있는 경우 주문일 비교
+          const existingOrderDate = formatDateForComparison(existingItem.ORDER_DATE);
+          const excelOrderDate = formatDateForComparison(excelItem.ORDER_DATE);
+
+          if (existingOrderDate === excelOrderDate) {
+            // 주문일이 같으면 업데이트 (배송정보 등 다른 필드 업데이트)
+            updatedData.push({
+              ...existingItem,
+              ADDRESS: excelItem.ADDRESS || existingItem.ADDRESS,
+              EMAIL: excelItem.EMAIL || existingItem.EMAIL,
+              QTY: excelItem.QTY || existingItem.QTY,
+              TOTAL: excelItem.TOTAL || existingItem.TOTAL,
+              DELI_COMP: excelItem.DELI_COMP || existingItem.DELI_COMP,
+              DELI_NUMB: excelItem.DELI_NUMB || existingItem.DELI_NUMB
+            });
+          } else {
+            // 주문일이 다르면 신규 데이터로 추가
+            newData.push({
+              ...excelItem,
+              // 인플루언서 정보는 기존 데이터에서 가져오기
+              NICK_NAME: existingItem.NICK_NAME || "알 수 없음"
+            });
+          }
+        } else {
+          // 기존 데이터가 없으면 신규 데이터로 추가
+          newData.push({
+            ...excelItem,
+            NICK_NAME: "알 수 없음" // 기본값
+          });
+        }
+      } catch (error) {
+        errors.push(`${index + 1}행 처리 중 오류: ${error.message}`);
+      }
+    });
+
+    // 업데이트되지 않은 기존 데이터도 유지
+    tblItems.value.forEach(existingItem => {
+      const key = `${existingItem.BUYER_NAME?.trim()}_${existingItem.PHONE?.replace(/\s/g, '').replace(/-/g, '')}`;
+      const hasUpdate = uploadData.some(excelItem => {
+        const excelKey = `${excelItem.BUYER_NAME?.trim()}_${excelItem.PHONE?.replace(/\s/g, '').replace(/-/g, '')}`;
+        return excelKey === key;
+      });
+
+      // 업데이트되지 않은 기존 데이터는 updatedData에 그대로 추가
+      if (!hasUpdate) {
+        updatedData.push(existingItem);
+      }
+    });
+
+    return { updatedData, newData, errors };
+  };
+
+  const formatDateForComparison = (dateStr) => {
+    if (!dateStr) return '';
+    // YYYY.MM.DD 또는 YYYY-MM-DD 형태를 YYYY-MM-DD로 통일
+    return dateStr.toString().replace(/\./g, '-').trim();
+  };
+
   const validateAndMatchOrders = async (uploadData) => {
     try {
       const response = await useAxios().post("/deli/validateOrders", {
@@ -872,6 +961,7 @@
         console.log(res.data);
         tblItems.value = res.data;
         pageObj.value.totalCnt = tblItems.value.length;
+        isExcelProcessed.value = false; // 초기 로드이므로 엑셀 처리 아님
       })
       .catch((error) => {
         $toast.error("제품 정보를 불러오는 중 오류가 발생했습니다.");
@@ -890,6 +980,7 @@
     const deliveryData = {
       item_seq: useDtStore.boardInfo.seq,
       inf_seq: memberSeq,
+      useOrderDateMatching: isExcelProcessed.value, // 엑셀 업로드로 처리된 경우 true
       deliveryList: tblItems.value.map((item) => ({
         buyerName: item.BUYER_NAME,
         address: item.ADDRESS,