feat: 优化
This commit is contained in:
@@ -37,6 +37,9 @@
|
||||
<div v-if="column.key === 'name'" class="voice-name">
|
||||
{{ record.name || '未命名' }}
|
||||
</div>
|
||||
<a-tooltip v-else-if="column.key === 'note'" :title="record.note" placement="topLeft">
|
||||
<span class="note-text">{{ record.note || '-' }}</span>
|
||||
</a-tooltip>
|
||||
<span v-else-if="column.key === 'createTime'">
|
||||
{{ formatDateTime(record.createTime) }}
|
||||
</span>
|
||||
@@ -56,16 +59,18 @@
|
||||
<a-modal
|
||||
v-model:open="modalVisible"
|
||||
:title="isCreateMode ? '新建配音' : '编辑配音'"
|
||||
:width="600"
|
||||
ok-text="确定"
|
||||
:width="480"
|
||||
ok-text="保存"
|
||||
cancel-text="取消"
|
||||
:confirm-loading="submitting"
|
||||
:mask-closable="false"
|
||||
centered
|
||||
@ok="handleSubmit"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<a-form ref="formRef" :model="formData" :rules="formRules" layout="vertical">
|
||||
<a-form-item label="配音名称" name="name">
|
||||
<a-input v-model:value="formData.name" placeholder="请输入配音名称" />
|
||||
<a-input v-model:value="formData.name" placeholder="请输入配音名称" allow-clear />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
@@ -74,28 +79,50 @@
|
||||
name="fileId"
|
||||
:rules="[{ required: true, message: '请上传音频文件' }]"
|
||||
>
|
||||
<a-upload
|
||||
v-model:file-list="fileList"
|
||||
:custom-request="handleCustomUpload"
|
||||
:before-upload="handleBeforeUpload"
|
||||
:max-count="1"
|
||||
accept="audio/*,.mp3,.wav,.aac,.m4a,.flac,.ogg"
|
||||
@remove="handleRemoveFile"
|
||||
@change="handleFileListChange"
|
||||
>
|
||||
<a-button type="primary" :loading="uploadState.uploading">
|
||||
<UploadOutlined v-if="!uploadState.uploading" />
|
||||
{{ uploadState.uploading ? '上传中...' : (fileList.length > 0 ? '重新上传' : '上传音频文件') }}
|
||||
</a-button>
|
||||
</a-upload>
|
||||
<div class="upload-hint">
|
||||
支持格式:MP3、WAV、AAC、M4A、FLAC、OGG,单个文件不超过 5MB<br>
|
||||
<span class="hint-text">🎤 配音建议:使用 5-20 秒的短配音效果更佳</span>
|
||||
<div class="upload-area" :class="{ 'has-file': fileList.length > 0 }">
|
||||
<a-upload-dragger
|
||||
v-model:file-list="fileList"
|
||||
:custom-request="handleCustomUpload"
|
||||
:before-upload="handleBeforeUpload"
|
||||
:max-count="1"
|
||||
:show-upload-list="false"
|
||||
accept="audio/*,.mp3,.wav,.aac,.m4a,.flac,.ogg"
|
||||
@remove="handleRemoveFile"
|
||||
>
|
||||
<template v-if="!uploadState.uploading && fileList.length === 0">
|
||||
<div class="upload-icon">
|
||||
<CloudUploadOutlined />
|
||||
</div>
|
||||
<p class="upload-text">点击或拖拽音频文件到此区域</p>
|
||||
<p class="upload-hint-inline">支持 MP3、WAV、AAC 等格式,最大 5MB</p>
|
||||
</template>
|
||||
<template v-else-if="uploadState.uploading">
|
||||
<a-progress type="circle" :percent="50" :width="60" status="active" />
|
||||
<p class="upload-text" style="margin-top: 12px">正在上传...</p>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="file-preview">
|
||||
<SoundOutlined class="file-icon" />
|
||||
<div class="file-info">
|
||||
<span class="file-name">{{ fileList[0]?.name || '音频文件' }}</span>
|
||||
<a-button type="link" size="small" danger @click.stop="handleRemoveFile">
|
||||
<DeleteOutlined /> 移除
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</a-upload-dragger>
|
||||
</div>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="备注" name="note">
|
||||
<a-textarea v-model="formData.note" :rows="3" placeholder="请输入备注信息" />
|
||||
<a-textarea
|
||||
v-model:value="formData.note"
|
||||
:rows="2"
|
||||
placeholder="备注信息(选填)"
|
||||
:auto-size="{ minRows: 2, maxRows: 4 }"
|
||||
allow-clear
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
@@ -107,7 +134,7 @@
|
||||
<script setup>
|
||||
import { ref, reactive, computed, onMounted } from 'vue'
|
||||
import { message, Modal } from 'ant-design-vue'
|
||||
import { PlusOutlined, SearchOutlined, UploadOutlined, PlayCircleOutlined } from '@ant-design/icons-vue'
|
||||
import { PlusOutlined, SearchOutlined, PlayCircleOutlined, CloudUploadOutlined, SoundOutlined, DeleteOutlined } from '@ant-design/icons-vue'
|
||||
import dayjs from 'dayjs'
|
||||
import BasicLayout from '@/layouts/components/BasicLayout.vue'
|
||||
import { MaterialService } from '@/api/material'
|
||||
@@ -170,9 +197,10 @@ const isCreateMode = computed(() => formMode.value === 'create')
|
||||
|
||||
// ========== 表格配置 ==========
|
||||
const columns = [
|
||||
{ title: '配音名称', key: 'name', dataIndex: 'name', width: 200 },
|
||||
{ title: '配音名称', key: 'name', dataIndex: 'name', width: 160 },
|
||||
{ title: '备注', key: 'note', dataIndex: 'note', ellipsis: true },
|
||||
{ title: '创建时间', key: 'createTime', dataIndex: 'createTime', width: 180 },
|
||||
{ title: '操作', key: 'actions', width: 90, fixed: 'right' }
|
||||
{ title: '操作', key: 'actions', width: 100, fixed: 'right' }
|
||||
]
|
||||
|
||||
// ========== 表单验证规则 ==========
|
||||
@@ -362,15 +390,6 @@ async function fetchAudioTextById(fileId) {
|
||||
}
|
||||
}
|
||||
|
||||
function handleFileListChange(info) {
|
||||
const { fileList: newFileList } = info
|
||||
if (newFileList) {
|
||||
fileList.value = newFileList.filter(function(item) {
|
||||
return item.status !== 'removed'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function handleRemoveFile() {
|
||||
formData.fileId = null
|
||||
fileList.value = []
|
||||
@@ -426,8 +445,8 @@ async function handleSubmit() {
|
||||
}
|
||||
|
||||
function handleCancel() {
|
||||
modalVisible.value = false
|
||||
resetForm()
|
||||
modalVisible.value = false
|
||||
resetForm()
|
||||
}
|
||||
|
||||
function resetForm() {
|
||||
@@ -442,7 +461,7 @@ onMounted(function() {
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style scoped lang="less">
|
||||
.search-bar {
|
||||
background: var(--color-surface);
|
||||
border-radius: var(--radius-card);
|
||||
@@ -459,10 +478,74 @@ onMounted(function() {
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.upload-hint {
|
||||
font-size: 12px;
|
||||
.note-text {
|
||||
color: var(--color-text-secondary);
|
||||
margin-top: 8px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
// 上传区域样式
|
||||
.upload-area {
|
||||
:deep(.ant-upload-drag) {
|
||||
border: 2px dashed var(--color-border, #d9d9d9);
|
||||
border-radius: 8px;
|
||||
background: var(--color-bg-container, #fafafa);
|
||||
transition: all 0.3s;
|
||||
padding: 24px 16px;
|
||||
|
||||
&:hover {
|
||||
border-color: var(--color-primary, #1890ff);
|
||||
background: var(--color-primary-bg, #e6f7ff);
|
||||
}
|
||||
}
|
||||
|
||||
&.has-file :deep(.ant-upload-drag) {
|
||||
border-style: solid;
|
||||
border-color: var(--color-success-border, #b7eb8f);
|
||||
background: var(--color-success-bg, #f6ffed);
|
||||
}
|
||||
}
|
||||
|
||||
.upload-icon {
|
||||
font-size: 40px;
|
||||
color: var(--color-primary, #1890ff);
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.upload-text {
|
||||
font-size: 14px;
|
||||
color: var(--color-text, #333);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.upload-hint-inline {
|
||||
font-size: 12px;
|
||||
color: var(--color-text-secondary, #999);
|
||||
}
|
||||
|
||||
.file-preview {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
|
||||
.file-icon {
|
||||
font-size: 32px;
|
||||
color: var(--color-primary, #1890ff);
|
||||
}
|
||||
|
||||
.file-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.file-name {
|
||||
font-size: 14px;
|
||||
color: var(--color-text, #333);
|
||||
max-width: 200px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user