Преглед изворни кода

Merge branch 'master' of https://gogs.interscope.i234.me/mo0647/influence

* 'master' of https://gogs.interscope.i234.me/mo0647/influence:
  배송관리
송용우 пре 4 месеци
родитељ
комит
19020e0ed3
3 измењених фајлова са 182 додато и 22 уклоњено
  1. 3 0
      backend/app/Controllers/Deli.php
  2. 2 1
      pages/view/common/deli/index.vue
  3. 177 21
      pages/view/common/deli/index2.vue

+ 3 - 0
backend/app/Controllers/Deli.php

@@ -14,6 +14,7 @@ class Deli extends ResourceController
         // POST JSON 파라미터 받기
         $request = $this->request->getJSON(true);
 
+        $itemType = isset($request['TYPE']) ? $request['TYPE'] : null;
         $showYn = isset($request['SHOW_YN']) ? $request['SHOW_YN'] : null;
         $infSeq = isset($request['INF_SEQ']) ? $request['INF_SEQ'] : null;
         $memberType = isset($request['MEMBER_TYPE']) ? $request['MEMBER_TYPE'] : null;
@@ -58,6 +59,8 @@ class Deli extends ResourceController
             $builder->where('I.SHOW_YN', $showYn);
         }
 
+        $builder->where('I.TYPE', $itemType);
+
         $builder->orderBy('I.UDPDATE', 'DESC');
 
         $lists = $builder->get()->getResultArray();

+ 2 - 1
pages/view/common/deli/index.vue

@@ -355,7 +355,8 @@ import pagination from "../components/common/pagination.vue";
 
   const itemListGet = async () => {
     let _req = {
-      MEMBER_TYPE: memberType
+      MEMBER_TYPE: memberType,
+      TYPE: "E"
     };
 
     if (memberType === "INFLUENCER") {

+ 177 - 21
pages/view/common/deli/index2.vue

@@ -72,17 +72,27 @@
     <div class="data--list--wrap">
       <div class="btn--actions--wrap">
         <div class="left--sections">
-          <v-btn class="custom-btn bdrs--10 btn-white" @click="deliLocated()"
+          <v-btn class="custom-btn btn-white bdrs--10" @click="deliLocated()"
             ><i class="ico"></i>개별 배송</v-btn
           >
-          <v-btn class="custom-btn btn-pink bdrs--10"
+          <v-btn class="custom-btn bdrs--10 btn-pink"
             ><i class="ico"></i>공동구매 배송</v-btn
           >
         </div>
         <div class="right--sections">
+          <div class="status-filter">
+            <v-select
+              v-model="statusFilter"
+              :items="statusOptions"
+              variant="outlined"
+              class="custom-select mini"
+              style="width: 120px; margin-right: 8px;"
+              @update:modelValue="applyStatusFilter"
+            >
+            </v-select>
+          </div>
         </div>
       </div>
-
       <div class="tbl-wrapper">
         <div class="tbl-wrap">
           <!-- ag grid -->
@@ -134,9 +144,12 @@ import pagination from "../components/common/pagination.vue";
 |    스토어
  ************************************************************************/
   const useDtStore = useDetailStore();
+  const useAtStore = useAuthStore();
   /************************************************************************
-|    전역
- ************************************************************************/
+   |    전역
+   ************************************************************************/
+  const memberType = useAtStore.auth.memberType;
+  const memberSeq = useAtStore.auth.seq;
   const searchModel = ref("");
   const selectedRange = ref('all');
   const itemStartDate = ref("");
@@ -155,6 +168,14 @@ import pagination from "../components/common/pagination.vue";
     { title: "전체", value: "" },
     { title: "제품명", value: "name" },
   ]);
