feat: 功能优化

This commit is contained in:
2025-11-19 21:57:16 +08:00
parent f052b0af65
commit 75abf48bc1
11 changed files with 818 additions and 164 deletions

View File

@@ -39,9 +39,6 @@
<div v-if="column.key === 'name'" class="voice-name">
{{ record.name || '未命名' }}
</div>
<div v-else-if="column.key === 'transcription'" class="transcription-text">
{{ formatTranscription(record.transcription) }}
</div>
<span v-else-if="column.key === 'createTime'">
{{ formatDateTime(record.createTime) }}
</span>
@@ -51,15 +48,6 @@
</a-button>
<a-space v-else-if="column.key === 'actions'">
<a-button type="link" size="small" @click="handleEdit(record)">编辑</a-button>
<a-button
type="link"
size="small"
:loading="transcribingId === record.id"
:disabled="!!record.transcription"
@click="handleTranscribe(record)"
>
{{ record.transcription ? '已识别' : '识别' }}
</a-button>
<a-button type="link" size="small" danger @click="handleDelete(record)">删除</a-button>
</a-space>
</template>
@@ -109,14 +97,6 @@
<a-form-item label="备注" name="note">
<a-textarea v-model="formData.note" :rows="3" placeholder="请输入备注信息" />
</a-form-item>
<a-form-item v-if="!isCreateMode" label="识别内容" name="transcription">
<a-textarea
v-model="formData.transcription"
:rows="4"
placeholder="识别内容,支持手动修改"
/>
</a-form-item>
</a-form>
</a-modal>
@@ -125,7 +105,7 @@
</template>
<script setup>
import { ref, reactive, computed, onMounted, onUnmounted, nextTick } from 'vue'
import { ref, reactive, computed, onMounted, nextTick } from 'vue'
import { message, Modal } from 'ant-design-vue'
import { PlusOutlined, SearchOutlined, UploadOutlined, PlayCircleOutlined } from '@ant-design/icons-vue'
import { VoiceService } from '@/api/voice'
@@ -133,12 +113,6 @@ import { MaterialService } from '@/api/material'
import dayjs from 'dayjs'
// ========== 常量 ==========
const POLLING_CONFIG = {
interval: 10000,
maxCount: 30,
transcriptionMaxLength: 50
}
const DEFAULT_FORM_DATA = {
id: null,
name: '',
@@ -146,8 +120,7 @@ const DEFAULT_FORM_DATA = {
autoTranscribe: true,
language: 'zh-CN',
gender: 'female',
note: '',
transcription: ''
note: ''
}
// ========== 响应式数据 ==========
@@ -155,13 +128,11 @@ const loading = ref(false)
const submitting = ref(false)
const uploading = ref(false)
const voiceList = ref([])
const transcribingId = ref(null)
const modalVisible = ref(false)
const formMode = ref('create')
const formRef = ref(null)
const audioPlayer = ref(null)
const fileList = ref([])
let pollingTimer = null
const searchParams = reactive({
name: '',
@@ -185,7 +156,6 @@ const isCreateMode = computed(() => formMode.value === 'create')
// ========== 表格配置 ==========
const columns = [
{ title: '配音名称', key: 'name', dataIndex: 'name', width: 200 },
{ title: '识别内容', key: 'transcription', dataIndex: 'transcription', width: 300 },
{ title: '创建时间', key: 'createTime', dataIndex: 'createTime', width: 180 },
{ title: '操作', key: 'actions', width: 200, fixed: 'right' }
]
@@ -197,12 +167,6 @@ const formRules = {
}
// ========== 工具函数 ==========
const formatTranscription = (transcription) => {
if (!transcription) return '未识别'
if (transcription.length <= POLLING_CONFIG.transcriptionMaxLength) return transcription
return transcription.substring(0, POLLING_CONFIG.transcriptionMaxLength) + '...'
}
const formatDateTime = (value) => {
if (!value) return '-'
return dayjs(value).format('YYYY-MM-DD HH:mm:ss')
@@ -215,8 +179,7 @@ const fillFormData = (data) => {
fileId: data.fileId || null,
language: data.language || 'zh-CN',
gender: data.gender || 'female',
note: data.note || '',
transcription: data.transcription || ''
note: data.note || ''
})
}
@@ -300,62 +263,6 @@ const handleDelete = (record) => {
})
}
// ========== 语音识别 ==========
const handleTranscribe = async (record) => {
transcribingId.value = record.id
try {
const res = await VoiceService.transcribe(record.id)
if (res.code !== 0) {
message.error(res.msg || '识别失败')
transcribingId.value = null
return
}
message.success('识别任务已提交,正在识别中...')
startPollingTranscription(record.id)
} catch (error) {
console.error('识别失败:', error)
message.error('识别失败,请稍后重试')
transcribingId.value = null
}
}
const stopPolling = () => {
if (pollingTimer) {
clearInterval(pollingTimer)
pollingTimer = null
}
transcribingId.value = null
}
const startPollingTranscription = (voiceId) => {
stopPolling()
let pollCount = 0
pollingTimer = setInterval(async () => {
pollCount++
try {
const res = await VoiceService.get(voiceId)
if (res.code === 0 && res.data?.transcription) {
stopPolling()
message.success('识别完成')
loadVoiceList()
return
}
if (pollCount >= POLLING_CONFIG.maxCount) {
stopPolling()
message.warning('识别超时,请稍后手动刷新查看结果')
loadVoiceList()
}
} catch (error) {
console.error('轮询识别结果失败:', error)
if (pollCount >= POLLING_CONFIG.maxCount) stopPolling()
}
}, POLLING_CONFIG.interval)
}
// ========== 音频播放 ==========
const handlePlayAudio = (record) => {
if (record.fileUrl && audioPlayer.value) {
@@ -460,8 +367,7 @@ const handleSubmit = async () => {
name: formData.name,
language: formData.language,
gender: formData.gender,
note: formData.note,
transcription: formData.transcription
note: formData.note
}
try {
@@ -476,12 +382,6 @@ const handleSubmit = async () => {
message.success(isCreateMode.value ? '创建成功' : '更新成功')
modalVisible.value = false
if (isCreateMode.value && formData.autoTranscribe && res.data) {
message.info('自动识别已启动,正在识别中...')
startPollingTranscription(res.data)
}
loadVoiceList()
} catch (error) {
console.error('提交失败:', error)
@@ -506,10 +406,6 @@ const resetForm = () => {
onMounted(() => {
loadVoiceList()
})
onUnmounted(() => {
stopPolling()
})
</script>
<style scoped>
@@ -550,12 +446,6 @@ onUnmounted(() => {
color: var(--color-text);
}
.transcription-text {
color: var(--color-text-secondary);
font-size: 13px;
line-height: 1.5;
}
.upload-hint {
font-size: 12px;
color: var(--color-text-secondary);