lionwebsite-frontend-desktop/llm_readme.md
chuzhongzai e25afb7445 重构 store 并修复多个 bug
- state.collectGallery.slice(0) → splice(0),修复收藏列表数据残留 bug
   - action 中 state 引用改为 context.state,遵循 Vuex 规范
   - 修复 _searchLocalByLink 中 gid 判空条件(null → undefined)
   - 修复 deleteTask splice 后索引跳过下一个元素
   - 简化 getShortname 用正则替代繁琐的手动遍历
   - 移除 loadWeekUsedAmount 冗余的成功提示弹窗
   - 添加 Axios 全局错误拦截器,统一处理网络请求失败
   - websocket 初始值 {} → null,修正类型
   - resetUndone 硬编码授权码改为从 state 获取
   - computed 移除副作用,改用 watch 实现
   - HentaiSearch 加载指示器 DOM 操作改为响应式 v-show
   - 提取重复的 validateLink 到共享工具函数
   - OnlineReader 全量 watch(store.state) → 精准监听 isReading
2026-06-07 16:18:44 +08:00

9.2 KiB
Raw Blame History

LionWebsite 项目分析

项目概述

LionWebsite 是一个基于 Vue 3 + Vite 构建的漫画/Gallery 下载与管理前端应用。用户通过授权码连接后端服务,可以搜索、下载、在线预览来自 exhentai/e-hentai 的漫画 gallery并管理下载任务。

后端基址: https://downloader.lionwebsite.xyz/

技术栈

技术 用途
Vue 3 (Composition API, <script setup>) 前端框架
Vite 5 构建工具
Element Plus 2.2 UI 组件库
Vuex 4 状态管理
Axios HTTP 请求
qs URL 序列化

项目结构

D:\WorkSpace\code\Vue\LionWebsite\
├── index.html              # 入口 HTML
├── package.json            # 依赖声明
├── vite.config.js          # Vite 配置(仅 vue 插件 + 0.0.0.0 host)
├── public/                 # 静态资源(空)
├── dist/                   # 构建产物
└── src/
    ├── main.js             # 应用入口: mount Element Plus + 全局 CSS
    ├── reset.css           # CSS reset
    ├── App.vue             # 根组件: el-container 布局
    ├── store/
    │   └── index.js        # Vuex store (所有状态与业务逻辑)
    └── components/
        ├── DashBoard.vue   # 仪表盘: 授权、查询、配置、搜索结果弹窗
        ├── Side.vue        # 主列表: Gallery 表格、翻页、分类/排序
        ├── HentaiSearch.vue# 在线搜索弹窗: 远程搜索 exhentai gallery
        └── OnlineReader.vue# 在线预览弹窗: 阅读下载完成的 gallery

组件详解

App.vue (根组件)

  • 使用 el-container 布局
  • 左侧 el-aside (750px) 放置 Side 组件
  • 右侧 el-main 放置 DashBoard 组件

DashBoard.vue — 仪表盘

功能: 授权登录、查询任务、修改授权码、在线搜索入口、节点重连、配置管理

  • 授权模块: 输入授权码 → 调用 store.dispatch("validate") → 记住密码(localStorage)
  • 查询模块: 支持按链接远程查询或按链接/关键字本地查询
  • 操作按钮: 修改授权码、删除本地授权码、夜间模式切换、在线搜索入口、重连节点
  • 配置弹窗: 夜间模式(跟随系统)、在线预览分页数、默认分类/排序/显示类型 → 持久化到 localStorage
  • 查询结果弹窗: 显示 gallery 详细信息,可选择分辨率提交下载任务
  • 缩略图预览: 鼠标悬停 gallery 时在仪表盘显示封面缩略图
  • 初始化: onMounted 时从 localStorage 恢复授权码与配置

Side.vue — 主列表

功能: 展示 gallery 表格、分页、分类/排序切换

  • 表格: 使用 Element Plus el-table,列含展开行(详细信息)、名字、操作(下载/收藏/在线看)、进度
  • 操作列:
    • 下载: 仅当 status==="下载完成" 时可用,直接 window.open 下载链接
    • 收藏/取消收藏: 调用 collectGallery / disCollectGallery
    • 在线看: 调用 readOnlineGallery
  • 分类切换: 我的下载 / 我的收藏 / 全部
  • 排序: 名字 / 简洁名字 / 任务创建时间
  • 显示类型: 完整名字 / 简洁名字
  • 翻页: 首页/上一页/下一页/尾页 + 直接输入页码
  • 缩略图悬停: 500ms 防抖后触发缩略图更新
  • 空状态提示: 根据分类显示"您未下载过"或"您未收藏过"

HentaiSearch.vue — 在线搜索

功能: 远程搜索 exhentai 上的 gallery

  • 输入关键字 → 调用 https://downloader.lionwebsite.xyz/query?keyword=xxx
  • 支持分页导航(首页/上一页/下一页/尾页),后端返回分页链接
  • 每个搜索结果展示: 封面缩略图、名字、上传时间、页数、类型、链接
  • 操作: "在线看"直接阅读、"查看详情"查询到本地并打开详情弹窗
  • 加载状态: CSS 旋转动画 loading 指示器

OnlineReader.vue — 在线预览

