107 lines
3.6 KiB
TypeScript
107 lines
3.6 KiB
TypeScript
// 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, unknown>) => string
|
|
|
|
interface SettingsContext {
|
|
form: MediaTranscodeProfile
|
|
formRef: Ref<FormInstance | undefined>
|
|
loading: Ref<boolean>
|
|
saving: Ref<boolean>
|
|
backfilling: Ref<boolean>
|
|
loadError: Ref<string>
|
|
canManage: ComputedRef<boolean>
|
|
t: Translate
|
|
}
|
|
|
|
/** 读取服务端配置并回填表单。 */
|
|
export const loadTranscodeProfile = async (context: SettingsContext): Promise<void> => {
|
|
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<boolean> => {
|
|
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<string, unknown>)[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<void> => {
|
|
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<void> => {
|
|
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
|
|
}
|
|
}
|