|
@@ -37,11 +37,16 @@ public class FamilyJoinRequestService {
|
|
|
@Resource
|
|
@Resource
|
|
|
private FamilyInvitationService familyInvitationService;
|
|
private FamilyInvitationService familyInvitationService;
|
|
|
|
|
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ private UnlockGateService unlockGateService;
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 创建家庭加入请求(待审批)
|
|
* 创建家庭加入请求(待审批)
|
|
|
*/
|
|
*/
|
|
|
public FamilyJoinRequest createJoinRequest(Long userId, String inviteCode, String familyRole) {
|
|
public FamilyJoinRequest createJoinRequest(Long userId, String inviteCode, String familyRole) {
|
|
|
Family family;
|
|
Family family;
|
|
|
|
|
+ Long inviterUserId = null;
|
|
|
|
|
+ String joinMethod = "by_code";
|
|
|
|
|
|
|
|
// 支持传入 familyId(数字)作为 inviteCode
|
|
// 支持传入 familyId(数字)作为 inviteCode
|
|
|
try {
|
|
try {
|
|
@@ -68,6 +73,9 @@ public class FamilyJoinRequestService {
|
|
|
if (family == null) {
|
|
if (family == null) {
|
|
|
throw new RuntimeException("邀请令牌无效");
|
|
throw new RuntimeException("邀请令牌无效");
|
|
|
}
|
|
}
|
|
|
|
|
+ // 审批绑定邀请人:谁分享的令牌,申请就由谁确认
|
|
|
|
|
+ inviterUserId = invitation.getCreatedBy();
|
|
|
|
|
+ joinMethod = "by_token";
|
|
|
} else {
|
|
} else {
|
|
|
family = familyMapper.selectOne(
|
|
family = familyMapper.selectOne(
|
|
|
new LambdaQueryWrapper<Family>()
|
|
new LambdaQueryWrapper<Family>()
|
|
@@ -104,7 +112,8 @@ public class FamilyJoinRequestService {
|
|
|
FamilyJoinRequest request = new FamilyJoinRequest();
|
|
FamilyJoinRequest request = new FamilyJoinRequest();
|
|
|
request.setRequesterUserId(userId);
|
|
request.setRequesterUserId(userId);
|
|
|
request.setTargetFamilyId(family.getId());
|
|
request.setTargetFamilyId(family.getId());
|
|
|
- request.setJoinMethod("by_code");
|
|
|
|
|
|
|
+ request.setInviterUserId(inviterUserId);
|
|
|
|
|
+ request.setJoinMethod(joinMethod);
|
|
|
request.setInviteRef(inviteCode.trim());
|
|
request.setInviteRef(inviteCode.trim());
|
|
|
request.setFamilyRole(familyRole);
|
|
request.setFamilyRole(familyRole);
|
|
|
request.setStatus("pending");
|
|
request.setStatus("pending");
|
|
@@ -112,14 +121,15 @@ public class FamilyJoinRequestService {
|
|
|
request.setUpdatedAt(new Date());
|
|
request.setUpdatedAt(new Date());
|
|
|
familyJoinRequestMapper.insert(request);
|
|
familyJoinRequestMapper.insert(request);
|
|
|
|
|
|
|
|
- log.info("已创建家庭加入请求: userId={}, familyId={}, requestId={}", userId, family.getId(), request.getId());
|
|
|
|
|
|
|
+ log.info("已创建家庭加入请求: userId={}, familyId={}, inviterUserId={}, requestId={}",
|
|
|
|
|
+ userId, family.getId(), inviterUserId, request.getId());
|
|
|
return request;
|
|
return request;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 家庭管理员审批加入请求
|
|
|
|
|
|
|
+ * 审批通过加入请求(审批人=邀请人,谁分享的卡谁确认;旧数据无邀请人时回退为家庭管理员)
|
|
|
*/
|
|
*/
|
|
|
- public void approveJoinRequest(Long requestId, Long adminUserId, String comment) {
|
|
|
|
|
|
|
+ public void approveJoinRequest(Long requestId, Long approverUserId, String comment) {
|
|
|
FamilyJoinRequest request = familyJoinRequestMapper.selectById(requestId);
|
|
FamilyJoinRequest request = familyJoinRequestMapper.selectById(requestId);
|
|
|
if (request == null) {
|
|
if (request == null) {
|
|
|
throw new RuntimeException("加入请求不存在");
|
|
throw new RuntimeException("加入请求不存在");
|
|
@@ -128,16 +138,12 @@ public class FamilyJoinRequestService {
|
|
|
throw new RuntimeException("该请求已处理");
|
|
throw new RuntimeException("该请求已处理");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 验证管理员身份
|
|
|
|
|
Family family = familyMapper.selectById(request.getTargetFamilyId());
|
|
Family family = familyMapper.selectById(request.getTargetFamilyId());
|
|
|
if (family == null) {
|
|
if (family == null) {
|
|
|
throw new RuntimeException("目标家庭不存在");
|
|
throw new RuntimeException("目标家庭不存在");
|
|
|
}
|
|
}
|
|
|
- User admin = userMapper.selectById(adminUserId);
|
|
|
|
|
- if (admin == null || !admin.getFamilyId().equals(family.getId())
|
|
|
|
|
- || !Boolean.TRUE.equals(admin.getIsFamilyAdmin())) {
|
|
|
|
|
- throw new RuntimeException("只有家庭管理员才能审批");
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // 验证审批人权限(邀请人,或旧数据兜底的家庭管理员)
|
|
|
|
|
+ checkApprovePermission(request, approverUserId);
|
|
|
|
|
|
|
|
// 审批通过:将用户加入家庭
|
|
// 审批通过:将用户加入家庭
|
|
|
User user = userMapper.selectById(request.getRequesterUserId());
|
|
User user = userMapper.selectById(request.getRequesterUserId());
|
|
@@ -159,18 +165,25 @@ public class FamilyJoinRequestService {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
request.setStatus("approved");
|
|
request.setStatus("approved");
|
|
|
- request.setApproverUserId(adminUserId);
|
|
|
|
|
|
|
+ request.setApproverUserId(approverUserId);
|
|
|
request.setComment(comment);
|
|
request.setComment(comment);
|
|
|
request.setUpdatedAt(new Date());
|
|
request.setUpdatedAt(new Date());
|
|
|
familyJoinRequestMapper.updateById(request);
|
|
familyJoinRequestMapper.updateById(request);
|
|
|
|
|
|
|
|
- log.info("已审批通过加入请求: requestId={}, userId={}, adminId={}", requestId, user.getId(), adminUserId);
|
|
|
|
|
|
|
+ // 与 /accept 直加路径保持一致:成员变更后刷新家庭通关解锁
|
|
|
|
|
+ try {
|
|
|
|
|
+ unlockGateService.refreshFamilyGates(family.getId(), user.getId());
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("刷新家庭通关解锁失败(不阻断审批): requestId={}, error={}", requestId, e.getMessage());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ log.info("已审批通过加入请求: requestId={}, userId={}, approverId={}", requestId, user.getId(), approverUserId);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 家庭管理员拒绝加入请求
|
|
|
|
|
|
|
+ * 拒绝加入请求(审批人=邀请人;旧数据无邀请人时回退为家庭管理员)
|
|
|
*/
|
|
*/
|
|
|
- public void rejectJoinRequest(Long requestId, Long adminUserId, String comment) {
|
|
|
|
|
|
|
+ public void rejectJoinRequest(Long requestId, Long approverUserId, String comment) {
|
|
|
FamilyJoinRequest request = familyJoinRequestMapper.selectById(requestId);
|
|
FamilyJoinRequest request = familyJoinRequestMapper.selectById(requestId);
|
|
|
if (request == null) {
|
|
if (request == null) {
|
|
|
throw new RuntimeException("加入请求不存在");
|
|
throw new RuntimeException("加入请求不存在");
|
|
@@ -179,37 +192,41 @@ public class FamilyJoinRequestService {
|
|
|
throw new RuntimeException("该请求已处理");
|
|
throw new RuntimeException("该请求已处理");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 验证管理员身份
|
|
|
|
|
- Family family = familyMapper.selectById(request.getTargetFamilyId());
|
|
|
|
|
- if (family == null) {
|
|
|
|
|
- throw new RuntimeException("目标家庭不存在");
|
|
|
|
|
- }
|
|
|
|
|
- User admin = userMapper.selectById(adminUserId);
|
|
|
|
|
- if (admin == null || !admin.getFamilyId().equals(family.getId())
|
|
|
|
|
- || !Boolean.TRUE.equals(admin.getIsFamilyAdmin())) {
|
|
|
|
|
- throw new RuntimeException("只有家庭管理员才能审批");
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // 验证审批人权限(邀请人,或旧数据兜底的家庭管理员)
|
|
|
|
|
+ checkApprovePermission(request, approverUserId);
|
|
|
|
|
|
|
|
request.setStatus("rejected");
|
|
request.setStatus("rejected");
|
|
|
- request.setApproverUserId(adminUserId);
|
|
|
|
|
|
|
+ request.setApproverUserId(approverUserId);
|
|
|
request.setComment(comment);
|
|
request.setComment(comment);
|
|
|
request.setUpdatedAt(new Date());
|
|
request.setUpdatedAt(new Date());
|
|
|
familyJoinRequestMapper.updateById(request);
|
|
familyJoinRequestMapper.updateById(request);
|
|
|
|
|
|
|
|
- log.info("已拒绝加入请求: requestId={}, userId={}, adminId={}, comment={}",
|
|
|
|
|
- requestId, request.getRequesterUserId(), adminUserId, comment);
|
|
|
|
|
|
|
+ log.info("已拒绝加入请求: requestId={}, userId={}, approverId={}, comment={}",
|
|
|
|
|
+ requestId, request.getRequesterUserId(), approverUserId, comment);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 查询家庭待审批请求列表
|
|
|
|
|
|
|
+ * 查询待我处理的加入申请列表:
|
|
|
|
|
+ * 新数据按邀请人查询(谁分享的卡,申请出现在谁的列表);
|
|
|
|
|
+ * 旧数据未绑定邀请人的,由目标家庭管理员兜底可见。
|
|
|
*/
|
|
*/
|
|
|
- public List<FamilyJoinRequestDTO> getPendingRequests(Long familyId) {
|
|
|
|
|
- List<FamilyJoinRequest> requests = familyJoinRequestMapper.selectList(
|
|
|
|
|
- new LambdaQueryWrapper<FamilyJoinRequest>()
|
|
|
|
|
- .eq(FamilyJoinRequest::getTargetFamilyId, familyId)
|
|
|
|
|
- .eq(FamilyJoinRequest::getStatus, "pending")
|
|
|
|
|
- .orderByDesc(FamilyJoinRequest::getCreatedAt)
|
|
|
|
|
- );
|
|
|
|
|
|
|
+ public List<FamilyJoinRequestDTO> getPendingRequests(Long viewerUserId) {
|
|
|
|
|
+ User viewer = userMapper.selectById(viewerUserId);
|
|
|
|
|
+ if (viewer == null) {
|
|
|
|
|
+ throw new RuntimeException("用户不存在");
|
|
|
|
|
+ }
|
|
|
|
|
+ boolean adminFallback = Boolean.TRUE.equals(viewer.getIsFamilyAdmin()) && viewer.getFamilyId() != null;
|
|
|
|
|
+ LambdaQueryWrapper<FamilyJoinRequest> wrapper = new LambdaQueryWrapper<FamilyJoinRequest>()
|
|
|
|
|
+ .eq(FamilyJoinRequest::getStatus, "pending")
|
|
|
|
|
+ .and(w -> {
|
|
|
|
|
+ w.eq(FamilyJoinRequest::getInviterUserId, viewerUserId);
|
|
|
|
|
+ if (adminFallback) {
|
|
|
|
|
+ w.or(o -> o.isNull(FamilyJoinRequest::getInviterUserId)
|
|
|
|
|
+ .eq(FamilyJoinRequest::getTargetFamilyId, viewer.getFamilyId()));
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ .orderByDesc(FamilyJoinRequest::getCreatedAt);
|
|
|
|
|
+ List<FamilyJoinRequest> requests = familyJoinRequestMapper.selectList(wrapper);
|
|
|
|
|
|
|
|
return requests.stream().map(req -> {
|
|
return requests.stream().map(req -> {
|
|
|
User user = userMapper.selectById(req.getRequesterUserId());
|
|
User user = userMapper.selectById(req.getRequesterUserId());
|
|
@@ -217,6 +234,8 @@ public class FamilyJoinRequestService {
|
|
|
dto.setId(req.getId());
|
|
dto.setId(req.getId());
|
|
|
dto.setRequesterUserId(req.getRequesterUserId());
|
|
dto.setRequesterUserId(req.getRequesterUserId());
|
|
|
dto.setRequesterNickname(user != null ? user.getNickname() : "未知用户");
|
|
dto.setRequesterNickname(user != null ? user.getNickname() : "未知用户");
|
|
|
|
|
+ dto.setRequesterAvatar(user != null ? user.getAvatar() : "");
|
|
|
|
|
+ dto.setInviterUserId(req.getInviterUserId());
|
|
|
dto.setInviteCode(req.getInviteRef());
|
|
dto.setInviteCode(req.getInviteRef());
|
|
|
dto.setTargetFamilyId(req.getTargetFamilyId());
|
|
dto.setTargetFamilyId(req.getTargetFamilyId());
|
|
|
Family family = familyMapper.selectById(req.getTargetFamilyId());
|
|
Family family = familyMapper.selectById(req.getTargetFamilyId());
|
|
@@ -273,4 +292,33 @@ public class FamilyJoinRequestService {
|
|
|
req.setUpdatedAt(new Date());
|
|
req.setUpdatedAt(new Date());
|
|
|
familyJoinRequestMapper.updateById(req);
|
|
familyJoinRequestMapper.updateById(req);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 校验审批人权限:
|
|
|
|
|
+ * 申请绑定邀请人的 → 仅该邀请人(且仍为目标家庭成员)可处理;
|
|
|
|
|
+ * 未绑定邀请人的旧数据 → 回退为原家庭管理员规则。
|
|
|
|
|
+ */
|
|
|
|
|
+ private void checkApprovePermission(FamilyJoinRequest request, Long approverUserId) {
|
|
|
|
|
+ User approver = userMapper.selectById(approverUserId);
|
|
|
|
|
+ if (approver == null) {
|
|
|
|
|
+ throw new RuntimeException("用户不存在");
|
|
|
|
|
+ }
|
|
|
|
|
+ Family family = familyMapper.selectById(request.getTargetFamilyId());
|
|
|
|
|
+ if (family == null) {
|
|
|
|
|
+ throw new RuntimeException("目标家庭不存在");
|
|
|
|
|
+ }
|
|
|
|
|
+ boolean isMember = approver.getFamilyId() != null && approver.getFamilyId().equals(request.getTargetFamilyId());
|
|
|
|
|
+ boolean allowed;
|
|
|
|
|
+ if (request.getInviterUserId() != null) {
|
|
|
|
|
+ allowed = request.getInviterUserId().equals(approverUserId) && isMember;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 旧数据兼容:未绑定邀请人时按原家庭管理员规则
|
|
|
|
|
+ allowed = isMember && Boolean.TRUE.equals(approver.getIsFamilyAdmin());
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!allowed) {
|
|
|
|
|
+ throw new RuntimeException(request.getInviterUserId() != null
|
|
|
|
|
+ ? "只有邀请人才能处理该申请"
|
|
|
|
|
+ : "只有家庭管理员才能审批");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|