Files
reader-star/apps/admin/src/views/competition/competition-add/modules/HardwareBinding.vue
rjl 3270e24c25 feat(competition): 新增比赛管理功能并优化UI交互
- 添加比赛创建向导,支持分步配置基础信息、分组管理、硬件绑定和题目配置
- 实现比赛卡片组件,支持复制和删除操作
- 优化比赛详情页的表单交互和样式
- 新增全局组件类型定义和图标
- 添加比赛海报上传功能
- 完善比赛状态管理,新增"已结束"状态
2026-01-21 08:41:36 +08:00

124 lines
3.2 KiB
Vue

<script setup lang="ts">
import { NGrid, NGridItem, NInput } from 'naive-ui'
import { ref, watch } from 'vue'
const props = defineProps<{
config?: {
groupCount: number
teamCount: number
}
}>()
interface HardwareGroup {
groupId: string
pens: Array<{ label: string, sn: string, online: boolean }>
}
const hardwareGroups = ref<HardwareGroup[]>([])
function generateHardwareGroups() {
if (!props.config)
return
const { groupCount, teamCount } = props.config
if (!groupCount || groupCount <= 0)
return
const totalGroups = groupCount
const newGroups: HardwareGroup[] = []
for (let i = 1; i <= totalGroups; i++) {
const idStr = String(i).padStart(2, '0')
const currentTeamCount = teamCount
const pens = []
for (let j = 1; j <= currentTeamCount; j++) {
pens.push({
label: `T${j}`,
sn: '',
online: false, // 模拟初始状态
})
}
newGroups.push({
groupId: idStr,
pens,
})
}
hardwareGroups.value = newGroups
}
watch(() => props.config, generateHardwareGroups, { deep: true, immediate: true })
function validate() {
// 暂时不需要强制校验硬件绑定,允许跳过
return true
}
defineExpose({ validate })
</script>
<template>
<div class="h-full">
<div class="mb-8">
<h2 class="mb-2 text-3xl text-gray-800 font-bold">
点阵笔硬件绑定
</h2>
<p class="text-gray-400">
请将点阵笔序列号 (SN) 绑定至对应队伍建议使用扫码枪快速录入
</p>
</div>
<!-- 状态提示栏 -->
<div class="mb-8 flex items-start gap-3 border border-indigo-100 rounded-lg bg-indigo-50 p-4">
<div class="i-carbon-radar mt-0.5 text-xl text-indigo-500" />
<div>
<div class="text-sm text-indigo-900 font-bold">
自动发现模式已开启
</div>
<div class="mt-1 text-xs text-indigo-400">
系统将自动扫描正在书写的点阵笔并提示绑定请确保基站已通电
</div>
</div>
</div>
<!-- 硬件状态卡片 -->
<NGrid :x-gap="24" :y-gap="24" cols="1 m:2 l:3" responsive="screen">
<NGridItem v-for="(group, idx) in hardwareGroups" :key="idx">
<div class="border border-gray-100 rounded-2xl bg-[#F8FAFC] p-6">
<div class="mb-4 text-gray-800 font-bold">
硬件绑定: {{ idx + 1 }} 分组
</div>
<div class="flex flex-col gap-3">
<div v-for="pen in group.pens" :key="pen.label" class="flex items-center gap-3 rounded-lg bg-white p-2">
<div class="w-8 text-center text-gray-400 font-bold">
{{ pen.label }}
</div>
<div class="flex-1">
<NInput
v-model:value="pen.sn" size="small" placeholder="点阵笔 SN" class="bg-transparent"
:bordered="false"
/>
</div>
<!-- 扫描图标 -->
<div class="i-carbon-qr-code text-gray-300" />
</div>
</div>
</div>
</NGridItem>
</NGrid>
</div>
</template>
<style scoped>
:deep(.n-input) {
background-color: transparent;
}
:deep(.n-input__input-el) {
font-weight: bold;
color: #4b5563;
}
</style>