在线咨询
开发教程

【保姆级】管理系统实战

微易网络
2026年2月11日 15:09
0 次阅读
【保姆级】管理系统实战

本文是一份面向初学者的“保姆级”实战指南,旨在手把手教你从零开始构建一个功能完整的员工信息管理系统。文章将详细演示如何运用网站开发技术(HTML、CSS、JavaScript、Node.js)实现系统核心,并确保其具备响应式设计以适配移动端。最后,指南会涵盖将系统部署到Linux服务器并实现公网访问的全过程。无论你是零基础新手还是有一定经验的开发者,都能通过本文学到清晰的开发路径和实用的代码实践。

引言:从零到一,构建你的第一个管理系统

在数字化浪潮中,无论是初创企业还是成熟公司,一套高效、稳定的内部管理系统都是提升运营效率的核心。然而,对于许多初学者或非专业开发者而言,“管理系统”这个词听起来既庞大又复杂,涉及前端、后端、数据库、服务器部署等诸多环节,令人望而却步。

本文旨在提供一个“保姆级”的实战指南,我们将手把手带你构建一个简易但功能完整的员工信息管理系统。这个项目将巧妙地串联起你提到的几个关键词:我们将使用网站开发技术(HTML, CSS, JavaScript, Node.js)来构建系统核心,其响应式设计能让它在手机端像APP一样良好运行,最后我们会将其部署到Linux服务器上,实现公网访问。无论你是零基础,还是有一定经验的开发者,都能从中获得清晰的路径和实用的代码。

一、 项目规划与技术栈选择

在动手写代码之前,清晰的规划是成功的一半。我们的目标是创建一个具备增删改查(CRUD)功能的员工信息管理系统。

1.1 系统功能与架构

  • 前端(用户界面):展示员工列表,提供表单用于添加/编辑员工信息,并实现删除操作。为了达到类似APP的体验,我们将采用响应式设计。
  • 后端(服务器逻辑):接收前端请求,处理业务逻辑(如数据验证),并与数据库进行交互。
  • 数据库:持久化存储员工数据,包括ID、姓名、部门、职位、入职日期等字段。

1.2 技术栈确定

为了兼顾易学性和实用性,我们选择以下“全JavaScript”方案:

  • 前端:纯HTML、CSS、JavaScript(使用Fetch API与后端通信)。无需复杂框架,突出原理。
  • 后端:Node.js + Express.js。Express是Node.js最流行的Web框架,简洁高效。
  • 数据库:SQLite(开发阶段) / MySQL(生产部署)。SQLite无需安装服务器,一个文件即数据库,非常适合学习和原型开发。
  • 服务器:Linux(如Ubuntu 20.04 LTS)。我们将学习如何在云服务器上部署我们的应用。

二、 开发环境搭建与后端构建

让我们从搭建后端服务开始,这是整个系统的“大脑”。

2.1 初始化项目与安装依赖

首先,确保你的电脑已安装 Node.js。然后打开终端,执行以下命令:

# 1. 创建项目文件夹并进入
mkdir employee-management-system
cd employee-management-system

# 2. 初始化Node.js项目,生成package.json文件
npm init -y

# 3. 安装必要的依赖包
npm install express sqlite3 cors
  • express: Web 框架。
  • sqlite3: 用于操作SQLite数据库。
  • cors: 处理跨域请求,便于前后端分离开发。

2.2 创建数据库与后端API

在项目根目录下,创建一个名为 server.js 的文件,并写入以下代码:

const express = require('express');
const sqlite3 = require('sqlite3').verbose();
const cors = require('cors');

const app = express();
const port = 3000;

// 启用CORS和JSON解析中间件
app.use(cors());
app.use(express.json());

// 连接SQLite数据库(如果文件不存在会自动创建)
const db = new sqlite3.Database('./employee.db', (err) => {
    if (err) {
        console.error('数据库连接失败:', err.message);
    } else {
        console.log('成功连接到SQLite数据库。');
        // 创建员工表
        db.run(`CREATE TABLE IF NOT EXISTS employees (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            name TEXT NOT NULL,
            department TEXT,
            position TEXT,
            hire_date TEXT
        )`);
    }
});

