|
@@ -10,12 +10,16 @@ import com.etotem.cfc.entity.FamilyMember;
|
|
|
import com.etotem.cfc.entity.FamilyRelationship;
|
|
import com.etotem.cfc.entity.FamilyRelationship;
|
|
|
import com.etotem.cfc.entity.FamilyMemberAttributes;
|
|
import com.etotem.cfc.entity.FamilyMemberAttributes;
|
|
|
import com.etotem.cfc.entity.FamilyMemberLog;
|
|
import com.etotem.cfc.entity.FamilyMemberLog;
|
|
|
|
|
+import com.etotem.cfc.entity.FiveDimensionScore;
|
|
|
|
|
+import com.etotem.cfc.entity.HealthReport;
|
|
|
import com.etotem.cfc.entity.User;
|
|
import com.etotem.cfc.entity.User;
|
|
|
import com.etotem.cfc.enums.GenerationLevel;
|
|
import com.etotem.cfc.enums.GenerationLevel;
|
|
|
import com.etotem.cfc.mapper.FamilyMapper;
|
|
import com.etotem.cfc.mapper.FamilyMapper;
|
|
|
import com.etotem.cfc.mapper.FamilyMemberAttributesMapper;
|
|
import com.etotem.cfc.mapper.FamilyMemberAttributesMapper;
|
|
|
import com.etotem.cfc.mapper.FamilyMemberLogMapper;
|
|
import com.etotem.cfc.mapper.FamilyMemberLogMapper;
|
|
|
import com.etotem.cfc.mapper.FamilyMemberMapper;
|
|
import com.etotem.cfc.mapper.FamilyMemberMapper;
|
|
|
|
|
+import com.etotem.cfc.mapper.FiveDimensionScoreMapper;
|
|
|
|
|
+import com.etotem.cfc.mapper.HealthReportMapper;
|
|
|
import com.etotem.cfc.mapper.UserMapper;
|
|
import com.etotem.cfc.mapper.UserMapper;
|
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
import org.slf4j.LoggerFactory;
|
|
@@ -63,6 +67,12 @@ public class FamilyMemberService {
|
|
|
@Resource
|
|
@Resource
|
|
|
private CouponService couponService;
|
|
private CouponService couponService;
|
|
|
|
|
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ private FiveDimensionScoreMapper fiveDimensionScoreMapper;
|
|
|
|
|
+
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ private HealthReportMapper healthReportMapper;
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 添加家庭成员
|
|
* 添加家庭成员
|
|
|
*/
|
|
*/
|
|
@@ -211,9 +221,11 @@ public class FamilyMemberService {
|
|
|
Long creatorId = (family != null) ? family.getCreatorId() : null;
|
|
Long creatorId = (family != null) ? family.getCreatorId() : null;
|
|
|
boolean isAdmin = creatorId != null && creatorId.equals(userId);
|
|
boolean isAdmin = creatorId != null && creatorId.equals(userId);
|
|
|
|
|
|
|
|
- // 查询 family_members 表
|
|
|
|
|
|
|
+ // 查询 family_members 表(排除回收箱成员)
|
|
|
List<FamilyMember> familyMembers = familyMemberMapper.selectList(
|
|
List<FamilyMember> familyMembers = familyMemberMapper.selectList(
|
|
|
- new LambdaQueryWrapper<FamilyMember>().eq(FamilyMember::getFamilyId, familyId));
|
|
|
|
|
|
|
+ new LambdaQueryWrapper<FamilyMember>()
|
|
|
|
|
+ .eq(FamilyMember::getFamilyId, familyId)
|
|
|
|
|
+ .ne(FamilyMember::getStatus, "recycled"));
|
|
|
|
|
|
|
|
// 查找当前查看者在 family_members 中的记录(用于计算视角标签)
|
|
// 查找当前查看者在 family_members 中的记录(用于计算视角标签)
|
|
|
FamilyMember viewerMember = null;
|
|
FamilyMember viewerMember = null;
|
|
@@ -365,7 +377,13 @@ public class FamilyMemberService {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 踢出家庭成员
|
|
|
|
|
|
|
+ * 踢出家庭成员(管理员操作)
|
|
|
|
|
+ * 规则:
|
|
|
|
|
+ * - 仅管理员可踢出
|
|
|
|
|
+ * - 被踢成员 CF 值(system_points)随成员带走
|
|
|
|
|
+ * - 收回该家庭发放给该成员的人口券(POPULATION)
|
|
|
|
|
+ * - 微信登录用户:迁移资产到其初始家庭(无则创建新家庭)
|
|
|
|
|
+ * - 非微信登录用户:进入回收箱(status=recycled),资产保留,可后续回收
|
|
|
*/
|
|
*/
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
public void kickMember(Long userId, Long memberId) {
|
|
public void kickMember(Long userId, Long memberId) {
|
|
@@ -384,30 +402,304 @@ public class FamilyMemberService {
|
|
|
|
|
|
|
|
// 从 family_members 踢出
|
|
// 从 family_members 踢出
|
|
|
FamilyMember member = familyMemberMapper.selectById(memberId);
|
|
FamilyMember member = familyMemberMapper.selectById(memberId);
|
|
|
- if (member != null && member.getFamilyId().equals(operator.getFamilyId())) {
|
|
|
|
|
- // 先清理关系记录
|
|
|
|
|
- familyRelationshipService.deleteRelationsForMember(memberId);
|
|
|
|
|
- familyMemberMapper.deleteById(memberId);
|
|
|
|
|
- logMemberAction(operator.getFamilyId(), memberId, "kick", member.getNickname(), null, userId);
|
|
|
|
|
- // 如果关联了 User:优先恢复到其自己创建的家庭,否则清除 familyId
|
|
|
|
|
- if (member.getUserId() != null) {
|
|
|
|
|
- User targetUser = userMapper.selectById(member.getUserId());
|
|
|
|
|
- if (targetUser != null && operator.getFamilyId().equals(targetUser.getFamilyId())) {
|
|
|
|
|
- Long ownFamilyId = findOwnFamilyId(targetUser.getId());
|
|
|
|
|
|
|
+ if (member == null || !member.getFamilyId().equals(operator.getFamilyId())) {
|
|
|
|
|
+ throw new RuntimeException("成员不存在");
|
|
|
|
|
+ }
|
|
|
|
|
+ // 不能踢出家庭创建者
|
|
|
|
|
+ if (member.getUserId() != null && Long.valueOf(member.getUserId()).equals(family.getCreatorId())) {
|
|
|
|
|
+ throw new RuntimeException("不能踢出家庭创建者,请先转让管理员权限");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Long oldFamilyId = member.getFamilyId();
|
|
|
|
|
+ Long targetUserId = member.getUserId();
|
|
|
|
|
+
|
|
|
|
|
+ // 收回该家庭发放给该成员的人口券
|
|
|
|
|
+ try {
|
|
|
|
|
+ couponService.revokeFamilyPopulationCoupons(oldFamilyId, memberId);
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("收回人口券异常: familyId={}, memberId={}", oldFamilyId, memberId, e);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 清理关系记录
|
|
|
|
|
+ familyRelationshipService.deleteRelationsForMember(memberId);
|
|
|
|
|
+
|
|
|
|
|
+ if (targetUserId != null) {
|
|
|
|
|
+ User targetUser = userMapper.selectById(targetUserId);
|
|
|
|
|
+ if (targetUser != null && oldFamilyId.equals(targetUser.getFamilyId())) {
|
|
|
|
|
+ boolean isWechatUser = isWechatUser(targetUser);
|
|
|
|
|
+ if (isWechatUser) {
|
|
|
|
|
+ // 微信用户:迁移资产到初始家庭,CF 带走
|
|
|
|
|
+ Long ownFamilyId = findOwnFamilyId(targetUserId);
|
|
|
|
|
+ if (ownFamilyId == null) {
|
|
|
|
|
+ ownFamilyId = createFamilyForUser(targetUser);
|
|
|
|
|
+ }
|
|
|
|
|
+ migrateMemberAssets(member, oldFamilyId, ownFamilyId);
|
|
|
|
|
+ member.setFamilyId(ownFamilyId);
|
|
|
|
|
+ member.setStatus("active");
|
|
|
|
|
+ member.setUpdatedAt(new Date());
|
|
|
|
|
+ familyMemberMapper.updateById(member);
|
|
|
targetUser.setFamilyId(ownFamilyId);
|
|
targetUser.setFamilyId(ownFamilyId);
|
|
|
targetUser.setUpdatedAt(new Date());
|
|
targetUser.setUpdatedAt(new Date());
|
|
|
userMapper.updateById(targetUser);
|
|
userMapper.updateById(targetUser);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 非微信用户:进入回收箱,资产保留在原家庭记录上
|
|
|
|
|
+ member.setStatus("recycled");
|
|
|
|
|
+ member.setUpdatedAt(new Date());
|
|
|
|
|
+ familyMemberMapper.updateById(member);
|
|
|
|
|
+ targetUser.setFamilyId(null);
|
|
|
|
|
+ targetUser.setUpdatedAt(new Date());
|
|
|
|
|
+ userMapper.updateById(targetUser);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- // children 表已废除,无需额外清理
|
|
|
|
|
- // 如果成员有效角色为 child,可能需要清理其他关联数据(按需扩展)
|
|
|
|
|
- if ("child".equals(computeEffectiveRole(member))) {
|
|
|
|
|
- // child 专属数据(如游戏记录等)后续按需清理
|
|
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 无关联用户(纯手动添加的成员):直接删除记录
|
|
|
|
|
+ familyMemberMapper.deleteById(memberId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ logMemberAction(oldFamilyId, memberId, "kick", member.getNickname(), null, userId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 主动退出家庭(微信登录用户)
|
|
|
|
|
+ * 规则:
|
|
|
|
|
+ * - 家庭创建者禁止退出,需先转让管理员
|
|
|
|
|
+ * - CF 值(system_points)清零丢弃(留在原家庭)
|
|
|
|
|
+ * - 迁移资产到初始家庭(无则创建新家庭)
|
|
|
|
|
+ */
|
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
|
|
+ public void leaveFamily(Long userId) {
|
|
|
|
|
+ User user = userMapper.selectById(userId);
|
|
|
|
|
+ if (user == null || user.getFamilyId() == null) {
|
|
|
|
|
+ throw new RuntimeException("用户未加入家庭");
|
|
|
|
|
+ }
|
|
|
|
|
+ Long oldFamilyId = user.getFamilyId();
|
|
|
|
|
+ Family family = familyMapper.selectById(oldFamilyId);
|
|
|
|
|
+ if (family == null) {
|
|
|
|
|
+ throw new RuntimeException("家庭不存在");
|
|
|
|
|
+ }
|
|
|
|
|
+ // 家庭创建者禁止退出
|
|
|
|
|
+ if (Long.valueOf(userId).equals(family.getCreatorId())) {
|
|
|
|
|
+ throw new RuntimeException("您是家庭创建者,请先转让管理员权限后再退出");
|
|
|
|
|
+ }
|
|
|
|
|
+ // 非微信用户禁止自主退出
|
|
|
|
|
+ if (!isWechatUser(user)) {
|
|
|
|
|
+ throw new RuntimeException("非微信登录用户不能自主退出家庭");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 查找该用户在 family_members 中的记录
|
|
|
|
|
+ FamilyMember member = familyMemberMapper.selectOne(
|
|
|
|
|
+ new LambdaQueryWrapper<FamilyMember>()
|
|
|
|
|
+ .eq(FamilyMember::getFamilyId, oldFamilyId)
|
|
|
|
|
+ .eq(FamilyMember::getUserId, userId)
|
|
|
|
|
+ .last("LIMIT 1"));
|
|
|
|
|
+ if (member == null) {
|
|
|
|
|
+ throw new RuntimeException("未找到该用户的家庭成员记录");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // CF 值清零丢弃(留在原家庭)
|
|
|
|
|
+ member.setSystemPoints(0);
|
|
|
|
|
+ member.setUpdatedAt(new Date());
|
|
|
|
|
+
|
|
|
|
|
+ // 清理关系记录
|
|
|
|
|
+ familyRelationshipService.deleteRelationsForMember(member.getId());
|
|
|
|
|
+
|
|
|
|
|
+ // 迁移资产到初始家庭
|
|
|
|
|
+ Long ownFamilyId = findOwnFamilyId(userId);
|
|
|
|
|
+ if (ownFamilyId == null) {
|
|
|
|
|
+ ownFamilyId = createFamilyForUser(user);
|
|
|
|
|
+ }
|
|
|
|
|
+ migrateMemberAssets(member, oldFamilyId, ownFamilyId);
|
|
|
|
|
+ member.setFamilyId(ownFamilyId);
|
|
|
|
|
+ member.setStatus("active");
|
|
|
|
|
+ familyMemberMapper.updateById(member);
|
|
|
|
|
+
|
|
|
|
|
+ user.setFamilyId(ownFamilyId);
|
|
|
|
|
+ user.setUpdatedAt(new Date());
|
|
|
|
|
+ userMapper.updateById(user);
|
|
|
|
|
+
|
|
|
|
|
+ logMemberAction(oldFamilyId, member.getId(), "leave", member.getNickname(), null, userId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 从回收箱回收成员(管理员操作):将回收箱中的非微信用户重新加入指定家庭
|
|
|
|
|
+ */
|
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
|
|
+ public void recycleMember(Long operatorUserId, Long memberId, Long targetFamilyId) {
|
|
|
|
|
+ User operator = userMapper.selectById(operatorUserId);
|
|
|
|
|
+ if (operator == null || operator.getFamilyId() == null) {
|
|
|
|
|
+ throw new RuntimeException("用户未加入家庭");
|
|
|
|
|
+ }
|
|
|
|
|
+ Family targetFamily = familyMapper.selectById(targetFamilyId);
|
|
|
|
|
+ if (targetFamily == null) {
|
|
|
|
|
+ throw new RuntimeException("目标家庭不存在");
|
|
|
|
|
+ }
|
|
|
|
|
+ // 仅管理员可回收
|
|
|
|
|
+ if (!Long.valueOf(operatorUserId).equals(targetFamily.getCreatorId())) {
|
|
|
|
|
+ throw new RuntimeException("只有目标家庭管理员才能回收成员");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ FamilyMember member = familyMemberMapper.selectById(memberId);
|
|
|
|
|
+ if (member == null) {
|
|
|
|
|
+ throw new RuntimeException("成员不存在");
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!"recycled".equals(member.getStatus())) {
|
|
|
|
|
+ throw new RuntimeException("该成员不在回收箱中");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 迁移资产到目标家庭
|
|
|
|
|
+ Long oldFamilyId = member.getFamilyId();
|
|
|
|
|
+ migrateMemberAssets(member, oldFamilyId, targetFamilyId);
|
|
|
|
|
+ member.setFamilyId(targetFamilyId);
|
|
|
|
|
+ member.setStatus("active");
|
|
|
|
|
+ member.setUpdatedAt(new Date());
|
|
|
|
|
+ familyMemberMapper.updateById(member);
|
|
|
|
|
+
|
|
|
|
|
+ // 关联用户重新归属目标家庭
|
|
|
|
|
+ if (member.getUserId() != null) {
|
|
|
|
|
+ User targetUser = userMapper.selectById(member.getUserId());
|
|
|
|
|
+ if (targetUser != null) {
|
|
|
|
|
+ targetUser.setFamilyId(targetFamilyId);
|
|
|
|
|
+ targetUser.setUpdatedAt(new Date());
|
|
|
|
|
+ userMapper.updateById(targetUser);
|
|
|
}
|
|
}
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ logMemberAction(targetFamilyId, memberId, "recycle", null, member.getNickname(), operatorUserId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 切换成员到目标家庭(被邀请走/加入新家庭场景)
|
|
|
|
|
+ * 规则:
|
|
|
|
|
+ * - 非微信用户禁止自主切换
|
|
|
|
|
+ * - 家庭创建者禁止切换(需先转让管理员)
|
|
|
|
|
+ * - CF 值(system_points)清零丢弃(留在原家庭)
|
|
|
|
|
+ * - 迁移资产到目标家庭
|
|
|
|
|
+ */
|
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
|
|
+ public void switchMemberToFamily(Long userId, Long targetFamilyId) {
|
|
|
|
|
+ User user = userMapper.selectById(userId);
|
|
|
|
|
+ if (user == null || user.getFamilyId() == null) {
|
|
|
|
|
+ throw new RuntimeException("用户未加入家庭");
|
|
|
|
|
+ }
|
|
|
|
|
+ Long oldFamilyId = user.getFamilyId();
|
|
|
|
|
+ if (oldFamilyId.equals(targetFamilyId)) {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
+ Family oldFamily = familyMapper.selectById(oldFamilyId);
|
|
|
|
|
+ if (oldFamily != null && Long.valueOf(userId).equals(oldFamily.getCreatorId())) {
|
|
|
|
|
+ throw new RuntimeException("您是家庭创建者,请先转让管理员权限后再切换家庭");
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!isWechatUser(user)) {
|
|
|
|
|
+ throw new RuntimeException("非微信登录用户不能自主切换家庭");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ FamilyMember member = familyMemberMapper.selectOne(
|
|
|
|
|
+ new LambdaQueryWrapper<FamilyMember>()
|
|
|
|
|
+ .eq(FamilyMember::getFamilyId, oldFamilyId)
|
|
|
|
|
+ .eq(FamilyMember::getUserId, userId)
|
|
|
|
|
+ .last("LIMIT 1"));
|
|
|
|
|
+ if (member == null) {
|
|
|
|
|
+ throw new RuntimeException("未找到该用户的家庭成员记录");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // CF 值清零丢弃(留在原家庭)
|
|
|
|
|
+ member.setSystemPoints(0);
|
|
|
|
|
+ member.setUpdatedAt(new Date());
|
|
|
|
|
+
|
|
|
|
|
+ // 清理关系记录
|
|
|
|
|
+ familyRelationshipService.deleteRelationsForMember(member.getId());
|
|
|
|
|
+
|
|
|
|
|
+ // 迁移资产到目标家庭
|
|
|
|
|
+ migrateMemberAssets(member, oldFamilyId, targetFamilyId);
|
|
|
|
|
+ member.setFamilyId(targetFamilyId);
|
|
|
|
|
+ member.setStatus("active");
|
|
|
|
|
+ familyMemberMapper.updateById(member);
|
|
|
|
|
+
|
|
|
|
|
+ user.setFamilyId(targetFamilyId);
|
|
|
|
|
+ user.setUpdatedAt(new Date());
|
|
|
|
|
+ userMapper.updateById(user);
|
|
|
|
|
|
|
|
- throw new RuntimeException("成员不存在");
|
|
|
|
|
|
|
+ logMemberAction(oldFamilyId, member.getId(), "switch", member.getNickname(), null, userId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 迁移成员资产到目标家庭:
|
|
|
|
|
+ * - five_dimension_scores(能量值):改 family_id
|
|
|
|
|
+ * - health_reports(健康报告):改 family_id
|
|
|
|
|
+ * - dan_assessment_results(测评):以 familyMemberId 关联,改 family_members.family_id 后自动跟随,无需迁移
|
|
|
|
|
+ * - family_member_attributes(属性):以 memberId 关联,自动跟随
|
|
|
|
|
+ * - family_relationships(关系):删旧建新(新家庭关系需重新计算)
|
|
|
|
|
+ */
|
|
|
|
|
+ private void migrateMemberAssets(FamilyMember member, Long oldFamilyId, Long targetFamilyId) {
|
|
|
|
|
+ if (oldFamilyId.equals(targetFamilyId)) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ Long memberId = member.getId();
|
|
|
|
|
+ // 能量值
|
|
|
|
|
+ try {
|
|
|
|
|
+ List<FiveDimensionScore> scores = fiveDimensionScoreMapper.selectList(
|
|
|
|
|
+ new LambdaQueryWrapper<FiveDimensionScore>()
|
|
|
|
|
+ .eq(FiveDimensionScore::getFamilyId, oldFamilyId)
|
|
|
|
|
+ .eq(FiveDimensionScore::getMemberId, memberId));
|
|
|
|
|
+ for (FiveDimensionScore s : scores) {
|
|
|
|
|
+ s.setFamilyId(targetFamilyId);
|
|
|
|
|
+ fiveDimensionScoreMapper.updateById(s);
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("迁移能量值异常: memberId={}", memberId, e);
|
|
|
|
|
+ }
|
|
|
|
|
+ // 健康报告(按 userId 或 subjectId 关联)
|
|
|
|
|
+ try {
|
|
|
|
|
+ if (member.getUserId() != null) {
|
|
|
|
|
+ List<HealthReport> reports = healthReportMapper.selectList(
|
|
|
|
|
+ new LambdaQueryWrapper<HealthReport>()
|
|
|
|
|
+ .eq(HealthReport::getFamilyId, oldFamilyId)
|
|
|
|
|
+ .and(w -> w.eq(HealthReport::getUserId, member.getUserId())
|
|
|
|
|
+ .or().eq(HealthReport::getSubjectId, member.getUserId())));
|
|
|
|
|
+ for (HealthReport r : reports) {
|
|
|
|
|
+ r.setFamilyId(targetFamilyId);
|
|
|
|
|
+ healthReportMapper.updateById(r);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("迁移健康报告异常: memberId={}", memberId, e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 判断用户是否为微信登录用户(openid 为真实微信 openid,而非 "phone:" 前缀)
|
|
|
|
|
+ */
|
|
|
|
|
+ private boolean isWechatUser(User user) {
|
|
|
|
|
+ if (user == null || user.getOpenid() == null) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ return !user.getOpenid().startsWith("phone:");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 为用户创建新家庭(不含成员记录——调用方随后会迁移原 family_members 记录过来,避免重复)
|
|
|
|
|
+ */
|
|
|
|
|
+ private Long createFamilyForUser(User user) {
|
|
|
|
|
+ Family family = new Family();
|
|
|
|
|
+ String familyName = (user.getNickname() != null && !user.getNickname().isEmpty())
|
|
|
|
|
+ ? user.getNickname() + "的家庭" : "我的家庭";
|
|
|
|
|
+ family.setName(familyName);
|
|
|
|
|
+ family.setInviteCode(generateInviteCode());
|
|
|
|
|
+ family.setCreatorId(user.getId());
|
|
|
|
|
+ family.setCreatedAt(new Date());
|
|
|
|
|
+ family.setUpdatedAt(new Date());
|
|
|
|
|
+ familyMapper.insert(family);
|
|
|
|
|
+ return family.getId();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private String generateInviteCode() {
|
|
|
|
|
+ String chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
|
|
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
|
|
+ java.util.Random random = new java.util.Random();
|
|
|
|
|
+ for (int i = 0; i < 6; i++) {
|
|
|
|
|
+ sb.append(chars.charAt(random.nextInt(chars.length())));
|
|
|
|
|
+ }
|
|
|
|
|
+ return sb.toString();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -763,7 +1055,9 @@ public class FamilyMemberService {
|
|
|
result.put("parents", userMapper.selectList(
|
|
result.put("parents", userMapper.selectList(
|
|
|
new LambdaQueryWrapper<User>().eq(User::getFamilyId, familyId).eq(User::getRole, "parent")));
|
|
new LambdaQueryWrapper<User>().eq(User::getFamilyId, familyId).eq(User::getRole, "parent")));
|
|
|
result.put("children", familyMemberMapper.selectList(
|
|
result.put("children", familyMemberMapper.selectList(
|
|
|
- new LambdaQueryWrapper<FamilyMember>().eq(FamilyMember::getFamilyId, familyId)));
|
|
|
|
|
|
|
+ new LambdaQueryWrapper<FamilyMember>()
|
|
|
|
|
+ .eq(FamilyMember::getFamilyId, familyId)
|
|
|
|
|
+ .ne(FamilyMember::getStatus, "recycled")));
|
|
|
return result;
|
|
return result;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|