feat: 完成配置中心重构和命名规范优化
- 重构config层为配置中心架构,支持动态配置管理 - 统一core层命名规范(event-bus→event, circuit-breaker→breaker, domain-sdk→sdk) - 修复数据库连接配置路径问题 - 实现配置中心完整功能:系统配置、动态配置、配置验证、统计 - 优化目录结构,为微服务架构做准备 - 修复TypeScript编译错误和依赖注入问题
This commit is contained in:
347
wwjcloud/src/config/core/appConfig.ts
Normal file
347
wwjcloud/src/config/core/appConfig.ts
Normal file
@@ -0,0 +1,347 @@
|
||||
/**
|
||||
* 应用配置中心
|
||||
* 集中管理所有配置,避免分散的 process.env 调用
|
||||
*/
|
||||
|
||||
export interface AppConfig {
|
||||
// 应用基础配置
|
||||
app: {
|
||||
name: string;
|
||||
version: string;
|
||||
port: number;
|
||||
environment: string;
|
||||
timezone: string;
|
||||
};
|
||||
|
||||
// 数据库配置
|
||||
database: {
|
||||
host: string;
|
||||
port: number;
|
||||
username: string;
|
||||
password: string;
|
||||
database: string;
|
||||
synchronize: boolean;
|
||||
logging: boolean;
|
||||
};
|
||||
|
||||
// Redis 配置
|
||||
redis: {
|
||||
host: string;
|
||||
port: number;
|
||||
password: string;
|
||||
db: number;
|
||||
keyPrefix: string;
|
||||
};
|
||||
|
||||
// Kafka 配置
|
||||
kafka: {
|
||||
clientId: string;
|
||||
brokers: string[];
|
||||
groupId: string;
|
||||
topicPrefix: string;
|
||||
};
|
||||
|
||||
// JWT 配置
|
||||
jwt: {
|
||||
secret: string;
|
||||
expiresIn: string;
|
||||
algorithm: string;
|
||||
};
|
||||
|
||||
// 缓存配置
|
||||
cache: {
|
||||
ttl: number;
|
||||
maxItems: number;
|
||||
prefix: string;
|
||||
};
|
||||
|
||||
// 日志配置
|
||||
logging: {
|
||||
level: string;
|
||||
format: string;
|
||||
filename?: string;
|
||||
};
|
||||
|
||||
// 文件上传配置
|
||||
upload: {
|
||||
path: string;
|
||||
maxSize: number;
|
||||
allowedTypes: string[];
|
||||
};
|
||||
|
||||
// 限流配置
|
||||
throttle: {
|
||||
ttl: number;
|
||||
limit: number;
|
||||
};
|
||||
|
||||
// 第三方服务配置
|
||||
thirdParty: {
|
||||
storage: {
|
||||
provider: string;
|
||||
config: Record<string, any>;
|
||||
};
|
||||
payment: {
|
||||
provider: string;
|
||||
config: Record<string, any>;
|
||||
};
|
||||
sms: {
|
||||
provider: string;
|
||||
config: Record<string, any>;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认配置
|
||||
*/
|
||||
const defaultConfig: AppConfig = {
|
||||
app: {
|
||||
name: 'WWJCloud Backend',
|
||||
version: '1.0.0',
|
||||
port: 3001,
|
||||
environment: 'development',
|
||||
timezone: 'Asia/Shanghai',
|
||||
},
|
||||
database: {
|
||||
host: 'localhost',
|
||||
port: 3306,
|
||||
username: 'root',
|
||||
password: '123456',
|
||||
database: 'wwjcloud',
|
||||
synchronize: false,
|
||||
logging: true,
|
||||
},
|
||||
redis: {
|
||||
host: 'localhost',
|
||||
port: 6379,
|
||||
password: '',
|
||||
db: 0,
|
||||
keyPrefix: 'wwjcloud:',
|
||||
},
|
||||
kafka: {
|
||||
clientId: 'wwjcloud-backend',
|
||||
brokers: ['localhost:9092'],
|
||||
groupId: 'wwjcloud-group',
|
||||
topicPrefix: 'wwjcloud.',
|
||||
},
|
||||
jwt: {
|
||||
secret: 'your-secret-key',
|
||||
expiresIn: '24h',
|
||||
algorithm: 'HS256',
|
||||
},
|
||||
cache: {
|
||||
ttl: 3600,
|
||||
maxItems: 1000,
|
||||
prefix: 'cache:',
|
||||
},
|
||||
logging: {
|
||||
level: 'info',
|
||||
format: 'json',
|
||||
filename: 'logs/app.log',
|
||||
},
|
||||
upload: {
|
||||
path: 'uploads/',
|
||||
maxSize: 10 * 1024 * 1024, // 10MB
|
||||
allowedTypes: ['jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx'],
|
||||
},
|
||||
throttle: {
|
||||
ttl: 60,
|
||||
limit: 100,
|
||||
},
|
||||
thirdParty: {
|
||||
storage: {
|
||||
provider: 'local',
|
||||
config: {},
|
||||
},
|
||||
payment: {
|
||||
provider: 'mock',
|
||||
config: {},
|
||||
},
|
||||
sms: {
|
||||
provider: 'mock',
|
||||
config: {},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* 环境变量配置加载器
|
||||
*/
|
||||
function loadFromEnv(): Partial<AppConfig> {
|
||||
return {
|
||||
app: {
|
||||
name: process.env.APP_NAME || defaultConfig.app.name,
|
||||
version: process.env.APP_VERSION || defaultConfig.app.version,
|
||||
port: parseInt(process.env.PORT || String(defaultConfig.app.port), 10),
|
||||
environment: process.env.NODE_ENV || defaultConfig.app.environment,
|
||||
timezone: process.env.TZ || defaultConfig.app.timezone,
|
||||
},
|
||||
database: {
|
||||
host: process.env.DB_HOST || defaultConfig.database.host,
|
||||
port: parseInt(process.env.DB_PORT || String(defaultConfig.database.port), 10),
|
||||
username: process.env.DB_USERNAME || defaultConfig.database.username,
|
||||
password: process.env.DB_PASSWORD || defaultConfig.database.password,
|
||||
database: process.env.DB_DATABASE || defaultConfig.database.database,
|
||||
synchronize: process.env.DB_SYNC === 'true',
|
||||
logging: process.env.DB_LOGGING === 'true',
|
||||
},
|
||||
redis: {
|
||||
host: process.env.REDIS_HOST || defaultConfig.redis.host,
|
||||
port: parseInt(process.env.REDIS_PORT || String(defaultConfig.redis.port), 10),
|
||||
password: process.env.REDIS_PASSWORD || defaultConfig.redis.password,
|
||||
db: parseInt(process.env.REDIS_DB || String(defaultConfig.redis.db), 10),
|
||||
keyPrefix: process.env.REDIS_KEY_PREFIX || defaultConfig.redis.keyPrefix,
|
||||
},
|
||||
kafka: {
|
||||
clientId: process.env.KAFKA_CLIENT_ID || defaultConfig.kafka.clientId,
|
||||
brokers: (process.env.KAFKA_BROKERS || defaultConfig.kafka.brokers.join(',')).split(','),
|
||||
groupId: process.env.KAFKA_GROUP_ID || defaultConfig.kafka.groupId,
|
||||
topicPrefix: process.env.KAFKA_TOPIC_PREFIX || defaultConfig.kafka.topicPrefix,
|
||||
},
|
||||
jwt: {
|
||||
secret: process.env.JWT_SECRET || defaultConfig.jwt.secret,
|
||||
expiresIn: process.env.JWT_EXPIRES_IN || defaultConfig.jwt.expiresIn,
|
||||
algorithm: process.env.JWT_ALGORITHM || defaultConfig.jwt.algorithm,
|
||||
},
|
||||
cache: {
|
||||
ttl: parseInt(process.env.CACHE_TTL || String(defaultConfig.cache.ttl), 10),
|
||||
maxItems: parseInt(process.env.CACHE_MAX_ITEMS || String(defaultConfig.cache.maxItems), 10),
|
||||
prefix: process.env.CACHE_PREFIX || defaultConfig.cache.prefix,
|
||||
},
|
||||
logging: {
|
||||
level: process.env.LOG_LEVEL || defaultConfig.logging.level,
|
||||
format: process.env.LOG_FORMAT || defaultConfig.logging.format,
|
||||
filename: process.env.LOG_FILENAME,
|
||||
},
|
||||
upload: {
|
||||
path: process.env.UPLOAD_PATH || defaultConfig.upload.path,
|
||||
maxSize: parseInt(process.env.UPLOAD_MAX_SIZE || String(defaultConfig.upload.maxSize), 10),
|
||||
allowedTypes: process.env.UPLOAD_ALLOWED_TYPES?.split(',') || defaultConfig.upload.allowedTypes,
|
||||
},
|
||||
throttle: {
|
||||
ttl: parseInt(process.env.THROTTLE_TTL || String(defaultConfig.throttle.ttl), 10),
|
||||
limit: parseInt(process.env.THROTTLE_LIMIT || String(defaultConfig.throttle.limit), 10),
|
||||
},
|
||||
thirdParty: {
|
||||
storage: {
|
||||
provider: process.env.STORAGE_PROVIDER || defaultConfig.thirdParty.storage.provider,
|
||||
config: JSON.parse(process.env.STORAGE_CONFIG || '{}'),
|
||||
},
|
||||
payment: {
|
||||
provider: process.env.PAYMENT_PROVIDER || defaultConfig.thirdParty.payment.provider,
|
||||
config: JSON.parse(process.env.PAYMENT_CONFIG || '{}'),
|
||||
},
|
||||
sms: {
|
||||
provider: process.env.SMS_PROVIDER || defaultConfig.thirdParty.sms.provider,
|
||||
config: JSON.parse(process.env.SMS_CONFIG || '{}'),
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置合并函数
|
||||
*/
|
||||
function mergeConfig(defaultConfig: AppConfig, envConfig: Partial<AppConfig>): AppConfig {
|
||||
return {
|
||||
...defaultConfig,
|
||||
...envConfig,
|
||||
app: { ...defaultConfig.app, ...envConfig.app },
|
||||
database: { ...defaultConfig.database, ...envConfig.database },
|
||||
redis: { ...defaultConfig.redis, ...envConfig.redis },
|
||||
kafka: { ...defaultConfig.kafka, ...envConfig.kafka },
|
||||
jwt: { ...defaultConfig.jwt, ...envConfig.jwt },
|
||||
cache: { ...defaultConfig.cache, ...envConfig.cache },
|
||||
logging: { ...defaultConfig.logging, ...envConfig.logging },
|
||||
upload: { ...defaultConfig.upload, ...envConfig.upload },
|
||||
throttle: { ...defaultConfig.throttle, ...envConfig.throttle },
|
||||
thirdParty: {
|
||||
storage: { ...defaultConfig.thirdParty.storage, ...envConfig.thirdParty?.storage },
|
||||
payment: { ...defaultConfig.thirdParty.payment, ...envConfig.thirdParty?.payment },
|
||||
sms: { ...defaultConfig.thirdParty.sms, ...envConfig.thirdParty?.sms },
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用配置实例
|
||||
*/
|
||||
export const appConfig: AppConfig = mergeConfig(defaultConfig, loadFromEnv());
|
||||
|
||||
/**
|
||||
* 配置获取工具函数
|
||||
*/
|
||||
export const config = {
|
||||
// 获取完整配置
|
||||
get(): AppConfig {
|
||||
return appConfig;
|
||||
},
|
||||
|
||||
// 获取应用配置
|
||||
getApp() {
|
||||
return appConfig.app;
|
||||
},
|
||||
|
||||
// 获取数据库配置
|
||||
getDatabase() {
|
||||
return appConfig.database;
|
||||
},
|
||||
|
||||
// 获取 Redis 配置
|
||||
getRedis() {
|
||||
return appConfig.redis;
|
||||
},
|
||||
|
||||
// 获取 Kafka 配置
|
||||
getKafka() {
|
||||
return appConfig.kafka;
|
||||
},
|
||||
|
||||
// 获取 JWT 配置
|
||||
getJwt() {
|
||||
return appConfig.jwt;
|
||||
},
|
||||
|
||||
// 获取缓存配置
|
||||
getCache() {
|
||||
return appConfig.cache;
|
||||
},
|
||||
|
||||
// 获取日志配置
|
||||
getLogging() {
|
||||
return appConfig.logging;
|
||||
},
|
||||
|
||||
// 获取上传配置
|
||||
getUpload() {
|
||||
return appConfig.upload;
|
||||
},
|
||||
|
||||
// 获取限流配置
|
||||
getThrottle() {
|
||||
return appConfig.throttle;
|
||||
},
|
||||
|
||||
// 获取第三方服务配置
|
||||
getThirdParty() {
|
||||
return appConfig.thirdParty;
|
||||
},
|
||||
|
||||
// 检查是否为生产环境
|
||||
isProduction(): boolean {
|
||||
return appConfig.app.environment === 'production';
|
||||
},
|
||||
|
||||
// 检查是否为开发环境
|
||||
isDevelopment(): boolean {
|
||||
return appConfig.app.environment === 'development';
|
||||
},
|
||||
|
||||
// 检查是否为测试环境
|
||||
isTest(): boolean {
|
||||
return appConfig.app.environment === 'test';
|
||||
},
|
||||
};
|
||||
|
||||
export default appConfig;
|
||||
35
wwjcloud/src/config/core/configModule.ts
Normal file
35
wwjcloud/src/config/core/configModule.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { ConfigModule as NestConfigModule } from '@nestjs/config';
|
||||
import { ConfigController } from '../controllers/configController';
|
||||
import { ConfigCenterService } from '../services/configCenterService';
|
||||
import { ConfigValidationService } from '../services/configValidationService';
|
||||
import { DynamicConfigService } from '../services/dynamicConfigService';
|
||||
import { DocsNavigationController } from '../controllers/docsNavigationController';
|
||||
import { appConfig } from './appConfig';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
NestConfigModule.forRoot({
|
||||
isGlobal: true,
|
||||
load: [() => appConfig],
|
||||
envFilePath: ['.env.local', '.env.development', '.env.production', '.env'],
|
||||
}),
|
||||
],
|
||||
controllers: [ConfigController, DocsNavigationController],
|
||||
providers: [
|
||||
ConfigCenterService,
|
||||
ConfigValidationService,
|
||||
DynamicConfigService,
|
||||
{
|
||||
provide: 'APP_CONFIG',
|
||||
useValue: appConfig,
|
||||
},
|
||||
],
|
||||
exports: [
|
||||
ConfigCenterService,
|
||||
ConfigValidationService,
|
||||
DynamicConfigService,
|
||||
'APP_CONFIG',
|
||||
],
|
||||
})
|
||||
export class ConfigModule {}
|
||||
4
wwjcloud/src/config/core/index.ts
Normal file
4
wwjcloud/src/config/core/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
// 核心配置导出
|
||||
export { appConfig, config } from './appConfig';
|
||||
export type { AppConfig } from './appConfig';
|
||||
export { ConfigModule } from './configModule';
|
||||
Reference in New Issue
Block a user