站内本项目源代码下载地址
技术栈: Node.js + Express + SQLite + 原生前端
1. 系统概述
1.1 项目背景
极简OA系统是一款面向中小型团队的办公自动化解决方案,采用极简设计理念,提供核心的办公功能模块,包括审批流程、考勤打卡、通知公告、用户管理和角色权限管理。
1.2 功能模块
| 模块 |
功能描述 |
适用角色 |
| 工作台 |
数据概览、快速打卡、最新公告 |
所有用户 |
| 审批流程 |
请假/报销/加班等审批申请与处理 |
所有用户 |
| 考勤打卡 |
上下班打卡、考勤记录查询 |
所有用户 |
| 通知公告 |
公告发布与查看 |
管理员/人事 |
| 用户管理 |
用户增删改查 |
管理员 |
| 角色管理 |
角色配置、权限分配 |
管理员 |
1.3 默认账号
| 账号 |
密码 |
角色 |
权限范围 |
| admin |
admin123 |
系统管理员 |
所有权限 |
| manager |
manager123 |
部门经理 |
审批处理、考勤管理、用户查看 |
| employee |
employee123 |
普通员工 |
基本办公功能 |
| hr |
hr123 |
人事专员 |
用户管理、考勤管理、公告管理 |
2. 技术架构
2.1 技术栈
┌─────────────────────────────────────────┐
│ 前端层 (Frontend) │
│ HTML5 + CSS3 + JavaScript (ES6+) │
│ Font Awesome 图标库 │
├─────────────────────────────────────────┤
│ 接口层 (API Layer) │
│ RESTful API / JSON │
│ JWT Token 认证 │
├─────────────────────────────────────────┤
│ 服务层 (Backend) │
│ Node.js + Express 4.x │
│ 中间件: CORS, Body-Parser │
├─────────────────────────────────────────┤
│ 数据层 (Data Layer) │
│ SQLite3 (文件型数据库) │
│ 零配置,开箱即用 │
└─────────────────────────────────────────┘
2.2 项目结构
mini-oa/
├── app.js # 应用入口
├── package.json # 依赖配置
├── oa.db # SQLite数据库文件
├── middleware/
│ └── auth.js # 认证与权限中间件
├── models/
│ ├── db.js # 数据库连接与操作类
│ └── initData.js # 系统初始化数据
├── routes/
│ ├── auth.js # 认证路由
│ ├── users.js # 用户路由
│ ├── approvals.js # 审批路由
│ ├── attendance.js # 考勤路由
│ ├── announcements.js # 公告路由
│ └── roles.js # 角色路由
└── public/ # 前端静态资源
├── index.html # 主页面
├── css/
│ └── style.css # 样式文件
├── js/
│ └── app.js # 前端逻辑
└── images/ # 图片资源
2.3 依赖清单
| 依赖包 |
版本 |
用途 |
| express |
^4.18.2 |
Web框架 |
| sqlite3 |
^5.1.6 |
数据库 |
| bcryptjs |
^2.4.3 |
密码加密 |
| jsonwebtoken |
^9.0.2 |
JWT认证 |
| cors |
^2.8.5 |
跨域支持 |
| body-parser |
^1.20.2 |
请求体解析 |
| multer |
^1.4.5-lts.1 |
文件上传 |
| nodemon |
^3.0.1 |
开发热重载 |
3. 数据库设计
3.1 ER关系图
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ users │ │ user_roles │ │ roles │
├─────────────┤ ├─────────────┤ ├─────────────┤
│ PK id │◄──────┤ PK user_id │ │ PK id │
│ username │ │ PK role_id │──────►│ name │
│ password │ └─────────────┘ │ desc │
│ name │ └──────┬──────┘
│ ... │ │
└─────────────┘ │
│ │
│ ┌─────────────┐ ┌───────────────┘
│ │role_permissions│ │
│ ├─────────────┤ │
└───►│ FK role_id │ │
│ FK perm_id │◄──────┘
└─────────────┘ ┌─────────────┐
│ permissions │
├─────────────┤
│ PK id │
│ code │
│ name │
│ module │
└─────────────┘
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ approvals │ │ attendance │ │announcements│
├─────────────┤ ├─────────────┤ ├─────────────┤
│ PK id │ │ PK id │ │ PK id │
│ FK applicant│──────►│ FK user_id │──────►│ FK author_id│
│ FK approver │──────►│ date │ │ title │
│ title │ │ check_in │ │ content │
│ status │ │ check_out│ │ priority │
└─────────────┘ └─────────────┘ └─────────────┘
3.2 表结构定义
3.2.1 用户表 (users)
| 字段 |
类型 |
约束 |
说明 |
| id |
INTEGER |
PK, AUTOINCREMENT |
主键 |
| username |
TEXT |
UNIQUE, NOT NULL |
用户名 |
| password |
TEXT |
NOT NULL |
加密密码 |
| name |
TEXT |
NOT NULL |
真实姓名 |
| role |
TEXT |
DEFAULT 'user' |
角色标识(保留字段) |
| department |
TEXT |
|
部门 |
| email |
TEXT |
|
邮箱 |
| phone |
TEXT |
|
电话 |
| avatar |
TEXT |
|
头像URL |
| status |
INTEGER |
DEFAULT 1 |
状态(1正常/0禁用) |
| created_at |
DATETIME |
DEFAULT CURRENT_TIMESTAMP |
创建时间 |
3.2.2 审批表 (approvals)
| 字段 |
类型 |
约束 |
说明 |
| id |
INTEGER |
PK, AUTOINCREMENT |
主键 |
| title |
TEXT |
NOT NULL |
审批标题 |
| type |
TEXT |
NOT NULL |
类型(leave/expense/overtime/business/other) |
| content |
TEXT |
|
详细内容 |
| applicant_id |
INTEGER |
NOT NULL, FK |
申请人ID |
| approver_id |
INTEGER |
FK |
审批人ID |
| status |
TEXT |
DEFAULT 'pending' |
状态(pending/approved/rejected) |
| remark |
TEXT |
|
审批意见 |
| created_at |
DATETIME |
DEFAULT CURRENT_TIMESTAMP |
创建时间 |
| updated_at |
DATETIME |
DEFAULT CURRENT_TIMESTAMP |
更新时间 |
3.2.3 考勤表 (attendance)
| 字段 |
类型 |
约束 |
说明 |
| id |
INTEGER |
PK, AUTOINCREMENT |
主键 |
| user_id |
INTEGER |
NOT NULL, FK |
用户ID |
| date |
TEXT |
NOT NULL |
日期 |
| check_in |
TEXT |
|
上班时间 |
| check_out |
TEXT |
|
下班时间 |
| status |
TEXT |
DEFAULT 'normal' |
状态(normal/late/early/absent) |
| remark |
TEXT |
|
备注 |
| created_at |
DATETIME |
DEFAULT CURRENT_TIMESTAMP |
创建时间 |
唯一约束: (user_id, date)
3.2.4 公告表 (announcements)
| 字段 |
类型 |
约束 |
说明 |
| id |
INTEGER |
PK, AUTOINCREMENT |
主键 |
| title |
TEXT |
NOT NULL |
标题 |
| content |
TEXT |
NOT NULL |
内容 |
| author_id |
INTEGER |
NOT NULL, FK |
发布人ID |
| priority |
TEXT |
DEFAULT 'normal' |
优先级(high/normal/low) |
| status |
INTEGER |
DEFAULT 1 |
状态(1显示/0删除) |
| created_at |
DATETIME |
DEFAULT CURRENT_TIMESTAMP |
创建时间 |
3.2.5 角色表 (roles)
| 字段 |
类型 |
约束 |
说明 |
| id |
INTEGER |
PK, AUTOINCREMENT |
主键 |
| name |
TEXT |
UNIQUE, NOT NULL |
角色名称 |
| description |
TEXT |
|
描述 |
| status |
INTEGER |
DEFAULT 1 |
状态 |
| created_at |
DATETIME |
DEFAULT CURRENT_TIMESTAMP |
创建时间 |
3.2.6 权限表 (permissions)
| 字段 |
类型 |
约束 |
说明 |
| id |
INTEGER |
PK, AUTOINCREMENT |
主键 |
| code |
TEXT |
UNIQUE, NOT NULL |
权限代码 |
| name |
TEXT |
NOT NULL |
权限名称 |
| module |
TEXT |
NOT NULL |
所属模块 |
| description |
TEXT |
|
描述 |
3.2.7 角色权限关联表 (role_permissions)
| 字段 |
类型 |
约束 |
说明 |
| role_id |
INTEGER |
PK, FK |
角色ID |
| permission_id |
INTEGER |
PK, FK |
权限ID |
3.2.8 用户角色关联表 (user_roles)
| 字段 |
类型 |
约束 |
说明 |
| user_id |
INTEGER |
PK, FK |
用户ID |
| role_id |
INTEGER |
PK, FK |
角色ID |
4. API接口设计
4.1 认证模块 (auth)
登录
POST /api/auth/login
Content-Type: application/json
Request:
{
"username": "admin",
"password": "admin123"
}
Response 200:
{
"token": "eyJhbGciOiJIUzI1NiIs...",
"user": {
"id": 1,
"username": "admin",
"name": "系统管理员",
"department": "管理部",
"roles": [{"id": 1, "name": "系统管理员"}],
"permissions": ["dashboard:view", "approval:view", ...]
}
}
Response 401:
{
"message": "用户名或密码错误"
}
注册
POST /api/auth/register
Content-Type: application/json
Request:
{
"username": "newuser",
"password": "password123",
"name": "新用户",
"department": "技术部",
"email": "user@company.com",
"phone": "13800138000"
}
Response 201:
{
"message": "注册成功",
"userId": 5
}
4.2 用户模块 (users)
获取用户列表
GET /api/users
Authorization: Bearer {token}
Response 200:
[
{
"id": 1,
"username": "admin",
"name": "系统管理员",
"department": "管理部",
"roles": "系统管理员",
"email": "admin@company.com",
"status": 1,
"created_at": "2026-06-04 14:29:00"
}
]
获取当前用户信息
GET /api/users/me
Authorization: Bearer {token}
Response 200:
{
"id": 1,
"username": "admin",
"name": "系统管理员",
"department": "管理部",
"email": "admin@company.com",
"roles": [...],
"permissions": [...]
}
更新用户信息
PUT /api/users/:id
Authorization: Bearer {token}
Content-Type: application/json
Request:
{
"name": "新名称",
"department": "新部门",
"email": "new@company.com",
"phone": "13800138001"
}
Response 200:
{
"message": "更新成功"
}
修改密码
PUT /api/users/:id/password
Authorization: Bearer {token}
Content-Type: application/json
Request:
{
"oldPassword": "admin123",
"newPassword": "newpassword123"
}
Response 200:
{
"message": "密码修改成功"
}
Response 400:
{
"message": "旧密码错误"
}
删除用户
DELETE /api/users/:id
Authorization: Bearer {token}
Response 200:
{
"message": "删除成功"
}
4.3 审批模块 (approvals)
获取审批列表
GET /api/approvals?status=pending&type=leave
Authorization: Bearer {token}
Response 200:
[
{
"id": 1,
"title": "请假申请",
"type": "leave",
"applicant_name": "张三",
"approver_name": "李四",
"status": "pending",
"created_at": "2026-06-04 14:30:00"
}
]
创建审批
POST /api/approvals
Authorization: Bearer {token}
Content-Type: application/json
Request:
{
"title": "请假申请-年假3天",
"type": "leave",
"content": "因家中有事,申请年假3天",
"approver_id": 2
}
Response 201:
{
"message": "提交成功",
"approvalId": 1
}
审批处理
PUT /api/approvals/:id
Authorization: Bearer {token}
Content-Type: application/json
Request:
{
"status": "approved",
"remark": "同意"
}
Response 200:
{
"message": "审批处理成功"
}
获取审批统计
GET /api/approvals/stats/overview
Authorization: Bearer {token}
Response 200:
[
{"status": "pending", "count": 5},
{"status": "approved", "count": 10},
{"status": "rejected", "count": 2}
]
4.4 考勤模块 (attendance)
获取考勤记录
GET /api/attendance?month=2026-06
Authorization: Bearer {token}
Response 200:
[
{
"id": 1,
"date": "2026-06-04",
"check_in": "09:00",
"check_out": "18:00",
"status": "normal"
}
]
打卡
POST /api/attendance/check
Authorization: Bearer {token}
Response 200:
{
"message": "上班打卡成功",
"type": "check_in",
"time": "09:00"
}
Response 200 (下班):
{
"message": "下班打卡成功",
"type": "check_out",
"time": "18:00"
}
获取今日考勤状态
GET /api/attendance/today
Authorization: Bearer {token}
Response 200:
{
"hasCheckedIn": true,
"hasCheckedOut": false,
"checkInTime": "09:00",
"checkOutTime": null
}
4.5 公告模块 (announcements)
获取公告列表
GET /api/announcements
Authorization: Bearer {token}
Response 200:
[
{
"id": 1,
"title": "端午节放假通知",
"content": "...",
"author_name": "系统管理员",
"priority": "normal",
"created_at": "2026-06-04 14:30:00"
}
]
获取公告详情
GET /api/announcements/:id
Authorization: Bearer {token}
发布公告
POST /api/announcements
Authorization: Bearer {token}
Content-Type: application/json
Request:
{
"title": "新公告",
"content": "公告内容",
"priority": "high"
}
Response 201:
{
"message": "发布成功",
"announcementId": 1
}
删除公告
DELETE /api/announcements/:id
Authorization: Bearer {token}
Response 200:
{
"message": "删除成功"
}
4.6 角色模块 (roles)
获取角色列表
GET /api/roles
Authorization: Bearer {token}
Response 200:
[
{
"id": 1,
"name": "系统管理员",
"description": "拥有所有权限",
"user_count": 1,
"status": 1,
"created_at": "2026-06-04 14:29:00"
}
]
获取角色详情
GET /api/roles/:id
Authorization: Bearer {token}
Response 200:
{
"id": 1,
"name": "系统管理员",
"description": "...",
"permissions": [
{"id": 1, "code": "dashboard:view", "name": "查看工作台", "module": "dashboard"}
]
}
创建角色
POST /api/roles
Authorization: Bearer {token}
Content-Type: application/json
Request:
{
"name": "新角色",
"description": "角色描述",
"permissions": [1, 2, 3]
}
Response 201:
{
"message": "角色创建成功",
"roleId": 5
}
更新角色
PUT /api/roles/:id
Authorization: Bearer {token}
Content-Type: application/json
Request:
{
"name": "更新后的角色名",
"description": "新描述",
"permissions": [1, 2, 4, 5]
}
删除角色
DELETE /api/roles/:id
Authorization: Bearer {token}
Response 200:
{
"message": "角色删除成功"
}
获取所有权限列表
GET /api/roles/permissions/all
Authorization: Bearer {token}
Response 200:
{
"dashboard": [
{"id": 1, "code": "dashboard:view", "name": "查看工作台", "module": "dashboard"}
],
"approval": [...],
"attendance": [...],
...
}
为用户分配角色
POST /api/roles/assign
Authorization: Bearer {token}
Content-Type: application/json
Request:
{
"userId": 5,
"roleIds": [2, 3]
}
Response 200:
{
"message": "角色分配成功"
}
5. 权限设计
5.1 RBAC模型
系统采用基于角色的访问控制(Role-Based Access Control)模型:
用户(User) ──N:M──► 角色(Role) ──N:M──► 权限(Permission)
- 一个用户可拥有多个角色
- 一个角色可包含多个权限
- 权限按模块分组管理
5.2 权限清单
| 模块 |
权限代码 |
权限名称 |
| 工作台 |
dashboard:view |
查看工作台 |
| 审批流程 |
approval:view |
查看审批 |
|
approval:create |
创建审批 |
|
approval:approve |
审批处理 |
| 考勤打卡 |
attendance:view |
查看考勤 |
|
attendance:check |
打卡 |
|
attendance:manage |
管理考勤 |
| 通知公告 |
announcement:view |
查看公告 |
|
announcement:create |
发布公告 |
|
announcement:delete |
删除公告 |
| 用户管理 |
user:view |
查看用户 |
|
user:create |
创建用户 |
|
user:edit |
编辑用户 |
|
user:delete |
删除用户 |
| 角色管理 |
role:view |
查看角色 |
|
role:create |
创建角色 |
|
role:edit |
编辑角色 |
|
role:delete |
删除角色 |
|
role:assign |
分配角色 |
5.3 默认角色权限分配
┌──────────────┬─────────────────────────────────────────────┐
│ 系统管理员 │ 所有权限 │
├──────────────┼─────────────────────────────────────────────┤
│ 部门经理 │ dashboard:view, approval:view/create/approve │
│ │ attendance:view/manage, announcement:view │
│ │ user:view │
├──────────────┼─────────────────────────────────────────────┤
│ 普通员工 │ dashboard:view, approval:view/create │
│ │ attendance:view/check, announcement:view │
├──────────────┼─────────────────────────────────────────────┤
│ 人事专员 │ dashboard:view, approval:view/approve │
│ │ attendance:view/manage │
│ │ announcement:view/create/delete │
│ │ user:view/create/edit │
└──────────────┴─────────────────────────────────────────────┘
5.4 权限中间件
// 认证中间件 - 验证JWT Token
authenticate(req, res, next)
// 权限检查中间件 - 检查是否拥有指定权限
requirePermission(permissionCode)
// 任意权限检查 - 拥有任一指定权限即可
requireAnyPermission(...permissionCodes)
// 获取用户权限列表
getUserPermissions(userId)
6. 前端设计
6.1 页面结构
┌─────────────────────────────────────────────┐
│ 顶部栏 (Top Bar) │
│ [页面标题] [当前日期] │
├──────────┬──────────────────────────────────┤
│ │ │
│ 侧边栏 │ 主内容区 │
│ (Sidebar)│ (Main Content) │
│ │ │
│ 工作台 │ ┌──────────────────────┐ │
│ 审批流程 │ │ 统计卡片区域 │ │
│ 考勤打卡 │ └──────────────────────┘ │
│ 通知公告 │ ┌──────────┬──────────┐ │
│ 用户管理 │ │ 快速打卡 │ 最新公告 │ │
│ 角色管理 │ └──────────┴──────────┘ │
│ │ │
│ [用户信息]│ │
│ [修改密码]│ │
│ [退出] │ │
└──────────┴──────────────────────────────────┘
6.2 页面清单
| 页面 |
路由 |
说明 |
| 登录页 |
/ |
用户名密码登录 |
| 工作台 |
#dashboard |
数据概览、快速操作 |
| 审批流程 |
#approvals |
审批列表、新建审批 |
| 考勤打卡 |
#attendance |
打卡、考勤记录 |
| 通知公告 |
#announcements |
公告列表、发布公告 |
| 用户管理 |
#users |
用户列表、添加用户 |
| 角色管理 |
#roles |
角色列表、权限配置 |
6.3 前端状态管理
// 全局状态
let currentUser = null; // 当前用户信息
let authToken = null; // JWT Token
let userPermissions = []; // 用户权限列表
// 权限检查函数
function hasPermission(permCode) {
return userPermissions.includes(permCode);
}
6.4 菜单权限控制
菜单项通过 data-perm 属性绑定权限代码:
<a href="#" class="nav-item" data-page="users" data-perm="user:view">
<i class="fas fa-users"></i>
<span>用户管理</span>
</a>
登录后根据用户权限动态显示/隐藏菜单:
function setupUserInterface() {
document.querySelectorAll('.nav-item[data-perm]').forEach(item => {
const requiredPerm = item.dataset.perm;
item.classList.toggle('hidden', !hasPermission(requiredPerm));
});
}
6.5 组件说明
| 组件 |
说明 |
| 统计卡片 |
显示待处理审批、已通过审批、出勤天数、最新公告数量 |
| 数据表格 |
统一风格的表格,支持空状态显示 |
| 筛选标签 |
审批状态筛选(全部/待处理/已通过/已拒绝) |
| 模态框 |
表单弹窗,支持创建/编辑操作 |
| Toast提示 |
操作成功/失败的消息提示 |
| 权限配置面板 |
按模块分组的权限复选框列表 |
7. 部署说明
7.1 环境要求
- Node.js >= 14.0
- npm >= 6.0
7.2 安装步骤
# 1. 解压项目
unzip mini-oa.zip
cd mini-oa
# 2. 安装依赖
npm install
# 3. 启动服务
npm start
# 4. 访问系统
# 打开浏览器访问 http://localhost:3000
7.3 开发模式
# 使用 nodemon 热重载
npm run dev
7.4 配置说明
| 配置项 |
环境变量 |
默认值 |
说明 |
| 端口 |
PORT |
3000 |
服务监听端口 |
| JWT密钥 |
JWT_SECRET |
mini-oa-secret-key |
Token签名密钥 |
7.5 数据初始化
系统首次启动时会自动:
- 创建数据库表结构
- 初始化默认角色(系统管理员、部门经理、普通员工、人事专员)
- 初始化权限列表
- 分配角色默认权限
- 创建默认管理员账号(admin/admin123)
- 创建测试账号(manager、employee、hr)
附录
A. 审批类型枚举
| 类型值 |
含义 |
| leave |
请假 |
| expense |
报销 |
| overtime |
加班 |
| business |
出差 |
| other |
其他 |
B. 审批状态枚举
| 状态值 |
含义 |
| pending |
待处理 |
| approved |
已通过 |
| rejected |
已拒绝 |
C. 公告优先级枚举
| 优先级 |
含义 |
| high |
重要 |
| normal |
普通 |
| low |
一般 |
D. 考勤状态枚举
| 状态值 |
含义 |
| normal |
正常 |
| late |
迟到 |
| early |
早退 |
| absent |
缺勤 |