OWL ITS + 탐지시스템(인터넷 진흥원)
- 이메일 실시간 발송
- 이슈 리스트에서 하위일감 개수 표시
- 이슈 리스트에서 하위 이슈는 안보이게
21개 파일 변경됨
239 ■■■■ 파일 변경됨
src/main/java/kr/wisestone/owl/repository/UserDepartmentRepository.java 2 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/scheduler/Scheduler.java 4 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/service/ProjectRoleService.java 4 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java 41 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/service/impl/ProjectRoleServiceImpl.java 10 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/service/impl/ProjectServiceImpl.java 81 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/service/impl/SystemEmailServiceImpl.java 12 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/vo/IssueVo.java 9 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/resources/mails/issueAddEmail.html 8 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/resources/mails/issueRemoveEmail.html 8 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/resources/mails/issueSendEmail.html 8 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/resources/mails/issueSendEmailTemplate1.html 8 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/resources/mails/issueSendEmailTemplate2.html 8 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/resources/mails/issueSendEmailTemplate3.html 8 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/resources/mybatis/query-template/issue-template.xml 1 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/WEB-INF/i18n/mail_ko_KR.properties 1 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/i18n/ko/global.json 1 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/scripts/app/issue/issueAddTableConfig.controller.js 14 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/scripts/app/issue/issueList.controller.js 7 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/scripts/app/user/userModify.controller.js 1 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/views/user/userModify.html 3 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/repository/UserDepartmentRepository.java
@@ -11,6 +11,8 @@
public interface UserDepartmentRepository extends JpaRepository<UserDepartment, Long> {
    List<UserDepartment> findByUserId(Long userId);
    List<UserDepartment> findByDepartmentId(Long departmentId);
    @Transactional
    void removeByUserId(@Param("userId") Long userId);
}
src/main/java/kr/wisestone/owl/scheduler/Scheduler.java
@@ -89,8 +89,8 @@
        this.systemEmailService.reservationSendEmail();
    }
    //  이메일 실시간 발송 - 10초마다 실행
    @Scheduled(fixedDelay = 10000)
    //  이메일 실시간 발송 - 1분마다 실행
    @Scheduled(cron = "0 * * * * *")
    public void realTimeEmailSystem() {
        //  실시간 이메일 발송
        this.systemEmailService.realTimeSendEmail();
src/main/java/kr/wisestone/owl/service/ProjectRoleService.java
@@ -10,8 +10,8 @@
public interface ProjectRoleService extends AbstractService<ProjectRole, Long, JpaRepository<ProjectRole, Long>>{
    //void addDefaultProjectRole(Project project, List<User> managers, List<User> users);
    void addDefaultProjectRole(Project project, List<User> managers, List<Department> departments);
    void addDefaultProjectRoleUser(Project project, List<User> managers, List<User> users);
    void addDefaultProjectRoleDepartment(Project project, List<User> managers, List<Department> departments);
    ProjectRole findByProjectIdAndRoleType(Long projectId, String roleType);
}
src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java
@@ -373,7 +373,6 @@
        projectRoleUserMap.put("statuses", Lists.newArrayList("02"));   //  관리자 조회
        //  관리자 정보 셋팅
        List<Map<String, Object>> projectRoleUsers = this.projectRoleUserService.findProjectRoleUser(projectRoleUserMap);
        if (projectRoleUsers != null && !projectRoleUsers.isEmpty()) {
            for (Map<String, Object> projectRoleUser : projectRoleUsers) {
                UserVo userVo = ConvertUtil.convertMapToClass(projectRoleUser, UserVo.class);
@@ -407,7 +406,7 @@
            departsBuilder.append(issueDepartment.getDepartment().getDepartmentName());
            departsBuilder.append("\n");
        }
        issueMap.put("departsBuilder", departsBuilder.toString());
        issueMap.put("departments", departsBuilder.toString());
        //  기간
        if (!StringUtils.isEmpty(issue.getStartDate())) {
@@ -558,6 +557,8 @@
        //  Map 에 있는 데이터를 IssueVo 데이터로 변환한다.
        this.setMapToIssueVo(results, issueVos, issueCondition);
        this.setCountDownIssues(results, issueVos);
        resJsonData.put(Constants.RES_KEY_CONTENTS, issueVos);
        resJsonData.put(Constants.REQ_KEY_PAGE_VO, new ResPage(pageable.getPageNumber(), pageable.getPageSize(),
                totalPage, totalCount));
@@ -565,6 +566,27 @@
        //  사용자 시스템 기능 사용 정보 수집
        log.info(ElasticSearchUtil.makeUserActiveHistoryMessage(this.webAppUtil.getLoginUser(), ElasticSearchConstants.ISSUE_FIND));
        return issueVos;
    }
    private void setCountDownIssues(List<Map<String, Object>> results, List<IssueVo> issueVos) {
        for (Map<String, Object> result : results){
            List<Issue> downIssues = this.issueRepository.findByParentIssueId((Long) result.get("id")); //하위이슈 가져오기
            if(downIssues != null && downIssues.size() > 0){ //상위이슈 가지고 있는 애들이 있으면
                for(Issue downIssue : downIssues){
                    Long parentIssueId = downIssue.getParentIssue().getId();
                    int downIssueCount = 1;
                    Issue parentIssue = this.getIssue(parentIssueId);
                    IssueVo parentIssueVo = ConvertUtil.copyProperties(parentIssue, IssueVo.class);
                    parentIssueVo.setDownIssueCount(downIssueCount);
                    for(IssueVo issueVo : issueVos){
                        if(issueVo.getId().equals(parentIssueVo.getId())){
                            issueVo.setDownIssueCount(parentIssueVo.getDownIssueCount());
                        }
                    }
                }
            }
        }
    }
    //  이슈 목록을 조회한다(차트용 - 연관일감포함)
@@ -669,6 +691,17 @@
    private void setMapToIssueVo(List<Map<String, Object>> results, List<IssueVo> issueVos, IssueCondition issueCondition) {
        for (Map<String, Object> result : results) {
            IssueVo issueVo = ConvertUtil.convertMapToClass(result, IssueVo.class);
            /*Issue downIssue = this.getIssue((Long) result.get("id"));
            if(downIssue.getParentIssue() != null){ //상위 이슈가 있으면
                Long parentIssueId = downIssue.getParentIssue().getId();
                int downIssueCount = 1;
                Issue parentIssue = this.getIssue(parentIssueId);
                IssueVo parentIssueVo = ConvertUtil.copyProperties(parentIssue, IssueVo.class);
                parentIssueVo.setDownIssueCount(downIssueCount);
                issueVos.add(parentIssueVo);
            }*/
            issueVos.add(issueVo);
            issueCondition.addIssueIds(String.valueOf(issueVo.getId()));
        }
@@ -1897,15 +1930,11 @@
                        result.put("customField_" + issueCustomFieldValueVo.getCustomFieldVo().getId().toString(), useValue + ", " + issueCustomFieldValueVo.getUseValue());
                    }
                }
                //업체, ISP, 호스팅 추가
                results.add(result);
            } catch (Exception e) {
                log.error("엑셀 다운로드 오류 발생");
            }
        }
        return results;
    }
