feat(admin): 新增活动管理功能并优化字典组件

- 新增活动管理相关功能,包括活动创建、编辑、删除和状态管理
- 新增 PublishStatus 枚举定义活动发布状态
- 优化字典组件,支持字符串和数字类型的字典值
- 重构业务数据存储逻辑,简化字典数据获取流程
- 新增活动详情页面,支持分组管理和队伍配置
- 集成富文本编辑器用于活动规则编辑
- 优化图片上传组件,支持小图上传模式
- 修复模板管理中的区域选择和分页问题
- 更新 TypeScript 类型定义,完善 API 接口
- 调整主题配置,新增活动状态相关颜色
This commit is contained in:
2026-02-04 18:01:52 +08:00
parent e1a19c48e0
commit ce5ee2a289
39 changed files with 2621 additions and 693 deletions

View File

@ -29,10 +29,10 @@ declare namespace Api {
* - "1": enabled
* - "2": disabled
*/
type EnableStatus = '1' | '2'
type EnableStatus = 1 | 2
/** question ui type */
type QuestionUiType = '1' | '2' | '3' | '4' /** 文本输入 | 单选 | 多选 | 下拉选择 */
type QuestionUiType = 1 | 2 | 3 | 4 /** 文本输入 | 单选 | 多选 | 下拉选择 */
/** question time type */
type QuestionTimeType = 5 | 10 | 15 | 20 | 30 | 45 | 60 | 90 /** 5s | 10s | 15s | 20s | 30s | 45s | 60s | 90s */
@ -47,10 +47,25 @@ declare namespace Api {
| 'TEMPLATE_IDIOM_IMAGE' /** 汉字听写-提示 | 汉字听写-同音 | 汉字加一加 | 词语听写 | 成语-文字要求 | 成语-看图 */
/** question score type */
type QuestionScoreType = '1' | '2' /** 固定分数 | 答题个数 */
type QuestionScoreType = 0 | 1 /** 固定分数 | 答题个数 */
/** competition round type */
type CompetitionRoundType = '1' | '2' /** 题包环节 | 加时环节 */
type CompetitionRoundType = 0 | 1 /** 题包环节 | 加时环节 */
/**
* competition publish status
*
* - 0: unpublished
* - 1: published
* - 2: processing
* - 3: finished
*/
enum PublishStatus {
Unpublished = 0,
Published = 1,
Processing = 2,
Finished = 3,
}
/** room */
interface Room {
@ -60,6 +75,36 @@ declare namespace Api {
Name: string
}
/** activity detail */
interface ActivityDetail {
/** 背景图片 */
BackgroundImg: string
/** 创建时间 */
CreatedTime: string
/** 结束时间 */
EndTime: string
/** 活动 id */
Id: number
/** 活动名称 */
Name: string
/** 发布状态 */
PublishStatus: number
/** 房间 id */
RoomID: number
/** 开始时间 */
StartTime: string
/** 队伍分组数量 */
TeamGroupNumber: number
/** 队伍数量 */
Teams: number
/** 活动副标题 */
ActivityTitle?: string
/** 普通赛事规则 */
ActivityContent?: string
/** 加时赛规则 */
ExtraTimeContent?: string
}
/** create room request */
interface CreateRoomRequest {
/** 活动 id */
@ -82,6 +127,28 @@ declare namespace Api {
backgroundImg: string
}
/** update room request */
interface UpdateRoomRequest {
/** 活动 id */
id: number
/** 活动名称 */
name: string
/** 开始时间 */
startTime: string
/** 结束时间 */
endTime: string
/** 队伍数量 */
teams: number
/** 队伍分组数量 */
teamGroupNumber: number
/** 活动副标题 */
activityTitle?: string
/** 普通赛事规则 */
activityContent?: string
/** 加时赛规则 */
extraTimeContent?: string
}
/** create team list request */
interface CreateTeamListRequest {
/** 队伍 id */
@ -100,6 +167,56 @@ declare namespace Api {
schoolName: string
/** 队伍分组 id */
teamGroupId: number
/** 队伍头像 */
headImg?: string
}
interface TeamListRecord {
/** 队伍 id */
Id: number
/** 主 id */
MainId: number
/** 队伍编号 */
Number: string
/** 队伍名称 */
Name: string
/** 笔序列号 */
PenSerial: string
/** 队员名单 */
NameList: string
/** 学校名称 */
SchoolName: string
/** 队伍分组 id */
TeamGroupId: number
/** 队伍头像 */
HeadImg?: string
}
interface QuestionListRecord {
/** 活动题目名称 */
ActitvityQuestionName: string
/** 活动 id */
ActivityID: number
/** 主键 id */
ID: number
/** 分值 */
Point: number
/** 题目 id */
QuestionID: number
/** 题目序号 */
QuestionIndex: number
/** 题目规则 */
QuestionRule: number
/** 题目副标题 */
QuestionSubTitle: string
/** 答题时间(秒) */
QuestionTime: number
/** 赛题包类型 */
RoundType: number
/** 题目模板 id */
TemplateID: number
/** UI 类型 */
UIType: QuestionTemplateId
}
interface CreateQuestionRequest {
@ -124,7 +241,7 @@ declare namespace Api {
/** 题目副标题 */
questionSubTitle: string
/** 题目模板 id */
templateID: QuestionTemplateId
templateID: number
/** 赛题包类型 */
roundType: number
}

View File

@ -140,6 +140,10 @@ declare namespace App {
success: string
warning: string
error: string
unpublished: string
published: string
processing: string
finished: string
}
interface ThemeColor extends OtherColor {

View File

@ -24,6 +24,8 @@ declare module 'vue' {
IconAntDesignSettingOutlined: typeof import('~icons/ant-design/setting-outlined')['default']
IconGridiconsFullscreen: typeof import('~icons/gridicons/fullscreen')['default']
IconGridiconsFullscreenExit: typeof import('~icons/gridicons/fullscreen-exit')['default']
'IconIc:baselineDeleteForever': typeof import('~icons/ic/baseline-delete-forever')['default']
'IconIc:roundPublish': typeof import('~icons/ic/round-publish')['default']
IconIcBaselineAdd: typeof import('~icons/ic/baseline-add')['default']
IconIcBaselineAddPlus: typeof import('~icons/ic/baseline-add-plus')['default']
IconIcBaselineArrowBack: typeof import('~icons/ic/baseline-arrow-back')['default']
@ -185,6 +187,8 @@ declare global {
const IconAntDesignSettingOutlined: typeof import('~icons/ant-design/setting-outlined')['default']
const IconGridiconsFullscreen: typeof import('~icons/gridicons/fullscreen')['default']
const IconGridiconsFullscreenExit: typeof import('~icons/gridicons/fullscreen-exit')['default']
const 'IconIc:baselineDeleteForever': typeof import('~icons/ic/baseline-delete-forever')['default']
const 'IconIc:roundPublish': typeof import('~icons/ic/round-publish')['default']
const IconIcBaselineAdd: typeof import('~icons/ic/baseline-add')['default']
const IconIcBaselineAddPlus: typeof import('~icons/ic/baseline-add-plus')['default']
const IconIcBaselineArrowBack: typeof import('~icons/ic/baseline-arrow-back')['default']

View File

@ -0,0 +1,8 @@
declare module '@wangeditor/editor-for-vue' {
import type { DefineComponent } from 'vue'
const Editor: DefineComponent<Record<string, any>, Record<string, any>, any>
const Toolbar: DefineComponent<Record<string, any>, Record<string, any>, any>
export { Editor, Toolbar }
}