import { DomainError } from '@/shared/exceptions/domain.exception'; /** * 账户序列号值对象 * 格式: D + 年(2位) + 月(2位) + 日(2位) + 5位序号 * 示例: D2512110008 -> 2025年12月11日的第8个注册用户 */ export class AccountSequence { private static readonly PATTERN = /^D\d{11}$/; constructor(public readonly value: string) { if (!AccountSequence.PATTERN.test(value)) { throw new DomainError( `账户序列号格式无效: ${value},应为 D + 年月日(6位) + 序号(5位)`, ); } } static create(value: string): AccountSequence { return new AccountSequence(value); } /** * 根据日期和当日序号生成新的账户序列号 * @param date 日期 * @param dailySequence 当日序号 (0-99999) */ static generate(date: Date, dailySequence: number): AccountSequence { if (dailySequence < 0 || dailySequence > 99999) { throw new DomainError(`当日序号超出范围: ${dailySequence},应为 0-99999`); } const year = String(date.getFullYear()).slice(-2); const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); const seq = String(dailySequence).padStart(5, '0'); return new AccountSequence(`D${year}${month}${day}${seq}`); } /** * 从序列号中提取日期字符串 (YYMMDD) */ get dateString(): string { return this.value.slice(1, 7); } /** * 从序列号中提取当日序号 */ get dailySequence(): number { return parseInt(this.value.slice(7), 10); } equals(other: AccountSequence): boolean { return this.value === other.value; } toString(): string { return this.value; } }