187 lines
4.8 KiB
TypeScript
187 lines
4.8 KiB
TypeScript
|
|
/**
|
||
|
|
* 배송/화물 관리 서비스
|
||
|
|
*
|
||
|
|
* 실제 데이터베이스 연동 시 필요한 메서드들을 미리 정의
|
||
|
|
*/
|
||
|
|
|
||
|
|
import pool from '../database/db';
|
||
|
|
|
||
|
|
export interface DeliveryItem {
|
||
|
|
id: string;
|
||
|
|
trackingNumber: string;
|
||
|
|
customer: string;
|
||
|
|
origin: string;
|
||
|
|
destination: string;
|
||
|
|
status: 'in_transit' | 'delivered' | 'delayed' | 'pickup_waiting';
|
||
|
|
estimatedDelivery: string;
|
||
|
|
delayReason?: string;
|
||
|
|
priority: 'high' | 'normal' | 'low';
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface CustomerIssue {
|
||
|
|
id: string;
|
||
|
|
customer: string;
|
||
|
|
trackingNumber: string;
|
||
|
|
issueType: 'damage' | 'delay' | 'missing' | 'other';
|
||
|
|
description: string;
|
||
|
|
status: 'open' | 'in_progress' | 'resolved';
|
||
|
|
reportedAt: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface TodayStats {
|
||
|
|
shipped: number;
|
||
|
|
delivered: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface DeliveryStatusResponse {
|
||
|
|
deliveries: DeliveryItem[];
|
||
|
|
issues: CustomerIssue[];
|
||
|
|
todayStats: TodayStats;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 배송 현황 조회
|
||
|
|
*
|
||
|
|
* TODO: 실제 DB 연동 시 구현 필요
|
||
|
|
* - 테이블명: deliveries (배송 정보)
|
||
|
|
* - 테이블명: customer_issues (고객 이슈)
|
||
|
|
*
|
||
|
|
* 예상 쿼리:
|
||
|
|
* SELECT * FROM deliveries WHERE DATE(created_at) = CURRENT_DATE
|
||
|
|
* SELECT * FROM customer_issues WHERE status != 'resolved' ORDER BY reported_at DESC
|
||
|
|
*/
|
||
|
|
export async function getDeliveryStatus(): Promise<DeliveryStatusResponse> {
|
||
|
|
try {
|
||
|
|
// TODO: 실제 DB 쿼리로 교체
|
||
|
|
// const deliveriesResult = await pool.query(
|
||
|
|
// `SELECT
|
||
|
|
// id, tracking_number as "trackingNumber", customer, origin, destination,
|
||
|
|
// status, estimated_delivery as "estimatedDelivery", delay_reason as "delayReason",
|
||
|
|
// priority
|
||
|
|
// FROM deliveries
|
||
|
|
// WHERE deleted_at IS NULL
|
||
|
|
// ORDER BY created_at DESC`
|
||
|
|
// );
|
||
|
|
|
||
|
|
// const issuesResult = await pool.query(
|
||
|
|
// `SELECT
|
||
|
|
// id, customer, tracking_number as "trackingNumber", issue_type as "issueType",
|
||
|
|
// description, status, reported_at as "reportedAt"
|
||
|
|
// FROM customer_issues
|
||
|
|
// WHERE deleted_at IS NULL
|
||
|
|
// ORDER BY reported_at DESC`
|
||
|
|
// );
|
||
|
|
|
||
|
|
// const statsResult = await pool.query(
|
||
|
|
// `SELECT
|
||
|
|
// COUNT(*) FILTER (WHERE status = 'in_transit') as shipped,
|
||
|
|
// COUNT(*) FILTER (WHERE status = 'delivered') as delivered
|
||
|
|
// FROM deliveries
|
||
|
|
// WHERE DATE(created_at) = CURRENT_DATE
|
||
|
|
// AND deleted_at IS NULL`
|
||
|
|
// );
|
||
|
|
|
||
|
|
// 임시 응답 (개발용)
|
||
|
|
return {
|
||
|
|
deliveries: [],
|
||
|
|
issues: [],
|
||
|
|
todayStats: {
|
||
|
|
shipped: 0,
|
||
|
|
delivered: 0,
|
||
|
|
},
|
||
|
|
};
|
||
|
|
} catch (error) {
|
||
|
|
console.error('배송 현황 조회 실패:', error);
|
||
|
|
throw error;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 지연 배송 목록 조회
|
||
|
|
*/
|
||
|
|
export async function getDelayedDeliveries(): Promise<DeliveryItem[]> {
|
||
|
|
try {
|
||
|
|
// TODO: 실제 DB 쿼리로 교체
|
||
|
|
// const result = await pool.query(
|
||
|
|
// `SELECT * FROM deliveries
|
||
|
|
// WHERE status = 'delayed'
|
||
|
|
// AND deleted_at IS NULL
|
||
|
|
// ORDER BY estimated_delivery ASC`
|
||
|
|
// );
|
||
|
|
|
||
|
|
return [];
|
||
|
|
} catch (error) {
|
||
|
|
console.error('지연 배송 조회 실패:', error);
|
||
|
|
throw error;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 고객 이슈 목록 조회
|
||
|
|
*/
|
||
|
|
export async function getCustomerIssues(status?: string): Promise<CustomerIssue[]> {
|
||
|
|
try {
|
||
|
|
// TODO: 실제 DB 쿼리로 교체
|
||
|
|
// const query = status
|
||
|
|
// ? `SELECT * FROM customer_issues WHERE status = $1 AND deleted_at IS NULL ORDER BY reported_at DESC`
|
||
|
|
// : `SELECT * FROM customer_issues WHERE deleted_at IS NULL ORDER BY reported_at DESC`;
|
||
|
|
|
||
|
|
// const result = status
|
||
|
|
// ? await pool.query(query, [status])
|
||
|
|
// : await pool.query(query);
|
||
|
|
|
||
|
|
return [];
|
||
|
|
} catch (error) {
|
||
|
|
console.error('고객 이슈 조회 실패:', error);
|
||
|
|
throw error;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 배송 정보 업데이트
|
||
|
|
*/
|
||
|
|
export async function updateDeliveryStatus(
|
||
|
|
id: string,
|
||
|
|
status: DeliveryItem['status'],
|
||
|
|
delayReason?: string
|
||
|
|
): Promise<void> {
|
||
|
|
try {
|
||
|
|
// TODO: 실제 DB 쿼리로 교체
|
||
|
|
// await pool.query(
|
||
|
|
// `UPDATE deliveries
|
||
|
|
// SET status = $1, delay_reason = $2, updated_at = NOW()
|
||
|
|
// WHERE id = $3`,
|
||
|
|
// [status, delayReason, id]
|
||
|
|
// );
|
||
|
|
|
||
|
|
console.log(`배송 상태 업데이트: ${id} -> ${status}`);
|
||
|
|
} catch (error) {
|
||
|
|
console.error('배송 상태 업데이트 실패:', error);
|
||
|
|
throw error;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 고객 이슈 상태 업데이트
|
||
|
|
*/
|
||
|
|
export async function updateIssueStatus(
|
||
|
|
id: string,
|
||
|
|
status: CustomerIssue['status']
|
||
|
|
): Promise<void> {
|
||
|
|
try {
|
||
|
|
// TODO: 실제 DB 쿼리로 교체
|
||
|
|
// await pool.query(
|
||
|
|
// `UPDATE customer_issues
|
||
|
|
// SET status = $1, updated_at = NOW()
|
||
|
|
// WHERE id = $2`,
|
||
|
|
// [status, id]
|
||
|
|
// );
|
||
|
|
|
||
|
|
console.log(`이슈 상태 업데이트: ${id} -> ${status}`);
|
||
|
|
} catch (error) {
|
||
|
|
console.error('이슈 상태 업데이트 실패:', error);
|
||
|
|
throw error;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|