import 'dart:async'; import 'package:autosos_flutter/api/order_api.dart'; import 'package:autosos_flutter/config/constant.dart'; import 'package:autosos_flutter/model/order.dart'; import 'package:autosos_flutter/model/payment.dart'; import 'package:autosos_flutter/service/audio_service.dart'; import 'package:autosos_flutter/service/location_service.dart'; import 'package:flutter/foundation.dart'; /// 订单状态机 + 业务编排服务(对应 Android 订单状态机) class OrderService { static final OrderService instance = OrderService._(); OrderService._(); Order? _current; Order? get currentOrder => _current; /// 状态变化回调 final _stateController = StreamController.broadcast(); Stream get stateStream => _stateController.stream; /// 救援中(conducting)→ 上报当前位置的轨迹点 Timer? _trackUploadTimer; /// 设置当前订单 void setCurrent(Order? order) { _current = order; if (order != null) { Constant.isService = order.status == OrderStatus.conducting; _stateController.add(OrderStateEvent.updated(order)); } } /// 接单 Future grab(int orderId) async { final resp = await OrderApi.instance.grabOrder(orderId); if (!resp.isSuccess) throw Exception(resp.message ?? '接单失败'); final order = resp.data!; setCurrent(order); return order; } /// 到达现场 Future arrive({double? lat, double? lng}) async { if (_current == null) throw Exception('当前无进行中订单'); final loc = LocationService.instance.last; final r = await OrderApi.instance.arriveScene( _current!.id, lat: lat ?? (loc?['latitude'] as num?)?.toDouble(), lng: lng ?? (loc?['longitude'] as num?)?.toDouble(), ); if (!r.isSuccess) throw Exception(r.message ?? '上报到达失败'); final updated = _current!.copyWith( status: OrderStatus.conducting, arrivedAt: DateTime.now(), ); setCurrent(updated); _startTrack(); } /// 完成订单 Future complete({ required List amountItems, String? remark, }) async { if (_current == null) throw Exception('当前无订单'); final r = await OrderApi.instance.completeOrder( orderId: _current!.id, amountItems: amountItems, remark: remark, ); if (!r.isSuccess) throw Exception(r.message ?? '完成订单失败'); _stopTrack(); setCurrent(_current!.copyWith( status: OrderStatus.completed, completedAt: DateTime.now(), )); return r.data; } /// 取消订单 Future cancel() async { if (_current == null) return; _stopTrack(); setCurrent(_current!.copyWith(status: OrderStatus.cancelled)); } /// 启动轨迹上传 void _startTrack() { _trackUploadTimer?.cancel(); _trackUploadTimer = Timer.periodic(const Duration(seconds: 10), (_) async { if (_current == null) return; final loc = LocationService.instance.last; if (loc == null) return; try { await OrderApi.instance.uploadTrackPoints(_current!.id, [ { 'lat': (loc['latitude'] as num?)?.toDouble() ?? 0, 'lng': (loc['longitude'] as num?)?.toDouble() ?? 0, 'time': DateTime.now().toIso8601String(), 'speed': (loc['speed'] as num?)?.toDouble() ?? 0, 'bearing': (loc['bearing'] as num?)?.toDouble() ?? 0, } ]); } catch (e) { debugPrint('Track upload failed: $e'); } }); } /// 停止轨迹上传 void _stopTrack() { _trackUploadTimer?.cancel(); _trackUploadTimer = null; } /// 收到新订单推送时触发本地语音提醒 Future onPushNewOrder(Map payload) async { final type = (payload['type'] as num?)?.toInt() ?? 0; if (type == Constant.NEW_ORDER_INSIDE) { AudioService.instance.newInsideOrder(); } else if (type == Constant.NEW_ORDER_JIUJIU) { AudioService.instance.newJiuJiuOrder(); } } void dispose() { _stopTrack(); _stateController.close(); } } /// 订单状态变化事件 class OrderStateEvent { final OrderStateEventType type; final Order? order; const OrderStateEvent(this.type, this.order); factory OrderStateEvent.updated(Order o) => OrderStateEvent(OrderStateEventType.updated, o); } enum OrderStateEventType { updated, completed, cancelled, paid }