import 'package:autosos_flutter/model/misc.dart'; import 'package:autosos_flutter/model/order.dart'; import 'package:autosos_flutter/model/payment.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'; /// 完成订单页(对应 Android FinishOrderActivity) /// 录入费用明细 → 提交完成 → 跳转记录页 class CompletePage extends ConsumerStatefulWidget { final int orderId; const CompletePage({super.key, required this.orderId}); @override ConsumerState createState() => _CompletePageState(); } class _CompletePageState extends ConsumerState { MultiState _state = MultiState.loading; Order? _order; final List _items = []; final TextEditingController _remarkCtrl = TextEditingController(); bool _submitting = false; @override void initState() { super.initState(); _load(); } @override void dispose() { _remarkCtrl.dispose(); super.dispose(); } Future _load() async { setState(() => _state = MultiState.loading); try { final resp = await ref.read(orderApiProvider).orderDetail(widget.orderId); if (!mounted) return; if (!resp.isSuccess || resp.data == null) { setState(() => _state = MultiState.error); return; } setState(() { _order = resp.data; // 默认添加一条基础服务费 if (_items.isEmpty) { _items.add(AmountItem( id: 0, title: '基础服务费', amount: resp.data!.amount, type: 'income', createdAt: DateTime.now(), orderNo: resp.data!.orderNo, )); } _state = MultiState.success; }); } catch (e) { if (mounted) setState(() => _state = MultiState.error); } } double get _total => _items.fold(0, (s, e) => s + e.amount); Future _addItem() async { final added = await showDialog( context: context, builder: (_) => const _AddAmountDialog(), ); if (added != null) setState(() => _items.add(added)); } Future _submit() async { if (_items.isEmpty) { Toast.error('请至少添加一项费用明细'); return; } setState(() => _submitting = true); EasyLoading.show(status: '提交中…'); try { final r = await ref.read(orderServiceProvider).complete( amountItems: _items, remark: _remarkCtrl.text.trim().isEmpty ? null : _remarkCtrl.text.trim(), ); EasyLoading.dismiss(); if (r is CompleteOrderInfo) { Toast.success('订单已完成'); if (mounted) { // 通知服务端完成(已在 OrderService 中调用) context.go(Routes.orderRecord); } } } catch (e) { EasyLoading.dismiss(); Toast.error('提交失败:$e'); } finally { if (mounted) setState(() => _submitting = false); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('完成订单'), actions: [ if (_order != null) Padding( padding: const EdgeInsets.only(right: 12), child: Center( child: Text( '订单 ${_order!.orderNo}', style: const TextStyle(fontSize: 12), ), ), ), ], ), body: MultiStateView( state: _state, onRetry: _load, child: _order == null ? const SizedBox.shrink() : ListView( padding: const EdgeInsets.all(12), children: [ _summary(), const SizedBox(height: 12), _itemList(), const SizedBox(height: 8), OutlinedButton.icon( onPressed: _addItem, icon: const Icon(Icons.add), label: const Text('添加费用项'), ), const SizedBox(height: 12), TextField( controller: _remarkCtrl, maxLines: 3, decoration: const InputDecoration( labelText: '备注', border: OutlineInputBorder(), ), ), const SizedBox(height: 16), Row( children: [ const Text('合计:', style: TextStyle(fontSize: 16)), Text( '¥${_total.toStringAsFixed(2)}', style: const TextStyle( color: Colors.red, fontSize: 22, fontWeight: FontWeight.bold, ), ), ], ), const SizedBox(height: 12), ElevatedButton( onPressed: _submitting ? null : _submit, style: ElevatedButton.styleFrom( backgroundColor: Colors.green, minimumSize: const Size.fromHeight(48), ), child: Text(_submitting ? '提交中…' : '提交完成'), ), ], ), ), ); } Widget _summary() { final o = _order!; return Material( color: Colors.white, borderRadius: BorderRadius.circular(8), child: Padding( padding: const EdgeInsets.all(12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(o.serviceType, style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), const SizedBox(height: 4), if (o.address != null) Text('地点:${o.address}', style: TextStyle(color: Colors.grey.shade700, fontSize: 13)), if (o.customerName != null) Text('客户:${o.customerName!}', style: TextStyle(color: Colors.grey.shade700, fontSize: 13)), ], ), ), ); } Widget _itemList() { return Material( color: Colors.white, borderRadius: BorderRadius.circular(8), child: Column( children: [ for (int i = 0; i < _items.length; i++) ListTile( title: Text(_items[i].title), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ Text('¥${_items[i].amount.toStringAsFixed(2)}', style: const TextStyle( color: Colors.red, fontWeight: FontWeight.bold, )), IconButton( icon: const Icon(Icons.delete_outline, color: Colors.red), onPressed: () => setState(() => _items.removeAt(i)), ), ], ), ), ], ), ); } } /// 新增费用项弹窗 class _AddAmountDialog extends StatefulWidget { const _AddAmountDialog(); @override State<_AddAmountDialog> createState() => _AddAmountDialogState(); } class _AddAmountDialogState extends State<_AddAmountDialog> { final _title = TextEditingController(); final _amount = TextEditingController(); @override void dispose() { _title.dispose(); _amount.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return AlertDialog( title: const Text('添加费用项'), content: Column( mainAxisSize: MainAxisSize.min, children: [ TextField( controller: _title, decoration: const InputDecoration( labelText: '费用名称', border: OutlineInputBorder(), ), ), const SizedBox(height: 8), TextField( controller: _amount, keyboardType: const TextInputType.numberWithOptions(decimal: true), decoration: const InputDecoration( labelText: '金额', prefixText: '¥ ', border: OutlineInputBorder(), ), ), ], ), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('取消'), ), ElevatedButton( onPressed: () { final t = _title.text.trim(); final a = double.tryParse(_amount.text.trim()) ?? 0; if (t.isEmpty || a <= 0) { Toast.error('请填写完整'); return; } Navigator.pop( context, AmountItem( id: 0, title: t, amount: a, type: 'income', createdAt: DateTime.now(), ), ); }, child: const Text('添加'), ), ], ); } }