fix(open-api): 修复开放API两处缺陷并支持小程序取 token

- songs.get.ts: 引用未定义变量 songsWithDetails 导致 /api/open/songs 缓存未命中时必然 500,改为 formattedSongs;并让缓存分支兼容 requester 为字符串的情况,避免返回 { name: undefined }
- schedules.get.ts: 数据库分支补齐 sequence / played / song.voteCount,与此前只有缓存分支才返回这些字段的行为对齐(缺少 sequence 会让前端无法显示歌曲序号)
- login.post.ts: 响应体返回 token,便于小程序/App 通过 Authorization: Bearer 访问(不影响原有 httpOnly cookie 行为)
This commit is contained in:
2026-09-26 13:48:27 +08:00
parent 6f5aa625e6
commit a140ce8621
3 changed files with 47 additions and 8 deletions
+33 -1
View File
@@ -1,6 +1,14 @@
import { createError, defineEventHandler, getQuery } from 'h3'
import { db } from '~/drizzle/db'
import { playTimes, schedules, songCollaborators, songs, systemSettings, users } from '~/drizzle/schema'
import {
playTimes,
schedules,
songCollaborators,
songs,
systemSettings,
users,
votes
} from '~/drizzle/schema'
import { and, asc, desc, eq, gte, inArray, like, lt, or, sql } from 'drizzle-orm'
import { formatDateTime } from '~/utils/timeUtils'
import { openApiCache } from '~~/server/utils/open-api-cache'
@@ -220,6 +228,8 @@ export default defineEventHandler(async (event) => {
.select({
id: schedules.id,
playDate: schedules.playDate,
sequence: schedules.sequence,
played: schedules.played,
createdAt: schedules.createdAt,
updatedAt: schedules.updatedAt,
song: {
@@ -312,6 +322,25 @@ export default defineEventHandler(async (event) => {
})
}
// 统计每首歌的票数。
// 该接口的缓存分支(本文件上方)会返回 voteCount,数据库分支此前漏了,
// 导致两条分支字段不一致,这里补齐。
const voteCountsMap = new Map<number, number>()
if (songIds.length > 0) {
const voteCountsData = await db
.select({
songId: votes.songId,
count: sql`count(*)`
})
.from(votes)
.where(inArray(votes.songId, songIds))
.groupBy(votes.songId)
voteCountsData.forEach((row) => {
voteCountsMap.set(row.songId, Number(row.count))
})
}
// 格式化数据
const formattedSchedules = schedulesData.map((schedule) => {
const collaborators = collaboratorsMap.get(schedule.song.id) || []
@@ -320,6 +349,8 @@ export default defineEventHandler(async (event) => {
id: schedule.id,
playDate: schedule.playDate,
playDateFormatted: formatDateTime(schedule.playDate),
sequence: schedule.sequence,
played: schedule.played,
semester: schedule.song.semester,
song: {
id: schedule.song.id,
@@ -328,6 +359,7 @@ export default defineEventHandler(async (event) => {
cover: schedule.song.cover,
musicPlatform: schedule.song.musicPlatform,
musicId: schedule.song.musicId,
voteCount: voteCountsMap.get(schedule.song.id) || 0,
played: schedule.song.played,
playedAt: schedule.song.playedAt,
requestedAt: formatDateTime(schedule.song.createdAt),