Files
operationSystem-back/src/main/java/com/caliverse/admin/domain/service/MailService.java
2025-05-01 07:09:05 +09:00

503 lines
22 KiB
Java

package com.caliverse.admin.domain.service;
import com.caliverse.admin.domain.dao.admin.HistoryMapper;
import com.caliverse.admin.domain.dao.admin.MailMapper;
import com.caliverse.admin.domain.dao.total.WalletUserMapper;
import com.caliverse.admin.domain.datacomponent.MetaDataHandler;
import com.caliverse.admin.domain.entity.*;
import com.caliverse.admin.domain.request.MailRequest;
import com.caliverse.admin.domain.response.MailResponse;
import com.caliverse.admin.dynamodb.service.DynamodbCaliumService;
import com.caliverse.admin.dynamodb.service.DynamodbUserService;
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.constants.CommonConstants;
import com.caliverse.admin.global.common.exception.RestApiException;
import com.caliverse.admin.global.common.utils.CommonUtils;
import com.caliverse.admin.global.common.utils.ExcelUtils;
import com.caliverse.admin.scheduler.ScheduleService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.core.io.ResourceLoader;
import java.net.MalformedURLException;
import java.nio.file.Path;
import java.time.LocalDateTime;
import java.util.*;
@Slf4j
@Service
@RequiredArgsConstructor
public class MailService {
private final DynamoDBService dynamoDBService;
private final WalletUserMapper walletUserMapper;
private final DynamodbUserService dynamodbUserService;
@Value("${excel.file-path}")
private String excelPath;
@Value("${caliverse.file}")
private String samplePath;
private final ExcelUtils excelUtils;
private final MailMapper mailMapper;
private final HistoryMapper historyMapper;
private final MetaDataHandler metaDataHandler;
private final ResourceLoader resourceLoader;
private final ScheduleService scheduleService;
private final HistoryService historyService;
private final DynamodbCaliumService dynamodbCaliumService;
public MailResponse getStockCalium(){
double stock_calium = dynamodbCaliumService.getCaliumTotal();
return MailResponse.builder()
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.resultData(MailResponse.ResultData.builder()
.stockCalium(stock_calium)
.build()
)
.build();
}
public MailResponse getList(Map requestParam){
// gameDB 조회 및 서비스 로직
//페이징 처리
requestParam = CommonUtils.pageSetting(requestParam);
List<Mail> list = mailMapper.getMailList(requestParam);
int allCnt = mailMapper.getAllCnt(requestParam);
return MailResponse.builder()
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.resultData(MailResponse.ResultData.builder()
.mailList(list)
.total(mailMapper.getTotal())
.totalAll(allCnt)
.pageNo(requestParam.get("page_no")!=null?
Integer.valueOf(requestParam.get("page_no").toString()):1)
.build()
)
.build();
}
public MailResponse getdetail(Long id){
// gameDB 조회 및 서비스 로직
Mail mail = mailMapper.getMailDetail(id);
mail.setMailList(mailMapper.getMessage(id));
// mail.setItemList(mailMapper.getItem(id));
List<Item> itemList = mailMapper.getItem(id);
for(Item item : itemList){
String itemName = metaDataHandler.getMetaItemNameData(Integer.parseInt(item.getItem()));
item.setItemName(metaDataHandler.getTextStringData(itemName));
}
mail.setItemList(itemList);
return MailResponse.builder()
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.resultData(MailResponse.ResultData.builder()
.mail(mail)
.build())
.build();
}
public MailResponse excelUpload(MultipartFile file){
List<Mail> list = new ArrayList<>();
// 파일 존재하지 않는 경우
if (file.isEmpty()) {
throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.NOT_EXIT_EXCEL.getMessage() ); //Excel 파일을 선택해주세요.
}
List listData = excelUtils.getListData(file, 1, 0);
// 엑셀 파일내 중복된 데이터 있는지 체크
if(excelUtils.hasDuplicates(listData)){
throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.DUPLICATE_EXCEL.getMessage() ); //Excel 파일을 선택해주세요.
}
listData.forEach(
item->{
Mail mail = new Mail();
mail.setGuid(item.toString());
list.add(mail);
}
);
// 파일을 서버에 저장
String fileName = excelUtils.saveExcelFile(file);
return MailResponse.builder()
.resultData(MailResponse.ResultData.builder()
.mailList(list).message(SuccessCode.EXCEL_UPLOAD.getMessage())
.fileName(fileName)
.build())
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.build();
}
public Resource excelDown(String fileName) {
Path filePath = Path.of(excelPath+fileName);
try {
if(fileName.contains("sample")){
return resourceLoader.getResource(samplePath + fileName);
}
Resource resource = new UrlResource(filePath.toUri());
if (resource.exists() && resource.isReadable()) {
return resource;
} else {
throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.NOT_EXIT_EXCEL.getMessage());
}
}catch (MalformedURLException e){
throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.NOT_EXIT_EXCEL.getMessage());
}
}
@Transactional(transactionManager = "transactionManager")
public MailResponse postMail(MailRequest mailRequest){
mailRequest.setCreateBy(CommonUtils.getAdmin().getId());
if(mailRequest.isReserve()){
mailRequest.setSendType(Mail.SENDTYPE.RESERVE_SEND);
}else{
mailRequest.setSendType(Mail.SENDTYPE.DIRECT_SEND);
mailRequest.setSendDt(LocalDateTime.now());
}
//단일일경우 guid 를 target 설정, 복수이면은 fileName을 target에 설정
if(mailRequest.getGuid() != null){
if(mailRequest.getUserType().equals(Mail.USERTYPE.GUID) && dynamoDBService.isGuidChecked(mailRequest.getGuid())){
log.error("postMail RECEIVETYPE Single Guid Find Fail");
throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.WARNING_GUID_CHECK.getMessage());
}
String guid = mailRequest.getGuid();
// 닉네임이면 guid로 바꾼다
if(mailRequest.getUserType().equals(Mail.USERTYPE.NICKNAME)) {
// guid = dynamoDBService.getNickNameByGuid(guid);
guid = getGuid(guid, Mail.USERTYPE.NICKNAME.name());
if(guid == null || mailRequest.getGuid().equals(guid)){
log.error("postMail RECEIVETYPE Single Nickname Find Fail");
throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.NICKNAME_CHECK.getMessage() );
}
}else if(mailRequest.getUserType().equals(Mail.USERTYPE.EMAIL)){
guid = getGuid(guid, Mail.USERTYPE.EMAIL.name());
if(guid == null || guid.isEmpty()){
log.error("postMail RECEIVETYPE Single EMAIL Find Fail");
throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.EMAIL_CHECK.getMessage() );
}
}
mailRequest.setReceiveType(Mail.RECEIVETYPE.SINGLE);
mailRequest.setTarget(guid);
}
//엑셀 처리
else{
mailRequest.setReceiveType(Mail.RECEIVETYPE.MULTIPLE);
if(mailRequest.getFileName() == null){
throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.NOT_EXIT_EXCEL.toString() ); //Excel 파일을 선택해주세요.
}
List<Excel> excelList = excelUtils.getExcelListData(mailRequest.getFileName());
for(Excel excel : excelList){
switch (excel.getType()) {
case "GUID" -> {
if (dynamoDBService.isGuidChecked(excel.getUser())) {
log.error("postMail Multi Guid({}) Find Fail", excel.getUser());
throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.WARNING_GUID_CHECK.toString());
}
}
case "NICKNAME" -> {
String user = getGuid(excel.getUser(), Mail.USERTYPE.NICKNAME.name());
if (user == null || user.isEmpty()) {
log.error("postMail Multi Nickname({}) Find Fail", excel.getUser());
throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.NICKNAME_CHECK.toString());
}
}
case "EMAIL" -> {
String user = getGuid(excel.getUser(), Mail.USERTYPE.EMAIL.name());
if (user == null || user.isEmpty()) {
log.error("postMail Multi Email({}) Find Fail", excel.getUser());
throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.EMAIL_CHECK.toString());
}
}
default ->
throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.USERTYPE_CHECK_EXCEL.toString()); //Excel 파일을 선택해주세요.
}
}
mailRequest.setTarget(mailRequest.getFileName());
}
mailMapper.postMail(mailRequest);
//log.info("mail_id::"+ mailRequest.getId());
HashMap<String,String> map = new HashMap<>();
map.put("mailId",String.valueOf(mailRequest.getId()));
//아이템 저장
if(mailRequest.getItemList()!= null && !mailRequest.getItemList().isEmpty()){
//칼리움일경우 수량체크
boolean hasCalium = mailRequest.getItemList().stream().anyMatch(item -> item.getItem().equals(CommonConstants.CALIUM_ITEM_CODE));
double caliumSum = 0;
if(hasCalium){
caliumSum = mailRequest.getItemList().stream()
.filter(item -> item.getItem().equals(CommonConstants.CALIUM_ITEM_CODE))
.mapToDouble(Item::getItemCnt)
.sum();
double stockCalium = dynamodbCaliumService.getCaliumTotal();
if(caliumSum > stockCalium){
throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.ERROR_MAIL_ITEM_CALIUM_OVER.toString());
}
}
mailRequest.getItemList().forEach(
item -> {
map.put("goodsId",item.getItem());
map.put("itemCnt", String.valueOf(item.getItemCnt()));
mailMapper.insertItem(map);
}
);
//재원저장소 칼리움 차감
if(hasCalium){
dynamodbCaliumService.caliumStockDeduction(caliumSum);
}
}
//메시지 저장
if(mailRequest.getMailList()!= null && !mailRequest.getMailList().isEmpty()){
mailRequest.getMailList().forEach(
item -> {
map.put("title",item.getTitle());
map.put("content",item.getContent());
map.put("language",item.getLanguage());
mailMapper.insertMessage(map);
}
);
}
log.info("postMail Insert Mail: {}", mailRequest);
//로그 기록
JSONObject jsonObject = new JSONObject();
jsonObject.put("mail_type",mailRequest.getMailType());
jsonObject.put("receiver",mailRequest.getTarget());
Mail.SENDTYPE sendType = mailRequest.getSendType();
jsonObject.put("send_type",sendType);
if(sendType.equals(Mail.SENDTYPE.RESERVE_SEND))
jsonObject.put("send_dt",mailRequest.getSendDt());
jsonObject.put("mail_list",map);
historyService.setLog(HISTORYTYPE.MAIL_ADD, jsonObject);
return MailResponse.builder()
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.resultData(MailResponse.ResultData.builder()
.message(SuccessCode.SAVE.getMessage())
.build())
.build();
}
@Transactional(transactionManager = "transactionManager")
public MailResponse updateMail(Long id, MailRequest mailRequest) {
mailRequest.setId(id);
mailRequest.setUpdateBy(CommonUtils.getAdmin().getId());
mailRequest.setUpdateDt(LocalDateTime.now());
if (mailRequest.isReserve()) {
mailRequest.setSendType(Mail.SENDTYPE.RESERVE_SEND);
} else {
mailRequest.setSendType(Mail.SENDTYPE.DIRECT_SEND);
mailRequest.setSendDt(LocalDateTime.now());
}
//단일일경우 guid 를 target 설정, 복수이면은 fileName을 target에 설정
if (mailRequest.getGuid() != null) {
String guid = mailRequest.getGuid();
// 닉네임이면 guid로 바꾼다
if(mailRequest.getUserType().equals(Mail.USERTYPE.NICKNAME)) guid = dynamodbUserService.getNameByGuid(guid);
mailRequest.setReceiveType(Mail.RECEIVETYPE.SINGLE);
mailRequest.setTarget(guid);
} else {
mailRequest.setReceiveType(Mail.RECEIVETYPE.MULTIPLE);
if (mailRequest.getFileName() == null) {
throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.NOT_EXIT_EXCEL.getMessage());
}
mailRequest.setTarget(mailRequest.getFileName());
}
Long mail_id = mailRequest.getId();
Mail before_info = mailMapper.getMailDetail(mail_id);
List<Message> before_msg = mailMapper.getMessage(mail_id);
List<Item> before_item = mailMapper.getItem(mail_id);
log.info("updateMail Update Before MailInfo: {}, Message: {}, Item: {}", before_info, before_msg, before_item);
mailMapper.updateMail(mailRequest);
// 스케줄에서 제거
scheduleService.closeTask("mail-" + mail_id.toString());
Map<String, String> map = new HashMap<>();
map.put("mailId", String.valueOf(mailRequest.getId()));
// item 테이블 데이터 삭제 처리 by mail_id
mailMapper.deleteItem(map);
// 아이템 업데이트
if (mailRequest.getItemList() != null && !mailRequest.getItemList().isEmpty()) {
mailRequest.getItemList().forEach(item -> {
map.put("goodsId", item.getItem());
map.put("itemCnt", String.valueOf(item.getItemCnt()));
mailMapper.insertItem(map);
});
}
// message 테이블 데이터 삭제 처리 by mail_id
mailMapper.deleteMessage(map);
// 메일 업데이트
if (mailRequest.getMailList() != null && !mailRequest.getMailList().isEmpty()) {
mailRequest.getMailList().forEach(item -> {
map.put("title", item.getTitle());
map.put("content", item.getContent());
map.put("language", item.getLanguage());
mailMapper.insertMessage(map);
});
}
log.info("updateMail Update After Mail: {}", mailRequest);
//로그 기록
JSONObject jsonObject = new JSONObject();
jsonObject.put("before_info",before_info.toString());
jsonObject.put("before_msg",before_msg.toString());
jsonObject.put("before_item",before_item.toString());
jsonObject.put("mail_type",mailRequest.getMailType());
jsonObject.put("receiver",mailRequest.getTarget());
Mail.SENDTYPE sendType = mailRequest.getSendType();
jsonObject.put("send_type",sendType);
if(sendType.equals(Mail.SENDTYPE.RESERVE_SEND))
jsonObject.put("send_dt",mailRequest.getSendDt());
historyService.setLog(HISTORYTYPE.MAIL_UPDATE, jsonObject);
return MailResponse.builder()
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.resultData(MailResponse.ResultData.builder()
.message(SuccessCode.UPDATE.getMessage())
.build())
.build();
}
@Transactional(transactionManager = "transactionManager")
public MailResponse deleteMail(MailRequest mailRequest){
Map<String,Object> map = new HashMap<>();
mailRequest.getList().forEach(
item->{
map.put("id",item.getId());
mailMapper.deleteMail(map);
// 스케줄에서 제거
scheduleService.closeTask("mail-" + item.getId());
log.info("deleteMail Mail: {}", item);
//로그 기록
List<Message> message = mailMapper.getMessage(Long.valueOf(item.getId()));
map.put("adminId", CommonUtils.getAdmin().getId());
map.put("name", CommonUtils.getAdmin().getName());
map.put("mail", CommonUtils.getAdmin().getEmail());
map.put("type", HISTORYTYPE.MAIL_DELETE);
JSONObject jsonObject = new JSONObject();
if(!message.isEmpty()){
jsonObject.put("message",message.get(0).getTitle());
}
map.put("content",jsonObject.toString());
historyMapper.saveLog(map);
}
);
return MailResponse.builder()
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.resultData(MailResponse.ResultData.builder()
.message(SuccessCode.DELETE.getMessage())
.build())
.build();
}
public List<Mail> getScheduleMailList(){
return mailMapper.getSchesuleMailList();
}
public List<Message> getMailMessageList(Long id){
return mailMapper.getMessage(id);
}
public List<Item> getMailItemList(Long id){
return mailMapper.getItem(id);
}
public void updateMailStatus(Long id, Mail.SENDSTATUS status){
Map<String,Object> map = new HashMap<>();
map.put("id", id);
map.put("status", status.toString());
mailMapper.updateCompleteMail(map);
}
//메타 아이템
public MailResponse getMetaItem(String metaId){
long id = Long.parseLong(metaId);
String item = metaDataHandler.getMetaItemNameData((int) id);
boolean isItem = (item != null && !item.isEmpty());
if(isItem) {
Item item_info = new Item();
item_info.setItem(metaId);
item_info.setItemName(metaDataHandler.getTextStringData(item));
return MailResponse.builder()
.status(CommonCode.SUCCESS.getHttpStatus())
.result(CommonCode.SUCCESS.getResult())
.resultData(MailResponse.ResultData.builder()
.message(SuccessCode.ITEM_EXIST.getMessage())
.itemInfo(item_info)
.build())
.build();
}else
return MailResponse.builder()
.status(CommonCode.ERROR.getHttpStatus())
.result(CommonCode.ERROR.getResult())
.resultData(MailResponse.ResultData.builder()
.message(ErrorCode.NOT_ITEM.getMessage())
.build())
.build();
}
public String getGuid(String target, String type){
if(Mail.USERTYPE.EMAIL.name().equals(type)){
WalletUser user = walletUserMapper.getUser(target);
return dynamodbUserService.getAccountIdByGuid(String.valueOf(user.getAccount_id()));
}else if(Mail.USERTYPE.NICKNAME.name().equals(type)){
return dynamodbUserService.getNameByGuid(target);
}
return target;
}
public void setScheduleLog(HISTORYTYPE type, String message){
//스케줄 로그 기록
historyService.setScheduleLog(type, message);
}
}