家族申请消息功能完善

This commit is contained in:
tianfeng 2025-12-23 11:30:32 +08:00
parent db2550840e
commit e9df22f1a1
10 changed files with 147 additions and 41 deletions

View File

@ -247,6 +247,11 @@ public enum OfficialNoticeTypeEnum {
*/
USER_SPECIAL_AUDIT_RESULTS,
/**
* 家族申请审批
*/
FAMILY_APPLY_APPROVAL,
;

View File

@ -71,6 +71,8 @@ public enum FamilyErrorCode implements IResponseErrorCode {
*/
UP_TO_THREE_RULES(2511, "Three rules at most"),
NOT_PERMISSION_VIEW(2512, "You do not have permission to view"),
;

View File

@ -0,0 +1,35 @@
package com.red.circle.other.inner.enums;
import lombok.Getter;
/**
* 家族消息状态枚举.
*/
@Getter
public enum FamilyMessageStatusEnum {
PENDING(0, "待审核"),
APPROVED(1, "已通过"),
REJECTED(2, "已驳回"),
CANCELLED(-1, "已取消");
private final Integer code;
private final String description;
FamilyMessageStatusEnum(Integer code, String description) {
this.code = code;
this.description = description;
}
public static FamilyMessageStatusEnum of(Integer code) {
if (code == null) {
return null;
}
for (FamilyMessageStatusEnum status : values()) {
if (status.code.equals(code)) {
return status;
}
}
return null;
}
}

View File

@ -18,6 +18,7 @@ import com.red.circle.other.infra.database.rds.service.family.FamilyMessageServi
import com.red.circle.other.infra.enums.family.FamilyMsgTypeEnum;
import com.red.circle.other.inner.asserts.DynamicErrorCode;
import com.red.circle.other.inner.asserts.FamilyErrorCode;
import com.red.circle.other.inner.enums.FamilyMessageStatusEnum;
import com.red.circle.other.inner.model.dto.famliy.FamilyDetailsDTO;
import java.util.Map;
@ -69,7 +70,7 @@ public class ApplyJoinFamilyExe {
.setFamilyId(cmd.getFamilyId())
.setSenderUser(cmd.getReqUserId())
.setSysOrigin(cmd.getReqSysOrigin().getOrigin())
.setStatus(Boolean.FALSE)
.setStatus(FamilyMessageStatusEnum.PENDING.getCode())
.setContent(FamilyMsgTypeEnum.JOIN_FAMILY.getDescription())
.setType(FamilyMsgTypeEnum.JOIN_FAMILY.name())
);

View File

@ -1,9 +1,15 @@
package com.red.circle.other.app.command.family;
import com.red.circle.external.inner.endpoint.message.ImMessageClient;
import com.red.circle.external.inner.endpoint.message.OfficialNoticeClient;
import com.red.circle.external.inner.model.cmd.message.notice.official.NoticeExtTemplateCustomizeCmd;
import com.red.circle.external.inner.model.enums.message.OfficialNoticeTypeEnum;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.core.response.CommonErrorCode;
import com.red.circle.other.app.dto.cmd.family.FamilyMessageHandleCmd;
import com.red.circle.other.domain.model.user.UserProfile;
import com.red.circle.other.domain.propcoupon.PropCoupon;
import com.red.circle.other.domain.propcoupon.PropCouponType;
import com.red.circle.other.infra.common.family.FamilyCommon;
import com.red.circle.other.infra.database.rds.entity.family.FamilyMemberInfo;
import com.red.circle.other.infra.database.rds.entity.family.FamilyMessage;
@ -12,6 +18,7 @@ import com.red.circle.other.infra.database.rds.service.family.FamilyMessageServi
import com.red.circle.other.infra.enums.family.FamilyMsgBusinessEnum;
import com.red.circle.other.infra.enums.family.FamilyRoleEnum;
import com.red.circle.other.inner.asserts.FamilyErrorCode;
import com.red.circle.other.inner.enums.FamilyMessageStatusEnum;
import com.red.circle.other.inner.model.dto.famliy.FamilyDetailsDTO;
import com.red.circle.tool.core.sequence.IdWorkerUtils;
import com.red.circle.tool.core.text.StringUtils;
@ -33,7 +40,7 @@ import org.springframework.stereotype.Component;
public class FamilyMessageHandleExe {
private final FamilyCommon familyCommon;
private final ImMessageClient imMessageClient;
private final OfficialNoticeClient officialNoticeClient;
private final FamilyMessageService familyMessageService;
private final FamilyMemberInfoService familyMemberInfoService;
@ -45,47 +52,61 @@ public class FamilyMessageHandleExe {
FamilyMessage msg = getMessage(cmd, approved);
updateMsg(cmd, msg);
FamilyDetailsDTO levelConfig = getFamilyLevel(approved);
if (isNotJoinFamily(cmd, approved, msg, levelConfig)) {
FamilyMemberInfo existingMember = getFamilyMemberByUserId(msg.getSenderUser());
if (Objects.nonNull(existingMember)) {
familyMessageService.cancelMessageIfUserJoined(msg.getId(), msg.getSenderUser());
return;
}
userJoinFamily(cmd, msg, levelConfig);
sendMsg(approved.getMemberUserId(), msg.getSenderUser(), "Welcome to join the big family");
boolean isAgree = Objects.equals(FamilyMsgBusinessEnum.AGREE.name(), cmd.getEvent());
boolean isRefuse = Objects.equals(FamilyMsgBusinessEnum.REFUSE.name(), cmd.getEvent());
}
private boolean isNotJoinFamily(FamilyMessageHandleCmd cmd, FamilyMemberInfo approved,
FamilyMessage msg, FamilyDetailsDTO levelConfig) {
if (Objects.nonNull(getFamilyMemberByUserId(msg.getSenderUser()))) {
sendMsg(approved.getMemberUserId(), msg.getSenderUser(),
FamilyErrorCode.THERE_ARE_FAMILIES_ERROR.getMessage());
return true;
if (isRefuse) {
updateMsg(cmd, msg, FamilyMessageStatusEnum.REJECTED);
sendNotification(msg.getSenderUser(), false);
return;
}
if (Objects.equals(FamilyMsgBusinessEnum.valueOf(cmd.getEvent()).name(),
FamilyMsgBusinessEnum.REFUSE.name())) {
sendMsg(approved.getMemberUserId(), msg.getSenderUser(),
FamilyErrorCode.FAMILY_REFUSE_JOIN.getMessage());
return true;
if (!isAgree) {
return;
}
FamilyDetailsDTO levelConfig = getFamilyLevel(approved);
Integer familyCurrentMemberCount = getMemberCount(levelConfig);
if (familyCurrentMemberCount >= levelConfig.getMaxMember()) {
ResponseAssert.failure(FamilyErrorCode.FAMILY_MEMBER_MAX);
return true;
return;
}
return false;
updateMsg(cmd, msg, FamilyMessageStatusEnum.APPROVED);
userJoinFamily(cmd, msg, levelConfig);
//取消其他申请记录
familyMessageService.cancelUserPendingMessages(msg.getSenderUser());
sendNotification(msg.getSenderUser(), true);
}
private void sendMsg(Long fromAccount, Long toAccount, String text) {
imMessageClient.sendMessageText(fromAccount, toAccount, text);
/**
* 发送通过和拒绝通知
*/
private void sendNotification(Long userId, boolean agree) {
String content = "Your family application has been approved";
if (!agree) {
content = "Your family application has been rejected";
}
officialNoticeClient.send(
NoticeExtTemplateCustomizeCmd.builder()
.toAccount(userId)
.noticeType(OfficialNoticeTypeEnum.FAMILY_APPLY_APPROVAL)
.content(content)
.build()
);
}
private void userJoinFamily(FamilyMessageHandleCmd cmd, FamilyMessage msg,
@ -130,9 +151,9 @@ public class FamilyMessageHandleExe {
.getFamilyDetails(familyApproved.getSysOrigin(), familyApproved.getFamilyId());
}
private void updateMsg(FamilyMessageHandleCmd cmd, FamilyMessage msg) {
private void updateMsg(FamilyMessageHandleCmd cmd, FamilyMessage msg, FamilyMessageStatusEnum status) {
msg.setApproveUser(cmd.getReqUserId());
msg.setStatus(Boolean.TRUE);
msg.setStatus(status.getCode());
msg.setBusinessEvent(cmd.getEvent());
msg.setUpdateUser(cmd.getReqUserId());
familyMessageService.updateSelectiveById(msg);
@ -144,7 +165,8 @@ public class FamilyMessageHandleExe {
ResponseAssert.notNull(CommonErrorCode.NOT_FOUND_RECORD_INFO, msg);
ResponseAssert.isFalse(CommonErrorCode.MSG_REPEAT_PROCESSING, msg.getStatus());
ResponseAssert.isTrue(CommonErrorCode.MSG_REPEAT_PROCESSING,
Objects.equals(msg.getStatus(), FamilyMessageStatusEnum.PENDING.getCode()));
ResponseAssert.isTrue(FamilyErrorCode.NOT_EXIST_FAMILY_INFO_DATA,
Objects.equals(msg.getFamilyId(), familyMemberInfo.getFamilyId()));

View File

@ -1,6 +1,7 @@
package com.red.circle.other.app.command.family;
import com.google.common.collect.Lists;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.core.dto.CommonCommand;
import com.red.circle.other.app.convertor.user.UserProfileAppConvertor;
import com.red.circle.other.app.dto.clientobject.family.FamilyMsgListCO;
@ -12,13 +13,13 @@ import com.red.circle.other.infra.database.rds.entity.family.FamilyMemberInfo;
import com.red.circle.other.infra.database.rds.entity.family.FamilyMessage;
import com.red.circle.other.infra.database.rds.service.family.FamilyMemberInfoService;
import com.red.circle.other.infra.database.rds.service.family.FamilyMessageService;
import com.red.circle.other.inner.asserts.FamilyErrorCode;
import com.red.circle.other.inner.model.dto.user.OwnSpecialIdDTO;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.TimestampUtils;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
@ -47,9 +48,8 @@ public class FamilyMessageListExe {
FamilyMemberInfo familyMemberInfo = getFamilyMemberByUserId(cmd);
if (!checkRole(familyMemberInfo)) {
return Lists.newArrayList();
}
ResponseAssert.isTrue(FamilyErrorCode.NOT_PERMISSION_VIEW, checkRole(familyMemberInfo));
List<FamilyMessage> msgList = getMsgList(cmd, familyMemberInfo);
if (CollectionUtils.isEmpty(msgList)) {
@ -68,6 +68,8 @@ public class FamilyMessageListExe {
.setFamilyUser(
new FamilyUserCO()
.setId(baseInfo.getId())
.setAccount(baseInfo.getAccount())
.setSpecialAccount(Optional.ofNullable(baseInfo.getOwnSpecialId()).map(OwnSpecialIdDTO::getAccount).orElse(null))
.setUserNickname(baseInfo.getUserNickname())
.setUserAvatar(baseInfo.getUserAvatar())
)

View File

@ -30,6 +30,16 @@ public class FamilyUserCO extends ClientObject {
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/**
* 账号
*/
private String account;
/**
* 靓号
*/
private String specialAccount;
/**
* 用户头像.
*/

View File

@ -80,9 +80,9 @@ public class FamilyMessage extends TimestampBaseEntity {
private String businessEvent;
/**
* 状态(0.未处理 1.已处理).
* 状态(0.待审核 1.已通过 2.已驳回 -1.已取消).
*/
@TableField("status")
private Boolean status;
private Integer status;
}

View File

@ -22,4 +22,8 @@ public interface FamilyMessageService extends BaseService<FamilyMessage> {
void deleteByFamilyId(Long familyId);
void deleteByFamilyIdByUserId(Long familyId, Long memberUserId);
void cancelUserPendingMessages(Long userId);
void cancelMessageIfUserJoined(Long messageId, Long userId);
}

View File

@ -6,6 +6,7 @@ import com.red.circle.framework.mybatis.service.impl.BaseServiceImpl;
import com.red.circle.other.infra.database.rds.dao.family.FamilyMessageDAO;
import com.red.circle.other.infra.database.rds.entity.family.FamilyMessage;
import com.red.circle.other.infra.database.rds.service.family.FamilyMessageService;
import com.red.circle.other.inner.enums.FamilyMessageStatusEnum;
import com.red.circle.tool.core.collection.CollectionUtils;
import java.util.List;
import java.util.Objects;
@ -28,7 +29,7 @@ public class FamilyMessageServiceImpl extends
public List<FamilyMessage> listUntreatedById(Long familyId, Long lastId) {
return Optional.ofNullable(query()
.eq(FamilyMessage::getFamilyId, familyId)
.eq(FamilyMessage::getStatus, Boolean.FALSE)
.eq(FamilyMessage::getStatus, FamilyMessageStatusEnum.PENDING.getCode())
.lt(Objects.nonNull(lastId), FamilyMessage::getId, lastId)
.orderByDesc(FamilyMessage::getId)
.last(PageConstant.DEFAULT_LIMIT)
@ -40,7 +41,7 @@ public class FamilyMessageServiceImpl extends
return Objects.nonNull(query()
.eq(FamilyMessage::getFamilyId, familyId)
.eq(FamilyMessage::getSenderUser, userId)
.eq(FamilyMessage::getStatus, Boolean.FALSE)
.eq(FamilyMessage::getStatus, FamilyMessageStatusEnum.PENDING.getCode())
.getOne());
}
@ -63,4 +64,28 @@ public class FamilyMessageServiceImpl extends
.eq(FamilyMessage::getApproveUser, userId)
.execute();
}
@Override
public void cancelUserPendingMessages(Long userId) {
if (Objects.isNull(userId)) {
return;
}
update()
.set(FamilyMessage::getStatus, FamilyMessageStatusEnum.CANCELLED.getCode())
.eq(FamilyMessage::getSenderUser, userId)
.eq(FamilyMessage::getStatus, FamilyMessageStatusEnum.PENDING.getCode())
.execute();
}
@Override
public void cancelMessageIfUserJoined(Long messageId, Long userId) {
if (Objects.isNull(messageId) || Objects.isNull(userId)) {
return;
}
update()
.set(FamilyMessage::getStatus, FamilyMessageStatusEnum.CANCELLED.getCode())
.eq(FamilyMessage::getId, messageId)
.eq(FamilyMessage::getSenderUser, userId)
.execute();
}
}