2025-09-18 16:13:37 +08:00
|
|
|
// 钱包页面
|
|
|
|
|
import 'package:easy_refresh/easy_refresh.dart';
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
import 'package:get/get.dart';
|
2025-09-22 14:41:47 +08:00
|
|
|
import 'package:loopin/IM/controller/im_user_info_controller.dart';
|
2025-09-18 16:13:37 +08:00
|
|
|
import 'package:loopin/behavior/custom_scroll_behavior.dart';
|
2025-09-22 14:41:47 +08:00
|
|
|
import 'package:loopin/components/empty_tip.dart';
|
2025-09-29 02:34:41 +08:00
|
|
|
import 'package:loopin/components/my_toast.dart';
|
2025-09-18 16:13:37 +08:00
|
|
|
import 'package:loopin/pages/my/merchant/balance/controller.dart';
|
2025-09-22 14:41:47 +08:00
|
|
|
import 'package:loopin/utils/index.dart';
|
2025-09-18 16:13:37 +08:00
|
|
|
|
|
|
|
|
class Balance extends StatefulWidget {
|
|
|
|
|
const Balance({super.key});
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
State<Balance> createState() => _BalanceState();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class _BalanceState extends State<Balance> {
|
2025-09-22 14:41:47 +08:00
|
|
|
final controller = Get.find<BalanceController>();
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
void dispose() {
|
|
|
|
|
Get.delete<BalanceController>();
|
|
|
|
|
super.dispose();
|
|
|
|
|
}
|
2025-09-18 16:13:37 +08:00
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
|
return Scaffold(
|
2025-09-22 14:41:47 +08:00
|
|
|
appBar: AppBar(title: Text("我的余额")),
|
2025-09-18 16:13:37 +08:00
|
|
|
body: ScrollConfiguration(
|
|
|
|
|
behavior: CustomScrollBehavior().copyWith(scrollbars: false),
|
|
|
|
|
child: Column(
|
|
|
|
|
children: [
|
|
|
|
|
// 上半部分:余额 + 充值
|
|
|
|
|
Container(
|
|
|
|
|
padding: const EdgeInsets.all(16),
|
|
|
|
|
color: Colors.blueAccent,
|
|
|
|
|
width: double.infinity,
|
|
|
|
|
child: Obx(() {
|
2025-09-22 14:41:47 +08:00
|
|
|
final ctl = Get.find<ImUserInfoController>();
|
|
|
|
|
final role = ctl.role.value;
|
|
|
|
|
final isLeader = Utils.hasRole(role, 5);
|
2025-09-18 16:13:37 +08:00
|
|
|
return Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
const Text(
|
|
|
|
|
"钱包余额",
|
|
|
|
|
style: TextStyle(color: Colors.white, fontSize: 16),
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(height: 8),
|
|
|
|
|
Text(
|
|
|
|
|
"¥ ${controller.balance.value.toStringAsFixed(2)}",
|
|
|
|
|
style: const TextStyle(
|
|
|
|
|
color: Colors.white,
|
|
|
|
|
fontSize: 28,
|
|
|
|
|
fontWeight: FontWeight.bold,
|
|
|
|
|
),
|
|
|
|
|
),
|
2025-09-22 14:41:47 +08:00
|
|
|
// if (isLeader) const SizedBox(height: 12),
|
|
|
|
|
Row(
|
|
|
|
|
children: [
|
|
|
|
|
ElevatedButton(
|
2025-09-29 02:34:41 +08:00
|
|
|
onPressed: () async {
|
2025-09-22 14:41:47 +08:00
|
|
|
// 加充值
|
2025-09-29 02:34:41 +08:00
|
|
|
// controller.recharge(money: '0.1');
|
|
|
|
|
final money = await showDialog<String>(
|
|
|
|
|
context: context,
|
|
|
|
|
builder: (context) {
|
|
|
|
|
String input = "";
|
|
|
|
|
return AlertDialog(
|
|
|
|
|
title: Text("请输入充值金额"),
|
|
|
|
|
content: TextField(
|
|
|
|
|
keyboardType: TextInputType.numberWithOptions(decimal: true),
|
|
|
|
|
decoration: InputDecoration(
|
|
|
|
|
hintText: "请输入50~200之间的金额",
|
|
|
|
|
),
|
|
|
|
|
onChanged: (value) => input = value,
|
|
|
|
|
),
|
|
|
|
|
actions: [
|
|
|
|
|
TextButton(
|
|
|
|
|
onPressed: () => Navigator.of(context).pop(), // 取消
|
|
|
|
|
child: Text("取消"),
|
|
|
|
|
),
|
|
|
|
|
TextButton(
|
|
|
|
|
onPressed: () {
|
|
|
|
|
final num? value = num.tryParse(input);
|
|
|
|
|
if (value == null) {
|
|
|
|
|
Navigator.of(context).pop();
|
|
|
|
|
MyToast().tip(title: '请输入正确的金额');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (value < 0 || value > 200) {
|
|
|
|
|
Navigator.of(context).pop();
|
|
|
|
|
MyToast().tip(title: '金额必须在 50 ~ 200 之间');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
Navigator.of(context).pop(input); // 返回合法输入
|
|
|
|
|
},
|
|
|
|
|
child: Text("确定"),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (money != null && money.isNotEmpty) {
|
|
|
|
|
controller.recharge(money: money);
|
|
|
|
|
}
|
2025-09-22 14:41:47 +08:00
|
|
|
},
|
|
|
|
|
style: ElevatedButton.styleFrom(
|
|
|
|
|
backgroundColor: Colors.orange,
|
|
|
|
|
),
|
|
|
|
|
child: const Text("充值"),
|
|
|
|
|
),
|
|
|
|
|
SizedBox(width: 20),
|
|
|
|
|
//
|
|
|
|
|
ElevatedButton(
|
2025-09-29 02:34:41 +08:00
|
|
|
onPressed: () async {
|
|
|
|
|
// onWithdrawPressed();
|
2025-09-22 14:41:47 +08:00
|
|
|
// 提现
|
2025-09-29 02:34:41 +08:00
|
|
|
if (controller.balance.value < 10) {
|
|
|
|
|
MyToast().tip(title: '钱包余额不足');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
final money = await showDialog<String>(
|
|
|
|
|
context: context,
|
|
|
|
|
builder: (context) {
|
|
|
|
|
String input = "";
|
|
|
|
|
return AlertDialog(
|
|
|
|
|
title: Text("请输入提现金额"),
|
|
|
|
|
content: TextField(
|
|
|
|
|
maxLength: 5,
|
|
|
|
|
maxLines: 1,
|
|
|
|
|
keyboardType: TextInputType.numberWithOptions(decimal: true),
|
|
|
|
|
decoration: InputDecoration(
|
|
|
|
|
hintText: "当前可提现金额为:${controller.balance.value}",
|
|
|
|
|
),
|
|
|
|
|
onChanged: (value) => input = value,
|
|
|
|
|
),
|
|
|
|
|
actions: [
|
|
|
|
|
TextButton(
|
|
|
|
|
onPressed: () => Navigator.of(context).pop(), // 取消
|
|
|
|
|
child: Text("取消"),
|
|
|
|
|
),
|
|
|
|
|
TextButton(
|
|
|
|
|
onPressed: () {
|
|
|
|
|
final num? value = num.tryParse(input);
|
|
|
|
|
if (value == null || value < 0.1) {
|
|
|
|
|
Navigator.of(context).pop();
|
|
|
|
|
MyToast().tip(title: '请输入正确的金额');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (value > controller.balance.value) {
|
|
|
|
|
Navigator.of(context).pop();
|
|
|
|
|
MyToast().tip(title: '您当前可提现余额为:${controller.balance.value}');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (value > 200) {
|
|
|
|
|
Navigator.of(context).pop();
|
|
|
|
|
MyToast().tip(title: '提现金额上限为200');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
Navigator.of(context).pop(input); // 返回合法输入
|
|
|
|
|
},
|
|
|
|
|
child: Text("确定"),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (money != null && money.isNotEmpty) {
|
|
|
|
|
controller.withDraw(money: money);
|
|
|
|
|
}
|
2025-09-22 14:41:47 +08:00
|
|
|
},
|
|
|
|
|
style: ElevatedButton.styleFrom(
|
|
|
|
|
backgroundColor: Colors.orange,
|
|
|
|
|
),
|
|
|
|
|
child: const Text("提现"),
|
|
|
|
|
),
|
|
|
|
|
],
|
2025-09-18 16:13:37 +08:00
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
);
|
|
|
|
|
}),
|
|
|
|
|
),
|
|
|
|
|
|
2025-09-29 02:34:41 +08:00
|
|
|
//提示内容
|
|
|
|
|
Padding(
|
|
|
|
|
padding: const EdgeInsets.all(16.0),
|
|
|
|
|
child: SizedBox(
|
|
|
|
|
width: double.infinity, // 占满父级宽度
|
|
|
|
|
child: Text(
|
|
|
|
|
'提示:\n'
|
|
|
|
|
'1. 余额不可用于购买商品\n'
|
|
|
|
|
'2. 余额只支持提现到授权的微信账户内\n'
|
|
|
|
|
'3. 提现申请通过后将于一个工作日内到账\n',
|
|
|
|
|
style: TextStyle(
|
|
|
|
|
fontSize: 14,
|
|
|
|
|
color: Colors.red[700],
|
|
|
|
|
),
|
|
|
|
|
textAlign: TextAlign.left,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
|
2025-09-18 16:13:37 +08:00
|
|
|
// 下半部分:流水记录分页列表
|
|
|
|
|
Expanded(
|
2025-09-22 14:41:47 +08:00
|
|
|
child: EasyRefresh.builder(
|
|
|
|
|
callLoadOverOffset: 20, //触底距离
|
|
|
|
|
callRefreshOverOffset: 20, // 下拉距离
|
|
|
|
|
header: ClassicHeader(
|
|
|
|
|
dragText: '下拉刷新',
|
|
|
|
|
armedText: '释放刷新',
|
|
|
|
|
readyText: '加载中...',
|
|
|
|
|
processingText: '加载中...',
|
|
|
|
|
processedText: '加载完成',
|
|
|
|
|
failedText: '加载失败,请重试',
|
|
|
|
|
messageText: '最后更新于 %T',
|
|
|
|
|
),
|
|
|
|
|
footer: ClassicFooter(
|
|
|
|
|
dragText: '加载更多',
|
|
|
|
|
armedText: '释放加载',
|
|
|
|
|
readyText: '加载中...',
|
|
|
|
|
processingText: '加载中...',
|
|
|
|
|
processedText: '加载完成',
|
|
|
|
|
noMoreText: '没有更多了~',
|
|
|
|
|
failedText: '加载失败,请重试',
|
|
|
|
|
messageText: '最后更新于 %T',
|
|
|
|
|
),
|
2025-09-18 16:13:37 +08:00
|
|
|
|
2025-09-22 14:41:47 +08:00
|
|
|
onRefresh: () async {
|
|
|
|
|
await controller.getData(reset: true);
|
|
|
|
|
},
|
|
|
|
|
onLoad: () async {
|
|
|
|
|
if (controller.hasMore.value) {
|
|
|
|
|
await controller.getData();
|
|
|
|
|
return controller.hasMore.value ? IndicatorResult.success : IndicatorResult.noMore;
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
childBuilder: (context, physics) {
|
|
|
|
|
return Obx(
|
|
|
|
|
() {
|
|
|
|
|
// 数据加载中
|
|
|
|
|
if (controller.isLoading.value && controller.data.isEmpty) {
|
|
|
|
|
return Center(
|
|
|
|
|
child: CircularProgressIndicator(),
|
2025-09-18 16:13:37 +08:00
|
|
|
);
|
2025-09-22 14:41:47 +08:00
|
|
|
}
|
|
|
|
|
//空
|
|
|
|
|
if (controller.data.isEmpty) {
|
|
|
|
|
return EmptyTip();
|
|
|
|
|
}
|
|
|
|
|
return ListView.builder(
|
|
|
|
|
physics: physics,
|
|
|
|
|
itemCount: controller.data.length,
|
|
|
|
|
itemBuilder: (context, index) {
|
|
|
|
|
final tx = controller.data[index];
|
|
|
|
|
|
|
|
|
|
return ListTile(
|
2025-09-29 02:34:41 +08:00
|
|
|
title: Text(tx.sourceName), // 来源
|
|
|
|
|
subtitle: Text(tx.createTime), // 时间
|
2025-09-22 14:41:47 +08:00
|
|
|
trailing: Text(
|
2025-09-29 02:34:41 +08:00
|
|
|
"变动金额:${tx.changeType == 1 ? '+' : '-'}${tx.changeAmount}", // 变动金额
|
2025-09-22 14:41:47 +08:00
|
|
|
style: TextStyle(
|
|
|
|
|
fontWeight: FontWeight.bold,
|
|
|
|
|
color: tx.changeType == 1 ? Colors.green : Colors.red,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
),
|
2025-09-18 16:13:37 +08:00
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-09-29 02:34:41 +08:00
|
|
|
|
|
|
|
|
String _handleSource(String source) {
|
|
|
|
|
String res;
|
|
|
|
|
if (source == '3') {
|
|
|
|
|
res = '充值';
|
|
|
|
|
} else if (source == '2') {
|
|
|
|
|
res = '待确认';
|
|
|
|
|
} else if (source == '1') {
|
|
|
|
|
res = '提现';
|
|
|
|
|
} else if (source == '5') {
|
|
|
|
|
res = '提现退款';
|
|
|
|
|
} else if (source == '4') {
|
|
|
|
|
res = '充值退款';
|
|
|
|
|
} else {
|
|
|
|
|
res = '未知';
|
|
|
|
|
}
|
|
|
|
|
return res;
|
|
|
|
|
}
|