deposit_detail_screen.dart 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter/services.dart';
  3. import '../../../core/l10n/app_localizations.dart';
  4. import '../../../core/theme/app_colors.dart';
  5. import '../../../data/models/asset/recharge_record.dart';
  6. class DepositDetailScreen extends StatelessWidget {
  7. const DepositDetailScreen({super.key, required this.record});
  8. final RechargeRecord record;
  9. @override
  10. Widget build(BuildContext context) {
  11. final cs = Theme.of(context).colorScheme;
  12. final isDark = Theme.of(context).brightness == Brightness.dark;
  13. return Scaffold(
  14. appBar: AppBar(
  15. title: Text(AppLocalizations.of(context)!.depositDetail, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600)),
  16. centerTitle: true,
  17. ),
  18. body: SingleChildScrollView(
  19. padding: const EdgeInsets.all(16),
  20. child: Column(
  21. crossAxisAlignment: CrossAxisAlignment.start,
  22. children: [
  23. // ── 金额部分 ──────────────────────────────
  24. Container(
  25. padding: const EdgeInsets.all(20),
  26. decoration: BoxDecoration(
  27. color: isDark ? AppColors.darkBgSecondary : AppColors.lightBgSecondary,
  28. borderRadius: BorderRadius.circular(12),
  29. ),
  30. child: Column(
  31. crossAxisAlignment: CrossAxisAlignment.start,
  32. children: [
  33. Text(
  34. AppLocalizations.of(context)!.amountLabel,
  35. style: TextStyle(
  36. color: cs.onSurface.withAlpha(120),
  37. fontSize: 13,
  38. ),
  39. ),
  40. const SizedBox(height: 8),
  41. Row(
  42. crossAxisAlignment: CrossAxisAlignment.baseline,
  43. textBaseline: TextBaseline.alphabetic,
  44. children: [
  45. Text(
  46. '+${record.amount}',
  47. style: TextStyle(
  48. color: AppColors.rise,
  49. fontSize: 28,
  50. fontWeight: FontWeight.w700,
  51. ),
  52. ),
  53. const SizedBox(width: 8),
  54. Text(
  55. 'USDT',
  56. style: TextStyle(
  57. color: cs.onSurface.withAlpha(120),
  58. fontSize: 14,
  59. ),
  60. ),
  61. ],
  62. ),
  63. const SizedBox(height: 12),
  64. Text(
  65. AppLocalizations.of(context)!.completed,
  66. style: TextStyle(
  67. color: AppColors.rise,
  68. fontSize: 12,
  69. fontWeight: FontWeight.w500,
  70. ),
  71. ),
  72. ],
  73. ),
  74. ),
  75. const SizedBox(height: 24),
  76. // ── 详情信息 ──────────────────────────────
  77. Container(
  78. padding: const EdgeInsets.all(16),
  79. decoration: BoxDecoration(
  80. color: isDark ? AppColors.darkBgSecondary : AppColors.lightBgSecondary,
  81. borderRadius: BorderRadius.circular(12),
  82. ),
  83. child: Column(
  84. children: [
  85. _DetailRow(
  86. label: AppLocalizations.of(context)!.depositCurrency,
  87. value: 'USDT',
  88. cs: cs,
  89. ),
  90. const SizedBox(height: 16),
  91. _DetailRow(
  92. label: AppLocalizations.of(context)!.depositAddress,
  93. value: record.address,
  94. cs: cs,
  95. isCopyable: true,
  96. copyValue: record.address,
  97. ),
  98. const SizedBox(height: 16),
  99. _DetailRow(
  100. label: AppLocalizations.of(context)!.txHash,
  101. value: record.txId,
  102. cs: cs,
  103. isCopyable: record.txId.isNotEmpty,
  104. copyValue: record.txId,
  105. truncate: true,
  106. ),
  107. const SizedBox(height: 16),
  108. _DetailRow(
  109. label: AppLocalizations.of(context)!.applyTime,
  110. value: record.createTime,
  111. cs: cs,
  112. ),
  113. ],
  114. ),
  115. ),
  116. ],
  117. ),
  118. ),
  119. );
  120. }
  121. }
  122. class _DetailRow extends StatelessWidget {
  123. const _DetailRow({
  124. required this.label,
  125. required this.value,
  126. required this.cs,
  127. this.isCopyable = false,
  128. this.copyValue,
  129. this.truncate = false,
  130. });
  131. final String label;
  132. final String value;
  133. final ColorScheme cs;
  134. final bool isCopyable;
  135. final String? copyValue;
  136. final bool truncate;
  137. @override
  138. Widget build(BuildContext context) {
  139. final displayValue = truncate && value.length > 16
  140. ? '${value.substring(0, 8)}...${value.substring(value.length - 8)}'
  141. : value;
  142. return GestureDetector(
  143. onTap: isCopyable
  144. ? () {
  145. if (copyValue != null && copyValue!.isNotEmpty) {
  146. Clipboard.setData(ClipboardData(text: copyValue!));
  147. ScaffoldMessenger.of(context).showSnackBar(
  148. SnackBar(content: Text(AppLocalizations.of(context)!.copied), duration: const Duration(seconds: 1)),
  149. );
  150. }
  151. }
  152. : null,
  153. child: Row(
  154. children: [
  155. Expanded(
  156. child: Column(
  157. crossAxisAlignment: CrossAxisAlignment.start,
  158. children: [
  159. Text(
  160. label,
  161. style: TextStyle(color: cs.onSurface.withAlpha(120), fontSize: 12),
  162. ),
  163. const SizedBox(height: 4),
  164. Text(
  165. displayValue,
  166. style: TextStyle(color: cs.onSurface, fontSize: 14, fontWeight: FontWeight.w500),
  167. maxLines: 2,
  168. overflow: TextOverflow.ellipsis,
  169. ),
  170. ],
  171. ),
  172. ),
  173. if (isCopyable) ...[
  174. const SizedBox(width: 8),
  175. Icon(Icons.content_copy_outlined, size: 16, color: cs.onSurface.withAlpha(120)),
  176. ],
  177. ],
  178. ),
  179. );
  180. }
  181. }