功能: 在弹窗中阅读 gallery 图片

  • 分页阅读: 每页显示 lengthPerPage 张图片(默认30),支持翻页
  • 图片懒加载: 每加载完成一张自动触发加载下一张(loadImage)
  • 支持大图预览: 点击图片使用 Element Plus el-imagepreview-src-list
  • 连续阅读: 翻页滚动体验优化(监听 switch 事件)
  • 页数 < 9 时显示全部页码按钮,>= 9 时只显示输入跳转

Vuex Store 分析 (store/index.js)

Store 是应用的核心,管理所有状态与后端通信。

State 关键字段

字段 类型 说明
totalGalleryTask Array 所有 gallery 任务
chosenGallery Object/false 当前选中的 gallery(待下载)
collectGallery Array 收藏的 gallery
downloadGallery Array 分配给当前用户的 gallery
searchTask Array 本地搜索结果
currentTasks Array 当前显示的 tasks(根据分类筛选)
readingGallery Object 正在阅读的 gallery
isReading Boolean 是否正在阅读
isAuth Boolean 是否已验证
AuthCode String 授权码
userId Number 用户 ID
username String 用户名
category String 分类: myDownload / myCollect / total
sortType String 排序: shortName / name / createTime
galleryNameType String 显示名: shortName / name
page Number 当前页码
length Number 每页条目数
websocket WebSocket WebSocket 连接

Actions (后端交互)

Action 方法 端点 说明
validate POST /validate 验证授权码,初始化数据
updateGalleryTasks GET /GalleryManage 获取所有 gallery 任务
postGalleryTask POST /GalleryManage 提交下载任务
queryGalleryTask GET /GalleryManage 按链接查询 gallery
loadWeekUsedAmount GET /GalleryManage/weekUsedAmount 查询本周用量
collectGallery POST /GalleryManage/collect 收藏 gallery
disCollectGallery POST /GalleryManage/disCollect 取消收藏
deleteGallery DELETE /GalleryManage 删除 gallery
readOnlineGallery POST /GalleryManage/cache 缓存并开始在线预览
alterAuthCode PUT /AuthCode 修改授权码
reconnect POST /GalleryManage/reconnect 重连下载节点
resetUndone POST /GalleryManage/reset 重置未完成任务

WebSocket 通信

  • 端点: wss://downloader.lionwebsite.xyz/ws/
  • 连接后发送: "DownloaderWebsocket"
  • 消息类型:
    • updateTasks: 增量更新任务进度
    • fullUpdate: 触发全量刷新

Getters

Getter 说明
currentTasks 返回当前页的 tasks(支持搜索态)
min 最小页码(1)
max 最大页码

辅助函数

  • getShortname(name): 从 gallery 名中去除中括号/括号内的标签信息
  • confirmCurrentTask(state): 根据 category 切换 currentTasks
  • sortTasks(state): 根据 sortType 排序
  • deleteTask(tasks, key, value): 从多个数组中删除匹配的任务

API 端点汇总

所有请求均需携带 AuthCode 参数:

端点 用途
POST /validate 授权码验证
GET/POST/DELETE /GalleryManage 任务 CRUD
GET /GalleryManage/weekUsedAmount 每周用量查询
POST /GalleryManage/collect 收藏
POST /GalleryManage/disCollect 取消收藏
POST /GalleryManage/cache 缓存 gallery 用于在线预览
POST /GalleryManage/reconnect 重连下载节点
POST /GalleryManage/reset 重置未完成任务
GET /GalleryManage/ehThumbnail 获取缩略图
GET /GalleryManage/file/{name}.zip 下载文件
GET /GalleryManage/onlineImage/{i} 在线预览图片
PUT /AuthCode 修改授权码
GET /query 远程搜索 exhentai
WS /ws/ WebSocket 实时推送

特色与关键实现

  1. 简洁名字处理: getShortname() 使用启发式逻辑从 gallery 完整名中剥离标签
  2. 防抖缩略图: Side 组件 mouseenter 时 500ms 防抖才更新缩略图
  3. 夜间模式: 通过 Element Plus 的 dark CSS class 切换,支持跟随系统偏好
  4. 权限分级: userId===3 的用户(Lion)有额外操作权限(重置任务、查看 downloader)
  5. 本地持久化: 授权码、分页配置、分类/排序/显示偏好均存 localStorage
  6. WebSocket 实时更新: 任务进度变化时服务端通过 WebSocket 推送增量更新
  7. 图片懒加载: 按页加载图片,每加载完成一张自动触发下一张加载

构建与运行

npm run dev      # 开发服务器 (0.0.0.0)
npm run build    # 生产构建
npm run preview  # 预览构建产物

潜在问题/改进点

  1. store/index.jsupdateGalleryTasks 的 action 引用了未在函数签名中声明的 state — 使用了外部模块级变量而非 context.state这在严格模式下可能引起问题
  2. state.websocket 在 Vuex 中初始化为 {} 而非 null,检查方式不够严谨
  3. getShortname 函数逻辑复杂且有多处副作用,可读性较低
  4. 部分错误处理较简略(如 queryGalleries 中无网络错误处理)
  5. store/index.js 中 action 使用全局 state 变量(而非 context.state),可能导致作用域混淆