fix(content): 短剧保存免费集数时同步分集免费状态
This commit is contained in:
1 parent
d7f226659c
commit
4c4b53cd69
4 files changed
+136
-46
No files matched your search
+16
@@ -30,6 +30,7 @@ import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
@Service
|
||||
@@ -42,6 +43,7 @@ public class DramaService {
|
||||
private final DramaEpisodeMapper dramaEpisodeMapper;
|
||||
private final DramaReviewRecordMapper dramaReviewRecordMapper;
|
||||
private final DramaCategoryService dramaCategoryService;
|
||||
private final EpisodePriceSync episodePriceSync;
|
||||
|
||||
public PageResult<DramaRespVO> page(DramaPageReqVO req) {
|
||||
List<String> dramaTypes = DramaMultiTagSupport.normalizeDramaTypes(req.getDramaTypes());
|
||||
@@ -109,6 +111,8 @@ public class DramaService {
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void update(Long id, DramaSaveReqVO req) {
|
||||
Drama drama = getExisting(id);
|
||||
Integer oldFreeEpisodes = drama.getFreeEpisodes();
|
||||
Integer oldUnlockCoin = drama.getUnlockCoin();
|
||||
apply(drama, req, false);
|
||||
if (req.getFavoriteCount() != null) {
|
||||
drama.setFavoriteCount(nonNegative(req.getFavoriteCount(), "收藏数"));
|
||||
@@ -120,6 +124,18 @@ public class DramaService {
|
||||
drama.setViewCount(nonNegative(req.getHeat(), "热度"));
|
||||
}
|
||||
dramaMapper.updateById(drama);
|
||||
syncEpisodePricesIfNeeded(drama, oldFreeEpisodes, oldUnlockCoin);
|
||||
}
|
||||
|
||||
/** 免费集数或解锁金币变化时,按定价规则回写分集。 */
|
||||
private void syncEpisodePricesIfNeeded(Drama drama, Integer oldFreeEpisodes, Integer oldUnlockCoin) {
|
||||
if (Objects.equals(oldFreeEpisodes, drama.getFreeEpisodes())
|
||||
&& Objects.equals(oldUnlockCoin, drama.getUnlockCoin())) {
|
||||
return;
|
||||
}
|
||||
int freeEpisodes = drama.getFreeEpisodes() == null ? 0 : Math.max(0, drama.getFreeEpisodes());
|
||||
int unlockCoin = drama.getUnlockCoin() == null ? 0 : Math.max(0, drama.getUnlockCoin());
|
||||
episodePriceSync.syncByDramaRule(drama.getId(), freeEpisodes, unlockCoin);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
// Author: fruit.com.cn
|
||||
|
||||
package com.fruitshorts.content.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.fruitshorts.content.dal.entity.DramaEpisode;
|
||||
import com.fruitshorts.content.dal.mapper.DramaEpisodeMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 按短剧免费集数规则同步分集 {@code is_free} / {@code unlock_coin}。
|
||||
*
|
||||
* <p>定价页与短剧编辑共用同一套规则,避免两处口径漂移。</p>
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class EpisodePriceSync {
|
||||
|
||||
private final DramaEpisodeMapper dramaEpisodeMapper;
|
||||
|
||||
/**
|
||||
* 全量同步某剧全部分集价格。
|
||||
*
|
||||
* <p>规则:{@code epNo > 0 && epNo <= freeEpisodes} 为免费且 coin=0,
|
||||
* 否则收费且 coin={@code unlockCoin}。</p>
|
||||
*
|
||||
* @return 实际写库的分集数
|
||||
*/
|
||||
public int syncByDramaRule(Long dramaId, int freeEpisodes, int unlockCoin) {
|
||||
List<DramaEpisode> episodes = dramaEpisodeMapper.selectList(Wrappers.<DramaEpisode>lambdaQuery()
|
||||
.eq(DramaEpisode::getDramaId, dramaId)
|
||||
.orderByAsc(DramaEpisode::getEpNo));
|
||||
int changed = 0;
|
||||
for (DramaEpisode episode : episodes) {
|
||||
int epNo = episode.getEpNo() == null ? 0 : episode.getEpNo();
|
||||
int isFree = resolveIsFree(epNo, freeEpisodes);
|
||||
int coin = resolveUnlockCoin(isFree, unlockCoin);
|
||||
if (!Objects.equals(episode.getIsFree(), isFree)
|
||||
|| !Objects.equals(episode.getUnlockCoin(), coin)) {
|
||||
episode.setIsFree(isFree);
|
||||
episode.setUnlockCoin(coin);
|
||||
dramaEpisodeMapper.updateById(episode);
|
||||
changed++;
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
/** 集号落在免费区间内则为免费。 */
|
||||
public static int resolveIsFree(int epNo, int freeEpisodes) {
|
||||
return epNo > 0 && epNo <= freeEpisodes ? 1 : 0;
|
||||
}
|
||||
|
||||
/** 免费集 coin 置 0,收费集用短剧解锁金币。 */
|
||||
public static int resolveUnlockCoin(int isFree, int unlockCoin) {
|
||||
return isFree == 1 ? 0 : unlockCoin;
|
||||
}
|
||||
}
|
||||
+56
-45
@@ -32,6 +32,7 @@ public class PriceService {
|
||||
private final DramaService dramaService;
|
||||
private final DramaMapper dramaMapper;
|
||||
private final DramaEpisodeMapper dramaEpisodeMapper;
|
||||
private final EpisodePriceSync episodePriceSync;
|
||||
|
||||
/** 读取当前价格配置:后台定价页进入时先看现状再改。 */
|
||||
public PriceRespVO detail(Long dramaId) {
|
||||
@@ -72,55 +73,13 @@ public class PriceService {
|
||||
drama.setUnlockCoin(unlockCoin);
|
||||
dramaMapper.updateById(drama);
|
||||
|
||||
int changed = episodePriceSync.syncByDramaRule(drama.getId(), freeEpisodes, unlockCoin);
|
||||
changed += applyEpisodeOverrides(drama.getId(), unlockCoin, req);
|
||||
|
||||
List<DramaEpisode> episodes = dramaEpisodeMapper.selectList(Wrappers.<DramaEpisode>lambdaQuery()
|
||||
.eq(DramaEpisode::getDramaId, drama.getId())
|
||||
.orderByAsc(DramaEpisode::getEpNo));
|
||||
|
||||
Map<Long, PriceSaveReqVO.EpisodePrice> overrides = new LinkedHashMap<>();
|
||||
if (req.getEpisodes() != null) {
|
||||
for (PriceSaveReqVO.EpisodePrice item : req.getEpisodes()) {
|
||||
if (item != null && item.getEpisodeId() != null) {
|
||||
overrides.put(item.getEpisodeId(), item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int changed = 0;
|
||||
for (DramaEpisode episode : episodes) {
|
||||
int epNo = episode.getEpNo() == null ? 0 : episode.getEpNo();
|
||||
int isFree = epNo > 0 && epNo <= freeEpisodes ? 1 : 0;
|
||||
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;
|
||||
coin = isFree == 1 ? 0 : unlockCoin;
|
||||
}
|
||||
if (isFree == 0 && override.getUnlockCoin() != null) {
|
||||
coin = Math.max(0, override.getUnlockCoin());
|
||||
}
|
||||
if (override.getPreviewSeconds() != null) {
|
||||
previewSeconds = Math.max(0, override.getPreviewSeconds());
|
||||
}
|
||||
}
|
||||
|
||||
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++;
|
||||
}
|
||||
}
|
||||
|
||||
PriceRespVO vo = new PriceRespVO();
|
||||
vo.setDramaId(drama.getId());
|
||||
vo.setFreeEpisodes(freeEpisodes);
|
||||
@@ -139,4 +98,56 @@ public class PriceService {
|
||||
}).toList());
|
||||
return vo;
|
||||
}
|
||||
|
||||
/** 在整剧规则同步后再落单集覆盖(含试看秒数)。 */
|
||||
private int applyEpisodeOverrides(Long dramaId, int unlockCoin, PriceSaveReqVO req) {
|
||||
Map<Long, PriceSaveReqVO.EpisodePrice> overrides = new LinkedHashMap<>();
|
||||
if (req.getEpisodes() != null) {
|
||||
for (PriceSaveReqVO.EpisodePrice item : req.getEpisodes()) {
|
||||
if (item != null && item.getEpisodeId() != null) {
|
||||
overrides.put(item.getEpisodeId(), item);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (overrides.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
List<DramaEpisode> episodes = dramaEpisodeMapper.selectList(Wrappers.<DramaEpisode>lambdaQuery()
|
||||
.eq(DramaEpisode::getDramaId, dramaId)
|
||||
.orderByAsc(DramaEpisode::getEpNo));
|
||||
int changed = 0;
|
||||
for (DramaEpisode episode : episodes) {
|
||||
PriceSaveReqVO.EpisodePrice override = overrides.get(episode.getId());
|
||||
if (override == null) {
|
||||
continue;
|
||||
}
|
||||
int isFree = episode.getIsFree() == null ? 0 : episode.getIsFree();
|
||||
int coin = episode.getUnlockCoin() == null ? 0 : episode.getUnlockCoin();
|
||||
Integer previewSeconds = null;
|
||||
if (override.getIsFree() != null) {
|
||||
isFree = override.getIsFree() == 1 ? 1 : 0;
|
||||
coin = EpisodePriceSync.resolveUnlockCoin(isFree, unlockCoin);
|
||||
}
|
||||
if (isFree == 0 && override.getUnlockCoin() != null) {
|
||||
coin = Math.max(0, override.getUnlockCoin());
|
||||
}
|
||||
if (override.getPreviewSeconds() != null) {
|
||||
previewSeconds = Math.max(0, override.getPreviewSeconds());
|
||||
}
|
||||
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++;
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user