+  const statusFilter = ref("ALL");
+  const statusOptions = ref([
+    { title: "전체", value: "ALL" },
+    { title: "신규", value: "NEW" },
+    { title: "대기", value: "PENDING" },
+    { title: "완료", value: "COMPLETE" }
+  ]);
+  const originalTblItems = ref([]); // 원본 데이터 저장용
   const { $toast, $log, $dayjs, $eventBus } = useNuxtApp();
   const router = useRouter();
   const pageId = ref("배송 관리");
@@ -191,28 +212,72 @@ import pagination from "../components/common/pagination.vue";
         headerName: "제품명",
         field: "NAME",
         //sortable: useAuthStore().getCompanyId == "0-000000" ? true : false,
+        cellRenderer: (params) => {
+          const status = params.data.status || 'NEW';
+          const productName = params.value || '';
+          const isVendor = memberType !== 'INFLUENCER';
+          
+          if (isVendor && status === 'NEW') {
+            return `
+              <div style="display: flex; align-items: center; gap: 8px; justify-content: space-between; width: 100%;">
+                <span style="flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">${productName}</span>
+                <span class="custom-new-badge" style="
+                  background: #f44336 !important;
+                  color: white;
+                  font-size: 10px;
+                  padding: 2px 6px;
+                  border-radius: 12px;
+                  min-width: 30px;
+                  height: 18px;
+                  display: inline-flex;
+                  align-items: center;
+                  justify-content: center;
+                  font-weight: bold;
+                  flex-shrink: 0;
+                ">NEW</span>
+              </div>
+            `;
+          }
+          return productName;
+        }
       },
       {
         headerName: "제품 총수량",
-        field: "STATUS",
+        field: "sum_qty",
         width: 140,
         cellRenderer: (params) => {
-          return params.value;
+          return Number(params.value).toLocaleString();
         },
       },
       {
         headerName: "총 주문금액",
-        field: "STATUS",
+        field: "sum_total",
         width: 140,
         cellRenderer: (params) => {
-          return params.value;
+          return Number(params.value).toLocaleString();
         },
       },
       {
         headerName: "주문일",
-        field: "ORDDATE",
+        field: "latest_reg_date",
         width: 140,
       },
+      {
+        headerName: "상태",
+        field: "status",
+        width: 120,
+        cellRenderer: (params) => {
+          const status = params.value || 'NEW';
+          const statusMap = {
+            'NEW': { text: '신규', color: 'primary', variant: 'elevated' },
+            'PENDING': { text: '대기', color: 'warning', variant: 'elevated' },
+            'COMPLETE': { text: '완료', color: 'success', variant: 'elevated' }
+          };
+          const config = statusMap[status] || statusMap['NEW'];
+          
+          return `<span class="v-chip v-chip--density-default v-chip--size-default v-chip--variant-${config.variant} bg-${config.color}" style="font-size: 12px; padding: 4px 8px;">${config.text}</span>`;
+        }
+      },
     ],
     rowData: tblItems.value, // 테이블 데이터
     autoSizeStrategy: {
@@ -285,24 +350,32 @@ import pagination from "../components/common/pagination.vue";
     router.push({
       path: "/view/common/deli/detail",
     });
-    useDtStore.adminInfo.adminId = __EVENT.data.ID;
-    useDtStore.adminInfo.pageType = "U";
+    useDtStore.boardInfo.seq = __EVENT.data.SEQ;
   };
 
   const itemListGet = async () => {
     let _req = {
-      // compId: useAuthStore().getCompanyId,
+      MEMBER_TYPE: memberType,
+      TYPE: "G",
     };
 
+    if (memberType === "INFLUENCER") {
+      _req.INF_SEQ = memberSeq;
+    } else if (memberType === "VENDOR") {
+      _req.COMPANY_NUMBER = useAtStore.auth.companyNumber || "1";
+    }
+
     useAxios()
-      .post("/item/list", _req)
+      .post("/deli/itemlist", _req)
       .then((res) => {
-        tblItems.value = res.data;
-        pageObj.value.totalCnt = tblItems.value.length;
+        originalTblItems.value = res.data;
+        applyStatusFilter();
 
-        itemStartDate.value = res.data[res.data.length-1].UDPDATE;
-        searchStartDate.value = itemStartDate.value;
-        searchEndDate.value = dayjs();
+        if (res.data.length > 0) {
+          itemStartDate.value = res.data[res.data.length-1].UDPDATE;
+          searchStartDate.value = itemStartDate.value;
+          searchEndDate.value = dayjs();
+        }
       });
   };
 
