// 功能描述:用户可见的隐私化配送轨迹、履约节点与人员摘要;版本:1.0.0。 class DeliveryTrackPoint { DeliveryTrackPoint.fromJson(Map data) : longitude = _number(data, 'longitude'), latitude = _number(data, 'latitude'), occurredAt = DateTime.parse(_required(data, 'occurred_at')).toLocal(); final double longitude, latitude; final DateTime occurredAt; static double _number(Map data, String key) { final value = data[key]; if (value is! num) throw FormatException('配送轨迹坐标异常:$key'); return value.toDouble(); } } class DeliveryTrackEvent { DeliveryTrackEvent.fromJson(Map data) : statusCode = data['status_code'] as int? ?? 0, title = _required(data, 'title'), detail = _required(data, 'detail'), occurredAt = DateTime.parse(_required(data, 'occurred_at')).toLocal(); final int statusCode; final String title, detail; final DateTime occurredAt; } /// 只接受服务端明确返回的本人订单事实;客户端不推算路线、位置或送达时间。 class DeliveryTrack { DeliveryTrack.fromJson(Map data) : identity = _required(data, 'identity'), statusCode = data['status_code'] as int? ?? 0, statusName = _required(data, 'status_name'), statusMessage = _required(data, 'status_message'), appointmentAt = DateTime.parse(_required(data, 'appointment_at')).toLocal(), updatedAt = _date(data['updated_at']), stationName = _text(data, 'station_name'), staffName = _text(data, 'staff_name'), staffAvatar = _text(data, 'staff_avatar'), staffPhoneMasked = _text(data, 'staff_phone_masked'), controlledCallAvailable = _flag(data, 'controlled_call_available'), routeAvailable = _flag(data, 'route_available'), destinationAvailable = _flag(data, 'destination_available'), destinationLongitude = _optionalNumber(data['destination_longitude']), destinationLatitude = _optionalNumber(data['destination_latitude']), points = List.unmodifiable([ for (final row in data['points'] as List) DeliveryTrackPoint.fromJson(Map.from(row as Map)), ]), timeline = List.unmodifiable([ for (final row in data['timeline'] as List) DeliveryTrackEvent.fromJson(Map.from(row as Map)), ]); final String identity, statusName, statusMessage, stationName, staffName; final String staffAvatar, staffPhoneMasked; final int statusCode; final DateTime appointmentAt; final DateTime? updatedAt; final bool controlledCallAvailable, routeAvailable, destinationAvailable; final double? destinationLongitude, destinationLatitude; final List points; final List timeline; static String _text(Map data, String key) => data[key] as String? ?? ''; static String _required(Map data, String key) { final value = _text(data, key); if (value.trim().isEmpty) throw FormatException('配送轨迹资料不完整:$key'); return value; } static bool _flag(Map data, String key) { if (data[key] is! bool) throw FormatException('配送轨迹状态异常:$key'); return data[key] as bool; } static double? _optionalNumber(Object? value) => value is num ? value.toDouble() : null; static DateTime? _date(Object? value) => value == null ? null : DateTime.tryParse('$value')?.toLocal(); } String _required(Map data, String key) { final value = data[key] as String? ?? ''; if (value.trim().isEmpty) throw FormatException('配送轨迹资料不完整:$key'); return value; }