From 2684a81383d12ab9282e8c1d2c7690db8605a036 Mon Sep 17 00:00:00 2001 From: hailin Date: Thu, 26 Feb 2026 23:36:08 -0800 Subject: [PATCH] =?UTF-8?q?fix(pre-planting):=20getEligibility=20=E8=BF=94?= =?UTF-8?q?=E5=9B=9E=20canPurchase=20=E5=AD=97=E6=AE=B5=E4=BF=AE=E5=A4=8D"?= =?UTF-8?q?=E5=BE=85=E5=BC=80=E5=90=AF"=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 后端 getEligibility() 原先只返回 hasPrePlanting/canTrade 等内部字段, 缺少前端购买页期望的 canPurchase/maxAdditional/message 字段。 由于 json['canPurchase'] ?? false 默认为 false,导致购买页始终显示"待开启"。 修复:getEligibility() 现在先查询 admin config 的 isActive 状态, 结合用户持仓计算出 canPurchase/maxAdditional/message,同时保留原有字段。 Co-Authored-By: Claude Opus 4.6 --- .../pre-planting-application.service.ts | 43 ++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/backend/services/planting-service/src/pre-planting/application/services/pre-planting-application.service.ts b/backend/services/planting-service/src/pre-planting/application/services/pre-planting-application.service.ts index b635c5eb..47f3f0ea 100644 --- a/backend/services/planting-service/src/pre-planting/application/services/pre-planting-application.service.ts +++ b/backend/services/planting-service/src/pre-planting/application/services/pre-planting-application.service.ts @@ -353,7 +353,11 @@ export class PrePlantingApplicationService { } /** - * 获取预种资格信息(供内部 API 使用) + * 获取预种资格信息(供内部 API + 移动端购买页使用) + * + * 返回字段同时满足两个消费者: + * - 内部 API: hasPrePlanting, canApplyAuthorization, canTrade + * - 移动端购买页: canPurchase, maxAdditional, message */ async getEligibility(accountSequence: string): Promise<{ hasPrePlanting: boolean; @@ -361,9 +365,40 @@ export class PrePlantingApplicationService { totalTreesMerged: number; canApplyAuthorization: boolean; canTrade: boolean; + canPurchase: boolean; + maxAdditional: number | null; + message: string | null; }> { + const config = await this.adminClient.getPrePlantingConfig(); + return this.prisma.$transaction(async (tx) => { const position = await this.positionRepo.findByAccountSequence(tx, accountSequence); + + // 计算购买资格 + let canPurchase = true; + let maxAdditional: number | null = null; + let message: string | null = null; + + if (config.isActive) { + // 开关打开,任何人都可以购买 + canPurchase = true; + } else if (!position || position.totalPortions === 0) { + // 开关关闭 + 无持仓 → 不可购买 + canPurchase = false; + message = '预种功能待开启'; + } else { + // 开关关闭 + 有持仓 → 看是否还能续购凑满 + const additionalNeeded = position.maxAdditionalPortionsToMerge(); + if (additionalNeeded === 0) { + canPurchase = false; + message = '预种功能已关闭,您当前份额已满,无法继续购买'; + } else { + canPurchase = true; + maxAdditional = additionalNeeded; + message = `预种功能已暂停,您可继续购买 ${additionalNeeded} 份以凑满合并`; + } + } + if (!position) { return { hasPrePlanting: false, @@ -371,6 +406,9 @@ export class PrePlantingApplicationService { totalTreesMerged: 0, canApplyAuthorization: true, canTrade: true, + canPurchase, + maxAdditional, + message, }; } return { @@ -379,6 +417,9 @@ export class PrePlantingApplicationService { totalTreesMerged: position.totalTreesMerged, canApplyAuthorization: position.totalTreesMerged >= 1, canTrade: position.totalTreesMerged >= 1, + canPurchase, + maxAdditional, + message, }; }); }