src/main/java/kr/wisestone/owl/service/impl/ProjectRoleServiceImpl.java
@@ -37,23 +37,23 @@
    }
    //  기본, 관리자 프로젝트 역할을 생성한다.
    /*@Override
    @Override
    @Transactional
    public void addDefaultProjectRole(Project project, List<User> managers, List<User> users) {
    public void addDefaultProjectRoleUser(Project project, List<User> managers, List<User> users) {
        ProjectRole projectRole = this.addProjectRole(project, "기본 프로젝트 역할", ProjectRole.TYPE_DEFAULT, Permission.ROLE_TYPE_PROJECT_JOIN);
        ProjectRole managerProjectRole = this.addProjectRole(project, "프로젝트 관리자 역할", ProjectRole.TYPE_MANAGER, Permission.ROLE_TYPE_PROJECT_MANAGER);
        //  프로젝트 관리자 저장
        this.projectRoleAssociatedUser(managers, managerProjectRole);
        //  프로젝트 일반 사용자 저장
        //this.projectRoleAssociatedUser(users, projectRole);
        this.projectRoleAssociatedUser(users, projectRole);
        this.projectRoleRepository.flush();
    }*/
    }
    //  프로젝트 역할 생성(관리자, 담당부서)
    @Override
    @Transactional
    public void addDefaultProjectRole(Project project, List<User> managers, List<Department> departments) {
    public void addDefaultProjectRoleDepartment(Project project, List<User> managers, List<Department> departments) {
        ProjectRole projectRole = this.addProjectRole(project, "기본 프로젝트 역할", ProjectRole.TYPE_DEFAULT, Permission.ROLE_TYPE_PROJECT_JOIN);
        ProjectRole managerProjectRole = this.addProjectRole(project, "프로젝트 관리자 역할", ProjectRole.TYPE_MANAGER, Permission.ROLE_TYPE_PROJECT_MANAGER);
        //  프로젝트 관리자 저장
src/main/java/kr/wisestone/owl/service/impl/ProjectServiceImpl.java
@@ -48,6 +48,9 @@
    private DepartmentService departmentService;
    @Autowired
    private UserDepartmentService userDepartmentService;
    @Autowired
    private ProjectRoleService projectRoleService;
    @Autowired
@@ -117,7 +120,7 @@
        project.setDefaultYn(true);
        this.projectRepository.saveAndFlush(project);
        //  프로젝트 기본 역할과 관리자 역할을 생성한다. 관리자는 생성한 사용자
        this.projectRoleService.addDefaultProjectRole(project, Lists.newArrayList(user), Lists.newArrayList());
        this.projectRoleService.addDefaultProjectRoleUser(project, Lists.newArrayList(user), Lists.newArrayList());
        //  각 프로젝트의 이슈 번호를 자동으로 생성한다.
        this.issueNumberGeneratorService.generateIssueNumber(project);
@@ -183,16 +186,8 @@
            sendEmails.add(user.getAccount());
        }
        List<Department> departments = Lists.newArrayList();
        //  부서 등록
        for (Long departmentId : projectForm.getDepartmentIds()) {
            Department department = this.departmentService.getDepartment(departmentId);
            departments.add(department);
        }
        //  기본, 관리자 프로젝트 역할을 생성하고 사용자를 해당 역할에 배정한다.
        //this.projectRoleService.addDefaultProjectRole(project, managers, users);
        this.projectRoleService.addDefaultProjectRole(project, managers, departments);
        this.projectRoleService.addDefaultProjectRoleUser(project, managers, users);
        //  프로젝트 참여자들에게 이메일 발송을 예약한다.
        Map<String, Object> projectMap = new HashMap<>();
@@ -220,15 +215,22 @@
        }
        List<Department> departments = Lists.newArrayList();
        List<String> sendEmails = Lists.newArrayList(); //  메일 대상자
        //  부서 등록
        for (Long departmentId : projectForm.getDepartmentIds()) {
            Department department = this.departmentService.getDepartment(departmentId);
            /*List<UserDepartment> userDepartments = this.userDepartmentService.getUserDepartments(departmentId);
            if(userDepartments != null){
                for (UserDepartment userDepartment : userDepartments){
                    User user = this.userService.getUser(userDepartment.getUserId());
                    sendEmails.add(user.getAccount());
                }
            }*/
            departments.add(department);
        }
        //  기본, 관리자 프로젝트 역할을 생성하고 사용자를 해당 역할에 배정한다.
        //this.projectRoleService.addDefaultProjectRole(project, managers, users);
        this.projectRoleService.addDefaultProjectRole(project, managers, departments);
        //  기본, 관리자 프로젝트 역할을 생성하고 담당부서를 해당 역할에 배정한다.
        this.projectRoleService.addDefaultProjectRoleDepartment(project, managers, departments);
        //  프로젝트 참여자들에게 이메일 발송을 예약한다.
        Map<String, Object> projectMap = new HashMap<>();
