|
|
@@ -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>
|