X10212 IT 运维工单台账与日报自动管理系统

ed7ae01061704edf24d3317c986b54a9

c3c08b353a1bf01d466bd65ddc526fbb

项目地址:https://github.com/jinxuan-cd/it-ops-system-github

IT 运维工单台账与日报自动管理系统

面向企业内部 IT 运维团队的一体化工单与日报平台:报障 → 抢单 → 处理 → 归档 → 日报/月报 → 知识沉淀 → 数据分析全链路打通,支持多角色权限隔离、SLA 时效管控、机房巡检、故障复盘与一键备份。

🔐 公网 / 内网双入口隔离:员工自助报障门户独立成公网端口(外勤、分公司扫码即可用),管理后台只留在内网端口;两个端口共用同一个后端与数据库,数据实时互通,但公网端口在网关层拿不到任何登录与数据管理接口。

  • 开发者:锦轩(邮箱 2686389727@qq.com)
  • 授权方式:个人与小团队免费,商业使用需购买授权,详见 授权与商业许可
  • 运行环境:Linux / Windows + Docker 20.10+,或 Node.js 20+ / MariaDB 10.11(MySQL 8.0 亦可)

目录

 


项目简介

 

中小企业的 IT 运维工作通常散落在微信群、Excel 和口头交接里:谁报了障、谁在处理、处理了多久、这个月做了多少事,都很难说清。本项目把这套流程做成一个可私有化部署的轻量系统:

  • 报障入口零门槛:员工扫码或点链接即可报障,无需注册账号。
  • 处理过程可追溯:每张工单记录发生 / 响应 / 完成时间,自动算 SLA 是否超期。
  • 日报月报自动化:一键把当日工单汇总成纯文本日报,明日计划自动转次日待办。
  • 数据说话:看板与团队运营分析给出受理量、完成率、平均处理时长、人员产出排名。
  • 部署即用:docker compose up -d 一条命令,自动建库建表、自动生成管理员账号。

适用规模:3~50 人的运维团队;单实例部署(无 Redis / 消息队列等外部依赖)。

功能特性

工单全流程

 

能力 说明
多种录入方式 标准录入(完整字段 + 知识库方案推荐)、快捷录入(极简草稿)、扫码报障自动建单、巡检异常转工单
抢单接单 新单进入待接单池,所有运维收到待办 + 右下角实时弹窗;点「接取」即转处理中(数据库原子更新,两人同抢只有一人成功)
派单转派 管理员 / 处理人可派单、转单、退回池子;被指派人立即收到待办与实时提醒
服务台模式(可选) 开启后新单只推服务台 + 管理员,由服务台统一派单;关闭则运维自行抢单
状态机 pending 待接单 → processing 处理中 → done 已完成,时间与状态强联动(见核心联动逻辑)
批量操作 批量标记完成 / 批量删除 / 导出选中;Excel 导出含状态与处理人
满意度回访 员工凭手机号后 4 位查进度,完成后可打 1–5 分并留言

时效与质量

 

能力 说明
SLA 策略 按「问题类别 + 优先级」配置响应/解决时限,支持默认兜底;工单自动计算截止时间并标记「即将超时 / 已超时」
优先级 低 / 普通 / 高 / 紧急四级,与 SLA 联动
一键重算 调整策略后可对历史工单批量重算 SLA 截止时间
数据体检 团队分析页可一键检测并修复异常数据(完成时间早于发生时间、已完成却无完成时间等)

汇报与沉淀

 

能力 说明
日报自动生成 一键汇总当日工单,可编辑、一键复制、提交后「明日计划」自动转次日待办
月报生成 基于当月工单/目标/故障数据生成月度工作报告
团队查阅 管理员 / 审计员可查看全员的日报、月报,含今日提交情况、7 天趋势、未提交名单、明细弹窗
知识库 检索、文档解析回填(txt/md/csv/pdf/docx)、来源工单跳转、浏览计数
知识自动沉淀 工单完成时勾选「同步知识库」→ 自动生成条目
常见问题门户 知识库条目标记「对外公开」后自动成为免登录 FAQ,支持搜索与折叠查看

运维专项

 

能力 说明
故障管理 P1–P4 分级、影响范围档位、受影响系统、发生/接单/恢复三时间点、原因、处理过程、复盘总结
机房巡检 巡检区域与巡检项可在设置页配置,支持「需拍照」项;逐项打卡 + 现场拍照留底 + 进度条,异常可一键转工单
账号台账 业务系统账号清单(系统/账号/权限范围/责任人/开通回收时间/状态)+ 台账汇总
项目管理 项目阶段拆解、进度、起止时间、状态
待办与目标 当日/本周/全部待办、月度目标与权重、完成月份自动记录

