fix(排期): 发布按钮不再兼任删除,清空排期改为显式操作并加服务端守卫
This commit is contained in:
@@ -741,6 +741,15 @@
|
|||||||
</div>
|
</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
|
<button
|
||||||
:disabled="!hasChanges"
|
: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"
|
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,
|
CalendarDays,
|
||||||
Image as ImageIcon,
|
Image as ImageIcon,
|
||||||
Layers,
|
Layers,
|
||||||
Inbox
|
Inbox,
|
||||||
|
Trash2
|
||||||
} from '@lucide/vue'
|
} from '@lucide/vue'
|
||||||
import AdminDatePicker from './AdminDatePicker.vue'
|
import AdminDatePicker from './AdminDatePicker.vue'
|
||||||
import PlaylistCardGenerator from './PlaylistCardGenerator.vue'
|
import PlaylistCardGenerator from './PlaylistCardGenerator.vue'
|
||||||
@@ -2504,21 +2514,26 @@ watch(
|
|||||||
)
|
)
|
||||||
|
|
||||||
// 发布排期(需要确认)
|
// 发布排期(需要确认)
|
||||||
|
//
|
||||||
|
// ⚠️ 这里**只管发布,绝不删除**。
|
||||||
|
//
|
||||||
|
// 以前为了「清空某天排期」把删除偷偷挂在发布按钮上:列表为空时点发布 → 弹「删除排期」→
|
||||||
|
// 调 bulk-publish 传空数组 → 服务端先删光该日期(含草稿)再插入 0 条。
|
||||||
|
// 于是只要**界面上的列表是空的**(数据还没加载回来、时段筛选没匹配上、切换日期后没刷新完…),
|
||||||
|
// 点「发布」就等于清空当天 —— 按钮叫发布,干的是删除。删除已经拆到
|
||||||
|
// clearTodaySchedule(),发布路径不再有任何破坏性分支。
|
||||||
const publishSchedule = async () => {
|
const publishSchedule = async () => {
|
||||||
try {
|
try {
|
||||||
// 如果列表为空,提示删除排期
|
|
||||||
if (localScheduledSongs.value.length === 0) {
|
if (localScheduledSongs.value.length === 0) {
|
||||||
confirmDialogTitle.value = '删除排期'
|
showToast('当前列表没有歌曲,没有需要发布的内容', 'info')
|
||||||
confirmDialogMessage.value = '确定要删除当天的所有排期吗?此操作不可恢复。'
|
return
|
||||||
confirmDialogType.value = 'danger'
|
|
||||||
confirmDialogConfirmText.value = '确认删除'
|
|
||||||
} else {
|
|
||||||
confirmDialogTitle.value = '发布排期'
|
|
||||||
confirmDialogMessage.value = '确定要发布当前排期吗?发布后将立即公示并发送通知。'
|
|
||||||
confirmDialogType.value = 'warning'
|
|
||||||
confirmDialogConfirmText.value = '发布排期'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
confirmDialogTitle.value = '发布排期'
|
||||||
|
confirmDialogMessage.value = '确定要发布当前排期吗?发布后将立即公示并发送通知。'
|
||||||
|
confirmDialogType.value = 'warning'
|
||||||
|
confirmDialogConfirmText.value = '发布排期'
|
||||||
|
|
||||||
confirmAction.value = async () => {
|
confirmAction.value = async () => {
|
||||||
await publishScheduleConfirmed()
|
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 () => {
|
const publishScheduleConfirmed = async () => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
|
|||||||
@@ -48,8 +48,16 @@ export default defineEventHandler(async (event) => {
|
|||||||
|
|
||||||
// 获取所有涉及的歌曲详情(用于通知)
|
// 获取所有涉及的歌曲详情(用于通知)
|
||||||
const songIds = body.songs.map((s: any) => s.songId)
|
const songIds = body.songs.map((s: any) => s.songId)
|
||||||
if (songIds.length === 0) {
|
/*
|
||||||
// 如果列表为空,说明是清空排期,直接执行删除逻辑即可
|
* ⚠️ 空 songs = 「清空该日期排期」:下面第 3 步会先删光该日期(含草稿)的排期,再插入 0 条。
|
||||||
|
* 这是个**破坏性操作**,绝不能因为前端列表没加载出来(数组恰好是空)就被误触发 ——
|
||||||
|
* 以前点「发布」就能把一整天删掉。所以清空必须由调用方显式带 confirmClear: true。
|
||||||
|
*/
|
||||||
|
if (songIds.length === 0 && body.confirmClear !== true) {
|
||||||
|
throw createError({
|
||||||
|
statusCode: 400,
|
||||||
|
message: '歌曲列表为空:发布需要至少一首歌;若要清空当天排期,请显式传 confirmClear: true'
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const songDetails =
|
const songDetails =
|
||||||
|
|||||||
Reference in New Issue
Block a user