import mysql from 'mysql2/promise' // MySQL 連接設定 const dbConfig = { host: process.env.DB_HOST!, port: parseInt(process.env.DB_PORT!), database: process.env.DB_DATABASE!, user: process.env.DB_USERNAME!, password: process.env.DB_PASSWORD!, waitForConnections: true, connectionLimit: 10, queueLimit: 0 } // 創建連接池 export const db = mysql.createPool(dbConfig) // 測試連接函數 export async function testConnection() { try { const connection = await db.getConnection() console.log('MySQL 資料庫連接成功') connection.release() return true } catch (error) { console.error('MySQL 資料庫連接失敗:', error) return false } } // Database types export interface User { id: string name: string email: string role: "executive" | "manager" | "hr" avatar_url?: string created_at: string updated_at: string } export interface KPI { id: string user_id: string title: string description?: string category: "financial" | "operational" | "team" | "innovation" | "strategy" weight: number target_value: number current_value: number unit?: string start_date: string end_date: string approved_by?: string status: "pending" | "approved" | "rejected" | "active" | "completed" created_at: string updated_at: string } export interface KPIProgress { id: string kpi_id: string progress: number comment?: string attachment_url?: string blockers?: string created_by: string created_at: string } export interface Review { id: string reviewer_id: string reviewee_id: string review_type: "quarterly" | "annual" | "one_on_one" | "goal_setting" scheduled_date: string completed_date?: string status: "scheduled" | "in_progress" | "completed" | "cancelled" summary?: string overall_rating?: number created_at: string updated_at: string } // CRUD API functions export const kpiService = { // READ - 獲取用戶的 KPI async getKPIsByUser(userId: string): Promise { try { const [rows] = await db.execute( 'SELECT * FROM kpi WHERE user_id = ? AND status = ?', [userId, 'active'] ) return rows as KPI[] } catch (error) { console.error('獲取 KPI 失敗:', error) throw error } }, // CREATE - 創建新 KPI async createKPI(kpi: Omit): Promise { try { const id = `kpi_${Date.now()}_${Math.random().toString(36).substr(2, 9)}` const now = new Date().toISOString() await db.execute( `INSERT INTO kpi (id, user_id, title, description, category, weight, target_value, current_value, unit, start_date, end_date, approved_by, status, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [ id, kpi.user_id, kpi.title, kpi.description, kpi.category, kpi.weight, kpi.target_value, kpi.current_value, kpi.unit, kpi.start_date, kpi.end_date, kpi.approved_by, kpi.status, now, now ] ) const [rows] = await db.execute('SELECT * FROM kpi WHERE id = ?', [id]) return (rows as KPI[])[0] } catch (error) { console.error('創建 KPI 失敗:', error) throw error } }, // UPDATE - 更新 KPI 進度 async updateKPIProgress(kpiId: string, progress: number, comment?: string, blockers?: string, userId?: string): Promise { try { const id = `progress_${Date.now()}_${Math.random().toString(36).substr(2, 9)}` const now = new Date().toISOString() await db.execute( `INSERT INTO kpi_progress (id, kpi_id, progress, comment, blockers, created_by, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)`, [id, kpiId, progress, comment, blockers, userId || 'system', now] ) // 同時更新 KPI 的當前值 await db.execute( 'UPDATE kpi SET current_value = ?, updated_at = ? WHERE id = ?', [progress, now, kpiId] ) } catch (error) { console.error('更新 KPI 進度失敗:', error) throw error } }, // UPDATE - 更新 KPI async updateKPI(id: string, updates: Partial): Promise { try { const now = new Date().toISOString() const fields = Object.keys(updates).filter(key => key !== 'id').map(key => `${key} = ?`) const values = Object.values(updates).filter((_, index) => Object.keys(updates)[index] !== 'id') if (fields.length === 0) throw new Error('沒有要更新的欄位') await db.execute( `UPDATE kpi SET ${fields.join(', ')}, updated_at = ? WHERE id = ?`, [...values, now, id] ) const [rows] = await db.execute('SELECT * FROM kpi WHERE id = ?', [id]) return (rows as KPI[])[0] } catch (error) { console.error('更新 KPI 失敗:', error) throw error } }, // DELETE - 刪除 KPI(軟刪除,將狀態改為 deleted) async deleteKPI(id: string): Promise { try { const now = new Date().toISOString() await db.execute( 'UPDATE kpi SET status = ?, updated_at = ? WHERE id = ?', ['deleted', now, id] ) } catch (error) { console.error('刪除 KPI 失敗:', error) throw error } }, } export const reviewService = { // READ - 獲取即將到來的評審 async getUpcomingReviews(userId: string): Promise { try { const [rows] = await db.execute( `SELECT r.*, u.name as reviewee_name, u.email as reviewee_email FROM reviews r LEFT JOIN users u ON r.reviewee_id = u.id WHERE r.reviewer_id = ? AND r.status = ? ORDER BY r.scheduled_date ASC`, [userId, 'scheduled'] ) return rows as Review[] } catch (error) { console.error('獲取評審列表失敗:', error) throw error } }, // CREATE - 創建新評審 async createReview(review: Omit): Promise { try { const id = `review_${Date.now()}_${Math.random().toString(36).substr(2, 9)}` const now = new Date().toISOString() await db.execute( `INSERT INTO reviews (id, reviewer_id, reviewee_id, review_type, scheduled_date, completed_date, status, summary, overall_rating, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [ id, review.reviewer_id, review.reviewee_id, review.review_type, review.scheduled_date, review.completed_date, review.status, review.summary, review.overall_rating, now, now ] ) const [rows] = await db.execute('SELECT * FROM reviews WHERE id = ?', [id]) return (rows as Review[])[0] } catch (error) { console.error('創建評審失敗:', error) throw error } }, // READ - 獲取所有評審 async getAllReviews(): Promise { try { const [rows] = await db.execute('SELECT * FROM reviews ORDER BY created_at DESC') return rows as Review[] } catch (error) { console.error('獲取所有評審失敗:', error) throw error } }, // UPDATE - 更新評審 async updateReview(id: string, updates: Partial): Promise { try { const now = new Date().toISOString() const fields = Object.keys(updates).filter(key => key !== 'id').map(key => `${key} = ?`) const values = Object.values(updates).filter((_, index) => Object.keys(updates)[index] !== 'id') if (fields.length === 0) throw new Error('沒有要更新的欄位') await db.execute( `UPDATE reviews SET ${fields.join(', ')}, updated_at = ? WHERE id = ?`, [...values, now, id] ) const [rows] = await db.execute('SELECT * FROM reviews WHERE id = ?', [id]) return (rows as Review[])[0] } catch (error) { console.error('更新評審失敗:', error) throw error } }, // DELETE - 刪除評審 async deleteReview(id: string): Promise { try { await db.execute('DELETE FROM reviews WHERE id = ?', [id]) } catch (error) { console.error('刪除評審失敗:', error) throw error } }, } // 用戶管理服務 export const userService = { // CREATE - 創建用戶 async createUser(user: Omit): Promise { try { const id = `user_${Date.now()}_${Math.random().toString(36).substr(2, 9)}` const now = new Date().toISOString() await db.execute( `INSERT INTO users (id, name, email, role, avatar_url, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?)`, [id, user.name, user.email, user.role, user.avatar_url, now, now] ) const [rows] = await db.execute('SELECT * FROM users WHERE id = ?', [id]) return (rows as User[])[0] } catch (error) { console.error('創建用戶失敗:', error) throw error } }, // READ - 獲取所有用戶 async getAllUsers(): Promise { try { const [rows] = await db.execute('SELECT * FROM users ORDER BY created_at DESC') return rows as User[] } catch (error) { console.error('獲取用戶列表失敗:', error) throw error } }, // READ - 根據 ID 獲取用戶 async getUserById(id: string): Promise { try { const [rows] = await db.execute('SELECT * FROM users WHERE id = ?', [id]) const users = rows as User[] return users.length > 0 ? users[0] : null } catch (error) { console.error('獲取用戶失敗:', error) throw error } }, // UPDATE - 更新用戶 async updateUser(id: string, updates: Partial): Promise { try { const now = new Date().toISOString() const fields = Object.keys(updates).filter(key => key !== 'id').map(key => `${key} = ?`) const values = Object.values(updates).filter((_, index) => Object.keys(updates)[index] !== 'id') if (fields.length === 0) throw new Error('沒有要更新的欄位') await db.execute( `UPDATE users SET ${fields.join(', ')}, updated_at = ? WHERE id = ?`, [...values, now, id] ) const [rows] = await db.execute('SELECT * FROM users WHERE id = ?', [id]) return (rows as User[])[0] } catch (error) { console.error('更新用戶失敗:', error) throw error } }, // DELETE - 刪除用戶 async deleteUser(id: string): Promise { try { await db.execute('DELETE FROM users WHERE id = ?', [id]) } catch (error) { console.error('刪除用戶失敗:', error) throw error } }, }