feat(competition): 实现比赛创建功能并集成后端API

- 新增比赛创建页面,包含基本信息、组别管理和题目配置三个步骤
- 添加 OSS 图片上传组件,支持海报上传到阿里云OSS
- 集成后端API:获取房间列表、创建活动、创建队伍和创建题目
- 优化表单数据绑定和验证逻辑,使用防抖减少频繁更新
- 修复组别管理Excel导入的数据填充问题
- 更新类型定义,添加CommonResponse和比赛相关接口类型
This commit is contained in:
2026-01-29 18:03:13 +08:00
parent 82b1dd7ebe
commit beaaee72b4
13 changed files with 493 additions and 147 deletions

View File

@ -52,6 +52,83 @@ declare namespace Api {
/** competition round type */
type CompetitionRoundType = '1' | '2' /** 题包环节 | 加时环节 */
/** room */
interface Room {
/** room id */
ID: number
/** room name */
Name: string
}
/** create room request */
interface CreateRoomRequest {
/** 活动 id */
id: number
/** 活动名称 */
name: string
/** 开始时间 */
startTime: string
/** 结束时间 */
endTime: string
/** 队伍数量 */
teams: number
/** 创建时间 */
createdTime: string
/** 房间 id */
roomID: number
/** 队伍分组数量 */
teamGroupNumber: number
/** 背景图片 */
backgroundImg: string
}
/** create team list request */
interface CreateTeamListRequest {
/** 队伍 id */
id: number
/** 主 id */
mainId: number
/** 队伍编号 */
number: string
/** 队伍名称 */
name: string
/** 笔序列号 */
penSerial: string
/** 队员名单 */
nameList: string
/** 学校名称 */
schoolName: string
/** 队伍分组 id */
teamGroupId: number
}
interface CreateQuestionRequest {
/** 题目 id */
id: number
/** 活动 id */
activityID: number
/** 问题 id */
questionID: number
/** 题目序号 */
questionIndex: number
/** 活动题目名称 */
actitvityQuestionName: string
/** 答题时间(秒) */
questionTime: number
/** 题目规则 */
questionRule: number
/** UI 类型 */
uiType: string
/** 分值 */
point: number
/** 题目副标题 */
questionSubTitle: string
/** 题目模板 id */
templateID: QuestionTemplateId
/** 赛题包类型 */
roundType: number
}
/** common record */
type CommonRecord<T = any> = {
/** record id */

View File

@ -23,6 +23,14 @@ declare namespace Api {
/** common search params of table */
type CommonSearchParams = Pick<Common.PaginatingCommonParams, 'currentPage' | 'pageSize'>
/** common response */
interface CommonResponse {
success: boolean
code: number
msg: string
data: any
}
/**
* enable status
*

View File

@ -147,6 +147,7 @@ declare module 'vue' {
NTreeSelect: typeof import('naive-ui')['NTreeSelect']
NUpload: typeof import('naive-ui')['NUpload']
NWatermark: typeof import('naive-ui')['NWatermark']
OssImageUpload: typeof import('./../components/common/oss-image-upload/index.vue')['default']
PageHeader: typeof import('./../components/common/page-header.vue')['default']
PinToggler: typeof import('./../components/common/pin-toggler.vue')['default']
ReloadButton: typeof import('./../components/common/reload-button.vue')['default']
@ -307,6 +308,7 @@ declare global {
const NTreeSelect: typeof import('naive-ui')['NTreeSelect']
const NUpload: typeof import('naive-ui')['NUpload']
const NWatermark: typeof import('naive-ui')['NWatermark']
const OssImageUpload: typeof import('./../components/common/oss-image-upload/index.vue')['default']
const PageHeader: typeof import('./../components/common/page-header.vue')['default']
const PinToggler: typeof import('./../components/common/pin-toggler.vue')['default']
const ReloadButton: typeof import('./../components/common/reload-button.vue')['default']