Skip to content

Repository files navigation

MyIcon

极简图标库,专为 NAS 设计。图标管理 Web 应用,提供在线图标链接,支持分类管理、上传、搜索、编辑、缩略图缓存与数据统计。

截图

首页 设置页 关于页
home settings about

技术栈

  • 框架: Nuxt 4 + Vue 3(SSR)
  • UI: Element Plus(按需导入)+ 玻璃态设计
  • 图表: ECharts 6(按需导入:PieChart + TooltipComponent + LegendComponent)
  • 国际化: 中文 / English(@nuxtjs/i18n)
  • 后端: Nitro(Nuxt 内置服务端)
  • 缩略图: sharp(WebP,200px,按需生成 + 后台批量生成)
  • 密码哈希: Node.js 内置 crypto.scryptSync(零依赖)
  • 容器化: Docker + docker-compose

功能一览

  • 图标上传、分类管理、搜索、编辑、删除
  • 缩略图自动生成与缓存(WebP,按需生成 + 后台批量生成 + 进度轮询)
  • 数据统计与分类饼图(ECharts,实时动画)
  • 多语言支持(中文 / English)
  • 深浅色主题切换(玻璃态 UI,暗色自适应遮罩)
  • 壁纸(本地/网络/自定义上传)+ 毛玻璃效果 + 自动压缩
  • 登录鉴权 + 游客模式(只读,动态切换)
  • 设置页瀑布流布局(9 张卡片,列数自适应)
  • 管理员「发布到服务器」按钮(仅修改后显示,影响全站)
  • 路径穿越防护、IP 限流、错误脱敏

快速开始

前置要求

  • Node.js >= 22

本地开发

# 安装依赖
npm install

# 开发模式(默认 http://localhost:3000)
npm run dev

# 生产构建与预览
npm run build
node .output/server/index.mjs

Docker 部署

# 构建并启动
docker compose up -d --build

# 访问 http://localhost:3000

开发脚本

项目附带 dev.sh 自启动脚本:自动释放 3000 端口、清理残留 nuxi 进程、后台启动并等待 HTTP 200:

bash dev.sh

使用说明

角色权限

角色 操作范围
管理员 完整 CRUD:上传/编辑/删除图标、管理分类、站点设置(含发布)、认证配置、缩略图生成
游客 只读浏览:搜索图标、查看分类、复制链接;设置页可修改个人偏好(仅本地 localStorage 保存)

设置页(管理员)

设置页共 9 张卡片,瀑布流布局,列数自适应窗口宽度:

区块 功能
外观设置 深浅模式、背景模糊、界面配色(4 色)、文字颜色(2 色)、图标配色(2 色)
壁纸设置 本地/网络/自定义上传、背景色
图标设置 图标大小、卡片圆角、间距、名称/边框显示、图标配色
搜索设置 显示搜索框、实时搜索、排序方式/顺序
分页设置 显示分页、单页隐藏、每页数量
文字内容 网站名称、功能介绍、描述文字
站点设置 界面语言、URL 前缀、自定义 CSS
账号安全 游客模式开关、用户名、密码修改
数据管理 图标分类饼图、数据统计(图标/缓存/空间)、缩略图生成/删除

管理员修改任意配置后,右上角出现「发布」按钮 → 点击写入 setting.json,全站生效。游客的本地偏好不受影响。

