Переглянути джерело

fix(family): 审批加入时创建者切换家庭前置校验——原家庭仅一人免转让;多人时错误信息指向申请人并给转让指引

liaoxg 1 тиждень тому
батько
коміт
46ddf3550c

+ 23 - 0
cfc-backend/src/main/java/com/etotem/cfc/service/FamilyJoinRequestService.java

@@ -5,10 +5,12 @@ import com.etotem.cfc.dto.FamilyJoinRequestDTO;
 import com.etotem.cfc.entity.FamilyInvitation;
 import com.etotem.cfc.entity.Family;
 import com.etotem.cfc.entity.FamilyJoinRequest;
+import com.etotem.cfc.entity.FamilyMember;
 import com.etotem.cfc.entity.User;
 import com.etotem.cfc.mapper.FamilyInvitationMapper;
 import com.etotem.cfc.mapper.FamilyJoinRequestMapper;
 import com.etotem.cfc.mapper.FamilyMapper;
+import com.etotem.cfc.mapper.FamilyMemberMapper;
 import com.etotem.cfc.mapper.UserMapper;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
@@ -31,6 +33,9 @@ public class FamilyJoinRequestService {
     @Resource
     private FamilyMapper familyMapper;
 
+    @Resource
+    private FamilyMemberMapper familyMemberMapper;
+
     @Resource
     private UserMapper userMapper;
 
@@ -155,6 +160,24 @@ public class FamilyJoinRequestService {
         }
 
         if (user.getFamilyId() != null && user.getFamilyId() != 0L && !user.getFamilyId().equals(family.getId())) {
+            // 申请人已有其他家庭:切换会被拒绝的情形前置拦截,给出明确主体与解决指引。
+            // 关键:错误主体是【申请人】而不是审批人——申请人若为原家庭创建者,切换家庭
+            // (FamilyMemberService.switchMemberToFamily)会抛「您是家庭创建者,请先转让管理员权限」,
+            // 审批人收到该文案会误读为自己要转让管理员(实际创建者=管理员,并无此问题)。
+            // 例外:原家庭仅创建者一人时,离开后家庭无人,不存在无主问题,允许直接切换加入。
+            Family oldFamily = familyMapper.selectById(user.getFamilyId());
+            if (oldFamily != null && user.getId().equals(oldFamily.getCreatorId())) {
+                Long otherMemberCount = familyMemberMapper.selectCount(
+                        new LambdaQueryWrapper<FamilyMember>()
+                                .eq(FamilyMember::getFamilyId, user.getFamilyId())
+                                .ne(FamilyMember::getUserId, user.getId())
+                                .ne(FamilyMember::getStatus, "recycled"));
+                if (otherMemberCount != null && otherMemberCount > 0) {
+                    String nick = (user.getNickname() != null && !user.getNickname().isEmpty())
+                            ? user.getNickname() : ("用户" + user.getId());
+                    throw new RuntimeException("申请人「" + nick + "」是原家庭创建者,且原家庭还有其他成员,暂不能切换家庭加入。需先由该申请人在原家庭成员页将管理员身份转让给他人,再重新发起申请");
+                }
+            }
             familyInvitationService.mergeIntoFamily(user.getId(), family.getId());
             log.info("审批通过并合并家庭: userId={}, oldFamily={}, targetFamily={}, requestId={}",
                     user.getId(), user.getFamilyId(), family.getId(), request.getId());

+ 10 - 1
cfc-backend/src/main/java/com/etotem/cfc/service/FamilyMemberService.java

@@ -604,7 +604,16 @@ public class FamilyMemberService {
         }
         Family oldFamily = familyMapper.selectById(oldFamilyId);
         if (oldFamily != null && Long.valueOf(userId).equals(oldFamily.getCreatorId())) {
-            throw new RuntimeException("您是家庭创建者,请先转让管理员权限后再切换家庭");
+            // 创建者离开须先转让管理员(防原家庭无主);但原家庭仅剩创建者一人时,
+            // 离开后家庭无人,不存在无主问题,无需转让,直接允许切换
+            Long otherMemberCount = familyMemberMapper.selectCount(
+                    new LambdaQueryWrapper<FamilyMember>()
+                            .eq(FamilyMember::getFamilyId, oldFamilyId)
+                            .ne(FamilyMember::getUserId, userId)
+                            .ne(FamilyMember::getStatus, "recycled"));
+            if (otherMemberCount != null && otherMemberCount > 0) {
+                throw new RuntimeException("您是家庭创建者,请先转让管理员权限后再切换家庭");
+            }
         }
         if (!isWechatUser(user)) {
             throw new RuntimeException("非微信登录用户不能自主切换家庭");