feat(results): 新增实时结果列表和详情页面,支持评委查看和评分
- 添加 results_results-list 和 results_results-detail 路由及页面 - 实现比赛列表展示,支持跳转到实时结果详情 - 在结果详情页面添加分组和题目切换功能 - 集成游戏统计 API,实时获取队伍答题数据 - 添加 TeamResultCard 和 GroupTabs 可复用组件 - 更新国际化配置和类型定义
This commit is contained in:
@ -150,14 +150,14 @@ async function submitForm() {
|
||||
activityID: 0,
|
||||
questionID: question.QuestionID,
|
||||
questionIndex: index,
|
||||
actitvityQuestionName: question.ActitvityQuestionName,
|
||||
actitvityQuestionName: question.ActitvityQuestionName || '',
|
||||
questionTime: question.QuestionTime,
|
||||
questionRule: question.QuestionRule,
|
||||
uiType: question.UIType,
|
||||
point: question.Point,
|
||||
templateID: question.TemplateID,
|
||||
roundType: round.roundType,
|
||||
questionSubTitle: question.ActitvityQuestionName,
|
||||
questionSubTitle: question.ActitvityQuestionName || '',
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -1,25 +1,19 @@
|
||||
<script setup lang="ts">
|
||||
// import type { CompetitionItem } from './modules/data'
|
||||
import { NButton, NGi, NGrid, NSpace } from 'naive-ui'
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { useRouterPush } from '@/hooks/common/router'
|
||||
import { fetchDeleteActivity, fetchGetActivityList } from '@/service/api/competition'
|
||||
import { useAppStore } from '@/store/modules/app'
|
||||
import CompetitionAddModal from '../competition-add/index.vue'
|
||||
|
||||
import CompetitionCard from './modules/competition-card.vue'
|
||||
|
||||
export interface CompetitionItem {
|
||||
Id: number
|
||||
Name: string
|
||||
StartTime: string
|
||||
EndTime: string
|
||||
TeamGroupNumber: number
|
||||
PublishStatus: number
|
||||
}
|
||||
const { routerPushByKey } = useRouterPush()
|
||||
|
||||
const appStore = useAppStore()
|
||||
const gap = computed(() => (appStore.isMobile ? 12 : 26))
|
||||
|
||||
const competitionListRef = ref<CompetitionItem[]>([])
|
||||
const competitionListRef = ref<Api.Competition.CompetitionItem[]>([])
|
||||
|
||||
const showAddModal = ref(false)
|
||||
|
||||
@ -27,12 +21,12 @@ function handleAdd() {
|
||||
showAddModal.value = true
|
||||
}
|
||||
|
||||
function handleCopy(item: CompetitionItem) {
|
||||
function handleCopy(item: Api.Competition.CompetitionItem) {
|
||||
// TODO: 实现复制逻辑
|
||||
window.$message?.success(`已复制活动:${item.Name}`)
|
||||
}
|
||||
|
||||
function handleDelete(item: CompetitionItem) {
|
||||
function handleDelete(item: Api.Competition.CompetitionItem) {
|
||||
const d = window.$dialog?.warning({
|
||||
title: '确认删除',
|
||||
content: `确定删除活动:${item.Name}吗?`,
|
||||
@ -82,6 +76,10 @@ async function fetchActivityList() {
|
||||
}
|
||||
}
|
||||
|
||||
function toDetail(item: Api.Competition.CompetitionItem) {
|
||||
routerPushByKey('competition_competition-detail', { query: { Id: item.Id.toString() } })
|
||||
}
|
||||
|
||||
onMounted(() => fetchActivityList())
|
||||
</script>
|
||||
|
||||
@ -109,7 +107,7 @@ onMounted(() => fetchActivityList())
|
||||
<!-- 卡片列表区域 -->
|
||||
<!-- 响应式布局:手机1列,平板2列,中屏3列,大屏4列 -->
|
||||
<NGrid :x-gap="gap" :y-gap="gap" responsive="screen" item-responsive>
|
||||
<NGi v-for="item in competitionListRef" :key="item.Id" span="24 s:12 m:8 l:6">
|
||||
<NGi v-for="item in competitionListRef" :key="item.Id" span="24 s:12 m:8 l:6" @click="toDetail(item)">
|
||||
<CompetitionCard :item="item" @copy="handleCopy" @delete="handleDelete" />
|
||||
</NGi>
|
||||
</NGrid>
|
||||
|
||||
@ -1,24 +1,21 @@
|
||||
<script setup lang="ts">
|
||||
import type { CompetitionItem } from '../index.vue'
|
||||
import dayjs from 'dayjs'
|
||||
import { NButton, NCard, NTag, NTooltip } from 'naive-ui'
|
||||
import { computed } from 'vue'
|
||||
import { PublishStatus } from '@/enum/business'
|
||||
import { useDict } from '@/hooks/business/useDict'
|
||||
import { useRouterPush } from '@/hooks/common/router'
|
||||
|
||||
const props = defineProps<Props>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'copy', item: CompetitionItem): void
|
||||
(e: 'delete', item: CompetitionItem): void
|
||||
(e: 'copy', item: Api.Competition.CompetitionItem): void
|
||||
(e: 'delete', item: Api.Competition.CompetitionItem): void
|
||||
}>()
|
||||
|
||||
const { options: publishStatusOptions } = useDict('publish_status')
|
||||
|
||||
const { routerPushByKey } = useRouterPush()
|
||||
|
||||
interface Props {
|
||||
item: CompetitionItem
|
||||
item: Api.Competition.CompetitionItem
|
||||
}
|
||||
|
||||
// 状态配置:颜色和文本
|
||||
@ -43,10 +40,6 @@ const statusConfig = computed(() => {
|
||||
// 处理标题换行
|
||||
// const formattedTitle = computed(() => props.item.title.replace(/\n/g, '<br/>'))
|
||||
|
||||
function toDetail(item: CompetitionItem) {
|
||||
routerPushByKey('competition_competition-detail', { query: { Id: item.Id.toString() } })
|
||||
}
|
||||
|
||||
// 随机背景色池
|
||||
const bgColors = [
|
||||
'bg-blue-50/80',
|
||||
@ -78,7 +71,7 @@ const decorationBgClass = computed(() => {
|
||||
<NCard
|
||||
:bordered="false"
|
||||
class="group relative h-full overflow-hidden border border-transparent rounded-2xl transition-all duration-300 hover:scale-[1.02] hover:border-blue-500 hover:shadow-xl hover:-translate-y-2"
|
||||
content-style="padding: 34px; display: flex; flex-direction: column; height: 100%;" @click="toDetail(item)"
|
||||
content-style="padding: 34px; display: flex; flex-direction: column; height: 100%;"
|
||||
>
|
||||
<!-- 特殊背景装饰 (所有卡片显示,随机颜色) -->
|
||||
<div
|
||||
@ -138,7 +131,7 @@ const decorationBgClass = computed(() => {
|
||||
<!-- 日期 -->
|
||||
<div class="mb-6 flex items-center text-gray-400">
|
||||
<icon-ic-baseline-calendar-month class="mr-2 text-xl" />
|
||||
<span class="text-base font-bold">{{ item.StartTime }} ~ {{ item.EndTime }}</span>
|
||||
<span class="text-base font-bold">{{ dayjs(item.StartTime).format('YYYY-MM-DD HH:mm') }} ~ {{ dayjs(item.EndTime).format('YYYY-MM-DD HH:mm') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user