jjsos_autosos_flutter/lib/pages/me/recharge_page.dart

155 lines
5.0 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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/services.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:fluwx/fluwx.dart';
/// 充值页(对应 Android RechargeActivity
class RechargePage extends ConsumerStatefulWidget {
const RechargePage({super.key});
@override
ConsumerState<RechargePage> createState() => _RechargePageState();
}
class _RechargePageState extends ConsumerState<RechargePage> {
final _amount = TextEditingController();
String _payMethod = 'wx';
String? _qrUrl;
bool _loading = false;
final _presets = [50.0, 100.0, 200.0, 500.0, 1000.0, 2000.0];
@override
void dispose() {
_amount.dispose();
super.dispose();
}
Future<void> _submit() async {
final amount = double.tryParse(_amount.text.trim());
if (amount == null || amount <= 0) {
Toast.error('请输入充值金额');
return;
}
setState(() => _loading = true);
EasyLoading.show(status: '生成订单中…');
try {
final r = await ref.read(userApiProvider).recharge(
amount: amount,
payMethod: _payMethod,
);
EasyLoading.dismiss();
if (!r.isSuccess || r.data == null) {
Toast.error(r.message ?? '下单失败');
return;
}
// 微信支付(带 sign 的预支付)
if (_payMethod == 'wx' && r.data is Map) {
final m = r.data as Map;
await Fluwx().pay(
which: Payment(
appId: m['appid'] ?? '',
partnerId: m['partnerid'] ?? '',
prepayId: m['prepayid'] ?? '',
packageValue: m['package'] ?? 'Sign=WXPay',
nonceStr: m['noncestr'] ?? '',
timestamp: int.tryParse(m['timestamp']?.toString() ?? '') ?? 0,
sign: m['sign'] ?? '',
),
);
return;
}
// 二维码
if (r.data is Map && (r.data as Map)['qr_code_url'] != null) {
setState(() => _qrUrl = (r.data as Map)['qr_code_url']);
} else {
Toast.success('订单已生成');
}
} catch (e) {
EasyLoading.dismiss();
Toast.error('充值失败:$e');
} finally {
if (mounted) setState(() => _loading = false);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('充值')),
body: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Text('选择充值金额',
style: TextStyle(fontWeight: FontWeight.bold)),
const SizedBox(height: 8),
Wrap(
spacing: 8,
runSpacing: 8,
children: _presets
.map(
(a) => ChoiceChip(
label: Text('¥${a.toStringAsFixed(0)}'),
selected: _amount.text == a.toStringAsFixed(0),
onSelected: (_) =>
setState(() => _amount.text = a.toStringAsFixed(0)),
),
)
.toList(),
),
const SizedBox(height: 12),
TextField(
controller: _amount,
keyboardType:
const TextInputType.numberWithOptions(decimal: true),
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[0-9.]')),
],
decoration: const InputDecoration(
labelText: '其他金额',
prefixText: '¥ ',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 16),
const Text('支付方式',
style: TextStyle(fontWeight: FontWeight.bold)),
RadioListTile<String>(
title: const Text('微信支付'),
value: 'wx',
groupValue: _payMethod,
onChanged: (v) => setState(() => _payMethod = v ?? 'wx'),
),
if (_qrUrl != null) ...[
const SizedBox(height: 16),
Center(
child: QrImageView(data: _qrUrl!, size: 200),
),
const SizedBox(height: 8),
const Center(
child: Text('请使用微信扫码支付',
style: TextStyle(color: Colors.grey)),
),
],
const SizedBox(height: 24),
ElevatedButton(
onPressed: _loading ? null : _submit,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.green,
minimumSize: const Size.fromHeight(48),
),
child: Text(_loading ? '处理中…' : '立即充值'),
),
],
),
),
);
}
}