feat(phase-12): RelationshipStageService — home service suggestions

Phase 12 Relationship — KEEP/EXTEND per JIRA. 不增加复杂状态.

New RelationshipStageService (match module):
  P12-V11-T01 Successful match -> premarital_suggestion
  P12-V11-T02 GettingToKnow match -> matchmaker + counseling
  P12-V11-T03 7-day silence in GettingToKnow -> counseling_recommendation

Rules are simple, based on existing Match.status + lastActivityAt:
- successful  -> 婚前辅导建议
- getting_to_know -> 红娘服务 + 婚恋咨询建议
- getting_to_know + 7d silence -> 婚恋咨询促活建议
- no Match    -> 默认红娘 + 婚恋课堂

Integration point: HomeApplicationService.buildRecommendations()
just inject RelationshipStageService and append suggestions to home DTO.
This commit is contained in:
Codex
2026-09-14 14:40:13 +08:00
parent e2a8a8c85f
commit 0418856ce3
@@ -0,0 +1,112 @@
package com.danyang.match.platform.match.service;
import com.danyang.match.platform.match.entity.Match;
import com.danyang.match.platform.match.mapper.MatchMapper;
import com.danyang.match.platform.notification.service.NotificationService;
import com.danyang.match.platform.shared.constant.Constants;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 关系阶段服务建议 — Phase 12
*
* 根据用户当前 Match 状态和互动情况,推荐相应的公益服务。
* 不增加复杂状态 — 只根据现有 Match.lastActivityAt / status 做规则推断。
*
* P12-V11-T01 Successful 首页服务建议
* P12-V11-T02 GettingToKnow 服务建议规则
* P12-V11-T03 Counseling recommendation rules
*/
@Service
@RequiredArgsConstructor
public class RelationshipStageService {
private static final Logger log = LoggerFactory.getLogger(RelationshipStageService.class);
/** Match 静默期阈值:多少天没互动 → 触发沉默服务建议 */
private static final int SILENCE_DAYS_THRESHOLD = 7;
private final MatchMapper matchMapper;
// ==================== 首页服务建议 ====================
/**
* 首页服务建议(HomeApplicationService 调用)
*
* 返回结构:[{serviceType, reason, targetPage}]
* serviceType: counseling / premarital / matchmaker / content / anti_fraud / service_station
*/
public List<ServiceSuggestion> getHomeServiceSuggestions(String userId) {
List<ServiceSuggestion> suggestions = new ArrayList<>();
List<Match> activeMatches = matchMapper.findActiveByUser(userId);
for (Match match : activeMatches) {
// T01: successful Match → 婚前辅导
if (Constants.MATCH_STATUS_SUCCESSFUL.equals(match.getStatus())) {
suggestions.add(new ServiceSuggestion(
"premarital",
"恭喜牵手成功!婚前辅导帮助你们更好地开始新生活。",
"/pages/premarital-intro/premarital-intro"));
}
// T02: getting_to_know Match → 红娘服务 + 婚恋咨询
if (Constants.MATCH_STATUS_GETTING_TO_KNOW.equals(match.getStatus())) {
// 有红娘建议优先展示
suggestions.add(new ServiceSuggestion(
"matchmaker",
"婚恋红娘可以帮你们梳理交往节奏、解决初期困惑。",
"/pages/matchmaker/matchmaker"));
suggestions.add(new ServiceSuggestion(
"counseling",
"一对一婚恋咨询,帮助你们更好地了解彼此。",
"/pages/counseling-intro/counseling-intro"));
}
// T03: getting_to_know 但长期沉默 → 心理咨询建议
if (Constants.MATCH_STATUS_GETTING_TO_KNOW.equals(match.getStatus())
&& match.getLastActivityAt() != null
&& match.getLastActivityAt().plus(SILENCE_DAYS_THRESHOLD, ChronoUnit.DAYS).isBefore(Instant.now())) {
suggestions.add(new ServiceSuggestion(
"counseling",
"你们已 7 天没有互动,婚恋咨询能帮你们重新找回话题。",
"/pages/counseling-intro/counseling-intro"));
}
}
// 没有任何 Match → 常规建议
if (activeMatches.isEmpty()) {
suggestions.add(new ServiceSuggestion(
"matchmaker",
"公益红娘可以帮你拓展优质择偶范围。",
"/pages/matchmaker/matchmaker"));
suggestions.add(new ServiceSuggestion(
"content",
"婚恋课堂专栏,学习科学的相处之道。",
"/pages/content/content"));
}
return suggestions;
}
/** 为首页返回 JSON-friendly 的简化版本 */
public List<Map<String, String>> getHomeServiceSuggestionsSimple(String userId) {
return getHomeServiceSuggestions(userId).stream()
.map(s -> Map.of(
"serviceType", s.serviceType,
"reason", s.reason,
"targetPage", s.targetPage))
.toList();
}
// ==================== DTO ====================
public record ServiceSuggestion(String serviceType, String reason, String targetPage) {}
}