import 'dart:async'; import 'package:autosos_flutter/model/order.dart'; import 'package:autosos_flutter/provider/providers.dart'; import 'package:autosos_flutter/router/app_router.dart'; import 'package:autosos_flutter/util/toast.dart'; import 'package:autosos_flutter/widget/multi_state_view.dart'; import 'package:flutter/material.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:intl/intl.dart'; /// 等待接单页(对应 Android WaitOrderActivity) /// 列出当前可抢订单,倒计时 0 后自动从列表移除 class WaitingPage extends ConsumerStatefulWidget { const WaitingPage({super.key}); @override ConsumerState createState() => _WaitingPageState(); } class _WaitingPageState extends ConsumerState { MultiState _state = MultiState.loading; List _items = []; Timer? _ticker; @override void initState() { super.initState(); _load(); // 每秒刷新倒计时 _ticker = Timer.periodic(const Duration(seconds: 1), (_) { if (mounted) setState(() {}); }); } @override void dispose() { _ticker?.cancel(); super.dispose(); } Future _load() async { setState(() => _state = MultiState.loading); try { final resp = await ref.read(orderApiProvider).waitingList(); if (!mounted) return; if (!resp.isSuccess) { setState(() => _state = MultiState.error); Toast.error(resp.message ?? '加载失败'); return; } setState(() { _items = resp.data ?? []; _state = _items.isEmpty ? MultiState.empty : MultiState.success; }); } catch (e) { if (mounted) setState(() => _state = MultiState.error); } } Future _grab(WaitingOrder item) async { EasyLoading.show(status: '抢单中…'); try { final order = await ref.read(orderServiceProvider).grab(item.orderId); EasyLoading.dismiss(); Toast.success('接单成功'); if (!mounted) return; // 跳转到救援中页 context.pushReplacement('${Routes.orderConduct}/${order.id}'); } catch (e) { EasyLoading.dismiss(); Toast.error('抢单失败:$e'); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('等待接单'), actions: [ IconButton(icon: const Icon(Icons.refresh), onPressed: _load), ], ), body: RefreshIndicator( onRefresh: _load, child: MultiStateView( state: _state, emptyText: '当前没有可接订单', onRetry: _load, child: ListView.separated( padding: const EdgeInsets.all(12), itemCount: _items.length, separatorBuilder: (_, __) => const SizedBox(height: 8), itemBuilder: (ctx, i) { final o = _items[i]; return _WaitingCard( item: o, onGrab: () => _grab(o), ); }, ), ), ), ); } } class _WaitingCard extends StatelessWidget { final WaitingOrder item; final VoidCallback onGrab; const _WaitingCard({required this.item, required this.onGrab}); String _formatCountdown(int s) { if (s <= 0) return '已超时'; final m = (s ~/ 60).toString().padLeft(2, '0'); final sec = (s % 60).toString().padLeft(2, '0'); return '$m:$sec'; } @override Widget build(BuildContext context) { final fmt = DateFormat('MM-dd HH:mm'); final expired = item.countdown <= 0; return Material( color: Colors.white, borderRadius: BorderRadius.circular(8), child: Padding( padding: const EdgeInsets.all(12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Container( padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 2, ), decoration: BoxDecoration( color: Colors.red.shade50, borderRadius: BorderRadius.circular(4), ), child: Text( item.serviceType, style: TextStyle( color: Colors.red.shade700, fontSize: 12, ), ), ), const SizedBox(width: 8), if (item.distance != null) Text( '距离 ${(item.distance! / 1000).toStringAsFixed(1)} km', style: TextStyle( fontSize: 12, color: Colors.grey.shade600, ), ), const Spacer(), Container( padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 4, ), decoration: BoxDecoration( color: expired ? Colors.grey : Colors.orange, borderRadius: BorderRadius.circular(4), ), child: Text( _formatCountdown(item.countdown), style: const TextStyle( color: Colors.white, fontSize: 12, fontWeight: FontWeight.bold, ), ), ), ], ), const SizedBox(height: 8), Text('订单号:${item.orderNo}', style: const TextStyle(fontSize: 13)), if (item.address != null && item.address!.isNotEmpty) ...[ const SizedBox(height: 4), Text('地点:${item.address}', style: TextStyle( fontSize: 13, color: Colors.grey.shade700)), ], const SizedBox(height: 4), Text('时间:${fmt.format(item.createdAt)}', style: TextStyle(fontSize: 12, color: Colors.grey.shade500)), const SizedBox(height: 8), Row( children: [ Text( '¥${item.amount.toStringAsFixed(2)}', style: const TextStyle( color: Colors.red, fontSize: 18, fontWeight: FontWeight.bold, ), ), const Spacer(), ElevatedButton.icon( onPressed: expired ? null : onGrab, icon: const Icon(Icons.flash_on, size: 18), label: const Text('立即抢单'), style: ElevatedButton.styleFrom( backgroundColor: Theme.of(context).primaryColor, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20), ), ), ), ], ), ], ), ), ); } }