feat: 07 创作者中心批 2(内容编辑 / 分集 / 提交审核)

为什么:批 1 只给了创作者"看"的能力(工作台、审核进度、通知),内容还是得后台代建。
批 2 补上"改":创作者自己建草稿、编分集、提交审核,后台只管审。落地过程中发现三个必须一起修的问题:

1. 【会卡死创作者】后台驳回提交时不动短剧状态,剧会永远停在 reviewing,
   而批 2 里 reviewing 是只读 —— 创作者既改不了也提不了。现在驳回与撤回都会把剧退回 draft。
2. 【上线了却放不出来】C 端只播 status=published 的分集,但没有任何地方在剧上线时把分集带上线。
   审核通过 PUBLISH 时,仍处于草稿的分集一并上线。
3. 【编辑会误删字段】底层 apply() 对 null 会写空串/默认值:只想改封面的一次调用会把标题、时长、
   排序一起清掉(自测时两集排序都变成 1 才发现)。creator 侧改成"未传字段沿用现值"。

- 新增 CreatorContentService + /admin/creator-center 的 10 个写接口与 2 个读接口,
  一律不接收 creatorId,归属走 requireMyDrama,改别人的作品/分集统一 403
- 状态闸:只有 draft / offline 可直接编辑;reviewing / approved / published 只读并给出下一步动作
- 提交矩阵:draft→CREATE(首次)/UPDATE/PUBLISH,offline→UPDATE/PUBLISH,reviewing/approved→PUBLISH,published→OFFLINE;
  同剧同时只允许一条在审提交;撤回后作品退回草稿,支持撤回重提
- 权限点 creator-center:drama:edit(创作者角色 + 超管),docs/api-phase1.md 2.10 补批 2 接口与规则表
- 分集收费与试看秒数本批不碰(批 3 的收费配置页负责),新增分集默认免费,避免误定价
This commit is contained in:
Vicky committed 2026-10-15 13:58:45 +08:00
1 parent ea875c3e2b
commit 255bcbf02b
11 files changed
+616 -5

No files matched your search

@@ -30,4 +30,14 @@ public enum ContentStatus {
}
return code;
}
/** 按状态码取枚举,未知状态返回 null(由调用方决定怎么提示)。 */
public static ContentStatus of(String code) {
for (ContentStatus status : values()) {
if (status.code.equals(code)) {
return status;
}
}
return null;
}
}
@@ -65,10 +65,24 @@ public class DramaService {
@Transactional(rollbackFor = Exception.class)
public Long create(DramaSaveReqVO req, Long operatorId) {
return insert(req, operatorId, 0L);
}
/**
* 创作者侧建草稿:和后台建剧走同一套字段映射,只是额外写入归属 creator_id。
* 后台账号记在 create_by(操作留痕),归属与操作人分开存,避免"谁建的"和"是谁的"混成一个字段。
*/
@Transactional(rollbackFor = Exception.class)
public Long createForCreator(DramaSaveReqVO req, Long creatorId, Long operatorId) {
return insert(req, operatorId, creatorId);
}
private Long insert(DramaSaveReqVO req, Long operatorId, Long creatorId) {
Drama drama = new Drama();
apply(drama, req);
drama.setCode(generateCode());
drama.setStatus(ContentStatus.DRAFT.getCode());
drama.setCreatorId(creatorId == null ? 0L : creatorId);
drama.setTotalEpisodes(0);
drama.setViewCount(0L);
drama.setPlayCount(0L);
@@ -141,6 +141,20 @@ public class EpisodeService {
}
}
/**
* 短剧上线时把仍处于「草稿」的分集一并上线,返回受影响条数。
*
* 为什么需要:C 端只播 status=published 的分集,创作者提交上线、后台审核通过后
* 若分集还停在草稿,就会出现"剧上线了但一集都播不了"。已下线等其它状态不动。
*/
@Transactional(rollbackFor = Exception.class)
public int publishDraftEpisodes(Long dramaId) {
return dramaEpisodeMapper.update(null, Wrappers.<DramaEpisode>lambdaUpdate()
.eq(DramaEpisode::getDramaId, dramaId)
.eq(DramaEpisode::getStatus, ContentStatus.DRAFT.getCode())
.set(DramaEpisode::getStatus, ContentStatus.PUBLISHED.getCode()));
}
private void ensureEpNoAvailable(Long dramaId, Integer epNo, Long excludeId) {
Long count = dramaEpisodeMapper.selectCount(Wrappers.<DramaEpisode>lambdaQuery()
.eq(DramaEpisode::getDramaId, dramaId)