feat: 功能优化
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user