// 1. 获取所有员工 - GET /api/employees
app.get('/api/employees', (req, res) => {
    const sql = `SELECT * FROM employees ORDER BY id DESC`;
    db.all(sql, [], (err, rows) => {
        if (err) {
            res.status(400).json({ "error": err.message });
            return;
        }
        res.json({
            "message": "success",
            "data": rows
        });
    });
});

// 2. 创建新员工 - POST /api/employees
app.post('/api/employees', (req, res) => {
    const { name, department, position, hire_date } = req.body;
    const sql = `INSERT INTO employees (name, department, position, hire_date) VALUES (?, ?, ?, ?)`;
    db.run(sql, [name, department, position, hire_date], function(err) {
        if (err) {
            res.status(400).json({ "error": err.message });
            return;
        }
        res.json({
            "message": "success",
            "data": { id: this.lastID, ...req.body }
        });
    });
});

// 3. 更新员工信息 - PUT /api/employees/:id
app.put('/api/employees/:id', (req, res) => {
    const { name, department, position, hire_date } = req.body;
    const sql = `UPDATE employees SET name=?, department=?, position=?, hire_date=? WHERE id=?`;
    db.run(sql, [name, department, position, hire_date, req.params.id], function(err) {
        if (err) {
            res.status(400).json({ "error": err.message });
            return;
        }
        res.json({
            "message": "success",
            "changes": this.changes // 返回受影响的行数
        });
    });
});

// 4. 删除员工 - DELETE /api/employees/:id
app.delete('/api/employees/:id', (req, res) => {
    const sql = `DELETE FROM employees WHERE id = ?`;
    db.run(sql, req.params.id, function(err) {
        if (err) {
            res.status(400).json({ "error": err.message });
            return;
        }
        res.json({ "message": "deleted", changes: this.changes });
    });
});

// 启动服务器
app.listen(port, () => {
    console.log(`后端服务器运行在 http://localhost:${port}`);
});

运行 node server.js,如果看到成功提示,说明你的后端API服务已经就绪!你可以使用Postman等工具测试 GET http://localhost:3000/api/employees 等接口。

三、 前端界面开发与交互实现

后端准备好后,我们来构建用户能看到和操作的界面。

3.1 创建HTML结构与基础样式

在项目根目录创建 index.html 和一个 style.css 文件。HTML结构包含一个表单和一个用于展示列表的表格区域。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>员工信息管理系统</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <h1>员工信息管理</h1>
        <form id="employeeForm">
            <input type="hidden" id="employeeId">
            <input type="text" id="name" placeholder="姓名" required>
            <input type="text" id="department" placeholder="部门">
            <input type="text" id="position" placeholder="职位">
            <input type="date" id="hire_date">
            <button type="submit" id="saveBtn">添加员工</button>
            <button type="button" id="cancelBtn">取消编辑</button>
        </form>
        <div id="message"></div>
        <table id="employeeTable">
            <thead>
                <tr><th>ID</th><th>姓名</th><th>部门</th><th>职位</th><th>入职日期</th><th>操作</th></tr>
            </thead>
            <tbody>
                <!-- 员工数据将通过JavaScript动态插入 -->
            </tbody>
        </table>
    </div>
    <script src="app.js"></script>
</body>
</html>

style.css 中,使用媒体查询(@media)实现响应式布局,确保在手机等小屏幕设备上表格和表单也能正常显示,获得近似APP的体验。

3.2 使用JavaScript实现核心交互逻辑

创建 app.js, 这是前端的“大脑”,负责与后端API通信并更新界面。

const API_BASE_URL = 'http://localhost:3000/api';
const form = document.getElementById('employeeForm');
const tableBody = document.querySelector('#employeeTable tbody');
const messageDiv = document.getElementById('message');

// 页面加载时获取并渲染员工列表
document.addEventListener('DOMContentLoaded', fetchEmployees);

