| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- import { Injectable } from '@angular/core';
- import { DouyinTranscriptJob, DouyinTranscriptStatus } from '../models/douyin-insight.model';
- @Injectable({ providedIn: 'root' })
- export class ViralTranscriptPresenterService {
- private readonly processingStatuses = new Set<DouyinTranscriptStatus>([
- 'queued',
- 'resolving_detail',
- 'selecting_media',
- 'downloading_media',
- 'extracting_audio',
- 'submitting_provider',
- 'polling_provider',
- 'pending',
- ]);
- private readonly labels: Record<DouyinTranscriptStatus, string> = {
- queued: '排队中',
- resolving_detail: '获取视频详情',
- selecting_media: '选择媒体',
- downloading_media: '下载媒体',
- extracting_audio: '提取音频',
- submitting_provider: '提交转写',
- polling_provider: '等待结果',
- pending: '处理中',
- completed: '已完成',
- failed: '失败',
- needs_media: '缺少可转写媒体',
- needs_media_processing: '需要媒体处理环境',
- needs_provider_config: '服务未配置',
- };
- canStart(analysis: { transcript?: string; transcriptJob?: DouyinTranscriptJob } | null | undefined, busy: boolean): boolean {
- if (!analysis || busy || !!analysis.transcript) return false;
- const status = analysis.transcriptJob?.status;
- return !status
- || status === 'failed'
- || status === 'needs_media'
- || status === 'needs_media_processing'
- || status === 'needs_provider_config';
- }
- statusLabel(job: DouyinTranscriptJob | undefined): string {
- if (!job) return '未提交';
- return this.labels[job.status] || job.stageLabel || '未知状态';
- }
- primaryMessage(job: DouyinTranscriptJob | undefined): string {
- if (!job) return '';
- return this.message(job);
- }
- isProcessing(job: DouyinTranscriptJob | undefined): boolean {
- return !!job && this.processingStatuses.has(job.status);
- }
- shouldWarn(job: DouyinTranscriptJob | undefined): boolean {
- return !!job && job.status !== 'completed' && !this.isProcessing(job);
- }
- toastType(job: DouyinTranscriptJob): 'success' | 'warn' {
- return this.isProcessing(job) || job.status === 'completed' ? 'success' : 'warn';
- }
- message(job: DouyinTranscriptJob): string {
- if (job.stageLabel && this.isProcessing(job)) return job.stageLabel;
- if (job.status === 'pending' || job.status === 'queued') return '逐字稿任务已提交,稍后可刷新结果';
- if (job.status === 'completed') return '逐字稿已回填';
- if (job.status === 'needs_media') return '未找到可转写媒体,请确认视频详情能返回音频或视频地址';
- if (job.status === 'needs_media_processing') return job.errorMessage || '需要可用的媒体处理环境,请确认本地 ffmpeg 可用';
- if (job.status === 'needs_provider_config') {
- return job.warnings?.[0] || '未读取到转写服务配置,请检查 VOC_TOKEN、TRANSCRIPTION_VOC_TOKEN 或 VOICE_TOKEN';
- }
- return job.errorMessage || job.warnings?.[0] || '逐字稿任务失败,可修复配置后重新提交';
- }
- }
|