import 'package:autosos_flutter/model/base_response.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/util/toast.dart'; import 'package:autosos_flutter/widget/qr_image.dart'; import 'package:flutter/material.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:fluwx/fluwx.dart'; import 'package:go_router/go_router.dart'; /// 收款页(对应 Android FinishOrderMoneyActivity) /// 三种方式:微信支付(技师端唤起收款码让客户扫)/ 现金收款 / 已扫码后回调 class CollectionPage extends ConsumerStatefulWidget { final int orderId; const CollectionPage({super.key, required this.orderId}); @override ConsumerState createState() => _CollectionPageState(); } class _CollectionPageState extends ConsumerState { Order? _order; final TextEditingController _amountCtrl = TextEditingController(); String _qrUrl = ''; bool _loading = false; @override void initState() { super.initState(); _load(); } @override void dispose() { _amountCtrl.dispose(); super.dispose(); } Future _load() async { try { final resp = await ref.read(orderApiProvider).orderDetail(widget.orderId); if (!mounted) return; if (!resp.isSuccess || resp.data == null) { Toast.error('订单不存在'); return; } setState(() { _order = resp.data; _amountCtrl.text = resp.data!.amount.toStringAsFixed(2); }); } catch (e) { Toast.error('加载失败:$e'); } } Future _wxPay() async { final amount = double.tryParse(_amountCtrl.text.trim()); if (amount == null || amount <= 0) { Toast.error('请输入有效金额'); return; } setState(() => _loading = true); EasyLoading.show(status: '生成中…'); try { final BaseResponse resp = await ref .read(orderApiProvider) .createPayQrCode(widget.orderId, amount); if (!resp.isSuccess) { EasyLoading.dismiss(); Toast.error(resp.message ?? '生成失败'); return; } setState(() => _qrUrl = resp.data ?? ''); EasyLoading.dismiss(); } catch (e) { EasyLoading.dismiss(); Toast.error('生成失败:$e'); } finally { if (mounted) setState(() => _loading = false); } } Future _wxPayNative() async { final amount = double.tryParse(_amountCtrl.text.trim()); if (amount == null || amount <= 0) { Toast.error('请输入有效金额'); return; } setState(() => _loading = true); EasyLoading.show(status: '调起微信…'); try { final BaseResponse resp = await ref .read(orderApiProvider) .createWxPay(widget.orderId, amount); EasyLoading.dismiss(); if (!resp.isSuccess || resp.data == null) { Toast.error(resp.message ?? '下单失败'); return; } final pay = resp.data!; await Fluwx().pay( which: Payment( appId: pay.appId, partnerId: pay.partnerId, prepayId: pay.prepayId, packageValue: pay.packageValue, nonceStr: pay.nonceStr, timestamp: int.tryParse(pay.timeStamp) ?? 0, sign: pay.sign, ), ); } catch (e) { EasyLoading.dismiss(); Toast.error('调起失败:$e'); } finally { if (mounted) setState(() => _loading = false); } } Future _cashPay() async { final amount = double.tryParse(_amountCtrl.text.trim()); if (amount == null || amount <= 0) { Toast.error('请输入有效金额'); return; } final ok = await showDialog( context: context, builder: (ctx) => AlertDialog( title: const Text('现金收款确认'), content: Text('确认已收到客户现金 ¥${amount.toStringAsFixed(2)}?'), actions: [ TextButton( onPressed: () => Navigator.pop(ctx, false), child: const Text('取消'), ), ElevatedButton( onPressed: () => Navigator.pop(ctx, true), child: const Text('确认'), ), ], ), ); if (ok != true) return; setState(() => _loading = true); try { final resp = await ref .read(orderApiProvider) .confirmCashPay(widget.orderId, amount); if (!resp.isSuccess) { Toast.error(resp.message ?? '提交失败'); return; } Toast.success('已记录现金收款'); if (mounted) context.pop(true); } catch (e) { Toast.error('提交失败:$e'); } finally { if (mounted) setState(() => _loading = false); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('客户付款')), body: _order == null ? const Center(child: CircularProgressIndicator()) : Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Text( '订单号:${_order!.orderNo}', style: const TextStyle(fontSize: 13), ), const SizedBox(height: 16), TextField( controller: _amountCtrl, keyboardType: const TextInputType.numberWithOptions( decimal: true, ), decoration: const InputDecoration( labelText: '收款金额', prefixText: '¥ ', border: OutlineInputBorder(), ), style: const TextStyle( fontSize: 28, fontWeight: FontWeight.bold, color: Colors.red, ), ), const SizedBox(height: 24), if (_qrUrl.isNotEmpty) ...[ Center( child: QrImageView( data: _qrUrl, size: 220, ), ), const SizedBox(height: 8), const Center( child: Text( '请客户扫码支付', style: TextStyle(color: Colors.grey), ), ), const SizedBox(height: 16), ], ElevatedButton.icon( onPressed: _loading ? null : _wxPay, icon: const Icon(Icons.qr_code_2), label: const Text('生成收款二维码'), style: ElevatedButton.styleFrom( backgroundColor: Colors.green, minimumSize: const Size.fromHeight(48), ), ), const SizedBox(height: 8), OutlinedButton.icon( onPressed: _loading ? null : _wxPayNative, icon: const Icon(Icons.wechat), label: const Text('调起微信收款'), style: OutlinedButton.styleFrom( side: const BorderSide(color: Colors.green), foregroundColor: Colors.green, minimumSize: const Size.fromHeight(48), ), ), const SizedBox(height: 8), OutlinedButton.icon( onPressed: _loading ? null : _cashPay, icon: const Icon(Icons.money), label: const Text('现金收款确认'), style: OutlinedButton.styleFrom( minimumSize: const Size.fromHeight(48), ), ), ], ), ), ); } }