@@ -243,6 +245,8 @@
        stringBuilder.append(")");
        projectMap.put("projectManagerName", stringBuilder.toString());
        //  프로젝트 담당부서 메일 발송 예약
        this.systemEmailService.reservationEmail(sendEmails.toArray(new String[sendEmails.size()]), EmailType.PROJECT_DEFAULT_INCLUDE, projectMap);
    }
@@ -555,7 +559,9 @@
        this.checkExcludeDepartmentAndRemoveIssueDepartment(project, existDepartmentIds, changeDepartmentIds);
        //  관리자/일반 사용자 변경 내역을 통지한다.
        this.notificationProjectRoleUser(changeProjectManagerNotifications, changeProjectUserNotifications, project);
        //this.notificationProjectRoleUser(changeProjectManagerNotifications, changeProjectUserNotifications, project);
        //  관리자/담당부서 변경 내역을 통지한다.
        this.notificationProjectRoleDepartment(changeProjectManagerNotifications, changeProjectDepartmentNotifications, project);
        return project;
    }
@@ -728,7 +734,7 @@
    }
    //  관리자를 변경한다.
    //  담당부서를 변경한다.
    private Map<String, Object> modifyProjectDepartments(Project project, ProjectForm projectForm) {
        ProjectRole projectRole = this.projectRoleService.findByProjectIdAndRoleType(project.getId(), ProjectRole.TYPE_DEFAULT);
        List<Department> oldDepartment = Lists.newArrayList();
@@ -747,9 +753,9 @@
            department.addProjectRole(projectRole);
        }
        //  제외 대상자 찾기, oldManager 에는 있는데 newManager 에 없으면 제외 대상
        //  제외 대상자 찾기, oldDepartment 에는 있는데 newDepartment 에 없으면 제외 대상
        List<String> excludeDepartments = this.systemEmailService.notificationDepartmentChange(oldDepartment, newDepartment);
        //  참여 대상자 찾기, newManager 에는 있는데 oldManager 에 없으면 초대받은 대상
        //  참여 대상자 찾기, newDepartment 에는 있는데 oldDepartment 에 없으면 초대받은 대상
        List<String> includeDepartments = this.systemEmailService.notificationDepartmentChange(newDepartment, oldDepartment);
        results.put("excludeDepartments", excludeDepartments);
