OWL ITS + 탐지시스템(인터넷 진흥원)
이민희
2022-01-06 47c5ce77b114324effdce5b3735ed0e661846108
- 이슈 상세페이지 연관,하위 이슈 페이징 처리
2개 파일 추가됨
14개 파일 변경됨
444 ■■■■■ 파일 변경됨
src/main/java/kr/wisestone/owl/constant/Constants.java 2 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/mapper/IssueRelationMapper.java 25 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/repository/IssueRepository.java 5 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/service/GanttService.java 2 ●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/service/IssueService.java 2 ●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/service/impl/GanttServiceImpl.java 4 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java 47 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/util/PageUtil.java 20 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/vo/IssueVo.java 74 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/vo/PageVo.java 62 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/web/controller/GanttController.java 5 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/web/controller/IssueController.java 5 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/resources/mybatis/query-template/issueRelation-template.xml 50 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/scripts/app/issue/issueDetail.controller.js 67 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/scripts/components/utils/resource.provider.js 8 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/views/issue/issueDetail.html 66 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/constant/Constants.java
@@ -5,6 +5,8 @@
 */
public class Constants {
    public static final String REQ_KEY_PAGE_VO = "page";
    public static final String REQ_KEY_RELATION_ISSUE_PAGE_VO = "relPage";
    public static final String REQ_KEY_DOWN_ISSUE_PAGE_VO = "downPage";
    public static final String REQ_KEY_CONTENT = "content";
    public static final String RES_KEY_MESSAGE = "message";
    public static final String RES_KEY_MSG_FAIL = "fail";
src/main/java/kr/wisestone/owl/mapper/IssueRelationMapper.java
New file
@@ -0,0 +1,25 @@
package kr.wisestone.owl.mapper;
import kr.wisestone.owl.domain.IssueRelation;
import kr.wisestone.owl.vo.IssueVo;
import kr.wisestone.owl.web.condition.IssueCondition;
import kr.wisestone.owl.web.condition.IssueCustomFieldValueCondition;
import kr.wisestone.owl.web.condition.IssueTypeCondition;
import kr.wisestone.owl.web.form.IssueForm;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
 * Created by wisestone on 2018-01-17.
 */
@Repository
public interface IssueRelationMapper {
    List<Map<String, Object>> findByIssueId(IssueVo issueVo);
    Long count(IssueVo issueVo);
}
src/main/java/kr/wisestone/owl/repository/IssueRepository.java
@@ -1,6 +1,9 @@
package kr.wisestone.owl.repository;
import kr.wisestone.owl.domain.Issue;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.query.Param;
@@ -8,4 +11,6 @@
public interface IssueRepository extends JpaRepository<Issue, Long> {
    List<Issue> findByParentIssueId(@Param("parentIssueId") Long parentIssueId);
    Page<Issue> findByParentIssueId(@Param("parentIssueId") Long parentIssueId, Pageable pageable);
}
src/main/java/kr/wisestone/owl/service/GanttService.java
@@ -28,7 +28,7 @@
    List<IssueVo> findIssue(Map<String, Object> resJsonData,
                            ProjectCondition projectCondition, Pageable pageable);
    void detailIssue(Map<String, Object> resJsonData, IssueCondition issueCondition);
    void detailIssue(Map<String, Object> resJsonData, IssueCondition issueCondition, Pageable relPageable, Pageable downPageable);
    Issue modifyIssue(IssueForm issueForm, List<MultipartFile> files);
src/main/java/kr/wisestone/owl/service/IssueService.java
@@ -55,7 +55,7 @@
    List<IssueVo> findChartIssue(Map<String, Object> resJsonData,
                                 ProjectCondition condition, Pageable pageable);
    void detailIssue(Map<String, Object> resJsonData, IssueCondition issueCondition);
    void detailIssue(Map<String, Object> resJsonData, IssueCondition issueCondition, Pageable relPageable, Pageable downPageable);
    Issue modifyIssue(IssueForm issueForm, List<MultipartFile> files);
src/main/java/kr/wisestone/owl/service/impl/GanttServiceImpl.java
@@ -95,8 +95,8 @@
    //  이슈 상세 정보를 조회한다.
    @Override
    @Transactional(readOnly = true)
    public void detailIssue(Map<String, Object> resJsonData, IssueCondition issueCondition) {
        issueService.detailIssue(resJsonData, issueCondition);
    public void detailIssue(Map<String, Object> resJsonData, IssueCondition issueCondition, Pageable relPageable, Pageable downPageable) {
        issueService.detailIssue(resJsonData, issueCondition, relPageable, downPageable);
    }
    //  이슈를 수정한다.
src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java
@@ -14,6 +14,7 @@
import kr.wisestone.owl.exception.OwlRuntimeException;
import kr.wisestone.owl.mapper.DepartmentMapper;
import kr.wisestone.owl.mapper.IssueMapper;
import kr.wisestone.owl.mapper.IssueRelationMapper;
import kr.wisestone.owl.mapper.ProjectMapper;
import kr.wisestone.owl.repository.IssueRelationRepository;
import kr.wisestone.owl.repository.IssueRepository;
@@ -33,6 +34,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.messaging.simp.SimpMessagingTemplate;
@@ -194,6 +197,9 @@
    @Autowired
    private WorkflowDepartmentRepository workflowDepartmentRepository;
    @Autowired
    private IssueRelationMapper issueRelationMapper;
    @Override
    protected JpaRepository<Issue, Long> getRepository() {
@@ -1465,13 +1471,19 @@
    //  이슈 상세 정보를 조회한다.
    @Override
    @Transactional(readOnly = true)
    public void detailIssue(Map<String, Object> resJsonData, IssueCondition issueCondition) {
    public void detailIssue(Map<String, Object> resJsonData, IssueCondition issueCondition, Pageable relPageable, Pageable downPageable) {
        IssueVo issueVo = new IssueVo();
        if (issueCondition.getId() != null) {
            Issue issue = this.getIssue(issueCondition.getId());
            issueVo = ConvertUtil.copyProperties(issue, IssueVo.class);
            User user = this.webAppUtil.getLoginUserObject();
            issueVo.setRelPage(relPageable.getPageNumber() * relPageable.getPageSize());
            issueVo.setRelPageSize(relPageable.getPageSize());
            issueVo.setDownPage(downPageable.getPageNumber() * downPageable.getPageSize());
            issueVo.setDownPageSize(downPageable.getPageSize());
            switch (issueCondition.getDeep()) {
                case "01": //  프로젝트, 이슈 유형, 이슈 상태,  우선순위, 중요도, 담당부서, 첨부파일, 사용자 정의 필드 정보를 셋팅한다.
@@ -1488,7 +1500,6 @@
                    this.setIssueCustomFields(issue, issueVo);  //  사용자 정의 필드 값 정보 셋팅
                    this.setRelationIssue(issue, issueVo);        //연관 일감 셋팅
                    this.setDownIssues(issue, issueVo); //하위 이슈 세팅
                    break;
                case "02": //  프로젝트, 이슈 유형, 이슈 상태,  우선순위, 중요도, 담당자, 첨부파일, 사용자 정의 필드 정보, 댓글, 기록을 셋팅한다.
@@ -1498,11 +1509,19 @@
                    break;
            }
        }
        Long relTotalCount = issueVo.getRelTotalCount();
        int relTotalPage = issueVo.getRelTotalPage();
        Long downTotalCount = issueVo.getDownTotalCount();
        int downTotalPage = issueVo.getDownTotalPage();
        //  사용자 시스템 기능 사용 정보 수집
        log.info(ElasticSearchUtil.makeUserActiveHistoryMessage(this.webAppUtil.getLoginUser(), ElasticSearchConstants.ISSUE_DETAIL));
        resJsonData.put(Constants.RES_KEY_CONTENTS, issueVo);
        resJsonData.put(Constants.REQ_KEY_RELATION_ISSUE_PAGE_VO, new ResPage(relPageable.getPageNumber(), relPageable.getPageSize(),
                relTotalPage, relTotalCount));
        resJsonData.put(Constants.REQ_KEY_DOWN_ISSUE_PAGE_VO, new ResPage(downPageable.getPageNumber(), downPageable.getPageSize(),
                downTotalPage, downTotalCount));
    }
    // 테이블 설정 셋팅
@@ -1527,8 +1546,13 @@
    // 하위 이슈 정보를 셋팅한다
    private void setDownIssues(Issue issue, IssueVo issueVo) {
        List<Issue> downIssues = this.issueRepository.findByParentIssueId(issue.getId());
        if(downIssues != null && downIssues.size()>0){
        //List<Issue> downIssues = this.issueRepository.findByParentIssueId(issue.getId());
        int startPage = (int) Math.floor(issueVo.getDownPage()/issueVo.getDownPageSize());
        Pageable pageable = PageRequest.of(startPage, issueVo.getDownPageSize());
        Page<Issue> downIssues = this.issueRepository.findByParentIssueId(issue.getId(), pageable);
        issueVo.setDownTotalPage(downIssues.getTotalPages());
        issueVo.setDownTotalCount(downIssues.getTotalElements());
        if(downIssues != null){
            List<IssueVo> resultList = new ArrayList<>();
            for(Issue downIssue : downIssues){
                IssueVo downIssueVo = ConvertUtil.copyProperties(downIssue, IssueVo.class);
@@ -1628,13 +1652,18 @@
    // 연관 이슈 정보를 셋팅한다
    private void setRelationIssue(Issue issue, IssueVo issueVo) {
        Set<IssueRelation> issueRelations = issue.getIssueRelations();
        if (issue != null && issueVo != null && issueRelations.size() > 0) {
            for (IssueRelation issueRelation : issueRelations) {
                IssueRelationVo issueRelationVo = ConvertUtil.copyProperties(issueRelation, IssueRelationVo.class);
        //Set<IssueRelation> issueRelations = issue.getIssueRelations();
        List<Map<String, Object>> results = this.issueRelationMapper.findByIssueId(issueVo);
        Long totalCount = this.issueRelationMapper.count(issueVo);
                Issue relationIssue = issueRelation.getRelationIssue();
        int totalPage = (int) Math.ceil((totalCount - 1) / issueVo.getRelPageSize()) + 1;
        issueVo.setRelTotalPage(totalPage);
        issueVo.setRelTotalCount(totalCount);
        if (issue != null && issueVo != null && results.size() > 0) {
            for (Map<String, Object> result : results) {
                IssueRelationVo issueRelationVo = ConvertUtil.convertMapToClass(result, IssueRelationVo.class);
                Issue relationIssue = this.findOne(issueRelationVo.getId());
                IssueVo relIssueVo = ConvertUtil.copyProperties(relationIssue, IssueVo.class);
                Project project = this.projectService.getProject(relationIssue.getProject().getId());
                relIssueVo.setProjectId(project.getId());
src/main/java/kr/wisestone/owl/util/PageUtil.java
@@ -28,17 +28,31 @@
        }
        if (pageVo.getPage() == null || pageVo.getPage() < 0) {
            throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.PAGE_NEGATIVE_OR_NULL));
            if (pageVo.getRelPage() == null || pageVo.getRelPage() < 0
                    || pageVo.getDownPage() == null || pageVo.getDownPage() < 0) {
                throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.PAGE_NEGATIVE_OR_NULL));
            }
        }
        if (pageVo.getPageSize() == null || pageVo.getPageSize() < 0) {
            throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.PAGE_SIZE_NEGATIVE_OR_NULL));
            if (pageVo.getRelPageSize() == null || pageVo.getRelPageSize() < 0
                    || pageVo.getDownPageSize() == null || pageVo.getDownPageSize() < 0) {
                throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.PAGE_SIZE_NEGATIVE_OR_NULL));
            }
        }
    }
    public Pageable convertPageable(PageVo pageVo) {
        return PageRequest.of(pageVo.getPage(), pageVo.getPageSize());
    }
    public Pageable convertRelPageable(PageVo pageVo) {
        return PageRequest.of(pageVo.getRelPage(), pageVo.getRelPageSize());
    }
    public Pageable convertDownPageable(PageVo pageVo) {
        return PageRequest.of(pageVo.getDownPage(), pageVo.getDownPageSize());
    }
    public Pageable getDefaultPageable() {
        return PageRequest.of(0, 300);
@@ -49,7 +63,7 @@
    }
    public PageVo getDefaultPageVo() {
        return new PageVo(0, 300);
        return new PageVo(0, 300,0, 300, 0, 300);
    }
    public static Pageable applySort(Pageable page, String field, Sort.Direction direction) {
src/main/java/kr/wisestone/owl/vo/IssueVo.java
@@ -71,6 +71,16 @@
    private String ispName;
    private String hostingName;
    private int relPage;
    private int relPageSize;
    private int relTotalPage;
    private Long relTotalCount;
    private int downPage;
    private int downPageSize;
    private int downTotalPage;
    private Long downTotalCount;
    public IssueVo(){}
    public Long getId() {
@@ -558,4 +568,68 @@
    public void setHostingName(String hostingName) {
        this.hostingName = hostingName;
    }
    public int getRelPageSize() {
        return relPageSize;
    }
    public void setRelPageSize(int relPageSize) {
        this.relPageSize = relPageSize;
    }
    public int getDownPageSize() {
        return downPageSize;
    }
    public void setDownPageSize(int downPageSize) {
        this.downPageSize = downPageSize;
    }
    public int getRelPage() {
        return relPage;
    }
    public void setRelPage(int relPage) {
        this.relPage = relPage;
    }
    public int getDownPage() {
        return downPage;
    }
    public void setDownPage(int downPage) {
        this.downPage = downPage;
    }
    public int getRelTotalPage() {
        return relTotalPage;
    }
    public void setRelTotalPage(int relTotalPage) {
        this.relTotalPage = relTotalPage;
    }
    public int getDownTotalPage() {
        return downTotalPage;
    }
    public void setDownTotalPage(int downTotalPage) {
        this.downTotalPage = downTotalPage;
    }
    public Long getRelTotalCount() {
        return relTotalCount;
    }
    public void setRelTotalCount(Long relTotalCount) {
        this.relTotalCount = relTotalCount;
    }
    public Long getDownTotalCount() {
        return downTotalCount;
    }
    public void setDownTotalCount(Long downTotalCount) {
        this.downTotalCount = downTotalCount;
    }
}
src/main/java/kr/wisestone/owl/vo/PageVo.java
@@ -5,12 +5,24 @@
    private Integer pageSize;
    private Integer totalCount;
    private Integer relPage;
    private Integer relPageSize;
    private Integer relTotalCount;
    private Integer downPage;
    private Integer downPageSize;
    private Integer downTotalCount;
    public PageVo() {
    }
    public PageVo(int page, int pageSize) {
    public PageVo(int page, int pageSize, int relPage, int relPageSize, int downPage, int downPageSize) {
        this.page = page;
        this.pageSize = pageSize;
        this.relPage = relPage;
        this.relPageSize = relPageSize;
        this.downPage = downPage;
        this.downPageSize = downPageSize;
    }
    public Integer getPage() {
@@ -36,4 +48,52 @@
    public void setTotalCount(Integer totalCount) {
        this.totalCount = totalCount;
    }
    public Integer getRelPage() {
        return relPage;
    }
    public void setRelPage(Integer relPage) {
        this.relPage = relPage;
    }
    public Integer getRelPageSize() {
        return relPageSize;
    }
    public void setRelPageSize(Integer relPageSize) {
        this.relPageSize = relPageSize;
    }
    public Integer getRelTotalCount() {
        return relTotalCount;
    }
    public void setRelTotalCount(Integer relTotalCount) {
        this.relTotalCount = relTotalCount;
    }
    public Integer getDownPage() {
        return downPage;
    }
    public void setDownPage(Integer downPage) {
        this.downPage = downPage;
    }
    public Integer getDownPageSize() {
        return downPageSize;
    }
    public void setDownPageSize(Integer downPageSize) {
        this.downPageSize = downPageSize;
    }
    public Integer getDownTotalCount() {
        return downTotalCount;
    }
    public void setDownTotalCount(Integer downTotalCount) {
        this.downTotalCount = downTotalCount;
    }
}
src/main/java/kr/wisestone/owl/web/controller/GanttController.java
@@ -82,7 +82,10 @@
    @ResponseBody
    Map<String, Object> detail(@RequestBody Map<String, Map<String, Object>> params) {
        Map<String, Object> resJsonData = new HashMap<>();
        this.ganttServiceService.detailIssue(resJsonData, IssueCondition.make(params.get(Constants.REQ_KEY_CONTENT)));
        Pageable relPageable = this.pageUtil.convertRelPageable(this.getPageVo(params));
        Pageable downPageable = this.pageUtil.convertDownPageable(this.getPageVo(params));
        this.ganttServiceService.detailIssue(resJsonData, IssueCondition.make(params.get(Constants.REQ_KEY_CONTENT)), relPageable, downPageable);
        return this.setSuccessMessage(resJsonData);
    }
src/main/java/kr/wisestone/owl/web/controller/IssueController.java
@@ -126,7 +126,10 @@
    @ResponseBody
    Map<String, Object> detail(@RequestBody Map<String, Map<String, Object>> params) {
        Map<String, Object> resJsonData = new HashMap<>();
        this.issueService.detailIssue(resJsonData, IssueCondition.make(params.get(Constants.REQ_KEY_CONTENT)));
        Pageable relPageable = this.pageUtil.convertRelPageable(this.getPageVo(params));
        Pageable downPageable = this.pageUtil.convertDownPageable(this.getPageVo(params));
        this.issueService.detailIssue(resJsonData, IssueCondition.make(params.get(Constants.REQ_KEY_CONTENT)), relPageable, downPageable);
        return this.setSuccessMessage(resJsonData);
    }
src/main/resources/mybatis/query-template/issueRelation-template.xml
New file
@@ -0,0 +1,50 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="kr.wisestone.owl.mapper.IssueRelationMapper">
    <resultMap id="issueResultMap" type="kr.wisestone.owl.domain.IssueRelation">
        <result property="id" column="id" />
        <result property="relationIssueType" column="relationIssueType" />
        <result property="registerId" column="registerId" />
        <result property="registerDate" column="registerDate" />
        <result property="modifyId" column="modifyId" />
        <result property="modifyDate" column="modifyDate" />
        <association property="issue" javaType="kr.wisestone.owl.domain.Issue">
            <id property="id" column="issueId" />
        </association>
        <association property="relationIssue" javaType="kr.wisestone.owl.domain.Issue">
            <result property="id" column="relationIssueId" />
        </association>
    </resultMap>
    <select id="findByIssueId" resultType="java.util.HashMap" parameterType="kr.wisestone.owl.vo.IssueVo">
        SELECT
        id AS id,
        issue_id AS issueId,
        relation_issue_id AS relationIssueId,
        relation_issue_type AS relationIssueType,
        register_id AS registerId,
        register_date AS registerDate,
        modify_id AS modifyId,
        modify_date AS modifyDate
        FROM issue_relation
        WHERE 1=1
        <if test="id != null and !id.equals('')">
            AND issue_id = #{id}
        </if>
        <if test="relPage != null and !relPage.equals('') and relPageSize != null and !relPageSize.equals('')">
            limit #{relPageSize} offset #{relPage};
        </if>
    </select>
    <select id="count" resultType="java.lang.Long" parameterType="kr.wisestone.owl.vo.IssueVo">
        SELECT
        COUNT(DISTINCT id)
        FROM issue_relation
        WHERE 1=1
        <if test="id != null and !id.equals('')">
            AND issue_id = #{id}
        </if>
    </select>
</mapper>
src/main/webapp/scripts/app/issue/issueDetail.controller.js
@@ -53,6 +53,7 @@
                $scope.fn.issueBack = issueBack;
                $scope.fn.removeRelationIssue = removeRelationIssue;
                $scope.fn.removeDownIssue = removeDownIssue;
                $scope.fn.changeDetailPageRowCount = changeDetailPageRowCount;    //  페이지 변경
                //  이슈 목록 컨트롤러 vm, fn 상속 중
                $scope.vm.viewer = {};      // 현재 이슈
@@ -89,6 +90,18 @@
                    issueHostingVos : []
                };
                $scope.vm.responseData = {
                    data : []
                };
                $scope.vm.page = {
                    selectedPage : 0,
                    selectedPageRowCount : String(10),
                    selectedRelPage : 0,
                    selectedRelPageRowCount : String(10),
                    selectedDownPage : 0,
                    selectedDownPageRowCount : String(10)
                };
                $scope.vm.issueNameDown = "";       // 선택된 하위 일감 이름
                $scope.vm.autoCompletePageDown = {
@@ -142,6 +155,11 @@
                    }
                }
                //  페이지 변경
                function changeDetailPageRowCount() {
                    $scope.fn.getIssueDetail(0,0);
                }
                function onActivate() {
                    window.scroll(0,240);
                }
@@ -150,7 +168,7 @@
                 // 이슈 목록 데이터 갱신
                $scope.$on("getIssueList", function () {
                    $scope.fn.getIssueDetail();
                    $scope.fn.getIssueDetail(0,0);
                });
                // 하위 이슈 삭제
@@ -213,7 +231,7 @@
                                    $resourceProvider.getPageContent(0, 10))).then(function (result) {
                                    if (result.data.message.status === "success") {
                                        $scope.fn.getIssueDetail();
                                        $scope.fn.getIssueDetail(0,0);
                                    }
                                    else {
                                        SweetAlert.error($filter("translate")("issue.failedToIssueDeleteIssueDown"), result.data.message.message); // "연관일감 삭제 실패"
@@ -286,7 +304,7 @@
                                    $resourceProvider.getPageContent(0, 10))).then(function (result) {
                                    if (result.data.message.status === "success") {
                                        $scope.fn.getIssueDetail();
                                        $scope.fn.getIssueDetail(0,0);
                                    }
                                    else {
                                        SweetAlert.error($filter("translate")("issue.failedToIssueDeleteIssueRelation"), result.data.message.message); // "연관일감 삭제 실패"
@@ -696,7 +714,7 @@
                        $resourceProvider.getPageContent(0, 10))).then(function (result) {
                        if (result.data.message.status === "success") {
                            $scope.fn.getIssueDetail();
                            $scope.fn.getIssueDetail(0,0);
                        }
                        else {
                            SweetAlert.error($filter("translate")("issue.failedToIssueAddIssueRelation"), result.data.message.message); // "연관일감 생성 실패"
@@ -728,7 +746,7 @@
                        $resourceProvider.getPageContent(0, 10))).then(function (result) {
                        if (result.data.message.status === "success") {
                            $scope.fn.getIssueDetail();
                            $scope.fn.getIssueDetail(0,0);
                        }
                        else {
                            SweetAlert.error($filter("translate")("issue.failedToIssueAddIssueDown"), result.data.message.message); // "연관일감 생성 실패"
@@ -754,7 +772,7 @@
                //  });
                $scope.$on("getIssueDetail", function (event, args) {
                    $scope.fn.getIssueDetail();
                    $scope.fn.getIssueDetail(0,0);
                });
                $scope.$watch(function() {
@@ -762,7 +780,7 @@
                }, function() {
                    if ($rootScope.currentDetailIssueId != null) {
                        $scope.vm.viewer.id = $rootScope.currentDetailIssueId;
                        $scope.fn.getIssueDetail();
                        $scope.fn.getIssueDetail(0,0);
                    }
                }, true);
@@ -952,19 +970,50 @@
                }
                //  이슈 상세 정보 조회
                function getIssueDetail() {
                function getIssueDetail(selectedRelPage, selectedDownPage) {
                    $rootScope.spinner = true;
                    if (selectedRelPage < 0) {
                        selectedRelPage = 0;
                    }
                    if (selectedDownPage < 0) {
                        selectedDownPage = 0;
                    }
                    //  현재 페이지 정보
                    var currentRelPage = 0;
                    var currentDownPage = 0;
                    //  쿠키에 선택한 페이지 정보가 없으면 기본 페이지 정보 0 을 저장
                    if (angular.isUndefined(selectedRelPage) || selectedRelPage === "") {
                        currentRelPage = $scope.vm.page.selectedRelPage;
                    }
                    else {
                        currentRelPage = selectedRelPage;
                    }
                    if (angular.isUndefined(selectedDownPage) || selectedDownPage === "") {
                        currentDownPage = $scope.vm.page.selectedDownPage;
                    }
                    else {
                        currentDownPage = selectedDownPage;
                    }
                    //  초기화 해야할 할목을 지정하여 다른 이슈를 클릭할 때 초기화해준다.
                    $scope.fn.initReload();
                    // $scope.fn.getRelTableConfigs();
                    // $scope.fn.getDownTableConfigs();
                    Issue.detail($resourceProvider.getContent(
                        {id : $scope.vm.viewer.id, deep : "02"},
                        $resourceProvider.getPageContent(0, 1))).then(function (result) {
                        $resourceProvider.getSubPageContent(currentRelPage, $scope.vm.page.selectedRelPageRowCount
                            , currentDownPage, $scope.vm.page.selectedDownPageRowCount))
                        ).then(function (result) {
                        if (result.data.message.status === "success") {
                            if (angular.isDefined(result.data.data)) {
                                $scope.vm.page.selectedRelPage = currentRelPage + 1;
                                $scope.vm.page.selectedDownPage = currentDownPage + 1;
                                $scope.vm.responseData = result.data;
                                $scope.vm.viewer = angular.copy(result.data.data);
                                //  이슈 이미지 미리 보기 만들기
                                $scope.fn.makePreviewImages(result.data.data.attachedFileVos);
src/main/webapp/scripts/components/utils/resource.provider.js
@@ -21,6 +21,14 @@
                                    page: page,
                                    pageSize: pageSize
                                };
                            },
                            getSubPageContent: function (relPage, relPageSize, downPage, downPageSize) {
                                return {
                                    relPage: relPage,
                                    relPageSize: relPageSize,
                                    downPage: downPage,
                                    downPageSize: downPageSize
                                };
                            }
                        }
                    }
src/main/webapp/views/issue/issueDetail.html
@@ -491,7 +491,23 @@
                    <!--<div class="col-md-1">
                        <button class="btn btn-darkgrey offset-10" ng-click="fn.addRelationIssueTableConfig()" type="button"><span translate="issue.settingTableDisplay">테이블 표시 설정</span></button>
                    </div>-->
                    <div class="btn-group offset-11">
                    <div class="col-md-3 mt-2">
                        <div class="dataTables_length">
                            <label>
                                <select name="relPageRow"
                                        tabindex="-1"
                                        class="form-control form-control-sm"
                                        ng-change="fn.changeDetailPageRowCount()"
                                        ng-model="vm.page.selectedRelPageRowCount">
                                    <option value="10">10</option>
                                    <option value="50">50</option>
                                    <option value="100">100</option>
                                </select> {{vm.page.selectedRelPage}}-{{vm.responseData.relPage.totalPage}} /
                                {{vm.responseData.relPage.totalCount | number}}<span translate="common.few">건</span>
                            </label>
                        </div>
                    </div>
                    <div class="btn-group" style="left: 975px; padding: 5px">
                        <button aria-expanded="false" aria-haspopup="true"
                                tabindex="-1"
                                class="btn btn-secondary dropdown-toggle"
@@ -545,6 +561,21 @@
                            </button>
                        </div>
                    </div>
                    <div class="controls-below-table text-center">
                        <ul uib-pagination
                            boundary-links-numbes="true"
                            items-per-page="vm.page.selectedRelPageRowCount"
                            total-items="vm.responseData.relPage.totalCount"
                            ng-model="vm.page.selectedRelPage"
                            max-size="10"
                            ng-click="fn.getIssueDetail(vm.page.selectedRelPage - 1, vm.page.selectedDownPage - 1)"
                            class="pagination pagination-sm"
                            previous-text="&lt;"
                            next-text="&gt;"
                            first-text=""
                            last-text="">
                        </ul>
                    </div>
                </div>
                <div class="row mt-30">
@@ -560,7 +591,23 @@
                    <div class="col-sm-1">
                        <button class="btn btn-darkgrey offset-10"  ng-click="fn.addDownIssueTableConfig()" type="button"><span translate="issue.settingTableDisplay">테이블 표시 설정</span></button>
                    </div>-->
                    <div class="btn-group offset-11">
                    <div class="col-md-5 mt-2">
                        <div class="dataTables_length">
                            <label>
                                <select name="downPageRow"
                                        tabindex="-1"
                                        class="form-control form-control-sm"
                                        ng-change="fn.changeDetailPageRowCount()"
                                        ng-model="vm.page.selectedDownPageRowCount">
                                    <option value="10">10</option>
                                    <option value="50">50</option>
                                    <option value="100">100</option>
                                </select> {{vm.page.selectedDownPage}}-{{vm.responseData.downPage.totalPage}} /
                                {{vm.responseData.downPage.totalCount | number}}<span translate="common.few">건</span>
                            </label>
                        </div>
                    </div>
                    <div class="btn-group" style="left: 730px; padding: 5px">
                        <button aria-expanded="false" aria-haspopup="true"
                                tabindex="-1"
                                class="btn btn-secondary dropdown-toggle"
@@ -604,6 +651,21 @@
                            </button>
                        </div>
                    </div>
                    <div class="controls-below-table text-center">
                        <ul uib-pagination
                            boundary-links-numbes="true"
                            items-per-page="vm.page.selectedDownPageRowCount"
                            total-items="vm.responseData.downPage.totalCount"
                            ng-model="vm.page.selectedDownPage"
                            max-size="10"
                            ng-click="fn.getIssueDetail(vm.page.selectedRelPage - 1, vm.page.selectedDownPage - 1)"
                            class="pagination pagination-sm"
                            previous-text="&lt;"
                            next-text="&gt;"
                            first-text=""
                            last-text="">
                        </ul>
                    </div>
                </div>
                <h6 class="todo-content-subheader mt-30" translate="common.content">내용</h6>