You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
227 lines
4.7 KiB
227 lines
4.7 KiB
/** 前端类型定义 — 与 PRD / API 契约一致 */
|
|
|
|
export type QuotePageStatus =
|
|
| "idle"
|
|
| "resolving_address"
|
|
| "validating"
|
|
| "processing"
|
|
| "success"
|
|
| "fallback"
|
|
| "error"
|
|
| "expired";
|
|
|
|
export type DataPageStatus = "loading" | "success" | "empty" | "error";
|
|
|
|
export type ServiceLevel = "standard" | "guaranteed";
|
|
export type RateOption = "lowest" | "fastest" | "bestValue";
|
|
export type UnitWeight = "lb" | "kg";
|
|
export type UnitDim = "in" | "cm";
|
|
export type DisplayUnit = "imperial" | "metric";
|
|
|
|
export type CargoType =
|
|
| "general_freight"
|
|
| "machinery"
|
|
| "furniture"
|
|
| "electronics"
|
|
| "building_materials"
|
|
| "auto_parts"
|
|
| "food_nonperishable"
|
|
| "apparel"
|
|
| "other";
|
|
|
|
export interface AddressInput {
|
|
street: string;
|
|
city: string;
|
|
state: string;
|
|
zip: string;
|
|
place_id: string;
|
|
formatted_address: string;
|
|
selected_from_suggestions: boolean;
|
|
mothership_option_id?: string;
|
|
mothership_display_label?: string;
|
|
selected_from_mothership?: boolean;
|
|
}
|
|
|
|
export interface MothershipAddressCandidate {
|
|
option_id: string;
|
|
display_label: string;
|
|
formatted_address: string;
|
|
street: string;
|
|
city: string;
|
|
state: string;
|
|
zip: string;
|
|
selectable?: boolean;
|
|
unavailable_reason?: string;
|
|
}
|
|
|
|
export interface MothershipCandidatesResult {
|
|
pickup_candidates: MothershipAddressCandidate[];
|
|
delivery_candidates: MothershipAddressCandidate[];
|
|
requires_selection: boolean;
|
|
quote_session_id?: string;
|
|
}
|
|
|
|
export interface QuoteRequestBody {
|
|
request_id: string;
|
|
customer_id: string;
|
|
pickup_address: AddressInput;
|
|
delivery_address: AddressInput;
|
|
weight: { value: number; unit: UnitWeight };
|
|
dimensions: {
|
|
length: number;
|
|
width: number;
|
|
height: number;
|
|
unit: UnitDim;
|
|
};
|
|
pallet_count: number;
|
|
cargo_type: CargoType;
|
|
service_level?: ServiceLevel;
|
|
rate_option?: RateOption;
|
|
display_unit?: DisplayUnit;
|
|
quote_session_id?: string;
|
|
}
|
|
|
|
export type QuoteStatus = "processing" | "done" | "failed" | "expired";
|
|
export type SourceType = "rpa" | "cache" | "stale";
|
|
|
|
export interface QuoteItem {
|
|
service_level: ServiceLevel;
|
|
rate_option: RateOption;
|
|
carrier: string;
|
|
transit_days: string;
|
|
transit_description: string;
|
|
raw_freight: number;
|
|
surcharges: number;
|
|
raw_total: number;
|
|
markup_percent: number;
|
|
markup_amount: number;
|
|
final_total: number;
|
|
breakdown: Array<{ item: string; amount: number }>;
|
|
}
|
|
|
|
export interface QuoteDetail {
|
|
quote_id: string;
|
|
request_id: string;
|
|
status: QuoteStatus;
|
|
valid_until?: string | null;
|
|
source_type?: SourceType | null;
|
|
is_realtime?: boolean;
|
|
confidence_score?: number | null;
|
|
currency: string;
|
|
quotes?: QuoteItem[];
|
|
error_code?: string | null;
|
|
error_message?: string | null;
|
|
}
|
|
|
|
export interface CreateQuoteResult {
|
|
quote_id: string;
|
|
status: "processing" | "done";
|
|
}
|
|
|
|
export type MarkupType = "percent" | "fixed";
|
|
|
|
export interface MarkupConfig {
|
|
customer_id: string;
|
|
markup_type: MarkupType;
|
|
markup_percent: number;
|
|
markup_fixed_amount: number | null;
|
|
operator_id: string;
|
|
remark: string | null;
|
|
updated_at: string;
|
|
}
|
|
|
|
export type AlertType =
|
|
| "PRICE_DEVIATION"
|
|
| "STALE_FALLBACK"
|
|
| "RPA_FAILED"
|
|
| "RPA_CAPTCHA"
|
|
| "STRUCT_CHANGE"
|
|
| "SESSION_EXPIRED"
|
|
| "SECURITY"
|
|
| "MANUAL_FALLBACK";
|
|
|
|
export interface AlertRecord {
|
|
id: string;
|
|
alert_type: AlertType;
|
|
quote_id: string | null;
|
|
cargo_hash: string | null;
|
|
detail_json: Record<string, unknown> | null;
|
|
status: "open" | "resolved";
|
|
resolver_id: string | null;
|
|
resolved_at: string | null;
|
|
created_at: string;
|
|
}
|
|
|
|
export type ErrorCode =
|
|
| "VALIDATION_FAILED"
|
|
| "UNAUTHORIZED"
|
|
| "FORBIDDEN"
|
|
| "QUOTE_NOT_FOUND"
|
|
| "RATE_LIMITED"
|
|
| "QUOTE_UNAVAILABLE"
|
|
| "QUOTE_TIMEOUT"
|
|
| "INTERNAL_ERROR";
|
|
|
|
export interface ApiOk<T> {
|
|
code: 0;
|
|
message: string;
|
|
data: T;
|
|
}
|
|
|
|
export interface ApiErr {
|
|
code: ErrorCode | string;
|
|
message: string;
|
|
data: null;
|
|
}
|
|
|
|
export type ApiResponse<T> = ApiOk<T> | ApiErr;
|
|
|
|
export interface AdminUser {
|
|
user_id: string;
|
|
role: "admin";
|
|
}
|
|
|
|
export interface LoginResponse {
|
|
token: string;
|
|
user: AdminUser;
|
|
}
|
|
|
|
export interface PaginatedResult<T> {
|
|
list: T[];
|
|
total: number;
|
|
page: number;
|
|
size: number;
|
|
}
|
|
|
|
export interface MetricsDashboard {
|
|
api_success_rate: number;
|
|
rpa_success_rate: number;
|
|
realtime_rate: number;
|
|
cache_hit_rate: number;
|
|
p95_latency_ms: number;
|
|
queue_depth: number;
|
|
open_alerts_count: number;
|
|
}
|
|
|
|
export interface RpaStatus {
|
|
workers: Array<{
|
|
worker_id: string;
|
|
last_seen_ms: number | null;
|
|
paused_seconds: number;
|
|
online: boolean;
|
|
}>;
|
|
queue_depth: number;
|
|
circuit_open: boolean;
|
|
success_rate_24h: number;
|
|
}
|
|
|
|
export interface QueueStats {
|
|
queue_name: string;
|
|
waiting: number;
|
|
active: number;
|
|
delayed: number;
|
|
failed: number;
|
|
completed: number;
|
|
depth: number;
|
|
}
|