랜드 소유권 변경시 우편 발송

This commit is contained in:
2025-03-14 18:23:39 +09:00
parent e1cb55871b
commit 160377fe20
13 changed files with 117 additions and 56 deletions

View File

@@ -23,6 +23,7 @@ public interface LandMapper {
int getMaxLandSeq(Integer landId);
int getPossibleLand(Integer landId);
int getPossibleLandOwnerChanges(Integer landId);
int postLandAuction(LandRequest landRequest);
int postLandOwnerChange(LandRequest landRequest);

View File

@@ -47,7 +47,8 @@ public enum HISTORYTYPE {
BATTLE_EVENT_DELETE("전투시스템 이벤트 삭제"),
LAND_OWNER_CHANGE_ADD("랜드 소유권 변경 등록"),
LAND_OWNER_CHANGE_UPDATE("랜드 소유권 변경 수정"),
LAND_OWNER_CHANGE_DELETE("랜드 소유권 변경 예약 취소")
LAND_OWNER_CHANGE_DELETE("랜드 소유권 변경 예약 취소"),
LAND_OWNER_CHANGE_MAIL("랜드 소유권 변경 우편")
;
private String historyType;
HISTORYTYPE(String type) {

View File

@@ -60,6 +60,7 @@ public class LandInfo {
AUCTION_WAIT,
AUCTION_END,
OWNED,
OWNED_WAIT
;
}
}

View File

@@ -10,6 +10,8 @@ import com.caliverse.admin.domain.entity.metadata.MetaBuildingData;
import com.caliverse.admin.domain.entity.metadata.MetaLandData;
import com.caliverse.admin.domain.request.LandRequest;
import com.caliverse.admin.domain.response.LandResponse;
import com.caliverse.admin.dynamodb.entity.ELandAuctionResult;
import com.caliverse.admin.dynamodb.entity.ELandAuctionState;
import com.caliverse.admin.dynamodb.service.DynamodbLandAuctionService;
import com.caliverse.admin.dynamodb.service.DynamodbLandService;
import com.caliverse.admin.dynamodb.service.DynamodbService;
@@ -163,47 +165,51 @@ public class LandService {
List<LandOwnerChange> ownerChanges = new ArrayList<>();
if(editor.equals(CommonConstants.USER)){
LandAttrib land = dynamodbLandService.getLandInfo(landId);
//경매 체크
int auctionNumber = dynamodbLandAuctionService.getLandAuctionNumber(landId);
if(auctionNumber > 0){
LandAuctionRegistryAttrib auctionRegistry = dynamodbLandAuctionService.getLandAuctionRegistry(landId, auctionNumber);
String auctionState = auctionRegistry.getAuctionState();
if (auctionState.equals(ELandAuctionState.STARTED.getName())) {
status = LandInfo.LAND_STATUS.AUCTION_RUNNING.toString();
} else if (auctionState.equals(ELandAuctionState.ENDED.getName())) {
String auctionResult = auctionRegistry.getAuctionResult();
if (auctionResult.equals(ELandAuctionResult.SUCCESSED.getName())) {
LandAuctionHighestBidUserAttrib bidUser = dynamodbLandAuctionService.getLandAuctionHighestUser(landId, auctionNumber);
status = LandInfo.LAND_STATUS.AUCTION_END.toString();
if (bidUser != null) {
ownerPrice = bidUser.getHighestBidPrice();
} else {
log.warn("LandAuction land: {}, auction_number: {} Ended Result Success bidUser null", landId, auctionNumber);
}
}
} else {
status = LandInfo.LAND_STATUS.AUCTION_WAIT.toString();
}
}
//랜드 존재
LandAttrib land = dynamodbLandService.getLandInfo(landId);
if(land != null){
ownerGuid = land.getOwnerUserGuid();
//소유 체크
if(!ownerGuid.isEmpty()){
ownerName = dynamodbUserService.getGuidByName(ownerGuid);
int auctionNumber = dynamodbLandAuctionService.getLandAuctionNumber(landId);
// 경매
if(auctionNumber > 0){
LandAuction auction = auctions.stream()
.filter(row -> row.getLandId().equals(landId) && row.getAuctionSeq().equals(auctionNumber))
.findFirst().orElse(null);
if(auction == null){
log.warn("getLandInfo.buildLandInfo auction info error landId: {}, auctionNumber: {}", landId, auctionNumber);
LandAuctionHighestBidUserAttrib bidUser = dynamodbLandAuctionService.getLandAuctionHighestUser(landId, auctionNumber);
LandAuctionRegistryAttrib auctionRegistry = dynamodbLandAuctionService.getLandAuctionRegistry(landId, auctionNumber);
if(bidUser != null && auctionRegistry != null){
status = LandInfo.LAND_STATUS.AUCTION_END.toString();
ownerPrice = bidUser.getHighestBidPrice();
ownerDate = convertIsoByDatetime(auctionRegistry.getAuctionEndTime());
}
}else{
LandAuction.AUCTION_STATUS auctionStatus = auction.getStatus();
if(auctionStatus.equals(LandAuction.AUCTION_STATUS.FAIL) || auctionStatus.equals(LandAuction.AUCTION_STATUS.CANCEL)){
status = "";
}else{
status = auctionStatus.toString();
if(auctionStatus.equals(LandAuction.AUCTION_STATUS.AUCTION_END)){
ownerPrice = auction.getClosePrice();
ownerDate = stringToDateTime(auction.getCloseEndDt());
}
}
}
}else{
String parsedDate = dynamodbLandService.getLandOwnerCreateDate(ownerGuid, landId);
ownerDate = parsedDate.isEmpty() ? "" : convertIsoByDatetime(parsedDate);
ownerName = dynamodbUserService.getGuidByName(ownerGuid);
if(status.equals(LandInfo.LAND_STATUS.NONE.toString())){
status = LandInfo.LAND_STATUS.OWNED.toString();
}
}
}else{
}
//변경 이력
ownerChanges = landMapper.getLandOwnerChangeInfo(landId);
if(!ownerChanges.isEmpty()){
long changesCount = ownerChanges.stream().filter(changeData -> changeData.getStatus().equals(LandOwnerChange.CHANGE_STATUS.WAIT)).count();
if(changesCount > 0){
status = LandInfo.LAND_STATUS.OWNED_WAIT.toString();
}
}
}else{
ownerName = CommonConstants.CALIVERSE_NAME;
@@ -442,6 +448,14 @@ public class LandService {
.build();
}
int chk = landMapper.getPossibleLandOwnerChanges(landRequest.getLandId());
if(chk > 0){
return LandResponse.builder()
.status(CommonCode.ERROR.getHttpStatus())
.result(ErrorCode.ERROR_LAND_OWNER_CHANGES_DUPLICATION.toString())
.build();
}
landRequest.setCreateBy(CommonUtils.getAdmin().getId());
boolean is_reserve = landRequest.isReserve();
if(!is_reserve){
@@ -471,11 +485,12 @@ public class LandService {
CommonUtils.getClientIp()
);
if(!is_reserve){
dynamodbLandService.ChangesLandOwner(landRequest);
map.put("status", LandOwnerChange.CHANGE_STATUS.FINISH);
updateLandOwnedChangeStatus(map);
}
// if(!is_reserve){
// dynamodbLandService.ChangesLandOwner(landRequest);
// map.put("status", LandOwnerChange.CHANGE_STATUS.FINISH);
// updateLandOwnedChangeStatus(map);
// dynamodbService.insertLandChangesMail(landRequest);
// }
return LandResponse.builder()
.status(CommonCode.SUCCESS.getHttpStatus())

View File

@@ -60,6 +60,7 @@ public enum ErrorCode {
ERROR_AUCTION_STATUS_IMPOSSIBLE("수정할 수 없는 경매상태입니다."),
ERROR_AUCTION_LAND_OWNER("해당 랜드는 소유자가 존재하여 경매를 진행할 수 없습니다."),
ERROR_LAND_OWNER_CHANGES_RESERVATION("소유권 변경 예약을 취소할 수 없는 상태입니다."),
ERROR_LAND_OWNER_CHANGES_DUPLICATION("등록된 소유권 변경 존재합니다."),
//Battle
ERROR_BATTLE_EVENT_TIME_OVER("해당 시간에 속하는 이벤트가 존재합니다."),

View File

@@ -14,8 +14,11 @@ public class CommonConstants {
public static final String LAND_PUBLIC = "public";
public static final String LAND_AUCTION = "auction";
public static final String LAND_EVENT = "event";
public static final String SYSTEM_MAIL_LAND_TRANS_KEY = "LandTrans";
public static final String FORMAT_DATE_ISO_DATETIME_MILLIS = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
public static final String FORMAT_DATE_ISO_DATETIME_MILLIS_NANO = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z'";
public static final String FORMAT_DATE_DATETIME = "yyyy-MM-dd HH:mm:ss";
public static final String FORMAT_DATE_ISO_DATETIME = "yyyy-MM-dd'T'HH:mm:ss";
public static final String FORMAT_DATE_MAIL_DATETIME = "yyyy/MM/dd/HH:mm:ss:SS";
}

View File

@@ -22,6 +22,8 @@ public class DynamoDBConstants {
public static final String PK_KEY_ACCOUNT_BASE = "account_base#";
public static final String PK_KEY_USER_BASE = "user_base#";
public static final String PK_KEY_NICKNAME = "nickname#";
public static final String PK_KEY_RECV_MAIL = "recv_mail#";
public static final String PK_KEY_SENT_MAIL = "sent_mail#";
//SK
@@ -37,6 +39,7 @@ public class DynamoDBConstants {
public static final String ATTRIB_BUILDING = "BuildingAttrib";
public static final String ATTRIB_OWNED_LAND = "OwnedLandAttrib";
public static final String ATTRIB_OWNED_BUILDING = "OwnedBuildingAttrib";
public static final String ATTRIB_MAIL = "MailAttrib";
//DOC
public static final String DOC_SYSTEMMAIL = "SystemMetaMailDoc";
@@ -49,12 +52,14 @@ public class DynamoDBConstants {
public static final String DOC_BUILDING = "BuildingDoc";
public static final String DOC_OWNED_LAND = "OwnedLandDoc";
public static final String DOC_OWNED_BUILDING = "OwnedBuildingDoc";
public static final String DOC_Mail = "MailDoc";
//SCHEMA
public static final String SCHEMA_UPDATE_TIME = "UpdatedDateTime";
//ETC
public static final String EMPTY = "empty";
public static final String TTL = "TTL";
public static final String MIN_DATE = "1970-01-01T00:00:00.000Z";
public static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSS";
}

View File

@@ -11,4 +11,5 @@ public class MetadataConstants {
public static final String JSON_LIST_LAND = "LandMetaDataList";
public static final String JSON_LIST_BATTLE_CONFIG = "BattleFFAConfigMetaDataList";
public static final String JSON_LIST_BATTLE_REWARD = "BattleFFARewardMetaDataList";
public static final String JSON_LIST_SYSTEM_META = "SystemMailMetaDataList";
}

View File

@@ -3,9 +3,7 @@ package com.caliverse.admin.global.common.utils;
import java.nio.charset.StandardCharsets;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.*;
@@ -34,8 +32,6 @@ import com.google.protobuf.ByteString;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import java.util.Base64;
@Component
@RequiredArgsConstructor
public class CommonUtils {
@@ -74,6 +70,10 @@ public class CommonUtils {
return null;
}
public static String getCreateGuId() {
return UUID.randomUUID().toString();
}
public static String objectToString(Object object){
if (object == null) {
return "";

View File

@@ -2,10 +2,7 @@ package com.caliverse.admin.global.common.utils;
import com.caliverse.admin.global.common.constants.CommonConstants;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.*;
import java.time.format.DateTimeFormatter;
public class DateUtils {
@@ -25,6 +22,11 @@ public class DateUtils {
return date.atOffset(ZoneOffset.UTC).format(formatter);
}
public static String stringToISODateTimeMillisNano(LocalDateTime date){
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(CommonConstants.FORMAT_DATE_ISO_DATETIME_MILLIS_NANO);
return date.atOffset(ZoneOffset.UTC).format(formatter);
}
public static LocalDateTime stringISOToLocalDateTime(String date){
Instant instant = Instant.parse(date);
return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
@@ -44,4 +46,17 @@ public class DateUtils {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSS");
return date.format(formatter);
}
public static String getMailDateFormat(LocalDateTime date){
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(CommonConstants.FORMAT_DATE_MAIL_DATETIME);
return date.atOffset(ZoneOffset.UTC).format(formatter);
}
public static LocalDateTime getMaxTime(){
return LocalDateTime.of(3000, 1, 1, 0, 0, 0, 0);
}
public static long dateToISOUnixTime(LocalDateTime date){
return date.atOffset(ZoneOffset.UTC).toEpochSecond();
}
}

View File

@@ -1,10 +1,9 @@
package com.caliverse.admin.global.component.transaction;
import com.caliverse.admin.global.common.utils.CommonUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import java.util.UUID;
@Component
public class TransactionIdManager {
private static final String TRANSACTION_ID_KEY = "TRANSACTION_ID";
@@ -12,13 +11,10 @@ public class TransactionIdManager {
public String getCurrentTransactionId() {
String currentId = (String) TransactionSynchronizationManager.getResource(TRANSACTION_ID_KEY);
if (currentId == null) {
currentId = generateTransactionId();
currentId = CommonUtils.getCreateGuId();
TransactionSynchronizationManager.bindResource(TRANSACTION_ID_KEY, currentId);
}
return currentId;
}
private String generateTransactionId() {
return UUID.randomUUID().toString();
}
}

View File

@@ -1,5 +1,7 @@
package com.caliverse.admin.scheduler.polling.service;
import com.caliverse.admin.domain.service.UserGameSessionService;
import com.caliverse.admin.dynamodb.service.DynamodbService;
import com.caliverse.admin.scheduler.CommonScheduler;
import com.caliverse.admin.scheduler.entity.SchedulerType;
import com.caliverse.admin.domain.entity.LandOwnerChange;
@@ -20,10 +22,14 @@ public class LandOwnerChangesScheduler extends CommonScheduler {
private final LandService landService;
private final DynamodbLandService dynamodbLandService;
private final DynamodbService dynamodbService;
private final UserGameSessionService userGameSessionService;
public LandOwnerChangesScheduler(LandService landService, DynamodbLandService dynamodbLandService) {
public LandOwnerChangesScheduler(LandService landService, DynamodbLandService dynamodbLandService, DynamodbService dynamodbService, UserGameSessionService userGameSessionService) {
this.landService = landService;
this.dynamodbLandService = dynamodbLandService;
this.dynamodbService = dynamodbService;
this.userGameSessionService = userGameSessionService;
}
@Override
@@ -47,12 +53,20 @@ public class LandOwnerChangesScheduler extends CommonScheduler {
.userGuid(guid)
.userName(landOwnerChange.getUserName())
.build();
//유저킥
userGameSessionService.kickUserSession(guid);
//랜드정보 처리
dynamodbLandService.ChangesLandOwner(landRequest);
Map map = new HashMap<>();
map.put("id", landOwnerChange.getId());
map.put("status", LandOwnerChange.CHANGE_STATUS.FINISH);
landService.updateLandOwnedChangeStatus(map);
//우편
dynamodbService.insertLandChangesMail(landRequest);
}
});
}

View File

@@ -209,6 +209,13 @@
AND status NOT IN ('AUCTION_END', 'DELETE', 'FAIL', 'CANCEL')
</select>
<select id="getPossibleLandOwnerChanges" parameterType="integer" resultType="integer">
SELECT count(*)
FROM land_ownership_changes
WHERE land_id = #{landId}
AND status = 'WAIT'
</select>
<!--이벤트 상세 조회-->
<select id="getLandAuctionDetail" parameterType="java.lang.Long" resultMap="LandAuctionResultMap" >
SELECT
@@ -383,12 +390,13 @@
, building_name
, status
, user_guid
, user_name
, is_reserve
, reservation_dt
FROM land_ownership_changes
WHERE (status = 'WAIT')
AND deleted = 0
AND is_reserve = 1
-- AND is_reserve = 1
</select>
</mapper>