feat: 支持批量上传关卡

This commit is contained in:
richarjiang
2026-05-01 08:44:56 +08:00
parent f3f27def2b
commit 66a9ee2950
27 changed files with 5262 additions and 515 deletions

View File

@@ -0,0 +1,34 @@
/**
* 一次性脚本:给所有已有关卡回填 sortKey。
*
* 前置prisma schema 已加 sortKey 字段,并已跑过 `pnpm run db:push`。
* 执行pnpm tsx prisma/backfill-sort-keys.ts
*/
import { PrismaClient } from '@prisma/client'
import { generateKeyBetween } from 'fractional-indexing'
async function main() {
const db = new PrismaClient()
try {
const levels = await db.level.findMany({
orderBy: [{ sortOrder: 'asc' }, { createdAt: 'asc' }],
select: { id: true },
})
let prev: string | null = null
for (const { id } of levels) {
const key = generateKeyBetween(prev, null)
await db.level.update({ where: { id }, data: { sortKey: key } })
prev = key
}
// eslint-disable-next-line no-console
console.log(`backfilled ${levels.length} rows`)
} finally {
await db.$disconnect()
}
}
main().catch((e) => {
// eslint-disable-next-line no-console
console.error(e)
process.exit(1)
})

View File

@@ -0,0 +1,26 @@
/**
* 一次性脚本:把所有关卡的 sortKey 重新分配成 a... 递增序列,
* 消除历史上因"插到头部"产生的 Z 系列 key。
*
* 背景MySQL 默认 collation 大小写不敏感,把 `Zz` 和 `zz` 视作相等,
* 这会和 fractional-indexing 的字节序排序冲突。虽然应用层已切到 JS 排序,
* 运行一次这个脚本可以让 DB 数据和 JS 排序"视觉上"也一致,方便排查。
*
* 运行pnpm tsx prisma/rebalance-sort-keys.ts
*/
import { rebalanceAllKeys } from '../lib/sort-key'
import { prisma } from '../lib/prisma'
async function main() {
const count = await rebalanceAllKeys()
console.log(`rebalanced ${count} levels`)
}
main()
.catch((e) => {
console.error(e)
process.exit(1)
})
.finally(async () => {
await prisma.$disconnect()
})

View File

@@ -22,12 +22,14 @@ model Level {
hint1 String?
hint2 String?
hint3 String?
sortKey String @default("a0") @map("sort_key") @db.VarChar(64)
sortOrder Int @default(0) @map("sort_order")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
userProgress WxUserLevelProgress[]
@@index([sortKey])
@@map("levels")
}