import { View } from "@tarojs/components"; import { Button, Checkbox, DatePicker, Input, PickerOption, PickerValue, TextArea, Toast, } from "@nutui/nutui-react-taro"; import { DealerPicker, Icon } from "@/components"; import { forwardRef, useImperativeHandle, useState } from "react"; import dayjs from "dayjs"; import Taro from "@tarojs/taro"; import { business } from "@/services"; import { validatePrice as validatePrice1 } from "@/utils"; interface IOrderVehicleProps { value: BusinessAPI.OrderVO; onChange: (orderVO: BusinessAPI.OrderVO) => void; } export interface OrderVehicleRef { validate: () => boolean; } export default forwardRef( function OrderVehicle(props, ref) { const { value, onChange } = props; const { orderVehicle, orderDealer } = value; const [originalData, setOriginalData] = useState(); const [show, setShow] = useState(false); // 校验状态 const [phoneError, setPhoneError] = useState(false); const [plateError, setPlateError] = useState(false); const [driverError, setDriverError] = useState(false); const [originError, setOriginError] = useState(false); const [destinationError, setDestinationError] = useState(false); const [priceError, setPriceError] = useState(false); const [strawCurtainPriceError, setStrawCurtainPriceError] = useState(false); const [deliveryTimeError, setDeliveryTimeError] = useState(false); const [dealerNameError, setDealerNameError] = useState(false); // 获取当年的第一天和今天,用于限制日期选择范围 const currentYear = new Date().getFullYear(); const startDate = new Date(currentYear, 0, 1); // 当年第一天 const endDate = new Date(); // 今天 // 校验手机号码函数 const validatePhone = (phone: string) => { if (!phone) { return false; } const phoneRegex = /^1[3456789]\d{9}$/; return phoneRegex.test(phone); }; // 校验车牌号函数 const validatePlate = (plate: string) => { if (!plate) { return false; } // 车牌号正则表达式(包含普通蓝牌、黄牌、绿牌、黑牌、白牌等) const plateRegex = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z][A-Z0-9]{4,5}[A-Z0-9挂学警港澳]$/; return plateRegex.test(plate); }; // 校验司机姓名函数 const validateDriver = (driver: string) => { if (!driver) { return false; } // 司机姓名至少2个字符 return driver.length >= 2; }; // 校验出发地函数 const validateOrigin = (origin: string) => { if (!origin) { return false; } // 出发地至少2个字符 return origin.length >= 2; }; // 校验目的地函数 const validateDestination = (destination: string) => { if (!destination) { return false; } // 目的地至少2个字符 return destination.length >= 2; }; // 校验运费函数 const validatePrice = (price: string | number) => { if (price === "" || price === undefined) { return false; } const priceNum = typeof price === "string" ? parseFloat(price) : price; // 运费必须大于等于0 return !Number.isNaN(priceNum) && priceNum >= 0; }; // 校验发货时间函数 const validateDeliveryTime = (deliveryTime: string) => { return !!deliveryTime; // 发货时间必须存在 }; // 校验经销商函数 const validateDealerName = (dealerName: string) => { return !!dealerName; // 经销商必须存在 }; // 对外暴露的校验方法 const validate = () => { console.log("vehicle", orderVehicle); const isPhoneValid = validatePhone(orderVehicle?.phone || ""); const isPlateValid = validatePlate(orderVehicle?.plate || ""); const isDriverValid = validateDriver(orderVehicle?.driver || ""); const isOriginValid = validateOrigin(orderVehicle?.origin || ""); const isDestinationValid = validateDestination( orderVehicle?.destination || "", ); const isPriceValid = validatePrice(orderVehicle?.price || 0); const isStrawCurtainPriceValid = !orderVehicle.openStrawCurtain || validatePrice(orderVehicle?.strawCurtainPrice || 0); const isDeliveryTimeValid = validateDeliveryTime( orderVehicle?.deliveryTime || "", ); const isDealerValid = validateDealerName(orderVehicle?.dealerName); setPhoneError(!isPhoneValid); setPlateError(!isPlateValid); setDriverError(!isDriverValid); setOriginError(!isOriginValid); setDestinationError(!isDestinationValid); setPriceError(!isPriceValid); setDeliveryTimeError(!isDeliveryTimeValid); setDealerNameError(!isDealerValid); if (orderVehicle.openStrawCurtain) { setStrawCurtainPriceError(!isStrawCurtainPriceValid); } const isValid = isPhoneValid && isPlateValid && isDriverValid && isOriginValid && isDestinationValid && isPriceValid && isStrawCurtainPriceValid && isDeliveryTimeValid && isDealerValid; if (!isValid) { Toast.show("toast", { icon: "fail", title: "提示", content: "请完善车辆信息后再进行下一步操作", }); } return isValid; }; useImperativeHandle(ref, () => ({ validate, })); const handlePhoneChange = (phone: string) => { onChange?.({ ...value, orderVehicle: { ...orderVehicle, phone: phone as any, }, }); // 校验手机号码并更新错误状态 const isValid = validatePhone(phone); setPhoneError(!isValid && phone !== ""); // 如果手机号有效,清除错误状态 if (isValid) { setPhoneError(false); } }; const handlePhoneBlur = () => { // 失去焦点时校验手机号码 if (orderVehicle?.phone && !validatePhone(orderVehicle.phone)) { setPhoneError(true); Toast.show("toast", { icon: "fail", title: "提示", content: "请输入正确的手机号码", }); } else { setPhoneError(false); } }; const handlePlateChange = (plate: string) => { onChange?.({ ...value, orderVehicle: { ...orderVehicle, plate: plate as any, }, }); // 校验车牌号并更新错误状态 const isValid = validatePlate(plate); setPlateError(!isValid && plate !== ""); // 如果车牌号有效,清除错误状态 if (isValid) { setPlateError(false); } }; const handlePlateBlur = () => { if (orderVehicle?.plate && !validatePlate(orderVehicle.plate)) { setPlateError(true); Toast.show("toast", { icon: "fail", title: "提示", content: "请输入正确的车牌号", }); } else { setPlateError(false); } }; const handleDriverChange = (driver: string) => { onChange?.({ ...value, orderVehicle: { ...orderVehicle, driver: driver as any, }, }); // 校验司机姓名并更新错误状态 const isValid = validateDriver(driver); setDriverError(!isValid && driver !== ""); // 如果司机姓名有效,清除错误状态 if (isValid) { setDriverError(false); } }; const handleDriverBlur = () => { if (orderVehicle?.driver && !validateDriver(orderVehicle.driver)) { setDriverError(true); Toast.show("toast", { icon: "fail", title: "提示", content: "司机姓名至少2个字符", }); } else { setDriverError(false); } }; const handleOriginChange = (origin: string) => { onChange?.({ ...value, orderVehicle: { ...orderVehicle, origin: origin as any, }, }); // 校验出发地并更新错误状态 const isValid = validateOrigin(origin); setOriginError(!isValid && origin !== ""); // 如果出发地有效,清除错误状态 if (isValid) { setOriginError(false); } }; const handleOriginBlur = () => { if (orderVehicle?.origin && !validateOrigin(orderVehicle.origin)) { setOriginError(true); Toast.show("toast", { icon: "fail", title: "提示", content: "出发地至少2个字符", }); } else { setOriginError(false); } }; const handleDestinationChange = (destination: string) => { onChange?.({ ...value, orderVehicle: { ...orderVehicle, destination: destination as any, }, }); // 校验目的地并更新错误状态 const isValid = validateDestination(destination); setDestinationError(!isValid && destination !== ""); // 如果目的地有效,清除错误状态 if (isValid) { setDestinationError(false); } }; const handleDestinationBlur = () => { if ( orderVehicle?.destination && !validateDestination(orderVehicle.destination) ) { setDestinationError(true); Toast.show("toast", { icon: "fail", title: "提示", content: "目的地至少2个字符", }); } else { setDestinationError(false); } }; const handlePriceChange = (price: string) => { // 只允许数字和小数点,小数点后最多两位 const numValue = validatePrice1(price); if (numValue !== undefined) { onChange?.({ ...value, orderVehicle: { ...orderVehicle, price: numValue as any, }, }); // 校验运费并更新错误状态 const isValid = validatePrice(price); setPriceError(!isValid && price !== ""); // 如果运费有效,清除错误状态 if (isValid) { setPriceError(false); } } }; const handlePriceBlur = () => { if (orderVehicle?.price && !validatePrice(orderVehicle.price)) { setPriceError(true); Toast.show("toast", { icon: "fail", title: "提示", content: "运费必须大于等于0", }); } else { setPriceError(false); } }; const handleStrawCurtainPriceChange = (strawCurtainPrice: string) => { const numValue = validatePrice1(strawCurtainPrice); if (numValue !== undefined) { onChange?.({ ...value, orderVehicle: { ...orderVehicle, strawCurtainPrice: numValue as any, }, }); // 校验草帘费用并更新错误状态 const isValid = validatePrice(strawCurtainPrice); setStrawCurtainPriceError(!isValid && strawCurtainPrice !== ""); // 如果草帘费用有效,清除错误状态 if (isValid) { setStrawCurtainPriceError(false); } } }; const handleStrawCurtainPriceBlur = () => { if ( orderVehicle?.strawCurtainPrice && !validatePrice(orderVehicle.strawCurtainPrice) ) { setStrawCurtainPriceError(true); Toast.show("toast", { icon: "fail", title: "提示", content: "草帘费用必须大于等于0", }); } else { setStrawCurtainPriceError(false); } }; const confirm = (_values: PickerValue[]) => { const selectedDate = dayjs(_values.join("-")).format("YYYY-MM-DD"); onChange?.({ ...value, orderVehicle: { ...orderVehicle, deliveryTime: selectedDate as any, }, }); // 校验发货时间 const isValid = validateDeliveryTime(selectedDate); setDeliveryTimeError(!isValid); }; const formatter = (type: string, option: PickerOption) => { switch (type) { case "year": option.label += "年"; break; case "month": option.label += "月"; break; case "day": option.label += "日"; break; case "hour": option.label += "时"; break; case "minute": option.label += "分"; break; default: break; } return option; }; const vehicleExtraction = async (originalData: string) => { // 简单校验message,避免无效的数据抽取 if (!originalData || originalData.trim() === "") { Toast.show("toast", { title: "请输入有效内容", icon: "none", }); return; } Taro.showLoading({ title: "识别中,请稍后", }); const { data: { data: newVehicle }, } = await business.extraction.vehicleExtraction({ message: originalData, dealerNames: "", }); if (newVehicle) { const dealerVO = newVehicle.dealerVO; onChange?.({ ...value, orderVehicle: { ...newVehicle, // 通过 - 分割 plate: newVehicle.plate?.split("-")[0]!, dealerId: newVehicle.dealerId || orderVehicle?.dealerId, dealerName: newVehicle.dealerName || orderVehicle?.dealerName, openStrawCurtain: false, //@ts-ignore strawCurtainPrice: "", deliveryTime: dayjs().format("YYYY-MM-DD"), originalData: originalData || "", }, orderDealer: { ...orderDealer, ...dealerVO, }, }); // 清除所有错误状态 setPlateError(false); setDriverError(false); setPhoneError(false); setOriginError(false); setDestinationError(false); setPriceError(false); setStrawCurtainPriceError(false); setDeliveryTimeError(false); setDealerNameError(false); } Taro.hideLoading(); }; return ( 智能识别