feat(mobile): connect trading and mining pages to real APIs
- Trading page: fetch settleableUsdt and dstBalance from wallet-service - Trading page: implement real settlement API call - Mining page: fetch community/province/city from authorization-service - Add loading states and error handling 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
76377c3bb6
commit
0b3ddd51bd
|
|
@ -29,9 +29,11 @@ class _MiningPageState extends ConsumerState<MiningPage> {
|
||||||
String? _avatarSvg;
|
String? _avatarSvg;
|
||||||
String? _avatarUrl;
|
String? _avatarUrl;
|
||||||
String? _localAvatarPath; // 本地头像文件路径
|
String? _localAvatarPath; // 本地头像文件路径
|
||||||
final String _community = '星空社区';
|
|
||||||
final String _province = '广东';
|
// 授权数据(从 authorization-service 获取)
|
||||||
final String _city = '深圳';
|
String _community = '--';
|
||||||
|
String _province = '--';
|
||||||
|
String _city = '--';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
|
@ -39,6 +41,7 @@ class _MiningPageState extends ConsumerState<MiningPage> {
|
||||||
// 先同步检查本地头像,再异步加载其他数据
|
// 先同步检查本地头像,再异步加载其他数据
|
||||||
_checkLocalAvatarSync();
|
_checkLocalAvatarSync();
|
||||||
_loadUserData();
|
_loadUserData();
|
||||||
|
_loadAuthorizationData();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 同步检查本地头像文件(在 build 之前快速获取)
|
/// 同步检查本地头像文件(在 build 之前快速获取)
|
||||||
|
|
@ -97,6 +100,31 @@ class _MiningPageState extends ConsumerState<MiningPage> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 加载授权数据(社区、省、市)
|
||||||
|
Future<void> _loadAuthorizationData() async {
|
||||||
|
try {
|
||||||
|
debugPrint('[MiningPage] 开始加载授权数据...');
|
||||||
|
final authorizationService = ref.read(authorizationServiceProvider);
|
||||||
|
final summary = await authorizationService.getMyAuthorizationSummary();
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {
|
||||||
|
_community = summary.communityName ?? '--';
|
||||||
|
_city = summary.cityCompanyName ?? '--';
|
||||||
|
_province = summary.provinceCompanyName ?? '--';
|
||||||
|
});
|
||||||
|
debugPrint('[MiningPage] 授权数据加载成功:');
|
||||||
|
debugPrint('[MiningPage] 社区: $_community');
|
||||||
|
debugPrint('[MiningPage] 市公司: $_city');
|
||||||
|
debugPrint('[MiningPage] 省公司: $_province');
|
||||||
|
}
|
||||||
|
} catch (e, stackTrace) {
|
||||||
|
debugPrint('[MiningPage] 加载授权数据失败: $e');
|
||||||
|
debugPrint('[MiningPage] 堆栈: $stackTrace');
|
||||||
|
// 失败时保持默认值 '--'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// 显示帮助信息
|
/// 显示帮助信息
|
||||||
void _showHelpInfo() {
|
void _showHelpInfo() {
|
||||||
showDialog(
|
showDialog(
|
||||||
|
|
@ -238,6 +266,16 @@ class _MiningPageState extends ConsumerState<MiningPage> {
|
||||||
|
|
||||||
/// 构建用户信息区域
|
/// 构建用户信息区域
|
||||||
Widget _buildUserInfo() {
|
Widget _buildUserInfo() {
|
||||||
|
// 构建省市显示文本
|
||||||
|
String locationText = '';
|
||||||
|
if (_province != '--' && _city != '--') {
|
||||||
|
locationText = '$_province · $_city';
|
||||||
|
} else if (_province != '--') {
|
||||||
|
locationText = _province;
|
||||||
|
} else if (_city != '--') {
|
||||||
|
locationText = _city;
|
||||||
|
}
|
||||||
|
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
child: Row(
|
child: Row(
|
||||||
|
|
@ -274,13 +312,14 @@ class _MiningPageState extends ConsumerState<MiningPage> {
|
||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
Text(
|
Text(
|
||||||
'社区: $_community / 省市: $_province · $_city',
|
'社区: $_community${locationText.isNotEmpty ? ' / $locationText' : ''}',
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
fontFamily: 'Inter',
|
fontFamily: 'Inter',
|
||||||
height: 1.5,
|
height: 1.5,
|
||||||
color: Color(0xFF8B5A2B),
|
color: Color(0xFF8B5A2B),
|
||||||
),
|
),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import '../../../../core/di/injection_container.dart';
|
||||||
|
|
||||||
/// 结算币种枚举
|
/// 结算币种枚举
|
||||||
enum SettlementCurrency { bnb, og, usdt, dst }
|
enum SettlementCurrency { bnb, og, usdt, dst }
|
||||||
|
|
@ -17,9 +18,45 @@ class _TradingPageState extends ConsumerState<TradingPage> {
|
||||||
// 当前选中的结算币种
|
// 当前选中的结算币种
|
||||||
SettlementCurrency _selectedCurrency = SettlementCurrency.usdt;
|
SettlementCurrency _selectedCurrency = SettlementCurrency.usdt;
|
||||||
|
|
||||||
// 模拟数据
|
// 钱包数据(从 wallet-service 获取)
|
||||||
final double _settleableAmount = 1234.56;
|
double _settleableAmount = 0.0;
|
||||||
final double _dstBalance = 5678.90;
|
double _dstBalance = 0.0;
|
||||||
|
bool _isLoading = true;
|
||||||
|
bool _isSettling = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_loadWalletData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 加载钱包数据
|
||||||
|
Future<void> _loadWalletData() async {
|
||||||
|
try {
|
||||||
|
debugPrint('[TradingPage] 开始加载钱包数据...');
|
||||||
|
final walletService = ref.read(walletServiceProvider);
|
||||||
|
final wallet = await walletService.getMyWallet();
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {
|
||||||
|
_settleableAmount = wallet.rewards.settleableUsdt;
|
||||||
|
_dstBalance = wallet.balances.dst.available;
|
||||||
|
_isLoading = false;
|
||||||
|
});
|
||||||
|
debugPrint('[TradingPage] 钱包数据加载成功:');
|
||||||
|
debugPrint('[TradingPage] 可结算 USDT: $_settleableAmount');
|
||||||
|
debugPrint('[TradingPage] DST 余额: $_dstBalance');
|
||||||
|
}
|
||||||
|
} catch (e, stackTrace) {
|
||||||
|
debugPrint('[TradingPage] 加载钱包数据失败: $e');
|
||||||
|
debugPrint('[TradingPage] 堆栈: $stackTrace');
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {
|
||||||
|
_isLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// 选择结算币种
|
/// 选择结算币种
|
||||||
void _selectCurrency(SettlementCurrency currency) {
|
void _selectCurrency(SettlementCurrency currency) {
|
||||||
|
|
@ -30,6 +67,16 @@ class _TradingPageState extends ConsumerState<TradingPage> {
|
||||||
|
|
||||||
/// 一键结算
|
/// 一键结算
|
||||||
void _onSettlement() {
|
void _onSettlement() {
|
||||||
|
if (_settleableAmount <= 0) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(
|
||||||
|
content: Text('没有可结算的收益'),
|
||||||
|
backgroundColor: Color(0xFF8B5A2B),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
|
|
@ -45,12 +92,7 @@ class _TradingPageState extends ConsumerState<TradingPage> {
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
_doSettlement();
|
||||||
const SnackBar(
|
|
||||||
content: Text('结算成功'),
|
|
||||||
backgroundColor: Color(0xFFD4AF37),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
child: const Text('确认'),
|
child: const Text('确认'),
|
||||||
),
|
),
|
||||||
|
|
@ -59,6 +101,56 @@ class _TradingPageState extends ConsumerState<TradingPage> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 执行结算
|
||||||
|
Future<void> _doSettlement() async {
|
||||||
|
if (_isSettling) return;
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
_isSettling = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
debugPrint('[TradingPage] 开始结算...');
|
||||||
|
debugPrint('[TradingPage] 金额: $_settleableAmount USDT');
|
||||||
|
debugPrint('[TradingPage] 币种: ${_getCurrencyName(_selectedCurrency)}');
|
||||||
|
|
||||||
|
final walletService = ref.read(walletServiceProvider);
|
||||||
|
final orderId = await walletService.settleRewards(
|
||||||
|
usdtAmount: _settleableAmount,
|
||||||
|
settleCurrency: _getCurrencyName(_selectedCurrency),
|
||||||
|
);
|
||||||
|
|
||||||
|
debugPrint('[TradingPage] 结算成功: orderId=$orderId');
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(
|
||||||
|
content: Text('结算成功'),
|
||||||
|
backgroundColor: Color(0xFFD4AF37),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
// 刷新钱包数据
|
||||||
|
_loadWalletData();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint('[TradingPage] 结算失败: $e');
|
||||||
|
if (mounted) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Text('结算失败: $e'),
|
||||||
|
backgroundColor: Colors.red,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {
|
||||||
|
_isSettling = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// 卖出DST转换为USDT
|
/// 卖出DST转换为USDT
|
||||||
void _onSellDst() {
|
void _onSellDst() {
|
||||||
showDialog(
|
showDialog(
|
||||||
|
|
@ -207,17 +299,26 @@ class _TradingPageState extends ConsumerState<TradingPage> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
Text(
|
_isLoading
|
||||||
'${_formatNumber(_settleableAmount)} USDT',
|
? const SizedBox(
|
||||||
style: const TextStyle(
|
width: 24,
|
||||||
fontSize: 32,
|
height: 24,
|
||||||
fontFamily: 'Inter',
|
child: CircularProgressIndicator(
|
||||||
fontWeight: FontWeight.w700,
|
strokeWidth: 2,
|
||||||
height: 1.25,
|
valueColor: AlwaysStoppedAnimation<Color>(Color(0xFFD4AF37)),
|
||||||
letterSpacing: -0.8,
|
),
|
||||||
color: Color(0xFF5D4037),
|
)
|
||||||
),
|
: Text(
|
||||||
),
|
'${_formatNumber(_settleableAmount)} USDT',
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 32,
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
height: 1.25,
|
||||||
|
letterSpacing: -0.8,
|
||||||
|
color: Color(0xFF5D4037),
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -226,29 +327,39 @@ class _TradingPageState extends ConsumerState<TradingPage> {
|
||||||
|
|
||||||
/// 构建一键结算按钮
|
/// 构建一键结算按钮
|
||||||
Widget _buildSettlementButton() {
|
Widget _buildSettlementButton() {
|
||||||
|
final bool canSettle = !_isLoading && !_isSettling && _settleableAmount > 0;
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: _onSettlement,
|
onTap: canSettle ? _onSettlement : null,
|
||||||
child: Container(
|
child: Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
height: 56,
|
height: 56,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: const Color(0xFFD4AF37),
|
color: canSettle ? const Color(0xFFD4AF37) : const Color(0x80D4AF37),
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
),
|
),
|
||||||
child: const Center(
|
child: Center(
|
||||||
child: Text(
|
child: _isSettling
|
||||||
'一键结算',
|
? const SizedBox(
|
||||||
style: TextStyle(
|
width: 24,
|
||||||
fontSize: 16,
|
height: 24,
|
||||||
fontFamily: 'Inter',
|
child: CircularProgressIndicator(
|
||||||
fontWeight: FontWeight.w700,
|
strokeWidth: 2,
|
||||||
height: 1.5,
|
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
|
||||||
letterSpacing: 0.24,
|
),
|
||||||
color: Colors.white,
|
)
|
||||||
),
|
: const Text(
|
||||||
),
|
'一键结算',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
height: 1.5,
|
||||||
|
letterSpacing: 0.24,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -373,14 +484,23 @@ class _TradingPageState extends ConsumerState<TradingPage> {
|
||||||
|
|
||||||
/// 构建DST余额显示
|
/// 构建DST余额显示
|
||||||
Widget _buildDstBalance() {
|
Widget _buildDstBalance() {
|
||||||
return Text(
|
return _isLoading
|
||||||
'DST 余额: ${_formatNumber(_dstBalance)}',
|
? const SizedBox(
|
||||||
style: const TextStyle(
|
width: 16,
|
||||||
fontSize: 14,
|
height: 16,
|
||||||
fontFamily: 'Inter',
|
child: CircularProgressIndicator(
|
||||||
height: 1.5,
|
strokeWidth: 2,
|
||||||
color: Color(0x995D4037),
|
valueColor: AlwaysStoppedAnimation<Color>(Color(0xFFD4AF37)),
|
||||||
),
|
),
|
||||||
);
|
)
|
||||||
|
: Text(
|
||||||
|
'DST 余额: ${_formatNumber(_dstBalance)}',
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
height: 1.5,
|
||||||
|
color: Color(0x995D4037),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue