feat(user): 重构用户端竞赛流程并添加新页面
- 将原单页竞赛流程拆分为独立路由页面(首页、封面、规则、抽题、答题、图解、组别、队伍) - 新增 Pinia store 管理竞赛状态、计时器和音频控制 - 添加 SCSS 变量文件定义主题色 - 更新路由配置和类型定义以支持新页面结构 - 重构 QuestionRenderer 组件优化样式 - 添加图标依赖并更新国际化配置 - 移动图片资源到用户目录并清理旧文件
This commit is contained in:
165
apps/admin/src/views/user/analysis/index.vue
Normal file
165
apps/admin/src/views/user/analysis/index.vue
Normal file
@ -0,0 +1,165 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import CompetitionLayout from '@/components/custom/user/CompetitionLayout.vue'
|
||||
import { useRouterPush } from '@/hooks/common/router'
|
||||
import { useCompetitionStore } from '@/store/modules/competition'
|
||||
|
||||
const { routerPushByKey } = useRouterPush()
|
||||
|
||||
const store = useCompetitionStore()
|
||||
|
||||
const zoomedImage = ref<string | null>(null)
|
||||
|
||||
// Mock team data
|
||||
const teams = ref([
|
||||
{
|
||||
id: 1,
|
||||
name: '第一队',
|
||||
writtenCount: 16,
|
||||
correctCount: 13,
|
||||
score: 13,
|
||||
manualScore: null as number | null,
|
||||
image: 'https://via.placeholder.com/300x400?text=Team+1+Answer',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '第二队',
|
||||
writtenCount: 15,
|
||||
correctCount: 12,
|
||||
score: 12,
|
||||
manualScore: null as number | null,
|
||||
image: 'https://via.placeholder.com/300x400?text=Team+2+Answer',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '第三队',
|
||||
writtenCount: 18,
|
||||
correctCount: 15,
|
||||
score: 15,
|
||||
manualScore: null as number | null,
|
||||
image: 'https://via.placeholder.com/300x400?text=Team+3+Answer',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: '第四队',
|
||||
writtenCount: 14,
|
||||
correctCount: 10,
|
||||
score: 10,
|
||||
manualScore: null as number | null,
|
||||
image: 'https://via.placeholder.com/300x400?text=Team+4+Answer',
|
||||
},
|
||||
])
|
||||
|
||||
function handleZoom(img: string) {
|
||||
zoomedImage.value = img
|
||||
}
|
||||
|
||||
function handleBack() {
|
||||
routerPushByKey('user_game')
|
||||
}
|
||||
|
||||
function handleNext() {
|
||||
const nextRoute = store.nextStep()
|
||||
routerPushByKey(nextRoute)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<CompetitionLayout
|
||||
:show-title="true"
|
||||
:show-back="true"
|
||||
:show-next="true"
|
||||
title="答题图解"
|
||||
action-position="top"
|
||||
back-btn-text="返回"
|
||||
next-btn-text="下一题"
|
||||
btn-theme="light"
|
||||
@back="handleBack"
|
||||
@next="handleNext"
|
||||
>
|
||||
<div class="relative h-full w-full flex flex-col items-center px-12 pt-10 font-sans">
|
||||
<!-- Content -->
|
||||
<div class="w-full flex flex-col flex-1 overflow-hidden">
|
||||
<div class="mb-2 text-xl text-red-600 font-bold">
|
||||
备注:由AI模型评判
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-4 h-full gap-6 pb-8">
|
||||
<div
|
||||
v-for="team in teams" :key="team.id"
|
||||
class="flex flex-col border-2 border-gray-200 rounded-xl bg-white/90 p-4 shadow-sm"
|
||||
>
|
||||
<div class="mb-2 text-xl text-gray-800 font-bold">
|
||||
{{ team.name }}
|
||||
</div>
|
||||
|
||||
<!-- Answer Image Area -->
|
||||
<div
|
||||
class="relative mb-4 flex-1 cursor-zoom-in overflow-hidden border border-gray-300 rounded bg-gray-50"
|
||||
@click="handleZoom(team.image)"
|
||||
>
|
||||
<!-- Grid Background Simulation -->
|
||||
<div class="pointer-events-none absolute inset-0 grid grid-cols-8 gap-px bg-gray-200 opacity-20">
|
||||
<div v-for="n in 64" :key="n" class="bg-white" />
|
||||
</div>
|
||||
<!-- Simulated Handwriting/Content -->
|
||||
<div class="absolute inset-0 flex items-center justify-center text-gray-400">
|
||||
(点击放大查看详情)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Stats & Score -->
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="text-sm text-gray-700 font-medium">
|
||||
写了数量{{ team.writtenCount }},正确{{ team.correctCount }}个,积分{{ team.score }}
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-red-500 font-bold">评委当场评</span>
|
||||
</div>
|
||||
|
||||
<div class="relative">
|
||||
<input
|
||||
v-model="team.manualScore"
|
||||
type="number"
|
||||
class="w-full border border-gray-300 rounded px-3 py-2 text-sm focus:border-blue-500 focus:outline-none"
|
||||
placeholder="留个输入框,修改正确积分"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Zoom Modal -->
|
||||
<div
|
||||
v-if="zoomedImage"
|
||||
class="fixed inset-0 z-50 flex items-center justify-center bg-black/80 backdrop-blur-sm"
|
||||
@click="zoomedImage = null"
|
||||
>
|
||||
<div class="relative max-h-[90vh] max-w-[90vw] p-4">
|
||||
<img :src="zoomedImage" class="max-h-full max-w-full rounded bg-white shadow-2xl" alt="Zoomed Answer">
|
||||
<div class="absolute bottom-4 left-1/2 text-sm text-white/80 -translate-x-1/2">
|
||||
点击任意处关闭
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CompetitionLayout>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* Custom Scrollbar for content if needed */
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #cbd5e1;
|
||||
border-radius: 4px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user