@@ -317,11 +390,30 @@ import pagination from "../components/common/pagination.vue";
     useAxios()
       .post("/item/search", _req)
       .then((res) => {
-        tblItems.value = res.data;
-        pageObj.value.totalCnt = tblItems.value.length;
+        originalTblItems.value = res.data;
+        applyStatusFilter();
       })
       .catch((error) => {});
   };
+
+  const applyStatusFilter = () => {
+    let filteredData = originalTblItems.value;
+    
+    if (statusFilter.value !== "ALL") {
+      filteredData = originalTblItems.value.filter(item => {
+        const itemStatus = item.status || 'NEW';
+        return itemStatus === statusFilter.value;
+      });
+    }
+    
+    tblItems.value = filteredData;
+    pageObj.value.totalCnt = tblItems.value.length;
+    
+    // ag-grid 데이터 갱신
+    if (gridApi.value) {
+      gridApi.value.setGridOption('rowData', tblItems.value);
+    }
+  };
   /************************************************************************
 |    팝업 이벤트버스 정의
 ************************************************************************/
@@ -340,5 +432,69 @@ import pagination from "../components/common/pagination.vue";
 
   onMounted(() => {
     itemListGet();
+    
+    // 업로드 상태 확인 및 사용자 피드백
+    const route = useRoute();
+    if (route.query.uploadStatus === 'success') {
+      const recordCount = route.query.recordCount || '0';
+      const itemId = route.query.itemId;
+      
+      $toast.success(`송장 정보가 성공적으로 등록되었습니다. (${recordCount}건)`);
+      
+      // URL에서 쿼리 파라미터 제거
+      router.replace({ path: '/view/common/deli' });
+    }
+
+    // 실시간 이벤트 리스너 등록
+    $eventBus.on('DELIVERY_STATUS_CHANGED', handleDeliveryStatusChange);
+    $eventBus.on('NEW_ORDER_RECEIVED', handleNewOrderReceived);
   });
+
+  onUnmounted(() => {
+    // 이벤트 리스너 제거
+    $eventBus.off('DELIVERY_STATUS_CHANGED', handleDeliveryStatusChange);
+    $eventBus.off('NEW_ORDER_RECEIVED', handleNewOrderReceived);
+  });
+
+  const handleDeliveryStatusChange = (data) => {
+    // 해당 아이템의 상태 업데이트
+    const itemIndex = originalTblItems.value.findIndex(item => item.SEQ == data.itemId);
+    if (itemIndex !== -1) {
+      originalTblItems.value[itemIndex].status = data.status;
+      
+      // 필터 재적용
+      applyStatusFilter();
+      
+      console.log('배송 상태 업데이트됨:', data);
+    }
+  };
+
+  const handleNewOrderReceived = (data) => {
+    // 새 주문 데이터를 리스트에 추가
+    const newOrder = {
+      SEQ: data.itemId,
+      NAME: data.itemName,
+      sum_qty: data.totalQty || 0,
+      sum_total: data.totalAmount || 0,
+      latest_reg_date: data.orderDate,
+      status: 'NEW'
+    };
+    
+    originalTblItems.value.unshift(newOrder);
+    applyStatusFilter();
+    
+    console.log('새 주문 추가됨:', data);
+  };
 </script>
+
+<style scoped>
+.status-filter {
+  display: flex;
+  align-items: center;
+}
+
+.btn--actions--wrap .right--sections {
+  display: flex;
+  align-items: center;
+}
+</style>