init: 整合项目(dashboard + www + docs)

This commit is contained in:
eafonyang
2026-07-30 11:23:50 +08:00
commit 99ab6cc4f4
435 changed files with 61037 additions and 0 deletions
+23
View File
@@ -0,0 +1,23 @@
const { Sequelize } = require('sequelize');
const { isDevelopment } = require('./env');
const sequelize = new Sequelize(
process.env.DATABASE_NAME || 'audio',
process.env.DATABASE_USER || 'root',
process.env.DATABASE_PASSWORD || 'root123',
{
host: process.env.DATABASE_HOST || 'localhost',
port: parseInt(process.env.DATABASE_PORT || '3306', 10),
dialect: 'mysql',
dialectOptions: {
charset: 'utf8mb4',
},
logging: isDevelopment ? (msg) => console.log(msg) : false,
define: {
timestamps: false,
freezeTableName: true,
},
}
);
module.exports = sequelize;
+12
View File
@@ -0,0 +1,12 @@
/**
* 统一环境判断工具
* 通过 APP_ENV 环境变量区分开发/正式环境
* - development: 本地开发
* - production: 正式环境(Docker 部署)
*/
const APP_ENV = (process.env.APP_ENV || 'development').trim().toLowerCase();
const isDevelopment = APP_ENV === 'development';
const isProduction = APP_ENV === 'production';
module.exports = { APP_ENV, isDevelopment, isProduction };
+14
View File
@@ -0,0 +1,14 @@
/**
* 统一从项目根目录加载 .envdashboard/.env
* - 本地开发:读取根目录 .env
* - Docker:由 compose env_file 注入,容器内无 .env 文件,不覆盖已有环境变量
*/
const path = require('path');
const fs = require('fs');
const dotenv = require('dotenv');
const rootEnvPath = path.resolve(__dirname, '../../../.env');
if (fs.existsSync(rootEnvPath)) {
dotenv.config({ path: rootEnvPath });
}
+28
View File
@@ -0,0 +1,28 @@
const winston = require('winston');
const path = require('path');
const fs = require('fs');
const logsDir = path.join(__dirname, '..', '..', 'logs');
if (!fs.existsSync(logsDir)) {
fs.mkdirSync(logsDir, { recursive: true });
}
const logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
winston.format.printf(({ timestamp, level, message, ...meta }) => {
const metaStr = Object.keys(meta).length ? ` ${JSON.stringify(meta)}` : '';
return `${timestamp} - ${level} - ${message}${metaStr}`;
})
),
transports: [
new winston.transports.Console(),
new winston.transports.File({
filename: path.join(logsDir, 'app.log'),
encoding: 'utf-8',
}),
],
});
module.exports = logger;
+31
View File
@@ -0,0 +1,31 @@
const Redis = require('ioredis');
const logger = require('./logger');
const REDIS_HOST = process.env.REDIS_HOST || '127.0.0.1';
const REDIS_PORT = parseInt(process.env.REDIS_PORT || '6379', 10);
const REDIS_PASSWORD = process.env.REDIS_PASSWORD || '';
const REDIS_EQ_DB = parseInt(process.env.REDIS_EQ_DB || '1', 10);
let eqCacheClient = null;
function getEqCacheRedis() {
if (!eqCacheClient) {
const options = {
host: REDIS_HOST,
port: REDIS_PORT,
db: REDIS_EQ_DB,
maxRetriesPerRequest: 2,
connectTimeout: 10000,
};
if (REDIS_PASSWORD) {
options.password = REDIS_PASSWORD;
}
eqCacheClient = new Redis(options);
eqCacheClient.on('error', (err) => {
logger.error(`Redis EQ cache error: ${err.message}`);
});
}
return eqCacheClient;
}
module.exports = { getEqCacheRedis };