import { PrePlantingContractStatus } from '../value-objects/pre-planting-contract-status.enum'; import { DomainEvent } from '../../../domain/events/domain-event.interface'; import { PrePlantingMergedEvent } from '../events/pre-planting-merged.event'; import { PrePlantingContractSignedEvent } from '../events/pre-planting-contract-signed.event'; export interface PrePlantingMergeData { id?: bigint; mergeNo: string; userId: bigint; accountSequence: string; sourceOrderNos: string[]; treeCount: number; provinceCode?: string | null; cityCode?: string | null; contractStatus: PrePlantingContractStatus; contractSignedAt?: Date | null; miningEnabledAt?: Date | null; mergedAt?: Date; } export class PrePlantingMerge { private _id: bigint | null; private readonly _mergeNo: string; private readonly _userId: bigint; private readonly _accountSequence: string; private readonly _sourceOrderNos: string[]; private readonly _treeCount: number; private _provinceCode: string | null; private _cityCode: string | null; private _contractStatus: PrePlantingContractStatus; private _contractSignedAt: Date | null; private _miningEnabledAt: Date | null; private readonly _mergedAt: Date; private _domainEvents: DomainEvent[] = []; private constructor( mergeNo: string, userId: bigint, accountSequence: string, sourceOrderNos: string[], provinceCode: string | null, cityCode: string | null, mergedAt?: Date, ) { this._id = null; this._mergeNo = mergeNo; this._userId = userId; this._accountSequence = accountSequence; this._sourceOrderNos = sourceOrderNos; this._treeCount = 1; this._provinceCode = provinceCode; this._cityCode = cityCode; this._contractStatus = PrePlantingContractStatus.PENDING; this._contractSignedAt = null; this._miningEnabledAt = null; this._mergedAt = mergedAt || new Date(); } /** * 创建合并记录 */ static create( mergeNo: string, userId: bigint, accountSequence: string, sourceOrderNos: string[], provinceCode: string, cityCode: string, totalTreesMergedAfter: number, ): PrePlantingMerge { if (sourceOrderNos.length !== 5) { throw new Error(`合并需要 5 个订单,收到 ${sourceOrderNos.length} 个`); } const merge = new PrePlantingMerge( mergeNo, userId, accountSequence, sourceOrderNos, provinceCode, cityCode, ); merge._domainEvents.push( new PrePlantingMergedEvent(mergeNo, { mergeNo, userId: userId.toString(), accountSequence, sourceOrderNos, treeCount: 1, provinceCode, cityCode, totalTreesMergedAfter, }), ); return merge; } /** * 从持久化数据重建 */ static reconstitute(data: PrePlantingMergeData): PrePlantingMerge { const merge = new PrePlantingMerge( data.mergeNo, data.userId, data.accountSequence, data.sourceOrderNos, data.provinceCode || null, data.cityCode || null, data.mergedAt, ); merge._id = data.id || null; merge._contractStatus = data.contractStatus; merge._contractSignedAt = data.contractSignedAt || null; merge._miningEnabledAt = data.miningEnabledAt || null; return merge; } /** * 签署合同 */ signContract(): void { if (this._contractStatus !== PrePlantingContractStatus.PENDING) { throw new Error(`合并 ${this._mergeNo} 合同状态不允许签署: ${this._contractStatus}`); } this._contractStatus = PrePlantingContractStatus.SIGNED; this._contractSignedAt = new Date(); this._miningEnabledAt = new Date(); this._domainEvents.push( new PrePlantingContractSignedEvent(this._mergeNo, { mergeNo: this._mergeNo, userId: this._userId.toString(), accountSequence: this._accountSequence, provinceCode: this._provinceCode || '', cityCode: this._cityCode || '', treeCount: this._treeCount, }), ); } setId(id: bigint): void { this._id = id; } get id(): bigint | null { return this._id; } get mergeNo(): string { return this._mergeNo; } get userId(): bigint { return this._userId; } get accountSequence(): string { return this._accountSequence; } get sourceOrderNos(): string[] { return [...this._sourceOrderNos]; } get treeCount(): number { return this._treeCount; } get provinceCode(): string | null { return this._provinceCode; } get cityCode(): string | null { return this._cityCode; } get contractStatus(): PrePlantingContractStatus { return this._contractStatus; } get contractSignedAt(): Date | null { return this._contractSignedAt; } get miningEnabledAt(): Date | null { return this._miningEnabledAt; } get mergedAt(): Date { return this._mergedAt; } get domainEvents(): DomainEvent[] { return [...this._domainEvents]; } clearDomainEvents(): void { this._domainEvents = []; } toPersistence(): PrePlantingMergeData { return { id: this._id || undefined, mergeNo: this._mergeNo, userId: this._userId, accountSequence: this._accountSequence, sourceOrderNos: this._sourceOrderNos, treeCount: this._treeCount, provinceCode: this._provinceCode, cityCode: this._cityCode, contractStatus: this._contractStatus, contractSignedAt: this._contractSignedAt, miningEnabledAt: this._miningEnabledAt, mergedAt: this._mergedAt, }; } }