新增日志导出选择

This commit is contained in:
kura 2026-05-02 16:18:45 +08:00
parent 78c750bcbf
commit 763a14265d
5 changed files with 33 additions and 29 deletions

View File

@ -69,8 +69,9 @@ fn export_subtitles(
state: tauri::State<'_, AppState>, state: tauri::State<'_, AppState>,
task_id: String, task_id: String,
format: String, format: String,
output_path: String,
) -> std::result::Result<String, String> { ) -> std::result::Result<String, String> {
task::export_task(state, task_id, format).map_err(error_to_string) task::export_task(state, task_id, format, output_path).map_err(error_to_string)
} }
#[tauri::command] #[tauri::command]

View File

@ -9,16 +9,6 @@ pub enum SubtitleFormat {
Ass, Ass,
} }
impl SubtitleFormat {
pub fn extension(&self) -> &'static str {
match self {
Self::Srt => "srt",
Self::Vtt => "vtt",
Self::Ass => "ass",
}
}
}
impl TryFrom<&str> for SubtitleFormat { impl TryFrom<&str> for SubtitleFormat {
type Error = anyhow::Error; type Error = anyhow::Error;

View File

@ -8,7 +8,7 @@ use std::{
time::Duration, time::Duration,
}; };
use anyhow::{Context, Result}; use anyhow::Result;
use tauri::{Emitter, Manager, Window}; use tauri::{Emitter, Manager, Window};
use uuid::Uuid; use uuid::Uuid;
@ -740,24 +740,16 @@ pub fn export_task(
state: tauri::State<'_, AppState>, state: tauri::State<'_, AppState>,
task_id: String, task_id: String,
format: String, format: String,
output_path: String,
) -> Result<String> { ) -> Result<String> {
let task = state.get_task(&task_id)?; let task = state.get_task(&task_id)?;
let format = SubtitleFormat::try_from(format.as_str())?; let format = SubtitleFormat::try_from(format.as_str())?;
let content = render(&task.segments, format, task.bilingual_output); let content = render(&task.segments, format, task.bilingual_output);
let source_path = PathBuf::from(&task.file_path); let output_path = PathBuf::from(output_path);
let stem = source_path if let Some(output_dir) = output_path.parent() {
.file_stem() fs::create_dir_all(output_dir)?;
.and_then(|item| item.to_str()) }
.unwrap_or("subtitle");
let output_dir = source_path
.parent()
.map(PathBuf::from)
.unwrap_or(std::env::current_dir().context("failed to get current directory")?);
fs::create_dir_all(&output_dir)?;
let output_path = output_dir.join(format!("{stem}.{}", format.extension()));
fs::write(&output_path, content)?; fs::write(&output_path, content)?;
Ok(output_path.display().to_string()) Ok(output_path.display().to_string())

View File

@ -2,7 +2,7 @@
import { computed, onMounted, onUnmounted, ref, watch } from 'vue' import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { invoke } from '@tauri-apps/api/core' import { invoke } from '@tauri-apps/api/core'
import { open } from '@tauri-apps/plugin-dialog' import { open, save } from '@tauri-apps/plugin-dialog'
import { listen, type UnlistenFn } from '@tauri-apps/api/event' import { listen, type UnlistenFn } from '@tauri-apps/api/event'
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow' import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow'
import TaskQueue from './components/TaskQueue.vue' import TaskQueue from './components/TaskQueue.vue'
@ -281,9 +281,30 @@ async function handleFiles(event: Event) {
input.value = '' input.value = ''
} }
function getDefaultExportPath(filePath: string, format: 'srt' | 'vtt' | 'ass') {
const separatorIndex = Math.max(filePath.lastIndexOf('/'), filePath.lastIndexOf('\\'))
const directory = separatorIndex >= 0 ? filePath.slice(0, separatorIndex + 1) : ''
const fileName = separatorIndex >= 0 ? filePath.slice(separatorIndex + 1) : filePath
const stem = fileName.replace(/\.[^./\\]*$/, '') || 'subtitle'
return `${directory}${stem}.${format}`
}
async function handleExport(format: 'srt' | 'vtt' | 'ass') { async function handleExport(format: 'srt' | 'vtt' | 'ass') {
if (!selectedTask.value) return if (!selectedTask.value) return
const output = await taskStore.exportTask(selectedTask.value.id, format) const outputPath = await save({
title: t('app.exportSubtitles'),
defaultPath: getDefaultExportPath(selectedTask.value.filePath, format),
filters: [
{
name: format.toUpperCase(),
extensions: [format],
},
],
})
if (!outputPath) return
const output = await taskStore.exportTask(selectedTask.value.id, format, outputPath)
feedback.value = output feedback.value = output
} }

View File

@ -170,8 +170,8 @@ export const useTaskStore = defineStore('tasks', {
} }
}, },
async exportTask(taskId: string, format: ExportFormat) { async exportTask(taskId: string, format: ExportFormat, outputPath: string) {
return invoke<string>('export_subtitles', { taskId, format }) return invoke<string>('export_subtitles', { taskId, format, outputPath })
}, },
}, },
}) })