
管理员
站长
- UID
- 1
- 积分
- 224315
- 余额
- 13 R
- Moe币
- 84800
- 在线时间
- 264 小时
- 注册时间
- 2025-12-28
- 最后登录
- 2026-9-19
|
tors.toList());
map.put("tagIds", tagIds);
return map;
}
@Override
public IPage<Map<String, Object>> adminPageQuery(MangaPageDTO dto) {
LambdaQueryWrapper<Manga> wrapper = new LambdaQueryWrapper<>();
if (dto.getKeyword() != null && !dto.getKeyword().isEmpty()) {
wrapper.like(Manga::getTitle, dto.getKeyword());
}
if (dto.getCategoryId() != null) {
wrapper.eq(Manga::getCategoryId, dto.getCategoryId());
}
if (dto.getPublishStatus() != null) {
wrapper.eq(Manga::getPublishStatus, dto.getPublishStatus());
}
if (dto.getStatus() != null) {
wrapper.eq(Manga::getStatus, dto.getStatus());
}
wrapper.orderByDesc(Manga::getSortWeight).orderByDesc(Manga::getCreateTime);
Page<Manga> page = mangaMapper.selectPage(
new Page<>(dto.getPageNum(), dto.getPageSize()), wrapper);
// 转换为带分类名称的 Map
List<Map<String, Object>> records = page.getRecords().stream().map(manga -> {
Map<String, Object> map = new HashMap<>();
map.put("id", manga.getId());
map.put("title", manga.getTitle());
map.put("author", manga.getAuthor());
map.put("cover", manga.getCover());
map.put("categoryId", manga.getCategoryId());
Category category = categoryMapper.selectById(manga.getCategoryId());
map.put("categoryName", category != null ? category.getName() : "");
map.put("status", manga.getStatus());
map.put("publishStatus", manga.getPublishStatus());
map.put("priceType", manga.getPriceType());
map.put("price", manga.getPrice());
map.put("ageRange", manga.getAgeRange());
map.put("clickCount", manga.getClickCount());
map.put("favoriteCount", manga.getFavoriteCount());
map.put("isRecommend", manga.getIsRecommend());
map.put("sortWeight", manga.getSortWeight());
map.put("isFree", manga.getIsFree());
map.put("lastChapterTitle", manga.getLastChapterTitle());
map.put("lastUpdateTime", manga.getLastUpdateTime());
map.put("createTime", manga.getCreateTime());
return map;
}).collect(Collectors.toList());
IPage<Map<String, Object>> result = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
result.setRecords(records);
return result;
}
@Override
@Transactional(rollbackFor = Exception.class)
public Long add(MangaAddDTO dto) {
Manga manga = new Manga();
manga.setTitle(dto.getTitle());
manga.setAuthor(dto.getAuthor() != null ? dto.getAuthor() : "");
manga.setCategoryId(dto.getCategoryId());
manga.setCover(dto.getCover() != null ? dto.getCover() : "");
manga.setDescription(dto.getDescription());
manga.setStatus(dto.getStatus() != null ? dto.getStatus() : 0);
manga.setIsFree(dto.getIsFree() != null ? dto.getIsFree() : 1);
manga.setPriceType(dto.getPriceType() != null ? dto.getPriceType() : 0);
manga.setPrice(dto.getPrice() != null ? dto.getPrice() : 0);
manga.setIsRecommend(dto.getIsRecommend() != null ? dto.getIsRecommend() : 0);
manga.setAgeRange(dto.getAgeRange() != null ? dto.getAgeRange() : 0);
manga.setSortWeight(dto.getSortWeight() != null ? dto.getSortWeight() : 0);
manga.setPublishStatus(1);
manga.setClickCount(0);
manga.setFavoriteCount(0);
manga.setCommentCount(0);
mangaMapper.insert(manga);
// 关联标签
if (dto.getTagIds() != null && !dto.getTagIds().isEmpty()) {
for (Long tagId : dto.getTagIds()) {
MangaTag mt = new MangaTag();
mt.setMangaId(manga.getId());
mt.setTagId(tagId);
mangaTagMapper.insert(mt);
}
}
return manga.getId();
}
@Override
@Transactional(rollbackFor = Exception.class)
public void update(Long id, MangaUpdateDTO dto) {
Manga manga = mangaMapper.selectById(id);
if (manga == null) {
throw new IllegalArgumentException("漫画不存在");
}
if (dto.getTitle() != null) manga.setTitle(dto.getTitle());
if (dto.getAuthor() != null) manga.setAuthor(dto.getAuthor());
if (dto.getCategoryId() != null) manga.setCategoryId(dto.getCategoryId());
if (dto.getCover() != null) manga.setCover(dto.getCover());
if (dto.getDescription() != null) manga.setDescription(dto.getDescription());
if (dto.getStatus() != null) manga.setStatus(dto.getStatus());
if (dto.getIsFree() != null) manga.setIsFree(dto.getIsFree());
if (dto.getPriceType() != null) manga.setPriceType(dto.getPriceType());
if (dto.getPrice() != null) manga.setPrice(dto.getPrice());
if (dto.getIsRecommend() != null) manga.setIsRecommend(dto.getIsRecommend());
if (dto.getAgeRange() != null) manga.setAgeRange(dto.getAgeRange());
if (dto.getSortWeight() != null) manga.setSortWeight(dto.getSortWeight());
mangaMapper.updateById(manga);
// 更新标签关联(先删后加)
if (dto.getTagIds() != null) {
mangaTagMapper.delete(new LambdaQueryWrapper<MangaTag>().eq(MangaTag::getMangaId, id));
for (Long tagId : dto.getTagIds()) {
MangaTag mt = new MangaTag();
mt.setMangaId(id);
mt.setTagId(tagId);
mangaTagMapper.insert(mt);
}
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(Long id) {
Manga manga = mangaMapper.selectById(id);
if (manga == null) {
throw new IllegalArgumentException("漫画不存在");
}
// 软删除:标记下架
manga.setPublishStatus(0);
mangaMapper.updateById(manga);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void setPublishStatus(Long id, Integer publishStatus) {
Manga manga = mangaMapper.selectById(id);
if (manga == null) {
throw new IllegalArgumentException("漫画不存在");
}
manga.setPublishStatus(publishStatus);
mangaMapper.updateById(manga);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void setRecommend(Long id, Integer isRecommend) {
Manga manga = mangaMapper.selectById(id);
if (manga == null) {
throw new IllegalArgumentException("漫画不存在");
}
manga.setIsRecommend(isRecommend);
mangaMapper.updateById(manga);
}
@Override
public MangaDetailVO getDetail(Long id, Long userId) {
Manga manga = mangaMapper.selectById(id);
if (manga == null) {
throw new IllegalArgumentException("漫画不存在");
}
// 青少年模式:非全年龄作品直接拒绝访问,防止绕过列表过滤直连详情
teenGuard.assertContentAllowed(userId, manga.getAgeRange());
Category category = categoryMapper.selectById(manga.getCategoryId());
MangaDetailVO vo = new MangaDetailVO();
vo.setId(manga.getId());
vo.setTitle(manga.getTitle());
vo.setAuthor(manga.getAuthor());
vo.setCover(manga.getCover());
vo.setDescription(manga.getDescription());
vo.setCategoryId(manga.getCategoryId());
vo.setCategoryName(category != null ? category.getName() : "");
vo.setStatus(manga.getStatus());
vo.setPriceType(manga.getPriceType());
vo.setPrice(manga.getPrice());
vo.setIsFree(manga.getIsFree());
vo.setAgeRange(manga.getAgeRange());
vo.setClickCount(manga.getClickCount());
vo.setFavoriteCount(manga.getFavoriteCount());
vo.setCommentCount(manga.getCommentCount());
vo.setTicketCount(manga.getTicketCount());
vo.setLastChapterId(manga.getLastChapterId());
vo.setLastChapterTitle(manga.getLastChapterTitle());
vo.setLastUpdateTime(manga.getLastUpdateTime());
// 查询标签
List<MangaTag> mangaTags = mangaTagMapper.selectList(
new LambdaQueryWrapper<MangaTag>().eq(MangaTag::getMangaId, id));
List<Map<String, Object>> tags = mangaTags.stream().map(mt -> {
Tag tag = tagMapper.selectById(mt.getTagId());
if (tag != null) {
Map<String, Object> t = new HashMap<>();
t.put("id", tag.getId());
t.put("name", tag.getName());
return t;
}
return null;
}).filter(Objects::nonNull).collect(Collectors.toList());
vo.setTags(tags);
// 查询章节列表(按章节号升序)
List<Chapter> chapters = chapterMapper.selectList(
new LambdaQueryWrapper<Chapter>()
.eq(Chapter::getMangaId, id)
.eq(Chapter::getStatus, 1)
.orderByAsc(Chapter::getChapterNo));
Set<Long> purchasedChapterIds = Collections.emptySet();
boolean userVip = false;
if (userId != null) {
User user = userMapper.selectById(userId);
userVip = user != null && user.getVipStatus() != null && user.getVipStatus() == 1
&& user.getVipExpire() != null && user.getVipExpire().isAfter(LocalDateTime.now());
purchasedChapterIds = userChapterPurchaseMapper.selectList(
new LambdaQueryWrapper<UserChapterPurchase>()
.eq(UserChapterPurchase::getUserId, userId)
.eq(UserChapterPurchase::getMangaId, id))
.stream()
.map(UserChapterPurchase::getChapterId)
.collect(Collectors.toSet());
}
final boolean isVip = userVip;
final Set<Long> purchasedIds = purchasedChapterIds;
vo.setChapterList(chapters.stream().map(c -> {
MangaDetailVO.ChapterVO cv = new MangaDetailVO.ChapterVO();
cv.setId(c.getId());
cv.setTitle(c.getTitle());
cv.setChapterNo(c.getChapterNo());
cv.setIsFree(c.getIsFree());
cv.setPrice(c.getPrice());
cv.setIsPurchased(c.getIsFree() == 1 || isVip || purchasedIds.contains(c.getId()));
|
|