// Author: fruit.com.cn import { nextTick } from 'vue' import type { ComputedRef, Ref } from 'vue' import { ElMessage } from 'element-plus' import type { FormInstance } from 'element-plus' import { getMediaTranscodeProfileApi, saveMediaTranscodeProfileApi } from '@/api/admin/media' import { runTranscodeBackfillApi } from '@/api/admin/transcode' import type { MediaTranscodeProfile } from '@/api/admin/types' import { applyProfileToForm, buildProfilePayload } from './transcodeProfileModel' type Translate = (key: string, named?: Record) => string interface SettingsContext { form: MediaTranscodeProfile formRef: Ref loading: Ref saving: Ref backfilling: Ref loadError: Ref canManage: ComputedRef t: Translate } /** 读取服务端配置并回填表单。 */ export const loadTranscodeProfile = async (context: SettingsContext): Promise => { context.loading.value = true context.loadError.value = '' try { const response = await getMediaTranscodeProfileApi() if (response.code !== 0) { context.loadError.value = response.message || context.t('transcodeSettings.loadFailed') return } applyProfileToForm(context.form, response.data) } catch { context.loadError.value = context.t('transcodeSettings.loadFailed') } finally { context.loading.value = false } } const validateProfile = async (context: SettingsContext): Promise => { if (!context.form.ladder.length) { ElMessage.warning(context.t('transcodeSettings.validation.atLeastOneEnabled')) return false } try { await context.formRef.value?.validate() return true } catch (fields) { const firstField = Object.keys((fields || {}) as Record)[0] if (firstField) { await nextTick() context.formRef.value?.scrollToField(firstField) } ElMessage.warning(context.t('transcodeSettings.validation.fixErrors')) return false } } /** 校验并保存,成功后用服务端返回值回填。 */ export const saveTranscodeProfile = async (context: SettingsContext): Promise => { if (!context.canManage.value || context.saving.value || !(await validateProfile(context))) { return } context.saving.value = true try { const response = await saveMediaTranscodeProfileApi(buildProfilePayload(context.form)) if (response.code !== 0) { ElMessage.error(response.message || context.t('transcodeSettings.saveFailed')) return } applyProfileToForm(context.form, response.data) ElMessage.success(context.t('transcodeSettings.saved')) } catch { ElMessage.error(context.t('transcodeSettings.saveFailed')) } finally { context.saving.value = false } } /** 手动补齐转码:扫一遍缺码率产物/帧图的分集并入队。 */ export const runTranscodeBackfill = async (context: SettingsContext): Promise => { if (!context.canManage.value || context.backfilling.value) { return } context.backfilling.value = true try { const response = await runTranscodeBackfillApi() if (response.code !== 0) { ElMessage.error(response.message || context.t('transcodeSettings.backfillFailed')) return } const triggered = response.data?.triggered ?? 0 if (triggered > 0) { ElMessage.success(context.t('transcodeSettings.backfillDone', { count: triggered })) } else { ElMessage.info(context.t('transcodeSettings.backfillEmpty')) } } catch { ElMessage.error(context.t('transcodeSettings.backfillFailed')) } finally { context.backfilling.value = false } }