From 11f448cedca7509a3a1668bcaa0c2efad70b362f Mon Sep 17 00:00:00 2001 From: rjl <98n9@163.com> Date: Thu, 12 Mar 2026 14:33:30 +0800 Subject: [PATCH] =?UTF-8?q?feat(admin):=20=E4=BC=98=E5=8C=96=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E7=95=8C=E9=9D=A2=E4=BA=A4=E4=BA=92=E4=B8=8E=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在抽题页面添加开始抽题按钮并绑定事件 - 调整队伍列表动画延迟和分组页面样式 - 修复结果发布条件逻辑,允许无结束时间时发布 - 增强TypeIt组件,支持动态配置和实例管理 - 更新Competition API类型定义,使用枚举类型 - 优化CompetitionLayout组件按钮显示时机 - 修正分析页面API调用参数类型 - 在拼写检查词典中添加Typeit --- .vscode/settings.json | 3 +- .../src/components/custom/typeit/index.vue | 80 ++++++++++++++----- .../custom/user/CompetitionLayout.vue | 9 ++- apps/admin/src/typings/api/Competition.d.ts | 2 +- .../views/results/results-detail/index.vue | 2 +- apps/admin/src/views/user/analysis/index.vue | 15 ++-- apps/admin/src/views/user/draw/index.vue | 5 +- apps/admin/src/views/user/groups/index.vue | 12 +-- apps/admin/src/views/user/teams/index.vue | 2 +- apps/admin/tsconfig.tsbuildinfo | 2 +- 10 files changed, 90 insertions(+), 42 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index e764788..bec9644 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -39,6 +39,7 @@ "totvsLanguageServer.welcomePage": false, "cSpell.words": [ "activityinfo", - "Echarts" + "Echarts", + "Typeit" ] // ` } diff --git a/apps/admin/src/components/custom/typeit/index.vue b/apps/admin/src/components/custom/typeit/index.vue index 261ac00..bc2a7bf 100644 --- a/apps/admin/src/components/custom/typeit/index.vue +++ b/apps/admin/src/components/custom/typeit/index.vue @@ -2,44 +2,84 @@ import type { Options } from 'typeit' import type { El } from 'typeit/dist/types' import TypeIt from 'typeit' -import { onMounted, shallowRef } from 'vue' +import { onBeforeUnmount, onMounted, shallowRef, watch } from 'vue' + +defineOptions({ name: 'TypeIt' }) + +const props = withDefaults(defineProps(), { + speed: 100, + loop: false, + cursor: true, + lifeLike: true, + strings: () => [], +}) + +interface Props { + /** 打字速度 */ + speed?: number + /** 是否循环 */ + loop?: boolean + /** 是否显示光标 */ + cursor?: boolean + /** 打字内容 */ + strings?: string | string[] + /** 像人一样打字 */ + lifeLike?: boolean + /** 开始前的延迟 */ + startDelay?: number + /** 下一段文字的延迟 */ + nextStringDelay?: number + /** 循环延迟 */ + loopDelay?: number + /** 兼容旧代码或用户自定义延迟参数 */ + typeDelay?: number +} const textRef = shallowRef() +const typeItInstance = shallowRef(null) function init() { if (!textRef.value) return - const options: Options = { - strings: 'SoybeanAdmin是一个清新优雅、高颜值且功能强大的后台管理模板', - lifeLike: true, - speed: 120, - loop: true, + if (typeItInstance.value) { + typeItInstance.value.destroy() } - const initTypeIt = new TypeIt(textRef.value, options) + // 清空内容,防止重叠 + textRef.value.textContent = '' - initTypeIt.go() + const options: Options = { + strings: props.strings, + lifeLike: props.lifeLike, + speed: props.speed, + loop: props.loop, + cursor: props.cursor, + startDelay: props.startDelay, + nextStringDelay: props.nextStringDelay ?? props.typeDelay, + loopDelay: props.loopDelay, + } + + typeItInstance.value = new TypeIt(textRef.value, options).go() } onMounted(() => { init() }) + +onBeforeUnmount(() => { + if (typeItInstance.value) { + typeItInstance.value.destroy() + } +}) + +watch(() => [props.strings, props.speed, props.loop], () => { + init() +}) diff --git a/apps/admin/src/components/custom/user/CompetitionLayout.vue b/apps/admin/src/components/custom/user/CompetitionLayout.vue index e857577..abf38b0 100644 --- a/apps/admin/src/components/custom/user/CompetitionLayout.vue +++ b/apps/admin/src/components/custom/user/CompetitionLayout.vue @@ -88,6 +88,7 @@ async function fetchSystemConfig() { const showContent = ref(false) const showSlotContent = ref(false) +const showButton = ref(false) function handleBack() { emit('back') @@ -115,10 +116,15 @@ onMounted(() => { }, 100) // 延迟显示内容,等待标题卷轴展开 - const delay = props.showTitle ? 800 : 100 + const delay = props.showTitle ? 500 : 100 setTimeout(() => { showSlotContent.value = true }, delay) + + // 延迟显示按钮,等待内容显示 + setTimeout(() => { + showButton.value = true + }, delay + 500) }) @@ -160,6 +166,7 @@ onMounted(() => {