feat(schedule)+fix(schedule)+feat(player): 排期管理5项功能 - 紧凑布局/投稿人优先算法/localStorage持久化/备选池修复/播放队列按钮

* fix+style(schedule): ScheduleManager 标签页紧凑布局,头部 min-height 防抖,内容区统间距与移动端适配
* feat(schedule): 新增自动排期策略「按投稿人数优先覆盖」,按 requester+collaborators 数排序分配好时段
* feat(schedule): localStorage 键 voicehub:schedule:auto-config 持久化策略/时段/学期/过滤等7项,onMounted 恢复,watch debounce 500ms 保存
* fix(schedule): songs/index.get.ts 新增 use_pool 查询参数,备选池过滤条件 status=PENDING + song.played=false + song未在任何排期中;ScheduleManager/draft-bulk 创建排期时将池记录 UPDATE 为 ASSIGNED
* feat(player): ScheduleManager 工具栏新增「构建播放队列」按钮,按 playDate+playTimeId+sequence 排序后调用 useAudioPlayer.playSong 加载播放列表,支持 confirm 确认与 toast 反馈
* refactor(useSongs): fetchSongs 增加第5参数 usePool,透传 use_pool=true 到 /api/songs
This commit is contained in:
2026-09-12 08:33:25 +08:00
parent 4d39afd23f
commit 153ee41ef0
5 changed files with 364 additions and 58 deletions
+22 -1
View File
@@ -1,5 +1,13 @@
import { db } from '~/drizzle/db'
import { playTimes, schedules, songs, users, votes, songReplayRequests } from '~/drizzle/schema'
import {
playTimes,
schedules,
songs,
users,
votes,
songReplayRequests,
scheduleSongPool
} from '~/drizzle/schema'
import { and, asc, count, desc, eq, gte, lte } from 'drizzle-orm'
import { createSongSelectedNotification } from '../../services/notificationService'
import { cacheService } from '~~/server/services/cacheService'
@@ -126,6 +134,19 @@ export default defineEventHandler(async (event) => {
// 获取客户端IP地址
const clientIP = getClientIP(event)
await tx
.update(scheduleSongPool)
.set({
status: 'ASSIGNED',
targetPlayDate: playDate
})
.where(
and(
eq(scheduleSongPool.songId, body.songId),
eq(scheduleSongPool.status, 'PENDING')
)
)
// 只有在非草稿模式下才创建通知
if (!isDraft) {
await createSongSelectedNotification(