分析与通知

 

能力 说明
数据看板 顶部切换今日 / 本周 / 本月 / 上月 / 本年,整页跟着换:6 张指标卡(受理 / 完成 / 完成率 / 平均处理时长 / 未完成 / 满意度 + 与上一周期环比)、趋势图(自动按小时 / 按天 / 按月分桶)、问题类别 TOP、类别与系统分布、本期最新工单、今日待办与本月目标
团队运营分析 全公司受理与完成量、完成率、平均时长、积压超期(分页滚动)、人员产出排名、人员维度下钻、问题类别排名、系统排名、部门排名、近 6 月趋势、自动生成「汇报要点」
消息推送 企微 / 钉钉 / 飞书 / 自定义 Webhook,订阅新故障、P1P2 升级、SLA 超时、每日提醒
定时提醒 内置调度器:每日 09:00 待跟进提醒、18:00 当日小结
操作审计 全量记录 POST/PUT/DELETE(操作人、IP、路径、方法、耗时、敏感字段脱敏),支持检索与汇总

平台能力

 

  • 公网内网双入口:员工自助门户独立端口(默认 8081),管理后台独立端口(默认 8080)。两个端口连的是同一个后端、同一个数据库,数据完全互通;公网端口只放行 4 个免登录接口,登录与管理接口在该端口上直接 404。
  • 多角色权限:管理员 / 审计员(全公司只读)/ 服务台 / 运维工程师,写操作按角色收口。
  • 数据隔离:所有业务表绑定 user_id,普通用户只能看到自己的数据。
  • 实时推送:SSE 长连接,新单/接单/退回/完成即时到达浏览器;员工在公网门户报障后,运维的管理端界面同样实时弹出提醒。
  • 一键备份恢复:打包成 zip(全部数据 + 上传附件),上传即还原,恢复前自动快照。
  • 移动端适配:宽度 ≤ 820px 自动切换抽屉菜单、卡片列表、全宽弹窗,手机浏览器直接可用。
  • 登录防护:连续输错密码触发图形验证码与账号锁定,防暴力破解。

技术栈

 

层次 技术选型
前端 Vue 3(<script setup>)、Element Plus、Vite、Pinia、Vue Router、ECharts
后端 Node.js 20、Express 4、mysql2 连接池、JWT、bcryptjs
数据库 MariaDB 10.11(InnoDB / utf8mb4 / +08:00 时区),兼容 MySQL 8.0
文件与导出 Multer 上传、ExcelJS 导出、archiver + adm-zip 备份、pdf-parse / mammoth 文档解析
部署 Docker Compose(db / backend / frontend / public-web),Nginx 托管静态资源并反代 API

目录结构

 

it-ops-system/
├── docker-compose.yml         # 一键部署编排(db / backend / frontend / public-web)
├── .env.example               # 部署环境变量模板(复制为 .env)
├── sql/
│   └── init.sql               # 数据库初始化:18 张表 + 视图 + 字典 + SLA + 设置
├── scripts/
│   ├── upgrade.sh             # 安全升级(只重建、永不带 -v,数据不丢)
│   ├── demo-data.sql          # 可选演示数据(一年工单 + 演示账号 + FAQ)
│   ├── gen-demo-data.py       # 生成上面的演示数据 SQL
│   └── demo-reset.sh          # 清空演示数据,恢复出厂
├── backend/                   # Express 后端(单进程,管理端与门户共用)
│   ├── src/
│   │   ├── index.js           # 入口:全部接口 + /api/public 免登录接口
│   │   ├── db.js              # 数据库连接池(MariaDB / MySQL 通用)
│   │   ├── middleware/        # auth 鉴权、upload 上传白名单、audit 审计
│   │   ├── routes/            # 23 个业务路由(见下表)
│   │   └── utils/             # 响应封装、SLA、实时推送、调度器、seed、文本清洗
│   ├── uploads/               # 上传附件(已挂卷,重建容器不丢)
│   ├── backups/               # 备份包(已挂卷)
│   └── Dockerfile
├── public-portal/             # 员工自助门户(公网端口,零依赖静态站)
│   ├── index.html             # 报障 / 查进度 / 常见问题(单页,Tab 切换)
│   ├── app.js  style.css
│   ├── nginx.conf             # 公网入口:只放行 /api/public/*,其余一律 404
│   └── Dockerfile
└── frontend/                  # Vue3 管理端(内网端口)
    ├── src/
    │   ├── api/               # 统一接口层(含拦截器与错误提示)
    │   ├── layout/            # 后台布局、待办面板、接单弹窗
    │   ├── router/ store/ utils/
    │   └── views/             # 各业务页面
    ├── nginx.conf
    └── Dockerfile

