fix(排期): 发布按钮不再兼任删除,清空排期改为显式操作并加服务端守卫

This commit is contained in:
2026-10-11 01:15:24 +08:00
parent 28238ab00f
commit b64ee5cbc6
2 changed files with 86 additions and 13 deletions
+76 -11
View File
@@ -741,6 +741,15 @@
</div>
<!-- 主要操作 -->
<!-- 清空当天排期:破坏性动作,独立出来(发布按钮不再兼任删除) -->
<button
:disabled="localScheduledSongs.length === 0"
class="shrink-0 w-11 h-11 bg-white border border-red-200 text-red-500 rounded-xl flex items-center justify-center active:scale-95 transition-all disabled:opacity-40 disabled:cursor-not-allowed"
title="删除当天全部排期"
@click="clearTodaySchedule"
>
<Trash2 class="w-5 h-5" />
</button>
<button
:disabled="!hasChanges"
class="flex-1 py-3 bg-blue-600 hover:bg-blue-500 text-white text-xs font-black uppercase tracking-widest rounded-xl shadow-lg shadow-blue-900/20 transition-all active:scale-95 disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-2"
@@ -933,7 +942,8 @@ import {
CalendarDays,
Image as ImageIcon,
Layers,
Inbox
Inbox,
Trash2
} from '@lucide/vue'
import AdminDatePicker from './AdminDatePicker.vue'
import PlaylistCardGenerator from './PlaylistCardGenerator.vue'
@@ -2504,21 +2514,26 @@ watch(
)
// 发布排期(需要确认)
//
// ⚠️ 这里**只管发布,绝不删除**。
//
// 以前为了「清空某天排期」把删除偷偷挂在发布按钮上:列表为空时点发布 → 弹「删除排期」→
// 调 bulk-publish 传空数组 → 服务端先删光该日期(含草稿)再插入 0 条。
// 于是只要**界面上的列表是空的**(数据还没加载回来、时段筛选没匹配上、切换日期后没刷新完…),
// 点「发布」就等于清空当天 —— 按钮叫发布,干的是删除。删除已经拆到
// clearTodaySchedule(),发布路径不再有任何破坏性分支。
const publishSchedule = async () => {
try {
// 如果列表为空,提示删除排期
if (localScheduledSongs.value.length === 0) {
confirmDialogTitle.value = '删除排期'
confirmDialogMessage.value = '确定要删除当天的所有排期吗?此操作不可恢复。'
confirmDialogType.value = 'danger'
confirmDialogConfirmText.value = '确认删除'
} else {
confirmDialogTitle.value = '发布排期'
confirmDialogMessage.value = '确定要发布当前排期吗?发布后将立即公示并发送通知。'
confirmDialogType.value = 'warning'
confirmDialogConfirmText.value = '发布排期'
showToast('当前列表没有歌曲,没有需要发布的内容', 'info')
return
}
confirmDialogTitle.value = '发布排期'
confirmDialogMessage.value = '确定要发布当前排期吗?发布后将立即公示并发送通知。'
confirmDialogType.value = 'warning'
confirmDialogConfirmText.value = '发布排期'
confirmAction.value = async () => {
await publishScheduleConfirmed()
}
@@ -2528,6 +2543,56 @@ const publishSchedule = async () => {
}
}
/**
* 清空当天的排期(含草稿)—— 独立的显式操作,跟「发布」彻底分开。
* 服务端 bulk-publish 收到空 songs 数组时会先删该日期全部排期再插入 0 条(即清空),
* 所以「删除」这个破坏性动作必须由调用方明确要求,见 bulk-publish.post.ts 里的 confirmClear。
*/
const clearTodaySchedule = () => {
if (localScheduledSongs.value.length === 0) {
showToast('当天本来就没有排期', 'info')
return
}
confirmDialogTitle.value = '删除当天排期'
confirmDialogMessage.value = `确定要删除 ${selectedDate.value} 的全部排期吗?已发布的排期和草稿都会一起删除,此操作不可恢复。`
confirmDialogType.value = 'danger'
confirmDialogConfirmText.value = '确认删除'
confirmAction.value = async () => {
loading.value = true
try {
await $fetch('/api/admin/schedule/bulk-publish', {
method: 'POST',
body: {
playDate: selectedDate.value,
playTimeId: selectedPlayTime.value ? parseInt(selectedPlayTime.value) : null,
songs: [],
confirmClear: true // 明确表示「我就是要清空」,缺了它服务端会拒(防止误清)
},
...auth.getAuthConfig()
})
hasChanges.value = false
await loadData()
updateLocalScheduledSongs()
if (window.$showNotification) {
window.$showNotification('当天排期已删除', 'success')
}
} catch (error) {
console.error('删除当天排期失败:', error)
if (window.$showNotification) {
window.$showNotification('删除失败: ' + (error.data?.message || error.message), 'error')
}
} finally {
loading.value = false
}
}
showConfirmDialog.value = true
}
// 确认发布排期
const publishScheduleConfirmed = async () => {
loading.value = true