jjsos_autosos_flutter/lib/model/order.dart

263 lines
8.5 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import 'package:autosos_flutter/model/user.dart';
/// 订单状态枚举(对应 Android ui.order.* 状态机)
enum OrderStatus {
pending, // 待处理check 阶段)
waiting, // 等待接单
accepted, // 已接单
conducting, // 救援中
photographing, // 拍照取证
signing, // 客户签名
collecting, // 收款中
completed, // 已完成
cancelled, // 已取消
offline, // 离线模式
unknown,
}
extension OrderStatusX on OrderStatus {
String get label {
switch (this) {
case OrderStatus.pending: return '待核单';
case OrderStatus.waiting: return '等待接单';
case OrderStatus.accepted: return '已接单';
case OrderStatus.conducting: return '救援中';
case OrderStatus.photographing: return '拍照取证';
case OrderStatus.signing: return '客户签字';
case OrderStatus.collecting: return '收款中';
case OrderStatus.completed: return '已完成';
case OrderStatus.cancelled: return '已取消';
case OrderStatus.offline: return '离线模式';
case OrderStatus.unknown: return '未知';
}
}
static OrderStatus fromString(String? s) {
switch (s) {
case 'pending': return OrderStatus.pending;
case 'waiting': return OrderStatus.waiting;
case 'accepted': return OrderStatus.accepted;
case 'conducting': return OrderStatus.conducting;
case 'photographing': return OrderStatus.photographing;
case 'signing': return OrderStatus.signing;
case 'collecting': return OrderStatus.collecting;
case 'completed': return OrderStatus.completed;
case 'cancelled': return OrderStatus.cancelled;
case 'offline': return OrderStatus.offline;
default: return OrderStatus.unknown;
}
}
}
/// 订单主体(对应 Android OrderDetailEntity / OrderList
class Order {
final int id;
final String orderNo; // 订单编号
final OrderStatus status;
final String serviceType; // 救援类型:非事故拖车、事故拖车、应急搭电等
final String? address; // 救援地点
final double? lat;
final double? lng;
final String? customerName;
final String? customerPhone;
final String? carNo; // 车牌号
final String? carType; // 车型
final String? description; // 描述/备注
final double amount; // 总金额
final double? mileage; // 拖车里程
final DateTime createdAt;
final DateTime? acceptedAt;
final DateTime? arrivedAt;
final DateTime? completedAt;
final List<String> photoUrls; // 现场照片
final String? signatureUrl; // 客户签字
final String? payMethod; // wx / cash
final UserInfo? technician; // 接单技师
const Order({
required this.id,
required this.orderNo,
required this.status,
required this.serviceType,
required this.amount,
required this.createdAt,
this.address,
this.lat,
this.lng,
this.customerName,
this.customerPhone,
this.carNo,
this.carType,
this.description,
this.mileage,
this.acceptedAt,
this.arrivedAt,
this.completedAt,
this.photoUrls = const [],
this.signatureUrl,
this.payMethod,
this.technician,
});
factory Order.fromJson(Map<String, dynamic> json) {
return Order(
id: json['id'] as int? ?? 0,
orderNo: json['order_no'] as String? ?? '',
status: OrderStatusX.fromString(json['status'] as String?),
serviceType: json['service_type'] as String? ?? '',
address: json['address'] as String?,
lat: (json['lat'] as num?)?.toDouble(),
lng: (json['lng'] as num?)?.toDouble(),
customerName: json['customer_name'] as String?,
customerPhone: json['customer_phone'] as String?,
carNo: json['car_no'] as String?,
carType: json['car_type'] as String?,
description: json['description'] as String?,
amount: (json['amount'] as num?)?.toDouble() ?? 0,
mileage: (json['mileage'] as num?)?.toDouble(),
createdAt: DateTime.tryParse(json['created_at'] as String? ?? '') ??
DateTime.now(),
acceptedAt: json['accepted_at'] != null
? DateTime.tryParse(json['accepted_at'] as String)
: null,
arrivedAt: json['arrived_at'] != null
? DateTime.tryParse(json['arrived_at'] as String)
: null,
completedAt: json['completed_at'] != null
? DateTime.tryParse(json['completed_at'] as String)
: null,
photoUrls: (json['photo_urls'] as List?)?.cast<String>() ?? const [],
signatureUrl: json['signature_url'] as String?,
payMethod: json['pay_method'] as String?,
technician: json['technician'] != null
? UserInfo.fromJson(json['technician'] as Map<String, dynamic>)
: null,
);
}
Map<String, dynamic> toJson() => {
'id': id,
'order_no': orderNo,
'status': status.name,
'service_type': serviceType,
'address': address,
'lat': lat,
'lng': lng,
'customer_name': customerName,
'customer_phone': customerPhone,
'car_no': carNo,
'car_type': carType,
'description': description,
'amount': amount,
'mileage': mileage,
'created_at': createdAt.toIso8601String(),
'accepted_at': acceptedAt?.toIso8601String(),
'arrived_at': arrivedAt?.toIso8601String(),
'completed_at': completedAt?.toIso8601String(),
'photo_urls': photoUrls,
'signature_url': signatureUrl,
'pay_method': payMethod,
};
Order copyWith({
OrderStatus? status,
double? amount,
DateTime? arrivedAt,
DateTime? completedAt,
List<String>? photoUrls,
String? signatureUrl,
String? payMethod,
}) {
return Order(
id: id,
orderNo: orderNo,
status: status ?? this.status,
serviceType: serviceType,
address: address,
lat: lat,
lng: lng,
customerName: customerName,
customerPhone: customerPhone,
carNo: carNo,
carType: carType,
description: description,
amount: amount ?? this.amount,
mileage: mileage,
createdAt: createdAt,
acceptedAt: acceptedAt,
arrivedAt: arrivedAt ?? this.arrivedAt,
completedAt: completedAt ?? this.completedAt,
photoUrls: photoUrls ?? this.photoUrls,
signatureUrl: signatureUrl ?? this.signatureUrl,
payMethod: payMethod ?? this.payMethod,
technician: technician,
);
}
}
/// 核单列表项(对应 Android CheckItemViewModel
class CheckItem {
final int orderId;
final String orderNo;
final String serviceType;
final String? address;
final DateTime createdAt;
final double amount;
final bool checked; // 是否已核单
const CheckItem({
required this.orderId,
required this.orderNo,
required this.serviceType,
required this.createdAt,
required this.amount,
this.address,
this.checked = false,
});
factory CheckItem.fromJson(Map<String, dynamic> json) => CheckItem(
orderId: json['order_id'] as int? ?? 0,
orderNo: json['order_no'] as String? ?? '',
serviceType: json['service_type'] as String? ?? '',
address: json['address'] as String?,
createdAt: DateTime.tryParse(json['created_at'] as String? ?? '') ??
DateTime.now(),
amount: (json['amount'] as num?)?.toDouble() ?? 0,
checked: json['checked'] as bool? ?? false,
);
}
/// 等待接单项(对应 Android OrderWaitingItemViewModel
class WaitingOrder {
final int orderId;
final String orderNo;
final String serviceType;
final String? address;
final double? distance; // 距离技师当前位置
final double amount;
final DateTime createdAt;
final int countdown; // 接单倒计时(秒)
const WaitingOrder({
required this.orderId,
required this.orderNo,
required this.serviceType,
required this.amount,
required this.createdAt,
required this.countdown,
this.address,
this.distance,
});
factory WaitingOrder.fromJson(Map<String, dynamic> json) => WaitingOrder(
orderId: json['order_id'] as int? ?? 0,
orderNo: json['order_no'] as String? ?? '',
serviceType: json['service_type'] as String? ?? '',
address: json['address'] as String?,
distance: (json['distance'] as num?)?.toDouble(),
amount: (json['amount'] as num?)?.toDouble() ?? 0,
createdAt: DateTime.tryParse(json['created_at'] as String? ?? '') ??
DateTime.now(),
countdown: json['countdown'] as int? ?? 0,
);
}