Repository: 2977094657/BiliHistoryFrontend
Branch: master
Commit: ac05f46d3ccd
Files: 104
Total size: 1.0 MB
Directory structure:
gitextract_3n4s52y9/
├── .dockerignore
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ └── 问题反馈-功能请求.md
│ └── workflows/
│ ├── docker-image.yml
│ └── tauri-release.yml
├── .gitignore
├── Dockerfile
├── LICENSE.md
├── README.md
├── deploy/
│ └── Caddyfile
├── index.html
├── jsconfig.json
├── package.json
├── postcss.config.js
├── src/
│ ├── App.vue
│ ├── api/
│ │ └── api.js
│ ├── components/
│ │ ├── PrivacyControl.vue
│ │ └── tailwind/
│ │ ├── ArtPlayerWithDanmaku.vue
│ │ ├── BusinessTypeSelector.vue
│ │ ├── CustomDropdown.vue
│ │ ├── DataSyncManager.vue
│ │ ├── DownloadDialog.vue
│ │ ├── EnvironmentCheck.vue
│ │ ├── FavoriteDialog.vue
│ │ ├── FilterDropdown.vue
│ │ ├── HistoryContent.vue
│ │ ├── LoginDialog.vue
│ │ ├── Navbar.vue
│ │ ├── Pagination.vue
│ │ ├── SearchBar.vue
│ │ ├── Settings.vue
│ │ ├── Sidebar.vue
│ │ ├── SimpleSearchBar.vue
│ │ ├── SummaryConfig.vue
│ │ ├── TaskTreeItem.vue
│ │ ├── UserVideos.vue
│ │ ├── VideoCategories.vue
│ │ ├── VideoDetailDialog.vue
│ │ ├── VideoPlayerDialog.vue
│ │ ├── VideoRecord.vue
│ │ ├── VideoSummary.vue
│ │ ├── analytics/
│ │ │ ├── layout/
│ │ │ │ └── AnalyticsLayout.vue
│ │ │ └── pages/
│ │ │ ├── AuthorCompletionPage.vue
│ │ │ ├── AuthorPopularAssociationPage.vue
│ │ │ ├── CategoryPopularDistributionPage.vue
│ │ │ ├── DurationAnalysisPage.vue
│ │ │ ├── DurationPopularDistributionPage.vue
│ │ │ ├── HeroPage.vue
│ │ │ ├── MonthlyPage.vue
│ │ │ ├── OverallCompletionPage.vue
│ │ │ ├── OverviewPage.vue
│ │ │ ├── PopularHitRatePage.vue
│ │ │ ├── PopularPredictionPage.vue
│ │ │ ├── RewatchPage.vue
│ │ │ ├── StreakPage.vue
│ │ │ ├── TagsPage.vue
│ │ │ ├── TimeAnalysisPage.vue
│ │ │ ├── TimeDistributionPage.vue
│ │ │ ├── TitleAnalysisPage.vue
│ │ │ ├── TitleInteractionAnalysisPage.vue
│ │ │ ├── TitleLengthAnalysisPage.vue
│ │ │ ├── TitleSentimentAnalysisPage.vue
│ │ │ └── TitleTrendAnalysisPage.vue
│ │ ├── dynamic/
│ │ │ ├── DynamicCardNormal.vue
│ │ │ └── DynamicCardVideo.vue
│ │ ├── layout/
│ │ │ └── MainLayout.vue
│ │ ├── page/
│ │ │ ├── AnimatedAnalytics.vue
│ │ │ ├── BiliTools.vue
│ │ │ ├── Comments.vue
│ │ │ ├── Downloads.vue
│ │ │ ├── DynamicDownloader.vue
│ │ │ ├── Favorites.vue
│ │ │ ├── History.vue
│ │ │ ├── Images.vue
│ │ │ ├── MediaManager.vue
│ │ │ ├── Remarks.vue
│ │ │ ├── SchedulerTasks.vue
│ │ │ ├── Search.vue
│ │ │ ├── VideoDetailsManager.vue
│ │ │ └── VideoDownloader.vue
│ │ └── scheduler/
│ │ ├── SelectDialog.vue
│ │ ├── TaskDetail.vue
│ │ ├── TaskForm.vue
│ │ └── TaskHistory.vue
│ ├── main.js
│ ├── router/
│ │ └── router.js
│ ├── store/
│ │ ├── darkMode.js
│ │ └── privacy.js
│ ├── style.css
│ └── utils/
│ ├── imageProxy.js
│ ├── imageUrl.js
│ ├── openUrl.js
│ └── privacyManager.js
├── src-tauri/
│ ├── Cargo.toml
│ ├── build.rs
│ ├── capabilities/
│ │ └── default.json
│ ├── icons/
│ │ └── icon.icns
│ ├── src/
│ │ ├── lib.rs
│ │ └── main.rs
│ ├── tauri.conf.json
│ ├── tauri.linux.conf.json
│ ├── tauri.macos.conf.json
│ └── tauri.windows.conf.json
├── tailwind.config.js
└── vite.config.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .dockerignore
================================================
.git
.gitignore
node_modules
Dockerfile
.dockerignore
dist
.cache
src-tauri
================================================
FILE: .github/ISSUE_TEMPLATE/问题反馈-功能请求.md
================================================
---
name: 问题反馈/功能请求
about: 提交问题反馈或新功能请求
title: ''
labels: ''
assignees: ''
---
## 问题类型
请在适当的选项前打 [x]
- [ ] 🐛 Bug报告
- [ ] ✨ 功能请求
- [ ] 📝 文档改进
- [ ] 🎨 UI/UX改进
- [ ] 🧰 技术支持
## 功能重要程度
请在适当的选项前打 [x]
- [ ] 🔴 核心功能(影响主要使用流程)
- [ ] 🟠 主要功能(影响重要使用场景)
- [ ] 🟡 次要功能(改善用户体验)
- [ ] 🟢 增强功能(锦上添花)
## 问题/请求详情
请尽可能详细描述您遇到的问题或需要的功能
## 复现步骤(针对Bug)
1.
2.
3.
## 当前行为(针对Bug)
描述目前看到的结果
## 期望行为
描述您期望看到的结果
## 运行环境
- 操作系统: Windows 10/11, macOS, Linux等
- 浏览器: Chrome, Firefox, Safari等(附上版本号)
- 应用版本:
- 可执行文件(附上版本号)
- 源码(附上你使用的提交hash)
- 设备类型: 桌面端/移动端
## 截图/视频
贴上相关截图或视频链接,帮助我们更好地理解问题
## 控制台日志
如果有浏览器控制台错误,请附上相关日志
## 额外信息
其他可能有助于解决问题的信息
================================================
FILE: .github/workflows/docker-image.yml
================================================
name: Docker Image
on:
push:
branches:
- master
tags:
- "v*"
workflow_dispatch:
permissions:
contents: read
packages: write
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Docker metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository_owner }}/bili-history-frontend
flavor: |
latest=false
tags: |
type=ref,event=tag
type=semver,pattern={{version}}
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
file: Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
================================================
FILE: .github/workflows/tauri-release.yml
================================================
name: Release (Tauri)
on:
push:
tags:
- "v*"
workflow_dispatch:
inputs:
tag:
description: "Git tag to build (e.g. v1.0.0)"
required: true
type: string
permissions:
contents: write
jobs:
build-tauri:
name: Build (${{ matrix.label }})
runs-on: ${{ matrix.platform }}
strategy:
fail-fast: false
matrix:
include:
- label: macos-universal
platform: macos-latest
args: --target universal-apple-darwin
- label: linux-x64
platform: ubuntu-24.04
args: ""
- label: windows-x64
platform: windows-latest
args: ""
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.tag || github.ref }}
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
- name: Rust cache
uses: swatinem/rust-cache@v2
with:
workspaces: "./src-tauri -> target"
- name: Install Linux dependencies
if: matrix.platform == 'ubuntu-24.04'
run: |
sudo apt-get update
sudo apt-get install -y \
libwebkit2gtk-4.1-dev \
libgtk-3-dev \
libayatana-appindicator3-dev \
librsvg2-dev \
patchelf \
libssl-dev \
pkg-config \
fakeroot \
libfuse2
- name: Install Windows dependencies
if: matrix.platform == 'windows-latest'
run: choco install nsis -y
- name: Install frontend dependencies
run: npm install --no-package-lock --include=optional --no-fund --no-audit
- name: Build and upload release assets
uses: tauri-apps/tauri-action@v0.6
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tagName: ${{ github.event.inputs.tag || github.ref_name }}
releaseName: "BiliHistoryFrontend ${{ github.event.inputs.tag || github.ref_name }}"
releaseBody: "See the assets to download and install this version."
releaseDraft: false
prerelease: ${{ contains(github.event.inputs.tag || github.ref_name, '-') }}
tauriScript: "npx tauri"
args: ${{ matrix.args }}
generateReleaseNotes: true
================================================
FILE: .gitignore
================================================
# generated by: https://gitignore.itranswarp.com/
#################### Node.gitignore ####################
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional stylelint cache
.stylelintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# vuepress v2.x temp and cache directory
.temp
.cache
# Docusaurus cache and generated files
.docusaurus
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
#################### Archives.gitignore ####################
# It's better to unpack these files and commit the raw source because
# git has its own built in compression methods.
*.7z
*.jar
*.rar
*.zip
*.gz
*.gzip
*.tgz
*.bzip
*.bzip2
*.bz2
*.xz
*.lzma
*.cab
*.xar
# Packing-only formats
*.iso
*.tar
# Package management formats
*.dmg
*.xpi
*.gem
*.egg
*.deb
*.rpm
*.msi
*.msm
*.msp
*.txz
#################### Backup.gitignore ####################
*.bak
*.gho
*.ori
*.orig
*.tmp
#################### Emacs.gitignore ####################
# -*- mode: gitignore; -*-
*~
\#*\#
/.emacs.desktop
/.emacs.desktop.lock
*.elc
auto-save-list
tramp
.\#*
# Org-mode
.org-id-locations
*_archive
# flymake-mode
*_flymake.*
# eshell files
/eshell/history
/eshell/lastdir
# elpa packages
/elpa/
# reftex files
*.rel
# AUCTeX auto folder
/auto/
# cask packages
.cask/
dist/
# Flycheck
flycheck_*.el
# server auth directory
/server/
# projectiles files
.projectile
# directory configuration
.dir-locals.el
# network security
/network-security.data
#################### Linux.gitignore ####################
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
#################### NotepadPP.gitignore ####################
# Notepad++ backups #
*.bak
#################### PuTTY.gitignore ####################
# Private key
*.ppk
#################### SublimeText.gitignore ####################
# Cache files for Sublime Text
*.tmlanguage.cache
*.tmPreferences.cache
*.stTheme.cache
# Workspace files are user-specific
*.sublime-workspace
# Project files should be checked into the repository, unless a significant
# proportion of contributors will probably not be using Sublime Text
# *.sublime-project
# SFTP configuration file
sftp-config.json
sftp-config-alt*.json
# Package control specific files
Package Control.last-run
Package Control.ca-list
Package Control.ca-bundle
Package Control.system-ca-bundle
Package Control.cache/
Package Control.ca-certs/
Package Control.merged-ca-bundle
Package Control.user-ca-bundle
oscrypto-ca-bundle.crt
bh_unicode_properties.cache
# Sublime-github package stores a github token in this file
# https://packagecontrol.io/packages/sublime-github
GitHub.sublime-settings
#################### Vim.gitignore ####################
# Swap
[._]*.s[a-v][a-z]
!*.svg # comment out if you don't need vector files
[._]*.sw[a-p]
[._]s[a-rt-v][a-z]
[._]ss[a-gi-z]
[._]sw[a-p]
# Session
Session.vim
Sessionx.vim
# Temporary
.netrwhist
*~
# Auto-generated tag files
tags
# Persistent undo
[._]*.un~
#################### VisualStudioCode.gitignore ####################
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets
# Local History for Visual Studio Code
.history/
# Built Visual Studio Code Extensions
*.vsix
#################### Windows.gitignore ####################
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
#################### macOS.gitignore ####################
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
#################### Custom.gitignore ####################
# add your custom gitignore here:
!.gitignore
!.gitsubmodules
/src-tauri/target/
/src-tauri/gen/
.idea
# tauri
target
src-tauri/gen
src-tauri/target
/CLAUDE.md
================================================
FILE: Dockerfile
================================================
FROM oven/bun:1 AS base
WORKDIR /app
FROM base AS install
COPY package.json bun.lock .
RUN bun install
FROM base AS build
ARG BACKEND_URL_ARG=http://localhost:8899
ENV VITE_DEFAULT_BACKEND_URL=${BACKEND_URL_ARG}
COPY . .
COPY --from=install /app/node_modules node_modules
RUN bun run build
FROM caddy:2-alpine AS release
COPY --from=build /app/dist /app
COPY deploy/Caddyfile /etc/caddy
EXPOSE 80
================================================
FILE: LICENSE.md
================================================
MIT License
Copyright (c) 2024-present 2977094657
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
这是一个基于 Vue 3 开发的 B 站历史记录分析工具的前端项目,为用户提供丰富的 B 站观看历史数据分析功能。
## 该项目需要配合 [BilibiliHistoryFetcher](https://github.com/2977094657/BilibiliHistoryFetcher) 后端项目一起使用
## 零基础快速运行(Windows 免安装版,推荐)
1. 下载 exe:后端 https://github.com/2977094657/BilibiliHistoryFetcher/releases/latest
2. 下载 exe:前端 https://github.com/2977094657/BiliHistoryFrontend/releases/latest
3. 两个都双击运行即可
## 快速开始
### 使用 Docker 安装
#### 使用预构建镜像(GitHub Container Registry)
```bash
docker pull ghcr.io/2977094657/bili-history-frontend:latest
docker run --name bili-history-frontend-web -p 5173:80 -d ghcr.io/2977094657/bili-history-frontend:latest
```
1. 安装[Docker](https://docs.docker.com/get-started/get-docker/).
2. 构建镜像:`docker build -t bili-history-frontend-web:dev .`
3. 启动容器:`docker run --name bili-history-frontend-web -p 5173:80 -d bili-history-frontend-web:dev`
4. 停止容器:`docker stop bili-history-frontend-web`
### [通过 1Panel 部署](https://github.com/2977094657/BilibiliHistoryFetcher/discussions/65)
由社区贡献者 [@QYG2297248353](https://github.com/QYG2297248353) 实现 ([#66](https://github.com/2977094657/BilibiliHistoryFetcher/pull/66))
### 使用源码安装
1. 克隆项目
```bash
git clone https://github.com/2977094657/BiliHistoryFrontend.git
cd BilibiliHistoryFrontend
```
2. 安装依赖
```bash
npm install
```
3. 启动开发服务器
```bash
# 网页版开发
npm run dev
```
## 首次使用指南
1. **登录账号**
- 点击侧边栏的设置,然后配置你的服务器地址
- 然后点击侧边栏中的"未登录"状态
- 使用 B 站手机 APP 扫描二维码进行登录
- 登录成功后会显示你的用户名
2. **获取历史记录**
- 登录成功后,点击导航栏中的"实时更新"按钮
- 首次使用时会自动获取你的全部历史记录,这可能需要一些时间
- 获取完成后数据会自动导入到本地数据库
- 页面会自动刷新并显示你的观看历史
3. **后续使用**
- 默认的计划任务会在每天 0 点自动获取历史记录
- 可去设置里配置邮箱进行通知,不配置不影响自动获取,只是无法收到通知
- 每次打开页面时,建议点击"实时更新"以获取最新记录
- 实时更新只会获取新增的记录,速度很快
## 页面介绍
**1. 年度总结页面**
**2. 主页** 支持列表/网格切换与日期、分区筛选,一键实时更新,支持隐私模式。
**3. 评论** 登录后查看我的评论,支持关键词与类型筛选,并可跳转原文。
**4. 我的收藏** 支持查看我创建/收藏及本地收藏夹,可同步到本地并下载收藏内容。
**5. 媒体管理** 集中管理已下载视频与图片,查看/编辑备注与评论,并可批量补全视频详情。
**6. 计划任务** 统一管理定时与链式任务,支持新建/编辑/执行/启用或禁用,并查看历史与成功率。
**7. 设置** 配置服务器、隐私与布局、数据导出。
**8. 视频下载功能** 输入 BV/链接或 UP UID 下载单个/合集/投稿,过程实时反馈。
**9. 视频观看总时长** 查询合集级观看总时长、平均时长与完播率,可按列查看统计
**10. 动态下载** 输入用户MID下载B站动态内容,实时显示下载进度
**11. 本地摘要功能** 基于本地语音转文字结合 DeepSeek 生成视频摘要,支持模型管理、环境检测与结果缓存。
## 使用 Tauri 构建桌面应用
### GitHub Actions 自动构建(多平台包体)
推送 tag(例如 `v1.0.0`)后,会自动在 GitHub Releases 里生成 Windows/macOS/Linux 的安装包与产物。
**环境准备**
1. 安装 Rust 开发环境
- 按照 [Rust 官方指南](https://www.rust-lang.org/tools/install) 安装 Rust
- Windows 用户还需安装 [Visual Studio C++ 构建工具](https://visualstudio.microsoft.com/visual-cpp-build-tools/)
2. 安装 Node.js 依赖
```bash
npm install
```
**开发与构建**
1. 开发模式
```bash
npm run tauri:dev
```
这将启动一个开发服务器,并自动打开应用窗口,支持热重载。
2. 构建可执行文件
```bash
npm run tauri:build:exe
```
构建完成后,将在项目根目录生成 `BiliBili-History-Frontend.exe` 可执行文件。
3. 清理构建文件
```bash
npm run tauri:clean
```
清理 `src-tauri/target` 目录中的构建产物,释放磁盘空间。
## 赞助与支持
如果本项目对你有帮助,欢迎通过以下方式赞助。付款时请在备注中填写“希望公开展示的链接”(如个人主页、B 站空间、GitHub 仓库等),我们会在 README 的“赞助鸣谢”表格中展示。

微信赞助
|

支付宝赞助
|
### 赞助鸣谢
| 联系内容 | 付款金额 |
| ----------------------------------------------------- | -------- |
| [星语半夏的个人空间-哔哩哔哩](https://b23.tv/WPHOtCS) | ¥15 |
| 匿名微信用户 | ¥5 |
| [EMP-NOVA13721RCL的个人空间-哔哩哔哩](https://space.bilibili.com/503193026) | ¥50 |
提示:已赞助但未收录,请在 Issues 提交凭证与备注链接;如需匿名可说明。
## 贡献指南
欢迎提交 Issue 和 Pull Request 来帮助改进这个项目。
## 致谢
- [bilibili-API-collect](https://github.com/SocialSisterYi/bilibili-API-collect) - 没有它就没有这个项目
- [Yutto](https://yutto.nyakku.moe/) - 可爱的 B 站视频下载工具
- [FasterWhisper](https://github.com/SYSTRAN/faster-whisper) - 音频转文字
- [DeepSeek](https://github.com/deepseek-ai/DeepSeek-R1) - DeepSeek AI API
- [ArtPlayer](https://github.com/zhw2590582/ArtPlayer) - 强大且灵活的 HTML5 视频播放器
- [aicu.cc](https://www.aicu.cc/) - 第三方 B 站用户评论 API
- [小黑盒用户 shengyI](https://www.xiaoheihe.cn/app/bbs/link/153880174) - 视频观看总时长功能思路提供者
- 所有贡献者,特别感谢:
- [@eli-yip](https://github.com/eli-yip) 对 Docker 部署的贡献
- [@QYG2297248353](https://github.com/QYG2297248353) 对 1Panel 部署的贡献
## Star History
[](https://star-history.com/#2977094657/BiliHistoryFrontend&Date)
================================================
FILE: deploy/Caddyfile
================================================
{
auto_https off
}
:80
respond /health 200 {
body `{"status": "ok"}`
}
root * /app
file_server
try_files {path} /index.html
================================================
FILE: index.html
================================================
b站历史记录
================================================
FILE: jsconfig.json
================================================
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "Node",
"target": "ESNext",
"jsx": "preserve",
"strictFunctionTypes": false,
"allowJs": true,
"checkJs": false
},
"exclude": ["node_modules", "dist"]
}
================================================
FILE: package.json
================================================
{
"name": "bilibilihistoryfrontend",
"version": "1.0.0",
"description": "获取Bili历史记录应用",
"author": "46",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"tauri": "tauri",
"tauri:dev": "tauri dev",
"tauri:build": "tauri build",
"tauri:build:windows": "tauri build --target x86_64-pc-windows-msvc",
"tauri:build:exe": "npm run tauri:build:windows && powershell -c \"Copy-Item ./src-tauri/target/x86_64-pc-windows-msvc/release/bilibili-history-frontend.exe ./BiliBili-History-Frontend.exe -Force\"",
"tauri:clean": "powershell -c \"if (Test-Path ./src-tauri/target) { Remove-Item -Recurse -Force ./src-tauri/target }\""
},
"dependencies": {
"@headlessui/vue": "^1.7.23",
"@heroicons/vue": "^2.1.5",
"@tailwindcss/forms": "^0.5.9",
"@tauri-apps/plugin-shell": "~2.2.1",
"@vant/touch-emulator": "^1.4.0",
"@vueuse/components": "^12.3.0",
"@vueuse/core": "^12.3.0",
"@vueuse/motion": "^2.2.6",
"animate.css": "^4.1.1",
"aos": "^2.3.4",
"artplayer": "^5.2.2",
"artplayer-plugin-danmuku": "^5.1.5",
"axios": "^1.7.7",
"crypto-js": "^4.2.0",
"echarts": "^5.6.0",
"echarts-wordcloud": "^2.1.0",
"gsap": "^3.12.5",
"html2canvas": "^1.4.1",
"jsencrypt": "^3.3.2",
"lottie-web": "^5.12.2",
"typeit": "^8.8.7",
"vant": "^4.9.15",
"vue": "^3.5.11",
"vue-countup-v3": "^1.4.2",
"vue-echarts": "^7.0.3",
"vue-router": "^4.4.5",
"vue3-lottie": "^3.3.1"
},
"devDependencies": {
"@tauri-apps/api": "~2.4.0",
"@tauri-apps/cli": "~2.4.0",
"@types/node": "^20.17.6",
"@vitejs/plugin-vue": "^5.1.4",
"@vue/runtime-core": "^3.5.13",
"autoprefixer": "^10.4.20",
"cross-env": "^7.0.3",
"postcss": "^8.4.47",
"tailwindcss": "^3.4.13",
"vite": "^5.4.8",
"vite-plugin-vue-inspector": "^5.3.1"
}
}
================================================
FILE: postcss.config.js
================================================
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
================================================
FILE: src/App.vue
================================================
================================================
FILE: src/api/api.js
================================================
import axios from 'axios'
// 导入通知组件
import 'vant/es/notify/style'
// 你的服务器地址
const DEFAULT_FALLBACK_URL = 'http://localhost:8899';
const VITE_CONFIGURED_DEFAULT_URL = import.meta.env.VITE_DEFAULT_BACKEND_URL || DEFAULT_FALLBACK_URL;
const getBaseUrl = () => {
return localStorage.getItem('baseUrl') || VITE_CONFIGURED_DEFAULT_URL
}
const BASE_URL = getBaseUrl()
// 服务器地址列表
const SERVER_URLS = [
'http://127.0.0.1:8899',
'http://localhost:8899',
'http://0.0.0.0:8899'
]
if (!SERVER_URLS.includes(VITE_CONFIGURED_DEFAULT_URL)) {
SERVER_URLS.unshift(VITE_CONFIGURED_DEFAULT_URL)
}
// 设置服务器地址
export const setBaseUrl = (url) => {
localStorage.setItem('baseUrl', url)
// 更新 axios 实例的 baseURL
updateInstanceBaseUrl(url)
// 触发API BASE URL更新事件,供其他API模块使用
try {
const event = new CustomEvent('api-baseurl-updated', { detail: { url } })
window.dispatchEvent(event)
console.log('已触发API BaseURL更新事件:', url)
} catch (error) {
console.error('触发API BaseURL更新事件失败:', error)
}
window.location.reload() // 刷新页面以应用新的baseUrl
}
// 获取当前服务器地址
export const getCurrentBaseUrl = () => {
return getBaseUrl()
}
// 创建一个 axios 实例
const instance = axios.create({
baseURL: BASE_URL,
})
// 请求拦截器
instance.interceptors.request.use(
(config) => {
return config
},
(error) => {
return Promise.reject(error)
}
)
// 响应拦截器
instance.interceptors.response.use(
(response) => {
return response
},
(error) => {
return Promise.reject(error)
}
)
// 更新 axios 实例的 baseURL
export const updateInstanceBaseUrl = (newBaseUrl) => {
instance.defaults.baseURL = newBaseUrl
}
// 历史记录相关接口
export const getBiliHistory2024 = (page, size, sortOrder, tagName, mainCategory, dateRange, useLocalImages = false, business = '') => {
return instance.get(`/history/all`, {
params: {
page,
size,
sort_order: sortOrder,
tag_name: tagName,
main_category: mainCategory,
date_range: dateRange,
use_local_images: useLocalImages,
business: business,
},
})
}
export const searchBiliHistory2024 = (search, searchType = 'all', page = 1, size = 30, useLocalImages = false, useSessdata = true) => {
return instance.get(`/history/search`, {
params: {
page,
size,
search,
search_type: searchType,
use_local_images: useLocalImages,
use_sessdata: useSessdata
},
})
}
// 获取可用年份列表
export const getAvailableYears = () => {
return instance.get(`/history/available-years`)
}
// 分类相关接口
export const getVideoCategories = () => {
return instance.get(`/categories/categories`) // 使用新的分类接口
}
export const getMainCategories = () => {
return instance.get(`/categories/main-categories`)
}
// 标题分析相关接口已拆分为以下独立接口:
// - getTitleKeywordAnalysis: 关键词分析
// - getTitleLengthAnalysis: 长度分析
// - getTitleSentimentAnalysis: 情感分析
// - getTitleTrendAnalysis: 趋势分析
// - getTitleInteractionAnalysis: 互动分析
// 获取标题关键词分析
export const getTitleKeywordAnalysis = (year, useCache = true) => {
return instance.get(`/title/keyword-analysis`, {
params: {
year,
use_cache: useCache
}
})
}
// 获取标题长度分析
export const getTitleLengthAnalysis = (year, useCache = true) => {
return instance.get(`/title/length-analysis`, {
params: {
year,
use_cache: useCache
}
})
}
// 获取标题情感分析
export const getTitleSentimentAnalysis = (year, useCache = true) => {
return instance.get(`/title/sentiment-analysis`, {
params: {
year,
use_cache: useCache
}
})
}
// 获取标题趋势分析
export const getTitleTrendAnalysis = (year, useCache = true) => {
return instance.get(`/title/trend-analysis`, {
params: {
year,
use_cache: useCache
}
})
}
// 获取标题互动分析
export const getTitleInteractionAnalysis = (year, useCache = true) => {
return instance.get(`/title/interaction-analysis`, {
params: {
year,
use_cache: useCache
}
})
}
// 观看时间分析相关接口已拆分为以下独立接口:
// - getViewingMonthlyStats: 月度统计分析
// - getViewingWeeklyStats: 周度统计分析
// - getViewingTimeSlots: 时段分析
// - getViewingContinuity: 观看连续性分析
// 更多维度接口将逐步添加...
// 获取月度观看统计分析
export const getViewingMonthlyStats = (year, useCache = true) => {
return instance.get(`/viewing/monthly-stats`, {
params: {
year,
use_cache: useCache
}
})
}
// 获取周度观看统计分析
export const getViewingWeeklyStats = (year, useCache = true) => {
return instance.get(`/viewing/weekly-stats`, {
params: {
year,
use_cache: useCache
}
})
}
// 获取时段观看分析
export const getViewingTimeSlots = (year, useCache = true) => {
return instance.get(`/viewing/time-slots`, {
params: {
year,
use_cache: useCache
}
})
}
// 获取观看连续性分析
export const getViewingContinuity = (year, useCache = true) => {
return instance.get(`/viewing/continuity`, {
params: {
year,
use_cache: useCache
}
})
}
// 获取重复观看分析
export const getViewingWatchCounts = (year, useCache = true) => {
return instance.get(`/viewing/watch-counts`, {
params: {
year,
use_cache: useCache
}
})
}
// 获取视频完成率分析
export const getViewingCompletionRates = (year, useCache = true) => {
return instance.get(`/viewing/completion-rates`, {
params: {
year,
use_cache: useCache
}
})
}
// 获取UP主完成率分析
export const getViewingAuthorCompletion = (year, useCache = true) => {
return instance.get(`/viewing/author-completion`, {
params: {
year,
use_cache: useCache
}
})
}
// 获取标签分析
export const getViewingTagAnalysis = (year, useCache = true) => {
return instance.get(`/viewing/tag-analysis`, {
params: {
year,
use_cache: useCache
}
})
}
// 获取视频时长分析
export const getViewingDurationAnalysis = (year, useCache = true) => {
return instance.get(`/viewing/duration-analysis`, {
params: {
year,
use_cache: useCache
}
})
}
// 原始的观看时间分析接口已删除,现在使用拆分后的独立接口
// 获取观看行为数据分析
export const getViewingBehavior = async (year, useCache = false) => {
return instance.get(`/viewing/viewing/`, {
params: {
year,
use_cache: useCache
}
})
}
// 获取每年每天的观看数合集
export const getYearlyAnalysis = async (year) => {
return instance.post(`/analysis/analyze`, null, {
params: {
year
}
})
}
// 获取热门视频命中率分析
export const getPopularHitRate = async (year, useCache = true) => {
return instance.get(`/popular/popular-hit-rate`, {
params: {
year,
use_cache: useCache
}
})
}
// 获取热门预测能力分析
export const getPopularPredictionAbility = async (year, useCache = true) => {
return instance.get(`/popular/popular-prediction-ability`, {
params: {
year,
use_cache: useCache
}
})
}
// 获取UP主热门关联分析
export const getAuthorPopularAssociation = async (year, useCache = true) => {
return instance.get(`/popular/author-popular-association`, {
params: {
year,
use_cache: useCache
}
})
}
// 获取热门视频分区分布分析
export const getCategoryPopularDistribution = async (year, useCache = true) => {
return instance.get(`/popular/category-popular-distribution`, {
params: {
year,
use_cache: useCache
}
})
}
// 获取热门视频时长分布分析
export const getDurationPopularDistribution = async (year, useCache = true) => {
return instance.get(`/popular/duration-popular-distribution`, {
params: {
year,
use_cache: useCache
}
})
}
// 实时更新历史记录
export const updateBiliHistoryRealtime = (syncDeleted = false) => {
return instance.get(`/fetch/bili-history-realtime`, {
params: {
sync_deleted: syncDeleted
}
}).then(response => {
// 检查响应格式
if (!response.data) {
throw new Error('响应数据格式错误')
}
// 如果返回未找到本地历史记录错误,则调用完整获取接口
if (response.data.status === 'error' && response.data.message === '未找到本地历史记录') {
return getBiliHistory()
}
return response
}).catch(error => {
console.error('API 请求错误:', error)
// 重新抛出错误,让调用者处理
throw error
})
}
// 获取完整历史记录
export const getBiliHistory = () => {
return instance.get('/fetch/bili-history').then(async response => {
// 检查响应格式
if (!response.data) {
throw new Error('响应数据格式错误')
}
// 如果获取历史记录成功,调用导入SQLite接口
if (response.data.status === 'success') {
try {
await importSqliteData()
// 1秒后刷新页面,让用户看到成功提示
setTimeout(() => {
window.location.reload()
}, 1000)
} catch (error) {
console.error('导入SQLite失败:', error)
// 即使导入失败也返回历史记录的响应
}
}
return response
}).catch(error => {
console.error('获取历史记录失败:', error)
throw error
})
}
// 获取每日视频统计
export const getDailyStats = async (date, year) => {
return instance.get(`/daily/daily-count`, {
params: {
date,
year
}
})
}
// 导入SQLite数据
export const importSqliteData = () => {
return instance.post(`/importSqlite/import_data_sqlite`)
}
// 导出相关接口
// 导出历史记录到Excel
export const exportHistory = (options = {}) => {
// 只传递非空参数
const params = {}
// 年份参数
if (options.year !== undefined && options.year !== null) {
params.year = options.year
}
// 月份参数
if (options.month !== undefined && options.month !== null) {
params.month = options.month
}
// 开始日期参数
if (options.start_date) {
params.start_date = options.start_date
}
// 结束日期参数
if (options.end_date) {
params.end_date = options.end_date
}
console.log('导出参数:', params)
return instance.post('/export/export_history', null, {
params
})
}
// 下载Excel文件
export const downloadExcelFile = (filename) => {
return instance.get(`/export/download_excel/${encodeURIComponent(filename)}`, {
responseType: 'blob',
headers: {
'Accept': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
}
}).then(response => {
// 创建blob链接并下载
const blob = new Blob([response.data], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
})
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = url
link.setAttribute('download', filename)
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
window.URL.revokeObjectURL(url)
return response
})
}
// 下载SQLite数据库
export const downloadDatabase = () => {
return instance.get('/export/download_db', {
responseType: 'blob',
headers: {
'Accept': 'application/x-sqlite3'
}
}).then(response => {
// 创建blob链接并下载
const blob = new Blob([response.data], {
type: 'application/x-sqlite3'
})
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = url
link.setAttribute('download', 'bilibili_history.db')
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
window.URL.revokeObjectURL(url)
return response
})
}
// 登录相关接口
// 生成登录二维码
export const generateLoginQRCode = () => {
return instance.get('/login/qrcode/generate')
}
// 获取二维码图片URL
export const getQRCodeImageURL = () => {
return `${BASE_URL}/login/qrcode/image`
}
// 获取二维码图片(返回blob URL)
export const getQRCodeImageBlob = async () => {
try {
const response = await instance.get('/login/qrcode/image', {
responseType: 'blob'
})
// 创建blob URL
const blob = new Blob([response.data], {
type: response.headers['content-type'] || 'image/png'
})
return URL.createObjectURL(blob)
} catch (error) {
console.error('获取二维码图片失败:', error)
throw error
}
}
// 轮询二维码状态
export const pollQRCodeStatus = (qrcodeKey) => {
return instance.get('/login/qrcode/poll', {
params: {
qrcode_key: qrcodeKey
}
})
}
// 退出登录
export const logout = () => {
return instance.post('/login/logout')
}
// 获取登录状态
export const getLoginStatus = () => {
return instance.get('/login/check')
}
// 获取视频摘要
export const getVideoSummary = (bvid, cid, upMid, forceRefresh = false) => {
return instance.get('/summary/get_summary', {
params: {
bvid,
cid,
up_mid: upMid,
force_refresh: forceRefresh
}
})
}
// 获取摘要配置
export const getSummaryConfig = () => {
return instance.get('/summary/config')
}
// 更新摘要配置
export const updateSummaryConfig = (config) => {
return instance.post('/summary/config', config)
}
// 批量删除历史记录
export const batchDeleteHistory = (items) => {
return instance.delete('/delete/batch-delete', {
data: items // 直接发送数组,不要包装在 items 对象中
})
}
// 删除B站历史记录
export const deleteBilibiliHistory = (kid, syncToBilibili = true) => {
return instance.delete(`/bilibili/history/single`, {
params: {
kid
},
data: {
sync_to_bilibili: syncToBilibili
}
})
}
// 批量删除B站历史记录
export const batchDeleteBilibiliHistory = (items) => {
return instance.delete('/bilibili/history/batch', {
data: {
items
}
})
}
// =============================
// 热门视频数据清理(按年分库)
// =============================
/**
* 获取热门视频数据库可用年份(降序)
* GET /bilibili/popular/years
* @returns {Promise}
*/
export const getPopularCleanupYears = () => {
return instance.get('/bilibili/popular/years')
}
// 数据库管理相关接口
// 重置数据库
export const resetDatabase = () => {
return instance.post('/history/reset-database')
}
// 备注相关接口
// 更新视频备注
export const updateVideoRemark = (bvid, viewAt, remark) => {
return instance.post('/history/update-remark', {
bvid,
view_at: viewAt,
remark
})
}
// 批量获取视频备注
export const batchGetRemarks = (records) => {
return instance.post('/history/batch-remarks', {
items: records
})
}
// 获取所有备注记录
export const getAllRemarks = (page = 1, size = 10, sortOrder = 0) => {
return instance.get('/history/remarks', {
params: {
page,
size,
sort_order: sortOrder
}
})
}
// 获取SQLite版本
export const getSqliteVersion = () => {
return instance.get('/history/sqlite-version')
}
// 图片管理相关接口
// 获取图片下载状态
export const getImagesStatus = () => {
return instance.get('/images/status')
}
// 开始下载图片
export const startImagesDownload = (year = null, useSessdata = true) => {
return instance.post('/images/start', null, {
params: {
year,
use_sessdata: useSessdata
}
})
}
// 停止下载图片
export const stopImagesDownload = () => {
return instance.post('/images/stop')
}
// 清空图片
export const clearImages = () => {
return instance.post('/images/clear')
}
// 下载视频
export const downloadVideo = async (bvid, sessdata = null, onMessage, downloadCover = true, onlyAudio = false, cid = 0, options = {}) => {
console.log('调用下载API, bvid:', bvid, '高级选项:', options)
const requestBody = {
url: bvid,
sessdata,
download_cover: downloadCover,
only_audio: onlyAudio,
cid,
// 添加高级选项
...options
}
// 从本地存储获取API密钥
const apiKey = localStorage.getItem('apiKey')
// 准备请求头
const headers = {
'Content-Type': 'application/json',
}
// 如果存在API密钥,添加到请求头
if (apiKey) {
headers['X-API-Key'] = apiKey
}
const response = await fetch(`${BASE_URL}/download/download_video`, {
method: 'POST',
headers,
body: JSON.stringify(requestBody)
})
if (!response.ok) {
const errorData = await response.json()
throw new Error(errorData.detail || '下载请求失败')
}
const reader = response.body.getReader()
const decoder = new TextDecoder()
let buffer = ''
while (true) {
const { value, done } = await reader.read()
if (done) break
buffer += decoder.decode(value, { stream: true })
// 处理缓冲区中的完整行
const lines = buffer.split('\n')
buffer = lines.pop() // 保留最后一个不完整的行
for (const line of lines) {
if (line.startsWith('data: ')) {
const content = line.substring(6).trim()
if (content && content !== 'close') {
onMessage(content)
}
}
}
}
// 处理最后可能剩余的数据
if (buffer) {
if (buffer.startsWith('data: ')) {
const content = buffer.substring(6).trim()
if (content && content !== 'close') {
onMessage(content)
}
}
}
}
// 检查 FFmpeg 安装状态
export const checkFFmpeg = () => {
return instance.get('/download/check_ffmpeg')
}
// 计划任务管理相关接口
export const getAllSchedulerTasks = (params = {}) => {
return instance.get('/scheduler/tasks', { params })
.then(response => {
return response
})
.catch(error => {
console.error('getAllSchedulerTasks API错误:', error)
throw error
})
}
export const getSchedulerTaskDetail = (taskId, params = {}) => {
return instance.get(`/scheduler/tasks`, {
params: {
task_id: taskId,
include_subtasks: true, // 默认包含子任务
...params
}
}).then(response => {
return response;
}).catch(error => {
console.error('API - 获取任务详情出错:', error);
throw error;
});
}
export const createSchedulerTask = (taskData) => {
return instance.post('/scheduler/tasks', taskData)
}
export const updateSchedulerTask = (taskId, taskData) => {
return instance.put(`/scheduler/tasks/${taskId}`, taskData)
}
export const deleteSchedulerTask = (taskId) => {
return instance.delete(`/scheduler/tasks/${taskId}`)
}
export const executeSchedulerTask = (taskId, options = {}) => {
return instance.post(`/scheduler/tasks/${taskId}/execute`, options)
}
// 子任务管理接口
export const addSubTask = (taskId, subTaskData) => {
console.log('调用addSubTask API:', { taskId, subTaskData })
return instance.post(`/scheduler/tasks/${taskId}/subtasks`, subTaskData)
.then(response => {
console.log('addSubTask API响应:', response)
return response
})
.catch(error => {
console.error('addSubTask API错误:', error)
throw error
})
}
export const deleteSubTask = (taskId, subTaskId) => {
return instance.delete(`/scheduler/tasks/${taskId}/subtasks/${subTaskId}`)
}
// 获取任务历史记录
export const getTaskHistory = ({
task_id = null,
include_subtasks = true,
status = null,
start_date = null,
end_date = null,
page = 1,
page_size = 20
}) => {
return instance.get(`/scheduler/tasks/history`, {
params: {
task_id,
include_subtasks,
status,
start_date,
end_date,
page,
page_size
}
})
}
// 系统接口
export const getAvailableEndpoints = () => {
return instance.get('/scheduler/available-endpoints')
}
// 启用/禁用任务
export const setTaskEnabled = (taskId, enabled) => {
return instance.post(`/scheduler/tasks/${taskId}/enable`, {
enabled
})
}
// 邮件配置相关接口
// 获取邮件配置
export const getEmailConfig = () => {
return instance.get('/config/email-config')
.then(response => {
console.log('邮件配置API响应成功:', response)
return response
})
.catch(error => {
console.error('邮件配置API错误:', error)
throw error
})
}
// 更新邮件配置
export const updateEmailConfig = (config) => {
return instance.post('/config/email-config', config)
.then(response => {
console.log('更新邮件配置API响应成功:', response)
return response
})
.catch(error => {
console.error('更新邮件配置API错误:', error)
throw error
})
}
// 测试邮件配置
export const testEmailConfig = (testData) => {
return instance.post('/config/test-email', testData)
.then(response => {
console.log('测试邮件API响应成功:', response)
return response
})
.catch(error => {
console.error('测试邮件API错误:', error)
throw error
})
}
// 音频转文字相关接口
export const checkAudioToTextEnvironment = () => {
return instance.get('/audio_to_text/check_environment')
}
// 检查系统资源
export const checkSystemResources = () => {
return instance.get('/audio_to_text/resource_check')
}
// 获取可用的 Whisper 模型列表
export const getWhisperModels = () => {
return instance.get('/audio_to_text/models')
}
// 查找音频文件路径
export const findAudioPath = (cid) => {
return instance.get('/audio_to_text/find_audio', {
params: { cid }
})
}
// 检查语音转文字文件是否存在
export const checkSttFile = (cid) => {
return instance.get('/audio_to_text/check_stt_file', {
params: { cid }
})
}
// 转录音频文件
export const transcribeAudio = (params) => {
return instance.post('/audio_to_text/transcribe', params)
}
// 根据CID生成视频摘要
export const summarizeByCid = (cid) => {
return instance.post('/summary/summarize_by_cid', {
cid
})
}
// 检查本地摘要文件
export const checkLocalSummary = (cid, includeContent = true) => {
return instance.get(`/summary/check_local_summary/${cid}`, {
params: {
include_content: includeContent
}
})
}
// 下载指定的Whisper模型
export const downloadWhisperModel = (modelSize) => {
return instance.post('/audio_to_text/download_model', null, {
params: {
model_size: modelSize
}
})
}
// 删除指定的Whisper模型
export const deleteWhisperModel = (modelSize) => {
return instance.delete('/audio_to_text/models', {
data: {
model_size: modelSize
}
})
}
// DeepSeek相关接口
export const checkDeepSeekApiKey = () => {
return instance.get('/deepseek/check_api_key')
}
export const setDeepSeekApiKey = (apiKey) => {
return instance.post('/deepseek/set_api_key', {
api_key: apiKey
})
}
export const getDeepSeekBalance = () => {
return instance.get('/deepseek/balance')
}
// API安全相关接口已移除
// 检查视频是否已下载
export const checkVideoDownload = (cids) => {
return instance.get(`/download/check_video_download`, {
params: {
cids: Array.isArray(cids) ? cids.join(',') : cids
}
})
}
// 获取已下载视频列表
export const getDownloadedVideos = (searchTerm = '', page = 1, limit = 20) => {
return instance.get(`/download/list_downloaded_videos`, {
params: {
search_term: searchTerm,
page,
limit
}
})
}
/**
* 删除已下载的视频
* @param {number|null} cid 视频的CID,若为null则必须指定directory
* @param {boolean} deleteDirectory 是否删除整个目录,默认为false(只删除视频文件)
* @param {string|null} directory 可选,指定要删除文件的目录路径
* 若提供则在该目录中查找和删除文件
* 对于从收藏夹下载的视频,由于没有CID,
* 可以设置cid为null并通过directory参数指定目录路径
* @returns {Promise