diff --git a/app.js b/app.js index 683612738d4a6c6a55ea5c7d3eaff6488bca7ecb..b6fb4a0e097f282ea915b3a8b973cd1ede3931c7 100644 --- a/app.js +++ b/app.js @@ -1,75 +1,87 @@ +// app.js (ไฟล์หลัก) require('dotenv').config(); const express = require('express'); const session = require('express-session'); const path = require('path'); const cors = require("cors"); const bodyParser = require('body-parser'); -const db = require('./db'); +const db = require('./db'); const authRoutes = require('./routes/auth'); -const chatAIRouter = require('./routes/chatAI'); const app = express(); -// Middlewares +// ทดสอบการเชื่อมต่อฐานข้อมูล +async function testConnection() { + try { + const connection = await db.getConnection(); + await connection.ping(); + console.log('✅ Database connection succeeded.'); + connection.release(); + } catch (err) { + console.error('❌ Database connection failed:', err); + process.exit(1); + } +} +testConnection(); + +// Middleware app.use(cors()); app.use(express.json()); app.use(express.urlencoded({ extended: true })); -app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()); -// ตั้งค่า Session +// การตั้งค่า Session app.use(session({ secret: process.env.SESSION_SECRET, resave: false, saveUninitialized: false })); -// Serve Static Files +// เสิร์ฟไฟล์สแตติก app.use(express.static(path.join(__dirname, 'public'))); // ตั้งค่า View Engine app.set('view engine', 'ejs'); app.set('views', path.join(__dirname, 'views')); -// ใช้ router สำหรับ Auth +// ใช้เส้นทางจาก authRoutes app.use('/auth', authRoutes); -// ---------------------- Routes ---------------------- +// ---------------------- เส้นทางหลัก ---------------------- app.get('/', (req, res) => { res.render('auth/login', { error: null }); }); app.get('/register', (req, res) => { - res.render('auth/register', { error: null, errors: null }); + res.render('auth/register', { error: null }); }); app.get('/index', async (req, res) => { + if (!req.session.user) return res.redirect('/'); try { const [activities] = await db.query('SELECT * FROM activity'); res.render('pages/index', { activities, user: req.session.user }); } catch (error) { - console.error('Error fetching activities:', error); + console.error('เกิดข้อผิดพลาดในการดึงข้อมูล:', error); res.status(500).send('เกิดข้อผิดพลาดในการดึงข้อมูล'); } }); -// Routes ที่ต้องล็อกอินก่อนเข้าใช้งาน +// ตรวจสอบการล็อกอินสำหรับเส้นทางที่ต้องการ +const requireAuth = (req, res, next) => { + if (!req.session.user) return res.redirect('/'); + next(); +}; + const protectedRoutes = ['/booking', '/chat', '/dashboard', '/settings']; protectedRoutes.forEach(route => { - app.get(route, (req, res) => { - if (!req.session.user) return res.redirect('/'); + app.get(route, requireAuth, (req, res) => { res.render(`pages${route}`, { user: req.session.user }); }); }); -// Chat AI Route -app.use('/api', chatAIRouter); -app.get('/chatAI', (req, res) => { - res.render('pages/chatAI', { user: req.session.user }); -}); - -// Start Server +// เริ่มต้นเซิร์ฟเวอร์ const port = process.env.PORT || 3000; app.listen(port, () => { - console.log(`🚀 Server started on port ${port}`); -}); + console.log(`🚀 เซิร์ฟเวอร์ทำงานที่พอร์ต ${port}`); +}); \ No newline at end of file diff --git a/db.js b/db.js index 8aadb6a79c2c95db484567eb1ad163e72d6ca54c..5ddaeae3eb462118d2850b176c171320e87559b4 100644 --- a/db.js +++ b/db.js @@ -1,4 +1,4 @@ -require('dotenv').config(); +// db.js (การตั้งค่าฐานข้อมูล) const mysql = require('mysql2/promise'); const pool = mysql.createPool({ @@ -12,20 +12,4 @@ const pool = mysql.createPool({ queueLimit: 0 }); -// ฟังก์ชันทดสอบการเชื่อมต่อฐานข้อมูล -async function testConnection() { - try { - const connection = await pool.getConnection(); - await connection.ping(); - console.log('✅ Database connection succeeded.'); - connection.release(); - } catch (err) { - console.error('❌ Database connection failed:', err); - process.exit(1); - } -} - -// เรียกใช้งานฟังก์ชันทดสอบการเชื่อมต่อ -testConnection(); - -module.exports = pool; +module.exports = pool; \ No newline at end of file diff --git a/routes/auth.js b/routes/auth.js index d12f88e5717a82ad3b14a9cc5c8db564b9d18405..cbaee2fb0c739adf1fcb4b0b88819d46d4020f42 100644 --- a/routes/auth.js +++ b/routes/auth.js @@ -1,57 +1,61 @@ +// routes/auth.js (เส้นทางเกี่ยวกับการรับรองตัวตน) const express = require('express'); +const router = express.Router(); const bcrypt = require('bcrypt'); const db = require('../db'); -const router = express.Router(); -// GET หน้า Login router.get('/login', (req, res) => { res.render('auth/login', { error: null }); }); -// POST การเข้าสู่ระบบ (ไม่มีการตรวจสอบรหัสผ่าน) router.post('/login', async (req, res) => { - const { username } = req.body; + const { username, password } = req.body; try { - const [rows] = await db.promise().query("SELECT * FROM user WHERE username = ?", [username]); - if (rows.length === 0) { - return res.status(400).render('auth/login', { error: 'ไม่พบชื่อผู้ใช้' }); + const [users] = await db.query('SELECT * FROM user WHERE username = ?', [username]); + if (users.length === 0) { + return res.render('auth/login', { error: 'ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง' }); } - // จำลองการล็อกอิน โดยเก็บ user ไว้ใน session - req.session.user = rows[0]; + + const user = users[0]; + const validPassword = await bcrypt.compare(password, user.password); + if (!validPassword) { + return res.render('auth/login', { error: 'ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง' }); + } + + req.session.user = user; res.redirect('/index'); } catch (error) { - console.error("Error:", error); - res.status(500).render('auth/login', { error: 'เกิดข้อผิดพลาด' }); + console.error('ข้อผิดพลาดในการล็อกอิน:', error); + res.render('auth/login', { error: 'เกิดข้อผิดพลาดในการล็อกอิน' }); } }); -// GET หน้า Register router.get('/register', (req, res) => { res.render('auth/register', { error: null }); }); -// POST การสมัครสมาชิก (ไม่มีการตรวจสอบข้อมูล) router.post('/register', async (req, res) => { const { username, email, password, phone, f_name, l_name, club_id } = req.body; try { const hashedPassword = await bcrypt.hash(password, 10); - await db.promise().query( - "INSERT INTO user (username, email, password, phone, f_name, l_name, club_id) VALUES (?, ?, ?, ?, ?, ?, ?)", - [username, email, hashedPassword, phone, f_name, l_name, club_id || null, 'member'] + await db.query( + `INSERT INTO user + (username, email, password, phone, f_name, l_name, club_id, role) + VALUES (?, ?, ?, ?, ?, ?, ?, 'member')`, + [username, email, hashedPassword, phone, f_name, l_name, club_id || null] ); res.redirect('/auth/login'); } catch (error) { - console.error("Error:", error); - res.status(500).render('auth/register', { error: 'เกิดข้อผิดพลาด' }); + console.error('ข้อผิดพลาดในการสมัครสมาชิก:', error); + res.render('auth/register', { error: 'เกิดข้อผิดพลาดในการสมัครสมาชิก' }); } }); -// GET ออกจากระบบ (Logout) router.get('/logout', (req, res) => { req.session.destroy((err) => { - if (err) console.error("Error destroying session:", err); + if (err) console.error('ข้อผิดพลาดในการออกจากระบบ:', err); res.redirect('/'); }); }); -module.exports = router; +module.exports = router; \ No newline at end of file diff --git a/routes/chatAI.js b/routes/chatAI.js deleted file mode 100644 index ba003d715a0cb9a4b0c36feabc43d1affd42dbc9..0000000000000000000000000000000000000000 --- a/routes/chatAI.js +++ /dev/null @@ -1,65 +0,0 @@ -const express = require('express'); -const axios = require('axios'); -const router = express.Router(); - -router.post('/chatAI', async (req, res) => { - try { - const { message } = req.body; - - // ตั้งค่า headers สำหรับ Server-Sent Events (SSE) - res.setHeader('Content-Type', 'text/event-stream'); - res.setHeader('Cache-Control', 'no-cache'); - res.setHeader('Connection', 'keep-alive'); - - const ollamaResponse = await axios.post( - 'http://localhost:11434/api/chat', - { - model: "deepseek-r1:latest", - messages: [ - { role: "user", content: message } - ], - stream: true - }, - { responseType: 'stream' } - ); - - // แก้ไขส่วนการรับข้อมูลจาก Ollama - ollamaResponse.data.on('data', (chunk) => { - try { - const lines = chunk.toString().split('\n'); - - for (const line of lines) { - if (!line.trim()) continue; // ข้ามบรรทัดว่าง - - try { - const parsed = JSON.parse(line); - if (parsed.message?.content) { - // ส่งข้อมูลในรูปแบบ SSE ที่ถูกต้อง - res.write(`data: ${JSON.stringify(parsed.message.content)}\n\n`); - } - } catch (err) { - console.error('JSON Parse Error:', err); - } - } - } catch (error) { - console.error('Stream error:', error); - } - }); - - ollamaResponse.data.on('end', () => { - res.end(); - }); - - ollamaResponse.data.on('error', (err) => { - console.error('Ollama stream error:', err); - res.write('event: error\ndata: "Connection failed"\n\n'); - res.end(); - }); - - } catch (error) { - console.error('API Error:', error); - res.status(500).json({ error: 'Internal server error' }); - } -}); - -module.exports = router; \ No newline at end of file diff --git a/views/pages/chatAI.ejs b/views/pages/chatAI.ejs deleted file mode 100644 index 0d6fb6e2220b7483e650d4107fd609923c96e8ba..0000000000000000000000000000000000000000 --- a/views/pages/chatAI.ejs +++ /dev/null @@ -1,87 +0,0 @@ -<%- include('../partials/header') %> - <link rel="stylesheet" href="/css/chatAI.css"> - <div class="main-content"> - <h1>คุยกับผู้ช่วย AI ของคุณ</h1> - <div id="chatBox"></div> - <div class="input-area"> - <input type="text" id="userInput" placeholder="Type your message..." style="width: 300px; padding: 8px;"> - <button onclick="sendMessage()" style="padding: 8px 16px;">Send</button> - </div> - </div> - - <script> - const chatBox = document.getElementById('chatBox'); - - async function sendMessage() { - const userInput = document.getElementById('userInput'); - const message = userInput.value.trim(); - - if (!message) return; - - // แสดงข้อความผู้ใช้ - appendMessage('user', message); - userInput.value = ''; - - try { - // สร้างข้อความบอทเริ่มต้น - const botMsgElement = appendMessage('bot', '...'); - - const response = await fetch('/api/chatAI', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ message }) - }); - - const reader = response.body.getReader(); - const decoder = new TextDecoder(); - - let accumulatedText = ''; - - // แก้ไขส่วนรับข้อมูลในฝั่งไคลเอนต์ - while (true) { - const { done, value } = await reader.read(); - if (done) break; - - const chunk = decoder.decode(value); - const events = chunk.split('\n\n'); // แยกแต่ละเหตุการณ์ SSE - - for (const event of events) { - if (!event.startsWith('data: ')) continue; - - const jsonStr = event.replace('data: ', ''); - try { - const text = JSON.parse(jsonStr); - if (text) { - accumulatedText += text; - botMsgElement.innerHTML = accumulatedText; - chatBox.scrollTop = chatBox.scrollHeight; - } - } catch (err) { - console.error('JSON Parse Error:', err); - } - } - } - } catch (err) { - console.error('Error:', err); - appendMessage('bot', 'Sorry, something went wrong.'); - } - } - - function appendMessage(sender, text) { - const msgDiv = document.createElement('div'); - msgDiv.className = `message ${sender}-message`; - - const prefix = sender === 'user' ? - '<strong>You:</strong> ' : - '<strong>Bot:</strong> '; - - msgDiv.innerHTML = prefix + text; - chatBox.appendChild(msgDiv); - - // Scroll to bottom - chatBox.scrollTop = chatBox.scrollHeight; - return msgDiv; - } - </script> - - </html> \ No newline at end of file