Files
lionwebsite-frontend-desktop/llm_readme.md
T
root 24b9b244b7 补构建配置并新增 .gitignore:线上依赖的 base 与固定产物名入库
vite.config.js:加 base:'/asserts/index/'、assetsDir:''、固定产物名
(entryFileNames:'index.js' 等)。当前线上 /var/www/lionwebsite/asserts/index/
的 index.js/index.css/index.html 均依赖此配置才能构建出来——属线上在用
但未入库的配置,不提交会导致 clone 后构建产物路径与线上不一致;
index.html:favicon 改为 /asserts/favicon.ico(与线上入口一致);
llm_readme.md:补文件末尾换行;
新增 .gitignore(npm 模板 + run.out):忽略 node_modules、dist、日志与编辑器文件。
2026-09-14 15:39:07 +08:00

202 lines
9.2 KiB
Markdown

# 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-image` 的 `preview-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. **图片懒加载**: 按页加载图片,每加载完成一张自动触发下一张加载
## 构建与运行
```bash
npm run dev # 开发服务器 (0.0.0.0)
npm run build # 生产构建
npm run preview # 预览构建产物
```
## 潜在问题/改进点
1. `store/index.js` 中 `updateGalleryTasks` 的 action 引用了未在函数签名中声明的 `state` — 使用了外部模块级变量而非 context.state,这在严格模式下可能引起问题
2. `state.websocket` 在 Vuex 中初始化为 `{}` 而非 `null`,检查方式不够严谨
3. `getShortname` 函数逻辑复杂且有多处副作用,可读性较低
4. 部分错误处理较简略(如 `queryGalleries` 中无网络错误处理)
5. `store/index.js` 中 action 使用全局 `state` 变量(而非 `context.state`),可能导致作用域混淆