package kr.wisestone.owl.service.impl;
|
|
import com.google.common.collect.Lists;
|
import kr.wisestone.owl.constant.MsgConstants;
|
import kr.wisestone.owl.domain.*;
|
import kr.wisestone.owl.domain.enumType.EmailType;
|
import kr.wisestone.owl.exception.OwlRuntimeException;
|
import kr.wisestone.owl.repository.UserInviteRepository;
|
import kr.wisestone.owl.service.*;
|
import kr.wisestone.owl.util.CommonUtil;
|
import kr.wisestone.owl.web.form.UserInviteForm;
|
import org.apache.commons.validator.routines.EmailValidator;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.messaging.simp.SimpMessagingTemplate;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.util.StringUtils;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Map;
|
|
@Service
|
public class UserInviteServiceImpl extends AbstractServiceImpl<UserInvite, Long, JpaRepository<UserInvite, Long>> implements UserInviteService {
|
|
private static final Logger log = LoggerFactory.getLogger(UserInviteServiceImpl.class);
|
|
@Autowired
|
private UserInviteRepository userInviteRepository;
|
|
@Autowired
|
private UserInviteProjectService userInviteProjectService;
|
|
@Autowired
|
private SystemEmailService systemEmailService;
|
|
@Autowired
|
private ProjectRoleService projectRoleService;
|
|
@Autowired
|
private ProjectRoleUserService projectRoleUserService;
|
|
@Autowired
|
private UserWorkspaceService userWorkspaceService;
|
|
@Autowired
|
private ProjectService projectService;
|
|
@Autowired
|
private UserService userService;
|
|
@Autowired
|
private WorkspaceService workspaceService;
|
|
@Autowired
|
private SimpMessagingTemplate simpMessagingTemplate;
|
|
@Override
|
protected JpaRepository<UserInvite, Long> getRepository() {
|
return this.userInviteRepository;
|
}
|
|
// 해당 업무 공간에 참여하고 있는지 확인 후 업무 공간에 참여시킨다. 또한 프로젝트에 참여되어 있는지 확인 후 프로젝트에도 참여시킨다.
|
@Override
|
@Transactional
|
public void checkInviteUser(User user) {
|
List<UserInvite> userInvites = this.userInviteRepository.findByEmailAndStatus(user.getAccount(), UserInvite.WORKSPACE_JOIN_READY);
|
|
for (UserInvite userInvite : userInvites) {
|
Workspace workspace = userInvite.getWorkspace();
|
// 업무 공간 참여
|
this.includeWorkspace(user, workspace);
|
// 프로젝트에 참여
|
this.includeProject(user, userInvite);
|
// 업무 공간 초대 상태를 완료로 업데이트
|
userInvite.setStatus(UserInvite.WORKSPACE_JOIN_COMPLETE);
|
}
|
|
if (userInvites.size() > 0) {
|
// 프로젝트 역할과 사용자 연결 업데이트
|
//this.userService.saveAndFlush(user);
|
// 초대 상태 업데이트
|
this.userInviteRepository.saveAll(userInvites);
|
}
|
}
|
|
// 업무 공간에 참여
|
private void includeWorkspace(User user, Workspace workspace) {
|
UserWorkspace userWorkspace = this.userWorkspaceService.findByUserIdAndWorkspaceId(user.getId(), workspace.getId());
|
|
if (userWorkspace != null) {
|
throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.INVITE_USER_USED_WORKSPACE));
|
}
|
|
// 해당 업무 공간의 활성인 사용자
|
Integer activeUserCount = this.userWorkspaceService.countByWorkspaceIdAndUseYn(workspace.getId(), true);
|
// 업무 공간에 더이상 사용자를 받을 공간이 없으면 비활성 상태로 업무 공간와 사용자를 연결한다.
|
if (workspace.getMaxUser() > activeUserCount) {
|
this.userWorkspaceService.addUserWorkspace(user, workspace, false, true);
|
}
|
else {
|
this.userWorkspaceService.addUserWorkspace(user, workspace, false, false);
|
// 웹 소켓으로 업무 공간 관리자에게 인원수 초과를 알려준다.
|
List<UserWorkspace> userWorkspaces = this.userWorkspaceService.findByWorkspaceIdAndManagerYn(workspace.getId(), true);
|
// 관리자에게 알림 팝업 표시 && 메일 전송
|
for (UserWorkspace managerUserWorkspace : userWorkspaces) {
|
User sendUser = managerUserWorkspace.getUser();
|
this.simpMessagingTemplate.convertAndSendToUser(sendUser.getAccount(), "/notification/workspace-max-user-excess", this.messageAccessor.getMessage(MsgConstants.WORKSPACE_MAX_USER_EXCESS));
|
|
Map<String, Object> workspaceMap = new HashMap<>();
|
workspaceMap.put("workspaceName", workspace.getName());
|
workspaceMap.put("activeUser", activeUserCount);
|
workspaceMap.put("disableUser", this.userWorkspaceService.countByWorkspaceIdAndUseYn(workspace.getId(), false));
|
// 업무 공간 활성 사용자 초과 알림 메일 전송
|
this.systemEmailService.directEmail(new String[]{sendUser.getAccount()}, EmailType.WORKSPACE_MAX_USER_EXCESS, workspaceMap, null);
|
}
|
}
|
}
|
|
// 기본 업무 공간에 참여
|
public void includePrimaryWorkspace(User user, Workspace workspace) {
|
// 해당 업무 공간의 활성인 사용자
|
Integer activeUserCount = this.userWorkspaceService.countByWorkspaceIdAndUseYn(workspace.getId(), true);
|
// 업무 공간에 더이상 사용자를 받을 공간이 없으면 비활성 상태로 업무 공간와 사용자를 연결한다.
|
if (workspace.getMaxUser() > activeUserCount) {
|
this.userWorkspaceService.addUserWorkspace(user, workspace, false, true);
|
}
|
else {
|
this.userWorkspaceService.addUserWorkspace(user, workspace, false, false);
|
// 웹 소켓으로 업무 공간 관리자에게 인원수 초과를 알려준다.
|
List<UserWorkspace> userWorkspaces = this.userWorkspaceService.findByWorkspaceIdAndManagerYn(workspace.getId(), true);
|
// 관리자에게 알림 팝업 표시 && 메일 전송
|
for (UserWorkspace managerUserWorkspace : userWorkspaces) {
|
User sendUser = managerUserWorkspace.getUser();
|
this.simpMessagingTemplate.convertAndSendToUser(sendUser.getAccount(), "/notification/workspace-max-user-excess", this.messageAccessor.getMessage(MsgConstants.WORKSPACE_MAX_USER_EXCESS));
|
|
Map<String, Object> workspaceMap = new HashMap<>();
|
workspaceMap.put("workspaceName", workspace.getName());
|
workspaceMap.put("activeUser", activeUserCount);
|
workspaceMap.put("disableUser", this.userWorkspaceService.countByWorkspaceIdAndUseYn(workspace.getId(), false));
|
// 업무 공간 활성 사용자 초과 알림 메일 전송
|
this.systemEmailService.directEmail(new String[]{sendUser.getAccount()}, EmailType.WORKSPACE_MAX_USER_EXCESS, workspaceMap, null);
|
}
|
}
|
}
|
// 프로젝트에 참여
|
private void includeProject(User user, UserInvite userInvite) {
|
for (UserInviteProject userInviteProject : userInvite.getUserInviteProjects()) {
|
Project project = userInviteProject.getProject();
|
// 기본 역할 확인
|
ProjectRole defaultProjectRole = this.projectRoleService.findByProjectIdAndRoleType(project.getId(), ProjectRole.TYPE_DEFAULT);
|
// 관리자 역할 확인
|
ProjectRole managerProjectRole = this.projectRoleService.findByProjectIdAndRoleType(project.getId(), ProjectRole.TYPE_MANAGER);
|
|
// 프로젝트 관리자 역할에 이미 연결되어 있으면 해당 프로젝트에 못들어간다.
|
ProjectRoleUser managerProjectRoleUser = this.projectRoleUserService.findByProjectRoleIdAndUserId(managerProjectRole.getId(), user.getId());
|
if (managerProjectRoleUser != null) {
|
continue;
|
}
|
|
ProjectRoleUser defaultProjectRoleUser = this.projectRoleUserService.findByProjectRoleIdAndUserId(defaultProjectRole.getId(), user.getId());
|
// 해당 역할에 사용자 연결이 안되어 있을 경우에만 연결
|
if (defaultProjectRoleUser == null) {
|
user.addProjectRole(defaultProjectRole);
|
}
|
}
|
}
|
|
// 업무 공간에 초대한 정보를 저장하고 이미 가입되어 있는 사용자는 즉시 해당 업무 공간, 프로젝트에 참여시킨다.
|
@Override
|
@Transactional
|
public void inviteWorkspace(UserInviteForm userInviteForm) {
|
|
for (String email : userInviteForm.getEmails()) {
|
// 이메일 유효성 검증
|
this.verifyEmail(CommonUtil.decryptAES128(email));
|
|
User user = this.userService.findByAccount(email);
|
Workspace workspace = this.workspaceService.getWorkspace(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId());
|
|
// 사용자가 이미 존재할 경우 해당 업무 공간에 초대한다.
|
// 사용자가 없을 경우 초대 메일을 전달한다.
|
// 초대받은 사용자는 회원 가입시 확인을 거쳐 해당 업무 공간로 가입시킨다.
|
if (user != null) {
|
// 이 초대를 보낸 사용자는 마지막으로 선택한 업무 공간에서 초대를 보낸 것이다. - 관리자뿐만 아니라 해당 업무 공간의 모든 사용자는 사람들을 초대할 수 있다.
|
UserWorkspace userWorkspace = this.userWorkspaceService.findByUserIdAndWorkspaceId(user.getId(), workspace.getId());
|
|
if (userWorkspace != null) {
|
throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.INVITE_USER_USED_WORKSPACE));
|
}
|
else {
|
// 업무 공간 기존 사용자에게 초대 메일 발송 - 자동으로 해당 업무 공간에 참여됨
|
this.addInvite(userInviteForm, workspace, email, EmailType.WORKSPACE_INVITE_SYSTEM_USER);
|
// 해당 업무 공간에 가입
|
this.checkInviteUser(user);
|
}
|
}
|
else {
|
// 업무 공간 초대 메일 발송 - 사용자가 직접 가입해야함.
|
this.addInvite(userInviteForm, workspace, email, EmailType.WORKSPACE_INVITE_NEW_USER);
|
}
|
}
|
}
|
|
// 이메일 유효성 검증
|
private void verifyEmail(String email) {
|
if (StringUtils.isEmpty(email)) {
|
throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.USER_INVALID_EMAIL));
|
}
|
else {
|
if (!EmailValidator.getInstance().isValid(email)) {
|
throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.USER_INVALID_EMAIL));
|
}
|
}
|
}
|
|
// 초대 정보 저장 및 메일 발송
|
private void addInvite(UserInviteForm userInviteForm, Workspace workspace, String email, EmailType emailType) {
|
// user invite 정보를 생성.
|
// 참여되는 프로젝트 셋팅
|
// 생성 종료 및 이메일 발송
|
UserInvite userInvite = this.userInviteRepository.findByEmailAndWorkspaceId(email, workspace.getId());
|
|
// 이미 초대장을 보낸적이 있으면 추가해야 할 프로젝트 정보를 추출한다.
|
if (userInvite != null) {
|
for (UserInviteProject userInviteProject : userInvite.getUserInviteProjects()) {
|
Project project = userInviteProject.getProject();
|
|
for (int count = 0; count < userInviteForm.getProjectIds().size(); count++) {
|
if (userInviteForm.getProjectIds().get(count).equals(project.getId())) {
|
userInviteForm.getProjectIds().remove(count);
|
break;
|
}
|
}
|
}
|
}
|
else {
|
List<Long> addProjectIds = this.checkHasProjectRole(email, userInviteForm.getProjectIds());
|
userInvite = new UserInvite();
|
userInvite.setEmail(email);
|
userInvite.setStatus(UserInvite.WORKSPACE_JOIN_READY);
|
userInvite.setWorkspace(workspace);
|
|
// 만약 추가해야할 프로젝트가 없을 경우(이미 해당 프로젝트에 소속되어있을 경우) 여기서 중단한다.
|
if (addProjectIds.isEmpty()) {
|
this.userInviteRepository.saveAndFlush(userInvite);
|
// 초대 메일을 발송한다.
|
this.sendInviteEmail(workspace, emailType, email);
|
return;
|
}
|
}
|
|
this.userInviteRepository.saveAndFlush(userInvite);
|
|
// 참여 프로젝트 셋팅
|
List<UserInviteProject> userInviteProjects = this.userInviteProjectService.addUserInviteProject(userInviteForm.getProjectIds(), userInvite);
|
|
if (!userInviteProjects.isEmpty()) {
|
for (UserInviteProject userInviteProject : userInviteProjects) {
|
userInvite.addUserInviteProjects(userInviteProject);
|
}
|
|
this.userInviteRepository.saveAndFlush(userInvite);
|
}
|
|
// 초대 메일을 발송한다.
|
this.sendInviteEmail(workspace, emailType, email);
|
}
|
|
// 초대 메일을 발송한다.
|
private void sendInviteEmail(Workspace workspace, EmailType emailType, String sendEmail) {
|
Map<String, Object> userInviteMap = new HashMap<>();
|
userInviteMap.put("inviteUserName", this.webAppUtil.getLoginUser().getName());
|
userInviteMap.put("workspaceName", workspace.getName());
|
|
// 업무 공간 초대 메일 발송
|
this.systemEmailService.directEmail(new String[]{sendEmail}, emailType, userInviteMap, this.webAppUtil.getLoginUser().getAccount());
|
}
|
|
// 해당 프로젝트역할에 사용자가 이미 소속되어 있는지 확인한다.
|
private List<Long> checkHasProjectRole(String email, List<Long> projectIds) {
|
List<Long> addProjectIds = Lists.newArrayList();
|
boolean projectHasRole = false;
|
User user = this.userService.findByAccount(email);
|
// 가입되어있지 않은 사용자는 체크하지 않는다.
|
if (user == null) {
|
return projectIds;
|
}
|
|
for (Long projectId : projectIds) {
|
Project project = this.projectService.getProject(projectId);
|
|
if (project != null) {
|
// 프로젝트 참여 여부 확인
|
for (ProjectRole projectRole : project.getProjectRoles()) {
|
ProjectRoleUser projectRoleUser = this.projectRoleUserService.findByProjectRoleIdAndUserId(projectRole.getId(), user.getId());
|
if (projectRoleUser != null) {
|
projectHasRole = true;
|
break;
|
}
|
}
|
// 만약 프로젝트 역할에 소속되어 있지 않으면 초대를 하자.
|
if (!projectHasRole) {
|
addProjectIds.add(project.getId());
|
}
|
}
|
}
|
|
return addProjectIds;
|
}
|
|
// 이전에 보낸 초대 정보 삭제
|
@Override
|
@Transactional
|
public void deleteUserInvite(Long workspaceId, List<String> email) {
|
List<UserInvite> userInvites = this.userInviteRepository.findByWorkspaceIdAndEmailIn(workspaceId, email);
|
this.userInviteRepository.deleteAll(userInvites);
|
this.userInviteRepository.flush();
|
}
|
}
|