From 38426e20c1457035fbe4226b4959040c9d00e62b Mon Sep 17 00:00:00 2001 From: wangfukang <15630117759@163.com> Date: Sun, 14 Jun 2026 18:42:19 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AF=B9=E6=8E=A5=E6=8B=BC=E5=9B=A2=E6=95=B0?= =?UTF-8?q?=E6=8D=AE1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hiver-admin/test-output/test-report.html | 16 +- .../MallDeliveryOrderController.java | 14 ++ .../mall/ie/controller/IeController.java | 12 ++ .../cc/hiver/mall/ie/dto/IeMatchStartDTO.java | 4 + .../cc/hiver/mall/ie/dto/IeProfileDTO.java | 1 + .../hiver/mall/ie/entity/IeUserProfile.java | 1 + .../hiver/mall/ie/service/IeMatchService.java | 5 + .../ie/service/impl/IeChatServiceImpl.java | 26 +++ .../ie/service/impl/IeMatchServiceImpl.java | 179 ++++++++++++++++-- .../java/cc/hiver/mall/ie/vo/IeHomeVO.java | 2 + .../java/cc/hiver/mall/ie/vo/IeMatchVO.java | 1 + .../cc/hiver/mall/ie/vo/IeUserProfileVO.java | 1 + .../service/impl/PlanetDrawServiceImpl.java | 8 + .../service/impl/PlanetServiceImpl.java | 35 +--- .../service/impl/PlanetTaskServiceImpl.java | 6 +- .../quartz/PlanetAdventureSettleTask.java | 6 + .../mall/service/HomeReminderService.java | 20 ++ .../serviceimpl/HomeReminderServiceImpl.java | 138 ++++++++++++++ .../db/ie_user_profile_companion_intent.sql | 5 + 19 files changed, 424 insertions(+), 56 deletions(-) create mode 100644 hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/HomeReminderService.java create mode 100644 hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/HomeReminderServiceImpl.java create mode 100644 hiver-modules/hiver-mall/src/main/resources/db/ie_user_profile_companion_intent.sql diff --git a/hiver-admin/test-output/test-report.html b/hiver-admin/test-output/test-report.html index 99dab182..6af080fb 100644 --- a/hiver-admin/test-output/test-report.html +++ b/hiver-admin/test-output/test-report.html @@ -35,7 +35,7 @@ Hiver
  • -六月 13, 2026 16:59:20 +六月 14, 2026 18:24:58
  • @@ -84,7 +84,7 @@

    passTest

    -

    16:59:20 下午 / 0.022 secs

    +

    18:24:59 下午 / 0.034 secs

    @@ -92,9 +92,9 @@
    #test-id=1
    passTest
    -06.13.2026 16:59:20 -06.13.2026 16:59:20 -0.022 secs +06.14.2026 18:24:59 +06.14.2026 18:24:59 +0.034 secs
    @@ -104,7 +104,7 @@ Pass - 16:59:20 + 18:24:59 Test passed @@ -128,13 +128,13 @@

    Started

    -

    六月 13, 2026 16:59:20

    +

    六月 14, 2026 18:24:58

    Ended

    -

    六月 13, 2026 16:59:20

    +

    六月 14, 2026 18:24:59

    diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/MallDeliveryOrderController.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/MallDeliveryOrderController.java index d6c3ac40..e0c6053a 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/MallDeliveryOrderController.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/MallDeliveryOrderController.java @@ -15,6 +15,7 @@ import cc.hiver.mall.pojo.query.MallDeliveryOrderPageQuery; import cc.hiver.mall.pojo.vo.WorkerRedisVo; import cc.hiver.mall.pojo.vo.WorkerRewardVO; import cc.hiver.mall.quartz.WorkerRewardTask; +import cc.hiver.mall.service.HomeReminderService; import cc.hiver.mall.service.mybatis.DealingsRecordService; import cc.hiver.mall.service.mybatis.MallAdPositionService; import cc.hiver.mall.service.mybatis.MallDeliveryOrderService; @@ -76,6 +77,9 @@ public class MallDeliveryOrderController { @Autowired private WaitOrderCacheUtil waitOrderCacheUtil; + @Autowired + private HomeReminderService homeReminderService; + /** * 鍒嗛〉鏌ヨ閰嶉佸崟 * hallOnly=true 鏃舵煡璇㈡姠鍗曞ぇ鍘咃紙鏈鎺ュ崟鐨勫崟锛 @@ -143,9 +147,19 @@ public class MallDeliveryOrderController { } } } + cacheResult.put("homeReminders", homeReminderService.homeReminders(currentUserId(), q.getRegionId())); return new ResultUtil().setData(cacheResult); } + private String currentUserId() { + try { + User user = securityUtil.getCurrUser(); + return user == null ? null : user.getId(); + } catch (Exception ignored) { + return null; + } + } + @PostMapping("/countOrderByStatus") @ApiOperation(value = "鏌ヨ褰撳墠閰嶉佸憳鎸囨淳鍗曞拰宸叉帴鍗曟暟閲") public Result>> countOrderByStatus(@RequestParam(value = "workerId") String workerId, diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/controller/IeController.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/controller/IeController.java index 3ec228d3..a7c14bb1 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/controller/IeController.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/controller/IeController.java @@ -98,6 +98,18 @@ public class IeController { return new ResultUtil().setData(matchService.startMatch(currentUserId(), dto)); } + @RequestMapping(value = "/profiles/{targetUserId}/match", method = RequestMethod.POST) + @ApiOperation("瀵规寚瀹氱敤鎴峰彂璧烽櫔浼") + public Result matchProfile(@PathVariable Long targetUserId) { + return new ResultUtil().setData(matchService.matchWithUser(currentUserId(), targetUserId)); + } + + @RequestMapping(value = "/companion-intents", method = RequestMethod.GET) + @ApiOperation("鏌ヨ鏈鏂版壘鎼瓙鍐呭") + public Result>> companionIntents(@RequestParam(required = false, defaultValue = "50") Integer limit) { + return new ResultUtil>>().setData(matchService.latestCompanionIntents(currentUserId(), limit)); + } + @RequestMapping(value = "/matches/page", method = RequestMethod.GET) @ApiOperation("鍒嗛〉鏌ヨ鎴戠殑鍖归厤璁板綍") public Result> pageMatches(@RequestParam(required = false, defaultValue = "1") Integer pageNumber, diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/dto/IeMatchStartDTO.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/dto/IeMatchStartDTO.java index ba81db78..ded96ec0 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/dto/IeMatchStartDTO.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/dto/IeMatchStartDTO.java @@ -12,6 +12,10 @@ public class IeMatchStartDTO { private String matchScope; /** 鎼瓙鎰忓浘锛歮ilktea濂惰尪/meal鍚冮キ/study鑷範/walk鏁f/chat鍙兂鑱婅亰 */ private String intent; + /** 鐢ㄦ埛鑷敱杈撳叆鐨勬壘鎼瓙鍐呭 */ + private String companionIntent; + /** 寮瑰眰妯$硦鎼滅储鍐呭 */ + private String fuzzyKeyword; private String mood; private Double longitude; private Double latitude; diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/dto/IeProfileDTO.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/dto/IeProfileDTO.java index 6faf9297..89e992e8 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/dto/IeProfileDTO.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/dto/IeProfileDTO.java @@ -11,6 +11,7 @@ public class IeProfileDTO { private String avatarUrl; private String gender; private String intro; + private String companionIntent; private List interestTags; private List personaImages; private String currentMode; diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/entity/IeUserProfile.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/entity/IeUserProfile.java index 4db57db2..acc00fe2 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/entity/IeUserProfile.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/entity/IeUserProfile.java @@ -16,6 +16,7 @@ public class IeUserProfile extends IeBaseEntity { private String avatarUrl; private String gender; private String intro; + private String companionIntent; private String interestTags; private String personaImages; private String currentMode; diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/service/IeMatchService.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/service/IeMatchService.java index a60be181..31395558 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/service/IeMatchService.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/service/IeMatchService.java @@ -8,6 +8,9 @@ import cc.hiver.mall.ie.vo.IeMatchVO; import cc.hiver.mall.ie.vo.IeUserProfileVO; import com.baomidou.mybatisplus.core.metadata.IPage; +import java.util.List; +import java.util.Map; + public interface IeMatchService { IeHomeVO home(Long userId); @@ -25,6 +28,8 @@ public interface IeMatchService { IeMatchVO matchWithUser(Long userId, Long targetUserId); + List> latestCompanionIntents(Long currentUserId, Integer limit); + IPage pageMatches(Long userId, Integer pageNumber, Integer pageSize); void rewardMatchQuota(Long userId, Integer amount); diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/service/impl/IeChatServiceImpl.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/service/impl/IeChatServiceImpl.java index 7abdef17..d111681a 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/service/impl/IeChatServiceImpl.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/service/impl/IeChatServiceImpl.java @@ -13,6 +13,7 @@ import cc.hiver.mall.ie.vo.IeAliyunModerationResult; import cc.hiver.mall.ie.vo.IeAuditResult; import cc.hiver.mall.ie.vo.IeChatEvent; import cc.hiver.mall.ie.vo.IeMessageAckVO; +import cc.hiver.mall.service.HomeReminderService; import cn.hutool.core.text.CharSequenceUtil; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -76,6 +77,9 @@ public class IeChatServiceImpl implements IeChatService { @Autowired private StringRedisTemplate stringRedisTemplate; + @Autowired + private HomeReminderService homeReminderService; + private static final String STREAK_REWARD_KEY = "ie:streak:reward:"; private static final int STREAK_LOOKBACK_DAYS = 60; private static final int STREAK_REWARD_INTERVAL = 7; @@ -173,6 +177,7 @@ public class IeChatServiceImpl implements IeChatService { messagingTemplate.convertAndSendToUser(String.valueOf(senderId), "/queue/ie/ack", ack); if (message.getIsBlocked() == 0 && !needMediaAudit) { deliverMessage(message, ack); + homeReminderService.incrementIeUnread(receiverId); } else if (message.getIsBlocked() == 0) { afterCommitOrNow(() -> { chatEventProducer.sendMediaAudit(message.getId()); @@ -649,6 +654,7 @@ public class IeChatServiceImpl implements IeChatService { } IeMessageAckVO ack = buildAck(message, null); deliverMessage(message, ack); + homeReminderService.incrementIeUnread(message.getReceiverId()); messagingTemplate.convertAndSendToUser(String.valueOf(message.getSenderId()), "/queue/ie/ack", ack); } @@ -765,6 +771,26 @@ public class IeChatServiceImpl implements IeChatService { record.setLastReadTime(new Date()); record.setUpdateTime(new Date()); recordMapper.updateById(record); + homeReminderService.setIeUnreadCount(userId, totalUnreadCount(userId)); + } + + private int totalUnreadCount(Long userId) { + List records = recordMapper.selectList(new LambdaQueryWrapper() + .eq(IeRecord::getUserId, userId)); + int total = 0; + for (IeRecord record : records) { + if (record.getRoomId() == null || record.getTargetUserId() == null) { + continue; + } + Long count = roomMessageMapper.selectCount(new LambdaQueryWrapper() + .eq(IeRoomMessage::getRoomId, record.getRoomId()) + .eq(IeRoomMessage::getSenderId, record.getTargetUserId()) + .eq(IeRoomMessage::getReceiverId, userId) + .eq(IeRoomMessage::getIsBlocked, 0) + .gt(record.getLastReadTime() != null, IeRoomMessage::getCreateTime, record.getLastReadTime())); + total += count == null ? 0 : count.intValue(); + } + return total; } /** diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/service/impl/IeMatchServiceImpl.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/service/impl/IeMatchServiceImpl.java index d40ab903..8ca506d7 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/service/impl/IeMatchServiceImpl.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/service/impl/IeMatchServiceImpl.java @@ -11,6 +11,7 @@ import cc.hiver.mall.ie.service.IeMatchService; import cc.hiver.mall.ie.service.IeRedisService; import cc.hiver.mall.ie.service.IeSecurityAuditService; import cc.hiver.mall.ie.vo.*; +import cc.hiver.mall.service.HomeReminderService; import cn.hutool.core.util.IdUtil; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -57,6 +58,9 @@ public class IeMatchServiceImpl implements IeMatchService { @Autowired private IeAliyunModerationService aliyunModerationService; + @Autowired + private HomeReminderService homeReminderService; + @Override public IeHomeVO home(Long userId) { IeUserProfile profile = ensureProfile(userId); @@ -70,7 +74,7 @@ public class IeMatchServiceImpl implements IeMatchService { vo.setWaitingCount(redisService.waitingCount(profile.getCurrentMode(), currentMood, profile.getRegionId(), hasText(profile.getRegionId()))); vo.setDailyQuota(effectiveDailyQuota(profile)); vo.setUsedQuota((int) redisService.todayUsedQuota(userId)); - vo.setUnreadCount(totalUnreadCount(userId)); + vo.setUnreadCount(cachedUnreadCount(userId)); vo.setCurrentMode(profile.getCurrentMode()); vo.setCurrentMood(currentMood); vo.setTargetModePreference(profile.getTargetModePreference()); @@ -78,12 +82,18 @@ public class IeMatchServiceImpl implements IeMatchService { vo.setProfileCompleted(profile.getProfileCompleted() == null ? 0 : profile.getProfileCompleted()); vo.setProfile(toProfileVO(profile)); vo.setHotStatuses(redisService.hotStatuses(8)); + vo.setCompanionIntents(latestCompanionIntents(userId, 50)); return vo; } @Override public int unreadCount(Long userId) { - return totalUnreadCount(userId); + return cachedUnreadCount(userId); + } + + private int cachedUnreadCount(Long userId) { + Integer cached = homeReminderService.getIeUnreadCount(userId); + return cached == null ? 0 : cached; } private int totalUnreadCount(Long userId) { @@ -141,6 +151,7 @@ public class IeMatchServiceImpl implements IeMatchService { // 鏄电О/涓鍙ヨ瘽浠嬬粛鍗曠嫭瀹★紙鍙栬繃婊ゅ悗鐨勬枃妗堬級锛屽ご鍍忓瓧銆佸叴瓒f爣绛俱佸湴鍖哄悕鍚堝苟鎴愪竴娆″鏍革紙鍙垽鎷︽埅锛 String anonymousName = auditProfileText("profile-name", userId, defaultText(dto.getAnonymousName(), profile.getAnonymousName())); String intro = auditProfileText("profile-intro", userId, defaultText(dto.getIntro(), "")); + String companionIntent = auditCompanionIntent(userId, defaultText(dto.getCompanionIntent(), profile.getCompanionIntent())); String avatarText = defaultText(dto.getAvatarText(), "鎴"); StringBuilder extraText = new StringBuilder(avatarText); if (dto.getInterestTags() != null) { @@ -162,6 +173,7 @@ public class IeMatchServiceImpl implements IeMatchService { } profile.setGender(normalizeGender(dto.getGender(), "unknown")); profile.setIntro(intro); + profile.setCompanionIntent(companionIntent); profile.setInterestTags(tagsToJson(dto.getInterestTags())); // 浜烘牸鍗$墖鍥剧墖锛氬彧瀹℃湰娆℃柊澧炵殑锛屽凡閫氳繃鐨勬棫鍥句笉閲嶅閫佸 if (dto.getPersonaImages() != null) { @@ -312,14 +324,20 @@ public class IeMatchServiceImpl implements IeMatchService { } statusDTO.setRegionId(regionId); statusDTO.setRegionName(regionName); + auditAndSaveMatchCompanionIntent(userId, profile, dto == null ? null : dto.getCompanionIntent()); updateStatus(userId, statusDTO); String mood = statusDTO.getMood() == null ? "quiet" : statusDTO.getMood(); String intent = normalizeIntent(dto == null ? null : dto.getIntent()); if (intent != null) { redisService.addToIntentPool(intent, userId); } - List candidates = candidateUsers(targetMode, mode, mood, regionId, regionScope); - if (intent != null) { + String fuzzyKeyword = normalizeFuzzyKeyword(dto == null ? null : dto.getFuzzyKeyword()); + boolean fuzzySearch = hasText(fuzzyKeyword); + List candidates = fuzzySearch ? fuzzyCandidates(userId, fuzzyKeyword, 80) : new ArrayList<>(); + if (candidates.isEmpty()) { + candidates = candidateUsers(targetMode, mode, mood, regionId, regionScope); + } + if (!fuzzySearch && intent != null) { // 鍚屾剰鍥剧殑浜轰紭鍏堣繘鍏ュ欓夛紙鍘婚噸浜ょ粰 LinkedHashSet 閫昏緫鍓嶇疆锛 List intentUsers = redisService.intentCandidates(intent, 50); intentUsers.removeAll(candidates); @@ -350,6 +368,9 @@ public class IeMatchServiceImpl implements IeMatchService { if (intent != null && redisService.inIntentPool(intent, candidateUserId)) { score += 200; } + if (fuzzySearch) { + score += fuzzyFieldScore(candidateProfile, fuzzyKeyword); + } matchedCandidates.add(new MatchCandidate(candidateUserId, score)); } for (MatchCandidate candidate : randomizeCandidates(matchedCandidates)) { @@ -403,13 +424,7 @@ public class IeMatchServiceImpl implements IeMatchService { } vo.setRoomId(room.getId()); vo.setRoomNo(room.getRoomNo()); - vo.setAvatarUrl(targetProfile.getAvatarUrl()); - vo.setGender(targetProfile.getGender()); - vo.setRegionId(targetProfile.getRegionId()); - vo.setRegionName(targetProfile.getRegionName()); - vo.setIntro(targetProfile.getIntro()); - vo.setInterestTags(jsonToTags(targetProfile.getInterestTags())); - vo.setPersonaImages(jsonToTags(targetProfile.getPersonaImages())); + fillMatchTargetProfile(vo, targetProfile); vo.setLastActiveText(lastActiveText(targetUserId, targetProfile, statusActiveMap.get(targetUserId))); vo.setIntent(intent); vo.setIntentMatched(intent != null && redisService.inIntentPool(intent, targetUserId)); @@ -444,7 +459,11 @@ public class IeMatchServiceImpl implements IeMatchService { if (hasBlockRelation(userId, targetUserId)) { throw new RuntimeException("浣犱滑涔嬮棿瀛樺湪榛戝悕鍗曞叧绯伙紝鏃犳硶鍙戣捣闄即"); } - IeUserProfile targetProfile = ensureProfile(targetUserId); + IeUserProfile targetProfile = findProfileByUserId(targetUserId); + if (targetProfile == null || targetProfile.getProfileCompleted() == null || targetProfile.getProfileCompleted() != 1 + || Integer.valueOf(1).equals(targetProfile.getIsDeleted())) { + throw new RuntimeException("瀵规柟璧勬枡涓嶅瓨鍦ㄦ垨鏆備笉鍙尮閰"); + } IeRoom existing = findReusableRoom(userId, targetUserId); boolean hasExistingRelation = existing != null || hasRoomRelation(userId, targetUserId); long maxQuota = effectiveDailyQuota(profile); @@ -481,13 +500,7 @@ public class IeMatchServiceImpl implements IeMatchService { IeMatchVO vo = toMatchVO(match); vo.setRoomId(room.getId()); vo.setRoomNo(room.getRoomNo()); - vo.setAvatarUrl(targetProfile.getAvatarUrl()); - vo.setGender(targetProfile.getGender()); - vo.setRegionId(targetProfile.getRegionId()); - vo.setRegionName(targetProfile.getRegionName()); - vo.setIntro(targetProfile.getIntro()); - vo.setInterestTags(jsonToTags(targetProfile.getInterestTags())); - vo.setPersonaImages(jsonToTags(targetProfile.getPersonaImages())); + fillMatchTargetProfile(vo, targetProfile); return vo; } catch (RuntimeException e) { if (!hasExistingRelation) { @@ -557,13 +570,55 @@ public class IeMatchServiceImpl implements IeMatchService { if (profile == null) { return; } + fillMatchTargetProfile(vo, profile); + } + + private void fillMatchTargetProfile(IeMatchVO vo, IeUserProfile profile) { + if (vo == null || profile == null) { + return; + } vo.setAnonymousName(defaultText(profile.getAnonymousName(), vo.getAnonymousName())); vo.setAvatarText(defaultText(profile.getAvatarText(), vo.getAvatarText())); vo.setAvatarUrl(profile.getAvatarUrl()); + vo.setGender(profile.getGender()); vo.setRegionId(defaultText(profile.getRegionId(), vo.getRegionId())); vo.setRegionName(defaultText(profile.getRegionName(), vo.getRegionName())); vo.setMode(defaultText(profile.getCurrentMode(), vo.getMode())); + vo.setIntro(profile.getIntro()); vo.setQuoteText(defaultText(profile.getIntro(), vo.getQuoteText())); + vo.setCompanionIntent(profile.getCompanionIntent()); + vo.setInterestTags(jsonToTags(profile.getInterestTags())); + vo.setPersonaImages(jsonToTags(profile.getPersonaImages())); + } + + @Override + public List> latestCompanionIntents(Long currentUserId, Integer limit) { + int safeLimit = limit == null ? 50 : Math.max(1, Math.min(limit, 50)); + List profiles = userProfileMapper.selectList(new LambdaQueryWrapper() + .eq(IeUserProfile::getProfileCompleted, 1) + .eq(IeUserProfile::getIsDeleted, 0) + .isNotNull(IeUserProfile::getCompanionIntent) + .ne(IeUserProfile::getCompanionIntent, "") + .orderByDesc(IeUserProfile::getUpdateTime) + .last("limit " + safeLimit)); + List> items = new ArrayList<>(); + for (IeUserProfile profile : profiles) { + if (profile == null || !hasText(profile.getCompanionIntent())) { + continue; + } + Map item = new HashMap<>(); + // 灏忕▼搴忕 JS Number 浼氫涪澶 Long 绮惧害锛屽畾鍚戝尮閰嶅繀椤荤敤瀛楃涓叉壙杞界湡瀹 userId銆 + item.put("userId", String.valueOf(profile.getUserId())); + item.put("isSelf", Objects.equals(profile.getUserId(), currentUserId)); + item.put("text", profile.getCompanionIntent()); + item.put("type", normalizeMode(profile.getCurrentMode(), "i")); + item.put("mood", "talk"); + item.put("anonymousName", defaultText(profile.getAnonymousName(), "鍗婂尶鍚嶆紓娴佽")); + item.put("avatarText", defaultText(profile.getAvatarText(), "鈼")); + item.put("avatarUrl", profile.getAvatarUrl()); + items.add(item); + } + return items; } private IeRoom createRoom(IeMatchAttempt match, Long userId, Long targetUserId, String mode, String mood) { @@ -852,6 +907,31 @@ public class IeMatchServiceImpl implements IeMatchService { return score; } + /** + * 妯$硦鎼滅储鍙湪鍛戒腑鐨勭敤鎴烽泦鍚堝唴鎸戞渶閫傚悎鐨勪汉锛涘瓧娈典紭鍏堢骇锛氭樀绉 > 涓鍙ヨ瘽绛惧悕 > 鎵炬惌瀛愬唴瀹广 + */ + private int fuzzyFieldScore(IeUserProfile profile, String keyword) { + if (profile == null || !hasText(keyword)) { + return 0; + } + String key = keyword.trim(); + int score = 0; + if (containsText(profile.getAnonymousName(), key)) { + score += 300; + } + if (containsText(profile.getIntro(), key)) { + score += 200; + } + if (containsText(profile.getCompanionIntent(), key)) { + score += 120; + } + return score; + } + + private boolean containsText(String value, String keyword) { + return value != null && keyword != null && value.contains(keyword); + } + /** * 闅忔満鍖栧欓夐『搴忥細鍏堟墦涔卞啀鎸夊緱鍒嗙ǔ瀹氭帓搴忥紙鍚屽垎椤哄簭闅忔満锛夛紝 * 鐒跺悗鍦ㄥ緱鍒嗘渶楂樼殑涓鎵归噷鏁翠綋闅忔満锛岄伩鍏嶆瘡娆¢兘鎸夊浐瀹氶『搴忓尮閰嶅埌鍚屼竴涓汉銆 @@ -930,6 +1010,33 @@ public class IeMatchServiceImpl implements IeMatchService { return users; } + private List fuzzyCandidates(Long currentUserId, String keyword, int limit) { + if (!hasText(keyword)) { + return new ArrayList<>(); + } + String like = "%" + keyword.trim() + "%"; + LambdaQueryWrapper query = new LambdaQueryWrapper() + .eq(IeUserProfile::getProfileCompleted, 1) + .eq(IeUserProfile::getIsDeleted, 0) + .ne(currentUserId != null, IeUserProfile::getUserId, currentUserId) + .and(wrapper -> wrapper + .like(IeUserProfile::getAnonymousName, like) + .or() + .like(IeUserProfile::getIntro, like) + .or() + .like(IeUserProfile::getCompanionIntent, like)) + .orderByDesc(IeUserProfile::getLastActiveTime) + .last("limit " + Math.max(1, Math.min(limit, 100))); + List profiles = userProfileMapper.selectList(query); + List users = new ArrayList<>(); + for (IeUserProfile profile : profiles) { + if (profile.getUserId() != null) { + users.add(profile.getUserId()); + } + } + return users; + } + private String auditProfileText(String bizType, Long userId, String content) { IeAuditResult result = auditService.audit(bizType, userId, userId, content); if (Boolean.TRUE.equals(result.getBlocked())) { @@ -938,6 +1045,31 @@ public class IeMatchServiceImpl implements IeMatchService { return result.getFilteredContent(); } + private String auditCompanionIntent(Long userId, String content) { + if (!hasText(content)) { + return ""; + } + String trimmed = content.trim(); + if (trimmed.length() > 24) { + throw new RuntimeException("鎵炬惌瀛愬唴瀹逛笉鑳借秴杩 24 涓瓧"); + } + return auditProfileText("profile-companion-intent", userId, trimmed); + } + + private String auditAndSaveMatchCompanionIntent(Long userId, IeUserProfile profile, String content) { + if (!hasText(content)) { + return profile == null ? "" : defaultText(profile.getCompanionIntent(), ""); + } + String audited = auditCompanionIntent(userId, content); + if (profile != null && !Objects.equals(profile.getCompanionIntent(), audited)) { + profile.setCompanionIntent(audited); + profile.setUpdateTime(new Date()); + profile.setLastActiveTime(new Date()); + userProfileMapper.updateById(profile); + } + return audited; + } + private void auditProfileImage(String imageUrl, String existingUrl) { if (imageUrl == null || imageUrl.trim().isEmpty() || imageUrl.equals(existingUrl)) { return; @@ -959,6 +1091,7 @@ public class IeMatchServiceImpl implements IeMatchService { vo.setAvatarUrl(profile.getAvatarUrl()); vo.setGender(profile.getGender()); vo.setIntro(profile.getIntro()); + vo.setCompanionIntent(profile.getCompanionIntent()); vo.setInterestTags(jsonToTags(profile.getInterestTags())); vo.setPersonaImages(jsonToTags(profile.getPersonaImages())); vo.setCurrentMode(profile.getCurrentMode()); @@ -1031,6 +1164,14 @@ public class IeMatchServiceImpl implements IeMatchService { return "school"; } + private String normalizeFuzzyKeyword(String value) { + if (!hasText(value)) { + return ""; + } + String keyword = value.trim(); + return keyword.length() > 24 ? keyword.substring(0, 24) : keyword; + } + private boolean hasText(String value) { return value != null && !value.trim().isEmpty(); } diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/vo/IeHomeVO.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/vo/IeHomeVO.java index 4f5efc60..f730b388 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/vo/IeHomeVO.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/vo/IeHomeVO.java @@ -3,6 +3,7 @@ package cc.hiver.mall.ie.vo; import lombok.Data; import java.util.List; +import java.util.Map; @Data public class IeHomeVO { @@ -18,4 +19,5 @@ public class IeHomeVO { private Integer profileCompleted; private IeUserProfileVO profile; private List hotStatuses; + private List> companionIntents; } diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/vo/IeMatchVO.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/vo/IeMatchVO.java index 129bf151..5e3d217c 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/vo/IeMatchVO.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/vo/IeMatchVO.java @@ -17,6 +17,7 @@ public class IeMatchVO { private String regionId; private String regionName; private String intro; + private String companionIntent; private List interestTags; private List personaImages; private String mode; diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/vo/IeUserProfileVO.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/vo/IeUserProfileVO.java index a52bd113..671bac89 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/vo/IeUserProfileVO.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/ie/vo/IeUserProfileVO.java @@ -12,6 +12,7 @@ public class IeUserProfileVO { private String avatarUrl; private String gender; private String intro; + private String companionIntent; private List interestTags; private List personaImages; private String currentMode; diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/planet/service/impl/PlanetDrawServiceImpl.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/planet/service/impl/PlanetDrawServiceImpl.java index 207ca587..a5cb5ded 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/planet/service/impl/PlanetDrawServiceImpl.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/planet/service/impl/PlanetDrawServiceImpl.java @@ -13,6 +13,7 @@ import cc.hiver.mall.planet.service.PlanetDrawService; import cc.hiver.mall.planet.service.PlanetNewsService; import cc.hiver.mall.planet.service.PlanetTaskService; import cc.hiver.mall.planet.service.PlanetTicketService; +import cc.hiver.mall.service.HomeReminderService; import cc.hiver.mall.service.mybatis.DealingsRecordService; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import lombok.extern.slf4j.Slf4j; @@ -80,6 +81,9 @@ public class PlanetDrawServiceImpl implements PlanetDrawService { @Autowired private DealingsRecordService dealingsRecordService; + @Autowired + private HomeReminderService homeReminderService; + /** * 鎶藉鍔熻兘寮哄埗鎸夊晢鍦堥殧绂伙細缂哄皯 regionId 鐩存帴鎷掔粷锛屾潨缁濊法鍖哄煙寮濂/鏌ヨ銆 */ @@ -449,6 +453,7 @@ public class PlanetDrawServiceImpl implements PlanetDrawService { winner.setIsRead(1); winner.setReadTime(new Date()); drawWinnerMapper.updateById(winner); + homeReminderService.clearPlanetReminders(userId, regionId); } @Override @@ -480,6 +485,7 @@ public class PlanetDrawServiceImpl implements PlanetDrawService { winner.setReadTime(new Date()); } drawWinnerMapper.updateById(winner); + homeReminderService.clearPlanetReminders(userId, regionId); DealingsRecord dealingsRecord = new DealingsRecord(); dealingsRecord.setDealingsWay(DealingsRecordConstant.TYPE_REMARK[8]); @@ -523,6 +529,8 @@ public class PlanetDrawServiceImpl implements PlanetDrawService { winner.setIsRead(0); winner.setCreateTime(now); drawWinnerMapper.insert(winner); + homeReminderService.addPlanetReward(ticket.getUserId(), record.getRegionId(), "draw", + "鐧藉珫鏄熺悆涓鍟", winner.getId()); } private List usableCandidates(List pool, Set cooldownUsers) { diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/planet/service/impl/PlanetServiceImpl.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/planet/service/impl/PlanetServiceImpl.java index 2d130de2..ee5da3b3 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/planet/service/impl/PlanetServiceImpl.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/planet/service/impl/PlanetServiceImpl.java @@ -1,21 +1,23 @@ package cc.hiver.mall.planet.service.impl; import cc.hiver.mall.planet.constant.PlanetConstant; -import cc.hiver.mall.planet.entity.*; +import cc.hiver.mall.planet.entity.PlanetPool; +import cc.hiver.mall.planet.entity.PlanetPoolTicket; +import cc.hiver.mall.planet.entity.PlanetReward; +import cc.hiver.mall.planet.entity.PlanetTicket; import cc.hiver.mall.planet.mapper.PlanetPoolTicketMapper; import cc.hiver.mall.planet.mapper.PlanetRewardMapper; -import cc.hiver.mall.planet.mapper.PlanetTicketLogMapper; import cc.hiver.mall.planet.pojo.PlanetDailyLoopVo; import cc.hiver.mall.planet.pojo.PlanetHomeVo; import cc.hiver.mall.planet.pojo.PlanetQuery; import cc.hiver.mall.planet.service.*; +import cc.hiver.mall.service.HomeReminderService; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.math.RoundingMode; -import java.util.Calendar; import java.util.Date; import java.util.List; @@ -55,15 +57,16 @@ public class PlanetServiceImpl implements PlanetService { private PlanetPoolTicketMapper poolTicketMapper; @Autowired - private PlanetTicketLogMapper ticketLogMapper; + private PlanetRewardMapper rewardMapper; @Autowired - private PlanetRewardMapper rewardMapper; + private HomeReminderService homeReminderService; @Override public PlanetHomeVo home(PlanetQuery query) { final String userId = query.getUserId(); final String regionId = query.getRegionId(); + homeReminderService.clearPlanetReminders(userId, regionId); final PlanetHomeVo vo = new PlanetHomeVo(); // 鍒濆鍖/琛ュ叏鐢ㄦ埛鍒歌褰 @@ -93,8 +96,8 @@ public class PlanetServiceImpl implements PlanetService { vo.setRemainHunt(huntService.remainHunt(userId)); vo.setLevel(PlanetConstant.dangerLevel(vo.getMyTicketCount())); vo.setMyRankNo(rankService.userRankNo(regionId, userId)); + vo.setRankList(rankService.rankTop(regionId, 10, userId)); vo.setDailyLoop(lightDailyLoop(userId, regionId, pool)); - vo.setUnreadWinning(drawService.unreadWinning(userId, regionId)); return vo; } @@ -130,7 +133,6 @@ public class PlanetServiceImpl implements PlanetService { final int suggested = myTickets <= 0 ? 3 : Math.min(10, Math.max(1, total / 20)); vo.setSuggestedAddTickets(suggested); vo.setSuggestedProbability(probability(calcWeightTickets(myTickets + suggested), weightTotal - myWeight + calcWeightTickets(myTickets + suggested))); - vo.setTodayCollectedTickets(todayCollectedTickets(userId, regionId)); return vo; } @@ -156,25 +158,6 @@ public class PlanetServiceImpl implements PlanetService { return total; } - private Integer todayCollectedTickets(String userId, String regionId) { - final Calendar c = Calendar.getInstance(); - c.set(Calendar.HOUR_OF_DAY, 0); - c.set(Calendar.MINUTE, 0); - c.set(Calendar.SECOND, 0); - c.set(Calendar.MILLISECOND, 0); - final List logs = ticketLogMapper.selectList(new LambdaQueryWrapper() - .select(PlanetTicketLog::getChangeCount) - .eq(PlanetTicketLog::getUserId, userId) - .eq(PlanetTicketLog::getRegionId, regionId) - .gt(PlanetTicketLog::getChangeCount, 0) - .ge(PlanetTicketLog::getCreateTime, c.getTime())); - int total = 0; - for (PlanetTicketLog log : logs) { - total += log.getChangeCount() == null ? 0 : log.getChangeCount(); - } - return total; - } - private BigDecimal probability(int mine, int total) { if (mine <= 0 || total <= 0) { return BigDecimal.ZERO; diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/planet/service/impl/PlanetTaskServiceImpl.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/planet/service/impl/PlanetTaskServiceImpl.java index c9280cad..21758aa4 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/planet/service/impl/PlanetTaskServiceImpl.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/planet/service/impl/PlanetTaskServiceImpl.java @@ -161,9 +161,9 @@ public class PlanetTaskServiceImpl implements PlanetTaskService { if (StringUtils.isEmpty(regionId)) { return; } - seedTask(regionId, PlanetConstant.TASK_WAIMAI, "瀹屾垚澶栧崠璁㈠崟", "姣忓畬鎴愪竴绗斿鍗栬鍗 +1 鏄熺悆鍒", 1, 0, 1); - seedTask(regionId, PlanetConstant.TASK_GROUP, "瀹屾垚鍥㈣喘璁㈠崟", "姣忓畬鎴愪竴绗斿洟璐鍗 +1 鏄熺悆鍒", 1, 0, 2); - seedTask(regionId, PlanetConstant.TASK_INVITE, "閭璇峰ソ鍙嬫敞鍐", "姣忛個璇蜂竴浣嶅ソ鍙嬫敞鍐 +3 鏄熺悆鍒", 3, 0, 3); + seedTask(regionId, PlanetConstant.TASK_WAIMAI, "瀹屾垚澶栧崠璁㈠崟", "姣忓畬鎴愪竴绗斿鍗栬鍗 +6 鏄熺悆鍒", 1, 0, 1); + seedTask(regionId, PlanetConstant.TASK_GROUP, "瀹屾垚鍥㈣喘璁㈠崟", "姣忓畬鎴愪竴绗斿洟璐鍗 +6 鏄熺悆鍒", 1, 0, 2); + seedTask(regionId, PlanetConstant.TASK_INVITE, "閭璇峰ソ鍙嬫敞鍐", "姣忛個璇蜂竴浣嶅ソ鍙嬫敞鍐 +6 鏄熺悆鍒", 3, 0, 3); seedTask(regionId, PlanetConstant.TASK_SIGN, "姣忔棩绛惧埌", "姣忔棩绛惧埌棰嗗彇 +1 鏄熺悆鍒", 1, 1, 4); } diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/quartz/PlanetAdventureSettleTask.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/quartz/PlanetAdventureSettleTask.java index fdf85873..0c90e086 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/quartz/PlanetAdventureSettleTask.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/quartz/PlanetAdventureSettleTask.java @@ -11,6 +11,7 @@ import cc.hiver.mall.planet.mapper.PlanetAdventureSessionMapper; import cc.hiver.mall.planet.mapper.PlanetTicketMapper; import cc.hiver.mall.planet.service.PlanetAdventureService; import cc.hiver.mall.planet.service.PlanetTicketService; +import cc.hiver.mall.service.HomeReminderService; import cc.hiver.mall.service.mybatis.DealingsRecordService; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import lombok.extern.slf4j.Slf4j; @@ -54,6 +55,9 @@ public class PlanetAdventureSettleTask { @Autowired private DealingsRecordService dealingsRecordService; + @Autowired + private HomeReminderService homeReminderService; + @Scheduled(cron = "0 30 21 * * ?") public void settleAdventureRanks() { try { @@ -165,6 +169,8 @@ public class PlanetAdventureSettleTask { dealingsRecord.setCreateBy(session.getUserId()); dealingsRecord.setRemark("瀛﹂櫌鍔╂帹璧涜崳鑰姒滅" + rankNo + "鍚嶇幇閲戝鍔"); dealingsRecordService.save(dealingsRecord); + homeReminderService.addPlanetReward(String.valueOf(session.getUserId()), session.getRegionId(), "rankTop", + "瀛﹂櫌鍔╂帹璧涚" + rankNo + "鍚嶅鍔 楼" + amount, linkId); return true; } } diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/HomeReminderService.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/HomeReminderService.java new file mode 100644 index 00000000..e54b5a63 --- /dev/null +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/HomeReminderService.java @@ -0,0 +1,20 @@ +package cc.hiver.mall.service; + +import java.util.Map; + +public interface HomeReminderService { + + void incrementIeUnread(Long userId); + + Integer getIeUnreadCount(Long userId); + + void setIeUnreadCount(Long userId, int count); + + void clearIeUnread(Long userId); + + void addPlanetReward(String userId, String regionId, String type, String title, String recordId); + + void clearPlanetReminders(String userId, String regionId); + + Map homeReminders(String userId, String regionId); +} diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/HomeReminderServiceImpl.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/HomeReminderServiceImpl.java new file mode 100644 index 00000000..3fdf0d5d --- /dev/null +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/HomeReminderServiceImpl.java @@ -0,0 +1,138 @@ +package cc.hiver.mall.serviceimpl; + +import cc.hiver.mall.service.HomeReminderService; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +@Service +public class HomeReminderServiceImpl implements HomeReminderService { + + private static final String KEY_PREFIX = "home:reminder:"; + private static final String FIELD_IE_UNREAD = "ieUnread"; + private static final String FIELD_PLANET_DRAW = "planetDraw"; + private static final String FIELD_PLANET_RANK_TOP = "planetRankTop"; + private static final long TTL_DAYS = 14L; + + @Autowired + private StringRedisTemplate stringRedisTemplate; + + @Override + public void incrementIeUnread(Long userId) { + if (userId == null) { + return; + } + String key = userKey(String.valueOf(userId)); + stringRedisTemplate.opsForHash().increment(key, FIELD_IE_UNREAD, 1); + stringRedisTemplate.expire(key, TTL_DAYS, TimeUnit.DAYS); + } + + @Override + public Integer getIeUnreadCount(Long userId) { + if (userId == null) { + return 0; + } + Object value = stringRedisTemplate.opsForHash().get(userKey(String.valueOf(userId)), FIELD_IE_UNREAD); + return parseInt(value); + } + + @Override + public void setIeUnreadCount(Long userId, int count) { + if (userId == null) { + return; + } + String key = userKey(String.valueOf(userId)); + if (count <= 0) { + stringRedisTemplate.opsForHash().delete(key, FIELD_IE_UNREAD); + return; + } + stringRedisTemplate.opsForHash().put(key, FIELD_IE_UNREAD, String.valueOf(count)); + stringRedisTemplate.expire(key, TTL_DAYS, TimeUnit.DAYS); + } + + @Override + public void clearIeUnread(Long userId) { + if (userId == null) { + return; + } + stringRedisTemplate.opsForHash().delete(userKey(String.valueOf(userId)), FIELD_IE_UNREAD); + } + + @Override + public void addPlanetReward(String userId, String regionId, String type, String title, String recordId) { + if (StrUtil.isBlank(userId)) { + return; + } + String field = "rankTop".equals(type) ? FIELD_PLANET_RANK_TOP : FIELD_PLANET_DRAW; + Map payload = new HashMap<>(); + payload.put("type", type); + payload.put("regionId", regionId); + payload.put("title", title); + payload.put("recordId", recordId); + payload.put("time", System.currentTimeMillis()); + String key = userKey(userId); + stringRedisTemplate.opsForHash().put(key, field, JSONUtil.toJsonStr(payload)); + stringRedisTemplate.expire(key, TTL_DAYS, TimeUnit.DAYS); + } + + @Override + public void clearPlanetReminders(String userId, String regionId) { + if (StrUtil.isBlank(userId)) { + return; + } + stringRedisTemplate.opsForHash().delete(userKey(userId), FIELD_PLANET_DRAW, FIELD_PLANET_RANK_TOP); + } + + @Override + public Map homeReminders(String userId, String regionId) { + Map result = new HashMap<>(); + if (StrUtil.isBlank(userId)) { + result.put("ieUnreadCount", 0); + result.put("ie", false); + result.put("planet", false); + return result; + } + String key = userKey(userId); + Integer ieUnread = parseInt(stringRedisTemplate.opsForHash().get(key, FIELD_IE_UNREAD)); + Object draw = stringRedisTemplate.opsForHash().get(key, FIELD_PLANET_DRAW); + Object rankTop = stringRedisTemplate.opsForHash().get(key, FIELD_PLANET_RANK_TOP); + result.put("ieUnreadCount", ieUnread); + result.put("ie", ieUnread > 0); + result.put("planet", draw != null || rankTop != null); + result.put("planetDraw", parseJson(draw)); + result.put("planetRankTop", parseJson(rankTop)); + return result; + } + + private String userKey(String userId) { + return KEY_PREFIX + userId; + } + + private Integer parseInt(Object value) { + if (value == null) { + return 0; + } + try { + return Math.max(0, Integer.parseInt(String.valueOf(value))); + } catch (Exception ignored) { + return 0; + } + } + + private Object parseJson(Object value) { + if (value == null || StrUtil.isBlank(String.valueOf(value))) { + return null; + } + try { + return JSONUtil.parseObj(String.valueOf(value)); + } catch (Exception ignored) { + return null; + } + } +} diff --git a/hiver-modules/hiver-mall/src/main/resources/db/ie_user_profile_companion_intent.sql b/hiver-modules/hiver-mall/src/main/resources/db/ie_user_profile_companion_intent.sql new file mode 100644 index 00000000..b66ab7d6 --- /dev/null +++ b/hiver-modules/hiver-mall/src/main/resources/db/ie_user_profile_companion_intent.sql @@ -0,0 +1,5 @@ +ALTER TABLE ie_user_profile + ADD COLUMN companion_intent VARCHAR(80) NULL COMMENT '鐢ㄦ埛鑷敱杈撳叆鐨勬壘鎼瓙鍐呭'; + +ALTER TABLE ie_user_profile + ADD INDEX idx_ie_profile_companion_latest (profile_completed, is_deleted, update_time);