OWL ITS + 탐지시스템(인터넷 진흥원)
wyu
2021-12-09 107ab8e67d089738ad8b3a1ff0efc96680a13cf6
Merge branch 'master' of http://192.168.0.25:9001/r/owl-kisa
1개 파일 추가됨
26개 파일 변경됨
465 ■■■■ 파일 변경됨
src/main/java/kr/wisestone/owl/repository/CompanyFieldRepository.java 1 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/repository/HostingFieldRepository.java 5 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/repository/IspFieldRepository.java 4 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/service/IssueService.java 4 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/service/impl/CompanyFieldServiceImpl.java 44 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/service/impl/HostingFieldServiceImpl.java 28 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/service/impl/IspFieldServiceImpl.java 28 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java 83 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/service/impl/IssueTypeServiceImpl.java 2 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/service/impl/UserServiceImpl.java 8 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/util/ConvertUtil.java 2 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/vo/CompanyFieldVo.java 23 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/web/controller/IssueController.java 24 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/resources/migration/V1_12__Alter_Table.sql 18 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/resources/migration/V1_13__Alter_Table.sql 17 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/i18n/ko/global.json 3 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/index.html 2 ●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/scripts/app/api/apiSetting.controller.js 6 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/scripts/app/hostingField/hostingFieldModify.controller.js 2 ●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/scripts/app/ispField/ispFieldModify.controller.js 3 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/scripts/app/issue/issueAdd.controller.js 18 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/scripts/app/issue/issueList.controller.js 110 ●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/scripts/components/issue/issue.service.js 12 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/scripts/main.js 2 ●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/views/api/apiSettingOverlap.html 2 ●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/views/ispField/ispFieldModify.html 2 ●●● 패치 | 보기 | raw | blame | 히스토리
src/main/webapp/views/issue/issueAdd.html 12 ●●●●● 패치 | 보기 | raw | blame | 히스토리
src/main/java/kr/wisestone/owl/repository/CompanyFieldRepository.java
@@ -8,4 +8,5 @@
    CompanyField findByUrl(@Param("url") String url);
    CompanyField findByUrlAndIdNot(@Param("url") String url, @Param("id") Long id);
}
src/main/java/kr/wisestone/owl/repository/HostingFieldRepository.java
@@ -1,8 +1,13 @@
package kr.wisestone.owl.repository;
import kr.wisestone.owl.domain.CompanyField;
import kr.wisestone.owl.domain.HostingField;
import kr.wisestone.owl.domain.IspField;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.query.Param;
public interface HostingFieldRepository extends JpaRepository<HostingField, Long> {
    HostingField findByUrl(@Param("url") String url);
    HostingField findByUrlAndIdNot(@Param("url") String url, @Param("id") Long id);
}
src/main/java/kr/wisestone/owl/repository/IspFieldRepository.java
@@ -1,8 +1,12 @@
package kr.wisestone.owl.repository;
import kr.wisestone.owl.domain.CompanyField;
import kr.wisestone.owl.domain.IspField;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.query.Param;
public interface IspFieldRepository extends JpaRepository<IspField, Long> {
    IspField findByUrl(@Param("url") String url);
    IspField findByUrlAndIdNot(@Param("url") String url, @Param("id") Long id);
}
src/main/java/kr/wisestone/owl/service/IssueService.java
@@ -54,6 +54,10 @@
    void removeIssues(IssueForm issueForm);
    void removeAllIssues(IssueForm issueForm);
    void removeDownIssues(IssueForm issueForm);
    void modifyIssueStatus(IssueForm issueForm, User user);
    Issue getIssue(Long taskId);
src/main/java/kr/wisestone/owl/service/impl/CompanyFieldServiceImpl.java
@@ -2,6 +2,10 @@
import kr.wisestone.owl.domain.CompanyField;
import kr.wisestone.owl.domain.CustomField;
import kr.wisestone.owl.domain.HostingField;
import kr.wisestone.owl.domain.IspField;
import kr.wisestone.owl.repository.HostingFieldRepository;
import kr.wisestone.owl.repository.IspFieldRepository;
import kr.wisestone.owl.service.UserService;
import kr.wisestone.owl.web.condition.CompanyFieldCondition;
import kr.wisestone.owl.web.form.CompanyFieldForm;
@@ -40,6 +44,12 @@
    private CompanyFieldMapper companyFieldMapper;
    @Autowired
    private IspFieldRepository ispFieldRepository;
    @Autowired
    private HostingFieldRepository hostingFieldRepository;
    @Autowired
    private UserService userService;
    @Autowired
