fix(reporting): 修复 contract.signed 事件 BigInt(undefined) 错误

根因:planting-service 发送的 contract.signed 消息为嵌套结构
  { eventName: 'contract.signed', data: { orderNo, userId, ... } }
但 reporting-service handleContractSigned 按扁平结构解析
  message.userId → undefined → BigInt(undefined) → TypeError
导致 ~200 次/10分钟持续报错。

修复:
- 消息类型改为匹配实际嵌套格式 { eventName, data: { ... } }
- 解构 message.data 后再访问各字段
- 添加 userId 防御性检查,避免再次 BigInt 崩溃
- 与 referral-service ContractSigningHandler 消息结构保持一致

影响范围:仅 reporting-service 活动记录,不影响核心业务流程
(referral-service / reward-service 已正确处理嵌套格式)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-02-15 07:59:16 -08:00
parent 2a725af83e
commit 875f86c263
1 changed files with 38 additions and 21 deletions

View File

@ -637,47 +637,64 @@ export class ActivityEventConsumerController {
/**
* (planting-service)
* Topic: contract.signed
*
* planting-service EventPublisherService.publishContractSigned :
* { eventName: 'contract.signed', data: { orderNo, userId, accountSequence, ... } }
*
* payload data referral-service ContractSigningHandler
* message.userId undefined BigInt(undefined)
* TypeError (~200/10)
*/
@MessagePattern('contract.signed')
async handleContractSigned(
@Payload()
message: {
orderNo: string;
userId: string;
accountSequence: string;
treeCount: number;
totalAmount: number;
provinceCode: string;
cityCode: string;
signedAt: string;
eventName: string;
data: {
orderNo: string;
userId: string;
accountSequence: string;
treeCount: number;
totalAmount: number;
provinceCode: string;
cityCode: string;
signedAt?: string;
};
},
) {
this.logger.log(`Received contract.signed event: ${message.orderNo}`);
const eventData = message.data;
if (!eventData?.userId) {
this.logger.warn(`Received contract.signed with missing data.userId, skipping. Raw: ${JSON.stringify(message)}`);
return;
}
this.logger.log(`Received contract.signed event: ${eventData.orderNo}`);
try {
const created = await this.activityRepo.createIfNotExists({
activityType: 'contract_signed' as ActivityType,
title: '合同签署',
description: `用户签署了 ${message.treeCount} 棵榴莲树认种合同`,
description: `用户签署了 ${eventData.treeCount} 棵榴莲树认种合同`,
icon: '📝',
relatedUserId: BigInt(message.userId),
relatedUserId: BigInt(eventData.userId),
relatedEntityType: 'contract',
relatedEntityId: message.orderNo,
relatedEntityId: eventData.orderNo,
metadata: {
orderNo: message.orderNo,
accountSequence: message.accountSequence,
treeCount: message.treeCount,
totalAmount: message.totalAmount,
provinceCode: message.provinceCode,
cityCode: message.cityCode,
signedAt: message.signedAt,
orderNo: eventData.orderNo,
accountSequence: eventData.accountSequence,
treeCount: eventData.treeCount,
totalAmount: eventData.totalAmount,
provinceCode: eventData.provinceCode,
cityCode: eventData.cityCode,
signedAt: eventData.signedAt,
},
});
if (created) {
this.logger.log(`Activity recorded for contract signing: ${message.orderNo}`);
this.logger.log(`Activity recorded for contract signing: ${eventData.orderNo}`);
} else {
this.logger.log(`Skipped duplicate contract signing event: ${message.orderNo}`);
this.logger.log(`Skipped duplicate contract signing event: ${eventData.orderNo}`);
}
} catch (error) {
this.logger.error(`Error recording contract signing activity:`, error);