feat(admin): 新增题库模块并优化比赛管理功能

新增题库模块,包含题目管理页面和Excel导入导出功能
优化比赛管理功能,包括分组管理、硬件绑定和题目配置
重构比赛添加流程,增加重置功能和数据校验
添加Excel工具函数,支持读取和导出Excel文件
更新依赖,添加xlsx库支持
This commit is contained in:
2026-01-21 16:29:38 +08:00
parent 3270e24c25
commit 89773bd49b
33 changed files with 1988 additions and 496 deletions

View File

@ -15,7 +15,6 @@ declare module 'vue' {
AppProvider: typeof import('./../components/common/app-provider.vue')['default']
BetterScroll: typeof import('./../components/custom/better-scroll.vue')['default']
ButtonIcon: typeof import('./../components/custom/button-icon.vue')['default']
copy: typeof import('./../components/custom/wave-bg copy.vue')['default']
CountTo: typeof import('./../components/custom/count-to.vue')['default']
DarkModeContainer: typeof import('./../components/common/dark-mode-container.vue')['default']
ExceptionBase: typeof import('./../components/common/exception-base.vue')['default']
@ -26,23 +25,34 @@ declare module 'vue' {
IconGridiconsFullscreenExit: typeof import('~icons/gridicons/fullscreen-exit')['default']
IconIcBaselineAdd: typeof import('~icons/ic/baseline-add')['default']
IconIcBaselineArrowBack: typeof import('~icons/ic/baseline-arrow-back')['default']
IconIcBaselineCalendar: typeof import('~icons/ic/baseline-calendar')['default']
IconIcBaselineArrowForward: typeof import('~icons/ic/baseline-arrow-forward')['default']
IconIcBaselineCalendarMonth: typeof import('~icons/ic/baseline-calendar-month')['default']
IconIcBaselineCheck: typeof import('~icons/ic/baseline-check')['default']
IconIcBaselineClose: typeof import('~icons/ic/baseline-close')['default']
IconIcBaselineContentCopy: typeof import('~icons/ic/baseline-content-copy')['default']
IconIcBaselineCopy: typeof import('~icons/ic/baseline-copy')['default']
IconIcBaselineDelete: typeof import('~icons/ic/baseline-delete')['default']
IconIcBaselineDownload: typeof import('~icons/ic/baseline-download')['default']
IconIcBaselineEdit: typeof import('~icons/ic/baseline-edit')['default']
IconIcBaselineFlash: typeof import('~icons/ic/baseline-flash')['default']
IconIcBaselineGroup: typeof import('~icons/ic/baseline-group')['default']
IconIcBaselineRefresh: typeof import('~icons/ic/baseline-refresh')['default']
IconIcBaselineRocketLaunch: typeof import('~icons/ic/baseline-rocket-launch')['default']
IconIcBaselineSave: typeof import('~icons/ic/baseline-save')['default']
IconIcBaselineScan: typeof import('~icons/ic/baseline-scan')['default']
IconIcBaselineSettingsBackupRestore: typeof import('~icons/ic/baseline-settings-backup-restore')['default']
IconIcBaselineUpload: typeof import('~icons/ic/baseline-upload')['default']
IconIcBaselineUploadFile: typeof import('~icons/ic/baseline-upload-file')['default']
IconIcOutlineAccessTime: typeof import('~icons/ic/outline-access-time')['default']
IconIcOutlineAddToPhotos: typeof import('~icons/ic/outline-add-to-photos')['default']
IconIcOutlineArchive: typeof import('~icons/ic/outline-archive')['default']
IconIcOutlineDelete: typeof import('~icons/ic/outline-delete')['default']
IconIcOutlineFolderOff: typeof import('~icons/ic/outline-folder-off')['default']
IconIcOutlineFormatListNumbered: typeof import('~icons/ic/outline-format-list-numbered')['default']
IconIcOutlineTimer: typeof import('~icons/ic/outline-timer')['default']
IconIcRoundLibraryAdd: typeof import('~icons/ic/round-library-add')['default']
IconIcRoundPlus: typeof import('~icons/ic/round-plus')['default']
IconLocalActivity: typeof import('~icons/local/activity')['default']
IconIcRoundStarBorder: typeof import('~icons/ic/round-star-border')['default']
IconLocalBanner: typeof import('~icons/local/banner')['default']
IconLocalReadLogo: typeof import('~icons/local/read-logo')['default']
IconMdiArrowDownThin: typeof import('~icons/mdi/arrow-down-thin')['default']
IconMdiArrowUpThin: typeof import('~icons/mdi/arrow-up-thin')['default']
IconMdiKeyboardEsc: typeof import('~icons/mdi/keyboard-esc')['default']
@ -70,7 +80,6 @@ declare module 'vue' {
NFormItem: typeof import('naive-ui')['NFormItem']
NGi: typeof import('naive-ui')['NGi']
NGrid: typeof import('naive-ui')['NGrid']
NIcon: typeof import('naive-ui')['NIcon']
NInput: typeof import('naive-ui')['NInput']
NInputGroup: typeof import('naive-ui')['NInputGroup']
NInputNumber: typeof import('naive-ui')['NInputNumber']
@ -78,7 +87,6 @@ declare module 'vue' {
NListItem: typeof import('naive-ui')['NListItem']
NLoadingBarProvider: typeof import('naive-ui')['NLoadingBarProvider']
NMenu: typeof import('naive-ui')['NMenu']
NMessage: typeof import('naive-ui')['NMessage']
NMessageProvider: typeof import('naive-ui')['NMessageProvider']
NModal: typeof import('naive-ui')['NModal']
NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
@ -89,7 +97,6 @@ declare module 'vue' {
NSwitch: typeof import('naive-ui')['NSwitch']
NTab: typeof import('naive-ui')['NTab']
NTabs: typeof import('naive-ui')['NTabs']
NTag: typeof import('naive-ui')['NTag']
NThing: typeof import('naive-ui')['NThing']
NTooltip: typeof import('naive-ui')['NTooltip']
NWatermark: typeof import('naive-ui')['NWatermark']
@ -113,7 +120,6 @@ declare global {
const AppProvider: typeof import('./../components/common/app-provider.vue')['default']
const BetterScroll: typeof import('./../components/custom/better-scroll.vue')['default']
const ButtonIcon: typeof import('./../components/custom/button-icon.vue')['default']
const copy: typeof import('./../components/custom/wave-bg copy.vue')['default']
const CountTo: typeof import('./../components/custom/count-to.vue')['default']
const DarkModeContainer: typeof import('./../components/common/dark-mode-container.vue')['default']
const ExceptionBase: typeof import('./../components/common/exception-base.vue')['default']
@ -124,23 +130,34 @@ declare global {
const IconGridiconsFullscreenExit: typeof import('~icons/gridicons/fullscreen-exit')['default']
const IconIcBaselineAdd: typeof import('~icons/ic/baseline-add')['default']
const IconIcBaselineArrowBack: typeof import('~icons/ic/baseline-arrow-back')['default']
const IconIcBaselineCalendar: typeof import('~icons/ic/baseline-calendar')['default']
const IconIcBaselineArrowForward: typeof import('~icons/ic/baseline-arrow-forward')['default']
const IconIcBaselineCalendarMonth: typeof import('~icons/ic/baseline-calendar-month')['default']
const IconIcBaselineCheck: typeof import('~icons/ic/baseline-check')['default']
const IconIcBaselineClose: typeof import('~icons/ic/baseline-close')['default']
const IconIcBaselineContentCopy: typeof import('~icons/ic/baseline-content-copy')['default']
const IconIcBaselineCopy: typeof import('~icons/ic/baseline-copy')['default']
const IconIcBaselineDelete: typeof import('~icons/ic/baseline-delete')['default']
const IconIcBaselineDownload: typeof import('~icons/ic/baseline-download')['default']
const IconIcBaselineEdit: typeof import('~icons/ic/baseline-edit')['default']
const IconIcBaselineFlash: typeof import('~icons/ic/baseline-flash')['default']
const IconIcBaselineGroup: typeof import('~icons/ic/baseline-group')['default']
const IconIcBaselineRefresh: typeof import('~icons/ic/baseline-refresh')['default']
const IconIcBaselineRocketLaunch: typeof import('~icons/ic/baseline-rocket-launch')['default']
const IconIcBaselineSave: typeof import('~icons/ic/baseline-save')['default']
const IconIcBaselineScan: typeof import('~icons/ic/baseline-scan')['default']
const IconIcBaselineSettingsBackupRestore: typeof import('~icons/ic/baseline-settings-backup-restore')['default']
const IconIcBaselineUpload: typeof import('~icons/ic/baseline-upload')['default']
const IconIcBaselineUploadFile: typeof import('~icons/ic/baseline-upload-file')['default']
const IconIcOutlineAccessTime: typeof import('~icons/ic/outline-access-time')['default']
const IconIcOutlineAddToPhotos: typeof import('~icons/ic/outline-add-to-photos')['default']
const IconIcOutlineArchive: typeof import('~icons/ic/outline-archive')['default']
const IconIcOutlineDelete: typeof import('~icons/ic/outline-delete')['default']
const IconIcOutlineFolderOff: typeof import('~icons/ic/outline-folder-off')['default']
const IconIcOutlineFormatListNumbered: typeof import('~icons/ic/outline-format-list-numbered')['default']
const IconIcOutlineTimer: typeof import('~icons/ic/outline-timer')['default']
const IconIcRoundLibraryAdd: typeof import('~icons/ic/round-library-add')['default']
const IconIcRoundPlus: typeof import('~icons/ic/round-plus')['default']
const IconLocalActivity: typeof import('~icons/local/activity')['default']
const IconIcRoundStarBorder: typeof import('~icons/ic/round-star-border')['default']
const IconLocalBanner: typeof import('~icons/local/banner')['default']
const IconLocalReadLogo: typeof import('~icons/local/read-logo')['default']
const IconMdiArrowDownThin: typeof import('~icons/mdi/arrow-down-thin')['default']
const IconMdiArrowUpThin: typeof import('~icons/mdi/arrow-up-thin')['default']
const IconMdiKeyboardEsc: typeof import('~icons/mdi/keyboard-esc')['default']
@ -168,7 +185,6 @@ declare global {
const NFormItem: typeof import('naive-ui')['NFormItem']
const NGi: typeof import('naive-ui')['NGi']
const NGrid: typeof import('naive-ui')['NGrid']
const NIcon: typeof import('naive-ui')['NIcon']
const NInput: typeof import('naive-ui')['NInput']
const NInputGroup: typeof import('naive-ui')['NInputGroup']
const NInputNumber: typeof import('naive-ui')['NInputNumber']
@ -176,7 +192,6 @@ declare global {
const NListItem: typeof import('naive-ui')['NListItem']
const NLoadingBarProvider: typeof import('naive-ui')['NLoadingBarProvider']
const NMenu: typeof import('naive-ui')['NMenu']
const NMessage: typeof import('naive-ui')['NMessage']
const NMessageProvider: typeof import('naive-ui')['NMessageProvider']
const NModal: typeof import('naive-ui')['NModal']
const NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
@ -187,7 +202,6 @@ declare global {
const NSwitch: typeof import('naive-ui')['NSwitch']
const NTab: typeof import('naive-ui')['NTab']
const NTabs: typeof import('naive-ui')['NTabs']
const NTag: typeof import('naive-ui')['NTag']
const NThing: typeof import('naive-ui')['NThing']
const NTooltip: typeof import('naive-ui')['NTooltip']
const NWatermark: typeof import('naive-ui')['NWatermark']

View File

@ -27,6 +27,7 @@ declare module "@elegant-router/types" {
"home": "/home";
"iframe-page": "/iframe-page/:url";
"login": "/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?";
"question": "/question";
};
/**
@ -65,6 +66,7 @@ declare module "@elegant-router/types" {
| "home"
| "iframe-page"
| "login"
| "question"
>;
/**
@ -90,6 +92,7 @@ declare module "@elegant-router/types" {
| "competition_competition-detail"
| "competition_competition-list"
| "home"
| "question"
>;
/**