diff --git a/backend-java/src/main/java/com/competition/modules/pub/controller/PublicActivityController.java b/backend-java/src/main/java/com/competition/modules/pub/controller/PublicActivityController.java index 78ea446..e2c60d6 100644 --- a/backend-java/src/main/java/com/competition/modules/pub/controller/PublicActivityController.java +++ b/backend-java/src/main/java/com/competition/modules/pub/controller/PublicActivityController.java @@ -44,7 +44,7 @@ public class PublicActivityController { @GetMapping("/{id}/my-registration") @Operation(summary = "查询我的报名信息") - public Result getMyRegistration(@PathVariable Long id) { + public Result> getMyRegistration(@PathVariable Long id) { Long userId = SecurityUtil.getCurrentUserId(); return Result.success(publicActivityService.getMyRegistration(id, userId)); } diff --git a/backend-java/src/main/java/com/competition/modules/pub/service/PublicActivityService.java b/backend-java/src/main/java/com/competition/modules/pub/service/PublicActivityService.java index 78a619f..421819a 100644 --- a/backend-java/src/main/java/com/competition/modules/pub/service/PublicActivityService.java +++ b/backend-java/src/main/java/com/competition/modules/pub/service/PublicActivityService.java @@ -64,6 +64,7 @@ public class PublicActivityService { result.put("contestType", contest.getContestType()); result.put("contestState", contest.getContestState()); result.put("status", contest.getStatus()); + result.put("visibility", contest.getVisibility()); result.put("startTime", contest.getStartTime()); result.put("endTime", contest.getEndTime()); result.put("coverUrl", contest.getCoverUrl()); @@ -81,6 +82,8 @@ public class PublicActivityService { result.put("registerState", contest.getRegisterState()); result.put("submitStartTime", contest.getSubmitStartTime()); result.put("submitEndTime", contest.getSubmitEndTime()); + result.put("reviewStartTime", contest.getReviewStartTime()); + result.put("reviewEndTime", contest.getReviewEndTime()); result.put("workType", contest.getWorkType()); result.put("workRequirement", contest.getWorkRequirement()); result.put("resultState", contest.getResultState()); @@ -89,14 +92,35 @@ public class PublicActivityService { } /** - * 查询当前用户的报名信息 + * 查询当前用户的报名信息(包含作品提交状态) */ - public BizContestRegistration getMyRegistration(Long contestId, Long userId) { - return contestRegistrationMapper.selectOne( + public Map getMyRegistration(Long contestId, Long userId) { + BizContestRegistration reg = contestRegistrationMapper.selectOne( new LambdaQueryWrapper() .eq(BizContestRegistration::getContestId, contestId) .eq(BizContestRegistration::getUserId, userId) .last("LIMIT 1")); + + if (reg == null) { + return null; + } + + Map result = new LinkedHashMap<>(); + result.put("id", reg.getId()); + result.put("contestId", reg.getContestId()); + result.put("userId", reg.getUserId()); + result.put("registrationType", reg.getRegistrationType()); + result.put("registrationState", reg.getRegistrationState()); + result.put("registrationTime", reg.getRegistrationTime()); + + // 查询是否已提交作品 + Long workCount = contestWorkMapper.selectCount( + new LambdaQueryWrapper() + .eq(BizContestWork::getRegistrationId, reg.getId())); + result.put("hasSubmittedWork", workCount > 0); + result.put("workCount", workCount); + + return result; } /** diff --git a/frontend/src/api/public.ts b/frontend/src/api/public.ts index 826f91a..03b982d 100644 --- a/frontend/src/api/public.ts +++ b/frontend/src/api/public.ts @@ -17,7 +17,14 @@ publicApi.interceptors.request.use((config) => { // 响应拦截器 publicApi.interceptors.response.use( - (response) => response.data?.data ?? response.data, + (response) => { + // 后端返回格式:{ code: 200, message: "success", data: xxx } + // 当 data 为 null 时,直接返回 null + if (response.data) { + return response.data.data !== undefined ? response.data.data : response.data + } + return response.data + }, (error) => { if (error.response?.status === 401) { localStorage.removeItem("public_token") @@ -207,8 +214,22 @@ export interface PublicActivity { registerEndTime: string submitStartTime: string submitEndTime: string + reviewStartTime: string + reviewEndTime: string organizers: any visibility: string + resultState: string + resultPublishTime: string | null + content: string + address: string | null + contactName: string | null + contactPhone: string | null + contactQrcode: string | null + coOrganizers: any + sponsors: any + registerState: string + workType: string + workRequirement: string } export const publicActivitiesApi = { @@ -228,7 +249,16 @@ export const publicActivitiesApi = { ) => publicApi.post(`/public/activities/${id}/register`, data), getMyRegistration: (id: number) => - publicApi.get(`/public/activities/${id}/my-registration`), + publicApi.get<{ + id: number + contestId: number + userId: number + registrationType: string + registrationState: string + registrationTime: string + hasSubmittedWork: boolean + workCount: number + } | null>(`/public/activities/${id}/my-registration`), submitWork: ( id: number, diff --git a/frontend/src/views/public/ActivityDetail.vue b/frontend/src/views/public/ActivityDetail.vue index 8394af4..18ba866 100644 --- a/frontend/src/views/public/ActivityDetail.vue +++ b/frontend/src/views/public/ActivityDetail.vue @@ -51,27 +51,33 @@ 立即报名 - 已报名,等待提交阶段 + 已报名 @@ -84,7 +90,7 @@ @@ -285,13 +291,17 @@ const checkRegistrationStatus = async () => { if (!isLoggedIn.value || !activity.value) return try { const reg = await publicActivitiesApi.getMyRegistration(activity.value.id) - if (reg) { + // 只有当 reg 存在且有 id 时才认为已报名 + if (reg && reg.id) { hasRegistered.value = true myRegistration.value = reg - // 检查是否已提交作品(报名接口已包含关联的 works) - hasSubmittedWork.value = reg.works && reg.works.length > 0 + // 检查是否已提交作品 + hasSubmittedWork.value = reg.hasSubmittedWork || false } - } catch { /* not registered */ } + } catch (e) { + // 未报名或查询失败,保持 hasRegistered = false + console.log('查询报名状态失败或未报名') + } } // 打开作品提交 @@ -363,8 +373,8 @@ const handleRegister = async () => { onMounted(async () => { await fetchDetail() - fetchChildren() - checkRegistrationStatus() + await fetchChildren() + await checkRegistrationStatus() }) @@ -493,6 +503,16 @@ $primary: #6366f1; color: $primary !important; border: 1px solid #c7d2fe !important; } + + .action-btn-disabled { + height: 48px !important; + border-radius: 14px !important; + font-size: 15px !important; + font-weight: 600 !important; + background: #f3f4f6 !important; + color: #9ca3af !important; + border: 1px solid #e5e7eb !important; + } } .results-hint {