@@ -826,6 +832,47 @@
        this.sendEmailProjectRoleChange(this.checkDuplicationEmails(projectUserIncludeUsers, excludeManagerAndIncludeUser, excludeUserAndIncludeManager), EmailType.PROJECT_DEFAULT_INCLUDE, projectMap);
    }
    //  프로젝트 참여, 제외 통지 정보 체크
    private void notificationProjectRoleDepartment(Map<String, Object> changeProjectManagerNotifications, Map<String, Object> changeProjectDepartmentNotifications, Project project) {
        List<String> projectManagerExcludeUsers = (List<String>) changeProjectManagerNotifications.get("excludeUsers");  //  관리자 제외 사용자
        List<String> projectManagerIncludeUsers = (List<String>) changeProjectManagerNotifications.get("includeUsers");  //  관리자 참여 사용자
        List<String> projectDepartmentExcludeDepartments = (List<String>) changeProjectDepartmentNotifications.get("excludeDepartments");    //  제외된 담당 부서
        List<String> projectDepartmentIncludeDepartments = (List<String>) changeProjectDepartmentNotifications.get("includeDepartments");    //  참여된 담당 부서
        Map<String, Object> projectMap = new HashMap<>();
        projectMap.put("workspaceName", project.getWorkspace().getName());
        projectMap.put("projectName", project.getName());
        projectMap.put("registerDate", DateUtil.convertDateToStr(new Date()));
        Map<String, Object> projectRoleManagerMap = new HashMap<>();
        projectRoleManagerMap.put("id", project.getId());
        projectRoleManagerMap.put("statuses", Lists.newArrayList("02"));   //  관리자 조회
        //  관리자 정보 셋팅
        List<Map<String, Object>> projectRoleManagers = this.projectRoleUserService.findProjectRoleUser(projectRoleManagerMap);
        if (projectRoleManagers != null && !projectRoleManagers.isEmpty()) {
            for (Map<String, Object> projectRoleManager : projectRoleManagers) {
                UserVo userVo = ConvertUtil.convertMapToClass(projectRoleManager, UserVo.class);
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.append(userVo.getName());
                stringBuilder.append("(");
                stringBuilder.append(CommonUtil.decryptAES128(userVo.getAccount()));
                stringBuilder.append(")");
                projectMap.put("projectManagerName", stringBuilder.toString());
            }
        }
        //  관리자 제외 메일
        this.sendEmailProjectRoleChange(projectManagerExcludeUsers, EmailType.PROJECT_MANAGER_EXCLUDE, projectMap);
        //  관리차 참여 메일
        this.sendEmailProjectRoleChange(projectManagerIncludeUsers, EmailType.PROJECT_MANAGER_INCLUDE, projectMap);
        //  담당 부서 제외 메일
        this.sendEmailProjectRoleChange(projectDepartmentExcludeDepartments, EmailType.PROJECT_DEFAULT_EXCLUDE, projectMap);
        //  담당 부서 참여 메일
        this.sendEmailProjectRoleChange(projectDepartmentIncludeDepartments, EmailType.PROJECT_DEFAULT_INCLUDE, projectMap);
    }
    //  중복으로 나가는 메일이 있는지 체크한다.
    private List<String> checkDuplicationEmails(List<String> checkEmails, List<String> excludeManagerAndIncludeUser, List<String> excludeUserAndIncludeManager) {
        List<String> sendProjectManagerExcludeUserEmails = Lists.newArrayList();
src/main/java/kr/wisestone/owl/service/impl/SystemEmailServiceImpl.java
@@ -13,10 +13,12 @@
import kr.wisestone.owl.domain.Department;
import kr.wisestone.owl.domain.SystemEmail;
import kr.wisestone.owl.domain.User;
import kr.wisestone.owl.domain.UserDepartment;
import kr.wisestone.owl.domain.enumType.EmailType;
import kr.wisestone.owl.exception.OwlRuntimeException;
import kr.wisestone.owl.repository.SystemEmailRepository;
import kr.wisestone.owl.service.SystemEmailService;
import kr.wisestone.owl.service.UserDepartmentService;
import kr.wisestone.owl.service.UserService;
import kr.wisestone.owl.util.*;
import org.apache.commons.io.FilenameUtils;
@@ -61,6 +63,9 @@
    @Autowired
    private SpringTemplateEngine springTemplateEngine;
    @Autowired
    private UserDepartmentService userDepartmentService;
    @Override
    protected JpaRepository<SystemEmail, Long> getRepository() {
@@ -332,6 +337,13 @@
            }
            if (excludeCheck) {
                /*List<UserDepartment> userDepartments = this.userDepartmentService.getUserDepartments(department.getId());
                if(userDepartments != null){
                    for (UserDepartment userDepartment : userDepartments){
                        User user = this.userService.getUser(userDepartment.getUserId());
                        results.add(user.getAccount());
                    }
                }*/
                results.add(department.getDepartmentName());
            }
        }