图标分类

  • 分类文件夹命名:索引 + "_" + 文件夹名称(如 01_图标
  • 文件夹封面图:Cover.png(放在对应分类文件夹下)
  • 上传图标到对应分类,点击图标即可获取 URL 链接
  • 支持搜索、分类筛选、分页浏览

缩略图

  • 按需生成:首次访问图标时自动生成 WebP 缩略图(200px 宽,参考 server/api/thumb.get.js
  • 后台批量生成:设置页「数据管理」→ 点击「生成缓存」,后台任务边生成边返回进度
  • 本地脚本:scripts/generate-thumbs.mjs 可独立运行批量生成(node scripts/generate-thumbs.mjs

项目结构

myicon/
├── app/                      # 前端
│   ├── pages/                # 路由页面
│   │   ├── index.vue         # 首页(导航 + 搜索 + 子页面切换,~755 行)
│   │   ├── home.vue          # 图标网格 + 分类筛选 + 分页(~591 行)
│   │   ├── setting.vue       # 设置页(9 张卡片,瀑布流,~1606 行)
│   │   ├── about.vue         # 关于页(8 张卡片,瀑布流,~561 行)
│   │   ├── login.vue         # 登录页(打字机效果 + 记住账号,~521 行)
│   │   └── [...slug].vue     # 安全兜底(catch-all 404)
│   ├── components/           # IconDialog.vue / FolderDialog.vue / IconPublish.vue
│   ├── layouts/              # blank.vue / default.vue
│   ├── assets/               # 静态资源
│   ├── plugins/              # 插件(auth-sync.client.js)
│   └── utils/                # api.js(Token 管理 + API 封装)/ color.js(颜色工具)
├── server/                   # 后端
│   ├── api/                  # API 路由
│   │   ├── config.js         # 通用文件操作 CRUD(read/write/readDir/mkdir/rename/delete/upload)
│   │   ├── icon-files.js     # 批量读取图标文件列表(公开)
│   │   ├── auth-status.get.js  # 游客模式状态(公开)
│   │   ├── authConfig.js     # 认证配置读取(需登录)
│   │   ├── authSave.js       # 认证配置写入(需登录)
│   │   ├── login.js          # 登录验证(scrypt 校验 + Token 签发)
│   │   ├── data-stats.js     # 数据统计 GET + 缩略图生成/删除 POST(含进度轮询)
│   │   └── thumb.get.js      # 缩略图按需生成(路径校验 + sharp 实时生成)
│   ├── middleware/           # rate-limit.js(IP 限流中间件)
│   ├── data/                 # auth.json / tokens.json(认证数据,Docker volume)
│   └── utils/                # auth.js(Token 验证/清理)/ hash.js(scrypt 哈希)
├── i18n/                     # 国际化
│   ├── locales/              # zh-CN.json(236 条)/ en-US.json(236 条)
│   └── i18n.config.ts        # Vue I18n 配置
├── public/data/              # 运行时数据(Docker volume)
│   ├── icon/                 # 图标文件(按分类文件夹)
│   ├── wallpaper/            # 壁纸图片
│   ├── img/                  # UI 资源图片
│   ├── qrcode/               # 打赏二维码
│   ├── .thumb/               # 缩略图缓存(WebP,自动生成,可重建)
│   └── setting.json          # 站点配置(管理员发布写入)
├── scripts/                  # 工具脚本
│   └── generate-thumbs.mjs   # 批量生成缩略图(独立运行)
├── Dockerfile                # 多阶段构建(node:22-slim)
├── docker-compose.yml        # 双 volume 持久化
├── dev.sh                    # 开发自启动脚本
├── nuxt.config.ts            # Nuxt 配置(Element Plus 按需 + i18n + 字体预加载)
└── package.json

数据存储

数据 路径 持久化(Docker)
图标文件 public/data/icon/ volume myicon-data
壁纸 public/data/wallpaper/ 同上
站点配置 public/data/setting.json 同上
UI 图片 public/data/img/ 同上
打赏二维码 public/data/qrcode/ 同上
认证配置 server/data/auth.json volume myicon-auth
登录 Token server/data/tokens.json 同上
缩略图缓存 public/data/.thumb/ 可随时重建,不入库

环境变量

变量 默认值 说明
NITRO_PORT / PORT 3000 服务端口
NITRO_HOST 0.0.0.0 监听地址(Docker 默认 0.0.0.0

无自定义环境变量。反代场景下,中间件通过 x-forwarded-forx-real-ip 取客户端 IP 用于限流(无需额外配置)。

API 参考

公开接口(无需登录)

端点 方法 说明
/api/auth-status GET 返回 { tourist: boolean },游客模式开关
/api/icon-files GET 所有分类及文件列表(含图标名称、扩展名、大小)
/api/thumb?path=... GET 缩略图(按需生成,路径相对 public/data/
/api/data-stats GET 数据统计(分类/图标/缓存/空间)

需登录接口(管理员)

端点 方法 说明
/api/login POST 登录验证,返回 { token, mode, username }
/api/config POST 文件操作(read/write/readDir/mkdir/rename/delete/upload)
/api/authConfig GET 读取认证配置({ tourist, username }
/api/authSave POST 写入认证配置({ tourist, username, password }
/api/data-stats POST 缩略图管理(action: generate/progress/delete

限流规则

中间件规则按路径前缀匹配(server/middleware/rate-limit.js,内存计数,按分钟窗口重置)。

路径 限制 说明
/api/login 5 次/分钟/IP 登录尝试
/api/authSave 20 次/分钟/IP 认证配置保存
/api/config 120 次/分钟/IP 文件操作(读/写/目录/上传)

安全

  • 密码哈希: crypto.scryptSync(salt + 64 字节 hash),支持旧明文密码兼容迁移
  • Token 管理: 随机 32 字节 hex,7 天过期,写入前自动清理过期条目,防止文件膨胀
  • 路径穿越防护: path.join + startsWith(ALLOWED_ROOT) 校验,拒绝越界访问
  • 上传校验: 白名单扩展名(png/jpg/jpeg/gif/webp/svg)+ 10MB 上限
  • 壁纸自动压缩: >512KB 的图片自动缩放到 ≤1920px 宽(保持原格式),节省存储与带宽
  • IP 限流: 进程内内存计数,按分钟窗口重置,Retry-After 响应头提示
  • 错误页: 自定义 404/错误页(app/error.vue),生产环境由 Nitro 默认脱敏错误响应
  • 认证数据隔离: server/data/ 不在 public/ 下,外部无法直接访问
  • 缩略图路径校验: 仅允许 public/data/ 下的文件生成缩略图

计划改进

  • 图标搜索防抖(大数据量性能优化)
  • 图标网格虚拟滚动或分页懒加载
  • 密码哈希迁移:旧明文密码自动升级为 scrypt
  • 通用 CSRF 中间件(当前仅依赖同源策略)
  • 切片上传支持大文件
  • 远程图标库拉取

About

轻量自托管图标库 — NAS 图标管理工具(Nuxt 4 + Element Plus)

Resources

Stars

4 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages