import { createClient, RedisClientType } from 'redis'; class RedisUtil { private client: RedisClientType | null = null; private static instance: RedisUtil; private constructor() {} public static getInstance(): RedisUtil { if (!RedisUtil.instance) { RedisUtil.instance = new RedisUtil(); } return RedisUtil.instance; } async connect(): Promise { if (!this.client) { this.client = createClient({ url: process.env.REDIS_URL || 'redis://127.0.0.1:6379' }); this.client.on('error', (err) => { console.error('Redis Client Error:', err); }); await this.client.connect(); } return this.client; } async disconnect(): Promise { if (this.client) { await this.client.disconnect(); this.client = null; } } async setSessionKey(userId: number, sessionKey: string, ttlSeconds: number = 7200): Promise { const client = await this.connect(); const key = `session_key:${userId}`; await client.set(key, sessionKey, { EX: ttlSeconds // 默认2小时过期,与微信session_key有效期一致 }); } async getSessionKey(userId: number): Promise { const client = await this.connect(); const key = `session_key:${userId}`; return await client.get(key); } async deleteSessionKey(userId: number): Promise { const client = await this.connect(); const key = `session_key:${userId}`; await client.del(key); } async isSessionKeyValid(userId: number): Promise { const sessionKey = await this.getSessionKey(userId); return !!sessionKey; } /** * 设置系统配置缓存 */ async setSystemConfig(tenantId: number, configKey: string, configValue: string, ttlSeconds: number = 3600): Promise { const client = await this.connect(); const key = `system_config:${tenantId}:${configKey}`; await client.set(key, configValue, { EX: ttlSeconds // 默认1小时过期 }); } /** * 获取系统配置缓存 */ async getSystemConfig(tenantId: number, configKey: string): Promise { const client = await this.connect(); const key = `system_config:${tenantId}:${configKey}`; return await client.get(key); } /** * 删除系统配置缓存 */ async deleteSystemConfig(tenantId: number, configKey: string): Promise { const client = await this.connect(); const key = `system_config:${tenantId}:${configKey}`; await client.del(key); } /** * 批量获取系统配置缓存 */ async getSystemConfigs(tenantId: number, configKeys: string[]): Promise> { const client = await this.connect(); const keys = configKeys.map(key => `system_config:${tenantId}:${key}`); const values = await client.mGet(keys); const result: Record = {}; configKeys.forEach((key, index) => { result[key] = values[index]; }); return result; } /** * 设置空值缓存(防止缓存穿透) */ async setNullSystemConfig(tenantId: number, configKey: string, ttlSeconds: number = 300): Promise { const client = await this.connect(); const key = `system_config:${tenantId}:${configKey}`; await client.set(key, '__NULL__', { EX: ttlSeconds // 默认5分钟过期 }); } /** * 检查是否为空值缓存 */ isNullValue(value: string | null): boolean { return value === '__NULL__'; } /** * 清除租户的所有系统配置缓存 */ async clearTenantSystemConfigs(tenantId: number): Promise { const client = await this.connect(); const pattern = `system_config:${tenantId}:*`; // 使用SCAN命令遍历匹配的键并删除 let cursor = 0; do { const result = await client.scan(cursor, { MATCH: pattern, COUNT: 100 }); cursor = result.cursor; const keys = result.keys; if (keys.length > 0) { await client.del(keys); } } while (cursor !== 0); } /** * 格式化系统配置缓存键 */ formatSystemConfigKey(tenantId: number, configKey: string): string { return `system_config:${tenantId}:${configKey}`; } } export const redisUtil = RedisUtil.getInstance();