src/main/java/kr/wisestone/owl/vo/IssueVo.java
@@ -52,6 +52,7 @@
    private String modifyByName;    //  변경자 정보 - 이슈 변경 정보 상세 확인에서 사용
    private WorkflowStatusVo workflowStatusVo;
    private IssueVo parentIssueVo;
    private int downIssueCount;
    private List<IssueCompanyVo> issueCompanyVos;
    private List<IssueIspVo> issueIspVos;
@@ -436,4 +437,12 @@
    public void setUsePartnerVos(List<UsePartnerVo> usePartnerVos) {
        this.usePartnerVos = usePartnerVos;
    }
    public int getDownIssueCount() {
        return downIssueCount;
    }
    public void setDownIssueCount(int downIssueCount) {
        this.downIssueCount = downIssueCount;
    }
}
src/main/resources/mails/issueAddEmail.html
@@ -59,11 +59,17 @@
                    </td>
                </tr>
                <tr>
                    <td style="padding: 20px 40px; color: #111; border: 1px solid #e7e7e7; border-left: none; width:50%">
                    <!--<td style="padding: 20px 40px; color: #111; border: 1px solid #e7e7e7; border-left: none; width:50%">
                        <div style="color: #9a9a9a; font-size: 12px; font-weight:bold; margin-bottom: 3px;">
                            <span th:utext="${#messages.msg('issue.add.assignee')}">담당자</span>
                        </div>
                        <div style="font-weight:bold;" th:utext="${assignees}"></div>
                    </td>-->
                    <td style="padding: 20px 40px; color: #111; border: 1px solid #e7e7e7; border-left: none; width:50%">
                        <div style="color: #9a9a9a; font-size: 12px; font-weight:bold; margin-bottom: 3px;">
                            <span th:utext="${#messages.msg('issue.add.department')}">담당부서</span>
                        </div>
                        <div style="font-weight:bold;" th:utext="${departments}"></div>
                    </td>
                    <td style="padding: 20px 40px; color: #111; border: 1px solid #e7e7e7; border-left: none; border-right: none;">
                        <div style="color: #9a9a9a; font-size: 12px; font-weight:bold; margin-bottom: 3px;">
