diff --git a/backend/services/contribution-service/src/app.module.ts b/backend/services/contribution-service/src/app.module.ts index 107eda6d..c9cb782e 100644 --- a/backend/services/contribution-service/src/app.module.ts +++ b/backend/services/contribution-service/src/app.module.ts @@ -26,7 +26,7 @@ import { PrePlantingCdcModule } from './pre-planting/pre-planting-cdc.module'; InfrastructureModule, ApplicationModule, ApiModule, - PrePlantingCdcModule, // 预种计划:独立 CDC consumer、独立 Prisma schema、1/5 算力、冻结调度 + PrePlantingCdcModule, // 预种计划:独立 CDC consumer、独立 Prisma schema、1/10 算力、冻结调度 ], providers: [ { diff --git a/backend/services/contribution-service/src/pre-planting/application/handlers/pre-planting-order-synced.handler.ts b/backend/services/contribution-service/src/pre-planting/application/handlers/pre-planting-order-synced.handler.ts index 3ce16c62..1cce81d1 100644 --- a/backend/services/contribution-service/src/pre-planting/application/handlers/pre-planting-order-synced.handler.ts +++ b/backend/services/contribution-service/src/pre-planting/application/handlers/pre-planting-order-synced.handler.ts @@ -25,7 +25,7 @@ export interface PrePlantingOrderSyncResult { * 1. 同步预种订单到 pre_planting_synced_orders(追踪表) * 2. 当订单状态为 PAID 时,标记需要算力计算 * 3. 在 synced_adoptions 中插入 marker 记录(用于 getDirectReferralAdoptedCount 正确计数) - * 4. 事务提交后,触发 1/5 算力计算(PostCommitCallback) + * 4. 事务提交后,触发 1/10 算力计算(PostCommitCallback) * * === 对现有系统的影响 === * - 零修改现有代码 diff --git a/backend/services/contribution-service/src/pre-planting/application/schedulers/pre-planting-freeze.scheduler.ts b/backend/services/contribution-service/src/pre-planting/application/schedulers/pre-planting-freeze.scheduler.ts index 25f31ef1..73ff913b 100644 --- a/backend/services/contribution-service/src/pre-planting/application/schedulers/pre-planting-freeze.scheduler.ts +++ b/backend/services/contribution-service/src/pre-planting/application/schedulers/pre-planting-freeze.scheduler.ts @@ -15,11 +15,11 @@ import { * [2026-02-17] 新增:每日检查预种用户的冻结/解冻条件 * * === 冻结规则 === - * - firstPurchaseAt + 1 年后,仍未满 5 份(totalPortions < 5)→ 冻结所有预种算力 + * - firstPurchaseAt + 1 年后,仍未满 10 份(totalPortions < 10)→ 冻结所有预种算力 * - 冻结方式:将预种算力记录标记为 expired(is_expired=true) * * === 解冻规则 === - * - 冻结后累积满 5 份(totalPortions >= 5)→ 解冻 + * - 冻结后累积满 10 份(totalPortions >= 10)→ 解冻 * - 解冻后的失效期 = 解冻日 + 2 年 * * === 正常到期(未被冻结过)=== @@ -77,7 +77,7 @@ export class PrePlantingFreezeScheduler { } /** - * 处理冻结:查找 firstPurchaseAt + 1 年已过且未满 5 份的用户 + * 处理冻结:查找 firstPurchaseAt + 1 年已过且未满 10 份的用户 */ private async processFreezes(now: Date): Promise { const freezeDeadline = new Date(now); @@ -86,7 +86,7 @@ export class PrePlantingFreezeScheduler { const candidates = await this.prePlantingPrisma.prePlantingFreezeState.findMany({ where: { firstPurchaseAt: { lte: freezeDeadline }, - totalPortions: { lt: 5 }, + totalPortions: { lt: 10 }, isFrozen: false, }, take: 100, @@ -122,13 +122,13 @@ export class PrePlantingFreezeScheduler { } /** - * 处理解冻:查找已冻结但现在满 5 份的用户 + * 处理解冻:查找已冻结但现在满 10 份的用户 */ private async processUnfreezes(now: Date): Promise { const candidates = await this.prePlantingPrisma.prePlantingFreezeState.findMany({ where: { isFrozen: true, - totalPortions: { gte: 5 }, + totalPortions: { gte: 10 }, }, take: 100, }); diff --git a/backend/services/contribution-service/src/pre-planting/application/services/pre-planting-contribution.service.ts b/backend/services/contribution-service/src/pre-planting/application/services/pre-planting-contribution.service.ts index b9fc959c..c9b5f83e 100644 --- a/backend/services/contribution-service/src/pre-planting/application/services/pre-planting-contribution.service.ts +++ b/backend/services/contribution-service/src/pre-planting/application/services/pre-planting-contribution.service.ts @@ -40,10 +40,11 @@ export interface PrePlantingMergeSyncResult { /** * 预种算力计算服务 * - * [2026-02-17] 新增:复用现有领域计算器,以 1/5 贡献值处理预种份额 + * [2026-02-17] 新增:复用现有领域计算器,以 1/10 贡献值处理预种份额 + * [2026-03-04] 更新:预种方案从「5份合1树」调整为「10份合1树」,每份算力从 rate/5 改为 rate/10 * * === 核心设计 === - * - 构建虚拟 SyncedAdoption 对象(treeCount=portionCount, contributionPerTree=rate/5) + * - 构建虚拟 SyncedAdoption 对象(treeCount=portionCount, contributionPerTree=rate/10) * - 调用现有 ContributionCalculatorService(领域服务)计算分配 * - 结果写入现有 contribution_accounts/contribution_records 表(挖矿系统可见) * - 使用 PRE_PLANTING_SOURCE_ID_OFFSET (10B) 偏移,避免与正常认种 ID 冲突 @@ -103,7 +104,7 @@ export class PrePlantingContributionService { return; } - // 获取当日每棵树贡献值(预种份额 = 1/5) + // 获取当日每棵树贡献值(预种份额 = 1/10,10份合1棵树) const adoptionDate = order.paidAt || order.createdAt; let contributionPerTree = new Decimal('22617'); try { @@ -123,7 +124,7 @@ export class PrePlantingContributionService { status: 'MINING_ENABLED', selectedProvince: order.provinceCode, selectedCity: order.cityCode, - contributionPerTree: contributionPerPortion, // 1/5 贡献值 + contributionPerTree: contributionPerPortion, // 1/10 贡献值 sourceSequenceNum: BigInt(0), syncedAt: new Date(), contributionDistributed: false, @@ -557,10 +558,11 @@ export class PrePlantingContributionService { /** * 预种合成树后算力切换 * - * [2026-02-28] 新增:5份预种合成1棵树,合同签署(mining_enabled_at 写入)后触发 + * [2026-02-28] 新增:预种合成1棵树,合同签署(mining_enabled_at 写入)后触发 + * [2026-03-04] 更新:合成阈值从 5份 改为 10份 * * === 操作流程 === - * 1. 作废5份份额的算力记录(is_expired=true,remark 说明原因,已挖积分不追回) + * 1. 作废全部份额的算力记录(is_expired=true,remark 说明原因,已挖积分不追回) * 2. 从认种人账户扣减旧个人算力(保持账户余额准确) * 3. 以1棵完整树的算力创建新记录(remark 标注合成来源) * 4. 团队分润账户通过 saveDistributionResult 自然更新(净效果≈0,旧=新) @@ -574,7 +576,7 @@ export class PrePlantingContributionService { const { mergeNo, mergeId, accountSequence, sourceOrderNos, miningEnabledAt } = result; const mergeSourceAdoptionId = PRE_PLANTING_MERGE_SOURCE_ID_OFFSET + mergeId; - // Step 1: 查找5份源订单的追踪记录 + // Step 1: 查找源订单的追踪记录 const sourceOrders = await this.prePlantingPrisma.prePlantingSyncedOrder.findMany({ where: { orderNo: { in: sourceOrderNos } }, }); @@ -671,7 +673,7 @@ export class PrePlantingContributionService { const expireRemark = `预种合成:本份额已合并为1棵树(${mergeNo}),算力转为树级计算,已挖积分不受影响`; const mergeRemark = - `预种合成树:由5份份额合并(${mergeNo})算力升级为整棵树,` + + `预种合成树:由${sourceOrderNos.length}份份额合并(${mergeNo})算力升级为整棵树,` + `源订单:${sourceOrderNos.join('、')}`; await this.unitOfWork.executeInTransaction(async () => { diff --git a/backend/services/contribution-service/src/pre-planting/domain/constants.ts b/backend/services/contribution-service/src/pre-planting/domain/constants.ts index 7b221721..4cb75f28 100644 --- a/backend/services/contribution-service/src/pre-planting/domain/constants.ts +++ b/backend/services/contribution-service/src/pre-planting/domain/constants.ts @@ -17,22 +17,25 @@ export const PRE_PLANTING_SOURCE_ID_OFFSET = 10_000_000_000n; /** * 预种每份的贡献值因子 * - * 每份预种 = 1棵树贡献值的 1/5 + * 每份预种 = 1棵树贡献值的 1/10(10份合1棵树) * 用法:contributionPerPortion = contributionPerTree / PRE_PLANTING_PORTION_DIVISOR + * + * [2026-03-04] 从 5 改为 10:预种方案从「5份合1树(3566USDT/份)」调整为「10份合1树(1887USDT/份)」 + * 注意:2026-03-01 前已创建的份额算力记录(3566USDT/份,按1/5计算)不追溯修正。 */ -export const PRE_PLANTING_PORTION_DIVISOR = 5; +export const PRE_PLANTING_PORTION_DIVISOR = 10; /** * 预种冻结期限(从首次购买日起算,单位:年) * - * 首次购买 + 1 年后仍未满 5 份 → 所有预种算力冻结 + * 首次购买 + 1 年后仍未满 10 份 → 所有预种算力冻结 */ export const PRE_PLANTING_FREEZE_PERIOD_YEARS = 1; /** * 解冻后的算力有效期(从解冻日起算,单位:年) * - * 冻结后满 5 份解冻 → 算力恢复,从解冻日起算 2 年后失效 + * 冻结后满 10 份解冻 → 算力恢复,从解冻日起算 2 年后失效 */ export const PRE_PLANTING_POST_UNFREEZE_VALIDITY_YEARS = 2; diff --git a/backend/services/contribution-service/src/pre-planting/pre-planting-cdc.module.ts b/backend/services/contribution-service/src/pre-planting/pre-planting-cdc.module.ts index 65bd4a21..852841e8 100644 --- a/backend/services/contribution-service/src/pre-planting/pre-planting-cdc.module.ts +++ b/backend/services/contribution-service/src/pre-planting/pre-planting-cdc.module.ts @@ -35,9 +35,9 @@ import { BonusClaimService } from '../application/services/bonus-claim.service'; * === 功能概述 === * 1. 通过独立 CDC consumer 消费预种表变更(cdc.pre-planting.public.*) * 2. 同步预种订单/持仓到独立追踪表(PrePlantingPrismaService) - * 3. 为每份预种订单计算 1/5 算力(复用现有领域计算器) + * 3. 为每份预种订单计算 1/10 算力(复用现有领域计算器,10份合1棵树) * 4. 在 synced_adoptions 中插入 marker 记录(让现有 unlock 逻辑自然计入预种用户) - * 5. 每日检查冻结/解冻条件(1 年未满 5 份 → 冻结;满 5 份 → 解冻 + 2 年有效期) + * 5. 每日检查冻结/解冻条件(1 年未满 10 份 → 冻结;满 10 份 → 解冻 + 2 年有效期) * * === 隔离保证 === * - 独立 Kafka consumer group:contribution-pre-planting-cdc(不影响现有 contribution-service-cdc-group)