205 lines
4.9 KiB
TypeScript
205 lines
4.9 KiB
TypeScript
/**
|
|
* 通知目标配置
|
|
*/
|
|
export interface NotificationTarget {
|
|
type: TargetType;
|
|
tagIds?: string[]; // 标签ID列表 (AND 关系)
|
|
segmentId?: string; // 人群包ID
|
|
accountSequences?: string[]; // 特定用户列表
|
|
}
|
|
|
|
/**
|
|
* 通知实体
|
|
*/
|
|
export class NotificationEntity {
|
|
constructor(
|
|
public readonly id: string,
|
|
public readonly title: string,
|
|
public readonly content: string,
|
|
public readonly type: NotificationType,
|
|
public readonly priority: NotificationPriority,
|
|
public readonly targetType: TargetType,
|
|
public readonly targetConfig: NotificationTarget | null,
|
|
public readonly imageUrl: string | null,
|
|
public readonly linkUrl: string | null,
|
|
public readonly isEnabled: boolean,
|
|
public readonly publishedAt: Date | null,
|
|
public readonly expiresAt: Date | null,
|
|
public readonly createdAt: Date,
|
|
public readonly updatedAt: Date,
|
|
public readonly createdBy: string,
|
|
) {}
|
|
|
|
/**
|
|
* 检查通知是否已发布且有效
|
|
*/
|
|
isActive(): boolean {
|
|
if (!this.isEnabled || !this.publishedAt) {
|
|
return false;
|
|
}
|
|
const now = new Date();
|
|
if (this.publishedAt > now) {
|
|
return false;
|
|
}
|
|
if (this.expiresAt && this.expiresAt < now) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* 检查是否已过期
|
|
*/
|
|
isExpired(): boolean {
|
|
if (!this.expiresAt) {
|
|
return false;
|
|
}
|
|
return this.expiresAt < new Date();
|
|
}
|
|
|
|
/**
|
|
* 检查是否为定向通知
|
|
*/
|
|
isTargeted(): boolean {
|
|
return this.targetType !== TargetType.ALL;
|
|
}
|
|
|
|
/**
|
|
* 检查是否需要标签过滤
|
|
*/
|
|
requiresTagFilter(): boolean {
|
|
return (
|
|
this.targetType === TargetType.BY_TAG &&
|
|
this.targetConfig?.tagIds !== undefined &&
|
|
this.targetConfig.tagIds.length > 0
|
|
);
|
|
}
|
|
|
|
/**
|
|
* 检查是否为特定用户通知
|
|
*/
|
|
isSpecificUsers(): boolean {
|
|
return (
|
|
this.targetType === TargetType.SPECIFIC &&
|
|
this.targetConfig?.accountSequences !== undefined &&
|
|
this.targetConfig.accountSequences.length > 0
|
|
);
|
|
}
|
|
|
|
/**
|
|
* 创建新通知
|
|
*/
|
|
static create(params: {
|
|
id: string;
|
|
title: string;
|
|
content: string;
|
|
type: NotificationType;
|
|
priority?: NotificationPriority;
|
|
targetType?: TargetType;
|
|
targetConfig?: NotificationTarget | null;
|
|
imageUrl?: string | null;
|
|
linkUrl?: string | null;
|
|
publishedAt?: Date | null;
|
|
expiresAt?: Date | null;
|
|
createdBy: string;
|
|
}): NotificationEntity {
|
|
const now = new Date();
|
|
const targetType = params.targetType ?? TargetType.ALL;
|
|
|
|
// 构建目标配置
|
|
let targetConfig: NotificationTarget | null = null;
|
|
if (params.targetConfig) {
|
|
targetConfig = {
|
|
...params.targetConfig,
|
|
type: targetType,
|
|
};
|
|
} else if (targetType !== TargetType.ALL) {
|
|
targetConfig = { type: targetType };
|
|
}
|
|
|
|
return new NotificationEntity(
|
|
params.id,
|
|
params.title,
|
|
params.content,
|
|
params.type,
|
|
params.priority ?? NotificationPriority.NORMAL,
|
|
targetType,
|
|
targetConfig,
|
|
params.imageUrl ?? null,
|
|
params.linkUrl ?? null,
|
|
true,
|
|
params.publishedAt ?? null,
|
|
params.expiresAt ?? null,
|
|
now,
|
|
now,
|
|
params.createdBy,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* 更新通知
|
|
*/
|
|
update(params: {
|
|
title?: string;
|
|
content?: string;
|
|
type?: NotificationType;
|
|
priority?: NotificationPriority;
|
|
targetType?: TargetType;
|
|
targetConfig?: NotificationTarget | null;
|
|
imageUrl?: string | null;
|
|
linkUrl?: string | null;
|
|
isEnabled?: boolean;
|
|
publishedAt?: Date | null;
|
|
expiresAt?: Date | null;
|
|
}): NotificationEntity {
|
|
return new NotificationEntity(
|
|
this.id,
|
|
params.title ?? this.title,
|
|
params.content ?? this.content,
|
|
params.type ?? this.type,
|
|
params.priority ?? this.priority,
|
|
params.targetType ?? this.targetType,
|
|
params.targetConfig !== undefined ? params.targetConfig : this.targetConfig,
|
|
params.imageUrl !== undefined ? params.imageUrl : this.imageUrl,
|
|
params.linkUrl !== undefined ? params.linkUrl : this.linkUrl,
|
|
params.isEnabled ?? this.isEnabled,
|
|
params.publishedAt !== undefined ? params.publishedAt : this.publishedAt,
|
|
params.expiresAt !== undefined ? params.expiresAt : this.expiresAt,
|
|
this.createdAt,
|
|
new Date(),
|
|
this.createdBy,
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 通知类型
|
|
*/
|
|
export enum NotificationType {
|
|
SYSTEM = 'SYSTEM',
|
|
ACTIVITY = 'ACTIVITY',
|
|
REWARD = 'REWARD',
|
|
UPGRADE = 'UPGRADE',
|
|
ANNOUNCEMENT = 'ANNOUNCEMENT',
|
|
}
|
|
|
|
/**
|
|
* 通知优先级
|
|
*/
|
|
export enum NotificationPriority {
|
|
LOW = 'LOW',
|
|
NORMAL = 'NORMAL',
|
|
HIGH = 'HIGH',
|
|
URGENT = 'URGENT',
|
|
}
|
|
|
|
/**
|
|
* 目标用户类型
|
|
* 注意:与 Prisma schema 中的 TargetType 枚举保持一致
|
|
*/
|
|
export enum TargetType {
|
|
ALL = 'ALL', // 所有用户
|
|
BY_TAG = 'BY_TAG', // 按标签筛选
|
|
SPECIFIC = 'SPECIFIC', // 特定用户列表
|
|
}
|