// 表单提交事件(用于添加和更新)
form.addEventListener('submit', async (e) => {
    e.preventDefault();
    const id = document.getElementById('employeeId').value;
    const employeeData = {
        name: document.getElementById('name').value,
        department: document.getElementById('department').value,
        position: document.getElementById('position').value,
        hire_date: document.getElementById('hire_date').value
    };

    const url = id ? `${API_BASE_URL}/employees/${id}` : `${API_BASE_URL}/employees`;
    const method = id ? 'PUT' : 'POST';

    try {
        const response = await fetch(url, {
            method: method,
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(employeeData)
        });
        const result = await response.json();
        showMessage(id ? '员工信息更新成功!' : '员工添加成功!', 'success');
        resetForm();
        fetchEmployees(); // 刷新列表
    } catch (error) {
        showMessage('操作失败:' + error.message, 'error');
    }
});

// 获取员工列表函数
async function fetchEmployees() {
    try {
        const response = await fetch(`${API_BASE_URL}/employees`);
        const result = await response.json();
        renderEmployeeTable(result.data);
    } catch (error) {
        showMessage('加载员工列表失败', 'error');
    }
}

// 渲染表格函数
function renderEmployeeTable(employees) {
    tableBody.innerHTML = '';
    employees.forEach(emp => {
        const row = tableBody.insertRow();
        row.innerHTML = `
            ${emp.id}
            ${emp.name}
            ${emp.department}
            ${emp.position}
            ${emp.hire_date}
            
                
                
            
        `;
    });
}

// 编辑员工函数(填充表单)
function editEmployee(id, name, department, position, hire_date) {
    document.getElementById('employeeId').value = id;
    document.getElementById('name').value = name;
    document.getElementById('department').value = department;
    document.getElementById('position').value = position;
    document.getElementById('hire_date').value = hire_date;
    document.getElementById('saveBtn').textContent = '更新员工';
    document.getElementById('cancelBtn').style.display = 'inline-block';
}

// 删除员工函数
async function deleteEmployee(id) {
    if (!confirm('确定要删除这名员工吗?')) return;
    try {
        const response = await fetch(`${API_BASE_URL}/employees/${id}`, { method: 'DELETE' });
        const result = await response.json();
        showMessage('员工删除成功!', 'success');
        fetchEmployees();
    } catch (error) {
        showMessage('删除失败', 'error');
    }
}

// 辅助函数:显示消息和重置表单
function showMessage(msg, type) {
    messageDiv.textContent = msg;
    messageDiv.className = `message ${type}`;
    setTimeout(() => messageDiv.textContent = '', 3000);
}
function resetForm() {
    form.reset();
    document.getElementById('employeeId').value = '';
    document.getElementById('saveBtn').textContent = '添加员工';
    document.getElementById('cancelBtn').style.display = 'none';
}
// 取消编辑按钮事件
document.getElementById('cancelBtn').addEventListener('click', resetForm);

现在,用浏览器打开 index.html(你可能需要启动一个本地静态服务器,如使用VSCode的Live Server插件),就可以完整地测试整个系统的增删改查功能了!

四、 部署到Linux服务器

让本地项目在互联网上可访问,是最后也是关键的一步。我们将使用一台Ubuntu Linux云服务器。

4.1 服务器准备与文件上传

  • 购买一台云服务器(如腾讯云、阿里云的Ubuntu 20.04实例)。
  • 使用SSH工具(如Termius, Xshell)连接到服务器。
  • 在服务器上安装Node.js和npm:sudo apt update && sudo apt install nodejs npm -y。建议使用nvm安装更新的版本。
  • 使用scp命令或SFTP工具(如FileZilla)将你的整个项目文件夹上传到服务器的某个目录,例如 /home/ubuntu/app

4.2 安装PM2并配置生产环境

在服务器上,进入项目目录,安装生产依赖,并使用PM2来守护我们的Node.js进程,保证应用持续运行。

# 1. 进入项目目录
cd /home/ubuntu/app

# 2. 安装依赖(与本地一致)
npm install

# 3. 全局安装PM2进程管理工具
sudo npm install -g pm2

