2026-05-26 15:10:35 +08:00

172 lines
3.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 许可证类型
export type LicenseType = 'FREE' | 'STANDARD' | 'PRO';
// 许可证配置
export interface LicenseConfig {
type: LicenseType;
limits: {
maxUsers: number; // -1 表示无限
maxMaterials: number; // -1 表示无限
};
features: {
customTemplates: boolean;
systemSettings: boolean;
departmentIsolation: boolean;
apiAccess: boolean;
intranetPenetration: boolean;
};
expiresAt: string | null; // ISO 日期字符串,null 表示永久
leaseExpiresAt: string | null; // 在线租约到期时间,旧许可证可为 null
}
// 签名后的许可证
export interface SignedLicense {
data: LicenseConfig & { issuedAt: string };
signature: string;
issuedAt: string;
}
// 硬件指纹
export interface HardwareFingerprint {
machineId: string;
hostname: string;
macAddress: string;
cpuId?: string;
instanceId: string;
}
// 激活请求
export interface ActivateRequest {
licenseKey: string;
fingerprint: HardwareFingerprint;
timestamp: number;
}
// 激活响应
export interface ActivateResponse {
success: boolean;
license?: SignedLicense;
error?: string;
}
// 验证请求
export interface VerifyRequest {
instanceId: string;
fingerprint: HardwareFingerprint;
timestamp: number;
signature: string;
}
// 验证响应
export interface VerifyResponse {
valid: boolean;
license?: SignedLicense;
error?: string;
}
// 心跳请求
export interface HeartbeatRequest {
instanceId: string;
fingerprint: HardwareFingerprint;
usage: {
userCount: number;
materialCount: number;
};
timestamp: number;
signature: string;
}
// 心跳响应
export interface HeartbeatResponse {
acknowledged: boolean;
license?: SignedLicense;
}
// 版本检查响应
export interface VersionCheckResponse {
latestVersion: string;
minRequiredVersion: string | null;
releaseNotes: string | null;
releaseDate: string;
isSecurityUpdate: boolean;
isCriticalUpdate: boolean;
downloadSize: string | null;
}
// 各版本默认在线租约:免费版更短,付费版更宽松
export const LICENSE_LEASE_DAYS: Record<LicenseType, number> = {
FREE: 3,
STANDARD: 30,
PRO: 60,
};
// 各版本的默认配置
export const LICENSE_CONFIGS: Record<LicenseType, Omit<LicenseConfig, 'expiresAt' | 'leaseExpiresAt'>> = {
FREE: {
type: 'FREE',
limits: {
maxUsers: 10,
maxMaterials: 100,
},
features: {
customTemplates: false,
systemSettings: false,
departmentIsolation: false,
apiAccess: false,
intranetPenetration: false,
},
},
STANDARD: {
type: 'STANDARD',
limits: {
maxUsers: -1,
maxMaterials: -1,
},
features: {
customTemplates: true,
systemSettings: true,
departmentIsolation: true,
apiAccess: true,
intranetPenetration: false,
},
},
PRO: {
type: 'PRO',
limits: {
maxUsers: -1,
maxMaterials: -1,
},
features: {
customTemplates: true,
systemSettings: true,
departmentIsolation: true,
apiAccess: true,
intranetPenetration: true,
},
},
};
/**
* 根据许可证类型生成配置
*/
export function generateLicenseConfig(
type: LicenseType,
expiresAt?: Date | null,
leaseExpiresAt?: Date
): LicenseConfig {
const baseConfig = LICENSE_CONFIGS[type];
const defaultLeaseExpiresAt = new Date(
Date.now() + LICENSE_LEASE_DAYS[type] * 24 * 60 * 60 * 1000
);
const resolvedLeaseExpiresAt = leaseExpiresAt || defaultLeaseExpiresAt;
const boundedLeaseExpiresAt = expiresAt && resolvedLeaseExpiresAt && expiresAt < resolvedLeaseExpiresAt
? expiresAt
: resolvedLeaseExpiresAt;
return {
...baseConfig,
expiresAt: expiresAt ? expiresAt.toISOString() : null,
leaseExpiresAt: boundedLeaseExpiresAt.toISOString(),
};
}