配套后端(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/... 接口
  • 即可实现 用户列表 + 角色分配 + 权限点管理

相关推荐
isysc12 小时前
面了一个校招生,竟然说我是老古董
java·后端·面试
uhakadotcom2 小时前
静态代码检测技术入门:Python 的 Tree-sitter 技术详解与示例教程
后端·面试·github
幂简集成explinks2 小时前
e签宝签署API更新实战:新增 signType 与 FDA 合规参数配置
后端·设计模式·开源
River4162 小时前
Javer 学 c++(十三):引用篇
c++·后端
RoyLin2 小时前
TypeScript设计模式:迭代器模式
javascript·后端·node.js
爱海贼的无处不在3 小时前
一个需求竟然要开14个会:程序员的日常到底有多“会”?
后端·程序员
IT_陈寒4 小时前
Java 性能优化:5个被低估的JVM参数让你的应用吞吐量提升50%
前端·人工智能·后端
南囝coding4 小时前
《独立开发者精选工具》第 018 期
前端·后端