DEMO效果

demo效果

方案

技术栈选择

Tauri

  • 优点: 轻量级、跨平台、安全性高。

  • 用途: 负责与操作系统交互,管理文件系统访问。

    为什么不使用Electron

    选择 Tauri 而不使用 Electron 的原因主要有以下几点:

Tauri 的优点

  1. 更小的应用体积:

    • Tauri 应用通常比 Electron 应用小得多,因为它使用系统自带的 WebView 而不是捆绑整个 Chromium。
  2. 更低的内存占用:

    • 使用系统的 WebView 控件,使得内存占用更低。
  3. 安全性:

    • Tauri 提供了更细粒度的 API 权限管理,安全性更高。
  4. 多语言支持:

    • 后端使用 Rust 编写,提供了强大的性能和安全保障。
  5. 现代化的开发体验:

    • 支持多种前端框架和工具,能与 Vite 等现代工具无缝集成。

Vite

  • 优点: 快速的开发和构建速度,热模块替换(HMR)。
  • 用途: 提供开发服务器和构建工具。

Vue 3

  • 优点: 响应式系统、组合式 API。
  • 用途: 构建用户界面和组件。

功能设计

1. 文件扫描

  • 功能描述: 扫描用户指定的本地文件夹,识别电影文件。
  • 实现思路: 使用 Tauri 提供的 API 进行本地文件系统访问,过滤出常见的视频文件格式(如 .mp4, .mkv)。

2. 资料刮削

  • 功能描述: 自动获取电影的相关信息,如标题、简介、海报等。
  • 实现思路:
    • 使用第三方 API(如 TMDb)进行数据请求。
    • 采用关键词或文件名进行匹配,获取最相关的电影信息。

3. 信息展示

  • 功能描述: 在应用界面中展示电影的详细信息。
  • 实现思路:
    • 使用 Vue 组件动态渲染电影列表。
    • 显示电影海报、标题、简介等信息。

4. 用户交互

  • 功能描述: 允许用户手动更新电影信息,添加自定义分类。
  • 实现思路:
    • 提供搜索功能,用户可以手动输入电影名称更新信息。
    • 允许用户创建和管理自定义分类标签。

数据处理

  • 本地缓存: 使用 Tauri 的本地存储功能缓存电影信息,减少重复请求。
  • 数据格式: 将电影信息存储为 JSON 格式,便于解析和展示。

UI/UX 设计

  • 界面布局: 使用响应式设计,确保在不同设备上有良好的显示效果。
  • 交互体验: 提供直观的操作流程,减少用户学习成本。

安全性考虑

  • 权限管理: 仅请求必要的文件系统权限,确保用户数据安全。
  • API 密钥保护: 使用环境变量存储 API 密钥,避免在客户端代码中暴露。

开发流程

1. 初始化项目

创建 Tauri 项目

npm create tauri-app
cd <project-name>

配置 Vite 和 Vue 3

安装依赖:

npm install vue@next
npm install @vitejs/plugin-vue

配置 vite.config.js

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
  plugins: [vue()],
});

2. 文件扫描模块

使用 Tauri 访问本地文件系统

在 Tauri 后端中使用 Rust 访问本地文件系统:

use std::fs;

#[tauri::command]
fn scan_directory(path: &str) -> Vec<String> {
    let paths = fs::read_dir(path).unwrap();
    let mut files = Vec::new();

    for path in paths {
        let path = path.unwrap().path();
        if let Some(ext) = path.extension() {
            if ext == "mp4" || ext == "mkv" {
                files.push(path.to_str().unwrap().to_string());
            }
        }
    }
    files
}

src-tauri/src/main.rs 中注册命令:

fn main() {
  tauri::Builder::default()
    .invoke_handler(tauri::generate_handler![scan_directory])
    .run(tauri::generate_context!())
    .expect("error while running tauri application");
}

3. 前端开发

创建 Vue 组件

src/components 中创建 MovieList.vue

<template>
  <div>
    <button @click="scanMovies">Scan Movies</button>
    <div v-for="movie in movies" :key="movie" class="movie-item">
      {{ movie }}
    </div>
  </div>
</template>

<script>
import { ref } from 'vue';
import { invoke } from '@tauri-apps/api/tauri';

export default {
  setup() {
    const movies = ref([]);

    async function scanMovies() {
      movies.value = await invoke('scan_directory', { path: '/your/movie/directory' });
    }

    return { movies, scanMovies };
  },
};
</script>

<style>
.movie-item {
  margin: 10px 0;
}
</style>

4. 资料刮削

使用 TMDb API 获取电影信息

安装 Axios:

npm install axios

创建一个 API 模块 src/api/movies.js

import axios from 'axios';

const API_KEY = 'YOUR_TMDB_API_KEY';

export async function fetchMovieData(movieName) {
  const response = await axios.get(`https://api.themoviedb.org/3/search/movie`, {
    params: {
      api_key: API_KEY,
      query: movieName,
    },
  });
  return response.data.results[0];
}

5. 组合功能

MovieList.vue 中调用 API:

<template>
  <div>
    <button @click="scanMovies">Scan Movies</button>
    <div v-for="movie in movies" :key="movie.id" class="movie-item">
      <img :src="`https://image.tmdb.org/t/p/w200/${movie.poster_path}`" alt="Movie Poster" />
      <h3>{{ movie.title }}</h3>
      <p>{{ movie.overview }}</p>
    </div>
  </div>
</template>

<script>
import { ref } from 'vue';
import { invoke } from '@tauri-apps/api/tauri';
import { fetchMovieData } from '../api/movies';

export default {
  setup() {
    const movies = ref([]);

    async function scanMovies() {
      const files = await invoke('scan_directory', { path: '/your/movie/directory' });
      const movieData = await Promise.all(files.map(file => fetchMovieData(file)));
      movies.value = movieData.filter(data => data);
    }

    return { movies, scanMovies };
  },
};
</script>

<style>
.movie-item {
  margin: 10px 0;
  display: flex;
  align-items: center;
}

.movie-item img {
  margin-right: 10px;
}
</style>

DEMO相关截图

WX20240813-232720@2x.png
screenshot-20240813-232800.png