chore(依赖): 前后端依赖升到最新,补上机房 Chrome 105 缺的两个 polyfill

几处随升级改的:
- VueUse 15 的 useNow 不再收 interval,不传 scheduler 默认逐帧刷新。比赛列表(1 秒)
  和后台建比赛(15 秒)改成用 useIntervalFn 当调度器,频率不变。
- 重新探测 modernPolyfills:mermaid 12 用了 Object.groupBy(Chrome 117),core-js 新数据
  把 URL.parse(Chrome 126)也算进来了,不补的话机房老机器上静默报 TypeError。清单 52 项。
- vue-router 5.4 弃用了导航守卫里的 next(),全局守卫改成返回值。
- web-tree-sitter 0.27:AST 规则在 dev 和编译后的二进制里各跑过一遍,判过、判不过都对;
  jieba 2.0.4 原生模块在仓库外起二进制能正常分词。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
xuyueandClaude Opus 5.5 committed 2026-10-12 14:03:34 +08:00
1 parent 6f47ad8358
commit e6c02dce33
7 files changed
+242 -199

No files matched your search

+2 -1
View File
@@ -61,7 +61,8 @@ const customDuration = ref(false)
const pickedStart = ref(toPickerValue(Date.now() + 10 * 60_000))
// 「10 分钟后」跟着钟走:老师在这页磨蹭几分钟再保存,开始时间也还是保存时的 10 分钟后
const now = useNow({ interval: 15_000 })
// VueUse 15 起 useNow 不收 interval 了,不传 scheduler 默认是逐帧刷新
const now = useNow({ scheduler: (cb) => useIntervalFn(cb, 15_000) })
function roundedNow() {
const ms = now.value.getTime()
return ms - (ms % 60_000)
+8 -15
View File
@@ -26,13 +26,13 @@ import { useUserStore } from "./shared/store/user"
const authStore = useAuthModalStore()
router.beforeEach(async (to, _from, next) => {
// vue-router 5.4 起 next() 回调已弃用,改成返回值:返回 "/" 就是跳回首页,什么都不返回就是放行
router.beforeEach(async (to) => {
// 检查是否需要认证
if (to.matched.some((record) => record.meta.requiresAuth)) {
if (!storage.get(STORAGE_KEY.AUTHED)) {
authStore.openLoginModal()
next("/")
return
return "/"
}
}
@@ -47,8 +47,7 @@ router.beforeEach(async (to, _from, next) => {
) {
if (!storage.get(STORAGE_KEY.AUTHED)) {
authStore.openLoginModal()
next("/")
return
return "/"
}
const userStore = useUserStore()
@@ -56,29 +55,23 @@ router.beforeEach(async (to, _from, next) => {
try {
await userStore.getMyProfile()
} catch {
next("/")
return
return "/"
}
}
if (to.matched.some((record) => record.meta.requiresSuperAdmin)) {
if (!userStore.isSuperAdmin) {
next("/")
return
return "/"
}
} else if (to.matched.some((record) => record.meta.requiresTeacherAdmin)) {
if (!userStore.isTeacherOrAbove) {
next("/")
return
return "/"
}
} else if (to.matched.some((record) => record.meta.requiresProblemPermission)) {
if (!userStore.hasProblemPermission) {
next("/")
return
return "/"
}
}
}
next()
})
app.mount("#app")
+2 -1
View File
@@ -89,7 +89,8 @@ onMounted(() => {
watchDebounced(() => query.keyword, listContests, { debounce: 500, maxWait: 1000 })
watch(() => [query.page, query.limit, query.scope], listContests)
const now = useNow({ interval: 1000 })
// VueUse 15 起 useNow 不收 interval 了,不传 scheduler 默认是逐帧刷新
const now = useNow({ scheduler: (cb) => useIntervalFn(cb, 1000) })
function remaining(contest: Contest) {
const seconds = Math.floor((Date.parse(contest.endTime) - now.value.getTime()) / 1000)
const text = secondsToDuration(Math.max(0, seconds))