|
|
@@ -10,14 +10,12 @@ import com.etotem.cfc.entity.FamilyMember;
|
|
|
import com.etotem.cfc.entity.FamilyRelationship;
|
|
|
import com.etotem.cfc.entity.FamilyMemberAttributes;
|
|
|
import com.etotem.cfc.entity.FamilyMemberLog;
|
|
|
-import com.etotem.cfc.entity.RelationshipType;
|
|
|
import com.etotem.cfc.entity.User;
|
|
|
import com.etotem.cfc.enums.GenerationLevel;
|
|
|
import com.etotem.cfc.mapper.FamilyMapper;
|
|
|
import com.etotem.cfc.mapper.FamilyMemberAttributesMapper;
|
|
|
import com.etotem.cfc.mapper.FamilyMemberLogMapper;
|
|
|
import com.etotem.cfc.mapper.FamilyMemberMapper;
|
|
|
-import com.etotem.cfc.mapper.RelationshipTypeMapper;
|
|
|
import com.etotem.cfc.mapper.UserMapper;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
@@ -39,9 +37,6 @@ public class FamilyMemberService {
|
|
|
@Resource
|
|
|
private FamilyMemberMapper familyMemberMapper;
|
|
|
|
|
|
- @Resource
|
|
|
- private RelationshipTypeMapper relationshipTypeMapper;
|
|
|
-
|
|
|
@Resource
|
|
|
private UserMapper userMapper;
|
|
|
|
|
|
@@ -88,37 +83,18 @@ public class FamilyMemberService {
|
|
|
if (genLevel == null) {
|
|
|
throw new IllegalArgumentException("无效的辈分等级: " + dto.getGenerationLevel());
|
|
|
}
|
|
|
- String relationshipTypeKey;
|
|
|
- boolean isSpouse = false;
|
|
|
- if (genLevel == GenerationLevel.PEER) {
|
|
|
- if (dto.getPeerType() == null || dto.getPeerType().trim().isEmpty()) {
|
|
|
- throw new IllegalArgumentException("同辈关系必须指定 peerType (sibling/spouse)");
|
|
|
- }
|
|
|
- switch (dto.getPeerType()) {
|
|
|
- case "spouse":
|
|
|
- relationshipTypeKey = "spouse";
|
|
|
- isSpouse = true;
|
|
|
- break;
|
|
|
- case "sibling":
|
|
|
- relationshipTypeKey = "sibling";
|
|
|
- break;
|
|
|
- default:
|
|
|
- throw new IllegalArgumentException("无效的同辈类型: " + dto.getPeerType());
|
|
|
- }
|
|
|
- } else if (genLevel.getOffset() > 0) {
|
|
|
- relationshipTypeKey = "parent";
|
|
|
- } else {
|
|
|
- relationshipTypeKey = "child";
|
|
|
- }
|
|
|
|
|
|
- // 验证关系类型是否存在
|
|
|
- RelationshipType relType = relationshipTypeMapper.selectOne(
|
|
|
- new LambdaQueryWrapper<RelationshipType>()
|
|
|
- .eq(RelationshipType::getTypeKey, relationshipTypeKey)
|
|
|
- .eq(RelationshipType::getEnabled, 1));
|
|
|
- if (relType == null) {
|
|
|
- throw new IllegalArgumentException("无效的关系类型: " + relationshipTypeKey);
|
|
|
+ // 计算辈分值(相对关联成员)
|
|
|
+ FamilyMember relative = null;
|
|
|
+ if (dto.getRelativeMemberId() != null) {
|
|
|
+ relative = familyMemberMapper.selectById(dto.getRelativeMemberId());
|
|
|
+ if (relative == null || !relative.getFamilyId().equals(familyId)) {
|
|
|
+ throw new IllegalArgumentException("关联成员不存在");
|
|
|
+ }
|
|
|
}
|
|
|
+ int generation = (relative != null ? relative.getGeneration() : 0) + genLevel.getOffset();
|
|
|
+ boolean isSpouse = genLevel == GenerationLevel.PEER
|
|
|
+ && "spouse".equals(dto.getPeerType());
|
|
|
|
|
|
// 创建家庭成员记录
|
|
|
FamilyMember member = new FamilyMember();
|
|
|
@@ -139,10 +115,8 @@ public class FamilyMemberService {
|
|
|
member.setBirthWeight(dto.getBirthWeight());
|
|
|
member.setBirthPlace(dto.getBirthPlace());
|
|
|
member.setIsCesarean(dto.getIsCesarean());
|
|
|
- member.setRelationshipType(relationshipTypeKey);
|
|
|
- member.setGeneration(genLevel.getOffset());
|
|
|
+ member.setGeneration(generation);
|
|
|
member.setIsSpouse(isSpouse);
|
|
|
- member.setRoleOverride("auto");
|
|
|
member.setShowToFamily(1);
|
|
|
member.setTotalPoints(0);
|
|
|
member.setCreatedAt(new Date());
|
|
|
@@ -174,7 +148,7 @@ public class FamilyMemberService {
|
|
|
// 为新成员创建与所有现有成员的双向关系
|
|
|
familyRelationshipService.createRelationsForNewMember(familyId, member.getId(), genLevel.getOffset());
|
|
|
|
|
|
- return toFamilyMemberVO(member, relType);
|
|
|
+ return toFamilyMemberVO(member);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -188,17 +162,11 @@ public class FamilyMemberService {
|
|
|
Long familyId = user.getFamilyId();
|
|
|
List<FamilyMemberVO> result = new ArrayList<>();
|
|
|
|
|
|
- // 1. 查询 relationship_types 用于映射显示名
|
|
|
- List<RelationshipType> relTypes = relationshipTypeMapper.selectList(
|
|
|
- new LambdaQueryWrapper<RelationshipType>().eq(RelationshipType::getEnabled, 1));
|
|
|
- java.util.Map<String, String> relTypeNameMap = relTypes.stream()
|
|
|
- .collect(Collectors.toMap(RelationshipType::getTypeKey, RelationshipType::getTypeName));
|
|
|
-
|
|
|
- // 2. 查询 family_members 表
|
|
|
+ // 查询 family_members 表
|
|
|
List<FamilyMember> familyMembers = familyMemberMapper.selectList(
|
|
|
new LambdaQueryWrapper<FamilyMember>().eq(FamilyMember::getFamilyId, familyId));
|
|
|
|
|
|
- // 2b. 查找当前查看者在 family_members 中的记录(用于计算视角标签)
|
|
|
+ // 查找当前查看者在 family_members 中的记录(用于计算视角标签)
|
|
|
FamilyMember viewerMember = null;
|
|
|
for (FamilyMember fm : familyMembers) {
|
|
|
if (userId.equals(fm.getUserId())) {
|
|
|
@@ -216,11 +184,9 @@ public class FamilyMemberService {
|
|
|
vo.setPhone(fm.getPhone());
|
|
|
vo.setAvatar(fm.getAvatar());
|
|
|
vo.setGender(fm.getGender());
|
|
|
- vo.setRelationshipType(fm.getRelationshipType());
|
|
|
- vo.setRelationshipTypeName(relTypeNameMap.getOrDefault(fm.getRelationshipType(), fm.getRelationshipType()));
|
|
|
+ vo.setGeneration(fm.getGeneration());
|
|
|
vo.setEffectiveRole(computeEffectiveRole(fm));
|
|
|
- vo.setRoleOverride(fm.getRoleOverride());
|
|
|
- vo.setRoleLabel(relTypeNameMap.getOrDefault(fm.getRelationshipType(), computeEffectiveRole(fm)));
|
|
|
+ vo.setRoleLabel(computeEffectiveRole(fm));
|
|
|
vo.setTotalPoints(fm.getTotalPoints());
|
|
|
vo.setShowToFamily(fm.getShowToFamily());
|
|
|
if (fm.getBirthday() != null) {
|
|
|
@@ -379,80 +345,17 @@ public class FamilyMemberService {
|
|
|
throw new IllegalArgumentException("出生日期格式错误,应为yyyy-MM-dd");
|
|
|
}
|
|
|
}
|
|
|
- if (dto.getRoleOverride() != null) {
|
|
|
- member.setRoleOverride(dto.getRoleOverride());
|
|
|
- }
|
|
|
|
|
|
member.setUpdatedAt(new Date());
|
|
|
familyMemberMapper.updateById(member);
|
|
|
logMemberAction(member.getFamilyId(), member.getId(), "update", oldNickname, member.getNickname(), userId);
|
|
|
|
|
|
- // 同步更新 family_members 中的 child 专属字段
|
|
|
- if ("child".equals(computeEffectiveRole(member))) {
|
|
|
- // family_members 本身已包含 child 专属字段,直接 updateById(member) 已足够
|
|
|
- }
|
|
|
-
|
|
|
- // 查询关系类型名称
|
|
|
- RelationshipType relType = relationshipTypeMapper.selectOne(
|
|
|
- new LambdaQueryWrapper<RelationshipType>()
|
|
|
- .eq(RelationshipType::getTypeKey, member.getRelationshipType()));
|
|
|
- return toFamilyMemberVO(member, relType);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取所有启用的关系类型列表
|
|
|
- */
|
|
|
- public List<RelationshipType> getRelationshipTypes() {
|
|
|
- return relationshipTypeMapper.selectList(
|
|
|
- new LambdaQueryWrapper<RelationshipType>()
|
|
|
- .eq(RelationshipType::getEnabled, 1)
|
|
|
- .orderByAsc(RelationshipType::getSortOrder));
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 根据关系类型key获取关系类型
|
|
|
- */
|
|
|
- public RelationshipType getRelationshipTypeByKey(String typeKey) {
|
|
|
- return relationshipTypeMapper.selectOne(
|
|
|
- new LambdaQueryWrapper<RelationshipType>()
|
|
|
- .eq(RelationshipType::getTypeKey, typeKey));
|
|
|
- }
|
|
|
-
|
|
|
- // ===== 管理端方法 =====
|
|
|
-
|
|
|
- public List<RelationshipType> listAllRelationshipTypes() {
|
|
|
- return relationshipTypeMapper.selectList(
|
|
|
- new LambdaQueryWrapper<RelationshipType>()
|
|
|
- .orderByAsc(RelationshipType::getSortOrder));
|
|
|
- }
|
|
|
-
|
|
|
- @Transactional(rollbackFor = Exception.class)
|
|
|
- public RelationshipType saveRelationshipType(RelationshipType type) {
|
|
|
- if (type.getId() != null) {
|
|
|
- RelationshipType existing = relationshipTypeMapper.selectById(type.getId());
|
|
|
- if (existing != null) {
|
|
|
- existing.setTypeKey(type.getTypeKey());
|
|
|
- existing.setTypeName(type.getTypeName());
|
|
|
- existing.setDefaultRole(type.getDefaultRole());
|
|
|
- existing.setSortOrder(type.getSortOrder());
|
|
|
- existing.setEnabled(type.getEnabled());
|
|
|
- relationshipTypeMapper.updateById(existing);
|
|
|
- return existing;
|
|
|
- }
|
|
|
- }
|
|
|
- type.setCreatedAt(new Date());
|
|
|
- relationshipTypeMapper.insert(type);
|
|
|
- return type;
|
|
|
- }
|
|
|
-
|
|
|
- @Transactional(rollbackFor = Exception.class)
|
|
|
- public void deleteRelationshipType(Long id) {
|
|
|
- relationshipTypeMapper.deleteById(id);
|
|
|
+ return toFamilyMemberVO(member);
|
|
|
}
|
|
|
|
|
|
// ===== 内部方法 =====
|
|
|
|
|
|
- private FamilyMemberVO toFamilyMemberVO(FamilyMember member, RelationshipType relType) {
|
|
|
+ private FamilyMemberVO toFamilyMemberVO(FamilyMember member) {
|
|
|
FamilyMemberVO vo = new FamilyMemberVO();
|
|
|
vo.setId(member.getId());
|
|
|
vo.setSource("family_member");
|
|
|
@@ -461,16 +364,9 @@ public class FamilyMemberService {
|
|
|
vo.setPhone(member.getPhone());
|
|
|
vo.setAvatar(member.getAvatar());
|
|
|
vo.setGender(member.getGender());
|
|
|
- vo.setRelationshipType(member.getRelationshipType());
|
|
|
- if (relType != null) {
|
|
|
- vo.setRelationshipTypeName(relType.getTypeName());
|
|
|
- vo.setRoleLabel(relType.getTypeName());
|
|
|
- } else {
|
|
|
- vo.setRelationshipTypeName(member.getRelationshipType());
|
|
|
- vo.setRoleLabel(computeEffectiveRole(member));
|
|
|
- }
|
|
|
+ vo.setGeneration(member.getGeneration());
|
|
|
vo.setEffectiveRole(computeEffectiveRole(member));
|
|
|
- vo.setRoleOverride(member.getRoleOverride());
|
|
|
+ vo.setRoleLabel(computeEffectiveRole(member));
|
|
|
vo.setTotalPoints(member.getTotalPoints());
|
|
|
vo.setShowToFamily(member.getShowToFamily());
|
|
|
if (member.getBirthday() != null) {
|
|
|
@@ -495,21 +391,14 @@ public class FamilyMemberService {
|
|
|
|
|
|
/**
|
|
|
* 计算成员的实际角色(effective role)
|
|
|
- * 优先级: roleOverride > defaultRole(关系类型模板) > 按年龄计算
|
|
|
+ * 基于 generation:>=0 → parent, <0 → child;无 generation 则按年龄 fallback
|
|
|
*/
|
|
|
private String computeEffectiveRole(FamilyMember member) {
|
|
|
- // 1. roleOverride 非 auto/null → 直接返回
|
|
|
- if (member.getRoleOverride() != null && !"auto".equals(member.getRoleOverride())) {
|
|
|
- return member.getRoleOverride();
|
|
|
- }
|
|
|
- // 2. 取关系类型模板值
|
|
|
- RelationshipType relType = relationshipTypeMapper.selectOne(
|
|
|
- new LambdaQueryWrapper<RelationshipType>()
|
|
|
- .eq(RelationshipType::getTypeKey, member.getRelationshipType()));
|
|
|
- if (relType != null && relType.getDefaultRole() != null) {
|
|
|
- return relType.getDefaultRole();
|
|
|
- }
|
|
|
- // 3. 按年龄计算
|
|
|
+ // 基于 generation 计算:generation >= 0 = parent, generation < 0 = child
|
|
|
+ if (member.getGeneration() != null) {
|
|
|
+ return member.getGeneration() >= 0 ? "parent" : "child";
|
|
|
+ }
|
|
|
+ // 兼容旧数据(无 generation):按年龄 fallback
|
|
|
if (member.getBirthday() != null) {
|
|
|
int age = calculateAge(member.getBirthday());
|
|
|
int childThreshold = systemConfigService.getChildAgeThreshold();
|
|
|
@@ -519,103 +408,129 @@ public class FamilyMemberService {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 计算视角相关的关系标签
|
|
|
- * 规则:
|
|
|
- * - 查看者自己 → "我"
|
|
|
- * - parent→child:独生→"儿子"/"女儿",多子女→"长"/"次"/"三"...+"子"/"女"
|
|
|
- * - child→parent → "父亲"/"母亲"
|
|
|
- * - child→child → 按年龄比较→"哥哥"/"姐姐"/"弟弟"/"妹妹"
|
|
|
- * - parent→parent → "丈夫"/"妻子"
|
|
|
- * - 性别缺失且为孩子角色 → "孩子"
|
|
|
+ * 计算视角相关的关系标签(基于 generation 差值)
|
|
|
+ * - generation diff > 0: 长辈
|
|
|
+ * - generation diff < 0: 晚辈
|
|
|
+ * - generation diff = 0: 同辈(配偶/兄弟姐妹)
|
|
|
*/
|
|
|
private String computeRelativeLabel(FamilyMember viewer, FamilyMember target, List<FamilyMember> allMembers) {
|
|
|
- // 自己 → "我"
|
|
|
if (viewer.getId().equals(target.getId())) {
|
|
|
return "我";
|
|
|
}
|
|
|
|
|
|
+ // 优先使用 generation diff
|
|
|
+ if (viewer.getGeneration() != null && target.getGeneration() != null) {
|
|
|
+ int genDiff = target.getGeneration() - viewer.getGeneration();
|
|
|
+ boolean isSpouse = Boolean.TRUE.equals(target.getIsSpouse());
|
|
|
+ String targetGender = target.getGender();
|
|
|
+
|
|
|
+ switch (genDiff) {
|
|
|
+ case 0:
|
|
|
+ if (isSpouse) {
|
|
|
+ return "male".equals(targetGender) ? "丈夫" : "妻子";
|
|
|
+ }
|
|
|
+ return computeSiblingLabel(viewer, target);
|
|
|
+ case 1:
|
|
|
+ return "male".equals(targetGender) ? "爸爸" : "妈妈";
|
|
|
+ case -1:
|
|
|
+ return computeParentChildLabel(viewer, target, allMembers);
|
|
|
+ case 2:
|
|
|
+ return "male".equals(targetGender) ? "爷爷" : "奶奶";
|
|
|
+ case -2:
|
|
|
+ return "male".equals(targetGender) ? "孙子" : "孙女";
|
|
|
+ case 3:
|
|
|
+ return "male".equals(targetGender) ? "曾祖父" : "曾祖母";
|
|
|
+ case -3:
|
|
|
+ return "male".equals(targetGender) ? "曾孙" : "曾孙女";
|
|
|
+ default:
|
|
|
+ return genDiff > 0 ? "长辈" : "晚辈";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 无 generation 时的 fallback(旧数据兼容)
|
|
|
String viewerRole = computeEffectiveRole(viewer);
|
|
|
String targetRole = computeEffectiveRole(target);
|
|
|
String targetGender = target.getGender();
|
|
|
|
|
|
// parent → child
|
|
|
if ("parent".equals(viewerRole) && "child".equals(targetRole)) {
|
|
|
- // 收集所有孩子,按生日从小到大排序(年长的排前面)
|
|
|
- List<FamilyMember> children = allMembers.stream()
|
|
|
- .filter(m -> "child".equals(computeEffectiveRole(m)))
|
|
|
- .sorted(Comparator.comparing(FamilyMember::getBirthday, Comparator.nullsLast(Comparator.naturalOrder())))
|
|
|
- .collect(Collectors.toList());
|
|
|
-
|
|
|
- // 找到目标在孩子中的序号
|
|
|
- int index = -1;
|
|
|
- for (int i = 0; i < children.size(); i++) {
|
|
|
- if (children.get(i).getId().equals(target.getId())) {
|
|
|
- index = i;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (children.size() == 1) {
|
|
|
- // 独生子女,无序号前缀
|
|
|
- if ("male".equals(targetGender)) return "儿子";
|
|
|
- if ("female".equals(targetGender)) return "女儿";
|
|
|
- return "孩子";
|
|
|
- }
|
|
|
-
|
|
|
- // 多子女,按年龄排序加序号前缀
|
|
|
- String[] ordinals = {"长", "次", "三", "四", "五", "六", "七", "八", "九", "十"};
|
|
|
- String prefix = (index >= 0 && index < ordinals.length) ? ordinals[index] : ("第" + (index + 1));
|
|
|
- if ("male".equals(targetGender)) return prefix + "子";
|
|
|
- if ("female".equals(targetGender)) return prefix + "女";
|
|
|
- return prefix + "孩子";
|
|
|
+ return computeParentChildLabel(viewer, target, allMembers);
|
|
|
}
|
|
|
|
|
|
// child → parent
|
|
|
if ("child".equals(viewerRole) && "parent".equals(targetRole)) {
|
|
|
- if ("male".equals(targetGender)) return "父亲";
|
|
|
- if ("female".equals(targetGender)) return "母亲";
|
|
|
- return "父亲";
|
|
|
+ return "male".equals(targetGender) ? "父亲" : "母亲";
|
|
|
}
|
|
|
|
|
|
// child → child (sibling)
|
|
|
if ("child".equals(viewerRole) && "child".equals(targetRole)) {
|
|
|
- Date viewerBday = viewer.getBirthday();
|
|
|
- Date targetBday = target.getBirthday();
|
|
|
-
|
|
|
- if (viewerBday != null && targetBday != null) {
|
|
|
- int cmp = viewerBday.compareTo(targetBday);
|
|
|
- if (cmp > 0) {
|
|
|
- // viewer older → target younger
|
|
|
- if ("male".equals(targetGender)) return "弟弟";
|
|
|
- if ("female".equals(targetGender)) return "妹妹";
|
|
|
- return "孩子";
|
|
|
- } else if (cmp < 0) {
|
|
|
- // viewer younger → target older
|
|
|
- if ("male".equals(targetGender)) return "哥哥";
|
|
|
- if ("female".equals(targetGender)) return "姐姐";
|
|
|
- return "孩子";
|
|
|
- }
|
|
|
- }
|
|
|
- // 无法比较生日或同龄 → 默认用哥哥/姐姐
|
|
|
- if ("male".equals(targetGender)) return "哥哥";
|
|
|
- if ("female".equals(targetGender)) return "姐姐";
|
|
|
- return "孩子";
|
|
|
+ return computeSiblingLabel(viewer, target);
|
|
|
}
|
|
|
|
|
|
// parent → parent (partner)
|
|
|
if ("parent".equals(viewerRole) && "parent".equals(targetRole)) {
|
|
|
- if ("male".equals(targetGender)) return "丈夫";
|
|
|
- if ("female".equals(targetGender)) return "妻子";
|
|
|
- return "配偶";
|
|
|
+ return "male".equals(targetGender) ? "丈夫" : "妻子";
|
|
|
}
|
|
|
|
|
|
- // 默认fallback:孩子角色无性别 → "孩子"
|
|
|
- if ("child".equals(targetRole)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算父母视角下的子女标签(含序数)
|
|
|
+ */
|
|
|
+ private String computeParentChildLabel(FamilyMember viewer, FamilyMember target, List<FamilyMember> allMembers) {
|
|
|
+ String targetGender = target.getGender();
|
|
|
+ // 收集所有孩子,按 generation 降序(辈分越高,年龄越大)或生日排序
|
|
|
+ List<FamilyMember> children = allMembers.stream()
|
|
|
+ .filter(m -> !m.getId().equals(viewer.getId()))
|
|
|
+ .filter(m -> {
|
|
|
+ if (viewer.getGeneration() != null && m.getGeneration() != null) {
|
|
|
+ return m.getGeneration() < viewer.getGeneration();
|
|
|
+ }
|
|
|
+ return "child".equals(computeEffectiveRole(m));
|
|
|
+ })
|
|
|
+ .sorted(Comparator.comparing(FamilyMember::getBirthday, Comparator.nullsLast(Comparator.naturalOrder())))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ int index = -1;
|
|
|
+ for (int i = 0; i < children.size(); i++) {
|
|
|
+ if (children.get(i).getId().equals(target.getId())) {
|
|
|
+ index = i;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (children.size() <= 1 || index < 0) {
|
|
|
if ("male".equals(targetGender)) return "儿子";
|
|
|
if ("female".equals(targetGender)) return "女儿";
|
|
|
return "孩子";
|
|
|
}
|
|
|
- return null;
|
|
|
+
|
|
|
+ String[] ordinals = {"长", "次", "三", "四", "五", "六", "七", "八", "九", "十"};
|
|
|
+ String prefix = (index < ordinals.length) ? ordinals[index] : ("第" + (index + 1));
|
|
|
+ if ("male".equals(targetGender)) return prefix + "子";
|
|
|
+ if ("female".equals(targetGender)) return prefix + "女";
|
|
|
+ return prefix + "孩子";
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算兄弟姐妹标签(按生日比较)
|
|
|
+ */
|
|
|
+ private String computeSiblingLabel(FamilyMember viewer, FamilyMember target) {
|
|
|
+ String targetGender = target.getGender();
|
|
|
+ Date viewerBday = viewer.getBirthday();
|
|
|
+ Date targetBday = target.getBirthday();
|
|
|
+
|
|
|
+ if (viewerBday != null && targetBday != null) {
|
|
|
+ int cmp = viewerBday.compareTo(targetBday);
|
|
|
+ if (cmp > 0) {
|
|
|
+ return "male".equals(targetGender) ? "弟弟" : "妹妹";
|
|
|
+ } else if (cmp < 0) {
|
|
|
+ return "male".equals(targetGender) ? "哥哥" : "姐姐";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 同龄或无法比较
|
|
|
+ return "male".equals(targetGender) ? "哥哥" : "姐姐";
|
|
|
}
|
|
|
|
|
|
private void logMemberAction(Long familyId, Long memberId, String action, String oldValue, String newValue, Long operatorId) {
|