配套后端(Node.js + Express + SQLite)

配套后端(Node.js + Express + SQLite) ,实现完整的:

  • 👤 用户表(users)
  • 🧩 角色表(roles)
  • 🔐 权限点表(permissions)
  • 🔗 角色权限关联表(role_permissions)
  • 🔗 用户角色关联表(user_roles)

并提供标准 REST 接口供前端(Naive Admin)调用。


📁 项目结构

markdown 复制代码
backend/
  server.js
  db.js
  routes/
    users.js
    roles.js
    permissions.js
  schema.sql

📁 db.js --- SQLite 初始化

sql 复制代码
import sqlite3 from "sqlite3";
import { open } from "sqlite";

export async function initDB() {
  const db = await open({
    filename: "./data.db",
    driver: sqlite3.Database
  });

  await db.exec(`
    CREATE TABLE IF NOT EXISTS users (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      nickname TEXT,
      phone TEXT
    );

    CREATE TABLE IF NOT EXISTS roles (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      name TEXT,
      description TEXT
    );

    CREATE TABLE IF NOT EXISTS permissions (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      key TEXT,
      label TEXT
    );

    CREATE TABLE IF NOT EXISTS user_roles (
      user_id INTEGER,
      role_id INTEGER,
      PRIMARY KEY (user_id, role_id)
    );

    CREATE TABLE IF NOT EXISTS role_permissions (
      role_id INTEGER,
      permission_id INTEGER,
      PRIMARY KEY (role_id, permission_id)
    );
  `);

  return db;
}

📁 routes/users.js

vbnet 复制代码
import express from "express";
export default function (db) {
  const router = express.Router();

  // 查询所有用户及其角色
  router.get("/", async (req, res) => {
    const users = await db.all(`
      SELECT u.id, u.nickname, u.phone,
             group_concat(r.name) as roleNames,
             group_concat(r.id) as roleIds
      FROM users u
      LEFT JOIN user_roles ur ON u.id = ur.user_id
      LEFT JOIN roles r ON ur.role_id = r.id
      GROUP BY u.id
    `);
    res.json(users);
  });

  router.post("/", async (req, res) => {
    const { nickname, phone, roleIds = [] } = req.body;
    const result = await db.run("INSERT INTO users (nickname, phone) VALUES (?,?)", [nickname, phone]);
    const userId = result.lastID;
    for (const r of roleIds) {
      await db.run("INSERT INTO user_roles (user_id, role_id) VALUES (?,?)", [userId, r]);
    }
    res.sendStatus(201);
  });

  router.put("/:id", async (req, res) => {
    const { nickname, phone, roleIds = [] } = req.body;
    await db.run("UPDATE users SET nickname=?, phone=? WHERE id=?", [nickname, phone, req.params.id]);
    await db.run("DELETE FROM user_roles WHERE user_id=?", [req.params.id]);
    for (const r of roleIds) {
      await db.run("INSERT INTO user_roles (user_id, role_id) VALUES (?,?)", [req.params.id, r]);
    }
    res.sendStatus(200);
  });

  router.delete("/:id", async (req, res) => {
    await db.run("DELETE FROM users WHERE id=?", [req.params.id]);
    await db.run("DELETE FROM user_roles WHERE user_id=?", [req.params.id]);
    res.sendStatus(200);
  });

  return router;
}

📁 routes/roles.js

csharp 复制代码
import express from "express";

export default function (db) {
  const router = express.Router();

  router.get("/", async (req, res) => {
    const roles = await db.all("SELECT * FROM roles");
    res.json(roles);
  });

  router.post("/", async (req, res) => {
    const { name, description } = req.body;
    await db.run("INSERT INTO roles (name, description) VALUES (?,?)", [name, description]);
    res.sendStatus(201);
  });

  router.put("/:id", async (req, res) => {
    const { name, description } = req.body;
    await db.run("UPDATE roles SET name=?, description=? WHERE id=?", [name, description, req.params.id]);
    res.sendStatus(200);
  });

  router.delete("/:id", async (req, res) => {
    await db.run("DELETE FROM roles WHERE id=?", [req.params.id]);
    await db.run("DELETE FROM role_permissions WHERE role_id=?", [req.params.id]);
    res.sendStatus(200);
  });

  // 更新角色的权限
  router.post("/:id/permissions", async (req, res) => {
    const { permIds = [] } = req.body;
    await db.run("DELETE FROM role_permissions WHERE role_id=?", [req.params.id]);
    for (const p of permIds) {
      await db.run("INSERT INTO role_permissions (role_id, permission_id) VALUES (?,?)", [req.params.id, p]);
    }
    res.sendStatus(200);
  });

  return router;
}

📁 routes/permissions.js

dart 复制代码
import express from "express";

export default function (db) {
  const router = express.Router();

  router.get("/", async (req, res) => {
    const perms = await db.all("SELECT id as key, label FROM permissions");
    res.json(perms);
  });

  router.post("/", async (req, res) => {
    const { key, label } = req.body;
    await db.run("INSERT INTO permissions (key, label) VALUES (?,?)", [key, label]);
    res.sendStatus(201);
  });

  router.delete("/:id", async (req, res) => {
    await db.run("DELETE FROM permissions WHERE id=?", [req.params.id]);
    await db.run("DELETE FROM role_permissions WHERE permission_id=?", [req.params.id]);
    res.sendStatus(200);
  });

  return router;
}

📁 server.js

javascript 复制代码
import express from "express";
import cors from "cors";
import { initDB } from "./db.js";
import usersRouter from "./routes/users.js";
import rolesRouter from "./routes/roles.js";
import permsRouter from "./routes/permissions.js";

const app = express();
app.use(cors());
app.use(express.json());

const db = await initDB();

app.use("/api/users", usersRouter(db));
app.use("/api/roles", rolesRouter(db));
app.use("/api/permissions", permsRouter(db));

app.listen(3001, () => {
  console.log("✅ 后端服务已启动:http://localhost:3001");
});

📌 功能总结

  • 用户表:users(id、nickname、phone)

  • 角色表:roles(id、name、description)

  • 权限点表:permissions(id、key、label)

  • 关联:

    • user_roles(多对多)
    • role_permissions(多对多)
  • 支持接口:

    • GET/POST/PUT/DELETE 用户
    • GET/POST/PUT/DELETE 角色 + 分配权限
    • GET/POST/DELETE 权限点

与前端 Naive Admin 模板完全匹配。


✅ 使用方式

vbscript 复制代码
npm install express sqlite3 sqlite cors
node server.js
  • 前端调用 http://localhost:3001/api/... 接口
  • 即可实现 用户列表 + 角色分配 + 权限点管理

相关推荐
风象南6 分钟前
SpringBoot 时间轮实现延时任务
后端
Victor35610 分钟前
Redis(93)Redis的数据加密机制是什么?
后端
Victor35612 分钟前
Redis(92)如何配置Redis的ACL?
后端
有你有我OK1 小时前
springboot Admin 服务端 客户端配置
spring boot·后端·elasticsearch
xiaoopin3 小时前
简单的分布式锁 SpringBoot Redisson‌
spring boot·分布式·后端
你的人类朋友8 小时前
设计模式有哪几类?
前端·后端·设计模式
Yeats_Liao8 小时前
Go Web 编程快速入门 10 - 数据库集成与ORM:连接池、查询优化与事务管理
前端·数据库·后端·golang
你的人类朋友9 小时前
适配器模式:适配就完事了bro!
前端·后端·设计模式
间彧10 小时前
SpringBoot集成RocketMQ事务消息
后端