src/main/resources/mails/issueRemoveEmail.html
@@ -59,11 +59,17 @@
                    </td>
                </tr>
                <tr>
                    <td style="padding: 20px 40px; color: #111; border: 1px solid #e7e7e7; border-left: none; width:50%">
                    <!--<td style="padding: 20px 40px; color: #111; border: 1px solid #e7e7e7; border-left: none; width:50%">
                        <div style="color: #9a9a9a; font-size: 12px; font-weight:bold; margin-bottom: 3px;">
                            <span th:utext="${#messages.msg('issue.add.assignee')}">담당자</span>
                        </div>
                        <div style="font-weight:bold;" th:utext="${assignees}"></div>
                    </td>-->
                    <td style="padding: 20px 40px; color: #111; border: 1px solid #e7e7e7; border-left: none; width:50%">
                        <div style="color: #9a9a9a; font-size: 12px; font-weight:bold; margin-bottom: 3px;">
                            <span th:utext="${#messages.msg('issue.add.department')}">담당부서</span>
                        </div>
                        <div style="font-weight:bold;" th:utext="${departments}"></div>
                    </td>
                    <td style="padding: 20px 40px; color: #111; border: 1px solid #e7e7e7; border-left: none; border-right: none;">
                        <div style="color: #9a9a9a; font-size: 12px; font-weight:bold; margin-bottom: 3px;">
src/main/resources/mails/issueSendEmail.html
@@ -59,11 +59,17 @@
                    </td>
                </tr>
                <tr>
                    <td style="padding: 20px 40px; color: #111; border: 1px solid #e7e7e7; border-left: none; width:50%">
                    <!--<td style="padding: 20px 40px; color: #111; border: 1px solid #e7e7e7; border-left: none; width:50%">
                        <div style="color: #9a9a9a; font-size: 12px; font-weight:bold; margin-bottom: 3px;">
                            <span th:utext="${#messages.msg('issue.add.assignee')}">담당자</span>
                        </div>
                        <div style="font-weight:bold;" th:utext="${assignees}"></div>
                    </td>-->
                    <td style="padding: 20px 40px; color: #111; border: 1px solid #e7e7e7; border-left: none; width:50%">
                        <div style="color: #9a9a9a; font-size: 12px; font-weight:bold; margin-bottom: 3px;">
                            <span th:utext="${#messages.msg('issue.add.department')}">담당부서</span>
                        </div>
                        <div style="font-weight:bold;" th:utext="${departments}"></div>
                    </td>
                    <td style="padding: 20px 40px; color: #111; border: 1px solid #e7e7e7; border-left: none; border-right: none;">
                        <div style="color: #9a9a9a; font-size: 12px; font-weight:bold; margin-bottom: 3px;">
