Files
BYW-VoiceHub/server/api/admin/card-codes/index.get.ts
T

75 lines
2.5 KiB
TypeScript

import { db } from '~/drizzle/db'
import { cardCodes } from '~/drizzle/schema'
import { and, count, desc, eq, ilike, or } from 'drizzle-orm'
export default defineEventHandler(async (event) => {
const user = event.context.user
if (!user) {
throw createError({ statusCode: 401, message: '未授权访问' })
}
if (!['SONG_ADMIN', 'ADMIN', 'SUPER_ADMIN'].includes(user.role)) {
throw createError({ statusCode: 403, message: '权限不足' })
}
try {
const query = getQuery(event)
const status = typeof query.status === 'string' ? query.status.trim().toUpperCase() : ''
const keyword = typeof query.q === 'string' ? query.q.trim() : ''
const page = Math.max(1, Number.parseInt(String(query.page || '1'), 10) || 1)
const limitInput = Number.parseInt(String(query.limit || '10'), 10) || 10
const limit = Math.min(100, Math.max(1, limitInput))
const offset = (page - 1) * limit
const conditions = [] as any[]
if (status) {
conditions.push(eq(cardCodes.status, status as any))
}
if (keyword) {
conditions.push(
or(
ilike(cardCodes.code, `%${keyword}%`),
ilike(cardCodes.note, `%${keyword}%`)
)
)
}
let queryBuilder = db.select().from(cardCodes)
let countQueryBuilder = db.select({ count: count() }).from(cardCodes)
if (conditions.length > 0) {
queryBuilder = queryBuilder.where(and(...conditions))
countQueryBuilder = countQueryBuilder.where(and(...conditions))
}
const [result, totalResult, statsRows] = await Promise.all([
queryBuilder.orderBy(desc(cardCodes.createdAt)).limit(limit).offset(offset),
countQueryBuilder,
db.select({ status: cardCodes.status, count: count() }).from(cardCodes).groupBy(cardCodes.status)
])
const stats = { total: 0, available: 0, locked: 0, redeemed: 0 }
for (const row of statsRows) {
const value = Number(row.count || 0)
stats.total += value
if (row.status === 'AVAILABLE') stats.available = value
if (row.status === 'LOCKED') stats.locked = value
if (row.status === 'REDEEMED') stats.redeemed = value
}
const total = Number(totalResult[0]?.count || 0)
return {
success: true,
data: result,
pagination: {
page,
limit,
total,
totalPages: Math.max(1, Math.ceil(total / limit))
},
stats
}
} catch (err) {
console.error('获取点歌券列表失败', err)
throw createError({ statusCode: 500, message: '获取点歌券列表失败' })
}
})