This commit is contained in:
2026-07-12 04:33:48 +08:00
parent f8a90ad305
commit e7ce0f7bae
151 changed files with 2765 additions and 2947 deletions

View File

@@ -24,10 +24,9 @@ import '../../routes.dart';
import '../../utils/util_web.dart' if (dart.library.io) '../../utils/util_io.dart';
class MobileOrderDetail extends StatefulWidget {
final Key key;
final int orderId;
final bool fromOrders;
const MobileOrderDetail(this.orderId, {this.key, this.fromOrders});
const MobileOrderDetail(this.orderId, {Key? key, required this.fromOrders});
@override
State<StatefulWidget> createState() {
@@ -37,18 +36,18 @@ class MobileOrderDetail extends StatefulWidget {
}
class MobileOrderDetailState extends State<MobileOrderDetail> {
Order order;
Order? order;
LatLng _lastMapPosition;
LatLng customerLatLng;
LatLng deliveryLatLng;
LatLng storeLatLng;
LatLng? _lastMapPosition;
LatLng? customerLatLng;
LatLng? deliveryLatLng;
LatLng? storeLatLng;
final Set<Marker> _markers = {};
final Set<Polyline> _polyLine = {};
BitmapDescriptor homeIcon;
BitmapDescriptor deliveryIcon;
BitmapDescriptor shopIcon;
BitmapDescriptor? homeIcon;
BitmapDescriptor? deliveryIcon;
BitmapDescriptor? shopIcon;
Completer<GoogleMapController> _controller = Completer();
@@ -91,15 +90,16 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
title: Text(S.of(context).order_detail),
backgroundColor: Theme.of(context).primaryColor,
),
body: WillPopScope(
onWillPop: () async {
if (widget.fromOrders != null && widget.fromOrders) {
return true;
body: PopScope(
canPop: false,
onPopInvokedWithResult: (didPop, result) {
if (didPop) return;
if (widget.fromOrders) {
Navigator.of(context).pop();
} else {
Routes.router.navigateTo(
context, '/orders', replace: true, clearStack: true);
}
return false;
},
child: ListView.builder(
itemCount: 4,
@@ -123,7 +123,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
width: double.infinity,
padding: EdgeInsets.only(top: 0.0, bottom: 16.0),
child: Text(
order.cartInfo.businessInfo.name,
'${order?.cartInfo?.businessInfo?.name}',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
@@ -142,7 +142,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
),
),
onTap: () {
Routes.router.navigateTo(context, '/shop/${order.businessId}/na/na/na');
Routes.router.navigateTo(context, '/shop/${order?.businessId}/na/na/na');
},
),
),
@@ -154,7 +154,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
Icons.phone,
),
onTap: () {
Utils.launchURL('tel:${order.businessInfo.phone}');
Utils.launchURL('tel:${order?.businessInfo?.phone}');
},
),
),
@@ -163,15 +163,15 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
);
if (!kIsWeb) {
if (order.shippingMethod == 'store-delivery' && order.status != Constants.STATUS_COMPLETE && order.status != Constants.STATUS_CANCELLED) {
if (order!.shippingMethod == 'store-delivery' && order!.status != Constants.STATUS_COMPLETE && order!.status != Constants.STATUS_CANCELLED) {
col.children.add(Container(
height: 200.0,
child: GoogleMap(
onMapCreated: _onMapCreated,
initialCameraPosition: CameraPosition(
target: LatLng(
double.parse(order.shippingAddress.lat),
double.parse(order.shippingAddress.lng)),
double.parse(order?.shippingAddress?.lat ?? ''),
double.parse(order?.shippingAddress?.lng ?? '')),
zoom: 11.0,
),
onCameraMove: _onCameraMove,
@@ -182,14 +182,14 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
].toSet(),
),
));
if (order.deliveryDistance != null && order.deliveryDistance.distance != null) {
if (order!.deliveryDistance != null && order!.deliveryDistance?.distance != null) {
col.children.add(Container(
padding: EdgeInsets.only(top: 6.0, bottom: 6.0),
margin: EdgeInsets.only(bottom: 6.0),
child: Text(
S.of(context).delivery_distance_token(
order.deliveryDistance.distance.text,
order.deliveryDistance.duration.text
order!.deliveryDistance!.distance?.text ?? '',
order!.deliveryDistance!.duration?.text ?? ''
),
),
decoration: BoxDecoration(
@@ -205,7 +205,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
}
}
for (CartLineItem lineItem in order.cartInfo.productList) {
for (CartLineItem lineItem in order!.cartInfo!.productList!) {
col.children.add(Container(
padding: EdgeInsets.only(top: 16.0, bottom: 0.0),
@@ -213,7 +213,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Util.showImage('${lineItem.product.imagePath}',
Util.showImage('${lineItem.product!.imagePath}',
width: 40.0,
height: 40.0,
fit: BoxFit.fill,
@@ -251,7 +251,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
width: 30.0,
alignment: Alignment.centerRight,
child: Text(
'x${lineItem.quantity.round()}',
'x${lineItem.quantity!.round()}',
style: TextStyle(
fontSize: 14.0,
),
@@ -304,7 +304,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
width: 100.0,
alignment: Alignment.centerRight,
child: Text(
'${order.getSubtotal().toStringAsFixed(2)}',
'${order!.getSubtotal().toStringAsFixed(2)}',
style: TextStyle(
fontSize: 15.0,
),
@@ -313,8 +313,8 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
],
),
);
for (var i = 0; i < order.cartInfo.extraFeeList.length; i++) {
ExtraFee extraFee = order.cartInfo.extraFeeList[i];
for (var i = 0; i < order!.cartInfo!.extraFeeList!.length; i++) {
ExtraFee extraFee = order!.cartInfo!.extraFeeList![i];
col.children.add(
Row(
mainAxisAlignment: MainAxisAlignment.start,
@@ -371,7 +371,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
width: 100.0,
alignment: Alignment.centerRight,
child: Text(
'${order.totalPrice.toStringAsFixed(2)}',
'${order!.totalPrice.toStringAsFixed(2)}',
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.bold,
@@ -424,7 +424,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
),
),
);
if (order.shippingMethod != 'pickup') {
if (order!.shippingMethod != 'pickup') {
col.children.add(Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
@@ -443,7 +443,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
child: Container(
margin: EdgeInsets.only(top: 10.0, bottom: 10.0),
child: Text(
'${order.address}, ${order.consignee}, ${order.phone}',
'${order!.address}, ${order!.consignee}, ${order!.phone}',
style: TextStyle(
color: Colors.black38,
),
@@ -481,7 +481,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
margin: EdgeInsets.only(top: 10.0, bottom: 10.0),
alignment: Alignment.centerRight,
child: Text(
'${order.cartInfo.businessInfo.fullAddress}',
'${order!.cartInfo!.businessInfo?.fullAddress}',
style: TextStyle(
color: Colors.black38,
),
@@ -520,7 +520,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
margin: EdgeInsets.only(top: 10.0, bottom: 10.0),
alignment: Alignment.centerRight,
child: Text(
'${Utils.timestampToString(context, order.bookedAt, withTime: true)}',
'${Utils.timestampToString(context, order!.bookedAt, withTime: true)}',
style: TextStyle(
color: Colors.black38,
),
@@ -558,7 +558,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
margin: EdgeInsets.only(top: 10.0, bottom: 10.0),
alignment: Alignment.centerRight,
child: Text(
order.shippingMethod == 'pickup' ? S.of(context).pickup : S.of(context).store_delivery,
order!.shippingMethod == 'pickup' ? S.of(context).pickup : S.of(context).store_delivery,
style: TextStyle(
color: Colors.black38,
),
@@ -648,7 +648,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Text(
'${order.orderNum}',
'${order!.orderNum}',
style: TextStyle(
color: Colors.black38,
),
@@ -670,7 +670,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
S.of(context).copy,
),
onTap: () {
Clipboard.setData(ClipboardData(text: '${order.orderNum}'));
Clipboard.setData(ClipboardData(text: '${order!.orderNum}'));
Fluttertoast.showToast(
msg: S.of(context).order_number_copied_to_clipboard,
toastLength: Toast.LENGTH_SHORT,
@@ -715,7 +715,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
margin: EdgeInsets.only(top: 10.0, bottom: 10.0),
alignment: Alignment.centerRight,
child: Text(
order.payMethod == 0 ? S.of(context).online_payment : S.of(context).pay_on_deliery,
order!.payMethod == 0 ? S.of(context).online_payment : S.of(context).pay_on_deliery,
style: TextStyle(
color: Colors.black38,
),
@@ -756,15 +756,15 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Text(
order.paymentStatus == Constants.PAYMENT_STATUS_PAID ? S.of(context).paid : S.of(context).unpaid,
order!.paymentStatus == Constants.PAYMENT_STATUS_PAID ? S.of(context).paid : S.of(context).unpaid,
style: TextStyle(
color: Colors.black38,
),
),
Container(
margin: order.paymentStatus != Constants.PAYMENT_STATUS_PAID && order.status != Constants.STATUS_CANCELLED ? EdgeInsets.only(left: 10.0, right: 10.0) : EdgeInsets.only(left: 0.0, right: 0.0),
child: order.paymentStatus != Constants.PAYMENT_STATUS_PAID && order.status != Constants.STATUS_CANCELLED ? Text('') : SizedBox.shrink(),
decoration: order.paymentStatus != Constants.PAYMENT_STATUS_PAID && order.status != Constants.STATUS_CANCELLED ? BoxDecoration(
margin: order!.paymentStatus != Constants.PAYMENT_STATUS_PAID && order!.status != Constants.STATUS_CANCELLED ? EdgeInsets.only(left: 10.0, right: 10.0) : EdgeInsets.only(left: 0.0, right: 0.0),
child: order!.paymentStatus != Constants.PAYMENT_STATUS_PAID && order!.status != Constants.STATUS_CANCELLED ? Text('') : SizedBox.shrink(),
decoration: order!.paymentStatus != Constants.PAYMENT_STATUS_PAID && order!.status != Constants.STATUS_CANCELLED ? BoxDecoration(
border: Border(
left: BorderSide(
width: 0.5,
@@ -774,16 +774,16 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
) : null,
),
GestureDetector(
child: order.paymentStatus != Constants.PAYMENT_STATUS_PAID
&& order.status != Constants.STATUS_CANCELLED
&& order.status != Constants.STATUS_COMPLETE ? Text(
child: order!.paymentStatus != Constants.PAYMENT_STATUS_PAID
&& order!.status != Constants.STATUS_CANCELLED
&& order!.status != Constants.STATUS_COMPLETE ? Text(
S.of(context).pay_now,
style: TextStyle(
fontWeight: FontWeight.bold,
),
) : SizedBox.shrink(),
onTap: () {
Routes.router.navigateTo(context, '/paynow/${order.id}');
Routes.router.navigateTo(context, '/paynow/${order!.id}');
},
),
],
@@ -821,7 +821,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
margin: EdgeInsets.only(top: 10.0, bottom: 10.0),
alignment: Alignment.centerRight,
child: Text(
Utils.timestampToString(context, order.createdAt, withTime: true),
Utils.timestampToString(context, order!.createdAt, withTime: true),
style: TextStyle(
color: Colors.black38,
),
@@ -877,7 +877,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
),
),
Text(
Utils.getOrderStatus(context, order.status),
Utils.getOrderStatus(context, order!.status),
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
@@ -899,7 +899,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
),
),);
for (Fulfillment fulfillment in order.fulfillments) {
for (Fulfillment fulfillment in order!.fulfillments) {
col.children.add(Container(
padding: EdgeInsets.only(top: 10.0, bottom: 10.0),
width: double.infinity,
@@ -983,7 +983,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
children: <Widget>[
Container(
padding: EdgeInsets.only(right: 10.0),
child: order.status == Constants.STATUS_PENDING && order.paymentStatus == Constants.PAYMENT_STATUS_UNPAID ?
child: order!.status == Constants.STATUS_PENDING && order!.paymentStatus == Constants.PAYMENT_STATUS_UNPAID ?
TextButton(
child: Text(
S.of(context).cancel_order,
@@ -994,34 +994,34 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
) : SizedBox.shrink(),
),
Container(
child: order.status == Constants.STATUS_COMPLETE && !order.hasComment ? ElevatedButton(
child: order!.status == Constants.STATUS_COMPLETE && !order!.hasComment ? ElevatedButton(
child: Text(
S.of(context).comment,
),
onPressed: () {
Routes.router.navigateTo(context, '/new-comment/${order.id}');
Routes.router.navigateTo(context, '/new-comment/${order!.id}');
},
) : SizedBox.shrink(),
),
],
),
Container(
child: order.paymentStatus != Constants.PAYMENT_STATUS_PAID
&& order.status != Constants.STATUS_CANCELLED
&& order.status != Constants.STATUS_COMPLETE ?
child: order!.paymentStatus != Constants.PAYMENT_STATUS_PAID
&& order!.status != Constants.STATUS_CANCELLED
&& order!.status != Constants.STATUS_COMPLETE ?
TextButton(
child: Text(
S.of(context).pay_now,
),
onPressed: () {
Routes.router.navigateTo(context, '/paynow/${order.id}');
Routes.router.navigateTo(context, '/paynow/${order!.id}');
},
) : TextButton(
child: Text(
S.of(context).order_again,
),
onPressed: () {
Utils.orderAgain(context, order.cartInfo);
Utils.orderAgain(context, order!.cartInfo!);
},
),
),
@@ -1059,13 +1059,13 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
order = Order.fromJson(data);
if (!kIsWeb) {
if (order.shippingMethod == 'store-delivery' && order.status != Constants.STATUS_COMPLETE && order.status != Constants.STATUS_CANCELLED) {
storeLatLng = LatLng(double.parse(order.businessInfo.address.lat),
double.parse(order.businessInfo.address.lng));
customerLatLng = LatLng(double.parse(order.shippingAddress.lat),
double.parse(order.shippingAddress.lng));
if (order!.shippingMethod == 'store-delivery' && order!.status != Constants.STATUS_COMPLETE && order!.status != Constants.STATUS_CANCELLED) {
storeLatLng = LatLng(double.parse(order!.businessInfo?.address.lat ?? '0'),
double.parse(order!.businessInfo?.address.lng ?? '0'));
customerLatLng = LatLng(double.parse(order!.shippingAddress?.lat ?? '0'),
double.parse(order!.shippingAddress?.lng ?? '0'));
deliveryLatLng =
LatLng(order.shipperPosition.lat, order.shipperPosition.lng);
LatLng(order!.shipperPosition.lat, order!.shipperPosition.lng);
_polyLine.clear();
_polyLine.add(
@@ -1078,8 +1078,8 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
],
width: 3,
points: [
order.shipperPosition.lat != 0.0 ? deliveryLatLng : storeLatLng,
customerLatLng,
order!.shipperPosition.lat != 0.0 ? deliveryLatLng! : storeLatLng!,
customerLatLng!,
]
)
);
@@ -1087,38 +1087,38 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
_markers.clear();
_markers.add(Marker(
markerId: MarkerId('shop_position'),
position: storeLatLng,
position: storeLatLng!,
infoWindow: InfoWindow(
title: S
.of(context)
.store,
snippet: '',
),
icon: shopIcon,
icon: shopIcon!,
));
_markers.add(Marker(
markerId: MarkerId('customer_position'),
position: customerLatLng,
position: customerLatLng!,
infoWindow: InfoWindow(
title: S
.of(context)
.customer,
snippet: order.shippingAddress.addressLine1,
snippet: order!.shippingAddress!.addressLine1,
),
icon: homeIcon,
icon: homeIcon!,
));
if (order.shipperPosition.lat != 0.0 &&
order.shipperPosition.lng != 0.0) {
if (order!.shipperPosition.lat != 0.0 &&
order!.shipperPosition.lng != 0.0) {
_markers.add(Marker(
markerId: MarkerId('shipper_position'),
position: deliveryLatLng,
position: deliveryLatLng!,
infoWindow: InfoWindow(
title: S
.of(context)
.delivery_guy,
snippet: '',
),
icon: deliveryIcon,
icon: deliveryIcon!,
));
}
}
@@ -1145,7 +1145,7 @@ class MobileOrderDetailState extends State<MobileOrderDetail> {
S.of(context).no,
),
style: TextButton.styleFrom(
primary: Theme.of(context).primaryColor,
foregroundColor: Theme.of(context).primaryColor,
),
onPressed: () {
Navigator.of(context).pop();