新增cp告白信封功能
This commit is contained in:
parent
6035415969
commit
9319ec228a
@ -252,6 +252,11 @@ public enum OfficialNoticeTypeEnum {
|
||||
*/
|
||||
FAMILY_APPLY_APPROVAL,
|
||||
|
||||
/**
|
||||
* CP告白信封
|
||||
*/
|
||||
CP_LOVE_LETTER,
|
||||
|
||||
;
|
||||
|
||||
|
||||
|
||||
@ -67,6 +67,11 @@ public enum UserRelationErrorCode implements IResponseErrorCode {
|
||||
*/
|
||||
UNAVAILABLE_NOT_REGION(4312, "Unavailable to operate not same region"),
|
||||
|
||||
/**
|
||||
* CP关系不存在.
|
||||
*/
|
||||
CP_RELATIONSHIP_NOT_EXISTS(4313, "CP relationship does not exist"),
|
||||
|
||||
;
|
||||
|
||||
|
||||
|
||||
@ -734,9 +734,14 @@ public enum GoldOrigin {
|
||||
FAMILY_BOX_REWARD("Family box reward"),
|
||||
|
||||
/**
|
||||
* 房间红包
|
||||
* 用户红包
|
||||
*/
|
||||
USER_RED_PACKET("User red packet"),
|
||||
|
||||
/**
|
||||
* CP告白信封
|
||||
*/
|
||||
CP_LOVE_LETTER("CP love letter"),
|
||||
;
|
||||
|
||||
private final String desc;
|
||||
|
||||
@ -2,14 +2,15 @@ package com.red.circle.other.adapter.app.user.relation;
|
||||
|
||||
import com.red.circle.common.business.dto.cmd.AppExtCommand;
|
||||
import com.red.circle.common.business.dto.cmd.UserIdCmd;
|
||||
import com.red.circle.common.business.dto.cmd.UserIdCommonCmd;
|
||||
import com.red.circle.framework.web.controller.BaseController;
|
||||
import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpCabinUserProfileCO;
|
||||
import com.red.circle.other.app.command.user.LoveLetterQueryCmdExe;
|
||||
import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpPairUserProfileCO;
|
||||
import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpUserProfileCO;
|
||||
import com.red.circle.other.domain.model.cp.loveletter.LoveLetterDetailCO;
|
||||
import com.red.circle.other.domain.model.cp.loveletter.LoveLetterWallCO;
|
||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyCmd;
|
||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyDismissCmd;
|
||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.ProcessApplyCmd;
|
||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.loveletter.SendLoveLetterCmd;
|
||||
import com.red.circle.other.app.service.user.relation.UserCpRelationService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.MediaType;
|
||||
@ -39,6 +40,7 @@ import java.util.List;
|
||||
public class CpRelationshipRestController extends BaseController {
|
||||
|
||||
private final UserCpRelationService userCpRelationService;
|
||||
private final LoveLetterQueryCmdExe loveLetterQueryCmdExe;
|
||||
|
||||
/**
|
||||
* 获取我的-cp对象.
|
||||
@ -105,4 +107,43 @@ public class CpRelationshipRestController extends BaseController {
|
||||
return userCpRelationService.getCpApplyId(cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送CP告白信封.
|
||||
*
|
||||
* @eo.name 发送CP告白信封
|
||||
* @eo.url /send-love-letter
|
||||
* @eo.method post
|
||||
* @eo.request-type json
|
||||
*/
|
||||
@PostMapping("/send-love-letter")
|
||||
public void sendLoveLetter(@RequestBody @Validated SendLoveLetterCmd cmd) {
|
||||
userCpRelationService.sendLoveLetter(cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询告白墙.
|
||||
*
|
||||
* @eo.name 查询告白墙
|
||||
* @eo.url /love-letter-wall
|
||||
* @eo.method get
|
||||
* @eo.request-type formdata
|
||||
*/
|
||||
@GetMapping("/love-letter-wall")
|
||||
public List<LoveLetterWallCO> getLoveLetterWall() {
|
||||
return loveLetterQueryCmdExe.queryWall();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询我收到的最新告白信封.
|
||||
*
|
||||
* @eo.name 查询我收到的最新告白信封
|
||||
* @eo.url /latest-love-letter
|
||||
* @eo.method get
|
||||
* @eo.request-type formdata
|
||||
*/
|
||||
@GetMapping("/latest-love-letter")
|
||||
public LoveLetterDetailCO getLatestLoveLetter(AppExtCommand cmd) {
|
||||
return loveLetterQueryCmdExe.queryLatestReceived(cmd);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,99 @@
|
||||
package com.red.circle.other.app.command.user;
|
||||
|
||||
import com.red.circle.common.business.dto.cmd.AppExtCommand;
|
||||
import com.red.circle.other.domain.gateway.user.CpLoveLetterGateway;
|
||||
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
|
||||
import com.red.circle.other.domain.model.cp.CpLoveLetterDomain;
|
||||
import com.red.circle.other.domain.model.cp.loveletter.LoveLetterDetailCO;
|
||||
import com.red.circle.other.domain.model.cp.loveletter.LoveLetterWallCO;
|
||||
import com.red.circle.other.domain.model.user.UserProfile;
|
||||
import com.red.circle.other.infra.convertor.user.CpLoveLetterConvertor;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 查询CP告白信封
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class LoveLetterQueryCmdExe {
|
||||
|
||||
private final CpLoveLetterGateway cpLoveLetterGateway;
|
||||
private final UserProfileGateway userProfileGateway;
|
||||
private final CpLoveLetterConvertor cpLoveLetterConvertor;
|
||||
|
||||
/**
|
||||
* 查询告白墙(最新50条)
|
||||
*/
|
||||
public List<LoveLetterWallCO> queryWall() {
|
||||
List<CpLoveLetterDomain> letters = cpLoveLetterGateway.listLatestLetters(50);
|
||||
if (letters.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
// 批量查询发送者信息
|
||||
Set<Long> senderIds = letters.stream()
|
||||
.map(CpLoveLetterDomain::getSenderId)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// 批量查询发送者信息
|
||||
Set<Long> receiverIds = letters.stream()
|
||||
.map(CpLoveLetterDomain::getReceiverId)
|
||||
.collect(Collectors.toSet());
|
||||
senderIds.addAll(receiverIds);
|
||||
|
||||
Map<Long, UserProfile> userProfileMap = userProfileGateway.listByUserIds(senderIds)
|
||||
.stream()
|
||||
.collect(Collectors.toMap(UserProfile::getId, Function.identity()));
|
||||
|
||||
// 组装返回数据
|
||||
return letters.stream()
|
||||
.map(letter -> {
|
||||
LoveLetterWallCO co = cpLoveLetterConvertor.toWallCO(letter);
|
||||
UserProfile profile = userProfileMap.get(letter.getSenderId());
|
||||
if (Objects.nonNull(profile)) {
|
||||
co.setSenderNickname(profile.getUserNickname());
|
||||
co.setSenderAvatar(profile.getUserAvatar());
|
||||
}
|
||||
UserProfile receiver = userProfileMap.get(letter.getReceiverId());
|
||||
if (Objects.nonNull(receiver)) {
|
||||
co.setReceiverNickname(receiver.getUserNickname());
|
||||
co.setReceiverAvatar(receiver.getUserAvatar());
|
||||
}
|
||||
return co;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询我收到的最新信封
|
||||
*/
|
||||
public LoveLetterDetailCO queryLatestReceived(AppExtCommand cmd) {
|
||||
Long userId = cmd.requiredReqUserId();
|
||||
|
||||
CpLoveLetterDomain letter = cpLoveLetterGateway.getLatestReceivedLetter(userId);
|
||||
if (Objects.isNull(letter)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 标记为已读
|
||||
if (letter.isUnread()) {
|
||||
cpLoveLetterGateway.markAsRead(letter.getId());
|
||||
}
|
||||
|
||||
// 查询发送者信息
|
||||
UserProfile senderProfile = userProfileGateway.getByUserId(letter.getSenderId());
|
||||
|
||||
LoveLetterDetailCO co = cpLoveLetterConvertor.toDetailCO(letter);
|
||||
if (Objects.nonNull(senderProfile)) {
|
||||
co.setSenderNickname(senderProfile.getUserNickname());
|
||||
co.setSenderAvatar(senderProfile.getUserAvatar());
|
||||
}
|
||||
|
||||
return co;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,108 @@
|
||||
package com.red.circle.other.app.command.user;
|
||||
|
||||
import com.red.circle.external.inner.endpoint.message.OfficialNoticeClient;
|
||||
import com.red.circle.external.inner.model.cmd.message.notice.official.NoticeExtTemplateTypeCmd;
|
||||
import com.red.circle.external.inner.model.enums.message.OfficialNoticeTypeEnum;
|
||||
import com.red.circle.framework.core.asserts.ResponseAssert;
|
||||
import com.red.circle.other.app.convertor.user.UserProfileAppConvertor;
|
||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.loveletter.SendLoveLetterCmd;
|
||||
import com.red.circle.other.app.util.OfficialNoticeUtils;
|
||||
import com.red.circle.other.domain.gateway.user.CpLoveLetterGateway;
|
||||
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
|
||||
import com.red.circle.other.domain.model.cp.CpLoveLetterDomain;
|
||||
import com.red.circle.other.infra.database.rds.service.user.user.CpRelationshipService;
|
||||
import com.red.circle.other.inner.asserts.user.UserRelationErrorCode;
|
||||
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
|
||||
import com.red.circle.tool.core.date.TimestampUtils;
|
||||
import com.red.circle.tool.core.tuple.PennyAmount;
|
||||
import com.red.circle.wallet.inner.endpoint.wallet.WalletGoldClient;
|
||||
import com.red.circle.wallet.inner.error.WalletErrorCode;
|
||||
import com.red.circle.wallet.inner.model.cmd.GoldReceiptCmd;
|
||||
import com.red.circle.wallet.inner.model.enums.GoldOrigin;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 发送CP告白信封
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class SendLoveLetterCmdExe {
|
||||
|
||||
private final CpLoveLetterGateway cpLoveLetterGateway;
|
||||
private final CpRelationshipService cpRelationshipService;
|
||||
private final WalletGoldClient walletGoldClient;
|
||||
private final OfficialNoticeClient officialNoticeClient;
|
||||
private final UserProfileGateway userProfileGateway;
|
||||
private final UserProfileAppConvertor userProfileAppConvertor;
|
||||
|
||||
private static final Long LOVE_LETTER_COST = 5000L;
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void execute(SendLoveLetterCmd cmd) {
|
||||
Long senderId = cmd.requiredReqUserId();
|
||||
Long receiverId = cmd.getReceiverId();
|
||||
|
||||
// 校验双方是否已建立CP关系
|
||||
boolean cpExists = cpRelationshipService.existsCp(senderId, receiverId);
|
||||
ResponseAssert.isTrue(UserRelationErrorCode.CP_RELATIONSHIP_NOT_EXISTS, cpExists);
|
||||
|
||||
// 扣除金币
|
||||
deductGold(senderId, cmd);
|
||||
|
||||
// 保存信封
|
||||
CpLoveLetterDomain letter = new CpLoveLetterDomain();
|
||||
letter.setSenderId(senderId);
|
||||
letter.setReceiverId(receiverId);
|
||||
letter.setContent(cmd.getContent());
|
||||
letter.setStatus(0);
|
||||
letter.setCostGold(LOVE_LETTER_COST);
|
||||
letter.setCreateTime(TimestampUtils.now());
|
||||
letter.setUpdateTime(TimestampUtils.now());
|
||||
cpLoveLetterGateway.save(letter);
|
||||
|
||||
// 发送System消息通知
|
||||
sendNotification(senderId, receiverId, cmd.getContent(), letter.getId());
|
||||
}
|
||||
|
||||
private void deductGold(Long userId, SendLoveLetterCmd cmd) {
|
||||
GoldReceiptCmd build = GoldReceiptCmd.builder()
|
||||
.appExpenditure()
|
||||
.userId(userId)
|
||||
.amount(PennyAmount.ofDollar(LOVE_LETTER_COST))
|
||||
.eventId(String.valueOf(userId))
|
||||
.sysOrigin(cmd.getReqSysOrigin().getOrigin())
|
||||
.origin(GoldOrigin.CP_LOVE_LETTER)
|
||||
.build();
|
||||
|
||||
try {
|
||||
walletGoldClient.changeBalance(build);
|
||||
} catch (Exception e) {
|
||||
log.error("扣除金币失败 userId={} cost={}", userId, LOVE_LETTER_COST, e);
|
||||
ResponseAssert.isTrue(WalletErrorCode.INSUFFICIENT_BALANCE, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendNotification(Long senderId, Long receiverId, String content, Long letterId) {
|
||||
UserProfileDTO senderProfile = userProfileAppConvertor.toUserProfileDTO(
|
||||
userProfileGateway.getByUserId(senderId)
|
||||
);
|
||||
|
||||
Map<Object, Object> templateParam = OfficialNoticeUtils.buildUserProfile(senderProfile);
|
||||
templateParam.put("content", content);
|
||||
officialNoticeClient.send(NoticeExtTemplateTypeCmd.builder()
|
||||
.toAccount(receiverId)
|
||||
.noticeType(OfficialNoticeTypeEnum.CP_LOVE_LETTER)
|
||||
.templateParam(templateParam)
|
||||
.expand(letterId)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -4,8 +4,10 @@ import com.red.circle.common.business.dto.cmd.AppExtCommand;
|
||||
import com.red.circle.common.business.dto.cmd.UserIdCmd;
|
||||
import com.red.circle.common.business.dto.cmd.UserIdCommonCmd;
|
||||
import com.red.circle.other.app.command.user.DismissCpApplyCmdExe;
|
||||
import com.red.circle.other.app.command.user.LoveLetterQueryCmdExe;
|
||||
import com.red.circle.other.app.command.user.ProcessCpApplyCmd;
|
||||
import com.red.circle.other.app.command.user.SendCpApplyCmdExe;
|
||||
import com.red.circle.other.app.command.user.SendLoveLetterCmdExe;
|
||||
import com.red.circle.other.app.command.user.query.CpApplyIdQryExe;
|
||||
import com.red.circle.other.app.command.user.query.UserCpPairUserProfileQryExe;
|
||||
import com.red.circle.other.app.command.user.query.UserCpRelationQryExe;
|
||||
@ -13,9 +15,12 @@ import com.red.circle.other.app.command.user.query.UserCpRelationQueryV4Exe;
|
||||
import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpCabinUserProfileCO;
|
||||
import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpPairUserProfileCO;
|
||||
import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpUserProfileCO;
|
||||
import com.red.circle.other.domain.model.cp.loveletter.LoveLetterDetailCO;
|
||||
import com.red.circle.other.domain.model.cp.loveletter.LoveLetterWallCO;
|
||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyCmd;
|
||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyDismissCmd;
|
||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.ProcessApplyCmd;
|
||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.loveletter.SendLoveLetterCmd;
|
||||
import com.red.circle.other.app.util.DistributedLockUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -39,6 +44,8 @@ public class UserCpRelationServiceImpl implements UserCpRelationService {
|
||||
private final UserCpPairUserProfileQryExe userCpPairUserProfileQryExe;
|
||||
private final UserCpRelationQueryV4Exe userCpRelationQueryV4Exe;
|
||||
private final DistributedLockUtil distributedLockUtil;
|
||||
private final SendLoveLetterCmdExe sendLoveLetterCmdExe;
|
||||
private final LoveLetterQueryCmdExe loveLetterQueryCmdExe;
|
||||
|
||||
@Override
|
||||
public CpUserProfileCO getCpUser(UserIdCmd cmd) {
|
||||
@ -81,5 +88,13 @@ public class UserCpRelationServiceImpl implements UserCpRelationService {
|
||||
return userCpRelationQueryV4Exe.execute(cmd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendLoveLetter(SendLoveLetterCmd cmd) {
|
||||
String key = "SEND_LOVE_LETTER:" + cmd.getReqUserId();
|
||||
distributedLockUtil.executeWithLock(key, () -> {
|
||||
sendLoveLetterCmdExe.execute(cmd);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,26 @@
|
||||
package com.red.circle.other.app.dto.cmd.user.relation.cp.loveletter;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import com.red.circle.common.business.dto.cmd.AppExtCommand;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 发送CP告白信封
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class SendLoveLetterCmd extends AppExtCommand {
|
||||
|
||||
@NotNull(message = "接收者用户ID不能为空")
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long receiverId;
|
||||
|
||||
@NotBlank(message = "告白内容不能为空")
|
||||
@Size(max = 80, message = "告白内容不能超过80字符")
|
||||
private String content;
|
||||
}
|
||||
@ -9,6 +9,7 @@ import com.red.circle.other.app.dto.clientobject.user.relation.cp.CpUserProfileC
|
||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyCmd;
|
||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.CpApplyDismissCmd;
|
||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.ProcessApplyCmd;
|
||||
import com.red.circle.other.app.dto.cmd.user.relation.cp.loveletter.SendLoveLetterCmd;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -33,5 +34,6 @@ public interface UserCpRelationService {
|
||||
|
||||
CpCabinUserProfileCO getCpUserV4(UserIdCommonCmd cmd);
|
||||
|
||||
void sendLoveLetter(SendLoveLetterCmd cmd);
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
package com.red.circle.other.domain.gateway.user;
|
||||
|
||||
import com.red.circle.other.domain.model.cp.CpLoveLetterDomain;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* CP告白信封数据网关
|
||||
*/
|
||||
public interface CpLoveLetterGateway {
|
||||
|
||||
/**
|
||||
* 保存信封
|
||||
*/
|
||||
void save(CpLoveLetterDomain letter);
|
||||
|
||||
/**
|
||||
* 查询告白墙最新N条
|
||||
*/
|
||||
List<CpLoveLetterDomain> listLatestLetters(Integer limit);
|
||||
|
||||
/**
|
||||
* 查询用户收到的最新一条信封
|
||||
*/
|
||||
CpLoveLetterDomain getLatestReceivedLetter(Long receiverId);
|
||||
|
||||
/**
|
||||
* 更新信封状态为已读
|
||||
*/
|
||||
void markAsRead(Long letterId);
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
package com.red.circle.other.domain.model.cp;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* CP告白信封领域模型
|
||||
*/
|
||||
@Data
|
||||
public class CpLoveLetterDomain {
|
||||
|
||||
private Long id;
|
||||
|
||||
private Long senderId;
|
||||
|
||||
private Long receiverId;
|
||||
|
||||
private String content;
|
||||
|
||||
private Integer status;
|
||||
|
||||
private Long costGold;
|
||||
|
||||
private Timestamp createTime;
|
||||
|
||||
private Timestamp updateTime;
|
||||
|
||||
/**
|
||||
* 是否未读
|
||||
*/
|
||||
public boolean isUnread() {
|
||||
return status == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 标记为已读
|
||||
*/
|
||||
public void markAsRead() {
|
||||
this.status = 1;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
package com.red.circle.other.domain.model.cp.loveletter;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.Data;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 告白信封详情
|
||||
*/
|
||||
@Data
|
||||
public class LoveLetterDetailCO {
|
||||
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long id;
|
||||
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long senderId;
|
||||
|
||||
private String senderNickname;
|
||||
|
||||
private String senderAvatar;
|
||||
|
||||
private String content;
|
||||
|
||||
private Integer status;
|
||||
|
||||
private Timestamp createTime;
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
package com.red.circle.other.domain.model.cp.loveletter;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.Data;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 告白墙信封
|
||||
*/
|
||||
@Data
|
||||
public class LoveLetterWallCO {
|
||||
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long id;
|
||||
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long senderId;
|
||||
|
||||
private String senderNickname;
|
||||
|
||||
private String senderAvatar;
|
||||
|
||||
private String receiverNickname;
|
||||
|
||||
private String receiverAvatar;
|
||||
|
||||
private String content;
|
||||
|
||||
private Timestamp createTime;
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
package com.red.circle.other.infra.convertor.user;
|
||||
|
||||
import com.red.circle.other.domain.model.cp.CpLoveLetterDomain;
|
||||
import com.red.circle.other.domain.model.cp.loveletter.LoveLetterDetailCO;
|
||||
import com.red.circle.other.domain.model.cp.loveletter.LoveLetterWallCO;
|
||||
import org.mapstruct.Mapper;
|
||||
|
||||
/**
|
||||
* CP告白信封转换器
|
||||
*/
|
||||
@Mapper(componentModel = "spring")
|
||||
public interface CpLoveLetterConvertor {
|
||||
|
||||
LoveLetterWallCO toWallCO(CpLoveLetterDomain letter);
|
||||
|
||||
LoveLetterDetailCO toDetailCO(CpLoveLetterDomain letter);
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package com.red.circle.other.infra.database.rds.dao.user.user;
|
||||
|
||||
import com.red.circle.framework.mybatis.dao.BaseDAO;
|
||||
import com.red.circle.other.infra.database.rds.entity.user.user.CpLoveLetter;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* CP告白信封 Mapper
|
||||
*/
|
||||
public interface CpLoveLetterDAO extends BaseDAO<CpLoveLetter> {
|
||||
|
||||
/**
|
||||
* 查询告白墙最新N条信封
|
||||
*/
|
||||
List<CpLoveLetter> listLatestLetters(@Param("limit") Integer limit);
|
||||
|
||||
/**
|
||||
* 查询用户收到的最新一条信封
|
||||
*/
|
||||
CpLoveLetter getLatestReceivedLetter(@Param("receiverId") Long receiverId);
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
package com.red.circle.other.infra.database.rds.entity.user.user;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* CP告白信封
|
||||
*/
|
||||
@Data
|
||||
@TableName("cp_love_letter")
|
||||
public class CpLoveLetter {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private Long senderId;
|
||||
|
||||
private Long receiverId;
|
||||
|
||||
private String content;
|
||||
|
||||
private Integer status;
|
||||
|
||||
private Long costGold;
|
||||
|
||||
@TableLogic
|
||||
private Integer isDeleted;
|
||||
|
||||
private LocalDateTime createTime;
|
||||
|
||||
private LocalDateTime updateTime;
|
||||
}
|
||||
@ -0,0 +1,84 @@
|
||||
package com.red.circle.other.infra.gateway.user;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.red.circle.other.domain.gateway.user.CpLoveLetterGateway;
|
||||
import com.red.circle.other.domain.model.cp.CpLoveLetterDomain;
|
||||
import com.red.circle.other.infra.database.rds.dao.user.user.CpLoveLetterDAO;
|
||||
import com.red.circle.other.infra.database.rds.entity.user.user.CpLoveLetter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* CP告白信封数据网关实现
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class CpLoveLetterGatewayImpl implements CpLoveLetterGateway {
|
||||
|
||||
private final CpLoveLetterDAO cpLoveLetterDAO;
|
||||
|
||||
@Override
|
||||
public void save(CpLoveLetterDomain letter) {
|
||||
CpLoveLetter entity = toEntity(letter);
|
||||
cpLoveLetterDAO.insert(entity);
|
||||
letter.setId(entity.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CpLoveLetterDomain> listLatestLetters(Integer limit) {
|
||||
List<CpLoveLetter> entities = cpLoveLetterDAO.listLatestLetters(limit);
|
||||
return entities.stream()
|
||||
.map(this::toDomain)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CpLoveLetterDomain getLatestReceivedLetter(Long receiverId) {
|
||||
CpLoveLetter entity = cpLoveLetterDAO.getLatestReceivedLetter(receiverId);
|
||||
return entity == null ? null : toDomain(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markAsRead(Long letterId) {
|
||||
LambdaUpdateWrapper<CpLoveLetter> wrapper = new LambdaUpdateWrapper<>();
|
||||
wrapper.eq(CpLoveLetter::getId, letterId)
|
||||
.set(CpLoveLetter::getStatus, 1);
|
||||
cpLoveLetterDAO.update(null, wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 领域模型转Entity
|
||||
*/
|
||||
private CpLoveLetter toEntity(CpLoveLetterDomain domain) {
|
||||
CpLoveLetter entity = new CpLoveLetter();
|
||||
entity.setId(domain.getId());
|
||||
entity.setSenderId(domain.getSenderId());
|
||||
entity.setReceiverId(domain.getReceiverId());
|
||||
entity.setContent(domain.getContent());
|
||||
entity.setStatus(domain.getStatus());
|
||||
entity.setCostGold(domain.getCostGold());
|
||||
entity.setCreateTime(domain.getCreateTime().toLocalDateTime());
|
||||
entity.setUpdateTime(domain.getUpdateTime().toLocalDateTime());
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Entity转领域模型
|
||||
*/
|
||||
private CpLoveLetterDomain toDomain(CpLoveLetter entity) {
|
||||
CpLoveLetterDomain domain = new CpLoveLetterDomain();
|
||||
domain.setId(entity.getId());
|
||||
domain.setSenderId(entity.getSenderId());
|
||||
domain.setReceiverId(entity.getReceiverId());
|
||||
domain.setContent(entity.getContent());
|
||||
domain.setStatus(entity.getStatus());
|
||||
domain.setCostGold(entity.getCostGold());
|
||||
domain.setCreateTime(Timestamp.valueOf(entity.getCreateTime()));
|
||||
domain.setUpdateTime(Timestamp.valueOf(entity.getUpdateTime()));
|
||||
return domain;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
<?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.user.user.CpLoveLetterDAO">
|
||||
|
||||
<select id="listLatestLetters" resultType="com.red.circle.other.infra.database.rds.entity.user.user.CpLoveLetter">
|
||||
SELECT * FROM cp_love_letter
|
||||
WHERE is_deleted = 0
|
||||
ORDER BY create_time DESC
|
||||
LIMIT #{limit}
|
||||
</select>
|
||||
|
||||
<select id="getLatestReceivedLetter" resultType="com.red.circle.other.infra.database.rds.entity.user.user.CpLoveLetter">
|
||||
SELECT * FROM cp_love_letter
|
||||
WHERE receiver_id = #{receiverId}
|
||||
AND is_deleted = 0
|
||||
ORDER BY create_time DESC
|
||||
LIMIT 1
|
||||
</select>
|
||||
</mapper>
|
||||
Loading…
x
Reference in New Issue
Block a user