本指南将带你从零构建一个轻量级的公路工程档案管理系统。为了确保零门槛落地,我们选择 Node.js (Express) 作为后端,Vue 3 + Element Plus 作为前端,SQLite 作为数据库。SQLite 是文件型数据库,无需安装任何数据库服务即可运行,非常适合工程一线人员在笔记本电脑或内网服务器上使用。
在开始之前,请确保你的电脑已安装 Node.js(建议版本 v16 以上)。如果没有安装,请访问 https://nodejs.org/ 下载 LTS 版本并一键安装。
首先创建项目根目录 road-archive-system,并在该目录下创建 server 文件夹用于存放后端代码。
打开命令行工具,进入 server 目录,执行以下命令初始化项目并安装依赖包:
cd road-archive-system
mkdir server
cd server
npm init -y
npm install express sqlite3 cors multer body-parser
依赖说明:
- express:Web 框架,用于构建 API 接口。
- sqlite3:嵌入式数据库引擎。
- cors:解决跨域问题。
- multer:处理文件上传(档案上传核心组件)。
在 server 目录下创建 database.js 文件。我们将设计两张核心表:projects(公路工程项目表)和 archives(档案明细表)。
const sqlite3 = require('sqlite3').verbose();
const path = require('path');
const dbPath = path.resolve(__dirname, 'road_archive.db');
const db = new sqlite3.Database(dbPath);
// 初始化数据库表结构
db.serialize(() => {
// 1. 创建工程项目表
db.run(`CREATE TABLE IF NOT EXISTS projects (
id INTEGER PRIMARY KEY AUTOINCREMENT,
project_name TEXT NOT NULL,
contract_section TEXT, // 合同段
start_stake TEXT, // 起止桩号
end_stake TEXT,
create_time DATETIME DEFAULT CURRENT_TIMESTAMP
)`);
// 2. 创建档案表
db.run(`CREATE TABLE IF NOT EXISTS archives (
id INTEGER PRIMARY KEY AUTOINCREMENT,
project_id INTEGER,
category TEXT, // 档案分类:如路基、路面、桥梁
file_name TEXT,
file_path TEXT,
uploader TEXT,
upload_time DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY(project_id) REFERENCES projects(id)
)`);
});
module.exports = db;
在 server 目录下创建 index.js,实现项目增删改查和档案上传功能。以下是完整的后端代码,复制即可使用:
const express = require('express');
const cors = require('cors');
const multer = require('multer');
const path = require('path');
const fs = require('fs');
const db = require('./database');
const app = express();
const PORT = 3000;
app.use(cors());
app.use(express.json());
// 配置文件上传存储目录
const uploadDir = path.join(__dirname, 'uploads');
if (!fs.existsSync(uploadDir)){
fs.mkdirSync(uploadDir);
}
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, uploadDir);
},
filename: (req, file, cb) => {
// 保持文件原名称,添加时间戳防止重名
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() 1E9);
cb(null, uniqueSuffix + '-' + file.originalname);
}
});
const upload = multer({ storage: storage });
// API 接口
// 1. 获取所有项目列表
app.get('/api/projects', (req, res) => {
db.all("SELECT FROM projects ORDER BY create_time DESC", [], (err, rows) => {
if (err) return res.status(500).json({ error: err.message });
res.json(rows);
});
});
// 2. 新增项目
app.post('/api/projects', (req, res) => {
const { project_name, contract_section, start_stake, end_stake } = req.body;
const sql = "INSERT INTO projects (project_name, contract_section, start_stake, end_stake) VALUES (?, ?, ?, ?)";
db.run(sql, [project_name, contract_section, start_stake, end_stake], function(err) {
if (err) return res.status(500).json({ error: err.message });
res.json({ id: this.lastID });
});
});
// 3. 获取指定项目的档案列表
app.get('/api/archives/:projectId', (req, res) => {
const { projectId } = req.params;
db.all("SELECT FROM archives WHERE project_id = ? ORDER BY upload_time DESC", [projectId], (err, rows) => {
if (err) return res.status(500).json({ error: err.message });
res.json(rows);
});
});
// 4. 上传档案
app.post('/api/upload', upload.single('file'), (req, res) => {
if (!req.file) return res.status(400).json({ error: "No file uploaded" });
const { project_id, category, uploader } = req.body;
const sql = "INSERT INTO archives (project_id, category, file_name, file_path, uploader) VALUES (?, ?, ?, ?, ?)";
db.run(sql, [project_id, category, req.file.originalname, req.file.filename, uploader], function(err) {
if (err) return res.status(500).json({ error: err.message });
res.json({ message: "File uploaded successfully", id: this.lastID });
});
});
// 启动服务
app.listen(PORT, () => {
console.log(`Server running at http://localhost:${PORT}`);
});
此时,后端服务已搭建完成。在命令行输入 node index.js 即可启动后端。
回到项目根目录 road-archive-system,我们使用 Vite 快速构建前端界面。

执行以下命令创建 Vue 项目并安装 UI 组件库 Element Plus(用于快速生成美观的表格和表单):
cd ..
npm create vite@latest client -- --template vue
cd client
npm install
npm install element-plus axios
npm run dev
修改 client/src/main.js,引入 Element Plus 样式和组件:
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
const app = createApp(App)
app.use(ElementPlus)
app.mount('app')
修改 client/src/App.vue。我们将界面分为左右两栏:左侧为工程项目列表,右侧为当前选中项目的档案管理与上传区域。代码如下:
公路工程项目列表
新建项目
{{ currentProject.project_name }} - 档案管理
上传新档案
选择文件
确认上传
已归档列表
请选择左侧项目查看档案
-
取消
创建
代码编写完毕,现在启动整个系统进行实际操作验证。
打开第一个终端窗口,进入 server 目录:
cd server
node index.js
终端显示 Server running at http://localhost:3000 表示后端启动成功,且会自动在当前目录生成 road_archive.db 数据库文件。
打开第二个终端窗口,进入 client 目录:
cd client
npm run dev
终端会显示 Local 地址,通常是 http://localhost:5173。使用浏览器访问该地址。
以上是开发环境运行。若需在实际工程管理中使用,建议执行以下打包步骤:
client 目录运行 npm run build,这将生成 dist 文件夹。将 dist 文件夹内的所有文件复制到 Nginx 或 Apache 的 Web 根目录。