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

相关推荐
TechTrek3 分钟前
Spring Boot 4.0正式发布了
java·spring boot·后端·spring boot 4.0
飞梦工作室23 分钟前
企业级 Spring Boot 邮件系统开发指南:从基础到高可用架构设计
java·spring boot·后端
haiyu柠檬25 分钟前
在Spring Boot中实现Azure的SSO+VUE3前端配置
java·spring boot·后端
q***721934 分钟前
springBoot 和springCloud 版本对应关系
spring boot·后端·spring cloud
百***81271 小时前
【SpringBoot】SpringBoot中分页插件(PageHelper)的使用
java·spring boot·后端
百***86461 小时前
SpringBoot中自定义Starter
java·spring boot·后端
q***07141 小时前
VScode 开发 Springboot 程序
java·spring boot·后端
q***46521 小时前
Spring中使用Async进行异步功能开发实战-以大文件上传为例
java·后端·spring
Codebee2 小时前
Qoder CLI 与 OneCode 平台深度整合技术实践:CLI委托驱动的开发范式革新
后端
码事漫谈2 小时前
C++程序执行起点不是main:颠覆你认知的真相
后端