701 lines
26 KiB
SQL
701 lines
26 KiB
SQL
-- =====================================================
|
||
-- 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,
|
||
`order_index` INT DEFAULT 0,
|
||
`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_order` (`order_index`),
|
||
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,
|
||
`registered_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;
|