Files
telegram-management-system/marketing-agent/services/safety-guard/src/config/redis.js
你的用户名 237c7802e5
Some checks failed
Deploy / deploy (push) Has been cancelled
Initial commit: Telegram Management System
Full-stack web application for Telegram management
- Frontend: Vue 3 + Vben Admin
- Backend: NestJS
- Features: User management, group broadcast, statistics

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 15:37:50 +08:00

156 lines
4.1 KiB
JavaScript

import Redis from 'ioredis';
import { logger } from '../utils/logger.js';
export class RedisClient {
constructor() {
this.client = null;
}
static getInstance() {
if (!RedisClient.instance) {
RedisClient.instance = new RedisClient();
}
return RedisClient.instance;
}
async connect() {
const config = {
host: process.env.REDIS_HOST || 'localhost',
port: process.env.REDIS_PORT || 6379,
password: process.env.REDIS_PASSWORD || undefined,
db: parseInt(process.env.REDIS_DB) || 2, // Different DB for safety guard
retryStrategy: (times) => {
const delay = Math.min(times * 50, 2000);
return delay;
},
enableOfflineQueue: false
};
try {
this.client = new Redis(config);
this.client.on('connect', () => {
logger.info('Redis connection established');
});
this.client.on('error', (err) => {
logger.error('Redis error:', err);
});
this.client.on('close', () => {
logger.warn('Redis connection closed');
});
// Wait for connection
await this.client.ping();
return this.client;
} catch (error) {
logger.error('Failed to connect to Redis:', error);
throw error;
}
}
async checkHealth() {
try {
const result = await this.client.ping();
return result === 'PONG';
} catch (error) {
logger.error('Redis health check failed:', error);
return false;
}
}
async disconnect() {
if (this.client) {
await this.client.quit();
logger.info('Redis connection closed');
}
}
// Cache methods with JSON serialization
async setWithExpiry(key, value, ttl) {
return await this.client.setex(key, ttl, JSON.stringify(value));
}
async get(key) {
const value = await this.client.get(key);
return value ? JSON.parse(value) : null;
}
async del(key) {
return await this.client.del(key);
}
async exists(key) {
return await this.client.exists(key);
}
// Hash operations
async hset(key, field, value) {
return await this.client.hset(key, field, JSON.stringify(value));
}
async hget(key, field) {
const value = await this.client.hget(key, field);
return value ? JSON.parse(value) : null;
}
async hdel(key, field) {
return await this.client.hdel(key, field);
}
async hgetall(key) {
const data = await this.client.hgetall(key);
const result = {};
for (const [field, value] of Object.entries(data)) {
result[field] = JSON.parse(value);
}
return result;
}
// List operations
async lpush(key, value) {
return await this.client.lpush(key, JSON.stringify(value));
}
async rpush(key, value) {
return await this.client.rpush(key, JSON.stringify(value));
}
async lrange(key, start, stop) {
const items = await this.client.lrange(key, start, stop);
return items.map(item => JSON.parse(item));
}
async ltrim(key, start, stop) {
return await this.client.ltrim(key, start, stop);
}
// Set operations
async sadd(key, member) {
return await this.client.sadd(key, JSON.stringify(member));
}
async srem(key, member) {
return await this.client.srem(key, JSON.stringify(member));
}
async smembers(key) {
const members = await this.client.smembers(key);
return members.map(member => JSON.parse(member));
}
async sismember(key, member) {
return await this.client.sismember(key, JSON.stringify(member));
}
// Expiry operations
async expire(key, seconds) {
return await this.client.expire(key, seconds);
}
async ttl(key) {
return await this.client.ttl(key);
}
}