feat: 07 创作者中心批 3(分片上传挂载 + 分集收费与试看)
为什么:创作者传完片子得把产物挂到分集上才能播,而这条链路之前有两个洞:
uploadId 是"凭证",谁拿到都能往别人的会话里塞分片 / 合并;产物挂载也没有归属校验,
拿到别人的 assetId 就能把自己的剧指向别人的素材。定价这边则缺创作者入口与试看秒数配置。
- 上传复用现有 /admin/media/upload/{init,chunk,complete},不重写;新增 GET /admin/media/upload/{uploadId}
做断点续传回显(receivedChunks/totalChunks/percent/status,完成后带 url)
- 上传会话归属校验:chunk / complete / 进度查询都要求会话发起人,别人拿到 uploadId 也操作不了(403)
- 新增 attach 接口:产物必须① 是本次登录的人上传的(media_asset.create_by)② bizType=EPISODE 且状态 ready/uploaded
③ 分集属于自己这部剧且作品可编辑;挂载时把产物时长补到分集上
- 收费配置复用 PriceService:新增创作者侧 GET/PUT /admin/creator-center/dramas/{id}/prices;
PriceSaveReqVO/PriceRespVO 补 previewSeconds(落在已有的 drama_episode.preview_seconds,不新造一套)
- 定价沿用"可编辑状态"口径:draft/offline 可改,已上线要先申请下线;dramaId 以路径为准,别人的 episodeId 被忽略
- 权限点 creator-center:upload / creator-center:price:update;创作者角色同时获得 cover:upload / episode:upload(复用上传接口)
实测:未登录请求付费集返回 {"accessType":"COIN_REQUIRED","unlockCoin":50,"previewSeconds":15},
免费集直接拿到签名播放地址 —— 创作者改的价格确实走到了 C 端付费判定。
This commit is contained in:
1 parent
255bcbf02b
commit
8b8ebf944f
12 files changed
+269
-10
No files matched your search
+14
-1
@@ -50,6 +50,7 @@ public class PriceService {
|
||||
item.setTitle(episode.getTitle());
|
||||
item.setFree(episode.getIsFree() != null && episode.getIsFree() == 1);
|
||||
item.setUnlockCoin(episode.getUnlockCoin());
|
||||
item.setPreviewSeconds(episode.getPreviewSeconds() == null ? 0 : episode.getPreviewSeconds());
|
||||
return item;
|
||||
}).toList());
|
||||
return vo;
|
||||
@@ -89,6 +90,7 @@ public class PriceService {
|
||||
int coin = isFree == 1 ? 0 : unlockCoin;
|
||||
|
||||
PriceSaveReqVO.EpisodePrice override = overrides.get(episode.getId());
|
||||
Integer previewSeconds = null;
|
||||
if (override != null) {
|
||||
if (override.getIsFree() != null) {
|
||||
isFree = override.getIsFree() == 1 ? 1 : 0;
|
||||
@@ -97,11 +99,21 @@ public class PriceService {
|
||||
if (isFree == 0 && override.getUnlockCoin() != null) {
|
||||
coin = Math.max(0, override.getUnlockCoin());
|
||||
}
|
||||
if (override.getPreviewSeconds() != null) {
|
||||
previewSeconds = Math.max(0, override.getPreviewSeconds());
|
||||
}
|
||||
}
|
||||
|
||||
if (!Objects.equals(episode.getIsFree(), isFree) || !Objects.equals(episode.getUnlockCoin(), coin)) {
|
||||
boolean priceChanged = !Objects.equals(episode.getIsFree(), isFree)
|
||||
|| !Objects.equals(episode.getUnlockCoin(), coin);
|
||||
boolean previewChanged = previewSeconds != null
|
||||
&& !Objects.equals(episode.getPreviewSeconds(), previewSeconds);
|
||||
if (priceChanged || previewChanged) {
|
||||
episode.setIsFree(isFree);
|
||||
episode.setUnlockCoin(coin);
|
||||
if (previewSeconds != null) {
|
||||
episode.setPreviewSeconds(previewSeconds);
|
||||
}
|
||||
dramaEpisodeMapper.updateById(episode);
|
||||
changed++;
|
||||
}
|
||||
@@ -120,6 +132,7 @@ public class PriceService {
|
||||
item.setTitle(episode.getTitle());
|
||||
item.setFree(episode.getIsFree() != null && episode.getIsFree() == 1);
|
||||
item.setUnlockCoin(episode.getUnlockCoin());
|
||||
item.setPreviewSeconds(episode.getPreviewSeconds() == null ? 0 : episode.getPreviewSeconds());
|
||||
return item;
|
||||
}).toList());
|
||||
return vo;
|
||||
|
||||
@@ -25,5 +25,7 @@ public class PriceRespVO {
|
||||
private String title;
|
||||
private Boolean free;
|
||||
private Integer unlockCoin;
|
||||
/** 试看秒数,0 = 不限制 */
|
||||
private Integer previewSeconds;
|
||||
}
|
||||
}
|
||||
+2
@@ -22,5 +22,7 @@ public class PriceSaveReqVO {
|
||||
/** 1 免费 / 0 收费 */
|
||||
private Integer isFree;
|
||||
private Integer unlockCoin;
|
||||
/** 试看秒数:0 = 不限制(复用 drama_episode.preview_seconds,播放接口已经在下发这个字段) */
|
||||
private Integer previewSeconds;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user