feat: 迁移自定义功能至 1.5.9.9 版本
包含音乐源限制、CI 防 OOM 优化、数据库连接池优化、管理端权限及 UI 细节定制等功能
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import { db } from '~/drizzle/db'
|
||||
import { playTimes, schedules, songs, songReplayRequests } from '~/drizzle/schema'
|
||||
import { and, desc, eq, gte, lte } from 'drizzle-orm'
|
||||
import { cacheService } from '~~/server/services/cacheService'
|
||||
import { getClientIP } from '~~/server/utils/ip-utils'
|
||||
import { createApiError } from '~~/server/utils/apiError'
|
||||
|
||||
// 输入验证函数
|
||||
function validateInput(body: any) {
|
||||
@@ -111,22 +111,39 @@ export default defineEventHandler(async (event) => {
|
||||
}
|
||||
}
|
||||
|
||||
// 校验重播申请绑定(草稿仅记录绑定关系,不修改申请状态)
|
||||
let replayRequestId: number | null = null
|
||||
const requestedReplayId = Number(body.replayRequestId)
|
||||
if (body.replayRequestId != null && Number.isInteger(requestedReplayId) && requestedReplayId > 0) {
|
||||
const replayRequestResult = await tx
|
||||
.select({ id: songReplayRequests.id, songId: songReplayRequests.songId, status: songReplayRequests.status })
|
||||
.from(songReplayRequests)
|
||||
.where(eq(songReplayRequests.id, requestedReplayId))
|
||||
.limit(1)
|
||||
// 检查是否已经为该歌曲创建过排期或草稿,如果有则删除旧的
|
||||
const existingScheduleResult = await tx
|
||||
.select()
|
||||
.from(schedules)
|
||||
.where(eq(schedules.songId, body.songId))
|
||||
.limit(1)
|
||||
|
||||
const replayRequest = replayRequestResult[0]
|
||||
if (!replayRequest || replayRequest.songId !== song.id || replayRequest.status !== 'PENDING') {
|
||||
throw createApiError(400, 'SONG_REPLAY_INVALID_REQUEST', '重播申请无效或已被处理')
|
||||
const existingSchedule = existingScheduleResult[0]
|
||||
if (existingSchedule) {
|
||||
// 删除现有排期或草稿
|
||||
await tx.delete(schedules).where(eq(schedules.id, existingSchedule.id))
|
||||
|
||||
// 恢复该歌曲的重播申请状态为 PENDING
|
||||
// 只恢复状态为 FULFILLED 的申请
|
||||
const updatedRequests = await tx
|
||||
.update(songReplayRequests)
|
||||
.set({
|
||||
status: 'PENDING',
|
||||
updatedAt: new Date()
|
||||
})
|
||||
.where(
|
||||
and(
|
||||
eq(songReplayRequests.songId, body.songId),
|
||||
eq(songReplayRequests.status, 'FULFILLED')
|
||||
)
|
||||
)
|
||||
.returning()
|
||||
|
||||
if (updatedRequests.length > 0) {
|
||||
console.log(
|
||||
`恢复了 ${updatedRequests.length} 个重播申请状态为 PENDING(草稿保存时删除旧排期)`
|
||||
)
|
||||
}
|
||||
|
||||
replayRequestId = replayRequest.id
|
||||
}
|
||||
|
||||
// 获取序号,如果未提供则查找当天最大序号+1
|
||||
@@ -149,8 +166,9 @@ export default defineEventHandler(async (event) => {
|
||||
.orderBy(desc(schedules.sequence))
|
||||
.limit(1)
|
||||
|
||||
const latestSchedule = sameDaySchedules[0]
|
||||
if (latestSchedule) sequence = (latestSchedule.sequence || 0) + 1
|
||||
if (sameDaySchedules.length > 0) {
|
||||
sequence = (sameDaySchedules[0].sequence || 0) + 1
|
||||
}
|
||||
}
|
||||
|
||||
// 解析输入的日期字符串,确保日期正确
|
||||
@@ -168,7 +186,6 @@ export default defineEventHandler(async (event) => {
|
||||
playDate: playDate,
|
||||
sequence: sequence,
|
||||
playTimeId: body.playTimeId || null,
|
||||
replayRequestId,
|
||||
isDraft: true, // 标记为草稿
|
||||
publishedAt: null // 草稿状态下没有发布时间
|
||||
})
|
||||
@@ -180,12 +197,21 @@ export default defineEventHandler(async (event) => {
|
||||
id: song.id,
|
||||
title: song.title,
|
||||
artist: song.artist,
|
||||
requesterId: song.requesterId,
|
||||
cardCodeId: song.cardCodeId
|
||||
requesterId: song.requesterId
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 清除相关缓存(在事务外执行,避免影响事务性能)
|
||||
try {
|
||||
await cacheService.clearSchedulesCache()
|
||||
await cacheService.clearSongsCache()
|
||||
console.log('[Cache] 排期缓存和歌曲列表缓存已清除(保存草稿)')
|
||||
} catch (cacheError) {
|
||||
console.error('[Cache] 清除缓存失败:', cacheError)
|
||||
// 缓存清除失败不应该影响主要操作的成功
|
||||
}
|
||||
|
||||
const responseData = {
|
||||
...result.schedule,
|
||||
song: result.song,
|
||||
|
||||
Reference in New Issue
Block a user