# 4. 使用PM2启动应用。设置应用名,并指定服务器端口(如80)
pm2 start server.js --name employee-management

# 5. 设置PM2开机自启
pm2 startup
pm2 save

4.3 配置Nginx反向代理(可选但推荐)

为了让外部通过域名(或服务器IP)的80端口访问,并提升性能,我们使用Nginx作为反向代理。

# 1. 安装Nginx
sudo apt install nginx -y

# 2. 创建Nginx站点配置文件
sudo nano /etc/nginx/sites-available/employee-management

在配置文件中写入以下内容(假设你的域名是 yourdomain.com, 或者直接用服务器IP):

server {
    listen 80;
    server_name yourdomain.com; # 替换为你的域名或IP

    location / {
        proxy_pass http://localhost:3000; # 转发到我们Node.js应用
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

保存后,启用该配置并重启Nginx:

sudo ln -s /etc/nginx/sites-available/employee-management /etc/nginx/sites-enabled/
sudo nginx -t # 测试配置语法
sudo systemctl restart nginx

现在,通过浏览器访问你的服务器IP或域名,就能看到部署在公网上的管理系统了!

总结

通过这个“保姆级”的实战项目,我们完成了一次完整的全栈开发旅程:

  • 理解了管理系统的基本架构(前端、后端、数据库)。
  • 掌握了使用Node.js + Express构建RESTful API的核心方法,实现了CRUD

微易网络

技术作者

2026年2月11日
0 次阅读

文章分类

开发教程

需要技术支持?

专业团队为您提供一站式软件开发服务

相关推荐

您可能还对这些文章感兴趣

管理系统实战常见问题汇总
开发教程

管理系统实战常见问题汇总

本文针对管理系统开发中的常见挑战,汇总了从项目初期到安全防护的关键问题与解决方案。文章重点剖析了开发初期在架构设计与数据建模中易犯的错误,如数据库设计不规范等陷阱,并强调了安全防护的重要性。旨在为开发者,特别是从零开始的团队,提供一套实用的实战指南,帮助其构建更健壮、安全、易用的系统,有效规避开发风险,提升项目质量。

2026/2/11
【保姆级】MySQL教程
开发教程

【保姆级】MySQL教程

本教程是一份面向初学者的“保姆级”MySQL实战指南。它不仅系统讲解MySQL数据库的安装、配置与核心SQL操作,更通过“从零开发商城系统”和“点餐系统”两个完整的实战项目,帮助读者在实践中深入掌握数据库设计与应用。教程还将探讨如何结合Redis来优化系统性能。目标是让学习者从入门到精通,具备构建真实数据驱动应用的能力。

2026/2/11
JavaScript ES6语法教程最佳实践与技巧
开发教程

JavaScript ES6语法教程最佳实践与技巧

这篇文章讲的是怎么把ES6那些好用的新语法,真正用到咱们的实际项目里。作者就像个经验丰富的老同事在聊天,特别懂咱们的痛点:看着别人用箭头函数、Promise写得那么溜,自己搞Vue.js或者云原生项目时,代码总感觉不够“现代”。文章不扯理论,直接分享最佳实践和技巧,比如怎么用Promise和Async/Await告别烦人的“回调地狱”,让您的代码更简洁高效,看完就能立刻在项目里用起来。

2026/3/16
Material UI教程学习资源推荐大全
开发教程

Material UI教程学习资源推荐大全

这篇文章讲了,很多朋友学Material UI时,光看官方文档容易懵,不知道怎么灵活定制样式。它就像一份贴心的“避坑指南”,专门为您整理了一套从入门到精通的实战学习资源。文章不仅推荐了比官方文档更易懂的教程,还会分享如何结合像Less这样的工具来轻松管理样式,目标就是帮您把Material UI真正用顺手,变成开发中的得力工具。

2026/3/16

需要专业的软件开发服务?

郑州微易网络科技有限公司,15+年开发经验,为您提供专业的小程序开发、网站建设、软件定制服务

技术支持:186-8889-0335 | 邮箱:hicpu@me.com