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

相关推荐
大学生资源网10 分钟前
基于springboot的万亩助农网站的设计与实现源代码(源码+文档)
java·spring boot·后端·mysql·毕业设计·源码
苏三的开发日记20 分钟前
linux端进行kafka集群服务的搭建
后端
苏三的开发日记38 分钟前
windows系统搭建kafka环境
后端
爬山算法1 小时前
Netty(19)Netty的性能优化手段有哪些?
java·后端
Tony Bai1 小时前
Cloudflare 2025 年度报告发布——Go 语言再次“屠榜”API 领域,AI 流量激增!
开发语言·人工智能·后端·golang
想用offer打牌1 小时前
虚拟内存与寻址方式解析(面试版)
java·后端·面试·系统架构
無量1 小时前
AQS抽象队列同步器原理与应用
后端
9号达人2 小时前
支付成功订单却没了?MyBatis连接池的坑我踩了
java·后端·面试
用户497357337982 小时前
【轻松掌握通信协议】C#的通信过程与协议实操 | 2024全新
后端
草莓熊Lotso2 小时前
C++11 核心精髓:类新功能、lambda与包装器实战
开发语言·c++·人工智能·经验分享·后端·nginx·asp.net