feat(pre-planting): 预种方案调整 — 18870 USDT/棵,10份合1树

=== 方案变更 ===
- 全树基础价: 17830 → 18870 USDT
- 每份价格:   3566 → 1887 USDT
- 合并阈值:   5 份 → 10 份

=== 后端改动 (planting-service) ===
1. pre-planting-right-amounts.ts:
   - PRE_PLANTING_PRICE_PER_PORTION: 3566 → 1887
   - PRE_PLANTING_PORTIONS_PER_TREE: 5 → 10
   - 10类权益金额按 floor(整棵树/10) 重算,余数归 HQ_BASE_FEE(319)
2. pre-planting-merge.aggregate.ts:
   - 合并校验从硬编码 5 改为引用 PRE_PLANTING_PORTIONS_PER_TREE 常量
3. purchase-pre-planting.dto.ts:
   - portionCount @Max(5) → @Max(10)
4. pre-planting-application.service.ts:
   - 加价补贴计算 /5 → /PRE_PLANTING_PORTIONS_PER_TREE
   - 错误文案引用常量,消除硬编码

=== 前端改动 (mobile-app) ===
1. pre_planting_purchase_page.dart: 默认价格、份数、协议文本(1/10、4%)
2. pre_planting_position_page.dart: _portionsPerTree 5→10
3. pre_planting_merge_detail_page.dart: 总价值计算和单份显示金额
4. tree_pricing_service.dart: fallback 默认值
5. pre_planting_service.dart: JSON 解析 fallback 默认值
6. 各文件注释同步更新

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-03-01 18:32:32 -08:00
parent 28cf0b7769
commit b3984c861c
15 changed files with 100 additions and 69 deletions

View File

