|
|
@@ -0,0 +1,518 @@
|
|
|
+package com.etotem.cfc.service;
|
|
|
+
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.etotem.cfc.entity.ActivityRegistration;
|
|
|
+import com.etotem.cfc.entity.DanAssessmentResult;
|
|
|
+import com.etotem.cfc.entity.Family;
|
|
|
+import com.etotem.cfc.entity.FamilyMember;
|
|
|
+import com.etotem.cfc.entity.HealthReport;
|
|
|
+import com.etotem.cfc.entity.ProductOrder;
|
|
|
+import com.etotem.cfc.entity.SocialCircle;
|
|
|
+import com.etotem.cfc.mapper.ActivityRegistrationMapper;
|
|
|
+import com.etotem.cfc.mapper.DanAssessmentResultMapper;
|
|
|
+import com.etotem.cfc.mapper.FamilyMapper;
|
|
|
+import com.etotem.cfc.mapper.FamilyMemberMapper;
|
|
|
+import com.etotem.cfc.mapper.HealthReportMapper;
|
|
|
+import com.etotem.cfc.mapper.ProductOrderMapper;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.HashSet;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Set;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 圈子匹配引擎
|
|
|
+ * 基于身·心·智·富·行五维数据发现共同点,推荐圈子
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@Service
|
|
|
+public class CircleMatchService {
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private ActivityRegistrationMapper activityRegistrationMapper;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private DanAssessmentResultMapper danAssessmentResultMapper;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private HealthReportMapper healthReportMapper;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private ProductOrderMapper productOrderMapper;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private FamilyMapper familyMapper;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private FamilyMemberMapper familyMemberMapper;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private CircleService circleService;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 为孩子发现匹配圈子(按匹配源分组)
|
|
|
+ */
|
|
|
+ public List<Map<String, Object>> discover(Long childId) {
|
|
|
+ List<Map<String, Object>> allRecommendations = new ArrayList<>();
|
|
|
+ Set<String> dedupKey = new HashSet<>();
|
|
|
+
|
|
|
+ // 1. 共同活动匹配
|
|
|
+ List<Map<String, Object>> activityCircles = matchByActivity(childId);
|
|
|
+ for (Map<String, Object> c : activityCircles) {
|
|
|
+ String key = c.get("type") + "_" + c.get("sourceId");
|
|
|
+ if (dedupKey.add(key)) {
|
|
|
+ allRecommendations.add(c);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 共同认知能力匹配
|
|
|
+ List<Map<String, Object>> abilityCircles = matchByAbility(childId);
|
|
|
+ for (Map<String, Object> c : abilityCircles) {
|
|
|
+ String key = c.get("type") + "_" + c.get("sourceId");
|
|
|
+ if (dedupKey.add(key)) {
|
|
|
+ allRecommendations.add(c);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 共同情绪特征匹配
|
|
|
+ List<Map<String, Object>> topicCircles = matchByEmotion(childId);
|
|
|
+ for (Map<String, Object> c : topicCircles) {
|
|
|
+ String key = c.get("type") + "_" + c.get("sourceId");
|
|
|
+ if (dedupKey.add(key)) {
|
|
|
+ allRecommendations.add(c);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 共同身体状况匹配
|
|
|
+ List<Map<String, Object>> healthCircles = matchByHealth(childId);
|
|
|
+ for (Map<String, Object> c : healthCircles) {
|
|
|
+ String key = c.get("type") + "_" + c.get("sourceId");
|
|
|
+ if (dedupKey.add(key)) {
|
|
|
+ allRecommendations.add(c);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 5. 共同产品匹配
|
|
|
+ List<Map<String, Object>> productCircles = matchByProduct(childId);
|
|
|
+ for (Map<String, Object> c : productCircles) {
|
|
|
+ String key = c.get("type") + "_" + c.get("sourceId");
|
|
|
+ if (dedupKey.add(key)) {
|
|
|
+ allRecommendations.add(c);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 6. 共同服务商匹配
|
|
|
+ List<Map<String, Object>> providerCircles = matchByProvider(childId);
|
|
|
+ for (Map<String, Object> c : providerCircles) {
|
|
|
+ String key = c.get("type") + "_" + c.get("sourceId");
|
|
|
+ if (dedupKey.add(key)) {
|
|
|
+ allRecommendations.add(c);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return allRecommendations;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 1. 共同活动匹配:参与同一活动的其他孩子
|
|
|
+ */
|
|
|
+ private List<Map<String, Object>> matchByActivity(Long childId) {
|
|
|
+ List<Map<String, Object>> result = new ArrayList<>();
|
|
|
+ try {
|
|
|
+ // 查找孩子参与的活动
|
|
|
+ LambdaQueryWrapper<ActivityRegistration> regWrapper = new LambdaQueryWrapper<ActivityRegistration>()
|
|
|
+ .eq(ActivityRegistration::getChildId, childId);
|
|
|
+ List<ActivityRegistration> myRegs = activityRegistrationMapper.selectList(regWrapper);
|
|
|
+
|
|
|
+ for (ActivityRegistration reg : myRegs) {
|
|
|
+ if (reg.getActivityId() == null) continue;
|
|
|
+
|
|
|
+ // 查找参与同一活动的其他孩子
|
|
|
+ LambdaQueryWrapper<ActivityRegistration> sameActWrapper = new LambdaQueryWrapper<ActivityRegistration>()
|
|
|
+ .eq(ActivityRegistration::getActivityId, reg.getActivityId())
|
|
|
+ .ne(ActivityRegistration::getChildId, childId);
|
|
|
+ List<ActivityRegistration> sameAct = activityRegistrationMapper.selectList(sameActWrapper);
|
|
|
+
|
|
|
+ if (!sameAct.isEmpty()) {
|
|
|
+ // 创建或复用圈子
|
|
|
+ Map<String, Object> circle = getOrCreateRecommendation(
|
|
|
+ "共同活动圈", "activity", "activity",
|
|
|
+ reg.getActivityId().longValue(), childId);
|
|
|
+ if (circle != null) {
|
|
|
+ circle.put("matchReason", "参加了同一活动");
|
|
|
+ result.add(circle);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("共同活动匹配异常: {}", e.getMessage());
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 2. 共同认知能力匹配:DAN COG 子分差值 < 10
|
|
|
+ */
|
|
|
+ private List<Map<String, Object>> matchByAbility(Long childId) {
|
|
|
+ List<Map<String, Object>> result = new ArrayList<>();
|
|
|
+ try {
|
|
|
+ DanAssessmentResult myDan = findLatestDan(childId);
|
|
|
+ if (myDan == null) return result;
|
|
|
+
|
|
|
+ // 查找其他认知能力相近的孩子
|
|
|
+ LambdaQueryWrapper<DanAssessmentResult> qw = new LambdaQueryWrapper<DanAssessmentResult>()
|
|
|
+ .eq(DanAssessmentResult::getStatus, "completed")
|
|
|
+ .ne(DanAssessmentResult::getChildId, childId)
|
|
|
+ .orderByDesc(DanAssessmentResult::getAssessmentDate);
|
|
|
+ List<DanAssessmentResult> others = danAssessmentResultMapper.selectList(qw);
|
|
|
+
|
|
|
+ // 按childId去重取最新
|
|
|
+ Map<Long, DanAssessmentResult> latestByChild = new HashMap<>();
|
|
|
+ for (DanAssessmentResult r : others) {
|
|
|
+ if (!latestByChild.containsKey(r.getChildId())) {
|
|
|
+ latestByChild.put(r.getChildId(), r);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (DanAssessmentResult other : latestByChild.values()) {
|
|
|
+ if (isCogSimilar(myDan, other)) {
|
|
|
+ Map<String, Object> circle = getOrCreateRecommendation(
|
|
|
+ "认知能力圈", "ability", "assessment",
|
|
|
+ myDan.getId(), childId);
|
|
|
+ if (circle != null) {
|
|
|
+ circle.put("matchReason", "认知能力相似");
|
|
|
+ result.add(circle);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("共同认知能力匹配异常: {}", e.getMessage());
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 3. 共同情绪特征匹配:EMI 子分相近
|
|
|
+ */
|
|
|
+ private List<Map<String, Object>> matchByEmotion(Long childId) {
|
|
|
+ List<Map<String, Object>> result = new ArrayList<>();
|
|
|
+ try {
|
|
|
+ DanAssessmentResult myDan = findLatestDan(childId);
|
|
|
+ if (myDan == null) return result;
|
|
|
+
|
|
|
+ LambdaQueryWrapper<DanAssessmentResult> qw = new LambdaQueryWrapper<DanAssessmentResult>()
|
|
|
+ .eq(DanAssessmentResult::getStatus, "completed")
|
|
|
+ .ne(DanAssessmentResult::getChildId, childId)
|
|
|
+ .orderByDesc(DanAssessmentResult::getAssessmentDate);
|
|
|
+ List<DanAssessmentResult> others = danAssessmentResultMapper.selectList(qw);
|
|
|
+
|
|
|
+ Map<Long, DanAssessmentResult> latestByChild = new HashMap<>();
|
|
|
+ for (DanAssessmentResult r : others) {
|
|
|
+ if (!latestByChild.containsKey(r.getChildId())) {
|
|
|
+ latestByChild.put(r.getChildId(), r);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (DanAssessmentResult other : latestByChild.values()) {
|
|
|
+ if (isEmiSimilar(myDan, other)) {
|
|
|
+ Map<String, Object> circle = getOrCreateRecommendation(
|
|
|
+ "情绪成长圈", "topic", "assessment",
|
|
|
+ myDan.getId(), childId);
|
|
|
+ if (circle != null) {
|
|
|
+ circle.put("matchReason", "情绪特征相近");
|
|
|
+ result.add(circle);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("共同情绪特征匹配异常: {}", e.getMessage());
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 4. 共同身体状况匹配:健康指标相近
|
|
|
+ */
|
|
|
+ private List<Map<String, Object>> matchByHealth(Long childId) {
|
|
|
+ List<Map<String, Object>> result = new ArrayList<>();
|
|
|
+ try {
|
|
|
+ // 查找孩子的最新健康报告
|
|
|
+ LambdaQueryWrapper<HealthReport> myHw = new LambdaQueryWrapper<HealthReport>()
|
|
|
+ .eq(HealthReport::getUserId, childId)
|
|
|
+ .eq(HealthReport::getStatus, "active")
|
|
|
+ .orderByDesc(HealthReport::getReportDate)
|
|
|
+ .last("LIMIT 1");
|
|
|
+ HealthReport myReport = healthReportMapper.selectOne(myHw);
|
|
|
+ if (myReport == null || myReport.getOverallScore() == null) return result;
|
|
|
+
|
|
|
+ // 查找其他健康指标相近的孩子
|
|
|
+ LambdaQueryWrapper<HealthReport> othersHw = new LambdaQueryWrapper<HealthReport>()
|
|
|
+ .eq(HealthReport::getStatus, "active")
|
|
|
+ .ne(HealthReport::getUserId, childId)
|
|
|
+ .orderByDesc(HealthReport::getReportDate);
|
|
|
+ List<HealthReport> others = healthReportMapper.selectList(othersHw);
|
|
|
+
|
|
|
+ Map<Long, HealthReport> latestByUser = new HashMap<>();
|
|
|
+ for (HealthReport r : others) {
|
|
|
+ if (!latestByUser.containsKey(r.getUserId())) {
|
|
|
+ latestByUser.put(r.getUserId(), r);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ int myScore = myReport.getOverallScore();
|
|
|
+ for (HealthReport other : latestByUser.values()) {
|
|
|
+ if (other.getOverallScore() != null
|
|
|
+ && Math.abs(other.getOverallScore() - myScore) < 15) {
|
|
|
+ Map<String, Object> circle = getOrCreateRecommendation(
|
|
|
+ "健康生活圈", "health", "health_report",
|
|
|
+ myReport.getId(), childId);
|
|
|
+ if (circle != null) {
|
|
|
+ circle.put("matchReason", "身体状况相近");
|
|
|
+ result.add(circle);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("共同身体状况匹配异常: {}", e.getMessage());
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 5. 共同产品匹配:购买了同一商品
|
|
|
+ */
|
|
|
+ private List<Map<String, Object>> matchByProduct(Long childId) {
|
|
|
+ List<Map<String, Object>> result = new ArrayList<>();
|
|
|
+ try {
|
|
|
+ // 使用 product_order 表查询
|
|
|
+ String tableName = "product_order";
|
|
|
+ String sql = "SELECT DISTINCT product_id FROM " + tableName
|
|
|
+ + " WHERE buyer_id = " + childId
|
|
|
+ + " AND product_id IS NOT NULL";
|
|
|
+ List<Map<String, Object>> myProducts;
|
|
|
+ try {
|
|
|
+ myProducts = productOrderMapper.selectMaps(
|
|
|
+ new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<ProductOrder>()
|
|
|
+ .select("DISTINCT product_id")
|
|
|
+ .eq("buyer_id", childId)
|
|
|
+ .isNotNull("product_id"));
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("product_order查询失败,尝试product_orders: {}", e.getMessage());
|
|
|
+ try {
|
|
|
+ myProducts = productOrderMapper.selectMaps(
|
|
|
+ new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<ProductOrder>()
|
|
|
+ .select("DISTINCT product_id")
|
|
|
+ .eq("buyer_id", childId)
|
|
|
+ .isNotNull("product_id"));
|
|
|
+ } catch (Exception e2) {
|
|
|
+ log.warn("product_orders查询也失败: {}", e2.getMessage());
|
|
|
+ myProducts = new ArrayList<>();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (Map<String, Object> row : myProducts) {
|
|
|
+ Object pid = row.get("product_id");
|
|
|
+ if (pid == null) continue;
|
|
|
+ Long productId = Long.valueOf(pid.toString());
|
|
|
+
|
|
|
+ // 查找买了同一商品的其他用户
|
|
|
+ String searchSql = "SELECT DISTINCT buyer_id FROM " + tableName
|
|
|
+ + " WHERE product_id = " + productId
|
|
|
+ + " AND buyer_id != " + childId;
|
|
|
+ List<Map<String, Object>> others;
|
|
|
+ try {
|
|
|
+ others = productOrderMapper.selectMaps(
|
|
|
+ new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<ProductOrder>()
|
|
|
+ .select("DISTINCT buyer_id")
|
|
|
+ .eq("product_id", productId)
|
|
|
+ .ne("buyer_id", childId));
|
|
|
+ } catch (Exception e) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!others.isEmpty()) {
|
|
|
+ Map<String, Object> circle = getOrCreateRecommendation(
|
|
|
+ "好物分享圈", "product", "product",
|
|
|
+ productId, childId);
|
|
|
+ if (circle != null) {
|
|
|
+ circle.put("matchReason", "购买了相同商品");
|
|
|
+ result.add(circle);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("共同产品匹配异常: {}", e.getMessage());
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 6. 共同服务商匹配:绑定了同一位teacher
|
|
|
+ */
|
|
|
+ private List<Map<String, Object>> matchByProvider(Long childId) {
|
|
|
+ List<Map<String, Object>> result = new ArrayList<>();
|
|
|
+ try {
|
|
|
+ // 查找孩子所在的家庭
|
|
|
+ LambdaQueryWrapper<FamilyMember> fmw = new LambdaQueryWrapper<FamilyMember>()
|
|
|
+ .eq(FamilyMember::getId, childId);
|
|
|
+ FamilyMember member = familyMemberMapper.selectOne(fmw);
|
|
|
+ if (member == null || member.getFamilyId() == null) return result;
|
|
|
+
|
|
|
+ // 查找家庭绑定的teacher
|
|
|
+ Family family = familyMapper.selectById(member.getFamilyId());
|
|
|
+ if (family == null || family.getTeacherId() == null) return result;
|
|
|
+
|
|
|
+ Long teacherId = family.getTeacherId();
|
|
|
+
|
|
|
+ // 查找绑定了同一teacher的其他家庭的孩子
|
|
|
+ LambdaQueryWrapper<Family> familyQw = new LambdaQueryWrapper<Family>()
|
|
|
+ .eq(Family::getTeacherId, teacherId)
|
|
|
+ .ne(Family::getId, member.getFamilyId());
|
|
|
+ List<Family> sameTeacherFamilies = familyMapper.selectList(familyQw);
|
|
|
+
|
|
|
+ for (Family f : sameTeacherFamilies) {
|
|
|
+ LambdaQueryWrapper<FamilyMember> childQw = new LambdaQueryWrapper<FamilyMember>()
|
|
|
+ .eq(FamilyMember::getFamilyId, f.getId());
|
|
|
+ List<FamilyMember> siblings = familyMemberMapper.selectList(childQw);
|
|
|
+ if (!siblings.isEmpty()) {
|
|
|
+ Map<String, Object> circle = getOrCreateRecommendation(
|
|
|
+ "规划师同门圈", "provider", "teacher",
|
|
|
+ teacherId, childId);
|
|
|
+ if (circle != null) {
|
|
|
+ circle.put("matchReason", "同一成长规划师");
|
|
|
+ result.add(circle);
|
|
|
+ }
|
|
|
+ break; // 一个teacher只创建一个圈子
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("共同服务商匹配异常: {}", e.getMessage());
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ // ==================== 辅助方法 ====================
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取或创建推荐圈子
|
|
|
+ */
|
|
|
+ private Map<String, Object> getOrCreateRecommendation(String baseName, String type,
|
|
|
+ String matchSource, Long sourceId,
|
|
|
+ Long childId) {
|
|
|
+ try {
|
|
|
+ // 查找是否已有相同源ID+类型的圈子
|
|
|
+ LambdaQueryWrapper<SocialCircle> qw = new LambdaQueryWrapper<SocialCircle>()
|
|
|
+ .eq(SocialCircle::getSourceId, sourceId)
|
|
|
+ .eq(SocialCircle::getType, type);
|
|
|
+ SocialCircle existing = circleService.getOne(qw);
|
|
|
+
|
|
|
+ if (existing != null) {
|
|
|
+ Map<String, Object> item = new HashMap<>();
|
|
|
+ item.put("id", existing.getId());
|
|
|
+ item.put("name", existing.getName());
|
|
|
+ item.put("type", existing.getType());
|
|
|
+ item.put("matchSource", existing.getMatchSource());
|
|
|
+ item.put("sourceId", existing.getSourceId());
|
|
|
+ item.put("memberCount", existing.getMemberCount());
|
|
|
+ return item;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 创建新圈子
|
|
|
+ SocialCircle circle = circleService.createCircle(baseName, type, matchSource,
|
|
|
+ sourceId, childId, "child");
|
|
|
+ Map<String, Object> item = new HashMap<>();
|
|
|
+ item.put("id", circle.getId());
|
|
|
+ item.put("name", circle.getName());
|
|
|
+ item.put("type", circle.getType());
|
|
|
+ item.put("matchSource", circle.getMatchSource());
|
|
|
+ item.put("sourceId", circle.getSourceId());
|
|
|
+ item.put("memberCount", circle.getMemberCount());
|
|
|
+ return item;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("创建推荐圈子失败: {}", e.getMessage());
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取孩子最新的DAN测评结果
|
|
|
+ */
|
|
|
+ private DanAssessmentResult findLatestDan(Long childId) {
|
|
|
+ LambdaQueryWrapper<DanAssessmentResult> qw = new LambdaQueryWrapper<DanAssessmentResult>()
|
|
|
+ .eq(DanAssessmentResult::getChildId, childId)
|
|
|
+ .eq(DanAssessmentResult::getStatus, "completed")
|
|
|
+ .orderByDesc(DanAssessmentResult::getAssessmentDate)
|
|
|
+ .last("LIMIT 1");
|
|
|
+ return danAssessmentResultMapper.selectOne(qw);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断COG认知能力是否相近(各维度差值<10)
|
|
|
+ */
|
|
|
+ private boolean isCogSimilar(DanAssessmentResult a, DanAssessmentResult b) {
|
|
|
+ int diffSum = 0;
|
|
|
+ int count = 0;
|
|
|
+
|
|
|
+ if (a.getAttentionScore() != null && b.getAttentionScore() != null) {
|
|
|
+ diffSum += Math.abs(a.getAttentionScore() - b.getAttentionScore());
|
|
|
+ count++;
|
|
|
+ }
|
|
|
+ if (a.getFocusScore() != null && b.getFocusScore() != null) {
|
|
|
+ diffSum += Math.abs(a.getFocusScore() - b.getFocusScore());
|
|
|
+ count++;
|
|
|
+ }
|
|
|
+ if (a.getMemoryScore() != null && b.getMemoryScore() != null) {
|
|
|
+ diffSum += Math.abs(a.getMemoryScore() - b.getMemoryScore());
|
|
|
+ count++;
|
|
|
+ }
|
|
|
+ if (a.getLogicScore() != null && b.getLogicScore() != null) {
|
|
|
+ diffSum += Math.abs(a.getLogicScore() - b.getLogicScore());
|
|
|
+ count++;
|
|
|
+ }
|
|
|
+ if (a.getPerceptionScore() != null && b.getPerceptionScore() != null) {
|
|
|
+ diffSum += Math.abs(a.getPerceptionScore() - b.getPerceptionScore());
|
|
|
+ count++;
|
|
|
+ }
|
|
|
+ if (a.getSpatialScore() != null && b.getSpatialScore() != null) {
|
|
|
+ diffSum += Math.abs(a.getSpatialScore() - b.getSpatialScore());
|
|
|
+ count++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (count == 0) return false;
|
|
|
+ return (diffSum / count) < 10;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断EMI情绪特征是否相近
|
|
|
+ */
|
|
|
+ private boolean isEmiSimilar(DanAssessmentResult a, DanAssessmentResult b) {
|
|
|
+ int diffSum = 0;
|
|
|
+ int count = 0;
|
|
|
+
|
|
|
+ if (a.getEmotionManagementScore() != null && b.getEmotionManagementScore() != null) {
|
|
|
+ diffSum += Math.abs(a.getEmotionManagementScore() - b.getEmotionManagementScore());
|
|
|
+ count++;
|
|
|
+ }
|
|
|
+ if (a.getEmpathyScore() != null && b.getEmpathyScore() != null) {
|
|
|
+ diffSum += Math.abs(a.getEmpathyScore() - b.getEmpathyScore());
|
|
|
+ count++;
|
|
|
+ }
|
|
|
+ if (a.getSocialAdaptabilityScore() != null && b.getSocialAdaptabilityScore() != null) {
|
|
|
+ diffSum += Math.abs(a.getSocialAdaptabilityScore() - b.getSocialAdaptabilityScore());
|
|
|
+ count++;
|
|
|
+ }
|
|
|
+ if (a.getSelfMotivationScore() != null && b.getSelfMotivationScore() != null) {
|
|
|
+ diffSum += Math.abs(a.getSelfMotivationScore() - b.getSelfMotivationScore());
|
|
|
+ count++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (count == 0) return false;
|
|
|
+ return (diffSum / count) < 10;
|
|
|
+ }
|
|
|
+}
|