| | |
| | | package kr.wisestone.owl.config; |
| | | |
| | | import kr.wisestone.owl.config.security.filter.AjaxSessionExpiredFilter; |
| | | import kr.wisestone.owl.config.security.filter.CustomAuthenticationFilter; |
| | | import kr.wisestone.owl.config.security.handler.AjaxAuthenticationEntryPoint; |
| | | import kr.wisestone.owl.config.security.handler.AjaxAuthenticationFailureHandler; |
| | | import kr.wisestone.owl.config.security.handler.AjaxAuthenticationSuccessHandler; |
| | |
| | | import org.springframework.security.core.session.SessionRegistry; |
| | | import org.springframework.security.crypto.factory.PasswordEncoderFactories; |
| | | import org.springframework.security.crypto.password.PasswordEncoder; |
| | | import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; |
| | | import org.springframework.security.web.session.ConcurrentSessionFilter; |
| | | import org.springframework.session.security.web.authentication.SpringSessionRememberMeServices; |
| | | |
| | |
| | | .antMatchers("/guide/detail").permitAll() |
| | | .antMatchers("/language/change").permitAll() |
| | | .antMatchers("/security/*").permitAll() |
| | | .antMatchers("/api/issue").permitAll() |
| | | .antMatchers("/**/*").authenticated(); |
| | | // http.addFilter(new CustomAuthenticationFilter()); |
| | | // http.addFilterBefore(new CustomAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); |
| | | |
| | | |
| | | http.rememberMe() |
| | |
| | | public static final String USER_NOT_EQUAL_PASSWORD = "USER_NOT_EQUAL_PASSWORD"; // 비밀번호가 맞지 않습니다. |
| | | public static final String USER_NOT_EXIST = "USER_NOT_EXIST"; // 사용자가 존재하지 않습니다. |
| | | public static final String USER_NOT_AUTHORIZED = "USER_NOT_AUTHORIZED"; // 사용자 인증 권한이 없습니다. |
| | | public static final String ERROR_TOKEN = "USER_NOT_AUTHORIZED_TOKEN"; // 유효하지 않은 토큰입니다. |
| | | public static final String USER_EXPIRED_PASSWORD = "USER_EXPIRED_PASSWORD"; // 비밀번호가 만료되었습니다. |
| | | public static final String USER_RETURN_PASSWORD_NOT_PROVIDER_SOCIAL_JOIN_USER = "USER_RETURN_PASSWORD_NOT_PROVIDER_SOCIAL_JOIN_USER"; // 비밀번호 찾기 기능을 소셜 계정 가입 사용자는 사용할 수 없습니다. |
| | | public static final String USER_NOT_USE_ACTIVE_STATUS = "USER_NOT_USE_ACTIVE_STATUS"; // 사용자는 활성 상태가 아니면 로그인할 수 없습니다. |
| | |
| | | public static final String ISP_NOT_EXIST = "ISP_NOT_EXIST"; // ISP가 존재하지 않습니다. |
| | | public static final String ISP_REMOVE_NOT_SELECT = "ISP_REMOVE_NOT_SELECT"; // 삭제할 ISP가 선택되지 않았습니다. |
| | | public static final String PROJECT_NOT_INCLUDE_DEPARTMENT = "PROJECT_NOT_INCLUDE_DEPARTMENT"; // 선택한 부서 중 프로젝트에 참여하고 있지 않은 부서가 있습니다. |
| | | |
| | | public static final String API_PARAMETER_ISSUE_TYPE_ERROR = "API_PARAMETER_ISSUE_TYPE_ERROR"; // api 파라미터 오류(이슈타입) |
| | | public static final String API_PARAMETER_PROJECT_ERROR = "API_PARAMETER_PROJECT_ERROR"; // api 파라미터 오류(프로젝트) |
| | | public static final String API_USER_ERROR = "API_USER_ERROR"; // api 사용자 오류 |
| | | } |
| | |
| | | package kr.wisestone.owl.domain; |
| | | |
| | | import org.hibernate.annotations.DynamicInsert; |
| | | import org.hibernate.annotations.DynamicUpdate; |
| | | |
| | | import javax.persistence.*; |
| | | import java.io.Serializable; |
| | | import java.util.HashSet; |
| | |
| | | * Created by wisestone on 2018-01-03. |
| | | */ |
| | | @Entity |
| | | @DynamicInsert |
| | | @DynamicUpdate |
| | | public class Issue extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | public static final String WORKSPACE_MANAGER = "WORKSPACE_MANAGER"; // 업무 공간 관리자 |
| | |
| | | public static final String REGISTER = "REGISTER"; // 이슈 등록자 |
| | | public static final String ASSIGNEE = "ASSIGNEE"; // 이슈 담당자 |
| | | public static final String DEPARTMENT = "DEPARTMENT"; // 이슈 담당부서 |
| | | |
| | | public static final String IS_API_YES = "Y"; |
| | | public static final String IS_API_NO = "N"; |
| | | |
| | | @Id |
| | | @GeneratedValue(strategy = GenerationType.IDENTITY) |
| | |
| | | private Long issueNumber; |
| | | private String startDate; |
| | | private String completeDate; |
| | | private String isApi; |
| | | |
| | | @ManyToOne(fetch=FetchType.LAZY) |
| | | @JoinColumn(name = "project_id") |
| | |
| | | public void setParentIssue(Issue parentIssue) { |
| | | this.parentIssue = parentIssue; |
| | | } |
| | | |
| | | public String isApi() { |
| | | return isApi; |
| | | } |
| | | |
| | | public void setApi(String api) { |
| | | isApi = api; |
| | | } |
| | | } |
| | |
| | | package kr.wisestone.owl.mapper; |
| | | |
| | | import kr.wisestone.owl.web.condition.IssueCondition; |
| | | import kr.wisestone.owl.web.condition.IssueCustomFieldValueCondition; |
| | | import kr.wisestone.owl.web.form.IssueForm; |
| | | import org.springframework.data.repository.query.Param; |
| | | import org.springframework.stereotype.Repository; |
| | |
| | | public interface IssueMapper { |
| | | List<Map<String, Object>> find(IssueCondition issueCondition); |
| | | |
| | | List<Map<String, Object>> findByCustomFieldValue(IssueCustomFieldValueCondition issueCustomFieldValueCondition); |
| | | |
| | | Long count(IssueCondition issueCondition); |
| | | |
| | | void insertBatch(@Param("issueForms") List<IssueForm> issueForms); |
| | |
| | | package kr.wisestone.owl.service; |
| | | |
| | | import kr.wisestone.owl.domain.ApiToken; |
| | | import kr.wisestone.owl.domain.CompanyField; |
| | | import kr.wisestone.owl.domain.CustomField; |
| | | import kr.wisestone.owl.domain.Event; |
| | | import kr.wisestone.owl.domain.*; |
| | | import kr.wisestone.owl.vo.ApiTokenVo; |
| | | import kr.wisestone.owl.vo.CompanyFieldVo; |
| | | import kr.wisestone.owl.vo.EventVo; |
| | | import kr.wisestone.owl.vo.UserVo; |
| | | import kr.wisestone.owl.web.condition.ApiTokenCondition; |
| | | import kr.wisestone.owl.web.condition.CompanyFieldCondition; |
| | | import kr.wisestone.owl.web.condition.EventCondition; |
| | |
| | | |
| | | ApiTokenVo find(); |
| | | |
| | | UserVo certification(String token); |
| | | |
| | | void remove(ApiTokenForm apiTokenForm); |
| | | } |
| | |
| | | |
| | | List<AttachedFile> addAttachedFile(List<MultipartFile> multipartFiles, Map<String, Object> content); |
| | | |
| | | List<AttachedFile> addAttachedFile(Workspace workspace, Issue issue, List<Map<String, Object>> files); |
| | | |
| | | List<AttachedFileVo> findAttachedFile(Map<String, Object> resJsonData, AttachedFileCondition condition); |
| | | |
| | | List<AttachedFile> findByIssueId(Long issueId); |
| | |
| | | import kr.wisestone.owl.web.form.IssueApiDefaultForm; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | public interface CustomFieldApiOverlapService extends AbstractService<CustomFieldApiOverlap, Long, JpaRepository<CustomFieldApiOverlap, Long>> { |
| | | void find(Map<String, Object> resJsonData, CustomFieldApiOverlapForm form); |
| | | List<CustomFieldApiOverlap> find(Long userId, Long issueTypeId); |
| | | boolean modify(Map<String, Object> resJsonData, CustomFieldApiOverlapForm form); |
| | | } |
| | |
| | | |
| | | public interface IssueApiDefaultService extends AbstractService<IssueApiDefault, Long, JpaRepository<IssueApiDefault, Long>> { |
| | | IssueApiDefault find(Map<String, Object> resJsonData, IssueApiDefaultForm form); |
| | | IssueApiDefault find(IssueApiDefaultForm form); |
| | | boolean modify(Map<String, Object> resJsonData, IssueApiDefaultForm form); |
| | | } |
| | |
| | | import kr.wisestone.owl.domain.enumType.CustomFieldType; |
| | | import kr.wisestone.owl.vo.IssueCustomFieldValueVo; |
| | | import kr.wisestone.owl.web.condition.IssueCondition; |
| | | import kr.wisestone.owl.web.condition.IssueCustomFieldValueCondition; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | | import java.util.List; |
| | |
| | | |
| | | boolean find(IssueCondition condition, Set<String> issueIds); |
| | | |
| | | Map<String, Object> find(IssueCustomFieldValueCondition issueCustomFieldValueCondition); |
| | | |
| | | List<Map<String, Object>> findInIssueIds(IssueCondition issueCondition); |
| | | |
| | | void removeIssueCustomFieldValuesByCustomFieldId(CustomField customField); |
| | |
| | | |
| | | import kr.wisestone.owl.domain.Issue; |
| | | import kr.wisestone.owl.domain.IssueDepartment; |
| | | import kr.wisestone.owl.domain.User; |
| | | import kr.wisestone.owl.domain.Workspace; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | | |
| | |
| | | //담당부서 |
| | | void modifyIssueDepartment(Issue issue, Workspace workspace, List<Long> departmentIds); |
| | | |
| | | void modifyIssueDepartment(Issue issue, User user, Workspace workspace, List<Long> departmentIds); |
| | | |
| | | void insertIssueDepartment(List<Map<String, Long>> issueAssigneeMaps); |
| | | |
| | | void removeIssueDepartment(Long projectId, List<Long> excludeUserIds); |
| | |
| | | |
| | | void addIssueHistory(Issue issue, IssueHistoryType issueHistoryType, String issueChangeDescription); |
| | | |
| | | void addIssueHistory(Issue issue, User user, IssueHistoryType issueHistoryType, String issueChangeDescription); |
| | | |
| | | void makeDescription(StringBuilder description, IssueHistoryType issueHistoryType, String issueChangeDescription); |
| | | |
| | | void makeDescription(User user, StringBuilder description, IssueHistoryType issueHistoryType, String issueChangeDescription); |
| | | |
| | | void findIssueHistory(Map<String, Object> resJsonData, IssueHistoryCondition issueHistoryCondition); |
| | | |
| | | List<IssueHistoryVo> findIssueHistory(Long issueId); |
| | |
| | | |
| | | import kr.wisestone.owl.domain.Issue; |
| | | import kr.wisestone.owl.domain.IssueType; |
| | | import kr.wisestone.owl.domain.User; |
| | | import kr.wisestone.owl.domain.Workflow; |
| | | import kr.wisestone.owl.vo.IssueVo; |
| | | import kr.wisestone.owl.web.condition.IssueCondition; |
| | | import kr.wisestone.owl.web.condition.ProjectCondition; |
| | | import kr.wisestone.owl.web.form.IssueApiForm; |
| | | import kr.wisestone.owl.web.form.IssueForm; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.data.jpa.repository.JpaRepository; |
| | |
| | | |
| | | Issue addIssue(IssueForm issueForm, List<MultipartFile> files); |
| | | |
| | | Issue addIssue(User user, IssueForm issueForm, List<MultipartFile> multipartFiles); |
| | | |
| | | Issue addApiIssue(IssueApiForm issueApiForm); |
| | | |
| | | |
| | | List<IssueVo> findIssue(Map<String, Object> resJsonData, |
| | | IssueCondition condition, Pageable pageable); |
| | | |
| | |
| | | |
| | | void checkUseWorkspace(); |
| | | |
| | | Workspace checkUseWorkspace(User user, Long workspaceId); |
| | | |
| | | ModelAndView checkUseExcelDownload(Model model); |
| | | |
| | | boolean checkUseTraffic(Long fileSize); |
| | |
| | | import io.jsonwebtoken.Jws; |
| | | import io.jsonwebtoken.Jwts; |
| | | import io.jsonwebtoken.SignatureAlgorithm; |
| | | import kr.wisestone.owl.constant.MsgConstants; |
| | | import kr.wisestone.owl.domain.ApiToken; |
| | | import kr.wisestone.owl.domain.User; |
| | | import kr.wisestone.owl.exception.OwlRuntimeException; |
| | | import kr.wisestone.owl.repository.ApiTokenRepository; |
| | | import kr.wisestone.owl.service.ApiTokenService; |
| | | import kr.wisestone.owl.util.ConvertUtil; |
| | |
| | | } |
| | | |
| | | //JWT 복호화 |
| | | public UserVo getUser(String jwt) { |
| | | private UserVo getUserVo(String jwt) { |
| | | |
| | | //결과값 = Claims |
| | | Jws<Claims> claims = decryption(jwt); |
| | | if (claims == null) |
| | | return null; |
| | | |
| | | ObjectMapper objectMapper = new ObjectMapper(); |
| | | //반환 타입은 LinkedHashMap 이다. 이를 User 타입으로 변환하기 위해 ObjectMapper 사용 |
| | | return objectMapper.convertValue(claims.getBody().get(DATA_KEY), UserVo.class); |
| | | } |
| | | |
| | | private Jws<Claims> decryption(String jwt) { |
| | | //결과값 = Claims |
| | | Jws<Claims> claims = null; |
| | | |
| | |
| | | } catch (Exception e) { |
| | | log.debug(e.getMessage(), e); |
| | | } |
| | | |
| | | ObjectMapper objectMapper = new ObjectMapper(); |
| | | //반환 타입은 LinkedHashMap 이다. 이를 User 타입으로 변환하기 위해 ObjectMapper 사용 |
| | | return objectMapper.convertValue(claims.getBody().get(DATA_KEY), UserVo.class); |
| | | return claims; |
| | | } |
| | | |
| | | |
| | | // 토큰 조회 |
| | | @Override |
| | |
| | | return null; |
| | | } |
| | | |
| | | // 토큰 사용자 인증 |
| | | @Override |
| | | public UserVo certification(String token) { |
| | | UserVo userVo = this.getUserVo(token); |
| | | if (userVo != null){ |
| | | return userVo; |
| | | } else { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ERROR_TOKEN)); |
| | | } |
| | | } |
| | | |
| | | // 토큰 삭제 |
| | | @Override |
| | | public void remove(ApiTokenForm apiTokenForm) { |
| | |
| | | } |
| | | } |
| | | |
| | | // 첨부 파일을 등록한다. - API 에서 사용 |
| | | @Override |
| | | @Transactional |
| | | public List<AttachedFile> addAttachedFile(Workspace workspace, Issue issue, List<Map<String, Object>> files) { |
| | | if (workspace == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.WORKSPACE_NOT_EXIST)); |
| | | } |
| | | |
| | | if (issue == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.ISSUE_NOT_EXIST)); |
| | | } |
| | | |
| | | if (files != null && files.size() > 0) { |
| | | List<Map<String, Object>> convertFileMaps = Lists.newArrayList(); |
| | | |
| | | for (Map<String, Object> file : files) { |
| | | String fileName = MapUtil.getString(file, "fileName"); |
| | | String fileStr = MapUtil.getString(file, "file"); |
| | | String contentType = MapUtil.getString(file, "contentType"); |
| | | convertFileMaps.add(CommonUtil.makeFileMap(fileName, fileStr, contentType)); |
| | | } |
| | | |
| | | return this.addAttachedFiles(workspace, convertFileMaps, issue, null, AttachedType.SUMMER); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | // 첨부 파일을 등록한다. - 이슈 생성, 수정에서 사용 |
| | | @Override |
| | | @Transactional |
| | |
| | | } |
| | | |
| | | @Override |
| | | public List<CustomFieldApiOverlap> find(Long userId, Long issueTypeId) { |
| | | return this.customFieldApiOverlapRepository.findByUserIdAndIssueTypeId(userId, issueTypeId); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional |
| | | public void find(Map<String, Object> resJsonData, CustomFieldApiOverlapForm form) { |
| | | UserVo userVo = this.webAppUtil.getLoginUser(); |
| | | List<CustomFieldApiOverlap> customFieldApiOverlaps = this.customFieldApiOverlapRepository.findByUserIdAndIssueTypeId(userVo.getId(), form.getIssueTypeId()); |
| | | List<CustomFieldApiOverlap> customFieldApiOverlaps = this.find(form.getUserId(), form.getIssueTypeId()); |
| | | if (customFieldApiOverlaps != null && customFieldApiOverlaps.size() > 0) { |
| | | |
| | | List<CustomFieldApiOverlapVo> customFieldApiOverlapVos = Lists.newArrayList(); |
| | |
| | | @Override |
| | | @Transactional |
| | | public IssueApiDefault find(Map<String, Object> resJsonData, IssueApiDefaultForm form) { |
| | | UserVo userVo = this.webAppUtil.getLoginUser(); |
| | | List<IssueApiDefault> issueApiDefaults = this.issueApiDefaultRepository.findByUserIdAndIssueTypeId(userVo.getId(), form.getIssueTypeId()); |
| | | if (issueApiDefaults != null && issueApiDefaults.size() > 0) { |
| | | IssueApiDefault issueApiDefault = issueApiDefaults.get(0); |
| | | form.setUserId(this.webAppUtil.getLoginId()); |
| | | IssueApiDefault issueApiDefault = this.find(form); |
| | | if (issueApiDefault != null) { |
| | | IssueApiDefaultVo issueApiDefaultVo = ConvertUtil.copyProperties(issueApiDefault, IssueApiDefaultVo.class); |
| | | Project project = issueApiDefault.getProject(); |
| | | if (project != null) { |
| | |
| | | } |
| | | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, issueApiDefaultVo); |
| | | } |
| | | return issueApiDefault; |
| | | } |
| | | |
| | | @Override |
| | | public IssueApiDefault find(IssueApiDefaultForm form) { |
| | | if (form.getUserId() != null && form.getIssueTypeId() != null) { |
| | | List<IssueApiDefault> issueApiDefaults = this.issueApiDefaultRepository.findByUserIdAndIssueTypeId(form.getUserId(), form.getIssueTypeId()); |
| | | if (issueApiDefaults != null && issueApiDefaults.size() > 0) { |
| | | return issueApiDefaults.get(0); |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | |
| | | return customFieldSearch; |
| | | } |
| | | |
| | | @Override |
| | | public Map<String, Object> find(IssueCustomFieldValueCondition issueCustomFieldValueCondition) { |
| | | if (issueCustomFieldValueCondition.getUseValues().size() > 0 || !StringUtils.isEmpty(issueCustomFieldValueCondition.getUseValue())) { |
| | | issueCustomFieldValueCondition.setWorkspaceId(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | |
| | | // 사용자 정의 필드 값 검색 시작 |
| | | Map<String, Object> result = new HashMap<>(); |
| | | |
| | | switch (CustomFieldType.valueOf(issueCustomFieldValueCondition.getCustomFieldType())) { |
| | | case INPUT: |
| | | result = this.issueCustomFieldValueMapper.findLikeUseValue(issueCustomFieldValueCondition); |
| | | break; |
| | | case MULTI_SELECT: |
| | | case SINGLE_SELECT: |
| | | result = this.issueCustomFieldValueMapper.findByUseValue(issueCustomFieldValueCondition); |
| | | break; |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | // 이슈에서 저장한 사용자 정의 필드 값을 조회한다. |
| | | @Override |
| | | @Transactional(readOnly = true) |
| | |
| | | package kr.wisestone.owl.service.impl; |
| | | |
| | | import com.google.common.collect.Lists; |
| | | import kr.wisestone.owl.domain.Issue; |
| | | import kr.wisestone.owl.domain.IssueDepartment; |
| | | import kr.wisestone.owl.domain.IssueUser; |
| | | import kr.wisestone.owl.domain.Workspace; |
| | | import kr.wisestone.owl.domain.*; |
| | | import kr.wisestone.owl.mapper.IssueDepartmentMapper; |
| | | import kr.wisestone.owl.mapper.IssueUserMapper; |
| | | import kr.wisestone.owl.repository.IssueDepartmentRepository; |
| | |
| | | @Override |
| | | @Transactional |
| | | public void modifyIssueDepartment(Issue issue, Workspace workspace, List<Long> departmentIds) { |
| | | User user = this.webAppUtil.getLoginUserObject(); |
| | | modifyIssueDepartment(issue, user, workspace, departmentIds); |
| | | } |
| | | |
| | | // 이슈 담당부서를 변경한다. |
| | | @Override |
| | | @Transactional |
| | | public void modifyIssueDepartment(Issue issue, User user, Workspace workspace, List<Long> departmentIds) { |
| | | List<Long> oldDepartmentIds = Lists.newArrayList(); |
| | | |
| | | // 이전 담당 부서 |
| | |
| | | issueAssigneeMap.put("departmentId", departmentId); //담당부서 |
| | | issueAssigneeMap.put("issueId", issue.getId()); |
| | | issueAssigneeMap.put("workspaceId", workspace.getId()); |
| | | issueAssigneeMap.put("registerId", this.webAppUtil.getLoginId()); |
| | | issueAssigneeMap.put("modifyId", this.webAppUtil.getLoginId()); |
| | | issueAssigneeMap.put("registerId", user.getId()); |
| | | issueAssigneeMap.put("modifyId", user.getId()); |
| | | addIssueAssigneeMaps.add(issueAssigneeMap); |
| | | } |
| | | |
| | |
| | | @Override |
| | | @Transactional |
| | | public void addIssueHistory(Issue issue, IssueHistoryType issueHistoryType, String issueChangeDescription) { |
| | | User user = this.webAppUtil.getLoginUserObject(); |
| | | addIssueHistory(issue, user, issueHistoryType, issueChangeDescription); |
| | | } |
| | | |
| | | // 이력 생성 |
| | | @Override |
| | | @Transactional |
| | | public void addIssueHistory(Issue issue, User user, IssueHistoryType issueHistoryType, String issueChangeDescription) { |
| | | IssueHistory issueHistory = new IssueHistory(); |
| | | issueHistory.setIssue(issue); |
| | | issueHistory.setProject(issue.getProject()); |
| | | issueHistory.setIssueHistoryType(issueHistoryType); |
| | | StringBuilder description = new StringBuilder(); |
| | | // 이력 정보를 만들어 낸다. |
| | | this.makeDescription(description, issueHistoryType, issueChangeDescription); |
| | | |
| | | this.makeDescription(user, description, issueHistoryType, issueChangeDescription); |
| | | issueHistory.setDescription(description.toString()); |
| | | |
| | | this.issueHistoryRepository.saveAndFlush(issueHistory); |
| | |
| | | // 이력 정보를 만들어 낸다. |
| | | @Override |
| | | public void makeDescription(StringBuilder description, IssueHistoryType issueHistoryType, String issueChangeDescription) { |
| | | User user = this.webAppUtil.getLoginUserObject(); |
| | | makeDescription(user, description, issueHistoryType, issueChangeDescription); |
| | | } |
| | | |
| | | // 이력 정보를 만들어 낸다. |
| | | @Override |
| | | public void makeDescription(User user, StringBuilder description, IssueHistoryType issueHistoryType, String issueChangeDescription) { |
| | | description.append("<div class=\"activity-text\">"); |
| | | |
| | | // 생성, 수정, 삭제에 대해 기록을 남긴다. |
| | |
| | | description.append("<span class='activity-timestamp'>"); |
| | | description.append(DateUtil.convertDateToStr(new Date())); |
| | | description.append(" ("); |
| | | description.append(this.webAppUtil.getLoginUser().getName()); |
| | | description.append(user.getName()); |
| | | description.append(" - "); |
| | | description.append(CommonUtil.decryptAES128(this.webAppUtil.getLoginUser().getAccount())); |
| | | description.append(CommonUtil.decryptAES128(user.getAccount())); |
| | | description.append(")"); |
| | | description.append("</span></h6>"); |
| | | break; |
| | |
| | | description.append(DateUtil.convertDateToStr(new Date())); |
| | | description.append(" ("); |
| | | |
| | | if (this.webAppUtil.getLoginUser() != null) { |
| | | description.append(this.webAppUtil.getLoginUser().getName()); |
| | | if (user != null) { |
| | | description.append(user.getName()); |
| | | description.append(" - "); |
| | | description.append(CommonUtil.decryptAES128(this.webAppUtil.getLoginUser().getAccount())); |
| | | description.append(CommonUtil.decryptAES128(user.getAccount())); |
| | | } |
| | | else { |
| | | description.append("OWL-ITS-SYSTEM"); |
| | |
| | | description.append("<span class=\"activity-timestamp\">"); |
| | | description.append(DateUtil.convertDateToStr(new Date())); |
| | | description.append(" ("); |
| | | description.append(this.webAppUtil.getLoginUser().getName()); |
| | | description.append(user.getName()); |
| | | description.append(" - "); |
| | | description.append(CommonUtil.decryptAES128(this.webAppUtil.getLoginUser().getAccount())); |
| | | description.append(CommonUtil.decryptAES128(user.getAccount())); |
| | | description.append(")"); |
| | | description.append("</span></h6>"); |
| | | break; |
| | |
| | | import kr.wisestone.owl.util.DateUtil; |
| | | import kr.wisestone.owl.vo.*; |
| | | import kr.wisestone.owl.web.condition.IssueCondition; |
| | | import kr.wisestone.owl.web.condition.IssueCustomFieldValueCondition; |
| | | import kr.wisestone.owl.web.condition.IssueTypeCustomFieldCondition; |
| | | import kr.wisestone.owl.web.condition.ProjectCondition; |
| | | import kr.wisestone.owl.web.form.IssueCommentForm; |
| | | import kr.wisestone.owl.web.form.IssueForm; |
| | | import kr.wisestone.owl.web.form.*; |
| | | import kr.wisestone.owl.web.view.ExcelView; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.apache.commons.lang3.time.StopWatch; |
| | |
| | | |
| | | @Autowired |
| | | private SeverityService severityService; |
| | | |
| | | @Autowired |
| | | private CustomFieldApiOverlapService customFieldApiOverlapService; |
| | | |
| | | @Autowired |
| | | private IssueApiDefaultService issueApiDefaultService; |
| | | |
| | | @Autowired |
| | | private ApiTokenService apiTokenService; |
| | | |
| | | @Autowired |
| | | private CompanyFieldService companyFieldService; |
| | |
| | | } |
| | | |
| | | |
| | | |
| | | // API 를 통해 이슈 추가. |
| | | @Override |
| | | @Transactional |
| | | public Issue addApiIssue(IssueApiForm issueApiForm) { |
| | | if (issueApiForm.getIssueTypeId() == null) { |
| | | throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.API_PARAMETER_ISSUE_TYPE_ERROR)); |
| | | } |
| | | |
| | | IssueForm issueForm = ConvertUtil.copyProperties(issueApiForm, IssueForm.class); |
| | | // issueForm.setFiles(issueApiForm.getFiles()); |
| | | IssueType issueType = this.issueTypeService.getIssueType(issueApiForm.getIssueTypeId()); |
| | | if (issueType == null){ |
| | | throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.API_PARAMETER_ISSUE_TYPE_ERROR)); |
| | | } |
| | | |
| | | // 프로젝트 입력 |
| | | Project project = issueType.getProject(); |
| | | if (project == null){ |
| | | throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.API_PARAMETER_PROJECT_ERROR)); |
| | | } |
| | | issueForm.setProjectId(project.getId()); |
| | | |
| | | // 토큰으로 유저 정보 가져오기 |
| | | String token = issueApiForm.getToken(); |
| | | UserVo userVo = this.apiTokenService.certification(token); |
| | | |
| | | // 해당 유저 정보가 현재 db에 있는지 확인 |
| | | User user = this.userService.getUser(userVo.getId()); |
| | | if (user != null) { |
| | | |
| | | // 기본값 입력하기 |
| | | IssueApiDefaultForm issueApiDefaultForm = new IssueApiDefaultForm(); |
| | | issueApiDefaultForm.setUserId(user.getId()); |
| | | issueApiDefaultForm.setIssueTypeId(issueForm.getIssueTypeId()); |
| | | IssueApiDefault issueApiDefault = this.issueApiDefaultService.find(issueApiDefaultForm); |
| | | if (issueApiDefault != null) { |
| | | ConvertUtil.copyProperties(issueApiDefault, issueForm); |
| | | issueForm.setPriorityId(issueApiDefault.getPriority().getId()); |
| | | issueForm.setSeverityId(issueApiDefault.getSeverity().getId()); |
| | | } |
| | | |
| | | // 중복 값 하위 이슈로 처리하기 |
| | | CustomFieldApiOverlapForm customFieldApiOverlapForm = new CustomFieldApiOverlapForm(); |
| | | customFieldApiOverlapForm.setUserId(user.getId()); |
| | | customFieldApiOverlapForm.setIssueTypeId(issueForm.getIssueTypeId()); |
| | | |
| | | IssueVo issueVo = this.findIssue(issueApiForm, user.getId()); |
| | | if (issueVo != null) { |
| | | issueForm.setParentIssueId(issueVo.getId()); |
| | | } |
| | | |
| | | issueForm.setIsApi(Issue.IS_API_YES); |
| | | |
| | | // 사용자 정의 필드 설정 |
| | | issueForm.setIssueCustomFields(issueApiForm.getCustomFieldValues()); |
| | | |
| | | // api 입력값 적용 |
| | | ConvertUtil.copyProperties(issueApiForm, issueForm); |
| | | |
| | | return addIssue(user, issueForm, issueApiForm.getMultipartFiles()); |
| | | } else { |
| | | throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.API_USER_ERROR)); |
| | | } |
| | | } |
| | | |
| | | // 중복된 상위 이슈 검색 |
| | | private IssueVo findIssue(IssueApiForm issueApiForm, Long userId) { |
| | | IssueCustomFieldValueCondition issueCustomFieldValueCondition = new IssueCustomFieldValueCondition(); |
| | | |
| | | List<CustomFieldApiOverlap> customFieldApiOverlaps = this.customFieldApiOverlapService.find(userId, issueApiForm.getIssueTypeId()); |
| | | if (customFieldApiOverlaps != null && customFieldApiOverlaps.size() > 0) { |
| | | for (CustomFieldApiOverlap customFieldApiOverlap : customFieldApiOverlaps) { |
| | | for (IssueCustomFieldValueForm issueCustomFieldValue : issueApiForm.getIssueCustomFieldValues()) { |
| | | if (customFieldApiOverlap.getCustomField().getId().equals(issueCustomFieldValue.getCustomFieldId())) { |
| | | issueCustomFieldValueCondition.addUseValues(issueCustomFieldValue.getUseValue()); |
| | | } |
| | | } |
| | | } |
| | | List<Map<String, Object>> results = this.issueMapper.findByCustomFieldValue(issueCustomFieldValueCondition); |
| | | if (results != null && results.size() > 0) { |
| | | IssueVo issueVo = new IssueVo(); |
| | | ConvertUtil.convertMapToObject(results.get(0), issueVo); |
| | | return issueVo; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | // 이슈를 생성한다. |
| | | @Override |
| | | @Transactional |
| | | public Issue addIssue(IssueForm issueForm, List<MultipartFile> multipartFiles) { |
| | | User user = this.webAppUtil.getLoginUserObject(); |
| | | return addIssue(user, issueForm, multipartFiles); |
| | | } |
| | | |
| | | // 이슈를 생성한다. |
| | | @Override |
| | | @Transactional |
| | | public Issue addIssue(User user, IssueForm issueForm, List<MultipartFile> multipartFiles) { |
| | | // 사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다. |
| | | this.workspaceService.checkUseWorkspace(); |
| | | Workspace workspace = this.workspaceService.checkUseWorkspace(user, user.getLastWorkspaceId()); |
| | | // 프로젝트 유효성 체크 |
| | | Project project = this.projectService.getProject(issueForm.getProjectId()); |
| | | // 이슈 유형 유효성 체크 |
| | |
| | | |
| | | issue.setIssueNumber(this.issueNumberGeneratorService.generateIssueNumber(project)); // 각 프로젝트의 고유 이슈 번호 생성 |
| | | |
| | | this.issueRepository.saveAndFlush(issue); |
| | | issue = this.issueRepository.saveAndFlush(issue); |
| | | |
| | | issue.setReverseIndex(issue.getId() * -1); // 쿼리 속도 개선을 위해 리버스 인덱스 생성 |
| | | // 담당자 지정 |
| | |
| | | // HOSTING 정보 저장 |
| | | this.issueHostingService.modifyIssueHostingField(issue, issueForm.getIssueHostingFields()); |
| | | |
| | | |
| | | // 첨부 파일 저장 |
| | | // multipartFile 을 file Map List 객체로 변경한다. |
| | | List<Map<String, Object>> convertFileMaps = this.convertMultipartFileToFile(multipartFiles); |
| | | // 첨부 파일 저장 |
| | | this.attachedFileService.addAttachedFile(convertFileMaps, issue, this.webAppUtil.getLoginUser().getAccount()); |
| | | this.attachedFileService.addAttachedFile(convertFileMaps, issue, user.getAccount()); |
| | | |
| | | // 텍스트 에디터에 첨부한 파일을 이슈와 연결 |
| | | this.checkNotHaveIssueIdAttachedFile(issue, issueForm); |
| | | // 사용자 정의 필드 저장 |
| | | this.issueCustomFieldValueService.modifyIssueCustomFieldValue(issue, issueForm.getIssueCustomFields()); |
| | | // 이슈 이력 생성 |
| | | this.issueHistoryService.addIssueHistory(issue, IssueHistoryType.ADD, null); |
| | | this.issueHistoryService.addIssueHistory(issue, user, IssueHistoryType.ADD, null); |
| | | // 이슈 위험 관리 생성 |
| | | this.issueRiskService.addIssueRisk(issue, project.getWorkspace()); |
| | | // 영속성 컨텍스트 비우기 |
| | | this.clear(); |
| | | // 이슈 생성, 삭제시 예약 이메일에 등록해놓는다. |
| | | this.reservationIssueEmail(issue.getId(), EmailType.ISSUE_ADD); |
| | | this.reservationIssueEmail(issue, EmailType.ISSUE_ADD); |
| | | // 사용자 시스템 기능 사용 정보 수집 |
| | | log.info(ElasticSearchUtil.makeUserActiveHistoryMessage(this.webAppUtil.getLoginUser(), ElasticSearchConstants.ISSUE_ADD)); |
| | | |
| | | UserVo userVo = ConvertUtil.copyProperties(user, UserVo.class); |
| | | log.info(ElasticSearchUtil.makeUserActiveHistoryMessage(userVo, ElasticSearchConstants.ISSUE_ADD)); |
| | | |
| | | return issue; |
| | | } |
| | | |
| | | // 이슈 생성, 삭제시 예약 이메일에 등록해놓는다. |
| | | private void reservationIssueEmail(Long id, EmailType emailType) { |
| | | Issue issue = this.getIssue(id); |
| | | |
| | | private void reservationIssueEmail(Issue issue, EmailType emailType) { |
| | | Map<String, Object> issueMap = new HashMap<>(); |
| | | // 이슈 정보를 이메일 전송에 사용하기 위해 Map 형태로 변환한다. |
| | | this.makeIssueMapToIssue(issue, issueMap); |
| | |
| | | private List<Map<String, Object>> convertMultipartFileToFile(List<MultipartFile> multipartFiles) { |
| | | List<Map<String, Object>> convertFileMaps = Lists.newArrayList(); |
| | | |
| | | if (multipartFiles != null && multipartFiles.size() > 0) { |
| | | for (MultipartFile multipartFile : multipartFiles) { |
| | | try { |
| | | Map<String, Object> fileMap = CommonUtil.makeFileMap(multipartFile); |
| | | convertFileMaps.add(fileMap); |
| | | } catch (Exception e) { |
| | | log.debug("multipartFile -> file 변환 오류" + e.getMessage()); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | // 이슈 생성, 삭제시 예약 이메일에 등록해놓는다. |
| | | this.reservationIssueEmail(issue.getId(), EmailType.ISSUE_REMOVE); |
| | | this.reservationIssueEmail(issue, EmailType.ISSUE_REMOVE); |
| | | // 이슈 삭제 |
| | | this.issueRepository.delete(issue); |
| | | |
| | |
| | | // 사용자 시스템 기능 사용 정보 수집 |
| | | log.info(ElasticSearchUtil.makeUserActiveHistoryMessage(this.webAppUtil.getLoginUser(), ElasticSearchConstants.ISSUE_ANOTHER_USER_SEND_EMAIL)); |
| | | |
| | | this.systemEmailService.directEmail(issueForm.getSendEmails().toArray(new String[issueForm.getSendEmails().size()]), EmailType.ISSUE_SEND, issueMap, null); //mailType.ISSUE_SEND - 템플릿 설정 |
| | | this.systemEmailService.directEmail(issueForm.getSendEmails().toArray(new String[issueForm.getSendEmails().size()]), EmailType.ISSUE_SEND, issueMap, null); |
| | | } |
| | | |
| | | // 예약 발생 이슈를 실행한다 |
| | |
| | | @Transactional |
| | | public void reservationIssue() { |
| | | List<IssueReservation> issueReservations = this.issueReservationService.findByIssueReservationTypeNotNull(); |
| | | |
| | | |
| | | Calendar calendar = Calendar.getInstance(); |
| | | int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); |
| | |
| | | @Override |
| | | public void modifyParentIssue(IssueForm issueDownForm) { |
| | | Issue issue = this.getIssue(issueDownForm.getId()); //하위 이슈 |
| | | Long newParentIssueId = issueDownForm.getParentIssueId(); //변경할 하위이슈의 상위이슈 |
| | | |
| | | StringBuilder sb = new StringBuilder(); |
| | | |
| | | Issue parentIssue = issue.getParentIssue(); //변경 전 하위이슈의 상위이슈 |
| | | if(parentIssue != null){ //변경 전 하위이슈의 상위이슈가 존재 할 경우 |
| | | this.issueHistoryService.detectDownIssues(IssueHistoryType.DELETE, issue, sb); |
| | | this.issueHistoryService.addIssueHistory(parentIssue, IssueHistoryType.MODIFY, sb.toString()); |
| | | } |
| | | |
| | | Long newParentIssueId = issueDownForm.getParentIssueId(); //변경할 하위이슈의 상위이슈 |
| | | StringBuilder sb = new StringBuilder(); |
| | | |
| | | if (newParentIssueId != null) { // 추가 할 경우 |
| | | // todo 이전 하위 일감 히스토리기록 필요 |
| | |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | /*@Override |
| | | @Transactional |
| | | public void findMailTargetAll(Map<String, Object> resJsonData, IssueCondition condition, Pageable pageable) { |
| | | IssueVo issueVo = new IssueVo(); |
| | |
| | | resJsonData.put(Constants.RES_KEY_CONTENTS, emailList); |
| | | resJsonData.put(Constants.REQ_KEY_PAGE_VO, new ResPage(pageable.getPageNumber(), pageable.getPageSize(), |
| | | totalPage, totalCount)); |
| | | } |
| | | }*/ |
| | | |
| | | /*@Override |
| | | @Transactional |
| | |
| | | @Override |
| | | @Transactional |
| | | public void checkUseWorkspace() { |
| | | Workspace workspace = this.getWorkspace(this.userService.getUser(this.webAppUtil.getLoginId()).getLastWorkspaceId()); |
| | | User user = this.webAppUtil.getLoginUserObject(); |
| | | Workspace workspace = this.getWorkspace(user.getLastWorkspaceId()); |
| | | |
| | | this.checkUseWorkspace(user, workspace.getId()); |
| | | } |
| | | |
| | | // 사용하고 있는 업무 공간이 활성 상태인지 확인한다. 사용 공간에서 로그인한 사용자가 비활성인지 확인한다. |
| | | @Override |
| | | @Transactional |
| | | public Workspace checkUseWorkspace(User user, Long workspaceId) { |
| | | if (user == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.USER_NOT_EXIST)); |
| | | } |
| | | |
| | | if (workspaceId == null) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.WORKSPACE_NOT_EXIST)); |
| | | } |
| | | |
| | | Workspace workspace = this.getWorkspace(workspaceId); |
| | | |
| | | if (workspace.getServiceType().equals(ServiceType.UNUSED)) { |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.WORKSPACE_USE_PERIOD_EXCESS)); |
| | | } |
| | | |
| | | UserWorkspace userWorkspace = this.userWorkspaceService.findByUserIdAndWorkspaceId(this.webAppUtil.getLoginId(), workspace.getId()); |
| | | UserWorkspace userWorkspace = this.userWorkspaceService.findByUserIdAndWorkspaceId(user.getId(), workspace.getId()); |
| | | |
| | | if (!userWorkspace.getUseYn()) { |
| | | // 해당 사용자가 관리하는 업무 공간를 마지막 접근 업무 공간로 변경한다. |
| | | this.userService.updateLastMyWorkspace(userWorkspace.getUser()); |
| | | |
| | | // 비활성 사용자는 더이상 해당 업무 공간에 있으면 안된다. |
| | | this.simpMessagingTemplate.convertAndSendToUser(this.webAppUtil.getLoginUser().getAccount(), "/notification/workspace-remove", this.messageAccessor.getMessage(MsgConstants.WORKSPACE_OUT, workspace.getName())); |
| | | this.simpMessagingTemplate.convertAndSendToUser(user.getAccount(), "/notification/workspace-remove", this.messageAccessor.getMessage(MsgConstants.WORKSPACE_OUT, workspace.getName())); |
| | | |
| | | throw new OwlRuntimeException( |
| | | this.messageAccessor.getMessage(MsgConstants.WORKSPACE_INCLUDE_DISABLED)); |
| | | } |
| | | |
| | | return workspace; |
| | | } |
| | | |
| | | // 사용 공간에서 로그인한 사용자가 비활성인지 확인하고 비활성일 경우 엑셀 다운로드를 금지한다. |
| | |
| | | return fileMap; |
| | | } |
| | | |
| | | // string file 정보를 file Map 형태로 변경한다. |
| | | public static Map<String, Object> makeFileMap(String fileName, String file, String contentType) { |
| | | Map<String, Object> fileMap = new HashMap<>(); |
| | | |
| | | try { |
| | | byte[] bytes = Base64.decodeBase64(file); |
| | | |
| | | fileMap.put("fileName", fileName); |
| | | fileMap.put("fileSize", bytes.length); |
| | | fileMap.put("contentType", contentType); |
| | | fileMap.put("file", CommonUtil.bytesToFile(fileName, bytes)); |
| | | } catch (Exception e) { |
| | | LOGGER.debug(e.getMessage()); |
| | | } |
| | | |
| | | return fileMap; |
| | | } |
| | | |
| | | public static String getPostDataString(Map<String, String> params) throws UnsupportedEncodingException { |
| | | StringBuilder result = new StringBuilder(); |
| | | boolean first = true; |
| | |
| | | return convertFile; |
| | | } |
| | | |
| | | // string을 파일로 변환 |
| | | public static File stringToFile(String fileName, String file) { |
| | | |
| | | byte[] bytes = null; |
| | | try { |
| | | bytes = Base64.decodeBase64(file); |
| | | |
| | | } catch (Exception ex) { |
| | | LOGGER.debug("string to bytes 변환 오류"); |
| | | } |
| | | |
| | | if (bytes != null) { |
| | | return bytesToFile(fileName, bytes); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | // bytes를 파일로 변환 |
| | | public static File bytesToFile(String fileName, byte[] bytes) { |
| | | File convertFile = new File(WebAppUtil.getContextRealPath() + TMP_UPLOAD_FOLDER + getFileNameByUUID(fileName)); |
| | | if (!convertFile.exists()) { |
| | | convertFile.mkdirs(); |
| | | } |
| | | |
| | | try{ |
| | | FileOutputStream lFileOutputStream = new FileOutputStream(convertFile); |
| | | lFileOutputStream.write(bytes); |
| | | lFileOutputStream.close(); |
| | | |
| | | }catch (IllegalStateException | IOException e) { |
| | | LOGGER.debug("bytes 파일 file 변환 오류"); |
| | | } |
| | | |
| | | return convertFile; |
| | | } |
| | | |
| | | public static InputStream getFileInputStream(String strPath, String strNewFileName){ |
| | | InputStream objInputStream = null; |
| | | |
| | |
| | | package kr.wisestone.owl.web.controller; |
| | | |
| | | import kr.wisestone.owl.constant.Constants; |
| | | import kr.wisestone.owl.domain.Issue; |
| | | import kr.wisestone.owl.service.GuideService; |
| | | import kr.wisestone.owl.service.IssueService; |
| | | import kr.wisestone.owl.util.ConvertUtil; |
| | | import kr.wisestone.owl.util.MapUtil; |
| | | import kr.wisestone.owl.web.condition.GuideCondition; |
| | | import kr.wisestone.owl.web.form.GuideForm; |
| | | import kr.wisestone.owl.web.form.IssueApiForm; |
| | | import kr.wisestone.owl.web.form.IssueForm; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.domain.Pageable; |
| | | import org.springframework.http.MediaType; |
| | |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RequestMethod; |
| | | import org.springframework.web.bind.annotation.ResponseBody; |
| | | import org.springframework.web.multipart.MultipartHttpServletRequest; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | |
| | | public class ApiController extends BaseController { |
| | | |
| | | @Autowired |
| | | private GuideService guideService; |
| | | private IssueService issueService; |
| | | |
| | | // 이슈 추가 |
| | | @RequestMapping(value = "api/issue", produces = MediaType.APPLICATION_JSON_VALUE) |
| | | // 이슈 추가(json 방식으로 파일전송) |
| | | // @RequestMapping(value = "api/issue", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) |
| | | // public |
| | | // @ResponseBody |
| | | // Map<String, Object> addIssue(@RequestBody Map<String, Map<String, Object>> params) { |
| | | // Map<String, Object> resJsonData = new HashMap<>(); |
| | | // |
| | | // IssueApiForm issueForm = IssueApiForm.make(params.get(Constants.REQ_KEY_CONTENT)); |
| | | // Issue issue = this.issueService.addApiIssue(issueForm); |
| | | // // 버전 생성 |
| | | // this.issueService.addIssueVersion(issue.getId()); |
| | | // return this.setSuccessMessage(resJsonData); |
| | | // } |
| | | @RequestMapping(value = "api/issue", method = RequestMethod.POST) |
| | | public |
| | | @ResponseBody |
| | | Map<String, Object> add(@RequestBody Map<String, Map<String, Object>> params) { |
| | | Map<String, Object> addIssue(MultipartHttpServletRequest request) throws Exception { |
| | | Map<String, Object> resJsonData = new HashMap<>(); |
| | | |
| | | // todo |
| | | |
| | | IssueApiForm issueForm = IssueApiForm.make(ConvertUtil.convertJsonToMap(request.getParameter(Constants.REQ_KEY_CONTENT)), request.getFiles("file")); |
| | | Issue issue = this.issueService.addApiIssue(issueForm); |
| | | // 버전 생성 |
| | | this.issueService.addIssueVersion(issue.getId()); |
| | | return this.setSuccessMessage(resJsonData); |
| | | } |
| | | |
| | | // 이슈 조회 |
| | | @RequestMapping(value = "/api/issuelist", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) |
| | | @RequestMapping(value = "/api/issueList", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) |
| | | public |
| | | @ResponseBody |
| | | Map<String, Object> find(@RequestBody Map<String, Map<String, Object>> params) { |
| | |
| | | Map<String, Object> resJsonData = new HashMap<>(); |
| | | Pageable pageable = this.pageUtil.convertPageable(this.getPageVo(params)); |
| | | |
| | | this.issueService.findMailTargetAll(resJsonData, IssueCondition.make(params.get(Constants.REQ_KEY_CONTENT)), pageable); |
| | | // this.issueService.findMailTargetAll(resJsonData, IssueCondition.make(params.get(Constants.REQ_KEY_CONTENT)), pageable); |
| | | |
| | | return this.setSuccessMessage(resJsonData); |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.web.form; |
| | | |
| | | public class CustomFieldValueForm { |
| | | private Long customFieldId; |
| | | private String value; |
| | | |
| | | public CustomFieldValueForm(){} |
| | | |
| | | public Long getCustomFieldId() { |
| | | return customFieldId; |
| | | } |
| | | |
| | | public void setCustomFieldId(Long customFieldId) { |
| | | this.customFieldId = customFieldId; |
| | | } |
| | | |
| | | public String getValue() { |
| | | return value; |
| | | } |
| | | |
| | | public void setValue(String value) { |
| | | this.value = value; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.web.form; |
| | | |
| | | import com.google.common.collect.Lists; |
| | | import kr.wisestone.owl.domain.IssueCustomFieldValue; |
| | | import kr.wisestone.owl.util.ConvertUtil; |
| | | import kr.wisestone.owl.util.MapUtil; |
| | | import kr.wisestone.owl.vo.CustomFieldVo; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.util.*; |
| | | |
| | | public class IssueApiForm { |
| | | private String token; |
| | | private String title; |
| | | private String projectKey; |
| | | private String description; |
| | | private Long issueTypeId; |
| | | private Long priorityId; |
| | | private Long severityId; |
| | | private Date startDate; |
| | | private Date endDate; |
| | | private Date searchTime; |
| | | private List<DepartmentForm> departments = Lists.newArrayList(); |
| | | private List<IssueCustomFieldValueForm> issueCustomFieldValues = Lists.newArrayList(); |
| | | private List<Map<String, Object>> CustomFieldValues = Lists.newArrayList(); |
| | | // private List<Map<String, Object>> files = Lists.newArrayList(); |
| | | private List<MultipartFile> multipartFiles = Lists.newArrayList(); |
| | | |
| | | public IssueApiForm() { |
| | | } |
| | | |
| | | public static IssueApiForm make(Map<String, Object> content, List<MultipartFile> files) { |
| | | IssueApiForm form = ConvertUtil.convertMapToClass(content, IssueApiForm.class); |
| | | form.setMultipartFiles(files); |
| | | |
| | | // 사용자 필드 정보 |
| | | if (MapUtil.getObject(content, "customFields") != null){ |
| | | List<Map<String, Object>> customFields = (List)MapUtil.getObject(content, "customFields"); |
| | | for (Map<String, Object> customField : customFields) { |
| | | IssueCustomFieldValueForm issueCustomFieldValueForm = ConvertUtil.convertMapToClass(customField, IssueCustomFieldValueForm.class); |
| | | form.addIssueCustomFieldValue(issueCustomFieldValueForm); |
| | | |
| | | |
| | | Map<String, Object> customFieldVo = new HashMap<>(); |
| | | customFieldVo.put("id", issueCustomFieldValueForm.getCustomFieldId()); |
| | | |
| | | customField.put("customFieldVo", customFieldVo); |
| | | |
| | | List<String> useValues = Lists.newArrayList(); |
| | | useValues.add(issueCustomFieldValueForm.getUseValue()); |
| | | customField.put("useValues", useValues); |
| | | |
| | | form.addCustomFieldValue(customField); |
| | | } |
| | | } |
| | | |
| | | // 첨부 파일 |
| | | // if (MapUtil.getObject(content, "files") != null){ |
| | | // form.setFiles((List)MapUtil.getObject(content, "files")); |
| | | // } |
| | | return form; |
| | | } |
| | | |
| | | public String getToken() { |
| | | return token; |
| | | } |
| | | |
| | | public void setToken(String token) { |
| | | this.token = token; |
| | | } |
| | | |
| | | public String getTitle() { |
| | | return title; |
| | | } |
| | | |
| | | public void setTitle(String title) { |
| | | this.title = title; |
| | | } |
| | | |
| | | public String getProjectKey() { |
| | | return projectKey; |
| | | } |
| | | |
| | | public void setProjectKey(String projectKey) { |
| | | this.projectKey = projectKey; |
| | | } |
| | | |
| | | public String getDescription() { |
| | | return description; |
| | | } |
| | | |
| | | public void setDescription(String description) { |
| | | this.description = description; |
| | | } |
| | | |
| | | public Long getIssueTypeId() { |
| | | return issueTypeId; |
| | | } |
| | | |
| | | public void setIssueTypeId(Long issueTypeId) { |
| | | this.issueTypeId = issueTypeId; |
| | | } |
| | | |
| | | public Long getPriorityId() { |
| | | return priorityId; |
| | | } |
| | | |
| | | public void setPriorityId(Long priorityId) { |
| | | this.priorityId = priorityId; |
| | | } |
| | | |
| | | public Long getSeverityId() { |
| | | return severityId; |
| | | } |
| | | |
| | | public void setSeverityId(Long severityId) { |
| | | this.severityId = severityId; |
| | | } |
| | | |
| | | public List<DepartmentForm> getDepartments() { |
| | | return departments; |
| | | } |
| | | |
| | | public void setDepartments(List<DepartmentForm> departments) { |
| | | this.departments = departments; |
| | | } |
| | | |
| | | public Date getStartDate() { |
| | | return startDate; |
| | | } |
| | | |
| | | public void setStartDate(Date startDate) { |
| | | this.startDate = startDate; |
| | | } |
| | | |
| | | public Date getEndDate() { |
| | | return endDate; |
| | | } |
| | | |
| | | public void setEndDate(Date endDate) { |
| | | this.endDate = endDate; |
| | | } |
| | | |
| | | public Date getSearchTime() { |
| | | return searchTime; |
| | | } |
| | | |
| | | public void setSearchTime(Date searchTime) { |
| | | this.searchTime = searchTime; |
| | | } |
| | | |
| | | public List<IssueCustomFieldValueForm> getIssueCustomFieldValues() { |
| | | return issueCustomFieldValues; |
| | | } |
| | | |
| | | public void setIssueCustomFieldValues(List<IssueCustomFieldValueForm> issueCustomFieldValues) { |
| | | this.issueCustomFieldValues = issueCustomFieldValues; |
| | | } |
| | | |
| | | public void addIssueCustomFieldValue(IssueCustomFieldValueForm issueCustomFieldValueForm) { |
| | | if (this.issueCustomFieldValues != null) { |
| | | this.issueCustomFieldValues.add(issueCustomFieldValueForm); |
| | | } |
| | | } |
| | | |
| | | public void addCustomFieldValue(Map<String, Object> map) { |
| | | if (this.CustomFieldValues != null) { |
| | | this.CustomFieldValues.add(map); |
| | | } |
| | | } |
| | | |
| | | public List<Map<String, Object>> getCustomFieldValues() { |
| | | return CustomFieldValues; |
| | | } |
| | | |
| | | public void setCustomFieldValues(List<Map<String, Object>> customFieldValues) { |
| | | CustomFieldValues = customFieldValues; |
| | | } |
| | | |
| | | // public List<Map<String, Object>> getFiles() { |
| | | // return files; |
| | | // } |
| | | // |
| | | // public void setFiles(List<Map<String, Object>> files) { |
| | | // this.files = files; |
| | | // } |
| | | |
| | | public List<MultipartFile> getMultipartFiles() { |
| | | return multipartFiles; |
| | | } |
| | | |
| | | public void setMultipartFiles(List<MultipartFile> multipartFiles) { |
| | | this.multipartFiles = multipartFiles; |
| | | } |
| | | } |
New file |
| | |
| | | package kr.wisestone.owl.web.form; |
| | | |
| | | public class IssueCustomFieldValueForm { |
| | | private Long customFieldId; |
| | | private String useValue; |
| | | |
| | | public IssueCustomFieldValueForm(){} |
| | | |
| | | public Long getCustomFieldId() { |
| | | return customFieldId; |
| | | } |
| | | |
| | | public void setCustomFieldId(Long customFieldId) { |
| | | this.customFieldId = customFieldId; |
| | | } |
| | | |
| | | public String getUseValue() { |
| | | return useValue; |
| | | } |
| | | |
| | | public void setUseValue(String useValue) { |
| | | this.useValue = useValue; |
| | | } |
| | | } |
| | |
| | | private List<Map<String, Object>> issueCompanyFields = Lists.newArrayList(); |
| | | private List<Map<String, Object>> issueIspFields = Lists.newArrayList(); |
| | | private List<Map<String, Object>> issueHostingFields = Lists.newArrayList(); |
| | | private List<Map<String, Object>> files = Lists.newArrayList(); // api용 첨부파일 |
| | | private Long parentIssueId; // 상위 이슈 |
| | | private String isApi; |
| | | |
| | | public IssueForm() { |
| | | } |
| | |
| | | // HOSTING 필드 정보 |
| | | if (MapUtil.getObject(params, "issueHostingFields") != null){ |
| | | form.setIssueHostingFields((List)MapUtil.getObject(params, "issueHostingFields")); |
| | | } |
| | | |
| | | // api 첨부파일 |
| | | if (MapUtil.getObject(params, "files") != null){ |
| | | form.setFiles((List)MapUtil.getObject(params, "files")); |
| | | } |
| | | return form; |
| | | } |
| | |
| | | public void setParentIssueId(Long parentIssueId) { |
| | | this.parentIssueId = parentIssueId; |
| | | } |
| | | |
| | | public String getIsApi() { |
| | | return isApi; |
| | | } |
| | | |
| | | public void setIsApi(String isApi) { |
| | | this.isApi = isApi; |
| | | } |
| | | |
| | | public List<Map<String, Object>> getFiles() { |
| | | return files; |
| | | } |
| | | |
| | | public void setFiles(List<Map<String, Object>> files) { |
| | | this.files = files; |
| | | } |
| | | } |
| | |
| | | |
| | | -- issue_type 테이블 업체,ISP,호스팅 컬럼 추가 |
| | | ALTER TABLE `issue_type` ADD COLUMN `use_partner` BIGINT(11) NOT NULL DEFAULT '0'; |
| | | |
| | | -- api 이슈 여부 |
| | | ALTER TABLE `issue` ADD COLUMN `is_api` VARCHAR(1) NOT NULL DEFAULT 'N'; |
| | |
| | | issue WHERE issue_status_id = #{issueStatusId}; |
| | | </select> |
| | | |
| | | <!-- 특정 사용자 정의 필드 값이 같은 이슈를 조회 --> |
| | | <select id="findByCustomFieldValue" resultType="java.util.HashMap" parameterType="kr.wisestone.owl.web.condition.IssueCustomFieldValueCondition"> |
| | | SELECT |
| | | id |
| | | FROM issue |
| | | LEFT OUTER JOIN issue_custom_field_value issue_custom FORCE INDEX(issueIdIndex) ON issue.id = issue_custom.issue_id |
| | | WHERE 1=1 |
| | | AND issue.parent_issue_id IS NULL |
| | | <choose> |
| | | <when test="useValues.size != 0"> |
| | | AND issue_custom.use_value IN |
| | | <foreach collection="useValues" item="item" index="index" separator="," open="(" close=")"> |
| | | #{item} |
| | | </foreach> |
| | | </when> |
| | | </choose> |
| | | </select> |
| | | |
| | | </mapper> |