src/main/resources/mails/issueSendEmailTemplate1.html
@@ -59,11 +59,17 @@
                    </td>
                </tr>
                <tr>
                    <td style="padding: 20px 40px; color: #111; border: 1px solid #e7e7e7; border-left: none; width:50%">
                    <!--<td style="padding: 20px 40px; color: #111; border: 1px solid #e7e7e7; border-left: none; width:50%">
                        <div style="color: #9a9a9a; font-size: 12px; font-weight:bold; margin-bottom: 3px;">
                            <span th:utext="${#messages.msg('issue.add.assignee')}">담당자</span>
                        </div>
                        <div style="font-weight:bold;" th:utext="${assignees}"></div>
                    </td>-->
                    <td style="padding: 20px 40px; color: #111; border: 1px solid #e7e7e7; border-left: none; width:50%">
                        <div style="color: #9a9a9a; font-size: 12px; font-weight:bold; margin-bottom: 3px;">
                            <span th:utext="${#messages.msg('issue.add.department')}">담당부서</span>
                        </div>
                        <div style="font-weight:bold;" th:utext="${departments}"></div>
                    </td>
                    <td style="padding: 20px 40px; color: #111; border: 1px solid #e7e7e7; border-left: none; border-right: none;">
                        <div style="color: #9a9a9a; font-size: 12px; font-weight:bold; margin-bottom: 3px;">
src/main/resources/mails/issueSendEmailTemplate2.html
@@ -59,11 +59,17 @@
                    </td>
                </tr>
                <tr>
                    <td style="padding: 20px 40px; color: #111; border: 1px solid #e7e7e7; border-left: none; width:50%">
                    <!--<td style="padding: 20px 40px; color: #111; border: 1px solid #e7e7e7; border-left: none; width:50%">
                        <div style="color: #9a9a9a; font-size: 12px; font-weight:bold; margin-bottom: 3px;">
                            <span th:utext="${#messages.msg('issue.add.assignee')}">담당자</span>
                        </div>
                        <div style="font-weight:bold;" th:utext="${assignees}"></div>
                    </td>-->
                    <td style="padding: 20px 40px; color: #111; border: 1px solid #e7e7e7; border-left: none; width:50%">
                        <div style="color: #9a9a9a; font-size: 12px; font-weight:bold; margin-bottom: 3px;">
                            <span th:utext="${#messages.msg('issue.add.department')}">담당부서</span>
                        </div>
                        <div style="font-weight:bold;" th:utext="${departments}"></div>
                    </td>
                    <td style="padding: 20px 40px; color: #111; border: 1px solid #e7e7e7; border-left: none; border-right: none;">
                        <div style="color: #9a9a9a; font-size: 12px; font-weight:bold; margin-bottom: 3px;">
src/main/resources/mails/issueSendEmailTemplate3.html
@@ -59,11 +59,17 @@
                    </td>
                </tr>
                <tr>
                    <td style="padding: 20px 40px; color: #111; border: 1px solid #e7e7e7; border-left: none; width:50%">
                    <!--<td style="padding: 20px 40px; color: #111; border: 1px solid #e7e7e7; border-left: none; width:50%">
                        <div style="color: #9a9a9a; font-size: 12px; font-weight:bold; margin-bottom: 3px;">
                            <span th:utext="${#messages.msg('issue.add.assignee')}">담당자</span>
                        </div>
                        <div style="font-weight:bold;" th:utext="${assignees}"></div>
                    </td>-->
                    <td style="padding: 20px 40px; color: #111; border: 1px solid #e7e7e7; border-left: none; width:50%">
                        <div style="color: #9a9a9a; font-size: 12px; font-weight:bold; margin-bottom: 3px;">
                            <span th:utext="${#messages.msg('issue.add.department')}">담당부서</span>
                        </div>
                        <div style="font-weight:bold;" th:utext="${departments}"></div>
                    </td>
                    <td style="padding: 20px 40px; color: #111; border: 1px solid #e7e7e7; border-left: none; border-right: none;">
                        <div style="color: #9a9a9a; font-size: 12px; font-weight:bold; margin-bottom: 3px;">
src/main/resources/mybatis/query-template/issue-template.xml
@@ -191,6 +191,7 @@
                </foreach>
            </when>
        </choose>
        AND issue.parent_issue_id IS NULL
        AND issue.reverse_index <![CDATA[ < ]]> 0
        AND workspace.id = #{workspaceId}
        GROUP BY issue.id
