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;
|
||
}
|