feat(app): 预种计划三按钮合并为单入口 Hub 页面
## 背景
「我」页面原有三个并排的预种按钮(预种购买 / 预种明细 / 团队预种),
三等分宽度导致文字拥挤,视觉层级也不清晰。
## 改动内容
### 新增文件
- `pre_planting_hub_page.dart`
预种计划 Hub 汇总页,竖排展示三个功能入口卡片:
· 预种购买(金色)→ /pre-planting/purchase
· 预种明细(棕色)→ /pre-planting/position
· 团队预种(绿色)→ /pre-planting/team
页面为纯导航页,无需加载数据;风格与 pre_planting_purchase_page
一致(渐变背景、金色「← 返回」Header、Inter 字体)。
### 修改文件
- `route_paths.dart` / `route_names.dart`
新增路由常量 prePlantingHub = '/pre-planting/hub'
- `app_router.dart`
注册 GoRoute(path: prePlantingHub) → PrePlantingHubPage
新增对应 import
- `profile_page.dart`
· 删除 `_buildPrePlantingButtons()`(三按钮并排 Widget)
· 删除已无用的三个导航方法:
_goToPrePlantingPurchase / _goToPrePlantingPosition / _goToTeamPrePlanting
· 新增 `_buildPrePlantingEntryButton()`:
满宽 48px 按钮,文字「申请预种计划」,点击跳转 Hub 页
· 布局调用处改为 _buildPrePlantingEntryButton()
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
979ba379c1
commit
8b48d80cd4
|
|
@ -0,0 +1,191 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
|
import '../../../../routes/route_paths.dart';
|
||||||
|
|
||||||
|
/// [2026-03-04] 预种计划 Hub 页面
|
||||||
|
///
|
||||||
|
/// 作为「我」页面「申请预种计划」按钮的下级页面,
|
||||||
|
/// 汇总展示预种三大功能入口:预种购买、预种明细、团队预种。
|
||||||
|
class PrePlantingHubPage extends StatelessWidget {
|
||||||
|
const PrePlantingHubPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body: Container(
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
gradient: LinearGradient(
|
||||||
|
begin: Alignment.topCenter,
|
||||||
|
end: Alignment.bottomCenter,
|
||||||
|
colors: [Color(0xFFFFF7E6), Color(0xFFEAE0C8)],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: SafeArea(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
_buildHeader(context),
|
||||||
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
_buildEntryCard(
|
||||||
|
context,
|
||||||
|
icon: Icons.add_circle_outline,
|
||||||
|
color: const Color(0xFFD4AF37),
|
||||||
|
title: '预种购买',
|
||||||
|
subtitle: '购买预种份额,累计 10 份合成 1 棵树',
|
||||||
|
onTap: () => context.push(RoutePaths.prePlantingPurchase),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
_buildEntryCard(
|
||||||
|
context,
|
||||||
|
icon: Icons.account_balance_wallet_outlined,
|
||||||
|
color: const Color(0xFF5D4037),
|
||||||
|
title: '预种明细',
|
||||||
|
subtitle: '查看预种订单和合并记录',
|
||||||
|
onTap: () => context.push(RoutePaths.prePlantingPosition),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
_buildEntryCard(
|
||||||
|
context,
|
||||||
|
icon: Icons.groups_outlined,
|
||||||
|
color: const Color(0xFF2E7D32),
|
||||||
|
title: '团队预种',
|
||||||
|
subtitle: '查看个人与团队预种统计',
|
||||||
|
onTap: () => context.push(RoutePaths.teamPrePlanting),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildHeader(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: const Color(0xFFFFF7E6).withValues(alpha: 0.8),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () => context.pop(),
|
||||||
|
child: Container(
|
||||||
|
width: 32,
|
||||||
|
height: 32,
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: const Icon(
|
||||||
|
Icons.arrow_back_ios,
|
||||||
|
color: Color(0xFFD4AF37),
|
||||||
|
size: 20,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 4),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () => context.pop(),
|
||||||
|
child: const Text(
|
||||||
|
'返回',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
height: 1.5,
|
||||||
|
color: Color(0xFFD4AF37),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 42),
|
||||||
|
const Expanded(
|
||||||
|
child: Text(
|
||||||
|
'预种计划',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 18,
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
height: 1.25,
|
||||||
|
letterSpacing: -0.27,
|
||||||
|
color: Color(0xFF5D4037),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildEntryCard(
|
||||||
|
BuildContext context, {
|
||||||
|
required IconData icon,
|
||||||
|
required Color color,
|
||||||
|
required String title,
|
||||||
|
required String subtitle,
|
||||||
|
required VoidCallback onTap,
|
||||||
|
}) {
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: onTap,
|
||||||
|
child: Container(
|
||||||
|
width: double.infinity,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 18),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white.withValues(alpha: 0.85),
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
border: Border.all(
|
||||||
|
color: color.withValues(alpha: 0.25),
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 48,
|
||||||
|
height: 48,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: color.withValues(alpha: 0.12),
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
child: Icon(icon, color: color, size: 24),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 16),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
title,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: color,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
Text(
|
||||||
|
subtitle,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 13,
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
color: Color(0xFF8D6E63),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Icon(
|
||||||
|
Icons.chevron_right,
|
||||||
|
color: color.withValues(alpha: 0.6),
|
||||||
|
size: 20,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1356,16 +1356,6 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [2026-02-17] 进入预种计划购买页
|
|
||||||
void _goToPrePlantingPurchase() {
|
|
||||||
context.push(RoutePaths.prePlantingPurchase);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// [2026-02-17] 进入预种持仓页
|
|
||||||
void _goToPrePlantingPosition() {
|
|
||||||
context.push(RoutePaths.prePlantingPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 谷歌验证器
|
/// 谷歌验证器
|
||||||
void _goToGoogleAuth() {
|
void _goToGoogleAuth() {
|
||||||
context.push(RoutePaths.googleAuth);
|
context.push(RoutePaths.googleAuth);
|
||||||
|
|
@ -1551,10 +1541,10 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
|
||||||
// 认种按钮
|
// 认种按钮
|
||||||
_buildPlantingButton(),
|
_buildPlantingButton(),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
// [2026-02-17] 预种计划按钮(购买 + 查看持仓)
|
// [2026-03-04] 预种计划入口(三功能合并为单按钮)
|
||||||
// 仅在后台管理端预种开关开启时显示
|
// 仅在后台管理端预种开关开启时显示
|
||||||
if (_isPrePlantingActive) ...[
|
if (_isPrePlantingActive) ...[
|
||||||
_buildPrePlantingButtons(),
|
_buildPrePlantingEntryButton(),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
],
|
],
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
|
|
@ -2041,20 +2031,13 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [2026-02-17] 构建预种计划按钮行(购买 + 查看持仓)
|
/// [2026-03-04] 构建预种计划入口按钮(原三按钮合并为一个)
|
||||||
///
|
Widget _buildPrePlantingEntryButton() {
|
||||||
/// 两个按钮并排显示:
|
return GestureDetector(
|
||||||
/// - 左侧「预种购买」:跳转到预种购买页(选择份数 → 支付 1887 USDT/份)
|
onTap: () => context.push(RoutePaths.prePlantingHub),
|
||||||
/// - 右侧「预种持仓」:跳转到预种持仓页(查看订单、合并记录、签约)
|
|
||||||
Widget _buildPrePlantingButtons() {
|
|
||||||
return Row(
|
|
||||||
children: [
|
|
||||||
// 预种购买按钮
|
|
||||||
Expanded(
|
|
||||||
child: GestureDetector(
|
|
||||||
onTap: _goToPrePlantingPurchase,
|
|
||||||
child: Container(
|
child: Container(
|
||||||
height: 44,
|
width: double.infinity,
|
||||||
|
height: 48,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: const Color(0xFFD4AF37).withValues(alpha: 0.15),
|
color: const Color(0xFFD4AF37).withValues(alpha: 0.15),
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
|
@ -2066,111 +2049,25 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
|
||||||
child: const Row(
|
child: const Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Icon(
|
Icon(Icons.eco_outlined, color: Color(0xFFD4AF37), size: 20),
|
||||||
Icons.add_circle_outline,
|
SizedBox(width: 8),
|
||||||
color: Color(0xFFD4AF37),
|
|
||||||
size: 18,
|
|
||||||
),
|
|
||||||
SizedBox(width: 6),
|
|
||||||
Text(
|
Text(
|
||||||
'预种购买',
|
'申请预种计划',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 14,
|
fontSize: 15,
|
||||||
fontFamily: 'Inter',
|
fontFamily: 'Inter',
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
color: Color(0xFFD4AF37),
|
color: Color(0xFFD4AF37),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
SizedBox(width: 4),
|
||||||
|
Icon(Icons.chevron_right, color: Color(0xFFD4AF37), size: 18),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 8),
|
|
||||||
// 预种持仓按钮
|
|
||||||
Expanded(
|
|
||||||
child: GestureDetector(
|
|
||||||
onTap: _goToPrePlantingPosition,
|
|
||||||
child: Container(
|
|
||||||
height: 44,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: const Color(0xFF5D4037).withValues(alpha: 0.08),
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
border: Border.all(
|
|
||||||
color: const Color(0xFF5D4037).withValues(alpha: 0.2),
|
|
||||||
width: 1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: const Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Icon(
|
|
||||||
Icons.account_balance_wallet_outlined,
|
|
||||||
color: Color(0xFF5D4037),
|
|
||||||
size: 18,
|
|
||||||
),
|
|
||||||
SizedBox(width: 6),
|
|
||||||
Text(
|
|
||||||
'预种明细',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
fontFamily: 'Inter',
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
color: Color(0xFF5D4037),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 8),
|
|
||||||
// [2026-03-02] 团队预种按钮(功能6)
|
|
||||||
Expanded(
|
|
||||||
child: GestureDetector(
|
|
||||||
onTap: _goToTeamPrePlanting,
|
|
||||||
child: Container(
|
|
||||||
height: 44,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: const Color(0xFF2E7D32).withValues(alpha: 0.08),
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
border: Border.all(
|
|
||||||
color: const Color(0xFF2E7D32).withValues(alpha: 0.2),
|
|
||||||
width: 1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: const Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Icon(
|
|
||||||
Icons.groups_outlined,
|
|
||||||
color: Color(0xFF2E7D32),
|
|
||||||
size: 18,
|
|
||||||
),
|
|
||||||
SizedBox(width: 6),
|
|
||||||
Text(
|
|
||||||
'团队预种',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
fontFamily: 'Inter',
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
color: Color(0xFF2E7D32),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [2026-03-02] 进入团队预种页(功能6)
|
|
||||||
void _goToTeamPrePlanting() {
|
|
||||||
context.push(RoutePaths.teamPrePlanting);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 构建主要内容卡片
|
/// 构建主要内容卡片
|
||||||
Widget _buildMainContentCard() {
|
Widget _buildMainContentCard() {
|
||||||
// Widget 结构始终保持,数据值根据状态显示 "0" 或实际值
|
// Widget 结构始终保持,数据值根据状态显示 "0" 或实际值
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ import '../features/contract_signing/presentation/pages/contract_signing_page.da
|
||||||
import '../features/contract_signing/presentation/pages/pending_contracts_page.dart';
|
import '../features/contract_signing/presentation/pages/pending_contracts_page.dart';
|
||||||
import '../features/pending_actions/presentation/pages/pending_actions_page.dart';
|
import '../features/pending_actions/presentation/pages/pending_actions_page.dart';
|
||||||
// [2026-02-17] 新增:预种计划页面(1887 USDT/份,累计 10 份合成 1 棵树)
|
// [2026-02-17] 新增:预种计划页面(1887 USDT/份,累计 10 份合成 1 棵树)
|
||||||
|
import '../features/pre_planting/presentation/pages/pre_planting_hub_page.dart';
|
||||||
import '../features/pre_planting/presentation/pages/pre_planting_purchase_page.dart';
|
import '../features/pre_planting/presentation/pages/pre_planting_purchase_page.dart';
|
||||||
import '../features/pre_planting/presentation/pages/pre_planting_position_page.dart';
|
import '../features/pre_planting/presentation/pages/pre_planting_position_page.dart';
|
||||||
import '../features/pre_planting/presentation/pages/pre_planting_merge_detail_page.dart';
|
import '../features/pre_planting/presentation/pages/pre_planting_merge_detail_page.dart';
|
||||||
|
|
@ -445,6 +446,13 @@ final appRouterProvider = Provider<GoRouter>((ref) {
|
||||||
builder: (context, state) => const ChangePhonePage(),
|
builder: (context, state) => const ChangePhonePage(),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
// [2026-03-04] Pre-Planting Hub Page (预种计划 - 入口汇总)
|
||||||
|
GoRoute(
|
||||||
|
path: RoutePaths.prePlantingHub,
|
||||||
|
name: RouteNames.prePlantingHub,
|
||||||
|
builder: (context, state) => const PrePlantingHubPage(),
|
||||||
|
),
|
||||||
|
|
||||||
// [2026-02-17] Pre-Planting Purchase Page (预种计划 - 购买页)
|
// [2026-02-17] Pre-Planting Purchase Page (预种计划 - 购买页)
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: RoutePaths.prePlantingPurchase,
|
path: RoutePaths.prePlantingPurchase,
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@ class RouteNames {
|
||||||
static const changePhone = 'change-phone';
|
static const changePhone = 'change-phone';
|
||||||
|
|
||||||
// [2026-02-17] Pre-Planting (预种计划)
|
// [2026-02-17] Pre-Planting (预种计划)
|
||||||
|
static const prePlantingHub = 'pre-planting-hub'; // [2026-03-04] Hub 汇总入口页
|
||||||
static const prePlantingPurchase = 'pre-planting-purchase'; // 购买页
|
static const prePlantingPurchase = 'pre-planting-purchase'; // 购买页
|
||||||
static const prePlantingPosition = 'pre-planting-position'; // 持仓页
|
static const prePlantingPosition = 'pre-planting-position'; // 持仓页
|
||||||
static const prePlantingMergeDetail = 'pre-planting-merge'; // 合并详情页
|
static const prePlantingMergeDetail = 'pre-planting-merge'; // 合并详情页
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@ class RoutePaths {
|
||||||
static const changePhone = '/kyc/change-phone';
|
static const changePhone = '/kyc/change-phone';
|
||||||
|
|
||||||
// [2026-02-17] Pre-Planting (预种计划)
|
// [2026-02-17] Pre-Planting (预种计划)
|
||||||
|
static const prePlantingHub = '/pre-planting/hub'; // [2026-03-04] Hub 汇总入口页
|
||||||
static const prePlantingPurchase = '/pre-planting/purchase'; // 购买页
|
static const prePlantingPurchase = '/pre-planting/purchase'; // 购买页
|
||||||
static const prePlantingPosition = '/pre-planting/position'; // 持仓页
|
static const prePlantingPosition = '/pre-planting/position'; // 持仓页
|
||||||
static const prePlantingMergeDetail = '/pre-planting/merge'; // 合并详情页
|
static const prePlantingMergeDetail = '/pre-planting/merge'; // 合并详情页
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue