const { Sequelize } = require('sequelize');

// 使用提供的数据库配置：root用户，密码123456，数据库名blog_db
const sequelize = new Sequelize('mysql://root:123456@localhost:3306/blog_db');

// 测试数据库连接
sequelize.authenticate()
    .then(() => console.log('Database connected successfully'))
    .catch((err) => console.error('Unable to connect to the database:', err));

module.exports = sequelize;

const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const User = require('../models/User');

// 用户注册
const registerUser = async (req, res) => {
    const { username, password } = req.body;
    try {
        const newUser = await User.create({ username, password });
        res.status(201).json({ message: '注册成功', user: newUser });
    } catch (error) {
        res.status(400).json({ message: '注册失败', error });
    }
};

// 用户登录
const loginUser = async (req, res) => {
    const { username, password } = req.body;
    const user = await User.findOne({ where: { username } });

    if (!user) {
        return res.status(400).json({ message: '用户不存在' });
    }

    const isMatch = await bcrypt.compare(password, user.password);

    if (isMatch) {
        const token = jwt.sign({ id: user.id }, 'secret_key', { expiresIn: '1h' });
        res.json({ message: '登录成功', token });
    } else {
        res.status(400).json({ message: '密码错误' });
    }
};

module.exports = { registerUser, loginUser };

const { Sequelize } = require('sequelize');
const Blog = require('../models/Blog');

// 获取所有博客文章
const getBlogs = async (req, res) => {
    try {
        // 从数据库获取所有博客文章
        const blogs = await Blog.findAll({
            order: [['createdAt', 'DESC']]  // 按照创建时间倒序排列
        });

        // 将博客数据传递给视图
        res.render('index', { blogs });
    } catch (error) {
        console.error('获取博客失败:', error);  // 打印错误信息
        res.status(500).json({ message: '获取博客失败', error });
    }
};

// 发布博客文章
const createBlog = async (req, res) => {
    const { title, content, category } = req.body;
    try {
        // 创建新的博客文章
        const newBlog = await Blog.create({ title, content, category });

        // 重定向到博客首页
        res.redirect('/');
    } catch (error) {
        console.error('发布文章失败:', error);  // 打印错误信息
        res.status(400).json({ message: '发布文章失败', error });
    }
};

// 获取所有标签（博客文章的分类）
const getTags = async (req, res) => {
    try {
        // 获取所有不重复的标签
        const tags = await Blog.findAll({
            attributes: [
                [Sequelize.fn('DISTINCT', Sequelize.col('category')), 'category']
            ]
        });

        // 将标签数据以数组的形式返回
        res.json(tags.map(tag => tag.category));
    } catch (error) {
        console.error('获取标签失败:', error);  // 打印错误信息
        res.status(500).json({ message: '获取标签失败', error });
    }
};

module.exports = { getBlogs, createBlog, getTags };

const { Sequelize, DataTypes } = require('sequelize');
const sequelize = require('../config/db');

const Blog = sequelize.define('Blog', {
    title: {
        type: DataTypes.STRING,
        allowNull: false
    },
    content: {
        type: DataTypes.TEXT,
        allowNull: false
    },
    category: {
        type: DataTypes.STRING,
        allowNull: false
    },
    createdAt: {
        type: DataTypes.DATE,
        defaultValue: Sequelize.NOW
    }
});

module.exports = Blog;

const { Sequelize, DataTypes } = require('sequelize');
const sequelize = require('../config/db');
const bcrypt = require('bcryptjs');

const User = sequelize.define('User', {
    username: {
        type: DataTypes.STRING,
        allowNull: false,
        unique: true
    },
    password: {
        type: DataTypes.STRING,
        allowNull: false
    }
});

// 注册前加密密码
User.beforeCreate(async (user) => {
    user.password = await bcrypt.hash(user.password, 10);
});

module.exports = User;

const express = require('express');
const { getBlogs, createBlog, getTags } = require('../controllers/blogController');
const router = express.Router();

// 博客列表
router.get('/', getBlogs);

// 发布博客
router.post('/publish', createBlog);

// 获取标签
router.get('/tags', getTags);

module.exports = router;

const express = require('express');
const { registerUser, loginUser } = require('../controllers/authController');
const router = express.Router();

// 注册路由
router.get('/register', (req, res) => {
    res.render('register');
});
router.post('/register', registerUser);

// 登录路由
router.get('/login', (req, res) => {
    res.render('login');
});
router.post('/login', loginUser);

module.exports = router;

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>博客系统</title>
  <style>
    /* 全局样式 */
    body {
      font-family: Arial, sans-serif;
      background-color: #f4f7fc;
      color: #333;
      margin: 0;
      padding: 0;
    }

    h1 {
      text-align: center;
      margin: 20px 0;
      color: #2c3e50;
    }

    /* 导航栏 */
    nav {
      background-color: #2c3e50;
      padding: 10px 0;
      text-align: center;
    }

    nav a {
      color: white;
      font-size: 16px;
      text-decoration: none;
      padding: 10px 15px;
      margin: 0 10px;
      border-radius: 4px;
      transition: background-color 0.3s;
    }

    nav a:hover {
      background-color: #34495e;
    }

    /* 博客列表 */
    #blogs {
      width: 80%;
      margin: 30px auto;
      padding: 20px;
      background-color: #fff;
      border-radius: 8px;
      box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
    }

    h2 {
      font-size: 24px;
      color: #2c3e50;
      border-bottom: 2px solid #ecf0f1;
      padding-bottom: 10px;
      margin-bottom: 20px;
    }

    .blog-post {
      background-color: #ecf0f1;
      padding: 15px;
      margin-bottom: 20px;
      border-radius: 6px;
      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
      transition: transform 0.3s;
    }

    .blog-post:hover {
      transform: translateY(-5px);
    }

    .blog-post h3 {
      color: #3498db;
      font-size: 22px;
      margin: 0 0 10px;
    }

    .blog-post p {
      font-size: 16px;
      line-height: 1.6;
      color: #555;
    }

    .blog-post small {
      display: block;
      margin-top: 10px;
      color: #7f8c8d;
      font-size: 14px;
    }

    .no-blogs {
      font-size: 18px;
      color: #e74c3c;
      text-align: center;
      margin-top: 30px;
    }
  </style>
</head>
<body>

<h1>欢迎来到博客系统</h1>

<!-- 导航栏 -->
<nav>
  <a href="/user/login">登录</a> |
  <a href="/user/register">注册</a> |
  <a href="/blog">查看博客</a>
</nav>

<!-- 博客内容 -->
<div id="blogs">
  <h2>博客列表</h2>

  <% if (blogs && blogs.length > 0) { %>
    <% blogs.forEach(blog => { %>
      <div class="blog-post">
        <h3><%= blog.title %></h3>
        <p><%= blog.content %></p>
        <small>分类: <%= blog.category %></small>
        <small>创建时间: <%= blog.createdAt.toISOString().slice(0, 19).replace("T", " ") %></small>
      </div>
    <% }) %>
  <% } else { %>
    <p class="no-blogs">暂无博客内容。</p> <!-- 如果没有博客，显示提示 -->
  <% } %>
</div>

</body>
</html>

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>登录</title>
  <style>
    /* 全局样式 */
    body {
      font-family: Arial, sans-serif;
      background-color: #f4f7fc;
      color: #333;
      margin: 0;
      padding: 0;
    }

    h1 {
      text-align: center;
      margin-top: 30px;
      color: #2c3e50;
    }

    /* 表单容器 */
    .form-container {
      width: 400px;
      margin: 30px auto;
      padding: 30px;
      background-color: #fff;
      border-radius: 8px;
      box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
    }

    .form-container input {
      width: 100%;
      padding: 12px;
      margin: 10px 0;
      border: 1px solid #ccc;
      border-radius: 4px;
      font-size: 16px;
    }

    .form-container button {
      width: 100%;
      padding: 12px;
      background-color: #3498db;
      color: white;
      font-size: 16px;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      transition: background-color 0.3s;
    }

    .form-container button:hover {
      background-color: #2980b9;
    }

    .form-container p {
      text-align: center;
      color: #7f8c8d;
    }

    .form-container a {
      color: #3498db;
      text-decoration: none;
    }

    .form-container a:hover {
      text-decoration: underline;
    }
  </style>
</head>
<body>

<h1>登录</h1>

<!-- 登录表单 -->
<div class="form-container">
  <form action="/user/login" method="POST">
    <input type="text" name="username" placeholder="用户名" required>
    <input type="password" name="password" placeholder="密码" required>
    <button type="submit">登录</button>
  </form>

  <p>没有账号? <a href="/user/register">点击注册</a></p>
</div>

</body>
</html>

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>注册</title>
  <style>
    /* 全局样式 */
    body {
      font-family: Arial, sans-serif;
      background-color: #f4f7fc;
      color: #333;
      margin: 0;
      padding: 0;
    }

    h1 {
      text-align: center;
      margin-top: 30px;
      color: #2c3e50;
    }

    /* 表单容器 */
    .form-container {
      width: 400px;
      margin: 30px auto;
      padding: 30px;
      background-color: #fff;
      border-radius: 8px;
      box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
    }

    .form-container input {
      width: 100%;
      padding: 12px;
      margin: 10px 0;
      border: 1px solid #ccc;
      border-radius: 4px;
      font-size: 16px;
    }

    .form-container button {
      width: 100%;
      padding: 12px;
      background-color: #3498db;
      color: white;
      font-size: 16px;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      transition: background-color 0.3s;
    }

    .form-container button:hover {
      background-color: #2980b9;
    }

    .form-container p {
      text-align: center;
      color: #7f8c8d;
    }

    .form-container a {
      color: #3498db;
      text-decoration: none;
    }

    .form-container a:hover {
      text-decoration: underline;
    }
  </style>
</head>
<body>

<h1>注册</h1>

<!-- 注册表单 -->
<div class="form-container">
  <form action="/user/register" method="POST">
    <input type="text" name="username" placeholder="用户名" required>
    <input type="password" name="password" placeholder="密码" required>
    <button type="submit">注册</button>
  </form>

  <p>已有账号? <a href="/user/login">点击登录</a></p>
</div>

</body>
</html>

const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const userRoutes = require('./routes/userRoutes');
const blogRoutes = require('./routes/blogRoutes');
const app = express();

// 配置静态文件
app.use(express.static(path.join(__dirname, 'public')));

// 配置 body-parser
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

// 设置视图引擎为 EJS
app.set('view engine', 'ejs');

// 使用路由
app.use('/user', userRoutes);
app.use('/blog', blogRoutes);

// 主页路由，调用博客控制器
app.get('/', require('./controllers/blogController').getBlogs);

// 启动服务器
app.listen(3000, () => {
    console.log('Server running on http://localhost:3000');
});

我想注册成功转到登录界面，登录成功转到index界面