diff --git a/apps/admin/src/assets/imgs/user/rank-title.svg b/apps/admin/src/assets/imgs/user/rank-title.svg new file mode 100644 index 0000000..f0cca8f --- /dev/null +++ b/apps/admin/src/assets/imgs/user/rank-title.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/admin/src/enum/business.ts b/apps/admin/src/enum/business.ts index 147dee4..fdd3069 100644 --- a/apps/admin/src/enum/business.ts +++ b/apps/admin/src/enum/business.ts @@ -5,6 +5,11 @@ export enum PublishStatus { Finished = 3, } +export enum RankPublishStatus { + Unpublished = 0, + Published = 1, +} + export enum QuestionType { SingleChoice = 'SingleChoice', // 单选题 MultipleChoice = 'MultipleChoice', // 多选题 diff --git a/apps/admin/src/locales/langs/en-us.ts b/apps/admin/src/locales/langs/en-us.ts index 91e088a..1a46487 100644 --- a/apps/admin/src/locales/langs/en-us.ts +++ b/apps/admin/src/locales/langs/en-us.ts @@ -258,6 +258,7 @@ const local: App.I18n.Schema = { 'results_results-list': 'Results List', 'results_results-detail': 'Results Detail', 'test': 'Test', + 'user_rank-list': 'User Rank List', }, page: { login: { diff --git a/apps/admin/src/locales/langs/zh-cn.ts b/apps/admin/src/locales/langs/zh-cn.ts index 587564c..390119d 100644 --- a/apps/admin/src/locales/langs/zh-cn.ts +++ b/apps/admin/src/locales/langs/zh-cn.ts @@ -254,6 +254,7 @@ const local: App.I18n.Schema = { 'results_results-list': '实时结果列表', 'results_results-detail': '实时结果详情', 'test': 'Test', + 'user_rank-list': '用户排名列表', }, page: { login: { diff --git a/apps/admin/src/router/elegant/imports.ts b/apps/admin/src/router/elegant/imports.ts index d59d57f..e773372 100644 --- a/apps/admin/src/router/elegant/imports.ts +++ b/apps/admin/src/router/elegant/imports.ts @@ -28,7 +28,6 @@ export const views: Record Promise import("@/views/question-store/index.vue"), "rank_rank-detail": () => import("@/views/rank/rank-detail/index.vue"), "rank_rank-list": () => import("@/views/rank/rank-list/index.vue"), - "results_results-detail-copy": () => import("@/views/results/results-detail-copy/index.vue"), "results_results-detail": () => import("@/views/results/results-detail/index.vue"), "results_results-list": () => import("@/views/results/results-list/index.vue"), "template_template-detail": () => import("@/views/template/template-detail/index.vue"), @@ -40,6 +39,8 @@ export const views: Record Promise import("@/views/user/game/index.vue"), user_groups: () => import("@/views/user/groups/index.vue"), user_home: () => import("@/views/user/home/index.vue"), + "user_rank-list": () => import("@/views/user/rank-list/index.vue"), + "user_rank-pending": () => import("@/views/user/rank-pending/index.vue"), user_rules: () => import("@/views/user/rules/index.vue"), user_teams: () => import("@/views/user/teams/index.vue"), }; diff --git a/apps/admin/src/router/elegant/routes.ts b/apps/admin/src/router/elegant/routes.ts index cfc16fa..d607f59 100644 --- a/apps/admin/src/router/elegant/routes.ts +++ b/apps/admin/src/router/elegant/routes.ts @@ -197,16 +197,6 @@ export const generatedRoutes: GeneratedRoute[] = [ hideInMenu: true } }, - { - name: 'results_results-detail-copy', - path: '/results/results-detail-copy', - component: 'view.results_results-detail-copy', - meta: { - title: 'results_results-detail-copy', - i18nKey: 'route.results_results-detail-copy', - hideInMenu: true - } - }, { name: 'results_results-list', path: '/results/results-list', @@ -341,6 +331,24 @@ export const generatedRoutes: GeneratedRoute[] = [ constant: true } }, + { + name: 'user_rank-list', + path: '/user/rank-list', + component: 'view.user_rank-list', + meta: { + title: 'user_rank-list', + i18nKey: 'route.user_rank-list' + } + }, + { + name: 'user_rank-pending', + path: '/user/rank-pending', + component: 'view.user_rank-pending', + meta: { + title: 'user_rank-pending', + i18nKey: 'route.user_rank-pending' + } + }, { name: 'user_rules', path: '/user/rules', diff --git a/apps/admin/src/router/elegant/transform.ts b/apps/admin/src/router/elegant/transform.ts index 4905f8b..e6627b5 100644 --- a/apps/admin/src/router/elegant/transform.ts +++ b/apps/admin/src/router/elegant/transform.ts @@ -180,7 +180,6 @@ const routeMap: RouteMap = { "rank_rank-list": "/rank/rank-list", "results": "/results", "results_results-detail": "/results/results-detail", - "results_results-detail-copy": "/results/results-detail-copy", "results_results-list": "/results/results-list", "template": "/template", "template_template-detail": "/template/template-detail", @@ -193,6 +192,8 @@ const routeMap: RouteMap = { "user_game": "/user/game", "user_groups": "/user/groups", "user_home": "/user/home", + "user_rank-list": "/user/rank-list", + "user_rank-pending": "/user/rank-pending", "user_rules": "/user/rules", "user_teams": "/user/teams" }; diff --git a/apps/admin/src/service/api/rank.ts b/apps/admin/src/service/api/rank.ts index b3c5401..dd79a6e 100644 --- a/apps/admin/src/service/api/rank.ts +++ b/apps/admin/src/service/api/rank.ts @@ -23,3 +23,40 @@ export function fetchTeamQuestionScore(TeamID: number) { method: 'get', }) } + +/** 获取活动排行列表 */ +export function fetchActivityRankList(PageIndex: number, PageSize: number = 10) { + return request>({ + url: `/Base/ActivityMain/GetActivity_Main_TotalPager?PageIndex=${PageIndex}&PageSizes=${PageSize}`, + method: 'get', + }) +} + +/** 修改排名的队伍分数 */ +export function updateTeamScore(data: Api.Rank.UpdateTeamScoreParams[], activityId: number) { + return request({ + url: `/Base/ActivityMain/UpdateTeamQuestionResultRecore/?ActivityID=${activityId}`, + method: 'post', + data, + }) +} + +/** 发布排名,更新状态 */ +export function publishRank(Id: number, Status = 1) { + return request({ + url: `/Base/ActivityMain/UpdateResultRecoreStatus`, + method: 'post', + data: { + Id, + Status, + }, + }) +} + +/** 获取用户排名列表 */ +export function fetchUserRankList(MainID: number, RoundType: number = 0) { + return request>({ + url: `/Base/ActivityMain/GetTeamsTotalList?MainID=${MainID}&RoundType=${RoundType}`, + method: 'get', + }) +} diff --git a/apps/admin/src/service/api/result.ts b/apps/admin/src/service/api/result.ts index 52ffe83..24a1b83 100644 --- a/apps/admin/src/service/api/result.ts +++ b/apps/admin/src/service/api/result.ts @@ -17,3 +17,12 @@ export function updateScore(data: { Id: number, ResultPotins: number, QuestionDe data, }) } + +/** 结束活动时候调用 */ +export function endActivity(ActivityID: number) { + return request({ + url: `/Base/ActivityMain/AddOrUpdateActivity_Main_Total?ActivityID=${ActivityID}`, + method: 'post', + data: { ActivityID }, + }) +} diff --git a/apps/admin/src/typings/api/rank.d.ts b/apps/admin/src/typings/api/rank.d.ts index ed2b8e9..5496596 100644 --- a/apps/admin/src/typings/api/rank.d.ts +++ b/apps/admin/src/typings/api/rank.d.ts @@ -31,6 +31,57 @@ declare namespace Api { /** common search params of table */ type CommonSearchParams = Pick + interface ActivityRankResList extends Array {} + + interface ActivityRankItem { + TeamID: number + Name: string + TotalPoint: number + Questions: QuestionScore[] + } + + interface QuestionScore { + QuestionNO: number + ResultPotin: number + } + + interface ActivityRankList { + Items: ActivityRank[] + TotalRecords: number + PageNumber: number + PageSize: number + TotalPages: number + } + + interface UpdateTeamScoreParams { + /** 主活动 ID */ + ActivityID: number + + Id: number + /** 结果得分 */ + ResultPotins: number + } + + /** activity rank */ + interface ActivityRank { + /** activity id */ + Id: number + /** activity id (MainID) */ + ActivityId: number + /** activity name */ + ActivityName: string + /** start time */ + StartTime: string + /** team number */ + TeamNum: number + /** max point */ + MaxPoint: number + /** last update time */ + LastUpdatetime: string + /** is publish */ + Status: number + } + /** * enable status * diff --git a/apps/admin/src/typings/components.d.ts b/apps/admin/src/typings/components.d.ts index e1b160d..c55fc50 100644 --- a/apps/admin/src/typings/components.d.ts +++ b/apps/admin/src/typings/components.d.ts @@ -28,6 +28,7 @@ declare module 'vue' { 'IconIc:baselineArrowRightAlt': typeof import('~icons/ic/baseline-arrow-right-alt')['default'] 'IconIc:baselineDeleteForever': typeof import('~icons/ic/baseline-delete-forever')['default'] 'IconIc:roundPublish': typeof import('~icons/ic/round-publish')['default'] + 'IconIc:roundStopCircle': typeof import('~icons/ic/round-stop-circle')['default'] 'IconIc:twotoneRule': typeof import('~icons/ic/twotone-rule')['default'] IconIcBaselineAdd: typeof import('~icons/ic/baseline-add')['default'] IconIcBaselineAddPlus: typeof import('~icons/ic/baseline-add-plus')['default'] @@ -201,6 +202,7 @@ declare global { const 'IconIc:baselineArrowRightAlt': typeof import('~icons/ic/baseline-arrow-right-alt')['default'] const 'IconIc:baselineDeleteForever': typeof import('~icons/ic/baseline-delete-forever')['default'] const 'IconIc:roundPublish': typeof import('~icons/ic/round-publish')['default'] + const 'IconIc:roundStopCircle': typeof import('~icons/ic/round-stop-circle')['default'] const 'IconIc:twotoneRule': typeof import('~icons/ic/twotone-rule')['default'] const IconIcBaselineAdd: typeof import('~icons/ic/baseline-add')['default'] const IconIcBaselineAddPlus: typeof import('~icons/ic/baseline-add-plus')['default'] diff --git a/apps/admin/src/typings/elegant-router.d.ts b/apps/admin/src/typings/elegant-router.d.ts index e8047fb..fd58133 100644 --- a/apps/admin/src/typings/elegant-router.d.ts +++ b/apps/admin/src/typings/elegant-router.d.ts @@ -34,7 +34,6 @@ declare module "@elegant-router/types" { "rank_rank-list": "/rank/rank-list"; "results": "/results"; "results_results-detail": "/results/results-detail"; - "results_results-detail-copy": "/results/results-detail-copy"; "results_results-list": "/results/results-list"; "template": "/template"; "template_template-detail": "/template/template-detail"; @@ -47,6 +46,8 @@ declare module "@elegant-router/types" { "user_game": "/user/game"; "user_groups": "/user/groups"; "user_home": "/user/home"; + "user_rank-list": "/user/rank-list"; + "user_rank-pending": "/user/rank-pending"; "user_rules": "/user/rules"; "user_teams": "/user/teams"; }; @@ -123,7 +124,6 @@ declare module "@elegant-router/types" { | "question-store" | "rank_rank-detail" | "rank_rank-list" - | "results_results-detail-copy" | "results_results-detail" | "results_results-list" | "template_template-detail" @@ -135,6 +135,8 @@ declare module "@elegant-router/types" { | "user_game" | "user_groups" | "user_home" + | "user_rank-list" + | "user_rank-pending" | "user_rules" | "user_teams" >; diff --git a/apps/admin/src/views/competition/competition-list/index.vue b/apps/admin/src/views/competition/competition-list/index.vue index ecbc4cb..98f4b05 100644 --- a/apps/admin/src/views/competition/competition-list/index.vue +++ b/apps/admin/src/views/competition/competition-list/index.vue @@ -3,6 +3,7 @@ import { NButton, NGi, NGrid, NSpace } from 'naive-ui' import { computed, onMounted, ref } from 'vue' import { useRouterPush } from '@/hooks/common/router' import { fetchCopyActivity, fetchDeleteActivity, fetchGetActivityList } from '@/service/api/competition' +import { endActivity } from '@/service/api/result' import { useAppStore } from '@/store/modules/app' import CompetitionAddModal from '../competition-add/index.vue' @@ -94,6 +95,39 @@ function toDetail(item: Api.Competition.CompetitionItem) { routerPushByKey('competition_competition-detail', { query: { Id: item.Id.toString() } }) } +async function handleCloseActivity(item: Api.Competition.CompetitionItem) { + const d = window.$dialog?.warning({ + title: '确认结束', + content: `确定结束活动:${item.Name}吗?结束活动后将生成排行榜数据。`, + positiveText: '确认结束', + negativeText: '取消', + onPositiveClick: async () => { + if (d) { + d.loading = true + } + try { + const { error } = await endActivity(item.Id) + if (error) { + window.$message?.error(error.message || '结束活动失败') + return false + } + window.$message?.success(`已结束活动:${item.Name}`) + fetchActivityList() + return true + } + catch (e: any) { + window.$message?.error(e.message || '操作失败') + return false + } + finally { + if (d) { + d.loading = false + } + } + }, + }) +} + onMounted(() => fetchActivityList()) @@ -122,7 +156,7 @@ onMounted(() => fetchActivityList()) - + diff --git a/apps/admin/src/views/competition/competition-list/modules/competition-card.vue b/apps/admin/src/views/competition/competition-list/modules/competition-card.vue index defb615..3b66f84 100644 --- a/apps/admin/src/views/competition/competition-list/modules/competition-card.vue +++ b/apps/admin/src/views/competition/competition-list/modules/competition-card.vue @@ -10,6 +10,7 @@ const props = defineProps() const emit = defineEmits<{ (e: 'copy', item: Api.Competition.CompetitionItem): void (e: 'delete', item: Api.Competition.CompetitionItem): void + (e: 'close', item: Api.Competition.CompetitionItem): void }>() const { options: publishStatusOptions } = useDict('publish_status') @@ -83,6 +84,20 @@ const decorationBgClass = computed(() => {
+ + + 结束活动 + + - - diff --git a/apps/admin/src/views/results/results-detail-copy/modules/GroupTabs.vue b/apps/admin/src/views/results/results-detail-copy/modules/GroupTabs.vue deleted file mode 100644 index e6cd0cb..0000000 --- a/apps/admin/src/views/results/results-detail-copy/modules/GroupTabs.vue +++ /dev/null @@ -1,45 +0,0 @@ - - - - - diff --git a/apps/admin/src/views/results/results-detail-copy/modules/TeamResultCard.vue b/apps/admin/src/views/results/results-detail-copy/modules/TeamResultCard.vue deleted file mode 100644 index a2f85b6..0000000 --- a/apps/admin/src/views/results/results-detail-copy/modules/TeamResultCard.vue +++ /dev/null @@ -1,114 +0,0 @@ - - - - - diff --git a/apps/admin/src/views/user/analysis/index.vue b/apps/admin/src/views/user/analysis/index.vue index fb52913..65fda6f 100644 --- a/apps/admin/src/views/user/analysis/index.vue +++ b/apps/admin/src/views/user/analysis/index.vue @@ -136,9 +136,9 @@ async function fetchGetGameStatisticsData() { } // 定时刷新 检查是否可以下一步 -timer.value = setInterval(checkNextStep, 2000) +timer.value = setInterval(checkNextStep, 3000) // 定时刷新 游戏统计数据 -statisticsTimer.value = setInterval(fetchGetGameStatisticsData, 2000) +statisticsTimer.value = setInterval(fetchGetGameStatisticsData, 3000) /** 销毁 定时刷新 检查是否可以下一步 */ onBeforeUnmount(() => { diff --git a/apps/admin/src/views/user/cover/index.vue b/apps/admin/src/views/user/cover/index.vue index 3e296ed..12e607b 100644 --- a/apps/admin/src/views/user/cover/index.vue +++ b/apps/admin/src/views/user/cover/index.vue @@ -2,7 +2,9 @@ import { computed, onMounted, ref } from 'vue' import { useRoute } from 'vue-router' import CompetitionLayout from '@/components/custom/user/CompetitionLayout.vue' +import { PublishStatus } from '@/enum/business' import { useRouterPush } from '@/hooks/common/router' +import { fetchUpdatePublishStatus } from '@/service/api/competition' import { fetchGetQuestionTableByActivityID } from '@/service/api/game' import { useActivityInfoStore } from '@/store/modules/activityinfo' import { AudioController } from '@/utils/audio' @@ -93,7 +95,20 @@ function handleBack() { routerBack() } -function handleNext() { +async function handleNext() { + // 封面页的下一步操作,更改活动状态 + // 判断状态是否为已发布或处理中,若已发布或处理中则不能更改状态 + if (activityInfo.value?.PublishStatus === PublishStatus.Published || activityInfo.value?.PublishStatus === PublishStatus.Processing) { + if (activityId.value) { + try { + await fetchUpdatePublishStatus(Number(activityId.value), PublishStatus.Processing) + } + catch (error) { + console.error('更新活动状态失败', error) + } + } + } + routerPushByKey('user_rules', { query: { activityId: activityId.value, @@ -143,24 +158,20 @@ onMounted(async () => {