@ -18,10 +18,10 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
* SelectProvinceCityDto * SelectProvinceCityDto
*/ */
export class PurchasePrePlantingDto { export class PurchasePrePlantingDto {
@ApiProperty({ description: '购买份数', example: 1, minimum: 1, maximum: 5 }) @ApiProperty({ description: '购买份数', example: 1, minimum: 1, maximum: 10 })
@IsInt() @IsInt()
@Min(1) @Min(1)
@Max(5) @Max(10)
portionCount: number; portionCount: number;
@ApiProperty({ description: '省代码(行政区划代码前两位)', example: '44' }) @ApiProperty({ description: '省代码(行政区划代码前两位)', example: '44' })

View File

@ -62,8 +62,8 @@ export class PrePlantingApplicationService {
// 获取当前定价配置(含总部运营成本压力涨价) // 获取当前定价配置(含总部运营成本压力涨价)
const pricingConfig = await this.treePricingClient.getTreePricingConfig(); const pricingConfig = await this.treePricingClient.getTreePricingConfig();
// 预种每份加价 = Math.floor(每棵树加价 / 5),涨价部分全额归总部 (S0000000001) // 预种每份加价 = Math.floor(每棵树加价 / 份数),涨价部分全额归总部 (S0000000001)
const portionSupplement = Math.floor(pricingConfig.currentSupplement / 5); const portionSupplement = Math.floor(pricingConfig.currentSupplement / PRE_PLANTING_PORTIONS_PER_TREE);
const orderNo = this.generateOrderNo(); const orderNo = this.generateOrderNo();
const totalAmount = portionCount * (PRE_PLANTING_PRICE_PER_PORTION + portionSupplement); const totalAmount = portionCount * (PRE_PLANTING_PRICE_PER_PORTION + portionSupplement);
@ -564,7 +564,7 @@ export class PrePlantingApplicationService {
throw new BadRequestException('预种功能已关闭,您当前份额已满,无法继续购买'); throw new BadRequestException('预种功能已关闭,您当前份额已满,无法继续购买');
} }
if (portionCount > maxAdditional) { if (portionCount > maxAdditional) {
throw new BadRequestException(`当前只可再购买 ${maxAdditional} 份以凑满5`); throw new BadRequestException(`当前只可再购买 ${maxAdditional} 份以凑满 ${PRE_PLANTING_PORTIONS_PER_TREE} `);
} }
} }
@ -574,7 +574,7 @@ export class PrePlantingApplicationService {
accountSequence: string, accountSequence: string,
position: import('../../domain/aggregates/pre-planting-position.aggregate').PrePlantingPosition, position: import('../../domain/aggregates/pre-planting-position.aggregate').PrePlantingPosition,
) { ) {
// 获取 5 笔待合并的已支付订单 // 获取待合并的已支付订单(数量由 PRE_PLANTING_PORTIONS_PER_TREE 决定)
const paidOrders = await this.orderRepo.findPaidOrdersByUserId( const paidOrders = await this.orderRepo.findPaidOrdersByUserId(
tx, tx,
userId, userId,
@ -582,7 +582,7 @@ export class PrePlantingApplicationService {
); );
if (paidOrders.length < PRE_PLANTING_PORTIONS_PER_TREE) { if (paidOrders.length < PRE_PLANTING_PORTIONS_PER_TREE) {
throw new Error('不足 5 笔已支付订单进行合并'); throw new Error(`不足 ${PRE_PLANTING_PORTIONS_PER_TREE} 笔已支付订单进行合并`);
} }
const sourceOrders = paidOrders.slice(0, PRE_PLANTING_PORTIONS_PER_TREE); const sourceOrders = paidOrders.slice(0, PRE_PLANTING_PORTIONS_PER_TREE);
@ -605,7 +605,7 @@ export class PrePlantingApplicationService {
); );
await this.mergeRepo.save(tx, merge); await this.mergeRepo.save(tx, merge);
// 标记 5 笔订单为已合并 // 标记订单为已合并
for (const order of sourceOrders) { for (const order of sourceOrders) {
order.markAsMerged(merge.id!); order.markAsMerged(merge.id!);
await this.orderRepo.save(tx, order); await this.orderRepo.save(tx, order);

View File

@ -1,4 +1,5 @@
import { PrePlantingContractStatus } from '../value-objects/pre-planting-contract-status.enum'; import { PrePlantingContractStatus } from '../value-objects/pre-planting-contract-status.enum';
import { PRE_PLANTING_PORTIONS_PER_TREE } from '../value-objects/pre-planting-right-amounts';
import { DomainEvent } from '../../../domain/events/domain-event.interface'; import { DomainEvent } from '../../../domain/events/domain-event.interface';
import { PrePlantingMergedEvent } from '../events/pre-planting-merged.event'; import { PrePlantingMergedEvent } from '../events/pre-planting-merged.event';
import { PrePlantingContractSignedEvent } from '../events/pre-planting-contract-signed.event'; import { PrePlantingContractSignedEvent } from '../events/pre-planting-contract-signed.event';
@ -69,8 +70,8 @@ export class PrePlantingMerge {
cityCode: string, cityCode: string,
totalTreesMergedAfter: number, totalTreesMergedAfter: number,
): PrePlantingMerge { ): PrePlantingMerge {
if (sourceOrderNos.length !== 5) { if (sourceOrderNos.length !== PRE_PLANTING_PORTIONS_PER_TREE) {
throw new Error(`合并需要 5 个订单,收到 ${sourceOrderNos.length}`); throw new Error(`合并需要 ${PRE_PLANTING_PORTIONS_PER_TREE} 个订单,收到 ${sourceOrderNos.length}`);
} }
const merge = new PrePlantingMerge( const merge = new PrePlantingMerge(

View File

@ -91,7 +91,7 @@ export class PrePlantingPosition {
} }
/** /**
* 5 * PRE_PLANTING_PORTIONS_PER_TREE
*/ */
performMerge(): void { performMerge(): void {
if (!this.canMerge()) { if (!this.canMerge()) {

View File

@ -1,26 +1,53 @@
/** /**
* 1/5 * 1/10
* *
* reward-service RIGHT_AMOUNTS15831 * === ===
* 9 = floor( / 5) HQ_BASE_FEE * [2026-03-01]
* - 15831 18870 USDT
* - 5 10
* - 3566 1887 USDT
*
* === ===
* reward-service RIGHT_AMOUNTS 10
* 9 = floor( / 10) HEADQUARTERS_BASE_FEE
*
* === & ===
* floor(/10) 10 (HQ)
* COST_FEE 2880 288 2880 0
* OPERATION_FEE 2100 210 2100 0
* RWAD_POOL_INJECTION 5760 576 5760 0
* SHARE_RIGHT 3600 360 3600 0
* PROVINCE_AREA_RIGHT 108 10 100 8
* PROVINCE_TEAM_RIGHT 144 14 140 4
* CITY_AREA_RIGHT 252 25 250 2
* CITY_TEAM_RIGHT 288 28 280 8
* COMMUNITY_RIGHT 576 57 570 6
*
* 9 15708 1568 15680 28
* HQ_BASE_FEE = 1887 - 1568 = 319 28
*
* 18870/10 1887 18870 0
*/ */
export const PRE_PLANTING_RIGHT_AMOUNTS = { export const PRE_PLANTING_RIGHT_AMOUNTS = {
COST_FEE: 576, // floor(2880/5) COST_FEE: 288, // floor(2880/10)
OPERATION_FEE: 420, // floor(2100/5) OPERATION_FEE: 210, // floor(2100/10)
HEADQUARTERS_BASE_FEE: 427, // 3566 - 3139 = 427吸收全部余额 HEADQUARTERS_BASE_FEE: 319, // 1887 - 1568 = 319(吸收全部余额)
RWAD_POOL_INJECTION: 1152, // floor(5760/5) RWAD_POOL_INJECTION: 576, // floor(5760/10)
SHARE_RIGHT: 720, // floor(3600/5) SHARE_RIGHT: 360, // floor(3600/10)
PROVINCE_AREA_RIGHT: 21, // floor(108/5) PROVINCE_AREA_RIGHT: 10, // floor(108/10)
PROVINCE_TEAM_RIGHT: 28, // floor(144/5) PROVINCE_TEAM_RIGHT: 14, // floor(144/10)
CITY_AREA_RIGHT: 50, // floor(252/5) CITY_AREA_RIGHT: 25, // floor(252/10)
CITY_TEAM_RIGHT: 57, // floor(288/5) CITY_TEAM_RIGHT: 28, // floor(288/10)
COMMUNITY_RIGHT: 115, // floor(576/5) COMMUNITY_RIGHT: 57, // floor(576/10)
} as const; } as const;
// 合计 = 576 + 420 + 427 + 1152 + 720 + 21 + 28 + 50 + 57 + 115 = 3566 // 合计 = 288 + 210 + 319 + 576 + 360 + 10 + 14 + 25 + 28 + 57 = 1887
export const PRE_PLANTING_PRICE_PER_PORTION = 3566; /** 每份价格USDT全树 18870 / 10 = 1887 */
export const PRE_PLANTING_PORTIONS_PER_TREE = 5; export const PRE_PLANTING_PRICE_PER_PORTION = 1887;
/** 合并阈值:购满此数量自动合并为 1 棵树 */
export const PRE_PLANTING_PORTIONS_PER_TREE = 10;
/** /**
* *

View File

@ -22,10 +22,11 @@ import { PrePlantingReferralClient } from './infrastructure/external/pre-plantin
import { PrePlantingAuthorizationClient } from './infrastructure/external/pre-planting-authorization.client'; import { PrePlantingAuthorizationClient } from './infrastructure/external/pre-planting-authorization.client';
/** /**
* (3566 / ) * ( / )
* *
* === === * === ===
* 3566 USDT/ 11/551 * [2026-03-01] 1887 USDT/ × 10 = 18870 USDT/ 3566 × 5 = 17830
* 1887 USDT/ 11/10101
* *
* *
* === === * === ===

View File

@ -98,7 +98,7 @@ class ApiEndpoints {
static const String pendingActionsComplete = '/user/pending-actions'; // POST /:id/complete static const String pendingActionsComplete = '/user/pending-actions'; // POST /:id/complete
// [2026-02-17] (-> Planting Service / PrePlantingModule) // [2026-02-17] (-> Planting Service / PrePlantingModule)
// 3566 USDT/ 5 1 // 1887 USDT/ 10 1
// /planting/* // /planting/*
static const String prePlanting = '/pre-planting'; static const String prePlanting = '/pre-planting';
static const String prePlantingConfig = '$prePlanting/config'; // static const String prePlantingConfig = '$prePlanting/config'; //

View File

@ -9,7 +9,7 @@ import '../services/authorization_service.dart';
import '../services/deposit_service.dart'; import '../services/deposit_service.dart';
import '../services/wallet_service.dart'; import '../services/wallet_service.dart';
import '../services/planting_service.dart'; import '../services/planting_service.dart';
// [2026-02-17] 3566 USDT/ // [2026-02-17] 1887 USDT/
import '../services/pre_planting_service.dart'; import '../services/pre_planting_service.dart';
// [2026-02-19] // [2026-02-19]
import '../services/transfer_service.dart'; import '../services/transfer_service.dart';
@ -102,7 +102,7 @@ final plantingServiceProvider = Provider<PlantingService>((ref) {
}); });
// [2026-02-17] Pre-Planting Service Provider ( planting-service / PrePlantingModule) // [2026-02-17] Pre-Planting Service Provider ( planting-service / PrePlantingModule)
// 3566 USDT/ 5 1 PlantingService // 1887 USDT/ 10 1 PlantingService
final prePlantingServiceProvider = Provider<PrePlantingService>((ref) { final prePlantingServiceProvider = Provider<PrePlantingService>((ref) {
final apiClient = ref.watch(apiClientProvider); final apiClient = ref.watch(apiClientProvider);
return PrePlantingService(apiClient: apiClient); return PrePlantingService(apiClient: apiClient);

View File

@ -7,8 +7,9 @@ import '../network/api_client.dart';
// [2026-02-17] API // [2026-02-17] API
// ============================================ // ============================================
// //
// 3566 / Flutter API // / Flutter API
// 3566 USDT/ 5 1 // [2026-03-01] 1887 USDT/ × 10 = 18870 USDT/
// 1887 USDT/ 10 1
// //
// === API === // === API ===
// planting-service PrePlantingModule // planting-service PrePlantingModule
@ -22,8 +23,8 @@ import '../network/api_client.dart';
// - POST /pre-planting/sign-contract // - POST /pre-planting/sign-contract
// //
// === PlantingService === // === PlantingService ===
// PlantingService 15831 USDT/ // PlantingService 18870 USDT/
// PrePlantingService 3566 USDT/ // PrePlantingService 1887 USDT/
// API // API
/// ///
@ -117,7 +118,7 @@ class PrePlantingPosition {
class PrePlantingOrder { class PrePlantingOrder {
final String orderNo; final String orderNo;
final int portionCount; // 1 final int portionCount; // 1
final double pricePerPortion; // 3566 USDT final double pricePerPortion; // 1887 USDT
final double totalAmount; // final double totalAmount; //
final PrePlantingOrderStatus status; final PrePlantingOrderStatus status;
final String? mergedToMergeId; // MergeId final String? mergedToMergeId; // MergeId
@ -141,8 +142,8 @@ class PrePlantingOrder {
return PrePlantingOrder( return PrePlantingOrder(
orderNo: json['orderNo'] ?? '', orderNo: json['orderNo'] ?? '',
portionCount: json['portionCount'] ?? 1, portionCount: json['portionCount'] ?? 1,
pricePerPortion: (json['pricePerPortion'] ?? 3566).toDouble(), pricePerPortion: (json['pricePerPortion'] ?? 1887).toDouble(),
totalAmount: (json['totalAmount'] ?? 3566).toDouble(), totalAmount: (json['totalAmount'] ?? 1887).toDouble(),
status: _parseStatus(json['status']), status: _parseStatus(json['status']),
mergedToMergeId: json['mergedToMergeId']?.toString(), mergedToMergeId: json['mergedToMergeId']?.toString(),
paidAt: json['paidAt'] != null ? DateTime.parse(json['paidAt']) : null, paidAt: json['paidAt'] != null ? DateTime.parse(json['paidAt']) : null,
@ -248,8 +249,8 @@ class CreatePrePlantingOrderResponse {
return CreatePrePlantingOrderResponse( return CreatePrePlantingOrderResponse(
orderNo: json['orderNo'] ?? '', orderNo: json['orderNo'] ?? '',
portionCount: json['portionCount'] ?? 1, portionCount: json['portionCount'] ?? 1,
totalAmount: (json['totalAmount'] ?? 3566).toDouble(), totalAmount: (json['totalAmount'] ?? 1887).toDouble(),
pricePerPortion: (json['pricePerPortion'] ?? 3566).toDouble(), pricePerPortion: (json['pricePerPortion'] ?? 1887).toDouble(),
merged: json['merged'] == true, merged: json['merged'] == true,
mergeNo: json['mergeNo']?.toString(), mergeNo: json['mergeNo']?.toString(),
); );

View File

@ -5,12 +5,12 @@ import '../network/api_client.dart';
/// ///
/// ///
/// - = basePrice + currentSupplement /// - = basePrice + currentSupplement
/// - = totalPrice / 5 /// - = totalPrice / 10
class TreePricingConfig { class TreePricingConfig {
/// 15831 /// 18870
final int basePrice; final int basePrice;
/// 3566 /// 1887
final int basePortionPrice; final int basePortionPrice;
/// ///
@ -48,11 +48,11 @@ class TreePricingConfig {
factory TreePricingConfig.fromJson(Map<String, dynamic> json) { factory TreePricingConfig.fromJson(Map<String, dynamic> json) {
return TreePricingConfig( return TreePricingConfig(
basePrice: json['basePrice'] ?? 15831, basePrice: json['basePrice'] ?? 18870,
basePortionPrice: json['basePortionPrice'] ?? 3566, basePortionPrice: json['basePortionPrice'] ?? 1887,
currentSupplement: json['currentSupplement'] ?? 0, currentSupplement: json['currentSupplement'] ?? 0,
totalPrice: json['totalPrice'] ?? 15831, totalPrice: json['totalPrice'] ?? 18870,
totalPortionPrice: json['totalPortionPrice'] ?? 3566, totalPortionPrice: json['totalPortionPrice'] ?? 1887,
autoIncreaseEnabled: json['autoIncreaseEnabled'] ?? false, autoIncreaseEnabled: json['autoIncreaseEnabled'] ?? false,
autoIncreaseAmount: json['autoIncreaseAmount'] ?? 0, autoIncreaseAmount: json['autoIncreaseAmount'] ?? 0,
autoIncreaseIntervalDays: json['autoIncreaseIntervalDays'] ?? 0, autoIncreaseIntervalDays: json['autoIncreaseIntervalDays'] ?? 0,
@ -65,11 +65,11 @@ class TreePricingConfig {
/// supplement=0 /// supplement=0
factory TreePricingConfig.defaultConfig() { factory TreePricingConfig.defaultConfig() {
return TreePricingConfig( return TreePricingConfig(
basePrice: 15831, basePrice: 18870,
basePortionPrice: 3566, basePortionPrice: 1887,
currentSupplement: 0, currentSupplement: 0,
totalPrice: 15831, totalPrice: 18870,
totalPortionPrice: 3566, totalPortionPrice: 1887,
autoIncreaseEnabled: false, autoIncreaseEnabled: false,
autoIncreaseAmount: 0, autoIncreaseAmount: 0,
autoIncreaseIntervalDays: 0, autoIncreaseIntervalDays: 0,

View File

@ -324,7 +324,7 @@ class _PrePlantingMergeDetailPageState
const SizedBox(height: 8), const SizedBox(height: 8),
_buildDetailRow( _buildDetailRow(
'总价值', '总价值',
'${(merge.sourceOrderNos.length * 3566).toString()} 绿积分', '${(merge.sourceOrderNos.length * 1887).toString()} 绿积分',
), ),
if (merge.selectedProvince != null) ...[ if (merge.selectedProvince != null) ...[
const SizedBox(height: 8), const SizedBox(height: 8),
@ -508,7 +508,7 @@ class _PrePlantingMergeDetailPageState
), ),
), ),
const Text( const Text(
'3,171 绿积分', '1,887 绿积分',
style: TextStyle( style: TextStyle(
fontSize: 13, fontSize: 13,
color: Color(0xFF745D43), color: Color(0xFF745D43),

View File

@ -11,7 +11,7 @@ import '../../../../routes/route_paths.dart';
// //
// //
// - // -
// - N/5 // - N/10
// - // -
// - / // - /
// //
@ -40,7 +40,7 @@ class _PrePlantingPositionPageState
extends ConsumerState<PrePlantingPositionPage> extends ConsumerState<PrePlantingPositionPage>
with SingleTickerProviderStateMixin { with SingleTickerProviderStateMixin {
// === === // === ===
static const int _portionsPerTree = 5; static const int _portionsPerTree = 10;
// === === // === ===

View File

@ -12,8 +12,9 @@ import '../../../../routes/route_paths.dart';
// ============================================ // ============================================
// //
// / // /
// - 3566 USDT/ // [2026-03-01] 1887 USDT/ × 10 = 18870 USDT/
// - 5 1 // - 1887 USDT/
// - 10 1
// - // -
// - // -
// //
@ -24,12 +25,12 @@ import '../../../../routes/route_paths.dart';
// 4. // 4.
// //
// === === // === ===
// planting_quantity_page.dart 15831 USDT/ // planting_quantity_page.dart 18870 USDT/
// 3566 USDT/ // 1887 USDT/
/// ///
/// ///
/// 3566 USDT/ 5 1 /// 1887 USDT/ 10 1
/// ///
class PrePlantingPurchasePage extends ConsumerStatefulWidget { class PrePlantingPurchasePage extends ConsumerStatefulWidget {
const PrePlantingPurchasePage({super.key}); const PrePlantingPurchasePage({super.key});
@ -44,10 +45,10 @@ class _PrePlantingPurchasePageState
// === === // === ===
/// USDT- admin-service /// USDT- admin-service
double _pricePerPortion = 3566.0; double _pricePerPortion = 1887.0;
/// ///
static const int _portionsPerTree = 5; static const int _portionsPerTree = 10;
/// ///
TreePricingConfig? _pricingConfig; TreePricingConfig? _pricingConfig;
@ -328,8 +329,8 @@ class _PrePlantingPurchasePageState
static const String _defaultAgreementText = static const String _defaultAgreementText =
'预种协议\n\n' '预种协议\n\n'
'1. 用户成功购买预种计划后,自动获得分享权。\n' '1. 用户成功购买预种计划后,自动获得分享权。\n'
'2. 每一份预种计划对应享有1棵猫山王榴莲树40%产果分红权的1/5份额,' '2. 每一份预种计划对应享有1棵猫山王榴莲树40%产果分红权的1/10份额,'
'即单份预种计划可享受该果树8%的产果分红权。'; '即单份预种计划可享受该果树4%的产果分红权。';
/// ///
Future<void> _confirmPurchase() async { Future<void> _confirmPurchase() async {
@ -870,7 +871,7 @@ class _PrePlantingPurchasePageState
); );
} }
/// N/5 /// N/10
Widget _buildMergeProgressCard() { Widget _buildMergeProgressCard() {
final available = _position!.availablePortions; final available = _position!.availablePortions;
final treesMerged = _position!.totalTreesMerged; final treesMerged = _position!.totalTreesMerged;
@ -1385,7 +1386,7 @@ class _PrePlantingPurchasePageState
const SizedBox(width: 8), const SizedBox(width: 8),
Expanded( Expanded(
child: Text( child: Text(
'预计涨价: ${_pricingConfig!.nextAutoIncreaseAt!.month}${_pricingConfig!.nextAutoIncreaseAt!.day}日后每份 +${(_pricingConfig!.autoIncreaseAmount / 5).floor()} 绿积分', '预计涨价: ${_pricingConfig!.nextAutoIncreaseAt!.month}${_pricingConfig!.nextAutoIncreaseAt!.day}日后每份 +${(_pricingConfig!.autoIncreaseAmount / _portionsPerTree).floor()} 绿积分',
style: const TextStyle( style: const TextStyle(
fontSize: 13, fontSize: 13,
fontFamily: 'Inter', fontFamily: 'Inter',

View File

@ -2056,7 +2056,7 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
/// [2026-02-17] + /// [2026-02-17] +
/// ///
/// ///
/// - 3566 USDT/ /// - 1887 USDT/
/// - /// -
Widget _buildPrePlantingButtons() { Widget _buildPrePlantingButtons() {
return Row( return Row(

View File

@ -44,7 +44,7 @@ import '../features/kyc/presentation/pages/change_phone_page.dart';
import '../features/contract_signing/presentation/pages/contract_signing_page.dart'; import '../features/contract_signing/presentation/pages/contract_signing_page.dart';
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] 3566 USDT/ 5 1 // [2026-02-17] 1887 USDT/ 10 1
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';