From 6bcc35ced84d31d4abc4735a5142ce7f90bcaf58 Mon Sep 17 00:00:00 2001 From: glx <783262171@qq.com> Date: Wed, 10 Jun 2026 14:37:10 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=A2=86=E5=9F=9F=E6=97=A5?= =?UTF-8?q?=E8=AE=B0=20=E5=8A=A8=E7=89=A9=E7=AC=94=E8=AE=B0=20=E5=8F=AF?= =?UTF-8?q?=E8=A7=81=E6=80=A7=E6=9D=83=E9=99=90=E8=BF=87=E6=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/query/OwnAdoptionDiaryQuery.java | 5 + .../mini/model/query/OwnStrayAnimalQuery.java | 3 + .../boot/mini/model/vo/AdoptionDiaryVO.java | 3 + .../mini/model/vo/StrayAnimalShortVO.java | 3 + .../impl/AdoptionDiaryServiceImpl.java | 176 +++++++++++------ .../service/impl/MiniFollowServiceImpl.java | 8 +- .../service/impl/StrayAnimalServiceImpl.java | 177 ++++++++++++------ .../service/impl/UserPostServiceImpl.java | 7 +- .../mapper/mini/MiniAdoptionDiaryMapper.xml | 7 + .../mapper/mini/MiniStrayAnimalMapper.xml | 10 + 10 files changed, 282 insertions(+), 117 deletions(-) diff --git a/src/main/java/com/youlai/boot/mini/model/query/OwnAdoptionDiaryQuery.java b/src/main/java/com/youlai/boot/mini/model/query/OwnAdoptionDiaryQuery.java index 746edac..6104139 100644 --- a/src/main/java/com/youlai/boot/mini/model/query/OwnAdoptionDiaryQuery.java +++ b/src/main/java/com/youlai/boot/mini/model/query/OwnAdoptionDiaryQuery.java @@ -4,6 +4,8 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; +import java.util.List; + @EqualsAndHashCode(callSuper = true) @Data public class OwnAdoptionDiaryQuery extends AdoptionDiaryQuery{ @@ -20,4 +22,7 @@ public class OwnAdoptionDiaryQuery extends AdoptionDiaryQuery{ @Schema(description = "权限", example = "public", hidden = true) private String visibility; + @Schema(description = "允许的可见性列表(用于他人页面访问控制)", hidden = true) + private List allowedVisibilities; + } diff --git a/src/main/java/com/youlai/boot/mini/model/query/OwnStrayAnimalQuery.java b/src/main/java/com/youlai/boot/mini/model/query/OwnStrayAnimalQuery.java index bc38593..580c4e2 100644 --- a/src/main/java/com/youlai/boot/mini/model/query/OwnStrayAnimalQuery.java +++ b/src/main/java/com/youlai/boot/mini/model/query/OwnStrayAnimalQuery.java @@ -15,4 +15,7 @@ public class OwnStrayAnimalQuery extends StrayAnimalQuery { @Schema(description = "创建动物的用户ID", example = "1", hidden = true) private Long creatorId; + @Schema(description = "允许的可见性列表(用于他人页面访问控制)", hidden = true) + private java.util.List allowedVisibilities; + } diff --git a/src/main/java/com/youlai/boot/mini/model/vo/AdoptionDiaryVO.java b/src/main/java/com/youlai/boot/mini/model/vo/AdoptionDiaryVO.java index 7524cf8..3a0597c 100644 --- a/src/main/java/com/youlai/boot/mini/model/vo/AdoptionDiaryVO.java +++ b/src/main/java/com/youlai/boot/mini/model/vo/AdoptionDiaryVO.java @@ -12,6 +12,9 @@ public class AdoptionDiaryVO { @Schema(description = "领养日记ID", hidden = true) private Long id; + @Schema(description = "作者用户ID", hidden = true) + private Long miniUserId; + @Schema(description = "作者uuid") private String authorUuid; diff --git a/src/main/java/com/youlai/boot/mini/model/vo/StrayAnimalShortVO.java b/src/main/java/com/youlai/boot/mini/model/vo/StrayAnimalShortVO.java index 7184f69..5e6146b 100644 --- a/src/main/java/com/youlai/boot/mini/model/vo/StrayAnimalShortVO.java +++ b/src/main/java/com/youlai/boot/mini/model/vo/StrayAnimalShortVO.java @@ -10,6 +10,9 @@ public class StrayAnimalShortVO { @Schema(description = "笔记ID(仅用于瀑布流游标,前端不需要展示)", hidden = true) private Long id; + @Schema(description = "作者用户ID", hidden = true) + private Long miniUserId; + @Schema(description = "作者uuid", example = "true") private String authorUuid; diff --git a/src/main/java/com/youlai/boot/mini/service/impl/AdoptionDiaryServiceImpl.java b/src/main/java/com/youlai/boot/mini/service/impl/AdoptionDiaryServiceImpl.java index 200e616..ed77532 100644 --- a/src/main/java/com/youlai/boot/mini/service/impl/AdoptionDiaryServiceImpl.java +++ b/src/main/java/com/youlai/boot/mini/service/impl/AdoptionDiaryServiceImpl.java @@ -37,6 +37,7 @@ import com.youlai.boot.mini.model.query.AdoptionDiaryWaterfallQuery; import com.youlai.boot.mini.model.query.OwnAdoptionDiaryQuery; import com.youlai.boot.mini.model.vo.*; import com.youlai.boot.mini.service.AdoptionDiaryService; +import com.youlai.boot.mini.service.MiniFollowService; import com.youlai.boot.mini.service.StrayAnimalService; import com.youlai.boot.system.mapper.UserMapper; import com.youlai.boot.system.model.entity.SysUser; @@ -76,6 +77,7 @@ public class AdoptionDiaryServiceImpl extends ServiceImpl allowed = new ArrayList<>(); + allowed.add("public"); + if (followService.isMutualFollow(viewerId, authorId)) { + allowed.add("friends"); + } + queryParams.setAllowedVisibilities(allowed); + } + return getDiaryPage(queryParams); } @Override public AdoptionDiaryDetailsVO getDetails(String diaryUuid, Long miniUserId) { - // 校验动物是否存在 MiniAdoptionDiary diary = getValidDiary(diaryUuid); + if (!canViewDetail(diary, miniUserId)) { + throw new MsgException("该日记仅好友可见"); + } + AdoptionDiaryDetailsVO adoptionDiaryDetailsVO = new AdoptionDiaryDetailsVO(); if (diary != null) { @@ -800,66 +818,43 @@ public class AdoptionDiaryServiceImpl extends ServiceImpl getWaterfall(AdoptionDiaryWaterfallQuery query, Long userId) { - // 1. 设置默认值,查 N+1 条 int pageSize = query.getPageSize(); - int querySize = pageSize + 1; + // 取3倍数据,因为后续布隆+可见性两次过滤会丢掉一部分 + int fetchSize = pageSize * 3; - // 2. 从DB查询 N+1 条 原始未过滤数据 - List originalList = baseMapper.getWaterfall( - query.getCursor(), - querySize, - userId - ); + // 1. 从DB取原始数据(仅按id降序,不含过滤) + List rawList = baseMapper.getWaterfall(query.getCursor(), fetchSize, userId); - // 3. 先基于原始数据计算分页信息(完全不受过滤影响) - Long nextCursor = null; - boolean isLastPage = true; - if (CollUtil.isNotEmpty(originalList)) { - if (originalList.size() > pageSize) { - nextCursor = originalList.get(pageSize - 1).getId(); - isLastPage = false; - } - } else { + if (CollUtil.isEmpty(rawList)) { return WaterfallResult.of(Collections.emptyList(), null, true); } - // 4.布隆过滤已浏览内容 ========== - List resultList = originalList.stream().limit(pageSize).collect(Collectors.toList()); - // 仅登录用户做过滤 - if (userId != null && CollUtil.isNotEmpty(resultList)) { - try { - String bloomKey = BLOOM_VIEW_KEY_PREFIX + userId; - RBloomFilter bloomFilter = redissonClient.getBloomFilter(bloomKey); - if (bloomFilter.isExists()) { - // 布隆存在正常过滤 - resultList = resultList.stream() - .filter(item -> !bloomFilter.contains(item.getId())) - .collect(Collectors.toList()); - } else { - log.debug("用户{}布隆不存在,同步重建浏览记录", userId); - try { - // 同步重建近1年的浏览记录,对接口响应影响极小 - rebuildUserBloomFromDB(userId, 365); - // 重建完成后,立即用新布隆过滤当前页数据,用户第一页就生效 - RBloomFilter newBloomFilter = redissonClient.getBloomFilter(bloomKey); - if (newBloomFilter.isExists()) { - resultList = resultList.stream() - .filter(item -> !newBloomFilter.contains(item.getId())) - .collect(Collectors.toList()); - } - log.debug("用户{}布隆同步重建完成,本次已过滤已浏览内容", userId); - } catch (Exception ex) { - // 重建失败跳过过滤,不影响主流程,下次访问自动重试 - log.error("用户{}布隆同步重建失败,本次不过滤,下次访问自动重试", userId, ex); - } - } - } catch (Exception e) { - // Redis异常自动降级为不过滤,不影响用户正常使用,恢复后下次访问自动重建 - log.error("布隆操作异常,自动降级不过滤,userId:{}, cursor:{}", userId, query.getCursor(), e); - } + // DB返回了满3倍数据,说明后面可能还有更多 + boolean hasMore = rawList.size() >= fetchSize; + + // 2. 布隆过滤器去重:过滤当前用户已看过的内容 + List afterBloom = applyBloomDedup(rawList, userId); + + // 3. 可见性过滤 + List afterVisibility = applyVisibilityFilter(afterBloom, userId); + + // 4. 截取 pageSize 条作为本页结果 + List resultList = afterVisibility.stream().limit(pageSize).toList(); + + // 5. 游标逻辑 + Long nextCursor = null; + boolean isLastPage = true; + if (resultList.size() >= pageSize) { + nextCursor = resultList.get(pageSize - 1).getId(); + isLastPage = false; + } else if (hasMore) { + nextCursor = CollUtil.isNotEmpty(resultList) + ? resultList.get(resultList.size() - 1).getId() + : rawList.get(rawList.size() - 1).getId(); + isLastPage = false; } - // 5. 设置默认图片(原有逻辑不变) + // 6. 设置默认图片 if (CollUtil.isNotEmpty(resultList)) { resultList.forEach(item -> { if (StrUtil.isBlank(item.getFirstImageUrl())) { @@ -871,6 +866,77 @@ public class AdoptionDiaryServiceImpl extends ServiceImpl applyBloomDedup(List list, Long userId) { + if (userId == null || CollUtil.isEmpty(list)) { + return list; + } + try { + String bloomKey = BLOOM_VIEW_KEY_PREFIX + userId; + RBloomFilter bloomFilter = redissonClient.getBloomFilter(bloomKey); + if (bloomFilter.isExists()) { + return list.stream() + .filter(item -> !bloomFilter.contains(item.getId())) + .toList(); + } + log.debug("用户{}布隆不存在,同步重建浏览记录", userId); + try { + rebuildUserBloomFromDB(userId, 365); + RBloomFilter newBloomFilter = redissonClient.getBloomFilter(bloomKey); + if (newBloomFilter.isExists()) { + return list.stream() + .filter(item -> !newBloomFilter.contains(item.getId())) + .toList(); + } + } catch (Exception ex) { + log.error("用户{}布隆同步重建失败,本次不过滤,下次访问自动重试", userId, ex); + } + } catch (Exception e) { + log.error("布隆操作异常,自动降级不过滤,userId:{}", userId, e); + } + return list; + } + + private List applyVisibilityFilter(List list, Long viewerId) { + if (CollUtil.isEmpty(list)) { + return list; + } + if (viewerId == null) { + return list.stream() + .filter(item -> "public".equals(item.getVisibility())) + .toList(); + } + Set authorIds = list.stream() + .map(AdoptionDiaryVO::getMiniUserId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + Set mutualFollowIds = followService.filterMutualFollows(viewerId, authorIds); + return list.stream() + .filter(item -> canView(viewerId, item.getMiniUserId(), item.getVisibility(), mutualFollowIds)) + .toList(); + } + + private boolean canView(Long viewerId, Long authorId, String visibility, Set mutualFollowIds) { + if (authorId != null && viewerId.equals(authorId)) { + return true; + } + return switch (visibility != null ? visibility : "public") { + case "public" -> true; + case "friends" -> authorId != null && mutualFollowIds.contains(authorId); + default -> false; + }; + } + + private boolean canViewDetail(MiniAdoptionDiary diary, Long viewerId) { + if (viewerId != null && viewerId.equals(diary.getMiniUserId())) { + return true; + } + return switch (diary.getVisibility()) { + case "public" -> true; + case "friends" -> viewerId != null && followService.isMutualFollow(viewerId, diary.getMiniUserId()); + default -> false; + }; + } + @Override public void rebuildUserBloomFromDB(Long userId) { // days传0代表重建所有历史记录 diff --git a/src/main/java/com/youlai/boot/mini/service/impl/MiniFollowServiceImpl.java b/src/main/java/com/youlai/boot/mini/service/impl/MiniFollowServiceImpl.java index 28c4eb2..8b2d30f 100644 --- a/src/main/java/com/youlai/boot/mini/service/impl/MiniFollowServiceImpl.java +++ b/src/main/java/com/youlai/boot/mini/service/impl/MiniFollowServiceImpl.java @@ -99,7 +99,7 @@ public class MiniFollowServiceImpl implements MiniFollowService { if (CollUtil.isNotEmpty(members)) { return members.stream().map(Long::valueOf).collect(Collectors.toSet()); } - // Cold start: load from DB and cache + // 从数据库和缓存加载 List ids = followMapper.selectFollowingIds(userId); if (CollUtil.isNotEmpty(ids)) { String[] strIds = ids.stream().map(String::valueOf).toArray(String[]::new); @@ -118,7 +118,7 @@ public class MiniFollowServiceImpl implements MiniFollowService { if (CollUtil.isEmpty(candidateIds)) { return Collections.emptySet(); } - // I follow them + // Set iFollow = getFollowingIds(userId); if (CollUtil.isEmpty(iFollow)) { return Collections.emptySet(); @@ -133,13 +133,13 @@ public class MiniFollowServiceImpl implements MiniFollowService { if (Boolean.TRUE.equals(theyFollowMe)) { mutuals.add(candidateId); } else { - // Redis miss for their set, fallback to DB + // Redis没有,回退到DB判断 Long count = followMapper.selectCount(new LambdaQueryWrapper() .eq(MiniUserFollow::getFollowerId, candidateId) .eq(MiniUserFollow::getFollowedId, userId)); if (count != null && count > 0) { mutuals.add(candidateId); - // warm their cache + // 刷新缓存 refreshFollowingCache(candidateId); } } diff --git a/src/main/java/com/youlai/boot/mini/service/impl/StrayAnimalServiceImpl.java b/src/main/java/com/youlai/boot/mini/service/impl/StrayAnimalServiceImpl.java index 655ce13..3636e7f 100644 --- a/src/main/java/com/youlai/boot/mini/service/impl/StrayAnimalServiceImpl.java +++ b/src/main/java/com/youlai/boot/mini/service/impl/StrayAnimalServiceImpl.java @@ -57,6 +57,7 @@ import com.youlai.boot.mini.model.query.OwnStrayAnimalQuery; import com.youlai.boot.mini.model.query.WaterfallQuery; import com.youlai.boot.mini.model.vo.*; import com.youlai.boot.mini.service.MiniPointRecordService; +import com.youlai.boot.mini.service.MiniFollowService; import com.youlai.boot.mini.service.StrayAnimalService; import com.youlai.boot.system.mapper.UserMapper; import com.youlai.boot.system.model.entity.SysUser; @@ -129,6 +130,7 @@ public class StrayAnimalServiceImpl extends ServiceImpl() .eq(MiniStrayAnimalNote::getStrayAnimalId, animal.getId())); + if (appStrayAnimalNote != null && !canViewDetail(appStrayAnimalNote, miniUserId)) { + throw new MsgException("该笔记仅好友可见"); + } + if (appStrayAnimalNote != null) { Map param = new HashMap<>(); param.put("noteId", appStrayAnimalNote.getId()); @@ -876,8 +882,21 @@ public class StrayAnimalServiceImpl extends ServiceImpl allowed = new ArrayList<>(); + allowed.add("public"); + if (followService.isMutualFollow(viewerId, authorId)) { + allowed.add("friends"); + } + queryParams.setAllowedVisibilities(allowed); + } + return getAnimalPage(queryParams); } @@ -1005,67 +1024,42 @@ public class StrayAnimalServiceImpl extends ServiceImpl getWaterfall(WaterfallQuery query, Long userId) { - // 1. 设置默认值,查 N+1 条 int pageSize = query.getPageSize(); - int querySize = pageSize + 1; - - // 2. 从DB查询 N+1 条 原始未过滤数据 - List originalList = miniStrayAnimalMapper.getWaterfall( - query.getCursor(), - querySize, - query.getAnimalType(), - userId - ); + int fetchSize = pageSize * 3; - // 3. 先基于原始数据计算分页信息(完全不受过滤影响) - Long nextCursor = null; - boolean isLastPage = true; - if (CollUtil.isNotEmpty(originalList)) { - if (originalList.size() > pageSize) { - nextCursor = originalList.get(pageSize - 1).getId(); - isLastPage = false; - } - } else { + // 1. 从DB取原始数据(仅按id降序,不含过滤) + List rawList = miniStrayAnimalMapper.getWaterfall( + query.getCursor(), fetchSize, query.getAnimalType(), userId); + + if (CollUtil.isEmpty(rawList)) { return WaterfallResult.of(Collections.emptyList(), null, true); } - // 4.布隆过滤已浏览内容 ========== - List resultList = originalList.stream().limit(pageSize).collect(Collectors.toList()); - // 仅登录用户做过滤 - if (userId != null && CollUtil.isNotEmpty(resultList)) { - try { - String bloomKey = BLOOM_VIEW_KEY_PREFIX + userId; - RBloomFilter bloomFilter = redissonClient.getBloomFilter(bloomKey); - if (bloomFilter.isExists()) { - // 布隆存在正常过滤 - resultList = resultList.stream() - .filter(item -> !bloomFilter.contains(item.getId())) - .collect(Collectors.toList()); - } else { - log.debug("用户{}布隆不存在,同步重建浏览记录", userId); - try { - // 同步重建近1年的浏览记录,对接口响应影响极小 - rebuildUserBloomFromDB(userId, 365); - // 重建完成后,立即用新布隆过滤当前页数据,用户第一页就生效 - RBloomFilter newBloomFilter = redissonClient.getBloomFilter(bloomKey); - if (newBloomFilter.isExists()) { - resultList = resultList.stream() - .filter(item -> !newBloomFilter.contains(item.getId())) - .collect(Collectors.toList()); - } - log.debug("用户{}布隆同步重建完成,本次已过滤已浏览内容", userId); - } catch (Exception ex) { - // 重建失败跳过过滤,不影响主流程,下次访问自动重试 - log.error("用户{}布隆同步重建失败,本次不过滤,下次访问自动重试", userId, ex); - } - } - } catch (Exception e) { - // Redis异常自动降级为不过滤,不影响用户正常使用,恢复后下次访问自动重建 - log.error("布隆操作异常,自动降级不过滤,userId:{}, cursor:{}", userId, query.getCursor(), e); - } + boolean hasMore = rawList.size() >= fetchSize; + + // 2. 布隆过滤器去重 + List afterBloom = applyBloomDedup(rawList, userId); + + // 3. 可见性过滤 + List afterVisibility = applyVisibilityFilter(afterBloom, userId); + + // 4. 截取 pageSize 条作为本页结果 + List resultList = afterVisibility.stream().limit(pageSize).toList(); + + // 5. 游标逻辑 + Long nextCursor = null; + boolean isLastPage = true; + if (resultList.size() >= pageSize) { + nextCursor = resultList.get(pageSize - 1).getId(); + isLastPage = false; + } else if (hasMore) { + nextCursor = CollUtil.isNotEmpty(resultList) + ? resultList.get(resultList.size() - 1).getId() + : rawList.get(rawList.size() - 1).getId(); + isLastPage = false; } - // 5. 设置默认图片(原有逻辑不变) + // 6. 设置默认图片 if (CollUtil.isNotEmpty(resultList)) { resultList.forEach(item -> { if (StrUtil.isBlank(item.getFirstImageUrl())) { @@ -1087,6 +1081,77 @@ public class StrayAnimalServiceImpl extends ServiceImpl applyBloomDedup(List list, Long userId) { + if (userId == null || CollUtil.isEmpty(list)) { + return list; + } + try { + String bloomKey = BLOOM_VIEW_KEY_PREFIX + userId; + RBloomFilter bloomFilter = redissonClient.getBloomFilter(bloomKey); + if (bloomFilter.isExists()) { + return list.stream() + .filter(item -> !bloomFilter.contains(item.getId())) + .toList(); + } + log.debug("用户{}布隆不存在,同步重建浏览记录", userId); + try { + rebuildUserBloomFromDB(userId, 365); + RBloomFilter newBloomFilter = redissonClient.getBloomFilter(bloomKey); + if (newBloomFilter.isExists()) { + return list.stream() + .filter(item -> !newBloomFilter.contains(item.getId())) + .toList(); + } + } catch (Exception ex) { + log.error("用户{}布隆同步重建失败,本次不过滤,下次访问自动重试", userId, ex); + } + } catch (Exception e) { + log.error("布隆操作异常,自动降级不过滤,userId:{}", userId, e); + } + return list; + } + + private List applyVisibilityFilter(List list, Long viewerId) { + if (CollUtil.isEmpty(list)) { + return list; + } + if (viewerId == null) { + return list.stream() + .filter(item -> "public".equals(item.getVisibility())) + .toList(); + } + Set authorIds = list.stream() + .map(StrayAnimalShortVO::getMiniUserId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + Set mutualFollowIds = followService.filterMutualFollows(viewerId, authorIds); + return list.stream() + .filter(item -> canView(viewerId, item.getMiniUserId(), item.getVisibility(), mutualFollowIds)) + .toList(); + } + + private boolean canView(Long viewerId, Long authorId, String visibility, Set mutualFollowIds) { + if (authorId != null && viewerId.equals(authorId)) { + return true; + } + return switch (visibility != null ? visibility : "public") { + case "public" -> true; + case "friends" -> authorId != null && mutualFollowIds.contains(authorId); + default -> false; + }; + } + + private boolean canViewDetail(MiniStrayAnimalNote note, Long viewerId) { + if (viewerId != null && viewerId.equals(note.getMiniUserId())) { + return true; + } + return switch (note.getVisibility()) { + case "public" -> true; + case "friends" -> viewerId != null && followService.isMutualFollow(viewerId, note.getMiniUserId()); + default -> false; + }; + } + /** * 重建用户的所有浏览记录布隆过滤器(全量重建) * @param userId 用户ID diff --git a/src/main/java/com/youlai/boot/mini/service/impl/UserPostServiceImpl.java b/src/main/java/com/youlai/boot/mini/service/impl/UserPostServiceImpl.java index 644384a..aa67833 100644 --- a/src/main/java/com/youlai/boot/mini/service/impl/UserPostServiceImpl.java +++ b/src/main/java/com/youlai/boot/mini/service/impl/UserPostServiceImpl.java @@ -813,7 +813,7 @@ public class UserPostServiceImpl extends ServiceImpl mutualFollowIds = followService.filterMutualFollows(viewerId, authorIds); return list.stream() .filter(item -> canView(viewerId, item.getMiniUserId(), item.getVisibility(), mutualFollowIds)) diff --git a/src/main/resources/mapper/mini/MiniAdoptionDiaryMapper.xml b/src/main/resources/mapper/mini/MiniAdoptionDiaryMapper.xml index 88a20f8..ddd1dee 100644 --- a/src/main/resources/mapper/mini/MiniAdoptionDiaryMapper.xml +++ b/src/main/resources/mapper/mini/MiniAdoptionDiaryMapper.xml @@ -74,6 +74,12 @@ AND d.visibility = #{query.visibility} + + AND d.visibility IN + + #{v} + + AND d.create_timestamp >= #{query.createStartTimestamp} @@ -158,6 +164,7 @@ ) SELECT ad.id, + ad.mini_user_id AS miniUserId, u.uuid AS authorUuid, u.nickname AS authorName, u.avatar AS authorAvatar, diff --git a/src/main/resources/mapper/mini/MiniStrayAnimalMapper.xml b/src/main/resources/mapper/mini/MiniStrayAnimalMapper.xml index a5390cb..80ad4b2 100644 --- a/src/main/resources/mapper/mini/MiniStrayAnimalMapper.xml +++ b/src/main/resources/mapper/mini/MiniStrayAnimalMapper.xml @@ -139,6 +139,7 @@ a.uuid AS animalUuid, n.uuid AS animalNoteUuid, + n.mini_user_id AS miniUserId, a.animal_type, @@ -187,6 +188,14 @@ AND n.mini_user_id = #{queryParams.creatorId} + + + AND n.visibility IN + + #{v} + + + AND a.animal_type = #{queryParams.animalType} @@ -312,6 +321,7 @@ u.avatar AS authorAvatar, a.uuid AS animalUuid, n.uuid AS animalNoteUuid, + n.mini_user_id AS miniUserId, a.animal_type, fi.source_url AS firstImageUrl, n.title,