修复弹窗

This commit is contained in:
En 2026-04-08 09:36:42 +08:00
parent 922f650365
commit a660493cf3

View File

@ -125,6 +125,18 @@
<Transition name="fade"> <Transition name="fade">
<div v-if="toast" class="toast">{{ toast }}</div> <div v-if="toast" class="toast">{{ toast }}</div>
</Transition> </Transition>
<!-- 确认弹窗替代原生 confirm -->
<div v-if="confirmVisible" class="confirm-overlay" @click.self="handleConfirmCancel">
<div class="confirm-modal">
<div class="confirm-title">{{ confirmTitle }}</div>
<div class="confirm-content">{{ confirmContent }}</div>
<div class="confirm-actions">
<button class="confirm-btn cancel" @click="handleConfirmCancel">{{ confirmCancelText }}</button>
<button class="confirm-btn ok" @click="handleConfirmOk">{{ confirmOkText }}</button>
</div>
</div>
</div>
</div> </div>
</template> </template>
@ -179,6 +191,39 @@ function showToast(msg) {
setTimeout(() => { toast.value = '' }, 2500) setTimeout(() => { toast.value = '' }, 2500)
} }
// confirm
const confirmVisible = ref(false)
const confirmTitle = ref('')
const confirmContent = ref('')
const confirmOkText = ref('确认')
const confirmCancelText = ref('取消')
let confirmResolve = null
/**
* 显示确认弹窗替代原生 confirm
* @returns {Promise<boolean>}
*/
function showConfirm(content, options = {}) {
confirmTitle.value = options.title || '确认操作'
confirmContent.value = content
confirmOkText.value = options.okText || '确认'
confirmCancelText.value = options.cancelText || '取消'
confirmVisible.value = true
return new Promise((resolve) => { confirmResolve = resolve })
}
function handleConfirmOk() {
confirmVisible.value = false
confirmResolve?.(true)
confirmResolve = null
}
function handleConfirmCancel() {
confirmVisible.value = false
confirmResolve?.(false)
confirmResolve = null
}
function formatTime(sec) { function formatTime(sec) {
if (!sec || isNaN(sec)) return '0:00' if (!sec || isNaN(sec)) return '0:00'
const m = Math.floor(sec / 60) const m = Math.floor(sec / 60)
@ -348,7 +393,12 @@ async function voiceSingle() {
} }
async function voiceAllConfirm() { async function voiceAllConfirm() {
if (!confirm('将为所有未配音的页面生成AI语音预计需要30-60秒确认继续')) return const confirmed = await showConfirm('将为所有未配音的页面生成AI语音预计需要30-60秒确认继续', {
title: 'AI 配音',
okText: '开始生成',
cancelText: '再想想',
})
if (!confirmed) return
voicingAll.value = true voicingAll.value = true
try { try {
const res = await voicePage({ workId: workId.value, voiceAll: true }) const res = await voicePage({ workId: workId.value, voiceAll: true })
@ -838,4 +888,69 @@ onBeforeUnmount(() => {
} }
.fade-enter-active, .fade-leave-active { transition: opacity 0.3s; } .fade-enter-active, .fade-leave-active { transition: opacity 0.3s; }
.fade-enter-from, .fade-leave-to { opacity: 0; } .fade-enter-from, .fade-leave-to { opacity: 0; }
/* ── 确认弹窗Ant Design 风格) ── */
.confirm-overlay {
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
background: rgba(0, 0, 0, 0.45);
z-index: 1100;
display: flex;
align-items: center;
justify-content: center;
padding: 16px;
}
.confirm-modal {
background: #fff;
border-radius: 8px;
padding: 24px;
min-width: 280px;
max-width: 400px;
box-shadow: 0 6px 30px rgba(0, 0, 0, 0.12);
animation: confirmFadeIn 0.2s ease;
}
@keyframes confirmFadeIn {
from { opacity: 0; transform: scale(0.95); }
to { opacity: 1; transform: scale(1); }
}
.confirm-title {
font-size: 16px;
font-weight: 600;
color: #1f2937;
margin-bottom: 8px;
}
.confirm-content {
font-size: 14px;
color: #6b7280;
line-height: 1.6;
margin-bottom: 24px;
}
.confirm-actions {
display: flex;
gap: 8px;
justify-content: flex-end;
}
.confirm-btn {
padding: 5px 16px;
border-radius: 6px;
font-size: 14px;
cursor: pointer;
height: 32px;
line-height: 1;
transition: all 0.2s;
&.cancel {
border: 1px solid #d1d5db;
background: #fff;
color: #374151;
&:hover { border-color: #6366f1; color: #6366f1; }
}
&.ok {
border: none;
background: #6366f1;
color: #fff;
font-weight: 500;
&:hover { background: #4f46e5; }
}
}
</style> </style>