feat(front): 前台默认浅色模式并新增居中投稿按钮与实时空闲档期
- 主题: useTheme 默认 ModernLight + variables.css SSR-safe 浅值并精修组件对比度 - 首页: 插入居中投稿 CTA + 紧邻档期概览卡片(今日排期/待播歌曲/空闲档期数) - 数据: useSongs 新增 fetchExpectedPlayDates 接入空闲档期并走 revision 轮询实时刷新 - 视觉: 移动端优先,少圆角硬边几何 + 概览卡片 3→1 列响应式
This commit is contained in:
@@ -17,6 +17,7 @@ export const useSongs = () => {
|
||||
const playTimes = ref<PlayTime[]>([])
|
||||
const playTimeEnabled = ref(false)
|
||||
const songCount = ref(0)
|
||||
const expectedPlayDates = ref<any[]>([])
|
||||
|
||||
// 显示通知
|
||||
const showNotification = (message: string, type: 'success' | 'error' | 'info' = 'info') => {
|
||||
@@ -916,6 +917,56 @@ export const useSongs = () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 获取期望播出日期及空闲档期
|
||||
const fetchExpectedPlayDates = async (silent = false, forceRefresh = false) => {
|
||||
if (!silent) {
|
||||
loading.value = true
|
||||
}
|
||||
try {
|
||||
const data = await dedup.dedupedRequest(
|
||||
'expected-play-dates',
|
||||
async () => {
|
||||
const url = forceRefresh
|
||||
? `/api/expected-play-dates?t=${Date.now()}`
|
||||
: '/api/expected-play-dates'
|
||||
return await $fetch(url)
|
||||
},
|
||||
undefined,
|
||||
forceRefresh
|
||||
)
|
||||
if (Array.isArray(data)) {
|
||||
expectedPlayDates.value = data
|
||||
} else if (data && Array.isArray((data as any).data)) {
|
||||
expectedPlayDates.value = (data as any).data
|
||||
} else {
|
||||
expectedPlayDates.value = []
|
||||
}
|
||||
return expectedPlayDates.value
|
||||
} catch (err: any) {
|
||||
if (!silent) {
|
||||
error.value = err.message || '获取档期数据失败'
|
||||
}
|
||||
return expectedPlayDates.value
|
||||
} finally {
|
||||
if (!silent) {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const totalFreeSlots = computed(() =>
|
||||
expectedPlayDates.value.reduce(
|
||||
(sum, d) => sum + (Array.isArray(d.freeSequences) ? d.freeSequences.length : 0),
|
||||
0
|
||||
)
|
||||
)
|
||||
|
||||
const openDaysCount = computed(() =>
|
||||
expectedPlayDates.value.filter((d) => !d.isFull).length
|
||||
)
|
||||
|
||||
const expectedPlayDatesLoaded = computed(() => Array.isArray(expectedPlayDates.value))
|
||||
|
||||
// 初始化加载
|
||||
const initialize = async () => {
|
||||
await fetchPlayTimes()
|
||||
@@ -932,6 +983,10 @@ export const useSongs = () => {
|
||||
publicSchedules,
|
||||
visibleSongs,
|
||||
songCount,
|
||||
expectedPlayDates,
|
||||
totalFreeSlots,
|
||||
openDaysCount,
|
||||
expectedPlayDatesLoaded,
|
||||
loading,
|
||||
error,
|
||||
notification,
|
||||
@@ -943,6 +998,7 @@ export const useSongs = () => {
|
||||
fetchPublicSchedules,
|
||||
fetchPlayTimes,
|
||||
fetchSongCount,
|
||||
fetchExpectedPlayDates,
|
||||
refreshSongsSilent,
|
||||
refreshSchedulesSilent,
|
||||
checkSimilarSongs,
|
||||
|
||||
Reference in New Issue
Block a user