109 lines
3.6 KiB
TypeScript
109 lines
3.6 KiB
TypeScript
import { http, unwrapApiResponse, type ApiEnvelope } from '@/shared/api/http'
|
|
|
|
|
|
export interface CustomerVisitAttachment {
|
|
fileId: string
|
|
fileName: string
|
|
contentType?: string | null
|
|
sizeBytes: number
|
|
}
|
|
|
|
export interface CustomerVisitRow {
|
|
id: string
|
|
customerId: string
|
|
deliveryNo: string
|
|
customerName?: string | null
|
|
contactName?: string | null
|
|
contactPhone?: string | null
|
|
destination?: string | null
|
|
deliveryCompletedAt: string
|
|
status: 'PENDING' | 'COMPLETED'
|
|
selectedInboundCode?: string | null
|
|
visitResult?: string | null
|
|
visitedAt?: string | null
|
|
visitCount: number
|
|
attachments: CustomerVisitAttachment[]
|
|
}
|
|
|
|
export interface CustomerVisitPage {
|
|
records: CustomerVisitRow[]
|
|
current: number
|
|
size: number
|
|
total: number
|
|
pages: number
|
|
visitable: number
|
|
pending: number
|
|
completed: number
|
|
}
|
|
|
|
export interface CustomerVisitInboundOption {
|
|
inboundOrderId: string
|
|
inboundCode: string
|
|
lastMileOrderId: string
|
|
lastMileOrderNo: string
|
|
destinationWarehouseCode?: string | null
|
|
destinationWarehouseName?: string | null
|
|
packageCount: number
|
|
}
|
|
|
|
export interface CustomerVisitDetail {
|
|
visit: CustomerVisitRow
|
|
inboundOrders: CustomerVisitInboundOption[]
|
|
customerFeedback?: string | null
|
|
remark?: string | null
|
|
visitedBy?: string | null
|
|
}
|
|
|
|
export async function listCustomerVisits(params: {
|
|
page: number
|
|
size: number
|
|
keyword?: string
|
|
status?: string
|
|
customerId?: string
|
|
completedFrom?: string
|
|
completedTo?: string
|
|
}) {
|
|
const response = await http.get<ApiEnvelope<CustomerVisitPage>, ApiEnvelope<CustomerVisitPage>>(
|
|
'/platform/v1/last-leg/customer-visits', { params },
|
|
)
|
|
return unwrapApiResponse(response)
|
|
}
|
|
|
|
export async function getCustomerVisit(visitId: string, customerId: string) {
|
|
const response = await http.get<ApiEnvelope<CustomerVisitDetail>, ApiEnvelope<CustomerVisitDetail>>(
|
|
`/platform/v1/last-leg/customer-visits/${encodeURIComponent(visitId)}`, { params: { customerId } },
|
|
)
|
|
return unwrapApiResponse(response)
|
|
}
|
|
|
|
export async function saveCustomerVisit(visitId: string, customerId: string, payload: {
|
|
selectedInboundOrderId: string
|
|
visitResult: string
|
|
customerFeedback?: string
|
|
remark?: string
|
|
attachments: CustomerVisitAttachment[]
|
|
}) {
|
|
const response = await http.put<ApiEnvelope<CustomerVisitDetail>, ApiEnvelope<CustomerVisitDetail>>(
|
|
`/platform/v1/last-leg/customer-visits/${encodeURIComponent(visitId)}`, payload, { params: { customerId } },
|
|
)
|
|
return unwrapApiResponse(response)
|
|
}
|
|
|
|
export async function uploadCustomerVisitAttachment(visitId: string, customerId: string, file: File) {
|
|
const body = new FormData()
|
|
body.append('file', file)
|
|
const response = await http.post<ApiEnvelope<CustomerVisitAttachment>, ApiEnvelope<CustomerVisitAttachment>>(
|
|
`/platform/v1/last-leg/customer-visits/${encodeURIComponent(visitId)}/attachments`, body,
|
|
{ params: { customerId }, headers: { 'Content-Type': 'multipart/form-data' } },
|
|
)
|
|
return unwrapApiResponse(response)
|
|
}
|
|
|
|
export async function updateDeliveryOrderStatus(deliveryNo: string, customerId: string, payload: { status: string; expectedVersion: number; remark?: string }) {
|
|
const response = await http.put<ApiEnvelope<{ visitId?: string | null; deliveryNo: string; deliveryStatus: string; visitStatus?: string | null; replayed: boolean }>, ApiEnvelope<{ visitId?: string | null; deliveryNo: string; deliveryStatus: string; visitStatus?: string | null; replayed: boolean }>>(
|
|
`/platform/v1/last-leg/delivery-orders/${encodeURIComponent(deliveryNo)}/status`, payload,
|
|
{ params: { customerId } },
|
|
)
|
|
return unwrapApiResponse(response)
|
|
}
|