chore: 初始化项目基础结构和资源文件
- 添加项目图标文件(app-icon.png、各平台图标) - 配置开发环境文件(.env、.nvmrc、.npmrc) - 添加静态资源文件(背景图片、字体、音频) - 初始化Tauri后端结构(build.rs、main.rs、模块文件) - 配置前端项目结构(TypeScript、Vue组件、样式) - 添加Node.js API服务基础结构 - 配置构建和开发工具(vite、prettier、gitignore)
This commit is contained in:
159
node_api/src/plugins/nacos/nacos-config.service.ts
Normal file
159
node_api/src/plugins/nacos/nacos-config.service.ts
Normal file
@ -0,0 +1,159 @@
|
||||
/**
|
||||
* Nacos 配置模块
|
||||
* 从 Nacos 配置中心加载和管理配置
|
||||
*/
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import * as nacos from 'nacos';
|
||||
import * as yaml from 'js-yaml';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { LoggerService } from '../logger/logger.service';
|
||||
|
||||
/** 声网应用配置接口 */
|
||||
export interface AgoraAppConfig {
|
||||
appId: string;
|
||||
appCertificate: string;
|
||||
}
|
||||
|
||||
/** 声网配置接口 */
|
||||
export interface AgoraConfig {
|
||||
apps: Record<string, AgoraAppConfig>;
|
||||
defaultAppId: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nacos 配置服务
|
||||
* 提供配置的读取和缓存功能
|
||||
*/
|
||||
@Injectable()
|
||||
export class NacosConfigService {
|
||||
private readonly logger = new LoggerService();
|
||||
private agoraConfig: AgoraConfig | null = null;
|
||||
private configClient!: nacos.NacosConfigClient;
|
||||
|
||||
constructor(private readonly configService: ConfigService) {
|
||||
this.initNacosClient();
|
||||
this.loadAgoraConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化 Nacos 客户端
|
||||
*/
|
||||
private initNacosClient(): void {
|
||||
const serverAddr = this.configService.get<string>('NACOS_SERVER_ADDR');
|
||||
const username = this.configService.get<string>('NACOS_USERNAME');
|
||||
const password = this.configService.get<string>('NACOS_PASSWORD');
|
||||
const namespace = this.configService.get<string>('NACOS_NAMESPACE_ID');
|
||||
|
||||
if (!serverAddr) {
|
||||
throw new Error('NACOS_SERVER_ADDR 环境变量未配置');
|
||||
}
|
||||
|
||||
try {
|
||||
// 创建 Nacos 配置客户端
|
||||
this.configClient = new nacos.NacosConfigClient({
|
||||
serverAddr,
|
||||
username: username || undefined,
|
||||
password: password || undefined,
|
||||
namespace: namespace || undefined,
|
||||
});
|
||||
|
||||
this.logger.info(`Nacos 客户端初始化成功,服务器地址:${serverAddr}`);
|
||||
} catch (error) {
|
||||
this.logger.error('Nacos 客户端初始化失败:', error);
|
||||
throw new Error(`Nacos 客户端初始化失败:${error.message}`, { cause: error });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 Nacos 加载声网配置文件
|
||||
*/
|
||||
private async loadAgoraConfig(): Promise<void> {
|
||||
try {
|
||||
const dataId = this.configService.get<string>('NACOS_DATA_ID');
|
||||
const group = this.configService.get<string>('NACOS_GROUP') || 'DEFAULT_GROUP';
|
||||
|
||||
// 从 Nacos 获取配置内容
|
||||
const configContent = await this.configClient.getConfig(
|
||||
this.configService.get<string>('NACOS_DATA_ID')!,
|
||||
this.configService.get<string>('NACOS_GROUP') || 'DEFAULT_GROUP'
|
||||
);
|
||||
|
||||
if (!configContent) {
|
||||
throw new Error(`Nacos 中未找到配置:dataId=${dataId}, group=${group}`);
|
||||
}
|
||||
|
||||
// 解析 YAML 配置
|
||||
const config = yaml.load(configContent) as AgoraConfig;
|
||||
|
||||
if (!config.apps || !config.defaultAppId) {
|
||||
throw new Error('Nacos 配置格式错误:必须包含 apps 和 defaultAppId 字段');
|
||||
}
|
||||
|
||||
if (!config.apps[config.defaultAppId]) {
|
||||
throw new Error(`Nacos 配置错误:defaultAppId '${config.defaultAppId}' 在 apps 中不存在`);
|
||||
}
|
||||
|
||||
this.agoraConfig = config;
|
||||
this.logger.info(`声网配置从 Nacos 加载成功,默认应用:${config.defaultAppId}`);
|
||||
|
||||
// 监听配置变化(可选,实现热更新)
|
||||
try {
|
||||
// 使用已解析的 dataId 和 group,传入对象格式
|
||||
this.configClient.subscribe({ dataId, group }, (content: string) => {
|
||||
this.logger.info('检测到 Nacos 配置变更,重新加载...');
|
||||
try {
|
||||
const newConfig = yaml.load(content) as AgoraConfig;
|
||||
this.agoraConfig = newConfig;
|
||||
this.logger.info(`声网配置已更新,默认应用:${newConfig.defaultAppId}`);
|
||||
} catch (error) {
|
||||
this.logger.error('配置更新失败', error);
|
||||
}
|
||||
});
|
||||
} catch {
|
||||
// 配置监听失败不影响主流程,记录警告日志
|
||||
this.logger.warn('Nacos 配置监听器设置失败,但配置已成功加载');
|
||||
}
|
||||
} catch (error) {
|
||||
this.logger.error('从 Nacos 加载声网配置失败', error);
|
||||
throw new Error(`从 Nacos 加载声网配置失败:${error.message}`, { cause: error });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取声网配置
|
||||
* @returns {AgoraConfig} 声网配置对象
|
||||
*/
|
||||
getAgoraConfig(): AgoraConfig {
|
||||
if (!this.agoraConfig) {
|
||||
throw new Error('声网配置未加载,请检查 Nacos 配置是否正确且格式有效');
|
||||
}
|
||||
return this.agoraConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定的声网应用配置
|
||||
* @param {string} appId - 应用 ID(可选,默认使用 defaultAppId)
|
||||
* @returns {AgoraAppConfig} 声网应用配置
|
||||
*/
|
||||
getAgoraAppConfig(appId?: string): AgoraAppConfig {
|
||||
const agoraConfig = this.getAgoraConfig();
|
||||
const targetAppId = appId || agoraConfig.defaultAppId;
|
||||
|
||||
const appConfig = agoraConfig.apps[targetAppId];
|
||||
if (!appConfig) {
|
||||
const errorMsg = `未找到声网应用配置:${targetAppId}。可用的应用 ID: ${Object.keys(agoraConfig.apps).join(', ')}`;
|
||||
this.logger.error(errorMsg);
|
||||
throw new Error(errorMsg);
|
||||
}
|
||||
|
||||
return appConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取默认的声网应用配置
|
||||
* @returns {AgoraAppConfig} 默认声网应用配置
|
||||
*/
|
||||
getDefaultAgoraAppConfig(): AgoraAppConfig {
|
||||
return this.getAgoraAppConfig();
|
||||
}
|
||||
}
|
||||
14
node_api/src/plugins/nacos/nacos.module.ts
Normal file
14
node_api/src/plugins/nacos/nacos.module.ts
Normal file
@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Nacos 配置模块
|
||||
*/
|
||||
import { Global, Module } from '@nestjs/common';
|
||||
import { ConfigModule } from '@nestjs/config';
|
||||
import { NacosConfigService } from './nacos-config.service';
|
||||
|
||||
@Global()
|
||||
@Module({
|
||||
imports: [ConfigModule],
|
||||
providers: [NacosConfigService],
|
||||
exports: [NacosConfigService],
|
||||
})
|
||||
export class NacosConfigModule {}
|
||||
Reference in New Issue
Block a user