320 lines
14 KiB
JavaScript
320 lines
14 KiB
JavaScript
const mysql = require('mysql2/promise');
|
|
|
|
// 資料庫配置
|
|
const dbConfig = {
|
|
host: process.env.DB_HOST || 'mysql.theaken.com',
|
|
port: parseInt(process.env.DB_PORT || '33306'),
|
|
user: process.env.DB_USER || 'root',
|
|
password: process.env.DB_PASSWORD || 'zh6161168',
|
|
database: process.env.DB_NAME || 'db_AI_scoring',
|
|
charset: 'utf8mb4',
|
|
timezone: '+08:00',
|
|
};
|
|
|
|
async function initializeDatabase() {
|
|
let connection;
|
|
|
|
try {
|
|
console.log('🔄 正在連接資料庫...');
|
|
|
|
// 先連接到 MySQL 伺服器(不指定資料庫)
|
|
const serverConnection = await mysql.createConnection({
|
|
host: dbConfig.host,
|
|
port: dbConfig.port,
|
|
user: dbConfig.user,
|
|
password: dbConfig.password,
|
|
charset: dbConfig.charset,
|
|
timezone: dbConfig.timezone,
|
|
});
|
|
|
|
console.log('✅ 成功連接到 MySQL 伺服器');
|
|
|
|
// 1. 建立資料庫
|
|
console.log('🔄 正在建立資料庫...');
|
|
await serverConnection.query(`
|
|
CREATE DATABASE IF NOT EXISTS \`db_AI_scoring\`
|
|
CHARACTER SET utf8mb4
|
|
COLLATE utf8mb4_unicode_ci
|
|
`);
|
|
console.log('✅ 資料庫建立完成');
|
|
|
|
// 2. 選擇資料庫
|
|
await serverConnection.query('USE `db_AI_scoring`');
|
|
console.log('✅ 已選擇資料庫');
|
|
|
|
// 3. 建立用戶表
|
|
console.log('🔄 正在建立用戶表...');
|
|
await serverConnection.query(`
|
|
CREATE TABLE IF NOT EXISTS \`users\` (
|
|
\`id\` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
|
\`email\` varchar(255) NOT NULL UNIQUE,
|
|
\`username\` varchar(100) NOT NULL UNIQUE,
|
|
\`password_hash\` varchar(255) NOT NULL,
|
|
\`full_name\` varchar(255) DEFAULT NULL,
|
|
\`avatar_url\` varchar(500) DEFAULT NULL,
|
|
\`role\` enum('admin', 'user') DEFAULT 'user',
|
|
\`is_active\` tinyint(1) DEFAULT 1,
|
|
\`email_verified_at\` timestamp NULL DEFAULT NULL,
|
|
\`last_login_at\` timestamp NULL DEFAULT NULL,
|
|
\`created_at\` timestamp DEFAULT CURRENT_TIMESTAMP,
|
|
\`updated_at\` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (\`id\`),
|
|
KEY \`idx_email\` (\`email\`),
|
|
KEY \`idx_username\` (\`username\`),
|
|
KEY \`idx_created_at\` (\`created_at\`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
`);
|
|
console.log('✅ 用戶表建立完成');
|
|
|
|
// 4. 建立評分標準模板表
|
|
console.log('🔄 正在建立評分標準模板表...');
|
|
await serverConnection.query(`
|
|
CREATE TABLE IF NOT EXISTS \`criteria_templates\` (
|
|
\`id\` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
|
\`user_id\` bigint(20) unsigned NOT NULL,
|
|
\`name\` varchar(255) NOT NULL,
|
|
\`description\` text DEFAULT NULL,
|
|
\`is_default\` tinyint(1) DEFAULT 0,
|
|
\`is_public\` tinyint(1) DEFAULT 0,
|
|
\`total_weight\` decimal(5,2) DEFAULT 100.00,
|
|
\`created_at\` timestamp DEFAULT CURRENT_TIMESTAMP,
|
|
\`updated_at\` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (\`id\`),
|
|
KEY \`idx_user_id\` (\`user_id\`),
|
|
KEY \`idx_is_default\` (\`is_default\`),
|
|
KEY \`idx_is_public\` (\`is_public\`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
`);
|
|
console.log('✅ 評分標準模板表建立完成');
|
|
|
|
// 5. 建立評分項目表
|
|
console.log('🔄 正在建立評分項目表...');
|
|
await serverConnection.query(`
|
|
CREATE TABLE IF NOT EXISTS \`criteria_items\` (
|
|
\`id\` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
|
\`template_id\` bigint(20) unsigned NOT NULL,
|
|
\`name\` varchar(255) NOT NULL,
|
|
\`description\` text DEFAULT NULL,
|
|
\`weight\` decimal(5,2) NOT NULL,
|
|
\`max_score\` decimal(5,2) DEFAULT 10.00,
|
|
\`sort_order\` int(11) DEFAULT 0,
|
|
\`created_at\` timestamp DEFAULT CURRENT_TIMESTAMP,
|
|
\`updated_at\` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (\`id\`),
|
|
KEY \`idx_template_id\` (\`template_id\`),
|
|
KEY \`idx_sort_order\` (\`sort_order\`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
`);
|
|
console.log('✅ 評分項目表建立完成');
|
|
|
|
// 6. 建立專案表
|
|
console.log('🔄 正在建立專案表...');
|
|
await serverConnection.query(`
|
|
CREATE TABLE IF NOT EXISTS \`projects\` (
|
|
\`id\` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
|
\`user_id\` bigint(20) unsigned NOT NULL,
|
|
\`template_id\` bigint(20) unsigned NOT NULL,
|
|
\`title\` varchar(255) NOT NULL,
|
|
\`description\` text DEFAULT NULL,
|
|
\`status\` enum('draft', 'uploading', 'analyzing', 'completed', 'failed') DEFAULT 'draft',
|
|
\`analysis_started_at\` timestamp NULL DEFAULT NULL,
|
|
\`analysis_completed_at\` timestamp NULL DEFAULT NULL,
|
|
\`created_at\` timestamp DEFAULT CURRENT_TIMESTAMP,
|
|
\`updated_at\` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (\`id\`),
|
|
KEY \`idx_user_id\` (\`user_id\`),
|
|
KEY \`idx_template_id\` (\`template_id\`),
|
|
KEY \`idx_status\` (\`status\`),
|
|
KEY \`idx_created_at\` (\`created_at\`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
`);
|
|
console.log('✅ 專案表建立完成');
|
|
|
|
// 7. 建立專案文件表
|
|
console.log('🔄 正在建立專案文件表...');
|
|
await serverConnection.query(`
|
|
CREATE TABLE IF NOT EXISTS \`project_files\` (
|
|
\`id\` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
|
\`project_id\` bigint(20) unsigned NOT NULL,
|
|
\`original_name\` varchar(255) NOT NULL,
|
|
\`file_name\` varchar(255) NOT NULL,
|
|
\`file_path\` varchar(500) NOT NULL,
|
|
\`file_size\` bigint(20) unsigned NOT NULL,
|
|
\`file_type\` varchar(100) NOT NULL,
|
|
\`mime_type\` varchar(100) NOT NULL,
|
|
\`upload_status\` enum('uploading', 'completed', 'failed') DEFAULT 'uploading',
|
|
\`upload_progress\` decimal(5,2) DEFAULT 0.00,
|
|
\`created_at\` timestamp DEFAULT CURRENT_TIMESTAMP,
|
|
\`updated_at\` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (\`id\`),
|
|
KEY \`idx_project_id\` (\`project_id\`),
|
|
KEY \`idx_file_type\` (\`file_type\`),
|
|
KEY \`idx_upload_status\` (\`upload_status\`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
`);
|
|
console.log('✅ 專案文件表建立完成');
|
|
|
|
// 8. 建立專案網站表
|
|
console.log('🔄 正在建立專案網站表...');
|
|
await serverConnection.query(`
|
|
CREATE TABLE IF NOT EXISTS \`project_websites\` (
|
|
\`id\` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
|
\`project_id\` bigint(20) unsigned NOT NULL,
|
|
\`url\` varchar(500) NOT NULL,
|
|
\`title\` varchar(255) DEFAULT NULL,
|
|
\`description\` text DEFAULT NULL,
|
|
\`status\` enum('pending', 'analyzing', 'completed', 'failed') DEFAULT 'pending',
|
|
\`created_at\` timestamp DEFAULT CURRENT_TIMESTAMP,
|
|
\`updated_at\` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (\`id\`),
|
|
KEY \`idx_project_id\` (\`project_id\`),
|
|
KEY \`idx_status\` (\`status\`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
`);
|
|
console.log('✅ 專案網站表建立完成');
|
|
|
|
// 9. 建立評審記錄表
|
|
console.log('🔄 正在建立評審記錄表...');
|
|
await serverConnection.query(`
|
|
CREATE TABLE IF NOT EXISTS \`evaluations\` (
|
|
\`id\` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
|
\`project_id\` bigint(20) unsigned NOT NULL,
|
|
\`overall_score\` decimal(5,2) DEFAULT NULL,
|
|
\`max_possible_score\` decimal(5,2) DEFAULT 100.00,
|
|
\`grade\` varchar(10) DEFAULT NULL,
|
|
\`analysis_duration\` int(11) DEFAULT NULL,
|
|
\`ai_model_version\` varchar(50) DEFAULT NULL,
|
|
\`status\` enum('pending', 'analyzing', 'completed', 'failed') DEFAULT 'pending',
|
|
\`error_message\` text DEFAULT NULL,
|
|
\`created_at\` timestamp DEFAULT CURRENT_TIMESTAMP,
|
|
\`updated_at\` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (\`id\`),
|
|
KEY \`idx_project_id\` (\`project_id\`),
|
|
KEY \`idx_status\` (\`status\`),
|
|
KEY \`idx_created_at\` (\`created_at\`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
`);
|
|
console.log('✅ 評審記錄表建立完成');
|
|
|
|
// 10. 建立評分結果表
|
|
console.log('🔄 正在建立評分結果表...');
|
|
await serverConnection.query(`
|
|
CREATE TABLE IF NOT EXISTS \`evaluation_scores\` (
|
|
\`id\` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
|
\`evaluation_id\` bigint(20) unsigned NOT NULL,
|
|
\`criteria_item_id\` bigint(20) unsigned NOT NULL,
|
|
\`score\` decimal(5,2) NOT NULL,
|
|
\`max_score\` decimal(5,2) NOT NULL,
|
|
\`weight\` decimal(5,2) NOT NULL,
|
|
\`weighted_score\` decimal(5,2) NOT NULL,
|
|
\`percentage\` decimal(5,2) NOT NULL,
|
|
\`created_at\` timestamp DEFAULT CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (\`id\`),
|
|
KEY \`idx_evaluation_id\` (\`evaluation_id\`),
|
|
KEY \`idx_criteria_item_id\` (\`criteria_item_id\`),
|
|
UNIQUE KEY \`unique_evaluation_criteria\` (\`evaluation_id\`, \`criteria_item_id\`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
`);
|
|
console.log('✅ 評分結果表建立完成');
|
|
|
|
// 11. 建立評語表
|
|
console.log('🔄 正在建立評語表...');
|
|
await serverConnection.query(`
|
|
CREATE TABLE IF NOT EXISTS \`evaluation_feedback\` (
|
|
\`id\` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
|
\`evaluation_id\` bigint(20) unsigned NOT NULL,
|
|
\`criteria_item_id\` bigint(20) unsigned DEFAULT NULL,
|
|
\`feedback_type\` enum('overall', 'criteria', 'strength', 'improvement') NOT NULL,
|
|
\`content\` text NOT NULL,
|
|
\`sort_order\` int(11) DEFAULT 0,
|
|
\`created_at\` timestamp DEFAULT CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (\`id\`),
|
|
KEY \`idx_evaluation_id\` (\`evaluation_id\`),
|
|
KEY \`idx_criteria_item_id\` (\`criteria_item_id\`),
|
|
KEY \`idx_feedback_type\` (\`feedback_type\`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
`);
|
|
console.log('✅ 評語表建立完成');
|
|
|
|
// 12. 建立系統設定表
|
|
console.log('🔄 正在建立系統設定表...');
|
|
await serverConnection.query(`
|
|
CREATE TABLE IF NOT EXISTS \`system_settings\` (
|
|
\`id\` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
|
\`setting_key\` varchar(100) NOT NULL UNIQUE,
|
|
\`setting_value\` text DEFAULT NULL,
|
|
\`description\` varchar(255) DEFAULT NULL,
|
|
\`created_at\` timestamp DEFAULT CURRENT_TIMESTAMP,
|
|
\`updated_at\` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (\`id\`),
|
|
KEY \`idx_setting_key\` (\`setting_key\`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
`);
|
|
console.log('✅ 系統設定表建立完成');
|
|
|
|
// 13. 插入預設數據
|
|
console.log('🔄 正在插入預設數據...');
|
|
|
|
// 插入預設評分標準模板
|
|
await serverConnection.query(`
|
|
INSERT IGNORE INTO \`criteria_templates\` (\`user_id\`, \`name\`, \`description\`, \`is_default\`, \`is_public\`, \`total_weight\`)
|
|
VALUES (1, '預設評分標準', '系統預設的評分標準模板', 1, 1, 100.00)
|
|
`);
|
|
|
|
// 插入預設評分項目
|
|
await serverConnection.query(`
|
|
INSERT IGNORE INTO \`criteria_items\` (\`template_id\`, \`name\`, \`description\`, \`weight\`, \`max_score\`, \`sort_order\`) VALUES
|
|
(1, '內容品質', '內容的準確性、完整性和專業度', 25.00, 10.00, 1),
|
|
(1, '視覺設計', '版面設計、色彩搭配和視覺效果', 20.00, 10.00, 2),
|
|
(1, '邏輯結構', '內容組織的邏輯性和條理性', 20.00, 10.00, 3),
|
|
(1, '創新性', '創意思維和獨特觀點的展現', 15.00, 10.00, 4),
|
|
(1, '實用性', '內容的實際應用價值和可操作性', 20.00, 10.00, 5)
|
|
`);
|
|
|
|
// 插入系統設定
|
|
await serverConnection.query(`
|
|
INSERT IGNORE INTO \`system_settings\` (\`setting_key\`, \`setting_value\`, \`description\`) VALUES
|
|
('max_file_size', '104857600', '最大文件上傳大小(位元組)'),
|
|
('allowed_file_types', 'ppt,pptx,pdf,mp4,avi,mov,wmv,flv,webm', '允許上傳的文件類型'),
|
|
('ai_analysis_timeout', '300', 'AI 分析超時時間(秒)'),
|
|
('max_concurrent_analyses', '5', '最大並發分析數量'),
|
|
('default_grade_thresholds', '{"A":90,"B":80,"C":70,"D":60}', '預設等級閾值')
|
|
`);
|
|
|
|
console.log('✅ 預設數據插入完成');
|
|
|
|
// 關閉連接
|
|
await serverConnection.end();
|
|
|
|
// 測試新建立的資料庫連接
|
|
console.log('🔄 正在測試資料庫連接...');
|
|
connection = await mysql.createConnection(dbConfig);
|
|
|
|
// 測試查詢
|
|
const [rows] = await connection.query('SELECT COUNT(*) as count FROM criteria_templates');
|
|
console.log(`✅ 資料庫測試成功,找到 ${rows[0].count} 個評分標準模板`);
|
|
|
|
// 顯示建立的資料表
|
|
const [tables] = await connection.query('SHOW TABLES');
|
|
console.log('📊 已建立的資料表:');
|
|
tables.forEach(table => {
|
|
console.log(` - ${Object.values(table)[0]}`);
|
|
});
|
|
|
|
await connection.end();
|
|
console.log('🎉 資料庫初始化完成!');
|
|
|
|
} catch (error) {
|
|
console.error('❌ 資料庫初始化失敗:', error.message);
|
|
console.error('詳細錯誤:', error);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
// 如果直接執行此腳本
|
|
if (require.main === module) {
|
|
initializeDatabase();
|
|
}
|
|
|
|
module.exports = { initializeDatabase };
|