新增家族动态功能
This commit is contained in:
parent
3b97886fab
commit
5563f3efbc
@ -158,6 +158,14 @@ public class FamilyRestController extends BaseController {
|
||||
return familyService.familyHomeList(cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* 家族动态列表
|
||||
*/
|
||||
@GetMapping("/news/list")
|
||||
public PageResult<FamilyNewsCO> familyNewsList(FamilyNewsListCmd cmd) {
|
||||
return familyService.familyNewsList(cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* 家族在线房间.
|
||||
*
|
||||
|
||||
@ -3,12 +3,18 @@ package com.red.circle.other.app.command.family;
|
||||
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.FamilyGrantUserRoleCmd;
|
||||
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
|
||||
import com.red.circle.other.domain.model.user.UserProfile;
|
||||
import com.red.circle.other.infra.common.family.FamilyCommon;
|
||||
import com.red.circle.other.infra.common.family.FamilyNewsRecorder;
|
||||
import com.red.circle.other.infra.database.rds.entity.family.FamilyMemberInfo;
|
||||
import com.red.circle.other.infra.database.rds.service.family.FamilyMemberInfoService;
|
||||
import com.red.circle.other.infra.enums.family.FamilyNewsTypeEnum;
|
||||
import com.red.circle.other.infra.enums.family.FamilyRoleEnum;
|
||||
import com.red.circle.other.inner.asserts.FamilyErrorCode;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@ -20,6 +26,8 @@ import org.springframework.stereotype.Component;
|
||||
public class FamilyGrantUserRoleExe {
|
||||
|
||||
private final FamilyCommon familyCommon;
|
||||
private final FamilyNewsRecorder familyNewsRecorder;
|
||||
private final UserProfileGateway userProfileGateway;
|
||||
private final FamilyMemberInfoService familyMemberInfoService;
|
||||
|
||||
public void execute(FamilyGrantUserRoleCmd cmd) {
|
||||
@ -39,7 +47,37 @@ public class FamilyGrantUserRoleExe {
|
||||
|
||||
validateBusinessRules(cmd, operator);
|
||||
|
||||
String oldRole = target.getMemberRole();
|
||||
familyMemberInfoService.updateRoleById(cmd.getAuthorizedMemberId(), cmd.getRoleKey());
|
||||
|
||||
UserProfile userProfile = userProfileGateway.getByUserId(target.getMemberUserId());
|
||||
String targetNickname = Optional.ofNullable(userProfile).map(UserProfile::getUserNickname).orElse(null);
|
||||
|
||||
FamilyNewsTypeEnum newsType = determineNewsType(oldRole, cmd.getRoleKey());
|
||||
if (newsType != null) {
|
||||
familyNewsRecorder.recordAndUpdateNotice(
|
||||
cmd.getReqSysOrigin().getOrigin(),
|
||||
operator.getFamilyId(),
|
||||
newsType,
|
||||
operator.getMemberUserId(),
|
||||
null,
|
||||
target.getMemberUserId(),
|
||||
targetNickname
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据旧角色和新角色确定动态类型
|
||||
*/
|
||||
private FamilyNewsTypeEnum determineNewsType(String oldRole, String newRole) {
|
||||
if (FamilyRoleEnum.MEMBER.getKey().equals(oldRole) && FamilyRoleEnum.MANAGE.getKey().equals(newRole)) {
|
||||
return FamilyNewsTypeEnum.MEMBER_PROMOTED_ADMIN;
|
||||
}
|
||||
if (FamilyRoleEnum.MANAGE.getKey().equals(oldRole) && FamilyRoleEnum.MEMBER.getKey().equals(newRole)) {
|
||||
return FamilyNewsTypeEnum.MEMBER_DEMOTED;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -8,11 +8,13 @@ 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.FamilyInfoEditCmd;
|
||||
import com.red.circle.other.infra.common.family.FamilyCommon;
|
||||
import com.red.circle.other.infra.common.family.FamilyNewsRecorder;
|
||||
import com.red.circle.other.infra.database.rds.entity.family.FamilyBaseInfo;
|
||||
import com.red.circle.other.infra.database.rds.entity.family.FamilyMemberInfo;
|
||||
import com.red.circle.other.infra.database.rds.service.approval.ApprovalUserSettingDataService;
|
||||
import com.red.circle.other.infra.database.rds.service.family.FamilyBaseInfoService;
|
||||
import com.red.circle.other.infra.database.rds.service.family.FamilyMemberInfoService;
|
||||
import com.red.circle.other.infra.enums.family.FamilyNewsTypeEnum;
|
||||
import com.red.circle.other.inner.asserts.DynamicErrorCode;
|
||||
import com.red.circle.other.inner.asserts.FamilyErrorCode;
|
||||
import com.red.circle.tool.core.text.StringUtils;
|
||||
@ -32,6 +34,7 @@ import org.springframework.stereotype.Component;
|
||||
public class FamilyInfoEditExe {
|
||||
|
||||
private final FamilyCommon familyCommon;
|
||||
private final FamilyNewsRecorder familyNewsRecorder;
|
||||
private final OssServiceClient ossServiceClient;
|
||||
private final FamilyBaseInfoService familyBaseInfoService;
|
||||
private final FamilyMemberInfoService familyMemberInfoService;
|
||||
@ -60,8 +63,22 @@ public class FamilyInfoEditExe {
|
||||
FamilyBaseInfo baseInfo = familyBaseInfoService.getBaseInfoById(manageMember.getFamilyId());
|
||||
ResponseAssert.notNull(FamilyErrorCode.NOT_EXIST_FAMILY_INFO_DATA, baseInfo);
|
||||
|
||||
boolean noticeChanged = StringUtils.isNotBlank(cmd.getFamilyNotice());
|
||||
familyBaseInfoService.updateSelectiveById(getFamilyBaseInfo(cmd, manageMember.getFamilyId()));
|
||||
|
||||
FamilyNewsTypeEnum newsType = noticeChanged
|
||||
? FamilyNewsTypeEnum.FAMILY_NOTICE_EDIT
|
||||
: FamilyNewsTypeEnum.FAMILY_INFO_EDIT;
|
||||
|
||||
familyNewsRecorder.recordAndUpdateNotice(
|
||||
cmd.getReqSysOrigin().getOrigin(),
|
||||
manageMember.getFamilyId(),
|
||||
newsType,
|
||||
manageMember.getMemberUserId(),
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
private FamilyBaseInfo getFamilyBaseInfo(FamilyInfoEditCmd cmd, Long familyId) {
|
||||
|
||||
@ -7,15 +7,18 @@ 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.gateway.user.UserProfileGateway;
|
||||
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.common.family.FamilyNewsRecorder;
|
||||
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.infra.enums.family.FamilyMsgBusinessEnum;
|
||||
import com.red.circle.other.infra.enums.family.FamilyNewsTypeEnum;
|
||||
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;
|
||||
@ -41,6 +44,8 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
public class FamilyMessageHandleExe {
|
||||
|
||||
private final FamilyCommon familyCommon;
|
||||
private final FamilyNewsRecorder familyNewsRecorder;
|
||||
private final UserProfileGateway userProfileGateway;
|
||||
private final OfficialNoticeClient officialNoticeClient;
|
||||
private final FamilyMessageService familyMessageService;
|
||||
private final FamilyMemberInfoService familyMemberInfoService;
|
||||
@ -150,6 +155,19 @@ public class FamilyMessageHandleExe {
|
||||
.setMemberUserId(userId)
|
||||
.setMemberRole(FamilyRoleEnum.MEMBER.name())
|
||||
);
|
||||
|
||||
UserProfile userProfile = userProfileGateway.getByUserId(userId);
|
||||
String userNickname = Optional.ofNullable(userProfile).map(UserProfile::getUserNickname).orElse(null);
|
||||
|
||||
familyNewsRecorder.recordAndUpdateNotice(
|
||||
sysOrigin,
|
||||
familyId,
|
||||
FamilyNewsTypeEnum.MEMBER_JOIN,
|
||||
null,
|
||||
null,
|
||||
userId,
|
||||
userNickname
|
||||
);
|
||||
// familyCommon.addGroup(familyId, userId);
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,69 @@
|
||||
package com.red.circle.other.app.command.family;
|
||||
|
||||
import com.red.circle.framework.dto.PageResult;
|
||||
import com.red.circle.other.app.dto.clientobject.family.FamilyNewsCO;
|
||||
import com.red.circle.other.app.dto.cmd.family.FamilyNewsListCmd;
|
||||
import com.red.circle.other.infra.database.rds.entity.family.FamilyMemberInfo;
|
||||
import com.red.circle.other.infra.database.rds.entity.family.FamilyNews;
|
||||
import com.red.circle.other.infra.database.rds.service.family.FamilyMemberInfoService;
|
||||
import com.red.circle.other.infra.database.rds.service.family.FamilyNewsService;
|
||||
import com.red.circle.tool.core.collection.CollectionUtils;
|
||||
import com.red.circle.tool.core.date.TimestampUtils;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 家族动态列表查询
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class FamilyNewsListExe {
|
||||
|
||||
private final FamilyNewsService familyNewsService;
|
||||
|
||||
public PageResult<FamilyNewsCO> execute(FamilyNewsListCmd cmd) {
|
||||
List<FamilyNews> newsList = familyNewsService.listByFamilyId(
|
||||
cmd.getFamilyId(),
|
||||
100
|
||||
);
|
||||
|
||||
if (CollectionUtils.isEmpty(newsList)) {
|
||||
return PageResult.newPageResult(0);
|
||||
}
|
||||
|
||||
int pageNo = cmd.getCursor();
|
||||
int pageSize = cmd.getLimit();
|
||||
int fromIndex = (pageNo - 1) * pageSize;
|
||||
int toIndex = Math.min(fromIndex + pageSize, newsList.size());
|
||||
|
||||
PageResult<FamilyNewsCO> pageResult = PageResult.newPageResult(fromIndex, toIndex, newsList.size());
|
||||
|
||||
if (fromIndex >= newsList.size()) {
|
||||
return pageResult;
|
||||
}
|
||||
|
||||
List<FamilyNewsCO> resultList = newsList.subList(fromIndex, toIndex).stream()
|
||||
.map(this::convertToCO)
|
||||
.toList();
|
||||
|
||||
pageResult.setRecords(resultList);
|
||||
return pageResult;
|
||||
}
|
||||
|
||||
private FamilyNewsCO convertToCO(FamilyNews news) {
|
||||
return new FamilyNewsCO()
|
||||
.setId(news.getId())
|
||||
.setNewsType(news.getNewsType())
|
||||
.setOperatorId(news.getOperatorId())
|
||||
.setOperatorName(news.getOperatorName())
|
||||
.setTargetUserId(news.getTargetUserId())
|
||||
.setTargetUserName(news.getTargetUserName())
|
||||
.setContent(news.getContent())
|
||||
.setCreateTime(news.getCreateTime().toString());
|
||||
}
|
||||
}
|
||||
@ -3,10 +3,15 @@ package com.red.circle.other.app.command.family;
|
||||
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.FamilyRemoveUserCmd;
|
||||
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
|
||||
import com.red.circle.other.domain.model.user.UserProfile;
|
||||
import com.red.circle.other.infra.common.family.FamilyCommon;
|
||||
import com.red.circle.other.infra.common.family.FamilyNewsRecorder;
|
||||
import com.red.circle.other.infra.database.rds.entity.family.FamilyMemberInfo;
|
||||
import com.red.circle.other.infra.database.rds.service.family.FamilyMemberInfoService;
|
||||
import com.red.circle.other.infra.enums.family.FamilyNewsTypeEnum;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.red.circle.other.inner.asserts.FamilyErrorCode;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@ -27,6 +32,8 @@ import org.springframework.stereotype.Component;
|
||||
public class FamilyRemoveUserExe {
|
||||
|
||||
private final FamilyCommon familyCommon;
|
||||
private final FamilyNewsRecorder familyNewsRecorder;
|
||||
private final UserProfileGateway userProfileGateway;
|
||||
private final FamilyMemberInfoService familyMemberInfoService;
|
||||
|
||||
public void execute(FamilyRemoveUserCmd cmd) {
|
||||
@ -44,12 +51,12 @@ public class FamilyRemoveUserExe {
|
||||
Objects.equals(member.getMemberUserId(), manageMember.getMemberUserId()));
|
||||
|
||||
if (isAdmin(manageMember)) {
|
||||
familyCommon.removeFamilyUser(member);
|
||||
removeUserAndRecordNews(member, manageMember, cmd, FamilyNewsTypeEnum.MEMBER_KICKED_ADMIN);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isAllowUpdate(manageMember, member)) {
|
||||
familyCommon.removeFamilyUser(member);
|
||||
removeUserAndRecordNews(member, manageMember, cmd, FamilyNewsTypeEnum.MEMBER_KICKED_MANAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -57,6 +64,24 @@ public class FamilyRemoveUserExe {
|
||||
|
||||
}
|
||||
|
||||
private void removeUserAndRecordNews(FamilyMemberInfo member, FamilyMemberInfo operator, FamilyRemoveUserCmd cmd,
|
||||
FamilyNewsTypeEnum newsType) {
|
||||
UserProfile userProfile = userProfileGateway.getByUserId(member.getMemberUserId());
|
||||
String targetNickname = Optional.ofNullable(userProfile).map(UserProfile::getUserNickname).orElse(null);
|
||||
|
||||
familyCommon.removeFamilyUser(member);
|
||||
|
||||
familyNewsRecorder.recordAndUpdateNotice(
|
||||
cmd.getReqSysOrigin().getOrigin(),
|
||||
operator.getFamilyId(),
|
||||
newsType,
|
||||
operator.getMemberUserId(),
|
||||
null,
|
||||
member.getMemberUserId(),
|
||||
targetNickname
|
||||
);
|
||||
}
|
||||
|
||||
private Boolean getExistFamilyByUserId(FamilyRemoveUserCmd cmd) {
|
||||
return familyCommon.isExistFamilyByUserId(cmd.getReqUserId());
|
||||
}
|
||||
|
||||
@ -2,13 +2,19 @@ package com.red.circle.other.app.command.family;
|
||||
|
||||
import com.red.circle.common.business.dto.cmd.AppExtCommand;
|
||||
import com.red.circle.framework.core.asserts.ResponseAssert;
|
||||
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
|
||||
import com.red.circle.other.domain.model.user.UserProfile;
|
||||
import com.red.circle.other.infra.common.family.FamilyCommon;
|
||||
import com.red.circle.other.infra.common.family.FamilyNewsRecorder;
|
||||
import com.red.circle.other.infra.database.rds.entity.family.FamilyMemberInfo;
|
||||
import com.red.circle.other.infra.database.rds.service.family.FamilyMemberInfoService;
|
||||
import com.red.circle.other.infra.enums.family.FamilyNewsTypeEnum;
|
||||
import com.red.circle.other.inner.asserts.FamilyErrorCode;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户退出所在家族.
|
||||
@ -22,6 +28,8 @@ import org.springframework.stereotype.Component;
|
||||
public class FamilyUserExitExe {
|
||||
|
||||
private final FamilyCommon familyCommon;
|
||||
private final FamilyNewsRecorder familyNewsRecorder;
|
||||
private final UserProfileGateway userProfileGateway;
|
||||
private final FamilyMemberInfoService familyMemberInfoService;
|
||||
|
||||
public void execute(AppExtCommand cmd) {
|
||||
@ -33,8 +41,20 @@ public class FamilyUserExitExe {
|
||||
ResponseAssert.isFalse(FamilyErrorCode.FOUNDER_NOT_ALLOWED_EXIT_FAMILY,
|
||||
isAdmin(familyMemberInfo));
|
||||
|
||||
UserProfile userProfile = userProfileGateway.getByUserId(familyMemberInfo.getMemberUserId());
|
||||
String userNickname = Optional.ofNullable(userProfile).map(UserProfile::getUserNickname).orElse(null);
|
||||
|
||||
familyCommon.removeFamilyUser(familyMemberInfo);
|
||||
|
||||
familyNewsRecorder.recordAndUpdateNotice(
|
||||
cmd.getReqSysOrigin().getOrigin(),
|
||||
familyMemberInfo.getFamilyId(),
|
||||
FamilyNewsTypeEnum.MEMBER_LEFT,
|
||||
null,
|
||||
null,
|
||||
familyMemberInfo.getMemberUserId(),
|
||||
userNickname
|
||||
);
|
||||
}
|
||||
|
||||
private boolean isAdmin(FamilyMemberInfo familyMemberInfo) {
|
||||
|
||||
@ -33,6 +33,7 @@ import com.red.circle.other.app.command.family.FamilyBoxContributeExe;
|
||||
import com.red.circle.other.app.command.family.FamilyBoxClaimExe;
|
||||
import com.red.circle.other.app.command.family.FamilyHomeListExe;
|
||||
import com.red.circle.other.app.command.family.FamilyMemberTop100Exe;
|
||||
import com.red.circle.other.app.command.family.FamilyNewsListExe;
|
||||
import com.red.circle.other.app.dto.clientobject.family.*;
|
||||
import com.red.circle.other.app.dto.clientobject.room.RoomVoiceProfileCO;
|
||||
import com.red.circle.other.app.dto.cmd.family.*;
|
||||
@ -89,6 +90,7 @@ public class FamilyServiceImpl implements FamilyService {
|
||||
private final FamilyBoxClaimExe familyBoxClaimExe;
|
||||
private final FamilyHomeListExe familyHomeListExe;
|
||||
private final FamilyMemberTop100Exe familyMemberTop100Exe;
|
||||
private final FamilyNewsListExe familyNewsListExe;
|
||||
private final DistributedLockUtil distributedLockUtil;
|
||||
|
||||
@Override
|
||||
@ -269,4 +271,9 @@ public class FamilyServiceImpl implements FamilyService {
|
||||
public PageResult<FamilyHomeListCO> familyHomeList(FamilyHomeListCmd cmd) {
|
||||
return familyHomeListExe.execute(cmd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<FamilyNewsCO> familyNewsList(FamilyNewsListCmd cmd) {
|
||||
return familyNewsListExe.execute(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,61 @@
|
||||
package com.red.circle.other.app.dto.clientobject.family;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import java.io.Serializable;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 家族动态CO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class FamilyNewsCO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 动态ID
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 动态类型
|
||||
*/
|
||||
private String newsType;
|
||||
|
||||
/**
|
||||
* 操作人用户ID
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long operatorId;
|
||||
|
||||
/**
|
||||
* 操作人昵称
|
||||
*/
|
||||
private String operatorName;
|
||||
|
||||
/**
|
||||
* 目标用户ID
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long targetUserId;
|
||||
|
||||
/**
|
||||
* 目标用户昵称
|
||||
*/
|
||||
private String targetUserName;
|
||||
|
||||
/**
|
||||
* 动态内容文本
|
||||
*/
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private String createTime;
|
||||
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package com.red.circle.other.app.dto.cmd.family;
|
||||
|
||||
import com.red.circle.common.business.dto.cmd.AppExtCommand;
|
||||
import com.red.circle.framework.dto.PageQuery;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 家族动态列表查询
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class FamilyNewsListCmd extends PageQuery {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Long familyId;
|
||||
|
||||
}
|
||||
@ -175,4 +175,9 @@ public interface FamilyService {
|
||||
* 家族首页列表.
|
||||
*/
|
||||
PageResult<FamilyHomeListCO> familyHomeList(FamilyHomeListCmd cmd);
|
||||
|
||||
/**
|
||||
* 家族动态列表.
|
||||
*/
|
||||
PageResult<FamilyNewsCO> familyNewsList(FamilyNewsListCmd cmd);
|
||||
}
|
||||
|
||||
@ -0,0 +1,71 @@
|
||||
package com.red.circle.other.infra.common.family;
|
||||
|
||||
import com.red.circle.other.infra.database.rds.entity.family.FamilyBaseInfo;
|
||||
import com.red.circle.other.infra.database.rds.entity.family.FamilyNews;
|
||||
import com.red.circle.other.infra.database.rds.service.family.FamilyBaseInfoService;
|
||||
import com.red.circle.other.infra.database.rds.service.family.FamilyNewsService;
|
||||
import com.red.circle.other.infra.enums.family.FamilyNewsTypeEnum;
|
||||
import java.util.Objects;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 家族动态记录通用服务
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class FamilyNewsRecorder {
|
||||
|
||||
private final FamilyNewsService familyNewsService;
|
||||
private final FamilyBaseInfoService familyBaseInfoService;
|
||||
|
||||
/**
|
||||
* 记录家族动态并更新家族公告
|
||||
*/
|
||||
public void recordAndUpdateNotice(
|
||||
String sysOrigin,
|
||||
Long familyId,
|
||||
FamilyNewsTypeEnum newsType,
|
||||
Long operatorId,
|
||||
String operatorName,
|
||||
Long targetUserId,
|
||||
String targetUserName
|
||||
) {
|
||||
familyNewsService.recordNews(
|
||||
sysOrigin,
|
||||
familyId,
|
||||
newsType,
|
||||
operatorId,
|
||||
operatorName,
|
||||
targetUserId,
|
||||
targetUserName
|
||||
);
|
||||
|
||||
updateFamilyNotice(familyId, newsType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新家族公告为最新动态
|
||||
*/
|
||||
private void updateFamilyNotice(Long familyId, FamilyNewsTypeEnum newsType) {
|
||||
try {
|
||||
FamilyNews latestNews = familyNewsService.getLatestNews(familyId);
|
||||
if (Objects.isNull(latestNews)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (newsType == FamilyNewsTypeEnum.FAMILY_INFO_EDIT || newsType == FamilyNewsTypeEnum.FAMILY_NOTICE_EDIT) {
|
||||
return ;
|
||||
}
|
||||
|
||||
familyBaseInfoService.updateSelectiveById(new FamilyBaseInfo()
|
||||
.setId(familyId)
|
||||
.setFamilyNotice(latestNews.getContent())
|
||||
);
|
||||
} catch (Exception e) {
|
||||
log.error("更新家族公告失败, familyId:{}, error:{}", familyId, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package com.red.circle.other.infra.database.rds.dao.family;
|
||||
|
||||
import com.red.circle.framework.mybatis.dao.BaseDAO;
|
||||
import com.red.circle.other.infra.database.rds.entity.family.FamilyNews;
|
||||
|
||||
/**
|
||||
* 家族动态 DAO
|
||||
*/
|
||||
public interface FamilyNewsDAO extends BaseDAO<FamilyNews> {
|
||||
|
||||
}
|
||||
@ -0,0 +1,88 @@
|
||||
package com.red.circle.other.infra.database.rds.entity.family;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.red.circle.framework.mybatis.entity.TimestampBaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 家族动态记录
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
@TableName("family_news")
|
||||
public class FamilyNews {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键标识
|
||||
*/
|
||||
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 来源系统
|
||||
*/
|
||||
@TableField("sys_origin")
|
||||
private String sysOrigin;
|
||||
|
||||
/**
|
||||
* 家族ID
|
||||
*/
|
||||
@TableField("family_id")
|
||||
private Long familyId;
|
||||
|
||||
/**
|
||||
* 动态类型
|
||||
*/
|
||||
@TableField("news_type")
|
||||
private String newsType;
|
||||
|
||||
/**
|
||||
* 操作人用户ID
|
||||
*/
|
||||
@TableField("operator_id")
|
||||
private Long operatorId;
|
||||
|
||||
/**
|
||||
* 操作人昵称
|
||||
*/
|
||||
@TableField("operator_name")
|
||||
private String operatorName;
|
||||
|
||||
/**
|
||||
* 目标用户ID
|
||||
*/
|
||||
@TableField("target_user_id")
|
||||
private Long targetUserId;
|
||||
|
||||
/**
|
||||
* 目标用户昵称
|
||||
*/
|
||||
@TableField("target_user_name")
|
||||
private String targetUserName;
|
||||
|
||||
/**
|
||||
* 动态内容文本
|
||||
*/
|
||||
@TableField("content")
|
||||
private String content;
|
||||
|
||||
/**
|
||||
* 额外数据JSON
|
||||
*/
|
||||
@TableField("extra_data")
|
||||
private String extraData;
|
||||
|
||||
@TableField("create_time")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
package com.red.circle.other.infra.database.rds.service.family;
|
||||
|
||||
import com.red.circle.framework.mybatis.service.BaseService;
|
||||
import com.red.circle.other.infra.database.rds.entity.family.FamilyNews;
|
||||
import com.red.circle.other.infra.enums.family.FamilyNewsTypeEnum;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 家族动态服务
|
||||
*/
|
||||
public interface FamilyNewsService extends BaseService<FamilyNews> {
|
||||
|
||||
/**
|
||||
* 记录家族动态
|
||||
*/
|
||||
void recordNews(
|
||||
String sysOrigin,
|
||||
Long familyId,
|
||||
FamilyNewsTypeEnum newsType,
|
||||
Long operatorId,
|
||||
String operatorName,
|
||||
Long targetUserId,
|
||||
String targetUserName
|
||||
);
|
||||
|
||||
/**
|
||||
* 查询家族动态列表(最新100条)
|
||||
*/
|
||||
List<FamilyNews> listByFamilyId(Long familyId, Integer limit);
|
||||
|
||||
/**
|
||||
* 获取最新一条动态
|
||||
*/
|
||||
FamilyNews getLatestNews(Long familyId);
|
||||
|
||||
/**
|
||||
* 删除家族所有动态
|
||||
*/
|
||||
void deleteByFamilyId(Long familyId);
|
||||
}
|
||||
@ -0,0 +1,117 @@
|
||||
package com.red.circle.other.infra.database.rds.service.family.impl;
|
||||
|
||||
import com.red.circle.framework.mybatis.constant.PageConstant;
|
||||
import com.red.circle.framework.mybatis.service.impl.BaseServiceImpl;
|
||||
import com.red.circle.other.infra.database.rds.dao.family.FamilyNewsDAO;
|
||||
import com.red.circle.other.infra.database.rds.entity.family.FamilyNews;
|
||||
import com.red.circle.other.infra.database.rds.service.family.FamilyNewsService;
|
||||
import com.red.circle.other.infra.enums.family.FamilyNewsTypeEnum;
|
||||
import com.red.circle.tool.core.collection.CollectionUtils;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 家族动态服务实现
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class FamilyNewsServiceImpl extends
|
||||
BaseServiceImpl<FamilyNewsDAO, FamilyNews> implements FamilyNewsService {
|
||||
|
||||
@Override
|
||||
public void recordNews(
|
||||
String sysOrigin,
|
||||
Long familyId,
|
||||
FamilyNewsTypeEnum newsType,
|
||||
Long operatorId,
|
||||
String operatorName,
|
||||
Long targetUserId,
|
||||
String targetUserName
|
||||
) {
|
||||
try {
|
||||
String content = newsType.generateContent(targetUserName);
|
||||
|
||||
FamilyNews news = new FamilyNews()
|
||||
.setSysOrigin(sysOrigin)
|
||||
.setFamilyId(familyId)
|
||||
.setNewsType(newsType.getCode())
|
||||
.setOperatorId(operatorId)
|
||||
.setOperatorName(operatorName)
|
||||
.setTargetUserId(targetUserId)
|
||||
.setTargetUserName(targetUserName)
|
||||
.setContent(content);
|
||||
|
||||
super.save(news);
|
||||
|
||||
cleanOldNews(familyId);
|
||||
} catch (Exception e) {
|
||||
log.error("记录家族动态失败, familyId:{}, newsType:{}, error:{}",
|
||||
familyId, newsType.getCode(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FamilyNews> listByFamilyId(Long familyId, Integer limit) {
|
||||
if (Objects.isNull(familyId)) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
int pageSize = Objects.nonNull(limit) && limit > 0 ? limit : 100;
|
||||
|
||||
return query()
|
||||
.eq(FamilyNews::getFamilyId, familyId)
|
||||
.orderByDesc(FamilyNews::getCreateTime)
|
||||
.last("LIMIT " + pageSize)
|
||||
.list();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FamilyNews getLatestNews(Long familyId) {
|
||||
if (Objects.isNull(familyId)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return query()
|
||||
.eq(FamilyNews::getFamilyId, familyId)
|
||||
.orderByDesc(FamilyNews::getCreateTime)
|
||||
.last(PageConstant.LIMIT_ONE)
|
||||
.getOne();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByFamilyId(Long familyId) {
|
||||
if (Objects.isNull(familyId)) {
|
||||
return;
|
||||
}
|
||||
delete().eq(FamilyNews::getFamilyId, familyId).execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理旧动态,保留最新100条
|
||||
*/
|
||||
private void cleanOldNews(Long familyId) {
|
||||
try {
|
||||
List<FamilyNews> allNews = query()
|
||||
.eq(FamilyNews::getFamilyId, familyId)
|
||||
.orderByDesc(FamilyNews::getCreateTime)
|
||||
.list();
|
||||
|
||||
if (CollectionUtils.isEmpty(allNews) || allNews.size() <= 100) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<Long> idsToDelete = allNews.stream()
|
||||
.skip(100)
|
||||
.map(FamilyNews::getId)
|
||||
.toList();
|
||||
|
||||
if (CollectionUtils.isNotEmpty(idsToDelete)) {
|
||||
delete().in(FamilyNews::getId, idsToDelete).execute();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("清理家族旧动态失败, familyId:{}, error:{}", familyId, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,72 @@
|
||||
package com.red.circle.other.infra.enums.family;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
/**
|
||||
* 家族动态类型枚举
|
||||
*/
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public enum FamilyNewsTypeEnum {
|
||||
|
||||
/**
|
||||
* 成员加入家族
|
||||
*/
|
||||
MEMBER_JOIN("MEMBER_JOIN", "[{targetUserName}] joined the family."),
|
||||
|
||||
/**
|
||||
* 成员被授权为管理员
|
||||
*/
|
||||
MEMBER_PROMOTED_ADMIN("MEMBER_PROMOTED_ADMIN", "[{targetUserName}] become an admin."),
|
||||
|
||||
/**
|
||||
* 成员被取消管理员
|
||||
*/
|
||||
MEMBER_DEMOTED("MEMBER_DEMOTED", "[{targetUserName}] was removed from admin."),
|
||||
|
||||
/**
|
||||
* 成员被族长踢出家族
|
||||
*/
|
||||
MEMBER_KICKED_ADMIN("MEMBER_KICKED", "[{targetUserName}] has been removed from the family by the family owner."),
|
||||
|
||||
/**
|
||||
* 成员被管理员踢出家族
|
||||
*/
|
||||
MEMBER_KICKED_MANAGE("MEMBER_KICKED", "[{targetUserName}] has been removed from the family by the family owner."),
|
||||
|
||||
|
||||
/**
|
||||
* 成员主动退出
|
||||
*/
|
||||
MEMBER_LEFT("MEMBER_LEFT", "[{targetUserName}] has left the family."),
|
||||
|
||||
/**
|
||||
* 家族资料修改
|
||||
*/
|
||||
FAMILY_INFO_EDIT("FAMILY_INFO_EDIT", "Family information has been updated."),
|
||||
|
||||
/**
|
||||
* 家族公告修改
|
||||
*/
|
||||
FAMILY_NOTICE_EDIT("FAMILY_NOTICE_EDIT", "The family announcement has been updated.");
|
||||
|
||||
private final String code;
|
||||
private final String template;
|
||||
|
||||
/**
|
||||
* 生成动态文本
|
||||
*/
|
||||
public String generateContent(String targetUserName) {
|
||||
if (this == FAMILY_INFO_EDIT || this == FAMILY_NOTICE_EDIT) {
|
||||
return template;
|
||||
}
|
||||
|
||||
String displayName = targetUserName;
|
||||
if (targetUserName != null && targetUserName.length() > 12) {
|
||||
displayName = targetUserName.substring(0, 12) + "[...]";
|
||||
}
|
||||
|
||||
return template.replace("{targetUserName}", displayName != null ? displayName : "");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.red.circle.other.infra.database.rds.dao.family.FamilyNewsDAO">
|
||||
|
||||
</mapper>
|
||||
Loading…
x
Reference in New Issue
Block a user