import { z } from "zod"; import { CARGO_TYPES } from "@/modules/quote/validation"; const US_ZIP_REGEX = /^\d{5}(-\d{4})?$/; const addressDraftSchema = z.object({ street: z.string().min(1, "请填写街道地址"), city: z.string().min(1, "请填写城市"), state: z.string().length(2, "请填写 2 位州码"), zip: z .string() .refine((v) => v === "" || US_ZIP_REGEX.test(v), "邮编格式无效") .optional() .default(""), }); const cargoSchema = z.object({ weight: z.object({ value: z.number({ invalid_type_error: "请填写重量" }), unit: z.enum(["lb", "kg"]), }), dimensions: z.object({ length: z.number({ invalid_type_error: "请填写长度" }), width: z.number({ invalid_type_error: "请填写宽度" }), height: z.number({ invalid_type_error: "请填写高度" }), unit: z.enum(["in", "cm"]), }), pallet_count: z.number({ invalid_type_error: "请填写托盘数" }), cargo_type: z.enum(CARGO_TYPES), }); const candidateSchema = z.object({ option_id: z.string().min(1), display_label: z.string().min(1), formatted_address: z.string().min(1), street: z.string().min(1), city: z.string().min(1), state: z.string().length(2), zip: z.string().optional().default(""), selectable: z.boolean().optional(), unavailable_reason: z.string().optional(), }); export const hostCandidatesBodySchema = z.object({ pickup_address: addressDraftSchema, delivery_address: addressDraftSchema, cargo: cargoSchema, }); export const hostSubmitBodySchema = z.object({ host_session_id: z.string().uuid("会话标识无效"), pickup_candidate: candidateSchema, delivery_candidate: candidateSchema, });