feat(content): 短剧支持审核通过并上线一步流转
backend-ci / test (push) Failing after 5m8s

新增 APPROVE_PUBLISH 动作与 approve-publish 接口,草稿/审核中/已下线
可直接流转为已上线,事务内同步上线草稿分集并记录一条审核记录,
后台审核操作由三步减为一步。
This commit is contained in:
jianghaifeng committed 2026-11-05 10:55:52 +08:00
1 parent eba7d400e1
commit 32ada4c2bf
3 files changed
+57

No files matched your search

@@ -113,6 +113,15 @@ public class DramaController {
return Result.ok();
}
@Operation(summary = "审核通过并上线")
@PostMapping("/{id}/approve-publish")
@PreAuthorize("@ss.hasPermission('drama:review')")
@OperationLog(module = "内容管理", action = "审核通过并上线")
public Result<Void> approvePublish(@PathVariable Long id, @RequestBody(required = false) DramaStatusReqVO req) {
changeStatus(id, "APPROVE_PUBLISH", req);
return Result.ok();
}
@Operation(summary = "上线")
@PostMapping("/{id}/publish")
@PreAuthorize("@ss.hasPermission('drama:review')")
@@ -162,6 +162,12 @@ public class DramaService {
requireState(current, "APPROVE", Set.of(ContentStatus.REVIEWING.getCode()));
yield ContentStatus.APPROVED.getCode();
}
case "APPROVE_PUBLISH" -> {
// 一步审核通过并上线,减少后台操作步骤
requireState(current, "APPROVE_PUBLISH", Set.of(ContentStatus.DRAFT.getCode(),
ContentStatus.REVIEWING.getCode(), ContentStatus.OFFLINE.getCode()));
yield ContentStatus.PUBLISHED.getCode();
}
case "REJECT" -> {
requireState(current, "REJECT", Set.of(ContentStatus.REVIEWING.getCode()));
yield ContentStatus.DRAFT.getCode();
@@ -4,11 +4,13 @@ package com.fruitshorts.content.service;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.fruitshorts.common.exception.ServiceException;
import com.fruitshorts.content.dal.entity.Drama;
import com.fruitshorts.content.dal.entity.DramaEpisode;
import com.fruitshorts.content.dal.mapper.DramaEpisodeMapper;
import com.fruitshorts.content.dal.mapper.DramaMapper;
import com.fruitshorts.content.dal.mapper.DramaReviewRecordMapper;
import com.fruitshorts.content.enums.ContentStatus;
import com.fruitshorts.content.vo.DramaSaveReqVO;
import org.apache.ibatis.builder.MapperBuilderAssistant;
import org.junit.jupiter.api.BeforeAll;
@@ -25,6 +27,7 @@ import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
@@ -159,6 +162,45 @@ class DramaServiceTest {
verify(dramaEpisodeMapper, never()).updateById(any(DramaEpisode.class));
}
@Test
void should_publish_directly_from_draft_when_approve_publish() {
Drama drama = givenDramaWithStatus(ContentStatus.DRAFT.getCode());
dramaService.changeStatus(DRAMA_ID, "APPROVE_PUBLISH", "", 1L, "admin");
assertThat(drama.getStatus()).isEqualTo(ContentStatus.PUBLISHED.getCode());
assertThat(drama.getPublishedAt()).isNotNull();
verify(dramaMapper).updateById(drama);
// 上线时同步把草稿分集发布
verify(dramaEpisodeMapper).update(any(), any());
}
@Test
void should_publish_directly_from_reviewing_when_approve_publish() {
Drama drama = givenDramaWithStatus(ContentStatus.REVIEWING.getCode());
dramaService.changeStatus(DRAMA_ID, "APPROVE_PUBLISH", "", 1L, "admin");
assertThat(drama.getStatus()).isEqualTo(ContentStatus.PUBLISHED.getCode());
}
@Test
void should_reject_approve_publish_when_already_published() {
givenDramaWithStatus(ContentStatus.PUBLISHED.getCode());
assertThatThrownBy(() -> dramaService.changeStatus(DRAMA_ID, "APPROVE_PUBLISH", "", 1L, "admin"))
.isInstanceOf(ServiceException.class);
}
private Drama givenDramaWithStatus(String status) {
Drama drama = new Drama();
drama.setId(DRAMA_ID);
drama.setStatus(status);
given(dramaMapper.selectById(DRAMA_ID)).willReturn(drama);
given(dramaMapper.updateById(any(Drama.class))).willReturn(1);
return drama;
}
private void givenExistingDrama(int freeEpisodes, int unlockCoin) {
Drama drama = new Drama();
drama.setId(DRAMA_ID);