@@ -60,7 +70,7 @@
    @Override
    public CompanyField addCompany(CompanyFieldForm companyFieldForm) {
        //  url 유효성 체크
        this.verifyUrl(companyFieldForm.getUrl());
        this.verifyUrl(companyFieldForm.getUrl(), null);
        CompanyField companyField = ConvertUtil.copyProperties(companyFieldForm, CompanyField.class);
        companyFieldRepository.saveAndFlush(companyField);
@@ -68,12 +78,18 @@
    }
    //  url 유효성 체크
    private void verifyUrl(String url) {
    private void verifyUrl(String url, Long id) {
        if (StringUtils.isEmpty(url)) {
            throw new OwlRuntimeException(
                    this.messageAccessor.getMessage(MsgConstants.COMPANYFIELD_NOT_URL));
        }
        CompanyField companyField = this.companyFieldRepository.findByUrl(url);
        CompanyField companyField;
        if(id == null){
            companyField = this.companyFieldRepository.findByUrl(url);
        } else {
            companyField = this.companyFieldRepository.findByUrlAndIdNot(url,id);
        }
        if (companyField != null) {
            throw new OwlRuntimeException(
@@ -94,7 +110,6 @@
        return this.convertCompanyVoToMap(results, totalCompanyCount, pageable, resJsonData);
    }
    // 업체 상세 조회한다.
    @Override
    public void detailCompany(Map<String, Object> resJsonData, CompanyFieldCondition companyFieldCondition) {
@@ -112,7 +127,7 @@
    @Override
    public void modifyCompany(CompanyFieldForm companyFieldForm) {
        //  url 유효성 체크
        this.verifyUrl(companyFieldForm.getUrl());
        this.verifyUrl(companyFieldForm.getUrl(), companyFieldForm.getId());
        CompanyField companyField = ConvertUtil.copyProperties(companyFieldForm, CompanyField.class);
        companyFieldRepository.saveAndFlush(companyField);
@@ -170,9 +185,28 @@
    //  검색 결과를 CompanyFieldVo 로 변환한다.
    private List<CompanyFieldVo> convertCompanyVoToMap(List<Map<String, Object>> results, Long totalCompanyCount, Pageable pageable, Map<String, Object> resJsonData) {
        List<CompanyFieldVo> companyFieldVos = Lists.newArrayList();
        List<IspFieldVo> ispFieldVos = Lists.newArrayList();
        List<HostingFieldVo> hostingFieldVos = Lists.newArrayList();
        for (Map<String, Object> result : results) {
            CompanyFieldVo companyFieldVo = ConvertUtil.convertMapToClass(result, CompanyFieldVo.class);
            String url = companyFieldVo.getUrl();
            IspField ispField = this.ispFieldRepository.findByUrl(url);
            IspFieldVo ispFieldVo = ConvertUtil.copyProperties(ispField, IspFieldVo.class);
            if(ispFieldVo != null){
                ispFieldVos.add(ispFieldVo);
            }
            companyFieldVo.setIspFieldVos(ispFieldVos);
            HostingField hostingField = this.hostingFieldRepository.findByUrl(url);
            HostingFieldVo hostingFieldVo = ConvertUtil.copyProperties(hostingField, HostingFieldVo.class);
            if(hostingFieldVo != null){
                hostingFieldVos.add(hostingFieldVo);
            }
            companyFieldVo.setHostingFieldVos(hostingFieldVos);
            companyFieldVos.add(companyFieldVo);
        }
src/main/java/kr/wisestone/owl/service/impl/HostingFieldServiceImpl.java
@@ -4,6 +4,7 @@
import kr.wisestone.owl.common.ExcelConditionCheck;
import kr.wisestone.owl.constant.Constants;
import kr.wisestone.owl.constant.MsgConstants;
import kr.wisestone.owl.domain.CompanyField;
import kr.wisestone.owl.domain.HostingField;
import kr.wisestone.owl.exception.OwlRuntimeException;
import kr.wisestone.owl.mapper.HostingFieldMapper;
@@ -18,6 +19,7 @@
import kr.wisestone.owl.web.condition.HostingFieldCondition;
import kr.wisestone.owl.web.form.HostingFieldForm;
import kr.wisestone.owl.web.view.ExcelView;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
@@ -56,9 +58,32 @@
    // Hosting 추가
    @Override
    public HostingField add(HostingFieldForm HostingFieldForm) {
        //  url 유효성 체크
        this.verifyUrl(HostingFieldForm.getUrl(), null);
        HostingField HostingField = ConvertUtil.copyProperties(HostingFieldForm, HostingField.class);
        hostingFieldRepository.saveAndFlush(HostingField);
        return HostingField;
    }
    //  url 유효성 체크
    private void verifyUrl(String url, Long id) {
        if (StringUtils.isEmpty(url)) {
            throw new OwlRuntimeException(
                    this.messageAccessor.getMessage(MsgConstants.COMPANYFIELD_NOT_URL));
        }
        HostingField hostingField;
        if(id == null){
            hostingField = this.hostingFieldRepository.findByUrl(url);
        } else {
            hostingField = this.hostingFieldRepository.findByUrlAndIdNot(url,id);
        }
        if (hostingField != null) {
            throw new OwlRuntimeException(
                    this.messageAccessor.getMessage(MsgConstants.COMPANYFIELD_USED_URL));
        }
    }
    // Hosting 목록을 가져온다.
@@ -91,6 +116,9 @@
    // Hosting 정로를 수정한다.
    @Override
    public void modify(HostingFieldForm HostingFieldForm) {
        //  url 유효성 체크
        this.verifyUrl(HostingFieldForm.getUrl(), HostingFieldForm.getId());
        HostingField HostingField = ConvertUtil.copyProperties(HostingFieldForm, HostingField.class);
        hostingFieldRepository.saveAndFlush(HostingField);
    }
src/main/java/kr/wisestone/owl/service/impl/IspFieldServiceImpl.java
@@ -4,6 +4,7 @@
import kr.wisestone.owl.common.ExcelConditionCheck;
import kr.wisestone.owl.constant.Constants;
import kr.wisestone.owl.constant.MsgConstants;
import kr.wisestone.owl.domain.CompanyField;
import kr.wisestone.owl.domain.IspField;
import kr.wisestone.owl.exception.OwlRuntimeException;
import kr.wisestone.owl.mapper.IspFieldMapper;
@@ -18,6 +19,7 @@
import kr.wisestone.owl.web.condition.IspFieldCondition;
import kr.wisestone.owl.web.form.IspFieldForm;
import kr.wisestone.owl.web.view.ExcelView;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
@@ -56,6 +58,9 @@
    // Isp 추가
    @Override
    public IspField add(IspFieldForm IspFieldForm) {
        //  url 유효성 체크
        this.verifyUrl(IspFieldForm.getUrl(), null);
        IspField IspField = ConvertUtil.copyProperties(IspFieldForm, IspField.class);
        ispFieldRepository.saveAndFlush(IspField);
        return IspField;
@@ -72,6 +77,26 @@
        Long totalIspCount = this.ispFieldMapper.count(condition);
        return this.convertIspVoToMap(results, totalIspCount, pageable, resJsonData);
    }
    //  url 유효성 체크
    private void verifyUrl(String url, Long id) {
        if (StringUtils.isEmpty(url)) {
            throw new OwlRuntimeException(
                    this.messageAccessor.getMessage(MsgConstants.COMPANYFIELD_NOT_URL));
        }
        IspField ispField;
        if(id == null){
            ispField = this.ispFieldRepository.findByUrl(url);
        } else {
            ispField = this.ispFieldRepository.findByUrlAndIdNot(url,id);
        }
        if (ispField != null) {
            throw new OwlRuntimeException(
                    this.messageAccessor.getMessage(MsgConstants.COMPANYFIELD_USED_URL));
        }
    }
@@ -91,6 +116,9 @@
    // Isp 정로를 수정한다.
    @Override
    public void modify(IspFieldForm IspFieldForm) {
        //  url 유효성 체크
        this.verifyUrl(IspFieldForm.getUrl(), IspFieldForm.getId());
        IspField IspField = ConvertUtil.copyProperties(IspFieldForm, IspField.class);
        ispFieldRepository.saveAndFlush(IspField);
    }
src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java
@@ -2096,20 +2096,95 @@
        List<Issue> removeIssues = Lists.newArrayList();
        for (Long issueId : issueForm.getRemoveIds()) {
            //하위이슈 체크
            List<Issue> downIssues = this.issueRepository.findByParentIssueId(issueId);
            if(downIssues != null && downIssues.size() > 0){
                for(Issue downIssue : downIssues){
                    if(downIssue.getParentIssue() != null){
                        downIssue.setParentIssue(null);
                    }
                }
            }
            Issue issue = this.issueRemoves(issueId, user);
            removeIssues.add(issue);
        }
        if (removeIssues.size() > 0) {
            //this.issueRepository.deleteAll(removeIssues);
        }
        /*if (removeIssues.size() > 0) {
            this.issueRepository.deleteAll(removeIssues);
        }*/
        //  사용자 시스템 기능 사용 정보 수집
        log.info(ElasticSearchUtil.makeUserActiveHistoryMessage(this.webAppUtil.getLoginUser(), ElasticSearchConstants.ISSUE_REMOVE));
    }
    //  이슈를 삭제한다.
    @Override
    @Transactional
    public void removeAllIssues(IssueForm issueForm) {
        //  사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다.
        User user = this.webAppUtil.getLoginUserObject();
        this.workspaceService.checkUseWorkspace();
        if (issueForm.getRemoveIds().size() < 1) {
            throw new OwlRuntimeException(
                    this.messageAccessor.getMessage(MsgConstants.ISSUE_REMOVE_NOT_SELECT));
        }
        List<Issue> removeIssues = Lists.newArrayList();
        for (Long issueId : issueForm.getRemoveIds()) {
            //하위이슈 체크
            List<Issue> downIssues = this.issueRepository.findByParentIssueId(issueId);
            if(downIssues != null && downIssues.size() > 0){
                for(Issue downIssue : downIssues){
                    Long downIssueId = downIssue.getId();
                    downIssue = this.issueRemoves(downIssueId, user);
                    removeIssues.add(downIssue);
                }
            }
            Issue issue = this.issueRemoves(issueId, user);
            removeIssues.add(issue);
        }
        //  사용자 시스템 기능 사용 정보 수집
        log.info(ElasticSearchUtil.makeUserActiveHistoryMessage(this.webAppUtil.getLoginUser(), ElasticSearchConstants.ISSUE_REMOVE));
    }
    //  하위이슈를 삭제한다.
    @Override
    @Transactional
    public void removeDownIssues(IssueForm issueForm) {
        //  사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다.
        User user = this.webAppUtil.getLoginUserObject();
        this.workspaceService.checkUseWorkspace();
        if (issueForm.getRemoveIds().size() < 1) {
            throw new OwlRuntimeException(
                    this.messageAccessor.getMessage(MsgConstants.ISSUE_REMOVE_NOT_SELECT));
        }
        List<Issue> removeIssues = Lists.newArrayList();
        Long downIssueId = 0L;
        for (Long issueId : issueForm.getRemoveIds()) {
            //삭제 할 이슈의 하위이슈 체크
            List<Issue> downIssues = this.issueRepository.findByParentIssueId(issueId);
            if(downIssues != null && downIssues.size() > 0){
                for(Issue downIssue : downIssues){
                    downIssueId = downIssue.getId();
                }
            }
            Issue issue = this.issueRemoves(downIssueId, user);
            removeIssues.add(issue);
        }
        //  사용자 시스템 기능 사용 정보 수집
        log.info(ElasticSearchUtil.makeUserActiveHistoryMessage(this.webAppUtil.getLoginUser(), ElasticSearchConstants.ISSUE_REMOVE));
    }
    private Issue issueRemoves(Long issueId, User user) {
        Issue issue = this.getIssue(issueId);
        Issue issue = null;
        if(issueId != null){
            issue = this.getIssue(issueId);
        }
        //  이슈 수정 권한을 갖고 있는지 확인
        this.verifyIssueModifyPermission(issue, user);
src/main/java/kr/wisestone/owl/service/impl/IssueTypeServiceImpl.java
@@ -80,6 +80,8 @@
        for (ProjectType projectType : projectTypes) {
            List<IssueType> issueTypes = Lists.newArrayList();
            Workflow workflow = this.workflowService.findByWorkspaceIdAndProjectType(workspace.getId(), projectType);
            //String projectKey = "BTS";
            //Project project = this.projectService.findByProjectKey(projectKey);
            switch (projectType) {
                case BTS_PROJECT:
src/main/java/kr/wisestone/owl/service/impl/UserServiceImpl.java
@@ -93,6 +93,9 @@
    private ProjectService projectService;
    @Autowired
    private IssueTypeService issueTypeService;
    @Autowired
    private UserSecurityService userSecurityService;
    @Autowired
@@ -258,7 +261,10 @@
                this.userWorkspaceService.addUserWorkspace(user, workspace, true, true);
                //  기본으로 제공되는 프로젝트를 생성한다.
//                this.projectService.addDefaultProject(user, workspace);
                this.projectService.addDefaultProject(user, workspace);
                // 기본으로 제공되는 프로젝트를 이슈 유형의 사용 프로젝트로 설정
                //this.issueTypeService.addDefaultUsedProject(workspace);
                user.setLastWorkspaceId(workspace.getId());
src/main/java/kr/wisestone/owl/util/ConvertUtil.java
@@ -5,6 +5,8 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import kr.wisestone.owl.constant.MsgConstants;
import kr.wisestone.owl.exception.OwlRuntimeException;
import kr.wisestone.owl.vo.CompanyFieldVo;
import kr.wisestone.owl.vo.IspFieldVo;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
src/main/java/kr/wisestone/owl/vo/CompanyFieldVo.java
@@ -1,5 +1,9 @@
package kr.wisestone.owl.vo;
import com.google.common.collect.Lists;
import java.util.List;
public class CompanyFieldVo extends UsePartnerVo {
    private String manager;
@@ -7,6 +11,9 @@
    private String email;
    private String url;
    private String memo;
    private List<IspFieldVo> ispFieldVos = Lists.newArrayList();
    private List<HostingFieldVo> hostingFieldVos = Lists.newArrayList();
    public CompanyFieldVo() {}
@@ -58,4 +65,20 @@
    public void setUrl(String url) {
        this.url = url;
    }
    public List<IspFieldVo> getIspFieldVos() {
        return ispFieldVos;
    }
    public void setIspFieldVos(List<IspFieldVo> ispFieldVos) {
        this.ispFieldVos = ispFieldVos;
    }
    public List<HostingFieldVo> getHostingFieldVos() {
        return hostingFieldVos;
    }
    public void setHostingFieldVos(List<HostingFieldVo> hostingFieldVos) {
        this.hostingFieldVos = hostingFieldVos;
    }
}
src/main/java/kr/wisestone/owl/web/controller/IssueController.java
@@ -137,6 +137,30 @@
        return this.setSuccessMessage(resJsonData);
    }
    //  하위이슈 삭제
    @RequestMapping(value = "/issue/removeAll", produces = MediaType.APPLICATION_JSON_VALUE)
    public
    @ResponseBody
    Map<String, Object> removesAll(@RequestBody Map<String, Map<String, Object>> params) {
        Map<String, Object> resJsonData = new HashMap<>();
        this.issueService.removeAllIssues(IssueForm.make(params.get(Constants.REQ_KEY_CONTENT)));
        return this.setSuccessMessage(resJsonData);
    }
    //  하위이슈 삭제
    /*@RequestMapping(value = "/issue/removeDown", produces = MediaType.APPLICATION_JSON_VALUE)
    public
    @ResponseBody
    Map<String, Object> removesDown(@RequestBody Map<String, Map<String, Object>> params) {
        Map<String, Object> resJsonData = new HashMap<>();
        this.issueService.removeDownIssues(IssueForm.make(params.get(Constants.REQ_KEY_CONTENT)));
        return this.setSuccessMessage(resJsonData);
    }*/
    //  이슈 다중 상태 변경
    @RequestMapping(value = "/issue/modifyMultiIssueStatus", produces = MediaType.APPLICATION_JSON_VALUE)
    public
src/main/resources/migration/V1_12__Alter_Table.sql
@@ -1,17 +1 @@
-- 필수 데이터 여부
ALTER TABLE `custom_field` ADD COLUMN  `required_data` VARCHAR(1) NOT NULL DEFAULT 'N';
-- url 항목 추가
ALTER TABLE `company_field` ADD COLUMN  `url` VARCHAR(255) NULL;
ALTER TABLE `isp_field` ADD COLUMN  `url` VARCHAR(255) NULL;
ALTER TABLE `hosting_field` ADD COLUMN  `url` VARCHAR(255) NULL;
ALTER TABLE `issue_company` ADD COLUMN  `url` VARCHAR(255) NULL;
ALTER TABLE `issue_isp` ADD COLUMN  `url` VARCHAR(255) NULL;
ALTER TABLE `issue_hosting` ADD COLUMN  `url` VARCHAR(255) NULL;
-- 자동 완료 상태 추가
ALTER TABLE `issue_type` ADD COLUMN  `complete_issue_status_id` BIGINT(20) NULL;
-- 업체의 url 컬럼 INDEX 추가
ALTER TABLE `company_field` ADD INDEX `urlIndex`(`url`);
ALTER TABLE `user` ADD INDEX `levelIdIndex`(`level_id`);
src/main/resources/migration/V1_13__Alter_Table.sql
New file
@@ -0,0 +1,17 @@
-- 필수 데이터 여부
ALTER TABLE `custom_field` ADD COLUMN  `required_data` VARCHAR(1) NOT NULL DEFAULT 'N';
-- url 항목 추가
ALTER TABLE `company_field` ADD COLUMN  `url` VARCHAR(255) NULL;
ALTER TABLE `isp_field` ADD COLUMN  `url` VARCHAR(255) NULL;
ALTER TABLE `hosting_field` ADD COLUMN  `url` VARCHAR(255) NULL;
ALTER TABLE `issue_company` ADD COLUMN  `url` VARCHAR(255) NULL;
ALTER TABLE `issue_isp` ADD COLUMN  `url` VARCHAR(255) NULL;
ALTER TABLE `issue_hosting` ADD COLUMN  `url` VARCHAR(255) NULL;
-- 자동 완료 상태 추가
ALTER TABLE `issue_type` ADD COLUMN  `complete_issue_status_id` BIGINT(20) NULL;
-- 업체의 url 컬럼 INDEX 추가
ALTER TABLE `company_field` ADD INDEX `urlIndex`(`url`);
src/main/webapp/i18n/ko/global.json
@@ -218,6 +218,8 @@
        "settingTableDisplay": "테이블 표시 설정",
        "deleteIssue": "이슈 삭제",
        "wantToDeleteSelectIssue": "선택한 이슈를 삭제하겠습니까? \n 사용자가 직접 삭제한 이슈는 어떠한 경우에도 복구가 불가능합니다.",
        "wantToDeleteOnlySelectIssue": "선택한 이슈만 삭제하겠습니까? \n 사용자가 직접 삭제한 이슈는 어떠한 경우에도 복구가 불가능합니다.",
        "wantToDeleteSelectDownIssue": "선택한 이슈의 하위 이슈가 존재 합니다. \n 선택한 이슈와 하위 이슈 모두 삭제하겠습니까? \n 사용자가 직접 삭제한 이슈는 어떠한 경우에도 복구가 불가능합니다.",
        "wantToDeleteSelectRelationIssue": "선택한 연관 이슈를 삭제하겠습니까? \n 사용자가 직접 삭제한 연관 이슈는 복구가 불가능합니다.",
        "failedToSaveFieldConditions": "검색 필드 조건 저장 실패",
        "failedToGetSearchFieldCondition": "검색 필드 조건 가져오기 실패",
@@ -783,6 +785,7 @@
        "createIssue": "이슈 생성",
        "updateIssue": "이슈 변경",
        "deleteIssue": "이슈 삭제",
        "deleteDownIssue": "하위 이슈 삭제",
        "sendMailIssue": "이슈 메일 전송",
        "updateTitle": "제목이 변경되었습니다.",
        "updateContent": "내용이 변경되었습니다.",
src/main/webapp/index.html
@@ -40,7 +40,7 @@
    <link type="text/css" rel="stylesheet" href="custom_components/js-autocomplete-single/js-autocomplete-single.css">
    <link type="text/css" rel="stylesheet" href="custom_components/js-autocomplete-multi/js-autocomplete-multi.css">
    <link type="text/css" rel="stylesheet" href="custom_components/js-html-diff/js-html-diff.css">
    <link type="text/css" rel="stylesheet" href="assets/styles/main.css?version=1.0.0">
    <link type="text/css" rel="stylesheet" href="assets/styles/main.css?version=0.9.0">
    <link type="text/css" rel="stylesheet" href="https://fonts.googleapis.com/css?family=Rubik:300,400,500">
    <!--    google font -->
src/main/webapp/scripts/app/api/apiSetting.controller.js
@@ -140,7 +140,7 @@
                    });
                }
                $scope.$watch("vm.issueTypeId", function (newValue){
                $scope.$watch("vm.issueTypeId", function (newValue, oldValue){
                    if (newValue != null && newValue !== "") {
                        $scope.fn.loadPage();
                    }
@@ -189,7 +189,6 @@
                }
                function onChangeIssueTypeOverlap() {
                    $scope.fn.getIssueStatuses();
                    $scope.fn.getIssueTypeCustomFields();
                    $scope.fn.getOverlapList();
                }
@@ -237,8 +236,6 @@
                            if (result.data.message.status === "success") {
                                SweetAlert.swal($filter("translate")("api.successToApiAutoCompleteIssueStatus"), result.data.message.message, "success"); // "설정 성공"
                                $scope.fn.getIssueTypes();
                                $scope.fn.getIssueStatuses();
                                $scope.fn.getIssueTypeCustomFields();
                            } else {
                                SweetAlert.swal($filter("translate")("api.failedToApiAutoCompleteIssueStatus"), result.data.message.message, "error"); // "설정 실패"
                            }
@@ -403,6 +400,7 @@
                    if (tab === "API_COL_SETTING") {
                        $scope.fn.onChangeColumnSetting();
                    } else if (tab === "API_OVERLAP_SETTING") {
                        $scope.fn.getIssueStatuses();
                        $scope.fn.onChangeIssueTypeOverlap();
                    } else if (tab === "API_SPEC_SETTING") {
                        $scope.fn.onChangeIssueTypeSpec();
src/main/webapp/scripts/app/hostingField/hostingFieldModify.controller.js
@@ -45,7 +45,7 @@
                    var content = {
                        id : parameter.id,
                        code : $rootScope.preventXss($scope.vm.form.name),
                        code : $rootScope.preventXss($scope.vm.form.code),
                        name : $rootScope.preventXss($scope.vm.form.name),
                        manager : $rootScope.preventXss($scope.vm.form.manager),
                        tel : $rootScope.preventXss($scope.vm.form.tel),
src/main/webapp/scripts/app/ispField/ispFieldModify.controller.js
@@ -24,6 +24,7 @@
                        name : "",  //ISP명
                        manager : "",   //담당자
                        tel : "",  //전화번호
                        code : "",
                        email : "",  //이메일
                        url : "", // url
                        memo : ""  //메모(비고)
@@ -44,7 +45,7 @@
                    var content = {
                        id : parameter.id,
                        code : $rootScope.preventXss($scope.vm.form.name),
                        code : $rootScope.preventXss($scope.vm.form.code),
                        name : $rootScope.preventXss($scope.vm.form.name),
                        manager : $rootScope.preventXss($scope.vm.form.manager),
                        tel : $rootScope.preventXss($scope.vm.form.tel),
src/main/webapp/scripts/app/issue/issueAdd.controller.js
@@ -388,6 +388,9 @@
                // 업체정보 결과 값 Event 처리(set)
                $scope.$on("companyFieldEvent", function (event, result) {
                    var ispFieldVos = result[0].ispFieldVos[0];
                    var hostingFieldVos = result[0].hostingFieldVos[0];
                    $scope.vm.companyId = result[0].id;
                    $scope.vm.companyName = result[0].name;
                    $scope.vm.companyManager = result[0].manager;
@@ -396,6 +399,21 @@
                    $scope.vm.companyUrl = result[0].url;
                    $scope.vm.companyMemo = result[0].memo;
                    $scope.vm.ispName = ispFieldVos.name;
                    $scope.vm.ispCode = ispFieldVos.code;
                    $scope.vm.ispManager = ispFieldVos.manager;
                    $scope.vm.ispTel = ispFieldVos.tel;
                    $scope.vm.ispEmail = ispFieldVos.email;
                    $scope.vm.ispUrl = ispFieldVos.url;
                    $scope.vm.ispMemo = ispFieldVos.memo;
                    $scope.vm.hostingName = hostingFieldVos.name;
                    $scope.vm.hostingCode = hostingFieldVos.code;
                    $scope.vm.hostingManager = hostingFieldVos.manager;
                    $scope.vm.hostingTel = hostingFieldVos.tel;
                    $scope.vm.hostingEmail = hostingFieldVos.email;
                    $scope.vm.hostingUrl = hostingFieldVos.url;
                    $scope.vm.hostingMemo = hostingFieldVos.memo;
                });
                // ISP정보 결과 값 Event 처리(set)
src/main/webapp/scripts/app/issue/issueList.controller.js
@@ -689,6 +689,7 @@
                function removes() {
                    var removeIds = [];
                    var removePermission = true;
                    var downIssueIds = false;
                    angular.forEach($scope.vm.responseData.data, function (data) {
                        if (data.checked && data.modifyPermissionCheck) {
@@ -697,6 +698,10 @@
                        if (data.checked && !data.modifyPermissionCheck) {
                            removePermission = false;
                        }
                        if (data.downIssueAllCount > 0){
                            downIssueIds = true;
                        }
                    });
@@ -719,25 +724,23 @@
                        return;
                    }
                    //  삭제 알림
                    SweetAlert.swal({
                            title : $filter("translate")("issue.deleteIssue"), // 이슈 삭제
                            text : $filter("translate")("issue.wantToDeleteSelectIssue"), // 선택한 이슈을 삭제하겠습니까? 삭제된 이슈은 복구할 수 없습니다.
                    if (downIssueIds) {
                        SweetAlert.swal({
                            title : $filter("translate")("common.deleteIssue"), // 이슈 삭제
                            text : $filter("translate")("issue.wantToDeleteSelectDownIssue"), // 하위 이슈가 존재 합니다. 선택한 이슈와 하위 이슈 모두 삭제하겠습니까? 삭제된 이슈는 복구할 수 없습니다.
                            type : "warning",
                            showCancelButton : true,
                            confirmButtonColor : "#DD6B55",
                            confirmButtonText : $filter("translate")("common.delete"), // 삭제
                            cancelButtonText : $filter("translate")("common.cancel"), // 취소
                            closeOnConfirm : false,
                            closeOnCancel : true
                            closeOnCancel : false
                        },
                        function (isConfirm) {
                            SweetAlert.close();
                            if (isConfirm) {
                            if (isConfirm) { //이슈 + 하위 삭제
                                $rootScope.spinner = true;
                                Issue.remove($resourceProvider.getContent(
                                Issue.removeAllIssues($resourceProvider.getContent(
                                    { removeIds : removeIds },
                                    $resourceProvider.getPageContent(0, 0))).then(function (result) {
@@ -745,9 +748,7 @@
                                        $timeout(function () {
                                            SweetAlert.success($filter("translate")("common.deleteSucceeded"), result.data.message.message); // 삭제 성공
                                        }, 100);
                                        $scope.fn.listView();
                                        $scope.fn.getPageList(0);
                                    }
                                    else {
@@ -755,11 +756,96 @@
                                            SweetAlert.error($filter("translate")("common.deleteFailed"), result.data.message.message); // 삭제 실패
                                        }, 100);
                                    }
                                    $rootScope.spinner = false;
                                });
                            } else {//  선택 한 이슈만 삭제
                                //  삭제 알림
                                SweetAlert.swal({
                                        title : $filter("translate")("issue.deleteIssue"), // 이슈 삭제
                                        text : $filter("translate")("issue.wantToDeleteOnlySelectIssue"), // 선택한 이슈만 삭제하겠습니까? 삭제된 이슈은 복구할 수 없습니다.
                                        type : "warning",
                                        showCancelButton : true,
                                        confirmButtonColor : "#DD6B55",
                                        confirmButtonText : $filter("translate")("common.delete"), // 삭제
                                        cancelButtonText : $filter("translate")("common.cancel"), // 취소
                                        closeOnConfirm : false,
                                        closeOnCancel : true
                                    },
                                    function (isConfirm) {
                                        SweetAlert.close();
                                        if (isConfirm) {
                                            $rootScope.spinner = true;
                                            Issue.remove($resourceProvider.getContent(
                                                { removeIds : removeIds },
                                                $resourceProvider.getPageContent(0, 0))).then(function (result) {
                                                if (result.data.message.status === "success") {
                                                    $timeout(function () {
                                                        SweetAlert.success($filter("translate")("common.deleteSucceeded"), result.data.message.message); // 삭제 성공
                                                    }, 100);
                                                    $scope.fn.listView();
                                                    $scope.fn.getPageList(0);
                                                }
                                                else {
                                                    $timeout(function () {
                                                        SweetAlert.error($filter("translate")("common.deleteFailed"), result.data.message.message); // 삭제 실패
                                                    }, 100);
                                                }
                                                $rootScope.spinner = false;
                                            });
                                        }
                                    });
                            }
                        });
                    } else {
                        //  삭제 알림
                        SweetAlert.swal({
                                title : $filter("translate")("issue.deleteIssue"), // 이슈 삭제
                                text : $filter("translate")("issue.wantToDeleteSelectIssue"), // 선택한 이슈을 삭제하겠습니까? 삭제된 이슈은 복구할 수 없습니다.
                                type : "warning",
                                showCancelButton : true,
                                confirmButtonColor : "#DD6B55",
                                confirmButtonText : $filter("translate")("common.delete"), // 삭제
                                cancelButtonText : $filter("translate")("common.cancel"), // 취소
                                closeOnConfirm : false,
                                closeOnCancel : true
                            },
                            function (isConfirm) {
                                SweetAlert.close();
                                if (isConfirm) {
                                    $rootScope.spinner = true;
                                    Issue.remove($resourceProvider.getContent(
                                        { removeIds : removeIds },
                                        $resourceProvider.getPageContent(0, 0))).then(function (result) {
                                        if (result.data.message.status === "success") {
                                            $timeout(function () {
                                                SweetAlert.success($filter("translate")("common.deleteSucceeded"), result.data.message.message); // 삭제 성공
                                            }, 100);
                                            $scope.fn.listView();
                                            $scope.fn.getPageList(0);
                                        }
                                        else {
                                            $timeout(function () {
                                                SweetAlert.error($filter("translate")("common.deleteFailed"), result.data.message.message); // 삭제 실패
                                            }, 100);
                                        }
                                        $rootScope.spinner = false;
                                    });
                                }
                            });
                    }
                }
                //  이슈 목록 테이블 설정
src/main/webapp/scripts/components/issue/issue.service.js
@@ -92,6 +92,18 @@
                    return response;
                });
            },
            removeAllIssues : function (conditions) {
                return $http.post("issue/removeAll", conditions).then(function (response) {
                    $log.debug("하위이슈 삭제 결과 : ", response);
                    return response;
                });
            },
            /*removeDownIssues : function (conditions) {
                return $http.post("issue/removeDown", conditions).then(function (response) {
                    $log.debug("하위이슈 삭제 결과 : ", response);
                    return response;
                });
            },*/
            importExcel : function (conditions) {
                conditions.url = "issue/importExcel";
                return $upload.upload(conditions).then(function (response) {
src/main/webapp/scripts/main.js
@@ -4,7 +4,7 @@
'use strict';
require.config({
    urlArgs : "bust=v1.0.0",
    urlArgs : "bust=v0.9.0",
    paths : {
        'jquery' : '../bower_components/jquery/dist/jquery',
        'jquery-ui' : '../bower_components/jquery-ui/jquery-ui',
src/main/webapp/views/api/apiSettingOverlap.html
@@ -62,7 +62,7 @@
                    class="form-control input-sm issue-select-label"
                    ng-style="{ 'color' : fn.getOptionColor(vm.completeIssueStatuses, vm.completeIssueStatusId) }"
                    ng-model="vm.completeIssueStatusId"
                    ng-change="fn.onChangeIssueTypeSpec()"
                    ng-change="fn.onChangeIssueTypeOverlap()"
                    required>
                <option ng-repeat="issueStatus in vm.completeIssueStatuses"
                        ng-style="{ 'color' : issueStatus.color, 'font-weight': 600 }"
src/main/webapp/views/ispField/ispFieldModify.html
@@ -12,7 +12,7 @@
        <form role="form" name="hostingFieldModifyForm">
            <div class="form-group">
                <label for="hostingFieldModifyForm1">
                    <span translate="hostingField.name">ISP명</span>
                    <span translate="ispField.name">ISP명</span>
                    <code class="highlighter-rouge">*</code>
                </label>
                <input id="hostingFieldModifyForm1"
src/main/webapp/views/issue/issueAdd.html
@@ -487,6 +487,17 @@
                <div class="col-lg-4">
                    <div class="form-group mb10">
                        <label class="issue-label"> <span translate="ispField.name">ISP 이름</span> </label>
                        <!--<input ng-click="show==false"
                               ng-show="show"
                               ng-hide="!show"
                               name="ispName"
                               type="text"
                               class="form-control"
                               kr-input
                               autocomplete="off"
                               ng-model="vm.ispName"
                               ng-maxlength="100"
                               maxlength="100">-->
                        <js-autocomplete-single data-input-name="ispField"
                                                selected-model="vm.form.issueIspFields"
                                                search="vm.ispName"
@@ -609,6 +620,7 @@
                        <label class="issue-label"> <span translate="hostingField.name">호스팅 이름</span> </label>
                        <js-autocomplete-single data-input-name="hostingField"
                                                selected-model="vm.form.issueHostingFields"
                                                ng-model="vm.hostingName"
                                                search="vm.hostingName"
                                                source="fn.getIssueHostingFieldList(vm.hostingName, vm.form.issueHostingFields, vm.autoCompletePage.hostingField.page, fn.getIssueHostingFieldListCallBack)"
                                                page="vm.autoCompletePage.hostingField.page"