diff --git a/components/aigc/generation/CGTaskCard.client.vue b/components/aigc/generation/CGTaskCard.client.vue index d03db70..e41dc7a 100644 --- a/components/aigc/generation/CGTaskCard.client.vue +++ b/components/aigc/generation/CGTaskCard.client.vue @@ -5,6 +5,7 @@ import { useDownload } from '~/composables/useDownload' import gsap from 'gsap' const toast = useToast() +const loginState = useLoginState() const { metaSymbol } = useShortcuts() const srtEditor = ref() @@ -18,14 +19,14 @@ const props = defineProps({ const emit = defineEmits(['delete']) defineShortcuts({ - 'p': { + p: { handler: () => { if (isDropdownOpen.value && isDownloadable.value) { isPreviewModalOpen.value = true } }, }, - 'meta_d': { + meta_d: { handler: () => { if (isDropdownOpen.value && isDownloadable.value) { srtEditor.value.open() @@ -33,14 +34,17 @@ defineShortcuts({ } }, }, - 'meta_s': { + meta_s: { handler: async () => { if (isDropdownOpen.value && isDownloadable.value) { - await startDownload(await fetchCourseSubtitleUrl(props.course), `眩生花微课_${props.course.title}_${props.course.task_id}.srt`) + await startDownload( + await fetchCourseSubtitleUrl(props.course), + `眩生花微课_${props.course.title}_${props.course.task_id}.srt` + ) } }, }, - 'delete': { + delete: { handler: () => { if (isDropdownOpen.value) { emit('delete', props.course.task_id) @@ -53,47 +57,51 @@ const isDropdownOpen = ref(false) const isPreviewModalOpen = ref(false) const stateDisplay = computed(() => { - if (props.course.progress === -1) return { - color: 'red', - text: '失败', - } - if (props.course.progress === 100) return { - color: 'green', - text: '完成', - } + if (props.course.progress === -1) + return { + color: 'red', + text: '失败', + } + if (props.course.progress === 100) + return { + color: 'green', + text: '完成', + } return { color: 'blue', - text: !!props.course.progress ? `${tweenedGenerateProgress.value.toFixed(0)}%` : '队列中', + text: !!props.course.progress + ? `${tweenedGenerateProgress.value.toFixed(0)}%` + : '队列中', } }) const isFailed = computed(() => props.course.progress === -1) -const isDownloadable = computed(() => !isFailed.value && props.course.progress === 100) +const isDownloadable = computed( + () => !isFailed.value && props.course.progress === 100 +) const generateProgress = computed(() => { return props.course.progress || 0 }) const tweenedGenerateProgress = ref(0) -watch(generateProgress, (newValue) => { - gsap.to(tweenedGenerateProgress, { - duration: 5, - value: newValue, - }) -}, { - immediate: true, -}) +watch( + generateProgress, + (newValue) => { + gsap.to(tweenedGenerateProgress, { + duration: 5, + value: newValue, + }) + }, + { + immediate: true, + } +) const downloadProgress = ref(0) -const startDownload = async ( - url: string, - filename: string, -) => { +const startDownload = async (url: string, filename: string) => { downloadProgress.value = 0 - const { - download, - progressEmitter, - } = useDownload(url, filename) + const { download, progressEmitter } = useDownload(url, filename) progressEmitter.on('done', () => { downloadProgress.value = 100 @@ -109,7 +117,7 @@ const startDownload = async ( downloadProgress.value = progress }) - progressEmitter.on('error', err => { + progressEmitter.on('error', (err) => { downloadProgress.value = 0 toast.add({ title: '下载失败', @@ -123,7 +131,9 @@ const startDownload = async ( } const copyTaskId = (extraMessage?: string) => { - navigator.clipboard.writeText(props.course.task_id + (extraMessage ? ` ${extraMessage}` : '')) + navigator.clipboard.writeText( + props.course.task_id + (extraMessage ? ` ${extraMessage}` : '') + ) toast.add({ title: '复制成功', description: '已复制任务 ID', @@ -138,162 +148,367 @@ const combinationState = ref<0 | 1 | undefined>(0) const onCombination = () => { isCombinationModalOpen.value = true combinationState.value = undefined - useVideoSubtitleEmbedding(props.course.video_url, props.course.subtitle_url).then(src => { - startDownload(src, `眩生花微课_${props.course.title}_${props.course.task_id}_combinated.mp4`) - combinationState.value = 1 - }).catch(err => { - toast.add({ - title: '嵌入字幕失败', - description: err.message || '未知错误', - color: 'red', - icon: 'i-tabler-alert-triangle', + useVideoSubtitleEmbedding(props.course.video_url, props.course.subtitle_url) + .then((src) => { + startDownload( + src, + `眩生花微课_${props.course.title}_${props.course.task_id}_combinated.mp4` + ) + combinationState.value = 1 }) - combinationState.value = 0 - }).finally(() => { - setTimeout(() => { + .catch((err) => { + toast.add({ + title: '嵌入字幕失败', + description: err.message || '未知错误', + color: 'red', + icon: 'i-tabler-alert-triangle', + }) combinationState.value = 0 - isCombinationModalOpen.value = false - }, 3000) - }) + }) + .finally(() => { + setTimeout(() => { + combinationState.value = 0 + isCombinationModalOpen.value = false + }, 3000) + }) +} + +const onRetryClick = (course: resp.gen.CourseGenItem) => { + useFetchWrapped< + req.gen.CourseGenCreate & AuthedRequest, + BaseResponse + >('App.Digital_Convert.Create', { + token: loginState.token!, + user_id: loginState.user.id, + task_title: course.title, + gen_server: 'main', + speed: 2 - course.speed, + ppt_url: course.ppt_url, + digital_human_id: course.digital_human_id, + custom_video: '[]', + opening_url: course.opening_url || '', + ending_url: course.opening_url || '', + }).then( + (res) => { + if (res.data.record_status === 1) { + toast.add({ + title: '重试已提交', + description: '已加入生成队列', + color: 'green', + icon: 'i-tabler-check', + }) + // delete + emit('delete', course.task_id) + } else { + toast.add({ + title: '提交重试失败', + description: res.msg || '未知错误', + color: 'red', + icon: 'i-tabler-alert-triangle', + }) + } + }, + (err) => { + toast.add({ + title: '提交重试失败', + description: err.message || '未知错误', + color: 'red', + icon: 'i-tabler-alert-triangle', + }) + } + ) } - \ No newline at end of file +