基于 Electron + Vite + Vue 3 的 Windows 平台本地 AI 绘画模型管理软件,单文件便携 EXE,开箱即用。
- 扫描与自动分类:递归扫描
.safetensors/.ckpt/.pt/.pth/.bin,按名称关键词自动分类为 Checkpoint / TextEncoders / VAE / LoRA,其余归入「其他模型」;支持二级分类标签、LoRA 标签(角色/风格/概念等)与 Checkpoint 基底模型标注;进度展示、随时取消、可排除目录 - 多模型库:保存多个模型根目录,侧栏一键切换;每个库的元数据与封面相互独立;切换时优先读取库内本地索引秒开列表,再后台校验磁盘结果;索引随局部扫描/删除增量维护,不再等待下一次全量扫描才更新
- 跨库移动/复制:把模型(含标注、封面、同名 sidecar)在多个已保存库之间整体迁移——保持库内相对路径镜像,元数据键与封面引用零重写直接生效;移动模式成功后清理源(同盘瞬时 rename,跨盘自动回退复制),目标已有同名文件跳过不覆盖,目标库存在未同步日志时拒绝迁移防止标注回退
- 目录监控:可选开启变更自动重扫——轮询快照比对(条目增删/重命名)+ 低频内容校验(同名覆盖写入),防抖合并后变更子树走局部增量扫描就地合并,不误触发关联写入
- 文件管理:重命名模型文件(扩展名保持不变,同名 sidecar 与标注同步迁移)、删除移入系统回收站并清理关联数据、打开所在文件夹、复制路径/推荐参数、原生右键菜单
- 模型导入:从本机任意位置多选模型文件,复制或移动入台;同名
.txt/.civitai.info/ 预览图一并搬运,重名自动追加编号,不覆盖库内文件,导入后局部扫描即时入列 - 重复检测:后台按体积预筛预热 SHA256(默认只计算大小相同的候选模型,避免全库读盘;可在设置中切换「全库预热/关闭」),渐进就绪无需重扫;内容完全相同的重复模型以角标提示,一键筛选重复项(按哈希分组聚拢),智能保留评分/收藏/最新最优副本、冗余副本批量移入回收站
- 双视图浏览:网格/列表切换,虚拟滚动支撑数千模型流畅浏览;缩略图后台缓存、多预览图悬停轮播;「智能视图」可保存当前搜索/筛选/排序组合,侧栏一键切换
- 搜索与筛选:按名称/备注/触发词搜索,按分类与收藏筛选,多种排序;搜索框支持结构化语法(与筛选叠加):
base:pony(基底家族)、tag:"我的标签"、type:lora、size:>1gb、score:>=4、fav:yes、nsfw:no,多个条件 AND 组合 - 封面管理:上传 / Ctrl+V 粘贴 / 拖拽导入多张预览图,可设默认封面,自动识别同名 sidecar 图,孤儿文件自动清理;一键移除全部示例图时同步清理对应失效缩略图
- 收藏 / 评分 / NSFW:星标收藏、五星评分即时保存;NSFW 模型封面默认模糊展示(可关闭),设置页可一键隐藏全部 NSFW 模型(含手动标注,搜索与筛选不再命中)
- 文件元数据自动解析:safetensors 头部本地毫秒级解析(仅读头部,零网络)——训练元信息(标题/作者/基底模型/网络结构/精度/训练分辨率)、张量统计(参数量、主精度、文本编码器·UNet·VAE 字节构成)与按键名推导的架构家族(SD1.5/SDXL/Flux/SD3.5);触发词候选与推荐分辨率一键填入,绝不覆盖用户标注
- 标签管理:设置页对全库自由标签重命名/合并/移除,整库生效并即时落盘(目标名已存在时自动合并)
- 推荐参数:为每个模型保存采样步数、CFG、采样器、调度器、精度、推荐分辨率区间与备注
- 批量操作:
Ctrl+点击快速多选、Shift+点击范围选择(与资源管理器同语义);批量收藏/评分/NSFW/标签/触发词填充/Civitai 识别/禁用/删除;长耗时批量可随时Esc请求取消并保留已完成部分 - Civitai 在线识别:走 civitai.red 站点(NSFW 模型无需跳转即可识别),按文件 SHA256 反查模型版本,一键补全空缺的触发词与备注(绝不覆盖已有标注),可勾选示例图批量导入为封面;哈希结果持久缓存并由后台队列预热,首次识别也可秒级返回
- 应用内检查更新:设置页一键查询 GitHub Releases 最新版本;启动后延迟静默自动检查(可关闭),发现新版本时提示并可直接在设置页下载
- 关联存储:界面设置(主题/视图/智能视图/扫描规则等)与封面、参数、备注等用户数据全部保存在模型根目录的
.modelvault/内,按相对路径关联,随文件夹移动/复制保持关联——换电脑打开即恢复完整配置;库内移动/重命名后重扫时自动重关联元数据(宁可不绑也绝不绑错);库目录离线(被移动/盘符未挂载)时写入自动挂起并保留在内存,恢复后补写,绝不在失效路径重建目录 - 数据备份:一键将当前库的设置与标注、封面打包为 zip,支持完整 / 仅标注 / 当前筛选结果三种范围,可恢复到任意模型文件夹(恢复前自动快照防覆盖);提供模型库体检——幽灵标注 / 失效封面引用 / 孤儿封面的只读检查与一键安全修复
- 模型清单导出:设置页「数据管理」中将当前搜索/筛选/排序结果导出为 CSV(Excel 可直接打开)/ Markdown 表格 / JSON(保留结构化字段),便于外部整理与分享
- 体验细节:亮/暗/跟随系统主题(同步原生标题栏)、强调色预设与自定义、卡片尺寸与展示内容配置、详情页全屏画廊、窗口尺寸位置记忆
模型浏览:卡片式首页,左侧分类筛选与计数、顶部搜索与排序,扫描全程异步不阻塞 UI。
模型详情:上传/粘贴封面图片、编辑推荐参数与备注。
Civitai模型站识别:一键识别Civitai模型站对应链接并获取示例图。
软件设置:支持丰富的自定义设置内容。
环境要求:Windows 10 及以上,Node.js ≥ 22.22.2(package.json engines 强制要求)。
# 1. 安装依赖
npm install
# 2. 启动开发模式(热重载)
npm start| 组件 | 版本 | 说明 |
|---|---|---|
| Electron | ^44 | 跨平台桌面运行时 |
| electron-vite | ^5 | 构建/开发工具链,内置 HMR 热重载 |
| Vue 3 | ^3.5 | 渲染进程前端框架 |
| electron-builder | ^26 | Windows 打包(portable 单文件便携版) |
| Vite | ^7 | 底层构建引擎 |
| vitest | ^5 | 单元测试(主进程 + 渲染层 store/组件) |
| 操作 | 快捷键 | 说明 |
|---|---|---|
| 聚焦搜索框 | Ctrl+F |
全局可用(面板打开或未选文件夹时无效) |
| 进入多选并全选 | Ctrl+A |
作用于当前筛选结果;输入框内保持原生全选 |
| 退出多选 | Esc |
批量进行中先请求取消(保留已完成部分);无多选时清空搜索 |
| 批量收藏 | Ctrl+D |
多选模式批量收藏;详情打开时收藏当前模型 |
| 批量删除 | Delete |
多选模式移入系统回收站(弹确认层) |
| 快速勾选 | Ctrl+点击 |
非多选模式直接进入多选并选中该卡片/行 |
| 范围选择 | Shift+点击 |
从上次点击项范围选中(与资源管理器同语义) |
| 网格/列表导航 | 方向键 / Home / End |
移动焦点卡片/行 |
| 激活焦点项 | Enter / Space |
打开详情;多选模式下切换选中 |
| 收藏 / 删除焦点项 | F / Delete |
焦点卡片快速收藏;弹出删除确认 |
输入控件(搜索框/文本域/下拉)内除
Ctrl+F外均不拦截按键,保持原生文本编辑行为。
| 命令 | 说明 |
|---|---|
npm start / npm run dev |
启动开发模式(主进程/渲染进程热重载) |
npm run build |
编译主进程、preload、渲染进程到 out/ |
npm run lint |
ESLint 代码检查(flat config,错误级规则) |
npm run typecheck |
TypeScript checkJs 类型检查(shared 契约层 + preload + 主进程服务层,渐进扩展) |
npm test |
运行单元测试(vitest,test:watch 为监视模式) |
npm run test:coverage |
运行单元测试并生成覆盖率报告(含防退化阈值门禁) |
npm run preview |
以生产构建产物启动应用预览 |
npm run dist |
编译并打包单文件便携版 EXE 到 dist/{version}/ |
npm run dist:dir |
编译并生成免安装目录(快速验证打包结果) |
- 打包配置见
electron-builder.yml(portable 单文件便携版,x64),产物为dist/{version}/ModelVault-{version}.exe - 单文件 EXE 运行时不在其所在目录生成任何文件:引导信息(库列表/激活库)与日志保存在
%APPDATA%\modelvault\,库设置与模型元数据随库保存在用户选择的模型文件夹 - 首次启动需解压到系统临时目录,启动速度略慢于常规安装版;Windows 10+ 可直接运行,无额外运行时依赖
- 如需更换应用图标,替换
build/icon.ico(需包含 256×256 及以上尺寸);也可临时放置 512×512 以上的正方形icon.png到build/,运行node scripts/generate-icon.mjs生成多尺寸 ico(源图不入库)
ModelVault/
├── build/ # 打包资源:应用图标 icon.ico
├── image/ # 软件界面截图(README 展示用)
├── .github/workflows/ # CI 质量门禁(ci.yml)+ 标签发布构建(release.yml)
├── scripts/ # 工具脚本(应用图标生成 / CSP 检查)
├── src/
│ ├── shared/ # 主/渲染进程共享常量(分类标签/扩展名/默认设置/枚举)
│ ├── main/ # 主进程
│ │ ├── index.js # 应用入口:生命周期、单实例锁、全局错误处理
│ │ ├── windows/mainWindow.js # 主窗口创建/管理(窗口状态记忆、WCO 标题栏)
│ │ ├── menu.js # 窗口级快捷键(无原生菜单栏模式)
│ │ ├── ipc.js # IPC 处理器注册入口(应用信息/主题/异常上报)
│ │ ├── ipc/models/ # 模型管理 IPC 处理器(按域拆分:scan/decorate/covers/
│ │ │ # meta/misc/files/civitai/backup/store/model-state)
│ │ ├── protocol.js # mvimg:// / civimg:// 自定义图片协议(白名单校验)
│ │ ├── fatal-error.js / quit.js / theme.js / logger.js / utils.js
│ │ └── services/ # 主进程服务层:扫描分类、关联存储(.modelvault/)、
│ │ # 原子写入、元数据重关联、目录监控、封面/缩略图、
│ │ # 备份恢复、检查更新、Civitai 客户端、哈希预热、
│ │ # safetensors 头部解析等
│ ├── preload/index.js # 预加载脚本:contextBridge + IPC 通道白名单
│ └── renderer/ # 渲染进程(Vue 3)
│ └── src/
│ ├── App.vue / main.js / error-report.js # 根组件 / 入口 / 错误上报链路
│ ├── constants/ # 推荐参数常量、强调色预设
│ ├── store/ # 全局响应式状态(按域拆分:筛选/库切换/批量/
│ │ # 增量扫描/封面/Civitai/智能视图/派生数据等)
│ └── components/ # TopBar / Sidebar / VirtualModelGrid / VirtualModelList /
│ # ModelCard / ModelDetail(含 detail/ 封面面板、
│ # AutoInfoPanel、CivitaiPanel、CoverGallery)/
│ # BatchBar / ConfirmOverlay / StatsSection /
│ # SettingsPage / ToastHost
├── tests/ # vitest 单元测试(主进程 + 渲染层 store 与组件)
├── electron.vite.config.mjs # electron-vite 配置
├── electron-builder.yml # 打包配置(portable 单文件)
└── package.json
渲染进程没有裸 invoke 入口,所有 invoke 通道必须在 src/shared/ipc-schema.js 注册表登记(单一来源:preload 白名单由注册表键集派生,payload schema 一并声明,未登记通道被 fail-closed 拒绝):
- 在
src/shared/ipc-schema.js的IPC_PAYLOAD_SCHEMAS中登记通道:带参通道用vObj/vStr等构造器声明 payload 结构门禁,无参通道登记vVoid():
'my:channel': vObj({ fields: { id: vStr({ required: true, max: 2000 }) } })- 在
src/main/ipc.js或src/main/ipc/models/对应域模块中注册处理器(统一经wrapHandler,自动执行 schema 前置校验与异常兜底;事件推送类通道在IPC_EVENT_CHANNELS登记,preload 的订阅白名单由此派生):
wrapHandler('my:channel', async (event, payload) => {
return 'result'
})- 在
src/preload/index.js的api对象中添加语义化方法(内部统一走invokeValidated/subscribe),渲染进程通过window.api.myDomain.doThing(payload)调用。
invoke 通道与两侧调用/注册点、事件通道与 preload 订阅点的一致性均由
tests/ipcSchema.test.js双向对账锁定,任一侧漏改即测试失败。
项目为纯 JavaScript,以 TypeScript 编译器 checkJs 模式做纯类型检查(npm run typecheck,无构建产物):tsconfig.json 当前覆盖 src/shared/(IPC 通道单一来源注册表、默认设置等跨进程契约)、src/preload/、src/main/ 全层(services、ipc handlers、协议/窗口/入口)以及 src/renderer/src/ 全部 .js(store/composables/components 纯逻辑/常量;.vue 模板不在 checkJs 范围,由组件测试覆盖)。src/renderer/src/store/global.d.ts 声明 window.api 与 *.vue/*.css 模块;strict 关闭以聚焦真实类型错误。覆盖范围与严格度按棘轮渐进扩展;为跨模块共享的数据结构补写 JSDoc 类型标注(如 SchemaRule/WatcherState/BackupManifest typedef)即可让检查器捕获字段改名/漏改类回归。
应用不显示原生菜单栏,快捷键在 src/main/menu.js 中通过 before-input-event 窗口级注册:F11 全屏切换;DevTools 与刷新快捷键仅在开发环境生效。窗口统一在 src/main/windows/ 管理,可参照 mainWindow.js 创建多窗口。
- 位置:
%APPDATA%\modelvault\logs\modelvault-YYYY-MM-DD.log(按天分文件,保留 14 天) - 用法:
import logger from './logger'后调用logger.info / warn / error - 性能基线(PERF-2):冷启动/切库等关键路径耗时以
[perf]前缀写入日志(startPerf打点,见src/main/services/perf.js;缩略图渲染仅记录超过 2s 的慢任务),优化前后可按前缀检索对比 - 主进程全局异常自动记录;渲染进程异常经
app:reportError通道上报写入同一日志,同类错误节流降噪
单元测试位于 tests/(93 个文件 / 1382 用例;渲染层 store 测试自 appStore.test.js 按域拆分为 appStore*.test.js,共享装配在 tests/helpers/storeTest.js):主进程纯逻辑与 IPC handler(node 环境)、渲染层 store 按域拆分测试、组件交互测试(@vue/test-utils + jsdom,文件头 // @vitest-environment jsdom 声明)。Electron API 在 tests/setup.js 中统一 mock,公共挂载/IPC 脚手架在 tests/helpers/ 中复用。新增纯函数模块或组件交互时请同步补充用例,运行 npm test 验证;npm run test:coverage 受防退化阈值门禁约束(Statements 80% / Branches 73% / Functions 77% / Lines 82%,棘轮渐进上调),store-meta/store-settings/watcher/backup 等数据完整性关键服务另有 per-file 覆盖率地板(见 vitest.config.mjs)。
ci.yml:push 到 main / PR 时运行质量门禁(Node 22/24 矩阵:ESLint → 类型检查 → 单元测试 → 三端编译 → 产物完整性校验 → 覆盖率归档)release.yml:推送v*标签触发 Windows 打包,自动创建 GitHub Release 并附加 EXE 与 SHA256 校验和- 发版流程与版本号约定(A2):版本标签统一采用
v{major}.{minor}.{patch}语义化格式(如v0.6.0),且必须与package.json的version一致(workflow 内置校验,不一致即失败)。发版步骤:更新package.json版本号并提交 →git tag v0.6.0→ 推送标签即自动构建并创建 Release(新 Release 默认标记为 Latest);打包流程可在 Actions 页用workflow_dispatch输入版本号做不建 Release 的演练。历史Beta-0.x标签为遗留格式:应用内更新只识别 v 前缀纯数字三段版本(V-06 安全设计),Latest 为遗留标签时会自动回查 Release 列表取最新合规版本,列表内也无合规版本则视为暂无更新 - 代码签名(E1):配置仓库 Secrets
CSC_LINK(base64 PFX)与CSC_KEY_PASSWORD后,electron-builder 自动为 EXE 做 SHA256 Authenticode 签名;MODELVAULT_SIGNER_THUMBPRINT(证书 SHA1 指纹)会在构建期注入主进程,应用内更新下载复用与安装前均强制「签名有效 + 指纹一致」。未配置证书时构建继续,应用内更新退化为仅 SHA256 校验
contextIsolation: true+nodeIntegration: false+sandbox: true,渲染进程无 Node 能力;preload 仅暴露白名单通道mvimg://图片协议仅允许访问当前模型根目录内文件(越界返回 403);civimg://远程图片代理仅放行 Civitai 官方 CDN 域名白名单(https 强制,防 SSRF)- 渲染进程导航一律拦截,外部链接经系统浏览器打开;HTML 含 CSP 策略
- 模型删除移入系统回收站(非永久删除);扫描根目录白名单校验;删除/移动/重命名/禁用/跨库传输等破坏性操作统一按 realpath 校验归属,库内 junction 指向库外时拒绝;封面导入有图片魔数校验与大小预检
- 应用内更新强制 SHA256 校验;配置发布者证书指纹后,下载复用与安装前还会校验 Authenticode(状态 Valid + 指纹一致),失败即拒绝执行
- 开发类快捷键(DevTools/刷新)在生产环境禁用



