Files
wwjcloud-nest-v1/wwjcloud/src/config/services/dynamicConfigService.ts

145 lines
3.7 KiB
TypeScript
Raw Normal View History

import { Injectable, Logger } from '@nestjs/common';
export interface DynamicConfig {
key: string;
value: any;
description?: string;
type?: 'string' | 'number' | 'boolean' | 'json';
category?: string;
isPublic?: boolean;
createdAt?: Date;
updatedAt?: Date;
}
@Injectable()
export class DynamicConfigService {
private readonly logger = new Logger(DynamicConfigService.name);
private readonly configs = new Map<string, DynamicConfig>();
constructor() {
// 初始化一些默认配置
this.initializeDefaultConfigs();
}
private initializeDefaultConfigs() {
const defaultConfigs: DynamicConfig[] = [
{
key: 'system.maintenance',
value: false,
description: '系统维护模式',
type: 'boolean',
category: 'system',
isPublic: true,
createdAt: new Date(),
updatedAt: new Date(),
},
{
key: 'system.debug',
value: process.env.NODE_ENV === 'development',
description: '调试模式',
type: 'boolean',
category: 'system',
isPublic: false,
createdAt: new Date(),
updatedAt: new Date(),
},
];
defaultConfigs.forEach(config => {
this.configs.set(config.key, config);
});
}
/**
*
*/
async getConfig(key: string): Promise<DynamicConfig | null> {
return this.configs.get(key) || null;
}
/**
*
*/
async getConfigList(category?: string): Promise<DynamicConfig[]> {
const configs = Array.from(this.configs.values());
if (category) {
return configs.filter(config => config.category === category);
}
return configs;
}
/**
*
*/
async setConfig(
key: string,
value: any,
options: {
description?: string;
type?: 'string' | 'number' | 'boolean' | 'json';
category?: string;
isPublic?: boolean;
} = {}
): Promise<void> {
const existingConfig = this.configs.get(key);
const now = new Date();
const config: DynamicConfig = {
key,
value,
description: options.description || existingConfig?.description,
type: options.type || this.inferType(value) || existingConfig?.type || 'string',
category: options.category || existingConfig?.category || 'general',
isPublic: options.isPublic !== undefined ? options.isPublic : existingConfig?.isPublic ?? true,
createdAt: existingConfig?.createdAt || now,
updatedAt: now,
};
this.configs.set(key, config);
this.logger.log(`动态配置已更新: ${key} = ${value}`);
}
/**
*
*/
async deleteConfig(key: string): Promise<void> {
if (this.configs.has(key)) {
this.configs.delete(key);
this.logger.log(`动态配置已删除: ${key}`);
}
}
/**
*
*/
private inferType(value: any): 'string' | 'number' | 'boolean' | 'json' {
if (typeof value === 'string') return 'string';
if (typeof value === 'number') return 'number';
if (typeof value === 'boolean') return 'boolean';
if (typeof value === 'object') return 'json';
return 'string';
}
/**
*
*/
async getConfigStats() {
const configs = Array.from(this.configs.values());
const categories = [...new Set(configs.map(c => c.category))];
return {
total: configs.length,
categories: categories.length,
public: configs.filter(c => c.isPublic).length,
private: configs.filter(c => !c.isPublic).length,
byCategory: categories.reduce((acc, category) => {
if (category) {
acc[category] = configs.filter(c => c.category === category).length;
}
return acc;
}, {} as Record<string, number>),
};
}
}