diff --git a/backend-java/src/main/java/com/competition/modules/biz/contest/controller/ContestNoticeController.java b/backend-java/src/main/java/com/competition/modules/biz/contest/controller/ContestNoticeController.java index f07600e..11f1adc 100644 --- a/backend-java/src/main/java/com/competition/modules/biz/contest/controller/ContestNoticeController.java +++ b/backend-java/src/main/java/com/competition/modules/biz/contest/controller/ContestNoticeController.java @@ -1,8 +1,11 @@ package com.competition.modules.biz.contest.controller; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.competition.common.enums.ErrorCode; import com.competition.common.enums.PublishStatus; +import com.competition.common.exception.BusinessException; import com.competition.common.result.PageResult; import com.competition.common.result.Result; import com.competition.common.util.SecurityUtil; @@ -19,7 +22,9 @@ import org.springframework.web.bind.annotation.*; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import java.util.Collections; import java.util.List; +import java.util.Map; @Tag(name = "活动公告") @RestController @@ -86,6 +91,7 @@ public class ContestNoticeController { .eq(BizContestNotice::getContestId, contestId) .eq(BizContestNotice::getTenantId, tenantId) .orderByDesc(BizContestNotice::getCreateTime)); + noticeService.fillContestInfo(list); return Result.success(list); } @@ -111,6 +117,7 @@ public class ContestNoticeController { wrapper.orderByDesc(BizContestNotice::getCreateTime); Page result = noticeService.page(new Page<>(page, pageSize), wrapper); + noticeService.fillContestInfo(result.getRecords()); return Result.success(PageResult.from(result)); } @@ -118,23 +125,85 @@ public class ContestNoticeController { @RequirePermission("notice:read") @Operation(summary = "查询公告详情") public Result findDetail(@PathVariable Long id) { - return Result.success(noticeService.getById(id)); + BizContestNotice notice = noticeService.getById(id); + if (notice != null) { + noticeService.fillContestInfo(Collections.singletonList(notice)); + } + return Result.success(notice); } @PatchMapping("/{id}") @RequirePermission("notice:update") - @Operation(summary = "更新公告") - public Result update(@PathVariable Long id, @RequestBody CreateNoticeDto dto) { - BizContestNotice notice = new BizContestNotice(); - notice.setId(id); - notice.setTitle(dto.getTitle()); - notice.setContent(dto.getContent()); - notice.setNoticeType(dto.getNoticeType()); - notice.setPriority(dto.getPriority()); - if (StringUtils.hasText(dto.getPublishTime())) { - notice.setPublishTime(parseDateTime(dto.getPublishTime())); + @Operation(summary = "更新公告(部分字段;publishTime 为 null 或空串表示取消发布并写入数据库 NULL)") + public Result update(@PathVariable Long id, @RequestBody Map body) { + Long tenantId = SecurityUtil.getCurrentTenantId(); + BizContestNotice existing = noticeService.getOne( + new LambdaQueryWrapper() + .eq(BizContestNotice::getId, id) + .eq(BizContestNotice::getTenantId, tenantId)); + if (existing == null) { + throw BusinessException.of(ErrorCode.NOT_FOUND, "公告不存在"); } - noticeService.updateById(notice); + + LambdaUpdateWrapper uw = new LambdaUpdateWrapper<>(); + uw.eq(BizContestNotice::getId, id); + uw.eq(BizContestNotice::getTenantId, tenantId); + + boolean hasUpdate = false; + if (body.containsKey("title")) { + Object v = body.get("title"); + if (v != null) { + uw.set(BizContestNotice::getTitle, String.valueOf(v)); + hasUpdate = true; + } + } + if (body.containsKey("content")) { + Object v = body.get("content"); + if (v != null) { + uw.set(BizContestNotice::getContent, String.valueOf(v)); + hasUpdate = true; + } + } + if (body.containsKey("noticeType")) { + Object v = body.get("noticeType"); + if (v != null) { + uw.set(BizContestNotice::getNoticeType, String.valueOf(v)); + hasUpdate = true; + } + } + if (body.containsKey("priority")) { + Object v = body.get("priority"); + if (v instanceof Number) { + uw.set(BizContestNotice::getPriority, ((Number) v).intValue()); + hasUpdate = true; + } + } + if (body.containsKey("contestId")) { + Object v = body.get("contestId"); + if (v instanceof Number) { + uw.set(BizContestNotice::getContestId, ((Number) v).longValue()); + hasUpdate = true; + } + } + // 仅当请求体包含 publishTime 键时才改发布时间:null / 空串 = 取消发布(必须写入 SQL NULL) + if (body.containsKey("publishTime")) { + Object v = body.get("publishTime"); + if (v == null || (v instanceof String && !StringUtils.hasText((String) v))) { + uw.set(BizContestNotice::getPublishTime, null); + hasUpdate = true; + } else if (v instanceof String && StringUtils.hasText((String) v)) { + LocalDateTime pt = parseDateTime((String) v); + if (pt != null) { + uw.set(BizContestNotice::getPublishTime, pt); + hasUpdate = true; + } + } + } + + if (!hasUpdate) { + return Result.success(); + } + noticeService.getBaseMapper().update(null, uw); return Result.success(); } diff --git a/backend-java/src/main/java/com/competition/modules/biz/contest/entity/BizContestNotice.java b/backend-java/src/main/java/com/competition/modules/biz/contest/entity/BizContestNotice.java index 19da44f..9e626f3 100644 --- a/backend-java/src/main/java/com/competition/modules/biz/contest/entity/BizContestNotice.java +++ b/backend-java/src/main/java/com/competition/modules/biz/contest/entity/BizContestNotice.java @@ -42,4 +42,9 @@ public class BizContestNotice extends BaseEntity { @Schema(description = "发布时间") @TableField("publish_time") private LocalDateTime publishTime; + + /** 关联活动(仅查询接口填充,不落库) */ + @Schema(description = "关联活动") + @TableField(exist = false) + private BizContest contest; } diff --git a/backend-java/src/main/java/com/competition/modules/biz/contest/service/IContestNoticeService.java b/backend-java/src/main/java/com/competition/modules/biz/contest/service/IContestNoticeService.java index 32246dc..793cef9 100644 --- a/backend-java/src/main/java/com/competition/modules/biz/contest/service/IContestNoticeService.java +++ b/backend-java/src/main/java/com/competition/modules/biz/contest/service/IContestNoticeService.java @@ -3,5 +3,12 @@ package com.competition.modules.biz.contest.service; import com.baomidou.mybatisplus.extension.service.IService; import com.competition.modules.biz.contest.entity.BizContestNotice; +import java.util.List; + public interface IContestNoticeService extends IService { + + /** + * 批量填充关联活动名称(仅设置 id、contestName,供前端展示) + */ + void fillContestInfo(List notices); } diff --git a/backend-java/src/main/java/com/competition/modules/biz/contest/service/impl/ContestNoticeServiceImpl.java b/backend-java/src/main/java/com/competition/modules/biz/contest/service/impl/ContestNoticeServiceImpl.java index 967e14b..d4b19a4 100644 --- a/backend-java/src/main/java/com/competition/modules/biz/contest/service/impl/ContestNoticeServiceImpl.java +++ b/backend-java/src/main/java/com/competition/modules/biz/contest/service/impl/ContestNoticeServiceImpl.java @@ -1,11 +1,54 @@ package com.competition.modules.biz.contest.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.competition.modules.biz.contest.entity.BizContest; import com.competition.modules.biz.contest.entity.BizContestNotice; import com.competition.modules.biz.contest.mapper.ContestNoticeMapper; import com.competition.modules.biz.contest.service.IContestNoticeService; +import com.competition.modules.biz.contest.service.IContestService; +import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; + @Service +@RequiredArgsConstructor public class ContestNoticeServiceImpl extends ServiceImpl implements IContestNoticeService { + + private final IContestService contestService; + + @Override + public void fillContestInfo(List notices) { + if (notices == null || notices.isEmpty()) { + return; + } + Set contestIds = notices.stream() + .map(BizContestNotice::getContestId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + if (contestIds.isEmpty()) { + return; + } + List contests = contestService.listByIds(contestIds); + Map map = contests.stream() + .collect(Collectors.toMap(BizContest::getId, Function.identity(), (a, b) -> a)); + for (BizContestNotice notice : notices) { + Long cid = notice.getContestId(); + if (cid == null) { + continue; + } + BizContest c = map.get(cid); + if (c != null) { + BizContest brief = new BizContest(); + brief.setId(c.getId()); + brief.setContestName(c.getContestName()); + notice.setContest(brief); + } + } + } }