src/main/webapp/WEB-INF/i18n/mail_ko_KR.properties
@@ -130,6 +130,7 @@
issue.add.issueType=\uC774\uC288 \uC720\uD615
issue.add.issueStatus=\uC774\uC288 \uC0C1\uD0DC
issue.add.assignee=\uB2F4\uB2F9\uC790
issue.add.department=\uB2F4\uB2F9\uBD80\uC11C
issue.add.schedule=\uC77C\uC815
issue.add.priority=\uC911\uC694\uB3C4
issue.add.severity=\uC6B0\uC120 \uC21C\uC704
src/main/webapp/i18n/ko/global.json
@@ -711,6 +711,7 @@
        "changeDate": "변경일",
        "lastChangeDate": "최근 변경일",
        "registrationDate": "등록일",
        "countDownIssue": "하위 이슈",
        "noDate": "기간 없음",
        "fullView": "전체보기",
        "comments": "댓글",
src/main/webapp/scripts/app/issue/issueAddTableConfig.controller.js
@@ -47,22 +47,28 @@
                        position : 4,
                        display : true
                    }, {
                        name : $filter("translate")("common.countDownIssue"), // 하위이슈 카운트
                        key : "COUNT_DOWN_ISSUE",
                        width : "width-100-p",
                        position : 5,
                        display : false
                    }, {
                        name : $filter("translate")("common.register"), // 등록자
                        key : "REGISTER",
                        width : "width-100-p",
                        position : 5,
                        position : 6,
                        display : false
                    }, {
                        name : $filter("translate")("common.period"), // 기간
                        key : "PERIOD",
                        width : "width-140-p",
                        position : 6,
                        position : 7,
                        display : false
                    }, {
                        name : $filter("translate")("common.lastChangeDate"), // 최근 변경일
                        key : "MODIFY_DATE",
                        width : "width-100-p",
                        position : 7,
                        position : 8,
                        display : false
                    }, {
                    }]
@@ -131,7 +137,7 @@
                }
                var content = {
                    delValue : $scope.vm.issueTableConfigs.splice(7,1),
                    delValue : $scope.vm.issueTableConfigs.splice(8,1),
                    issueTableConfigs : JSON.stringify($scope.vm.issueTableConfigs),
                    issueTypeId : $rootScope.getCurrentIssueTypeId()
                };
src/main/webapp/scripts/app/issue/issueList.controller.js
@@ -284,6 +284,13 @@
                                .setDAlign("text-center")
                                .setDName("modifyDate"));
                            break;
                        case "COUNT_DOWN_ISSUE" : //  하위 이슈 개수
                            $scope.vm.tableConfigs.push($tableProvider.config()
                                .setHName("common.countDownIssue")
                                .setHWidth("bold " + issueTableConfig.width)
                                .setDAlign("text-center")
                                .setDName("downIssueCount"));
                            break;
                    }
                    //  사용자 정의 필드 컬럼
src/main/webapp/scripts/app/user/userModify.controller.js
@@ -85,7 +85,6 @@
                            $scope.vm.form.account = result.data.data.account;
                            $scope.vm.form.phone = result.data.data.phone;
                            if(result.data.data.reservationNotifyTime === "realTime"){
                                $scope.vm.form.reservationNotifyTime = "";
                                $scope.vm.form.realtimeNotify = true;
                            }else{
                                $scope.vm.form.reservationNotifyTime = result.data.data.reservationNotifyTime;
src/main/webapp/views/user/userModify.html
@@ -32,7 +32,7 @@
                </div>
            </div>
            <div class="row">
            <div ng-show="" class="row">
                <div class="col-sm-6">
                    <div class="form-group">
                        <label for="userModifyForm3"><span translate="users.setEmailNotificationTime">이메일 알림 시간 설정</span> <code class="highlighter-rouge">*</code></label>
@@ -47,6 +47,7 @@
                               option="Y"
                               ng-disabled="vm.form.realtimeNotify"
                               ng-required="!vm.form.realtimeNotify"
                               placeholder="이메일 알림 시간을 설정해주세요."
                               ng-model="vm.form.reservationNotifyTime">
                    </div>
                </div>