89 lines
3.7 KiB
Dart
89 lines
3.7 KiB
Dart
|
|
// 功能描述:用户可见的隐私化配送轨迹、履约节点与人员摘要;版本:1.0.0。
|
|||
|
|
class DeliveryTrackPoint {
|
|||
|
|
DeliveryTrackPoint.fromJson(Map<String, Object?> 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<String, Object?> data, String key) {
|
|||
|
|
final value = data[key];
|
|||
|
|
if (value is! num) throw FormatException('配送轨迹坐标异常:$key');
|
|||
|
|
return value.toDouble();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
class DeliveryTrackEvent {
|
|||
|
|
DeliveryTrackEvent.fromJson(Map<String, Object?> 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<String, Object?> 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<String, Object?>.from(row as Map)),
|
|||
|
|
]),
|
|||
|
|
timeline = List.unmodifiable([
|
|||
|
|
for (final row in data['timeline'] as List)
|
|||
|
|
DeliveryTrackEvent.fromJson(Map<String, Object?>.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<DeliveryTrackPoint> points;
|
|||
|
|
final List<DeliveryTrackEvent> timeline;
|
|||
|
|
|
|||
|
|
static String _text(Map<String, Object?> data, String key) => data[key] as String? ?? '';
|
|||
|
|
static String _required(Map<String, Object?> data, String key) {
|
|||
|
|
final value = _text(data, key);
|
|||
|
|
if (value.trim().isEmpty) throw FormatException('配送轨迹资料不完整:$key');
|
|||
|
|
return value;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static bool _flag(Map<String, Object?> 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<String, Object?> data, String key) {
|
|||
|
|
final value = data[key] as String? ?? '';
|
|||
|
|
if (value.trim().isEmpty) throw FormatException('配送轨迹资料不完整:$key');
|
|||
|
|
return value;
|
|||
|
|
}
|