Files
ai-showcase-platform/database-schema.sql

698 lines
26 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- =====================================================
-- AI 展示平台資料庫結構設計
-- 資料庫: MySQL
-- 主機: mysql.theaken.com
-- 端口: 33306
-- 資料庫名: db_AI_Platform
-- 用戶: AI_Platform
-- 密碼: Aa123456
-- =====================================================
-- 創建資料庫 (如果不存在)
CREATE DATABASE IF NOT EXISTS `db_AI_Platform`
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
USE `db_AI_Platform`;
-- 1. 用戶表 (users)
CREATE TABLE `users` (
`id` VARCHAR(36) PRIMARY KEY,
`name` VARCHAR(100) NOT NULL,
`email` VARCHAR(255) UNIQUE NOT NULL,
`password_hash` VARCHAR(255) NOT NULL,
`avatar` VARCHAR(500) NULL,
`department` VARCHAR(100) NOT NULL,
`role` ENUM('user', 'developer', 'admin') DEFAULT 'user',
`join_date` DATE NOT NULL,
`total_likes` INT DEFAULT 0,
`total_views` INT DEFAULT 0,
`is_active` BOOLEAN DEFAULT TRUE,
`last_login` TIMESTAMP NULL,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX `idx_email` (`email`),
INDEX `idx_department` (`department`),
INDEX `idx_role` (`role`),
INDEX `idx_join_date` (`join_date`)
);
-- 2. 評審表 (judges)
CREATE TABLE `judges` (
`id` VARCHAR(36) PRIMARY KEY,
`name` VARCHAR(100) NOT NULL,
`title` VARCHAR(100) NOT NULL,
`department` VARCHAR(100) NOT NULL,
`expertise` JSON NOT NULL,
`avatar` VARCHAR(500) NULL,
`is_active` BOOLEAN DEFAULT TRUE,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX `idx_department` (`department`),
INDEX `idx_is_active` (`is_active`)
);
-- 3. 團隊表 (teams)
CREATE TABLE `teams` (
`id` VARCHAR(36) PRIMARY KEY,
`name` VARCHAR(200) NOT NULL,
`leader_id` VARCHAR(36) NOT NULL,
`department` VARCHAR(100) NOT NULL,
`contact_email` VARCHAR(255) NOT NULL,
`total_likes` INT DEFAULT 0,
`is_active` BOOLEAN DEFAULT TRUE,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (`leader_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
INDEX `idx_leader` (`leader_id`),
INDEX `idx_department` (`department`),
INDEX `idx_is_active` (`is_active`)
);
-- =====================================================
-- 4. 團隊成員表 (team_members)
-- =====================================================
CREATE TABLE `team_members` (
`id` VARCHAR(36) PRIMARY KEY,
`team_id` VARCHAR(36) NOT NULL,
`user_id` VARCHAR(36) NOT NULL,
`role` VARCHAR(50) NOT NULL DEFAULT 'member',
`joined_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`team_id`) REFERENCES `teams`(`id`) ON DELETE CASCADE,
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
UNIQUE KEY `unique_team_user` (`team_id`, `user_id`),
INDEX `idx_team` (`team_id`),
INDEX `idx_user` (`user_id`)
);
-- =====================================================
-- 5. 競賽表 (competitions)
-- =====================================================
CREATE TABLE `competitions` (
`id` VARCHAR(36) PRIMARY KEY,
`name` VARCHAR(200) NOT NULL,
`year` INT NOT NULL,
`month` INT NOT NULL,
`start_date` DATE NOT NULL,
`end_date` DATE NOT NULL,
`status` ENUM('upcoming', 'active', 'judging', 'completed') DEFAULT 'upcoming',
`description` TEXT,
`type` ENUM('individual', 'team', 'mixed', 'proposal') NOT NULL,
`evaluation_focus` TEXT,
`max_team_size` INT NULL,
`is_active` BOOLEAN DEFAULT TRUE,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX `idx_year_month` (`year`, `month`),
INDEX `idx_status` (`status`),
INDEX `idx_type` (`type`),
INDEX `idx_dates` (`start_date`, `end_date`)
);
-- =====================================================
-- 6. 競賽評審關聯表 (competition_judges)
-- =====================================================
CREATE TABLE `competition_judges` (
`id` VARCHAR(36) PRIMARY KEY,
`competition_id` VARCHAR(36) NOT NULL,
`judge_id` VARCHAR(36) NOT NULL,
`assigned_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`competition_id`) REFERENCES `competitions`(`id`) ON DELETE CASCADE,
FOREIGN KEY (`judge_id`) REFERENCES `judges`(`id`) ON DELETE CASCADE,
UNIQUE KEY `unique_competition_judge` (`competition_id`, `judge_id`),
INDEX `idx_competition` (`competition_id`),
INDEX `idx_judge` (`judge_id`)
);
-- =====================================================
-- 7. 競賽規則表 (competition_rules)
-- =====================================================
CREATE TABLE `competition_rules` (
`id` VARCHAR(36) PRIMARY KEY,
`competition_id` VARCHAR(36) NOT NULL,
`name` VARCHAR(200) NOT NULL,
`description` TEXT,
`weight` DECIMAL(5,2) NOT NULL DEFAULT 0.00,
`order_index` INT DEFAULT 0,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`competition_id`) REFERENCES `competitions`(`id`) ON DELETE CASCADE,
INDEX `idx_competition` (`competition_id`),
INDEX `idx_order` (`order_index`)
);
-- =====================================================
-- 8. 競賽獎項類型表 (competition_award_types)
-- =====================================================
CREATE TABLE `competition_award_types` (
`id` VARCHAR(36) PRIMARY KEY,
`competition_id` VARCHAR(36) NOT NULL,
`name` VARCHAR(200) NOT NULL,
`description` TEXT,
`icon` VARCHAR(50) NOT NULL,
`color` VARCHAR(20) NOT NULL,
`is_active` BOOLEAN DEFAULT TRUE,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`competition_id`) REFERENCES `competitions`(`id`) ON DELETE CASCADE,
INDEX `idx_competition` (`competition_id`),
INDEX `idx_is_active` (`is_active`)
);
-- =====================================================
-- 9. 應用表 (apps)
-- =====================================================
CREATE TABLE `apps` (
`id` VARCHAR(36) PRIMARY KEY,
`name` VARCHAR(200) NOT NULL,
`description` TEXT,
`creator_id` VARCHAR(36) NOT NULL,
`team_id` VARCHAR(36) NULL,
`category` VARCHAR(100) NOT NULL,
`type` VARCHAR(100) NOT NULL,
`icon` VARCHAR(50) DEFAULT 'Bot',
`icon_color` VARCHAR(100) DEFAULT 'from-blue-500 to-purple-500',
`app_url` VARCHAR(500) NULL,
`likes_count` INT DEFAULT 0,
`views_count` INT DEFAULT 0,
`rating` DECIMAL(3,2) DEFAULT 0.00,
`is_active` BOOLEAN DEFAULT TRUE,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (`creator_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
FOREIGN KEY (`team_id`) REFERENCES `teams`(`id`) ON DELETE SET NULL,
INDEX `idx_creator` (`creator_id`),
INDEX `idx_team` (`team_id`),
INDEX `idx_category` (`category`),
INDEX `idx_type` (`type`),
INDEX `idx_likes` (`likes_count`),
INDEX `idx_views` (`views_count`)
);
-- =====================================================
-- 10. 提案表 (proposals)
-- =====================================================
CREATE TABLE `proposals` (
`id` VARCHAR(36) PRIMARY KEY,
`title` VARCHAR(300) NOT NULL,
`description` TEXT,
`problem_statement` TEXT NOT NULL,
`solution` TEXT NOT NULL,
`expected_impact` TEXT NOT NULL,
`team_id` VARCHAR(36) NOT NULL,
`attachments` JSON NULL,
`status` ENUM('draft', 'submitted', 'under_review', 'approved', 'rejected') DEFAULT 'draft',
`submitted_at` TIMESTAMP NULL,
`is_active` BOOLEAN DEFAULT TRUE,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (`team_id`) REFERENCES `teams`(`id`) ON DELETE CASCADE,
INDEX `idx_team` (`team_id`),
INDEX `idx_status` (`status`),
INDEX `idx_submitted` (`submitted_at`)
);
-- =====================================================
-- 11. 評論投票表 (review_votes)
-- =====================================================
CREATE TABLE `review_votes` (
`id` VARCHAR(36) PRIMARY KEY,
`review_id` VARCHAR(36) NOT NULL,
`user_id` VARCHAR(36) NOT NULL,
`is_helpful` BOOLEAN NOT NULL, -- true = 有幫助, false = 沒幫助
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`review_id`) REFERENCES `user_ratings`(`id`) ON DELETE CASCADE,
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
UNIQUE KEY `unique_user_review_vote` (`user_id`, `review_id`),
INDEX `idx_review` (`review_id`),
INDEX `idx_user` (`user_id`),
INDEX `idx_helpful` (`is_helpful`)
);
-- =====================================================
-- 12. 競賽參與應用表 (competition_apps)
-- =====================================================
CREATE TABLE `competition_apps` (
`id` VARCHAR(36) PRIMARY KEY,
`competition_id` VARCHAR(36) NOT NULL,
`app_id` VARCHAR(36) NOT NULL,
`submitted_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`competition_id`) REFERENCES `competitions`(`id`) ON DELETE CASCADE,
FOREIGN KEY (`app_id`) REFERENCES `apps`(`id`) ON DELETE CASCADE,
UNIQUE KEY `unique_competition_app` (`competition_id`, `app_id`),
INDEX `idx_competition` (`competition_id`),
INDEX `idx_app` (`app_id`)
);
-- =====================================================
-- 12. 競賽參與團隊表 (competition_teams)
-- =====================================================
CREATE TABLE `competition_teams` (
`id` VARCHAR(36) PRIMARY KEY,
`competition_id` VARCHAR(36) NOT NULL,
`team_id` VARCHAR(36) NOT NULL,
`submitted_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`competition_id`) REFERENCES `competitions`(`id`) ON DELETE CASCADE,
FOREIGN KEY (`team_id`) REFERENCES `teams`(`id`) ON DELETE CASCADE,
UNIQUE KEY `unique_competition_team` (`competition_id`, `team_id`),
INDEX `idx_competition` (`competition_id`),
INDEX `idx_team` (`team_id`)
);
-- =====================================================
-- 13. 競賽參與提案表 (competition_proposals)
-- =====================================================
CREATE TABLE `competition_proposals` (
`id` VARCHAR(36) PRIMARY KEY,
`competition_id` VARCHAR(36) NOT NULL,
`proposal_id` VARCHAR(36) NOT NULL,
`submitted_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`competition_id`) REFERENCES `competitions`(`id`) ON DELETE CASCADE,
FOREIGN KEY (`proposal_id`) REFERENCES `proposals`(`id`) ON DELETE CASCADE,
UNIQUE KEY `unique_competition_proposal` (`competition_id`, `proposal_id`),
INDEX `idx_competition` (`competition_id`),
INDEX `idx_proposal` (`proposal_id`)
);
-- =====================================================
-- 14. 應用評分表 (app_judge_scores)
-- =====================================================
CREATE TABLE `app_judge_scores` (
`id` VARCHAR(36) PRIMARY KEY,
`judge_id` VARCHAR(36) NOT NULL,
`app_id` VARCHAR(36) NOT NULL,
`innovation_score` INT NOT NULL CHECK (`innovation_score` >= 1 AND `innovation_score` <= 10),
`technical_score` INT NOT NULL CHECK (`technical_score` >= 1 AND `technical_score` <= 10),
`usability_score` INT NOT NULL CHECK (`usability_score` >= 1 AND `usability_score` <= 10),
`presentation_score` INT NOT NULL CHECK (`presentation_score` >= 1 AND `presentation_score` <= 10),
`impact_score` INT NOT NULL CHECK (`impact_score` >= 1 AND `impact_score` <= 10),
`total_score` DECIMAL(5,2) NOT NULL,
`comments` TEXT,
`submitted_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`judge_id`) REFERENCES `judges`(`id`) ON DELETE CASCADE,
FOREIGN KEY (`app_id`) REFERENCES `apps`(`id`) ON DELETE CASCADE,
UNIQUE KEY `unique_judge_app` (`judge_id`, `app_id`),
INDEX `idx_judge` (`judge_id`),
INDEX `idx_app` (`app_id`),
INDEX `idx_total_score` (`total_score`)
);
-- =====================================================
-- 15. 提案評分表 (proposal_judge_scores)
-- =====================================================
CREATE TABLE `proposal_judge_scores` (
`id` VARCHAR(36) PRIMARY KEY,
`judge_id` VARCHAR(36) NOT NULL,
`proposal_id` VARCHAR(36) NOT NULL,
`problem_identification_score` INT NOT NULL CHECK (`problem_identification_score` >= 1 AND `problem_identification_score` <= 10),
`solution_feasibility_score` INT NOT NULL CHECK (`solution_feasibility_score` >= 1 AND `solution_feasibility_score` <= 10),
`innovation_score` INT NOT NULL CHECK (`innovation_score` >= 1 AND `innovation_score` <= 10),
`impact_score` INT NOT NULL CHECK (`impact_score` >= 1 AND `impact_score` <= 10),
`presentation_score` INT NOT NULL CHECK (`presentation_score` >= 1 AND `presentation_score` <= 10),
`total_score` DECIMAL(5,2) NOT NULL,
`comments` TEXT,
`submitted_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`judge_id`) REFERENCES `judges`(`id`) ON DELETE CASCADE,
FOREIGN KEY (`proposal_id`) REFERENCES `proposals`(`id`) ON DELETE CASCADE,
UNIQUE KEY `unique_judge_proposal` (`judge_id`, `proposal_id`),
INDEX `idx_judge` (`judge_id`),
INDEX `idx_proposal` (`proposal_id`),
INDEX `idx_total_score` (`total_score`)
);
-- =====================================================
-- 16. 獎項表 (awards)
-- =====================================================
CREATE TABLE `awards` (
`id` VARCHAR(36) PRIMARY KEY,
`competition_id` VARCHAR(36) NOT NULL,
`app_id` VARCHAR(36) NULL,
`team_id` VARCHAR(36) NULL,
`proposal_id` VARCHAR(36) NULL,
`app_name` VARCHAR(200) NULL,
`team_name` VARCHAR(200) NULL,
`proposal_title` VARCHAR(300) NULL,
`creator` VARCHAR(100) NOT NULL,
`award_type` ENUM('gold', 'silver', 'bronze', 'popular', 'innovation', 'technical', 'custom') NOT NULL,
`award_name` VARCHAR(200) NOT NULL,
`score` DECIMAL(5,2) NOT NULL,
`year` INT NOT NULL,
`month` INT NOT NULL,
`icon` VARCHAR(50) NOT NULL,
`custom_award_type_id` VARCHAR(36) NULL,
`competition_type` ENUM('individual', 'team', 'proposal') NOT NULL,
`rank` INT DEFAULT 0,
`category` ENUM('innovation', 'technical', 'practical', 'popular', 'teamwork', 'solution', 'creativity') NOT NULL,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`competition_id`) REFERENCES `competitions`(`id`) ON DELETE CASCADE,
FOREIGN KEY (`app_id`) REFERENCES `apps`(`id`) ON DELETE SET NULL,
FOREIGN KEY (`team_id`) REFERENCES `teams`(`id`) ON DELETE SET NULL,
FOREIGN KEY (`proposal_id`) REFERENCES `proposals`(`id`) ON DELETE SET NULL,
INDEX `idx_competition` (`competition_id`),
INDEX `idx_year_month` (`year`, `month`),
INDEX `idx_award_type` (`award_type`),
INDEX `idx_rank` (`rank`),
INDEX `idx_category` (`category`)
);
-- =====================================================
-- 17. 用戶收藏表 (user_favorites)
-- =====================================================
CREATE TABLE `user_favorites` (
`id` VARCHAR(36) PRIMARY KEY,
`user_id` VARCHAR(36) NOT NULL,
`app_id` VARCHAR(36) NOT NULL,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
FOREIGN KEY (`app_id`) REFERENCES `apps`(`id`) ON DELETE CASCADE,
UNIQUE KEY `unique_user_app` (`user_id`, `app_id`),
INDEX `idx_user` (`user_id`),
INDEX `idx_app` (`app_id`)
);
-- =====================================================
-- 18. 用戶按讚表 (user_likes)
-- =====================================================
CREATE TABLE `user_likes` (
`id` VARCHAR(36) PRIMARY KEY,
`user_id` VARCHAR(36) NOT NULL,
`app_id` VARCHAR(36) NOT NULL,
`liked_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
FOREIGN KEY (`app_id`) REFERENCES `apps`(`id`) ON DELETE CASCADE,
UNIQUE KEY `unique_user_app_date` (`user_id`, `app_id`, `liked_at`),
INDEX `idx_user` (`user_id`),
INDEX `idx_app` (`app_id`),
INDEX `idx_liked_at` (`liked_at`)
);
-- =====================================================
-- 19. 用戶瀏覽記錄表 (user_views)
-- =====================================================
CREATE TABLE `user_views` (
`id` VARCHAR(36) PRIMARY KEY,
`user_id` VARCHAR(36) NOT NULL,
`app_id` VARCHAR(36) NOT NULL,
`viewed_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`ip_address` VARCHAR(45) NULL,
`user_agent` TEXT NULL,
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
FOREIGN KEY (`app_id`) REFERENCES `apps`(`id`) ON DELETE CASCADE,
INDEX `idx_user` (`user_id`),
INDEX `idx_app` (`app_id`),
INDEX `idx_viewed_at` (`viewed_at`)
);
-- =====================================================
-- 20. 用戶評分表 (user_ratings)
-- =====================================================
CREATE TABLE `user_ratings` (
`id` VARCHAR(36) PRIMARY KEY,
`user_id` VARCHAR(36) NOT NULL,
`app_id` VARCHAR(36) NOT NULL,
`rating` DECIMAL(3,2) NOT NULL CHECK (`rating` >= 1.0 AND `rating` <= 5.0),
`comment` TEXT NULL,
`rated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
FOREIGN KEY (`app_id`) REFERENCES `apps`(`id`) ON DELETE CASCADE,
INDEX `idx_user` (`user_id`),
INDEX `idx_app` (`app_id`),
INDEX `idx_rating` (`rating`)
);
-- =====================================================
-- 21. AI助手聊天會話表 (chat_sessions)
-- =====================================================
CREATE TABLE `chat_sessions` (
`id` VARCHAR(36) PRIMARY KEY,
`user_id` VARCHAR(36) NOT NULL,
`session_name` VARCHAR(200) NULL,
`is_active` BOOLEAN DEFAULT TRUE,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE,
INDEX `idx_user` (`user_id`),
INDEX `idx_is_active` (`is_active`)
);
-- =====================================================
-- 22. AI助手聊天訊息表 (chat_messages)
-- =====================================================
CREATE TABLE `chat_messages` (
`id` VARCHAR(36) PRIMARY KEY,
`session_id` VARCHAR(36) NOT NULL,
`text` TEXT NOT NULL,
`sender` ENUM('user', 'bot') NOT NULL,
`quick_questions` JSON NULL,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`session_id`) REFERENCES `chat_sessions`(`id`) ON DELETE CASCADE,
INDEX `idx_session` (`session_id`),
INDEX `idx_sender` (`sender`),
INDEX `idx_created_at` (`created_at`)
);
-- =====================================================
-- 23. AI助手配置表 (ai_assistant_configs)
-- =====================================================
CREATE TABLE `ai_assistant_configs` (
`id` VARCHAR(36) PRIMARY KEY,
`api_key` VARCHAR(255) NOT NULL,
`api_url` VARCHAR(500) NOT NULL,
`model` VARCHAR(100) NOT NULL,
`max_tokens` INT DEFAULT 200,
`temperature` DECIMAL(3,2) DEFAULT 0.70,
`system_prompt` TEXT NOT NULL,
`is_active` BOOLEAN DEFAULT TRUE,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX `idx_is_active` (`is_active`)
);
-- =====================================================
-- 24. 系統設定表 (system_settings)
-- =====================================================
CREATE TABLE `system_settings` (
`id` VARCHAR(36) PRIMARY KEY,
`key` VARCHAR(100) UNIQUE NOT NULL,
`value` TEXT NOT NULL,
`description` TEXT,
`category` VARCHAR(50) DEFAULT 'general',
`is_public` BOOLEAN DEFAULT FALSE,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX `idx_key` (`key`),
INDEX `idx_category` (`category`),
INDEX `idx_is_public` (`is_public`)
);
-- =====================================================
-- 25. 活動日誌表 (activity_logs)
-- =====================================================
CREATE TABLE `activity_logs` (
`id` VARCHAR(36) PRIMARY KEY,
`user_id` VARCHAR(36) NULL,
`action` VARCHAR(100) NOT NULL,
`resource_type` VARCHAR(50) NOT NULL,
`resource_id` VARCHAR(36) NULL,
`details` JSON NULL,
`ip_address` VARCHAR(45) NULL,
`user_agent` TEXT NULL,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE SET NULL,
INDEX `idx_user` (`user_id`),
INDEX `idx_action` (`action`),
INDEX `idx_resource` (`resource_type`, `resource_id`),
INDEX `idx_created_at` (`created_at`)
);
-- =====================================================
-- 觸發器:自動計算總分
-- =====================================================
-- 應用評分觸發器
DELIMITER //
CREATE TRIGGER `calculate_app_total_score`
BEFORE INSERT ON `app_judge_scores`
FOR EACH ROW
BEGIN
SET NEW.total_score = (
NEW.innovation_score +
NEW.technical_score +
NEW.usability_score +
NEW.presentation_score +
NEW.impact_score
) / 5.0;
END//
CREATE TRIGGER `calculate_app_total_score_update`
BEFORE UPDATE ON `app_judge_scores`
FOR EACH ROW
BEGIN
SET NEW.total_score = (
NEW.innovation_score +
NEW.technical_score +
NEW.usability_score +
NEW.presentation_score +
NEW.impact_score
) / 5.0;
END//
-- 提案評分觸發器
CREATE TRIGGER `calculate_proposal_total_score`
BEFORE INSERT ON `proposal_judge_scores`
FOR EACH ROW
BEGIN
SET NEW.total_score = (
NEW.problem_identification_score +
NEW.solution_feasibility_score +
NEW.innovation_score +
NEW.impact_score +
NEW.presentation_score
) / 5.0;
END//
CREATE TRIGGER `calculate_proposal_total_score_update`
BEFORE UPDATE ON `proposal_judge_scores`
FOR EACH ROW
BEGIN
SET NEW.total_score = (
NEW.problem_identification_score +
NEW.solution_feasibility_score +
NEW.innovation_score +
NEW.impact_score +
NEW.presentation_score
) / 5.0;
END//
DELIMITER ;
-- =====================================================
-- 視圖:用戶統計視圖
-- =====================================================
CREATE VIEW `user_statistics` AS
SELECT
u.id,
u.name,
u.email,
u.department,
u.role,
u.join_date,
u.total_likes,
u.total_views,
COUNT(DISTINCT f.app_id) as favorite_count,
COUNT(DISTINCT l.app_id) as liked_apps_count,
COUNT(DISTINCT v.app_id) as viewed_apps_count,
AVG(r.rating) as average_rating_given,
COUNT(DISTINCT t.id) as teams_joined,
COUNT(DISTINCT CASE WHEN t.leader_id = u.id THEN t.id END) as teams_led
FROM users u
LEFT JOIN user_favorites f ON u.id = f.user_id
LEFT JOIN user_likes l ON u.id = l.user_id
LEFT JOIN user_views v ON u.id = v.user_id
LEFT JOIN user_ratings r ON u.id = r.user_id
LEFT JOIN team_members tm ON u.id = tm.user_id
LEFT JOIN teams t ON tm.team_id = t.id
WHERE u.is_active = TRUE
GROUP BY u.id;
-- =====================================================
-- 視圖:應用統計視圖
-- =====================================================
CREATE VIEW `app_statistics` AS
SELECT
a.id,
a.name,
a.description,
a.category,
a.type,
a.likes_count,
a.views_count,
a.rating,
u.name as creator_name,
u.department as creator_department,
t.name as team_name,
COUNT(DISTINCT f.user_id) as favorite_users_count,
COUNT(DISTINCT l.user_id) as liked_users_count,
COUNT(DISTINCT v.user_id) as viewed_users_count,
AVG(ajs.total_score) as average_judge_score,
COUNT(DISTINCT ajs.judge_id) as judge_count
FROM apps a
LEFT JOIN users u ON a.creator_id = u.id
LEFT JOIN teams t ON a.team_id = t.id
LEFT JOIN user_favorites f ON a.id = f.app_id
LEFT JOIN user_likes l ON a.id = l.app_id
LEFT JOIN user_views v ON a.id = v.app_id
LEFT JOIN app_judge_scores ajs ON a.id = ajs.app_id
WHERE a.is_active = TRUE
GROUP BY a.id;
-- =====================================================
-- 視圖:競賽統計視圖
-- =====================================================
CREATE VIEW `competition_statistics` AS
SELECT
c.id,
c.name,
c.year,
c.month,
c.type,
c.status,
COUNT(DISTINCT cj.judge_id) as judge_count,
COUNT(DISTINCT ca.app_id) as app_count,
COUNT(DISTINCT ct.team_id) as team_count,
COUNT(DISTINCT cp.proposal_id) as proposal_count,
COUNT(DISTINCT aw.id) as award_count
FROM competitions c
LEFT JOIN competition_judges cj ON c.id = cj.competition_id
LEFT JOIN competition_apps ca ON c.id = ca.competition_id
LEFT JOIN competition_teams ct ON c.id = ct.competition_id
LEFT JOIN competition_proposals cp ON c.id = cp.competition_id
LEFT JOIN awards aw ON c.id = aw.competition_id
WHERE c.is_active = TRUE
GROUP BY c.id;
-- =====================================================
-- 插入初始數據
-- =====================================================
-- 插入系統設定
INSERT INTO `system_settings` (`id`, `key`, `value`, `description`, `category`, `is_public`) VALUES
(UUID(), 'site_name', '強茂集團 AI 展示平台', '網站名稱', 'general', TRUE),
(UUID(), 'site_description', '企業內部 AI 應用展示與競賽管理系統', '網站描述', 'general', TRUE),
(UUID(), 'max_team_size', '5', '最大團隊人數', 'competition', FALSE),
(UUID(), 'max_file_size', '10485760', '最大文件上傳大小(字節)', 'upload', FALSE),
(UUID(), 'allowed_file_types', 'jpg,jpeg,png,gif,pdf,doc,docx,ppt,pptx', '允許上傳的文件類型', 'upload', FALSE);
-- 插入 AI 助手配置
INSERT INTO `ai_assistant_configs` (`id`, `api_key`, `api_url`, `model`, `max_tokens`, `temperature`, `system_prompt`, `is_active`) VALUES
(UUID(), 'sk-3640dcff23fe4a069a64f536ac538d75', 'https://api.deepseek.com/v1/chat/completions', 'deepseek-chat', 200, 0.70, '你是一個競賽管理系統的AI助手專門幫助用戶了解如何使用這個系統。請用友善、專業的語氣回答用戶問題並提供具體的操作步驟。回答要簡潔明瞭避免過長的文字。重要請不要使用任何Markdown格式只使用純文字回答。回答時請使用繁體中文。', TRUE);
-- =====================================================
-- 完成
-- =====================================================
SELECT '資料庫結構創建完成!' as message;