后端路由:auth users tickets todos goals knowledge projects dictionary dashboard analytics dailyReport monthlyReport incidents inspections accounts sla notify auditLog system backup aiConfig publicApi realtime。


快速开始

 

方式一:Docker Compose(推荐,生产同款)

 

前置:Docker 20.10+ / Docker Compose v2。

# 1. 获取代码
git clone <仓库地址> it-ops-system
cd it-ops-system

# 2. 准备环境变量(生产必须改口令与 JWT_SECRET)
cp .env.example .env
vim .env        # 修改 MYSQL_* / JWT_SECRET / DEFAULT_ADMIN_PASSWORD

# 3. 构建并启动(首次会自动建库、建表、写入初始字典与管理员)
docker compose up -d --build

# 4. 查看状态与日志
docker compose ps
docker compose logs -f backend

启动后访问:

入口 地址 网络范围
管理后台(运维/管理员) http://服务器内网IP:8080 只在内网开放
员工自助门户(报障/查进度/FAQ) http://服务器公网IP:8081 可对公网开放

两个端口连的是同一个后端、同一个数据库,报障进来自动出现在管理后台的工单列表,数据不需要任何同步。 门户端口(8081)在网关层只放行 /api/public/*,访问 http://公网IP:8081/api/auth/login、/api/tickets、/uploads/... 一律返回 404。 db 与 backend 不映射宿主机端口,只存在于容器网络内(要本机调试后端,临时在 compose 里加回 - "127.0.0.1:3000:3000")。 入口密钥在后端首次启动时自动生成,登录管理后台后到「系统设置 → 自助服务入口」查看二维码与链接,并把「公网门户地址」填成 http://公网IP:8081。

方式二:本地开发

 

前置:Node.js ≥ 20、本地 MariaDB 10.11 或 MySQL 8.0。

# 1. 建库并初始化
mariadb -uroot -p -e "CREATE DATABASE itops DEFAULT CHARACTER SET utf8mb4"
mariadb -uroot -p itops < sql/init.sql

# 2. 启动后端
cd backend
cp .env.example .env        # 按本地数据库修改 DB_* 与 JWT_SECRET
npm install
npm run dev                 # http://localhost:3000

# 3. 启动前端(另开终端)
cd frontend
npm install
npm run dev                 # http://localhost:5173,已配置 /api 代理到 3000

也可以用根目录脚本:

npm run install:all     # 安装前后端依赖
npm run dev:backend     # 启动后端
npm run dev:frontend    # 启动前端

默认账号与角色

 

首次启动(用户表为空时)自动创建管理员:

账号 初始密码 角色
admin admin123 管理员

初始密码可通过 .env 的 DEFAULT_ADMIN_PASSWORD 指定;首次登录后请立即到「系统设置 → 安全」修改。 系统初始化后只保留管理员一个账号,其它账号由管理员在「账号管理」中按需创建。

角色权限:

角色 标识 权限
管理员 admin 全部功能 + 账号管理 + 字典维护 + SLA 策略 + 备份恢复 + 审计日志 + 团队运营分析
审计员 auditor 只读查看全公司看板、团队分析、工单/知识库/日报月报明细;非 GET 请求被后端统一拦截(仅放行改自己资料与密码)
服务台 service 查看全部工单并派单/转单;需在「系统设置 → 工单流转」开启服务台派单后才生效
运维工程师 user 本人录入的工单 + 指派给自己的工单 + 待接单池

系统初始化

 

系统出厂即为空业务数据状态,可直接交付使用:

初始化项 状态
表结构 18 张表 + v_ticket_duration 视图,sql/init.sql 全量定义
部门 / 应用系统 / 问题类别 44 条默认字典(可在「基础字典维护」增改停删)
SLA 策略 4 条默认策略(低/普通/高/紧急)
系统设置 报障入口、FAQ 门户、服务台、巡检区域与巡检项默认值
业务数据 全部为空:工单、故障、巡检、台账、知识库、日报、月报、待办、目标、项目、审计日志
账号 仅 admin

重新初始化(清空所有业务数据)

 

# 方式 A:彻底重建数据库(推荐,最干净)
docker compose down -v          # -v 会删除 db 数据卷,数据不可恢复!
docker compose up -d --build

# 方式 B:保留容器,只重跑初始化脚本
docker compose exec -T db sh -c \
  'mariadb -uroot -p"$MARIADB_ROOT_PASSWORD" itops' < sql/init.sql

⚠️ docker compose down -v 会清空数据库与上传文件。执行前请先在「系统设置 → 备份恢复」下载一份备份包。

如需只清空业务数据、保留账号与字典,可在数据库执行:

SET FOREIGN_KEY_CHECKS = 0;
TRUNCATE TABLE ticket;        TRUNCATE TABLE todo;
TRUNCATE TABLE knowledge;     TRUNCATE TABLE daily_report;
TRUNCATE TABLE monthly_report;TRUNCATE TABLE month_goal;
TRUNCATE TABLE project;       TRUNCATE TABLE incident;
TRUNCATE TABLE inspection;    TRUNCATE TABLE account_ledger;
TRUNCATE TABLE audit_log;
SET FOREIGN_KEY_CHECKS = 1;

演示数据(可选,只想先看效果)

 

出厂是空库,看板和团队分析的图表都是 0,不好判断效果。想直接看真实图表(月度趋势、上月汇总、超期分页、人员维度分析),可以铺一份演示数据:

# 铺演示数据:一年的工单 + 3 个演示账号 + 5 条常见问题
docker compose exec -T db mariadb -uitops -p"$MYSQL_PASSWORD" itops < scripts/demo-data.sql

# 用完一键清空(保留 admin、字典、系统设置)
bash scripts/demo-reset.sh

演示账号 zhangwei / lijing / wangqiang,密码与 admin 相同。数据跨全年、含已完成与超期未完成工单,专门用来验证图表与分页。

演示数据脚本由 scripts/gen-demo-data.py 生成。生产环境不要执行。


核心联动逻辑

 

  1. 工单标记【已完成】并勾选【同步知识库】→ 自动生成知识库条目。
  2. 录入工单选择【应用系统 + 问题类别】→ 优先匹配知识库方案,无匹配走关键词兜底。
  3. 日报【明日工作计划】提交 → 自动拆分为次日待办(重复提交会先清掉当日自动生成的待办,不会翻倍)。
  4. 右侧全局浮动待办面板 → 实时拉取当日未完成待办。
  5. 看板 → 聚合工单 / 待办 / 目标,计算环比与平均处理时长。
  6. 知识库上传文档(txt/md/csv/pdf/docx)→ 自动解析文本回填。
  7. 所有业务数据绑定 user_id,严格数据隔离(管理员可看全部)。
  8. 工单保存/导入时按 SLA 策略计算响应与解决截止时间,并标记超时状态。
  9. 故障登记为 P1/P2 → 立即通过已配置的 Webhook 推送告警;恢复后自动统计恢复时长。
  10. 巡检出现异常项 → 一键转成工单,把异常清单写进服务内容。
  11. 自助报障提交 → 生成带编号的工单(来源标记 qr),员工凭手机后 4 位查进度、完成后评价满意度。
  12. 编辑工单把状态改为「已完成」但没填完成时间 → 自动补当前时间;改回「处理中」→ 清空完成时间。
  13. 把工单「完成时间」删掉 → 状态自动回退为「处理中」(删除故障「恢复时间」同理回退为「未恢复」)。
  14. 巡检项勾选「需拍照」但没传图 → 提交时二次确认(不强制阻断,现场拍不了也能先记录)。
  15. 扫码报障 → 工单为 pending → 给每个运维生成 source='ticket' 的待办,并通过 SSE 推送到在线浏览器;被接取/派单后其他人的待办与弹窗立即关闭。公网门户与内网管理端共用同一个后端进程,所以门户提交的报障会立刻推送到运维的浏览器。
  16. 接单采用数据库原子更新(WHERE assignee_id IS NULL AND status='pending'),两人同时点只有一人成功,另一人收到「手慢了,已被接取」。
  17. 删除工单会同步删除关联的接单待办,避免待办里留下点不开的死链。
  18. 停用或降级账号后,鉴权中间件 60 秒内即生效(含强制下线),不需要重启服务。
  19. 最后一个管理员不可被降级 / 停用 / 删除,避免把自己锁在系统外。

数据口径说明

 

指标 口径
受理量 按 happen_time(工单发生时间)落在统计区间内计数
完成量 按 finish_time(完成时间)落在区间内计数,与受理量分开统计,避免跨期完成让完成率超过 100%
完成率 本期受理且已完成 ÷ 本期受理
平均处理时长 只统计 finish_time 晚于 happen_time 的工单(真正记录了起止时间的),历史批量导入只填日期的记录不计入分母;无有效样本显示「—」
超期未完成 未完成工单按 NOW() - happen_time 计算已挂时长,用 GREATEST(...,0) 兜底,不会出现负数
故障类指标 只在有故障记录时展示;无故障时看板与分析页自动隐藏故障卡片
看板时间维度 今日 = 当天 0 点起;本周 = 周一起;本月 / 上月 = 自然月;本年 = 1 月 1 日起。环比对比「上一同长度周期」(今日↔昨日、本周↔上周、本月↔上月、本年↔去年)
看板趋势分桶 今日按小时(24 桶)、本周 / 本月 / 上月按天、本年按月,空桶补 0,图表不会跳段

时区:容器数据库必须使用 TZ=Asia/Shanghai + --default-time-zone=+08:00(docker-compose.yml 已固定)。 若数据库跑在 UTC,NOW() 会比北京时间早 8 小时,导致「已挂时长」出现负数、趋势图分桶错位、SLA 超期判定滞后 8 小时。后端计算本地时间统一使用 todayStr() / nowStr(),不使用 toISOString()。


公网 / 内网双入口隔离

 

员工不一定在内网:分公司、外勤、出差的人要用手机扫码报障,管理后台却绝不能放到公网。 因此系统把「员工自助」和「管理后台」拆成两个端口:

管理后台 员工自助门户
默认端口 8080 8081
配置项 .env 里的 ADMIN_PORT .env 里的 PUBLIC_PORT
面向 内网(运维、管理员、审计员) 公网(全体员工手机扫码)
界面 Vue3 完整后台 零依赖静态页(约 30KB,弱网秒开)
后端 同一个 backend 容器 同一个 backend 容器
可访问接口 全部 仅 `/api/public/config
需要登录 是 否(凭入口密钥 k)

两道防护:

  1. 网关层(主防线):门户 nginx 只反代 /api/public/,/api/(其它)、/uploads/、点文件一律 return 404;只允许 GET/POST/HEAD。
  2. 数据库层:db 与 backend 不做宿主机端口映射,公网只能碰到门户那个 nginx。

公网侧额外加固:

  • 按 IP 限流:报障提交 6 次/分钟、其它公开接口 60 次/分钟(网关 limit_req + 应用内计数双保险)。
  • 严格响应头:X-Frame-Options: DENY、Content-Security-Policy(只允许自身资源)、X-Robots-Tag: noindex、server_tokens off。
  • 只暴露必要字段:进度查询不返回处理人名与内部沟通;填过手机号的单必须校验后 4 位才能查看。

部署要点:云安全组 / 宝塔 WAF 只把 8081 映射到公网;8080 只在局域网可达,不做公网映射。

改端口后不生效?

 

.env 里的 ADMIN_PORT / PUBLIC_PORT 只在创建容器时生效,docker compose restart 不会重建容器:

# 改完 .env 执行这个(不是 restart)
docker compose up -d --force-recreate
# 确认实际映射的端口
docker compose ps

还要确认端口没被别的程序占用(宝塔/1Panel 自己、旧容器都可能占着):

ss -lntp | grep -E ':8080|:8081'     # 应分别对应 frontend / public-web 容器

默认端口:管理端 8080(只内网)、员工报障 8081(对公网开放,宝塔 WAF 反代到这里)。


数据库:MariaDB 10.11 与迁移

 

镜像固定为 mariadb:10.11(LTS,兼容 MySQL 协议与语法,启动比 MySQL 8.0 更快、内存占用更低)。 sql/init.sql 同时兼容 MariaDB 10.11 与 MySQL 8.0,两份都能直接跑。

从 MySQL 8.0 换成 MariaDB(重要)

 

MariaDB 无法读取 MySQL 8.0 的数据目录,所以换镜像必须换新数据卷(compose 里已改名为 mariadb_data,与旧的 db_data 分开)。 系统出厂即为空数据,通常直接重建最省事:

cd /opt/it-ops-system
git pull

# 1. 停掉旧栈(同时清掉旧镜像的容器)
docker compose down

# 2. 删掉旧的 MySQL 8 数据卷(卷名以 docker volume ls 为准)
docker volume ls | grep -E 'db_data|itops'
docker volume rm it-ops-system_db_data        # 确认数据可丢弃再执行

# 3. 重新构建启动:MariaDB 会按 init.sql 全新初始化
docker compose up -d --build
docker compose logs -f db | tail -30          # 看到 ready for connections 即成功
docker compose logs -f backend | tail -20     # 看到「数据库连接成功」+「已创建默认管理员账号」

如果旧库数据必须保留(例如已经在用,只是要换镜像),先用旧的 MySQL 8 容器把数据导出来:

# ① 单独起旧的 mysql:8.0 容器挂旧卷,并用 --skip-grant-tables 绕过忘记的口令
docker run -d --name old-mysql -v it-ops-system_db_data:/var/lib/mysql mysql:8.0   --skip-grant-tables --skip-networking=0
sleep 20

# ② 导出(此时无需口令)
docker exec old-mysql mysqldump -uroot --single-transaction --routines --triggers   --default-character-set=utf8mb4 itops > /opt/itops-old.sql

# ③ 起新栈(MariaDB 空库初始化),再把数据灌进去
docker rm -f old-mysql
docker compose up -d --build
sleep 30
docker compose exec -T db sh -c 'mariadb -uroot -p"$MARIADB_ROOT_PASSWORD" itops' < /opt/itops-old.sql
docker compose restart backend

导出文件里如果带 utf8mb4_0900_ai_ci(MySQL 8 默认排序规则),导入 MariaDB 前替换成 utf8mb4_unicode_ci: sed -i 's/utf8mb4_0900_ai_ci/utf8mb4_unicode_ci/g' /opt/itops-old.sql

数据库连不上 / 口令被拒绝?

 

症状:后端日志刷 Access denied for user 'root'@'localhost',或页面登录报 500、docker compose exec db mariadb -uroot -p... 提示 ERROR 1045。

根因只有一个:数据卷已经初始化过,库里的真实口令不会再跟着 .env 变。 MYSQL_ROOT_PASSWORD / MYSQL_PASSWORD 仅在数据目录为空的第一次启动时生效。

三种处理方式(按代价从低到高):

# 方式 1:把 .env 改回当初初始化时用的口令,然后重建容器
docker compose up -d --force-recreate

# 方式 2:进容器改口令(数据保留)
docker compose exec db mariadb -uroot -p        # 用当前能登录的口令
#   → ALTER USER 'root'@'localhost' IDENTIFIED BY '新口令';
#   → ALTER USER 'itops'@'%' IDENTIFIED BY '新口令';
#   → FLUSH PRIVILEGES;
# 改完把 .env 里的口令同步,再 up -d --force-recreate

# 方式 3:数据可丢弃,删卷重建(最干净)
docker compose down -v && docker compose up -d --build

后端已内置友好提示:口令被拒绝时会打印连接目标(itops@db:3306/itops,不含口令)和上述三种处理方式,不会只丢一句 ER_ACCESS_DENIED_ERROR。


自助入口与移动端

 

  • 设置页「自助服务入口」提供二维码与两个免登录链接(指向公网门户):
    • 报障入口:{公网门户地址}/report?k=<入口密钥>
    • 常见问题:{公网门户地址}/faq?k=<入口密钥>
  • 「公网门户地址」填成 http://公网IP:8081(或域名)后,二维码自动改指公网;未填写时会提示「当前二维码只有连内网才能打开」。
  • 端口千万别填 8080:8080 是管理端(要登录),扫码会打开后台登录页,员工看到的是”另一个系统”。填成管理端端口时设置页会红字拦住,后端也会拒绝保存。
  • 报障的故障截图支持直接粘贴:截图后 Ctrl+V(手机长按粘贴),本地压缩后直接上传,不用先存相册再选文件;也保留「选择图片 / 拍照」两个按钮,最多 3 张。
  • 门户页脚显示版本号(如 v20261102),设置页「自助服务入口」也显示同一版本。两边不一致说明浏览器在用旧缓存或服务器门户没更新——门户静态资源已设 no-cache,正常刷新即可。
  • 入口密钥保存在 sys_setting.report_key,可在设置页一键重置(旧二维码立即失效,需重新打印)。
  • 报障时若填写了手机号,查询进度与评价必须校验手机号后 4 位,避免单号被枚举。
  • 报障与 FAQ 接口均有限频,防刷。
  • 宽度 ≤ 820px 自动进入移动端布局:侧栏变抽屉、筛选表单竖排、工单/故障/巡检列表改卡片、弹窗占满宽度、顶部显示当前页面名。
  • 手机端菜单只保留高频入口(数据看板、团队分析、工单录入、工单记录、故障、巡检、待办、项目、知识库、日报生成、日报月报查阅),系统设置放在抽屉底部;桌面端功能仍可通过地址直达。
  • 巡检拍照走系统相机(input capture),不依赖 HTTPS、不触发摄像头授权;上传前自动压缩到 1600px / JPEG。

实时消息说明

 

  • 通道:GET /api/realtime/stream?token=<JWT>,浏览器端全局只建一条连接。
  • 事件:ticket:new(新工单进池)、ticket:taken(被接走/已派单)、ticket:released(退回池子)、ticket:done(已完成)。
  • 反向代理必须关闭缓冲(proxy_buffering off),否则事件会被攒着一起发;frontend/nginx.conf 已为 /api/realtime/ 单独配置。
  • 兜底:页面重新可见(visibilitychange)时主动拉一次待接单池,SSE 断线期间不会漏单。

数据备份与恢复

 

「系统设置 → 数据管理 → 系统备份与恢复」(仅管理员)把整个系统打成一个 zip 包:

包内文件 内容
meta.json 版本、备份时间、各表条数、附件数量
db.json 全部数据表:工单、故障、巡检、台账、知识库、项目、日报/月报、待办、目标、字典、系统设置、账号、AI 配置、审计日志
uploads/* 工单附件、巡检照片等原件
  • 备份包存放在容器内 /app/backups(宿主机 backend/backups,已挂卷),默认保留最近 20 个。
  • 恢复方式:上传 .zip 或直接选服务器上已有的备份包。流程:读包 → 生成「恢复前快照」→ 附件回写 → 数据表在事务内整体替换(失败回滚)→ 校验至少保留一个可用管理员。
  • 备份包包含账号密码哈希与 AI 密钥,请只存放在可信位置。
  • backend/backups/backup.sh 可用于只备份 MySQL 的定时任务(gzip + 保留 30 天):
# crontab -e 加入:每日 2 点备份
0 2 * * * /path/it-ops-system/backend/backups/backup.sh >> /var/log/itops_backup.log 2>&1

安全说明

 

通用

 

  • 密码 bcrypt 加密存储;JWT 会话鉴权;所有写操作走角色校验;按用户隔离数据。
  • 附件上传有扩展名与 MIME 双重白名单(拒绝 html / svg 等可执行内容)。
  • 静态附件响应带 X-Content-Type-Options: nosniff 与 Content-Security-Policy: sandbox,避免上传文件被当作页面执行。
  • 审计日志对敏感字段(密码、Token、密钥)自动脱敏。
  • 建议只在内网部署;如需公网访问,请在前面加一层 HTTPS 反向代理(如 Nginx + Let’s Encrypt)并限制来源 IP。

网络隔离(公网 / 内网)

 

  • 对公网只暴露 8081(员工自助门户);8080(管理后台)只在局域网可达。
  • db 与 backend 不做任何宿主机端口映射,即使服务器有公网 IP 也连不上数据库与内部 API。
  • 门户 nginx 是唯一对公网开的口子,只放行 /api/public/*,其余路径(含 /api/auth、/api/tickets、/uploads)直接 404。
  • 生产建议再叠加:公网门户走 HTTPS(避免报障内容明文)、限制公网侧并发连接数、把管理端访问限制到办公网段(云安全组 / 防火墙白名单 / 宝塔 WAF)。

登录防护(防暴力破解)

 

触发条件 处理
同一账号连续输错 3 次 后续登录必须输入图形验证码(一次性、5 分钟有效,点击图片可刷新)
连续输错 5 次 账号锁定 5 分钟
验证码错误 同样计入失败次数,防止绕过
登录成功 失败计数立即清零
  • 失败计数保存在后端内存(单实例部署足够),重启即清零;多实例部署请迁移到 Redis 或数据库。
  • 账号不存在时也执行一次 bcrypt 比对,避免通过响应时间判断账号是否存在。
  • 停用账号后 60 秒内即无法继续使用旧 Token。

AI 接入

 

AI 能力(智能日报、月度工作报告、知识库整理)按用户各自配置,不使用全局 Token:

  1. 登录后进入左侧菜单「AI 助手」;
  2. 选择供应商(DeepSeek / OpenAI / 通义千问 / Kimi / OpenRouter / Ollama / 自定义),填写 API 地址、Token、模型名;
  3. 点「测试连接」验证后保存。

未配置或调用失败时,系统自动降级为规则汇总(列出今日处理事项与结果),功能不受影响。

报错 原因与处理
429 上游限流,稍后重试或换模型
401 / 403 Token 无效或无该模型权限
404 API 地址或模型名不正确

用本地模型(LM Studio / Ollama / vLLM):后端在容器里,容器内的 localhost 是容器自己。

场景 地址填法
AI 服务与平台同机 http://host.docker.internal:1234/v1
AI 服务在局域网另一台机器 http://192.168.x.x:1234/v1

只填到 /v1 即可,系统自动补全 /v1/chat/completions;Token 可留空(未填则不发送 Authorization 头);模型名不确定时点「获取模型」自动拉取 GET /v1/models 列表。


生产部署建议

 

  1. 改默认口令:admin 初始密码与 .env 中的 MYSQL_*、JWT_SECRET 全部替换为随机值(openssl rand -hex 32)。
  2. 数据持久化:db_data 卷、backend/uploads、backend/backups 已挂载到宿主机;迁移服务器时整目录拷贝即可。
  3. 开机自启:三个服务均已配置 restart: unless-stopped。
  4. 端口收敛(重要):只把 8081(员工自助门户)映射到公网;8080(管理后台)限内网访问。db 与 backend 默认不做宿主机映射,不要为了”方便”给它们加公网端口。
  5. 反向代理与 HTTPS:域名访问时用外层 Nginx / 宝塔 WAF 转发到 127.0.0.1:8080(管理端)与 127.0.0.1:8081(门户),并为 /api/realtime/ 保留 proxy_buffering off 与较长的 proxy_read_timeout。
  6. 定时备份:同时开启「系统设置 → 备份恢复」的 zip 备份与服务器 crontab,并定期把备份包拷贝到别的机器。
  7. 日志与监控:docker compose logs -f backend,或接入宿主机日志收集;内置调度器会在每日固定时间推送提醒,可用作存活探测。

常用运维命令:

docker compose ps                    # 查看服务状态
docker compose logs -f --tail=200 backend
docker compose restart backend        # 只重启后端
docker compose down                   # 停止(保留数据)
docker compose up -d                  # 启动

升级与更新

 

升级步骤(Docker 部署)

 

# 1. 先备份:登录系统 →「系统设置 → 备份恢复」→ 立即备份并下载 zip
#    同时备份宿主机上的上传目录
cp -r backend/uploads  /backup/uploads-$(date +%F)

# 2. 拉取新代码
git pull                # 或解压新的发布包覆盖

# 3. 重新构建并启动(数据库结构变更由后端启动时自动幂等迁移)
docker compose up -d --build

# 4. 验证
docker compose logs -f backend     # 看到 [migrate] 相关日志且无报错

数据库升级机制:后端每次启动会执行 migrateSchema(),全部为 CREATE TABLE IF NOT EXISTS / 「列不存在才新增」,可重复执行;sys_meta 表记录一次性数据修复,已执行过的不会再跑。因此升级不需要手工执行 SQL,回滚同理(把代码切回旧版本重启即可)。

升级会不会把数据清空?——不会

 

这是刻意设计的行为,升级时请认准一个原则:只要不带 -v,数据就一定在。

操作 会不会重新执行 init.sql 工单数据
docker compose restart 不会 保留
docker compose up -d --build(日常升级) 不会 保留
docker compose up -d --force-recreate 不会 保留
换镜像版本后重建 不会 保留
docker compose down(不加 -v) 不会 保留
docker compose down -v 会(空库重建) 全部清空

原因:sql/init.sql 挂在 /docker-entrypoint-initdb.d/,数据库入口脚本只在数据目录为空时才执行它。数据卷 mariadb_data 里有内容之后,这个脚本就会被跳过。

想更省心可以直接用升级脚本(自带检查,绝不会删卷):

bash scripts/upgrade.sh          # 用当前代码重建容器
bash scripts/upgrade.sh --pull   # 先 git pull 再升级

脚本会先检测数据卷是否存在、提示先备份,然后执行 docker compose up -d --build,永远不会带 -v。

前端构建更新(不走 Docker)

 

cd frontend && npm install && npm run build     # 产物在 frontend/dist
# 将 dist 覆盖到 Nginx 站点目录即可

员工门户(public-portal)改了要重建 public-web

 

门户是独立的静态站镜像(public-web 服务),改完 public-portal/ 下的文件必须重建该服务, 否则员工扫码看到的还是旧页面(管理端和门户是两个不同的容器):

docker compose up -d --build public-web

排查「扫码看到的样式不对」按顺序看:

  1. 页脚版本号(如 v20261102)是否与「系统设置 → 自助服务入口」显示的门户版本一致; 不一致说明浏览器在用旧缓存(已设 no-cache,强刷即可)或服务器没重建 public-web。
  2. 设置页填的公网地址端口是不是 8081(填成 8080 会打开后台登录页,形状完全不同)。
  3. 手机在不在能访问到该地址的网络里(公网 IP / 端口映射 / 安全组)。

版本管理建议

 

  • 用 Git 管理代码,main 为稳定分支,改动走特性分支合并。
  • 每次发布打 tag(如 v1.2.0)并在更新日志登记变更。
  • .env、backend/uploads/、backend/backups/ 不纳入版本管理(已在 .gitignore 中排除)。

重要提示

源码工具资源类要求技术能力: 源码工具对技术要求较高,不建议小白购买下载,建议具有一定思考和动手能力的用户购买。
请谨慎考虑: 小白和缺乏思考动手能力者不建议赞助。本站只收集整理资源,部分源码不一定能运行。有空会测试部分源码及修改,赞助前请谨慎!
虚拟商品购买须知: 虚拟类商品具有可复制性,一经打赏赞助,不支持退款。请谅解,谢谢合作!

© 版权声明
THE END
喜欢就支持一下吧
点赞10 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容