feat(script-favorite): add ScriptFavoriteServiceImpl

- toggleFavorite: upsert via logical-delete check + save, @Transactional
- getFavoritePage: paginate favorites then fetch EpicScript details
- getFavoritedScriptIds: batch IN query for checking multiple scripts
- isFavorited: count > 0 check for single script
- getFavoriteCount: total count for current user
- Uses UserContextHolder for userId, consistent with project pattern
This commit is contained in:
2026-07-19 21:41:54 +08:00
parent 674188f471
commit 9d352f40a0
@@ -0,0 +1,149 @@
package com.emotion.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.emotion.common.PageResult;
import com.emotion.dto.response.EpicScriptResponse;
import com.emotion.dto.response.ScriptFavoriteResponse;
import com.emotion.entity.ScriptFavorite;
import com.emotion.mapper.ScriptFavoriteMapper;
import com.emotion.service.EpicScriptService;
import com.emotion.service.ScriptFavoriteService;
import com.emotion.util.UserContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
/**
* 剧本收藏服务实现
*
* @author huazhongmin
* @date 2026-07-19
*/
@Slf4j
@Service
public class ScriptFavoriteServiceImpl extends ServiceImpl<ScriptFavoriteMapper, ScriptFavorite>
implements ScriptFavoriteService {
private static final DateTimeFormatter FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@Autowired
private EpicScriptService epicScriptService;
@Override
@Transactional(rollbackFor = Exception.class)
public ScriptFavoriteResponse toggleFavorite(String scriptId) {
String userId = UserContextHolder.getCurrentUserId();
ScriptFavoriteResponse r = new ScriptFavoriteResponse();
r.setScriptId(scriptId);
if (!StringUtils.hasText(userId)) {
r.setIsFavorited(false);
return r;
}
LambdaQueryWrapper<ScriptFavorite> w = new LambdaQueryWrapper<>();
w.eq(ScriptFavorite::getUserId, userId)
.eq(ScriptFavorite::getScriptId, scriptId)
.eq(ScriptFavorite::getIsDeleted, 0);
ScriptFavorite existing = this.getOne(w);
if (existing != null) {
this.removeById(existing.getId());
r.setIsFavorited(false);
} else {
ScriptFavorite fav = new ScriptFavorite();
fav.setUserId(userId);
fav.setScriptId(scriptId);
this.save(fav);
r.setIsFavorited(true);
if (fav.getCreateTime() != null) {
r.setFavoriteTime(fav.getCreateTime().format(FMT));
}
}
return r;
}
@Override
public PageResult<EpicScriptResponse> getFavoritePage(long current, long size) {
String userId = UserContextHolder.getCurrentUserId();
if (!StringUtils.hasText(userId)) {
return new PageResult<>();
}
LambdaQueryWrapper<ScriptFavorite> w = new LambdaQueryWrapper<>();
w.eq(ScriptFavorite::getUserId, userId)
.eq(ScriptFavorite::getIsDeleted, 0)
.orderByDesc(ScriptFavorite::getCreateTime);
Page<ScriptFavorite> page = new Page<>(current, size);
Page<ScriptFavorite> result = this.page(page, w);
List<EpicScriptResponse> records = result.getRecords().stream()
.map(ScriptFavorite::getScriptId)
.map(epicScriptService::getScriptById)
.filter(Objects::nonNull)
.collect(Collectors.toList());
PageResult<EpicScriptResponse> pr = new PageResult<>();
pr.setCurrent(result.getCurrent());
pr.setSize(result.getSize());
pr.setTotal(result.getTotal());
pr.setPages(result.getPages());
pr.setRecords(records);
return pr;
}
@Override
public Set<String> getFavoritedScriptIds(Set<String> scriptIds) {
String userId = UserContextHolder.getCurrentUserId();
if (!StringUtils.hasText(userId) || scriptIds == null || scriptIds.isEmpty()) {
return Collections.emptySet();
}
LambdaQueryWrapper<ScriptFavorite> w = new LambdaQueryWrapper<>();
w.eq(ScriptFavorite::getUserId, userId)
.in(ScriptFavorite::getScriptId, scriptIds)
.eq(ScriptFavorite::getIsDeleted, 0);
return this.list(w).stream()
.map(ScriptFavorite::getScriptId)
.collect(Collectors.toSet());
}
@Override
public boolean isFavorited(String scriptId) {
String userId = UserContextHolder.getCurrentUserId();
if (!StringUtils.hasText(userId) || !StringUtils.hasText(scriptId)) {
return false;
}
LambdaQueryWrapper<ScriptFavorite> w = new LambdaQueryWrapper<>();
w.eq(ScriptFavorite::getUserId, userId)
.eq(ScriptFavorite::getScriptId, scriptId)
.eq(ScriptFavorite::getIsDeleted, 0);
return this.count(w) > 0;
}
@Override
public long getFavoriteCount() {
String userId = UserContextHolder.getCurrentUserId();
if (!StringUtils.hasText(userId)) {
return 0L;
}
LambdaQueryWrapper<ScriptFavorite> w = new LambdaQueryWrapper<>();
w.eq(ScriptFavorite::getUserId, userId)
.eq(ScriptFavorite::getIsDeleted, 0);
return this.count(w);
}
}