Files
operationSystem-back/src/main/java/com/caliverse/admin/domain/service/UsersService.java
2025-08-06 14:39:05 +09:00

596 lines
25 KiB
Java

package com.caliverse.admin.domain.service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import com.caliverse.admin.domain.RabbitMq.MessageHandlerService;
import com.caliverse.admin.domain.entity.EReqType;
import com.caliverse.admin.domain.entity.FriendRequest;
import com.caliverse.admin.domain.entity.SEARCHTYPE;
import com.caliverse.admin.domain.entity.log.LogAction;
import com.caliverse.admin.domain.request.MailRequest;
import com.caliverse.admin.dynamodb.domain.atrrib.AccountBaseAttrib;
import com.caliverse.admin.dynamodb.domain.atrrib.MailAttrib;
import com.caliverse.admin.dynamodb.domain.atrrib.MailJsonAttrib;
import com.caliverse.admin.dynamodb.domain.atrrib.MoneyAttrib;
import com.caliverse.admin.dynamodb.domain.doc.MailDoc;
import com.caliverse.admin.dynamodb.dto.PageResult;
import com.caliverse.admin.dynamodb.service.*;
import com.caliverse.admin.global.common.annotation.BusinessProcess;
import com.caliverse.admin.global.common.annotation.RequestLog;
import com.caliverse.admin.global.common.constants.CommonConstants;
import com.caliverse.admin.redis.service.RedisUserInfoService;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.caliverse.admin.domain.datacomponent.MetaDataHandler;
import com.caliverse.admin.domain.request.UsersRequest;
import com.caliverse.admin.domain.response.UsersResponse;
import com.caliverse.admin.global.common.code.CommonCode;
import com.caliverse.admin.global.common.code.ErrorCode;
import com.caliverse.admin.global.common.code.SuccessCode;
import com.caliverse.admin.global.common.exception.RestApiException;
import com.caliverse.admin.global.common.utils.CommonUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
@Service
@RequiredArgsConstructor
@Slf4j
public class UsersService {
private final DynamodbService dynamodbService;
private final UserGameSessionService userGameSessionService;
private final RedisUserInfoService redisUserInfoService;
private final DynamodbUserService dynamodbUserService;
private final DynamodbItemService dynamodbItemService;
private final DynamodbMailService dynamodbMailService;
private final DynamodbQuestService dynamodbQuestService;
private final DynamodbMyHomeService dynamodbMyHomeService;
private final DynamodbFriendService dynamodbFriendService;
private final MessageHandlerService messageHandlerService;
private final ReqIdService reqIdService;
@Autowired
private MetaDataHandler metaDataHandler;
// 닉네임 변경
@BusinessProcess(action = LogAction.NICKNAME_CHANGE)
@RequestLog
public UsersResponse changeNickname(UsersRequest usersRequest){
String guid = usersRequest.getGuid();
String nickname = usersRequest.getNickname();
String newNickname = usersRequest.getNewNickname();
//신규 닉네임 유효성 체크
ErrorCode check = CommonUtils.isValidNickname(newNickname);
if(!check.equals(ErrorCode.SUCCESS)){
throw new RestApiException(CommonCode.ERROR.getHttpStatus(), check.toString() );
}
userGameSessionService.kickUserSession(guid, String.format("%s User Nickname Changes", nickname));
dynamodbUserService.changesNickname(guid, nickname, newNickname);
log.info("Nickname Changed complete guid: {}", guid);
return UsersResponse.builder()
.resultData(UsersResponse.ResultData.builder()
.message(SuccessCode.UPDATE.getMessage())
.build())
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.build();
}
// GM 권한 변경
@BusinessProcess(action = LogAction.ADMIN_LEVEL)
@RequestLog
public UsersResponse changeAdminLevel(UsersRequest usersRequest){
String guid = usersRequest.getGuid();
dynamodbUserService.updateAdminLevel(guid, usersRequest.getAdminLevel());
log.info("Admin Level Changed Complete guid: {}", guid);
return UsersResponse.builder()
.resultData(UsersResponse.ResultData.builder()
.message(SuccessCode.UPDATE.getMessage())
.build())
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.build();
}
// 유저 킥
@BusinessProcess(action = LogAction.KICK_USER)
@RequestLog
public UsersResponse userKick(UsersRequest usersRequest){
String guid = usersRequest.getGuid();
String adminUser = CommonUtils.getAdmin().getEmail();
userGameSessionService.kickUserSession(guid, String.format("admin %s kick out", adminUser));
log.info("User Kicked Complete guid: {}", guid);
return UsersResponse.builder()
.resultData(UsersResponse.ResultData.builder()
.message(SuccessCode.SUCCESS.getMessage())
.build())
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.build();
}
// 유정 정보 조회 닉네임,GUID,Account ID
@RequestLog
public UsersResponse findUsers(Map requestParam){
String searchType = requestParam.get("search_type").toString();
String searchKey = requestParam.get("search_key").toString();
Map<String,String> resultMap = new HashMap<>();
if(searchType.equals(SEARCHTYPE.NAME.name())){
String name_guid = dynamodbUserService.getNameByGuid(searchKey.toLowerCase());
if(!name_guid.isEmpty()){
resultMap.put("guid", name_guid); //nickname은 무조건 소문자
resultMap.put("nickname", searchKey);
}
}else if(searchType.equals(SEARCHTYPE.GUID.name())){
String guid_name = dynamodbUserService.getGuidByName(searchKey);
if(!guid_name.isEmpty()){
resultMap.put("guid", searchKey);
resultMap.put("nickname", guid_name);
}
}else if(searchType.equals(SEARCHTYPE.ACCOUNT.name())){
String account_guid = dynamodbUserService.getAccountIdByGuid(searchKey);
if(!account_guid.isEmpty()){
resultMap.put("guid", account_guid);
resultMap.put("nickname", dynamodbUserService.getAccountIdByName(searchKey));
}
}
return UsersResponse.builder()
.resultData(UsersResponse.ResultData.builder()
.result(resultMap)
.build())
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.build();
}
//유저 기본 정보
@RequestLog
public UsersResponse getBasicInfo(String guid){
String account_id = dynamodbUserService.getGuidByAccountId(guid);
AccountBaseAttrib accountBaseAttrib = dynamodbUserService.getAccountInfo(account_id);
UsersResponse.UserInfo userInfo = UsersResponse.UserInfo.builder()
.aid(accountBaseAttrib.getUserGuid())
.userId(accountBaseAttrib.getAccountId())
.nation(accountBaseAttrib.getLanguageType())
.membership("")
.friendCode("")
.createDt(accountBaseAttrib.getCreatedDateTime())
.accessDt(accountBaseAttrib.getLoginDateTime())
.endDt(accountBaseAttrib.getLogoutDateTime())
.walletUrl("")
.adminLevel(accountBaseAttrib.getAuthAdminLevelType())
.spareSlot("")
.build();
// charInfo
MoneyAttrib moneyAttrib = dynamodbUserService.getMoneyInfo(guid);
UsersResponse.CharInfo charInfo = UsersResponse.CharInfo.builder()
.characterName(dynamodbUserService.getGuidByName(guid))
.level("")
.goldCali(moneyAttrib.getGold())
.redCali(moneyAttrib.getCalium())
.blackCali(moneyAttrib.getRuby())
.blueCali(moneyAttrib.getSapphire())
.build();
boolean userSession = userGameSessionService.userSession(guid);
return UsersResponse.builder()
.resultData(
UsersResponse.ResultData.builder()
.charInfo(charInfo)
.userInfo(userInfo)
.userSession(userSession)
.build()
)
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.build();
}
//아바타 정보
@RequestLog
public UsersResponse getAvatarInfo(String guid){
//avatarInfo
Map<String, Object> charInfo = dynamodbUserService.getAvatarInfo(guid);
return UsersResponse.builder()
.resultData(
UsersResponse.ResultData.builder()
.avatarInfo((UsersResponse.AvatarInfo) charInfo.get("avatarInfo"))
.build()
)
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.build();
}
//의상 정보
@RequestLog
public UsersResponse getClothInfo(String guid){
Map<String, Object> charInfo = dynamodbItemService.getClothItems(guid);
return UsersResponse.builder()
.resultData(
UsersResponse.ResultData.builder()
.clothInfo((UsersResponse.ClothInfo) charInfo.get("clothInfo"))
.build()
)
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.build();
}
//도구 정보
@RequestLog
public UsersResponse getToolSlotInfo(String guid){
Map<String, Object> toolSlot = dynamodbItemService.getTools(guid);
return UsersResponse.builder()
.resultData(
UsersResponse.ResultData.builder()
.slotInfoList((UsersResponse.SlotInfo) toolSlot.get("toolSlotInfo"))
.build()
)
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.build();
}
//인벤토리 정보
@RequestLog
public UsersResponse getInventoryInfo(String guid){
UsersResponse.InventoryInfo inventoryInfo = dynamodbItemService.getInvenItems(guid);
log.info("getInventoryInfo Inventory Items: {}", inventoryInfo);
return UsersResponse.builder()
.resultData(
UsersResponse.ResultData.builder()
.inventoryInfo(inventoryInfo)
.build()
)
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.build();
}
//인벤토리 아이템 삭제
@BusinessProcess(action = LogAction.ITEM)
@RequestLog
public UsersResponse deleteInventoryItem(Map<String, String> requestParams){
String guid = requestParams.get("guid");
String item_guid = requestParams.get("item_guid");
int current_cnt = Integer.parseInt(requestParams.get("current_cnt"));
int update_cnt = Integer.parseInt(requestParams.get("cnt"));
userGameSessionService.kickUserSession(guid, "Item delete");
if(update_cnt >= current_cnt){
dynamodbItemService.deleteItem(guid, item_guid);
log.info("Item delete complete guid: {}", guid);
return UsersResponse.builder()
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.resultData(UsersResponse.ResultData.builder()
.message(SuccessCode.DELETE.getMessage())
.build())
.build();
}else{
int cnt = current_cnt - update_cnt;
dynamodbItemService.updateItemStack(guid, item_guid, cnt);
log.info("Item update complete guid: {}", guid);
return UsersResponse.builder()
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.resultData(UsersResponse.ResultData.builder()
.message(SuccessCode.UPDATE.getMessage())
.build())
.build();
}
}
//우편 정보
@RequestLog
public UsersResponse getMail(UsersRequest usersRequest){
PageResult<MailDoc> mailPageResult = dynamodbMailService.getMail(usersRequest.getMailType(), usersRequest.getGuid(), "", usersRequest.getPageKey());
List<UsersResponse.Mail> mailList = new ArrayList<>();
mailPageResult.getItems().forEach(doc -> {
try {
MailAttrib attrib = doc.getAttribValue();
List<UsersResponse.MailItem> itemList = new ArrayList<>();
if(attrib == null){
MailJsonAttrib mailJsonAttrib = dynamodbMailService.getMailJsonAttrib(doc.getPK(),doc.getSK());
mailJsonAttrib.getItemList().forEach(item -> {
UsersResponse.MailItem mailItem = new UsersResponse.MailItem();
mailItem.setItemId(CommonUtils.objectToString(item.getItemId()));
mailItem.setCount(item.getCount());
String item_nm = metaDataHandler.getMetaItemNameData(item.getItemId());
mailItem.setItemName(metaDataHandler.getTextStringData(item_nm));
itemList.add(mailItem);
});
UsersResponse.Mail mail = UsersResponse.Mail.builder()
.mailGuid(mailJsonAttrib.getMailGuid())
.title(mailJsonAttrib.getTitle())
.content(mailJsonAttrib.getText())
.senderNickname(mailJsonAttrib.getSenderNickName())
.receiveNickname(mailJsonAttrib.getReceiverNickName())
.status(mailJsonAttrib.isRead())
.isSystemMail(mailJsonAttrib.isSystemMail())
.isGetItem(mailJsonAttrib.isGetItem())
.createDt(mailJsonAttrib.getCreateTime())
.mailItemList(itemList)
.build();
mailList.add(mail);
}else{
attrib.getItemList().forEach(item -> {
UsersResponse.MailItem mailItem = new UsersResponse.MailItem();
mailItem.setItemId(CommonUtils.objectToString(item.getItemId()));
mailItem.setCount(item.getCount());
String item_nm = metaDataHandler.getMetaItemNameData(item.getItemId());
mailItem.setItemName(metaDataHandler.getTextStringData(item_nm));
itemList.add(mailItem);
});
UsersResponse.Mail mail = UsersResponse.Mail.builder()
.mailGuid(attrib.getMailGuid())
.title(attrib.getTitle())
.content(attrib.getText())
.senderNickname(attrib.getSenderNickName())
.receiveNickname(attrib.getReceiverNickName())
.status(Boolean.parseBoolean(attrib.getIsRead()))
.isSystemMail(Boolean.parseBoolean(attrib.getIsSystemMail()))
.isGetItem(Boolean.parseBoolean(attrib.getIsGetItem()))
.createDt(attrib.getCreateTime())
.mailItemList(itemList)
.build();
mailList.add(mail);
}
} catch (Exception e) {
log.error(e.getMessage());
throw new RestApiException(CommonCode.ERROR.getHttpStatus(), e.getMessage());
}
});
return UsersResponse.builder()
.resultData(
UsersResponse.ResultData.builder()
.mailList(mailList)
.pageKey(mailPageResult.getLastEvaluatedKey() == null ?
null :
mailPageResult.getLastEvaluatedKey().entrySet().stream()
.collect(Collectors.toMap(
Map.Entry::getKey,
entry -> entry.getValue().s()
))
)
.build()
)
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.build();
}
//우편 삭제
@BusinessProcess(action = LogAction.MAIL)
@RequestLog
public UsersResponse deleteMail(Map<String, String> requestParams){
String guid = requestParams.get("guid");
String mail_guid = requestParams.get("mail_guid");
String type = requestParams.get("type");
userGameSessionService.kickUserSession(guid, "delete mail");
dynamodbMailService.deleteMail(type, guid, mail_guid);
log.info("Delete mail complete guid: {}", guid);
return UsersResponse.builder()
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.resultData(UsersResponse.ResultData.builder()
.message(SuccessCode.DELETE.getMessage())
.build())
.build();
}
//우편 아이템 삭제
@BusinessProcess(action = LogAction.MAIL_ITEM)
@RequestLog
public UsersResponse deleteMailItem(MailRequest.DeleteMailItem deleteMailItem){
userGameSessionService.kickUserSession(deleteMailItem.getGuid(), "delete mail item");
dynamodbMailService.deleteMailItem(deleteMailItem.getType(), deleteMailItem.getGuid(),
deleteMailItem.getMailGuid(), deleteMailItem.getItemId(), deleteMailItem.getParrentCount(), deleteMailItem.getCount());
log.info("Delete mail item complete guid: {}", deleteMailItem.getGuid());
return UsersResponse.builder()
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.resultData(UsersResponse.ResultData.builder()
.message(SuccessCode.UPDATE.getMessage())
.build())
.build();
}
//마이홈 정보
@RequestLog
public UsersResponse getMyhome(String guid){
List<UsersResponse.Myhome> myhome = dynamodbMyHomeService.getMyHome(guid);
return UsersResponse.builder()
.resultData(
UsersResponse.ResultData.builder()
.myhomeInfo(myhome)
.build()
)
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.build();
}
//친구 목록
@RequestLog
public UsersResponse getFriendList(String guid){
List<UsersResponse.Friend> friendList = dynamodbFriendService.getFriend(guid);
List<UsersResponse.Friend> friendBlockList = dynamodbFriendService.getBlockUser(guid);
List<UsersResponse.Friend> friendSendList = new ArrayList<>();
List<UsersResponse.Friend> friendReceiveList = new ArrayList<>();
List<FriendRequest> sendRequestList = redisUserInfoService.getFriendRequestInfo("send", guid);
List<FriendRequest> receiveRequestList = redisUserInfoService.getFriendRequestInfo("receive", guid);
AtomicInteger idx = new AtomicInteger(1);
for(FriendRequest friendReq : sendRequestList){
UsersResponse.Friend friend = new UsersResponse.Friend();
friend.setRowNum(idx.getAndIncrement());
String receive_guid = friendReq.getReceiverGuid();
friend.setFriendGuid(receive_guid);
friend.setFriendName(dynamodbUserService.getGuidByName(receive_guid));
friend.setReceiveDt(friendReq.getRequestTime());
friend.setLanguage(dynamodbUserService.getUserLanguage(receive_guid));
friendSendList.add(friend);
}
idx = new AtomicInteger(1);
for(FriendRequest friendReq : receiveRequestList){
UsersResponse.Friend friend = new UsersResponse.Friend();
friend.setRowNum(idx.getAndIncrement());
String send_guid = friendReq.getSenderGuid();
friend.setFriendGuid(send_guid);
friend.setFriendName(dynamodbUserService.getGuidByName(send_guid));
friend.setReceiveDt(friendReq.getRequestTime());
friend.setLanguage(dynamodbUserService.getUserLanguage(send_guid));
friendReceiveList.add(friend);
}
return UsersResponse.builder()
.resultData(
UsersResponse.ResultData.builder()
.friendList(friendList)
.friendSendList(friendSendList)
.friendReceiveList(friendReceiveList)
.friendBlockList(friendBlockList)
.build()
)
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.build();
}
//타투 정보
@RequestLog
public UsersResponse getTattoo(String guid){
List<UsersResponse.Tattoo> resTatto = dynamodbItemService.getTattoo(guid);
return UsersResponse.builder()
.resultData(
UsersResponse.ResultData.builder()
.tattooList(resTatto)
.build()
)
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.build();
}
//퀘스트 정보
@RequestLog
public UsersResponse getQuest(String guid){
List<UsersResponse.QuestInfo> questList = dynamodbQuestService.getQuestItems(guid);
return UsersResponse.builder()
.resultData(
UsersResponse.ResultData.builder()
.questList(questList)
.build()
)
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.build();
}
@BusinessProcess(action = LogAction.QUEST_TASK)
@RequestLog
public UsersResponse CompleteQuestTask(UsersRequest usersRequest){
String serverName = redisUserInfoService.getFirstChannel();
if(serverName.isEmpty()){
log.error("CompleteQuestTask serverList is empty");
throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.NOT_FOUND_SERVER.getMessage());
}
String guid = usersRequest.getGuid();
userGameSessionService.kickUserSession(guid, "Force complete quest task");
String accountId = dynamodbUserService.getGuidByAccountId(guid);
try{
messageHandlerService.sendQuestTaskCompleteMessage(
serverName,
accountId,
reqIdService.generateNextReqId(
EReqType.QUEST_TASK,
CommonUtils.getAdmin() == null ? CommonConstants.SYSTEM : CommonUtils.getAdmin().getId().toString(),
"퀘스트 TASK 강제 완료 요청"
),
usersRequest.getQuestKey(),
usersRequest.getTaskNo()
);
} catch (Exception e) {
log.error("CompleteQuestTask messageHandlerService error: {}", e.getMessage(), e);
throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.MESSAGE_SEND_FAIL.getMessage());
}
log.info("CompleteQuestTask Quest Task forced completion guid: {}, quest: {}", guid, usersRequest.getQuestKey());
return UsersResponse.builder()
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.resultData(UsersResponse.ResultData.builder()
.message(SuccessCode.UPDATE.name())
.build())
.build();
}
}