diff --git a/frontend/mobile-app/lib/core/services/transfer_service.dart b/frontend/mobile-app/lib/core/services/transfer_service.dart index 4cb8c36e..7c0e1993 100644 --- a/frontend/mobile-app/lib/core/services/transfer_service.dart +++ b/frontend/mobile-app/lib/core/services/transfer_service.dart @@ -236,21 +236,21 @@ class TransferService { /// 发起转让 /// /// [buyerAccountSequence] 买方账号 - /// [plantingOrderNos] 要转让的认种订单号列表 - /// [pricePerTree] 每棵售价 + /// [plantingOrderNos] 要转让的认种订单号列表(空列表时由后端自动选择) + /// [treeCount] 转让棵数 Future createTransfer({ required String buyerAccountSequence, required List plantingOrderNos, - required double pricePerTree, + required int treeCount, }) async { try { - debugPrint('[TransferService] 发起转让: buyer=$buyerAccountSequence, trees=${plantingOrderNos.length}'); + debugPrint('[TransferService] 发起转让: buyer=$buyerAccountSequence, treeCount=$treeCount'); final response = await _apiClient.post( '/transfers', data: { 'buyerAccountSequence': buyerAccountSequence, 'plantingOrderNos': plantingOrderNos, - 'pricePerTree': pricePerTree.toString(), + 'treeCount': treeCount, }, ); diff --git a/frontend/mobile-app/lib/features/transfer/presentation/pages/transfer_initiate_page.dart b/frontend/mobile-app/lib/features/transfer/presentation/pages/transfer_initiate_page.dart index c2d2230e..4f4b96a5 100644 --- a/frontend/mobile-app/lib/features/transfer/presentation/pages/transfer_initiate_page.dart +++ b/frontend/mobile-app/lib/features/transfer/presentation/pages/transfer_initiate_page.dart @@ -11,9 +11,9 @@ import '../../../../routes/route_paths.dart'; // // 用户发起树转让的表单页面: // - 输入买方账号 -// - 输入每棵售价 -// - 自动计算手续费(5%)和卖方到账金额 +// - 输入转让棵数 // - 确认发起转让 +// 注:价格线下柜台签合同交易,APP 仅完成系统层面所有权 + 算力转移 // // === 回滚方式 === // 删除 features/transfer/ 目录 @@ -28,27 +28,18 @@ class TransferInitiatePage extends ConsumerStatefulWidget { class _TransferInitiatePageState extends ConsumerState { final _buyerController = TextEditingController(); - final _priceController = TextEditingController(); final _treeCountController = TextEditingController(text: '1'); bool _isSubmitting = false; String? _errorMessage; - // 平台手续费率 - static const double _feeRate = 0.05; - @override void dispose() { _buyerController.dispose(); - _priceController.dispose(); _treeCountController.dispose(); super.dispose(); } - double get _pricePerTree => double.tryParse(_priceController.text) ?? 0; int get _treeCount => int.tryParse(_treeCountController.text) ?? 1; - double get _totalPrice => _pricePerTree * _treeCount; - double get _feeAmount => _totalPrice * _feeRate; - double get _sellerReceive => _totalPrice - _feeAmount; Future _handleSubmit() async { final buyer = _buyerController.text.trim(); @@ -56,10 +47,6 @@ class _TransferInitiatePageState extends ConsumerState { setState(() => _errorMessage = '请输入买方账号'); return; } - if (_pricePerTree <= 0) { - setState(() => _errorMessage = '请输入有效的每棵售价'); - return; - } if (_treeCount <= 0) { setState(() => _errorMessage = '请输入有效的转让棵数'); return; @@ -77,12 +64,9 @@ class _TransferInitiatePageState extends ConsumerState { ), content: Text( '买方账号: $buyer\n' - '转让棵数: $_treeCount 棵\n' - '每棵售价: ${_pricePerTree.toStringAsFixed(0)} USDT\n' - '总价: ${_totalPrice.toStringAsFixed(0)} USDT\n' - '手续费: ${_feeAmount.toStringAsFixed(2)} USDT (${(_feeRate * 100).toStringAsFixed(0)}%)\n' - '您将收到: ${_sellerReceive.toStringAsFixed(2)} USDT\n\n' - '转让发起后需要卖方确认,确认后 Saga 流程将自动执行。', + '转让棵数: $_treeCount 棵\n\n' + '确认后系统将完成树所有权变更及算力调整。\n' + '交易价格请线下柜台签署合同确定。', style: const TextStyle(color: Color(0xFF5D4037), fontSize: 14, height: 1.6), ), actions: [ @@ -115,7 +99,7 @@ class _TransferInitiatePageState extends ConsumerState { final order = await service.createTransfer( buyerAccountSequence: buyer, plantingOrderNos: [], // 由后端根据棵数自动选择 - pricePerTree: _pricePerTree, + treeCount: _treeCount, ); if (mounted) { @@ -178,7 +162,7 @@ class _TransferInitiatePageState extends ConsumerState { SizedBox(width: 8), Expanded( child: Text( - '转让已认种的果树所有权。发起后需卖方确认,系统将自动完成资金冻结、所有权变更、算力调整等流程。', + '转让已认种的果树所有权。系统将自动完成所有权变更及算力调整,交易价格请线下柜台签署合同确定。', style: TextStyle(fontSize: 13, color: Color(0xFF8B5A2B)), ), ), @@ -207,48 +191,8 @@ class _TransferInitiatePageState extends ConsumerState { inputFormatters: [FilteringTextInputFormatter.digitsOnly], onChanged: (_) => setState(() {}), ), - const SizedBox(height: 20), - - // 每棵售价 - _buildLabel('每棵售价 (USDT)'), - const SizedBox(height: 8), - _buildTextField( - controller: _priceController, - hintText: '输入每棵售价', - keyboardType: const TextInputType.numberWithOptions(decimal: true), - inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'[\d.]'))], - onChanged: (_) => setState(() {}), - ), const SizedBox(height: 24), - // 费用计算卡片 - if (_pricePerTree > 0) ...[ - Container( - padding: const EdgeInsets.all(16), - decoration: BoxDecoration( - color: const Color(0x99FFFFFF), - borderRadius: BorderRadius.circular(12), - boxShadow: const [ - BoxShadow( - color: Color(0x1A000000), - blurRadius: 6, - offset: Offset(0, 4), - ), - ], - ), - child: Column( - children: [ - _feeRow('总价', '${_totalPrice.toStringAsFixed(0)} USDT'), - _feeRow('手续费 (${(_feeRate * 100).toStringAsFixed(0)}%)', '${_feeAmount.toStringAsFixed(2)} USDT'), - const Divider(color: Color(0xFFEAE0C8)), - _feeRow('您将收到', '${_sellerReceive.toStringAsFixed(2)} USDT', - valueColor: const Color(0xFFD4AF37)), - ], - ), - ), - const SizedBox(height: 24), - ], - // 错误信息 if (_errorMessage != null) ...[ Container( @@ -429,24 +373,4 @@ class _TransferInitiatePageState extends ConsumerState { ); } - Widget _feeRow(String label, String value, {Color? valueColor}) { - return Padding( - padding: const EdgeInsets.symmetric(vertical: 4), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text(label, style: const TextStyle(fontSize: 13, color: Color(0xFF745D43))), - Text( - value, - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w500, - color: valueColor ?? const Color(0xFF5D4037), - fontFamily: 'Inter', - ), - ), - ], - ), - ); - } }