diff --git a/backend/services/trading-service/src/application/services/c2c.service.ts b/backend/services/trading-service/src/application/services/c2c.service.ts index 5840e160..69852dc2 100644 --- a/backend/services/trading-service/src/application/services/c2c.service.ts +++ b/backend/services/trading-service/src/application/services/c2c.service.ts @@ -780,38 +780,73 @@ export class C2cService { }, }); - // 3. MATCHED/PAID 订单恢复为新的 PENDING 订单 + // 3. MATCHED/PAID 订单恢复:优先合并到已有的同 maker/type/price 的 PENDING 订单 if (shouldRestore) { const priceDecimal = new Decimal(freshOrder.price); - restoreOrderNo = this.generateOrderNo(); - const totalAmount = priceDecimal.mul(quantityDecimal).toString(); - this.logger.log( - `[EXPIRY][TX] 步骤3: 恢复为新 PENDING 订单 ${restoreOrderNo}, ` + - `类型=${freshOrder.type}, maker=${freshOrder.makerAccountSequence}, ` + - `数量=${quantityDecimal}, 总金额=${totalAmount}`, - ); - await tx.c2cOrder.create({ - data: { - orderNo: restoreOrderNo, + + // 查找是否已有可合并的 PENDING 订单(同 maker + 同类型 + 同价格) + const existingPending = await tx.c2cOrder.findFirst({ + where: { + makerAccountSequence: freshOrder.makerAccountSequence, type: freshOrder.type as any, status: C2C_ORDER_STATUS.PENDING as any, - makerAccountSequence: freshOrder.makerAccountSequence, - makerUserId: freshOrder.makerUserId, - makerPhone: freshOrder.makerPhone, - makerNickname: freshOrder.makerNickname, price: freshOrder.price, - quantity: quantityDecimal.toString(), - totalAmount, - minAmount: '0', - maxAmount: '0', - paymentMethod: isSell ? freshOrder.paymentMethod : null, - paymentAccount: isSell ? freshOrder.paymentAccount : null, - paymentQrCode: isSell ? freshOrder.paymentQrCode : null, - paymentRealName: isSell ? freshOrder.paymentRealName : null, - sellerKavaAddress: isSell ? freshOrder.sellerKavaAddress : null, - remark: freshOrder.remark, }, }); + + if (existingPending) { + // 合并到已有 PENDING 订单:增加数量和总金额 + const existingQty = new Decimal(existingPending.quantity.toString()); + const mergedQty = existingQty.plus(quantityDecimal); + const mergedTotal = priceDecimal.mul(mergedQty).toString(); + restoreOrderNo = existingPending.orderNo; + + this.logger.log( + `[EXPIRY][TX] 步骤3: 合并到已有 PENDING 订单 ${existingPending.orderNo}, ` + + `原数量=${existingQty} + 恢复=${quantityDecimal} = ${mergedQty}`, + ); + + await tx.c2cOrder.update({ + where: { orderNo: existingPending.orderNo }, + data: { + quantity: mergedQty.toString(), + totalAmount: mergedTotal, + }, + }); + } else { + // 无可合并订单,创建新的 PENDING 订单 + restoreOrderNo = this.generateOrderNo(); + const totalAmount = priceDecimal.mul(quantityDecimal).toString(); + + this.logger.log( + `[EXPIRY][TX] 步骤3: 创建新 PENDING 订单 ${restoreOrderNo}, ` + + `类型=${freshOrder.type}, maker=${freshOrder.makerAccountSequence}, ` + + `数量=${quantityDecimal}, 总金额=${totalAmount}`, + ); + + await tx.c2cOrder.create({ + data: { + orderNo: restoreOrderNo, + type: freshOrder.type as any, + status: C2C_ORDER_STATUS.PENDING as any, + makerAccountSequence: freshOrder.makerAccountSequence, + makerUserId: freshOrder.makerUserId, + makerPhone: freshOrder.makerPhone, + makerNickname: freshOrder.makerNickname, + price: freshOrder.price, + quantity: quantityDecimal.toString(), + totalAmount, + minAmount: '0', + maxAmount: '0', + paymentMethod: isSell ? freshOrder.paymentMethod : null, + paymentAccount: isSell ? freshOrder.paymentAccount : null, + paymentQrCode: isSell ? freshOrder.paymentQrCode : null, + paymentRealName: isSell ? freshOrder.paymentRealName : null, + sellerKavaAddress: isSell ? freshOrder.sellerKavaAddress : null, + remark: freshOrder.remark, + }, + }); + } } else { this.logger.debug(`[EXPIRY][TX] 步骤3: PENDING 订单无需恢复`); }