Add aftersales work order frontend pages
- Public scan-to-confirm page (/aftersales/:sn) with phone last-4 verification - Admin list + detail pages with state machine, QR generation, reassign, force-close - PublicLayout extracted from PublicQuery so both pages share logo + 备案 chrome - PublicQuery auto-redirects scanned zjbf-sh-* serials to the aftersales page - AdminLayout: new 售后工单 menu entry Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -117,4 +117,87 @@ export interface EmployeeSerialPagination {
|
||||
export interface EmployeeSerialResponse {
|
||||
data: EmployeeSerial[];
|
||||
pagination: EmployeeSerialPagination;
|
||||
}
|
||||
|
||||
export type AftersalesServiceType = 'software' | 'hardware' | 'other';
|
||||
export type AftersalesWorkOrderStatus = 'created' | 'pending_confirmation' | 'closed' | 'rejected';
|
||||
export type AftersalesAuthorizationStatus = 'pending' | 'authorized' | 'unauthorized';
|
||||
|
||||
export interface AftersalesOrder {
|
||||
id: number;
|
||||
serialNumber: string;
|
||||
companyName: string;
|
||||
companyAddress: string;
|
||||
contactName: string;
|
||||
contactPhone: string;
|
||||
serviceType: AftersalesServiceType;
|
||||
issueDescription: string;
|
||||
resolutionNote: string;
|
||||
workOrderStatus: AftersalesWorkOrderStatus;
|
||||
authorizationStatus: AftersalesAuthorizationStatus;
|
||||
technicianId?: number;
|
||||
createdBy?: number;
|
||||
scannedAt?: string;
|
||||
confirmedAt?: string;
|
||||
rejectCount: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
technician?: User;
|
||||
creator?: User;
|
||||
}
|
||||
|
||||
export interface AftersalesPublicView {
|
||||
serialNumber: string;
|
||||
companyName: string;
|
||||
companyAddress: string;
|
||||
contactName: string;
|
||||
serviceType: AftersalesServiceType;
|
||||
issueDescription: string;
|
||||
resolutionNote: string;
|
||||
workOrderStatus: AftersalesWorkOrderStatus;
|
||||
authorizationStatus: AftersalesAuthorizationStatus;
|
||||
technicianName: string;
|
||||
createdAt: string;
|
||||
confirmedAt?: string;
|
||||
}
|
||||
|
||||
export interface CreateAftersalesRequest {
|
||||
companyName: string;
|
||||
companyAddress: string;
|
||||
contactName: string;
|
||||
contactPhone: string;
|
||||
serviceType: AftersalesServiceType;
|
||||
issueDescription: string;
|
||||
technicianId?: number;
|
||||
}
|
||||
|
||||
export interface UpdateAftersalesRequest {
|
||||
companyAddress?: string;
|
||||
contactName?: string;
|
||||
contactPhone?: string;
|
||||
serviceType?: AftersalesServiceType;
|
||||
issueDescription?: string;
|
||||
resolutionNote?: string;
|
||||
technicianId?: number;
|
||||
}
|
||||
|
||||
export interface AftersalesListFilter {
|
||||
page?: number;
|
||||
limit?: number;
|
||||
search?: string;
|
||||
workOrderStatus?: AftersalesWorkOrderStatus;
|
||||
serviceType?: AftersalesServiceType;
|
||||
technicianId?: number;
|
||||
mine?: boolean;
|
||||
}
|
||||
|
||||
export interface AftersalesListResponse {
|
||||
data: AftersalesOrder[];
|
||||
pagination: EmployeeSerialPagination;
|
||||
}
|
||||
|
||||
export interface CustomerConfirmRequest {
|
||||
phoneLast4: string;
|
||||
action: 'authorize' | 'reject';
|
||||
rejectReason?: string;
|
||||
}
|
||||
Reference in New Issue
Block a user