From 306f6173e4dc458074f74ceeddbfbc0d52765401 Mon Sep 17 00:00:00 2001
From: wyu <kknd09321@nate.com>
Date: 목, 06 1월 2022 10:49:46 +0900
Subject: [PATCH] Merge branch 'master' of http://192.168.0.25:9001/r/owl-kisa

---
 src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java                |    5 
 src/main/java/kr/wisestone/owl/web/form/ApiIssueModifyForm.java                  |   63 +++++++
 src/main/java/kr/wisestone/owl/web/form/ApiTokenForm.java                        |    8 
 src/main/resources/mybatis/query-template/issue-template.xml                     |    8 
 src/main/java/kr/wisestone/owl/config/SwaggerConfig.java                         |   94 ++++++++++
 src/main/java/kr/wisestone/owl/config/SecurityConfiguration.java                 |    2 
 pom.xml                                                                          |   11 +
 src/main/resources/log4j2.xml                                                    |    8 
 src/main/java/kr/wisestone/owl/web/condition/IssueCustomFieldValueCondition.java |   23 ++
 /dev/null                                                                        |   81 ---------
 src/main/java/kr/wisestone/owl/web/form/ApiIssueAddForm.java                     |   53 +++++
 src/main/java/kr/wisestone/owl/web/controller/ApiTokenController.java            |   21 ++
 src/main/java/kr/wisestone/owl/web/form/IssueApiForm.java                        |   65 +++----
 src/main/java/kr/wisestone/owl/web/controller/Api/ApiController.java             |   98 ++++++++++
 14 files changed, 408 insertions(+), 132 deletions(-)

diff --git a/pom.xml b/pom.xml
index 94c22f5..b2bb567 100644
--- a/pom.xml
+++ b/pom.xml
@@ -521,6 +521,17 @@
             <version>0.9.1</version>
         </dependency>
 
+        <!-- Swagger(api 臾몄꽌�솕) -->
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger2</artifactId>
+            <version>2.9.2</version>
+        </dependency>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger-ui</artifactId>
+            <version>2.9.2</version>
+        </dependency>
     </dependencies>
 
     <repositories>
diff --git a/src/main/java/kr/wisestone/owl/config/SecurityConfiguration.java b/src/main/java/kr/wisestone/owl/config/SecurityConfiguration.java
index 62056ea..3df8251 100644
--- a/src/main/java/kr/wisestone/owl/config/SecurityConfiguration.java
+++ b/src/main/java/kr/wisestone/owl/config/SecurityConfiguration.java
@@ -145,7 +145,9 @@
                 .antMatchers("/language/change").permitAll()
                 .antMatchers("/security/*").permitAll()
                 .antMatchers("/api/issue").permitAll()
+                .antMatchers("/api/issue/*").permitAll()
                 .antMatchers("/**/*").authenticated();
+
 //        http.addFilter(new CustomAuthenticationFilter());
 //        http.addFilterBefore(new CustomAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
 
diff --git a/src/main/java/kr/wisestone/owl/config/SwaggerConfig.java b/src/main/java/kr/wisestone/owl/config/SwaggerConfig.java
new file mode 100644
index 0000000..ab42cb3
--- /dev/null
+++ b/src/main/java/kr/wisestone/owl/config/SwaggerConfig.java
@@ -0,0 +1,94 @@
+package kr.wisestone.owl.config;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.Parameter;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+/**
+ * API 臾몄꽌 �젣�옉 �뙣�궎吏� Swagger �꽕�젙 �겢�옒�뒪
+ */
+@Configuration
+@EnableSwagger2
+public class SwaggerConfig {
+
+    private static final String API_NAME = "OWL API";
+    private static final String API_VERSION = "1.0.0";
+    private static final String API_DESCRIPTION = "OWL API 紐낆꽭�꽌";
+
+
+    /**
+     * API �꽕�젙
+     * @return docket class
+     */
+    @Bean
+    public Docket api() {
+//        Parameter parameterBuilder = new ParameterBuilder()
+//                .name(HttpHeaders.AUTHORIZATION)
+//                .description("Access Tocken")
+//                .modelRef(new ModelRef("string"))
+//                .parameterType("header")
+//                .required(false)
+//                .build();
+
+        List<Parameter> globalParameters = new ArrayList<>();
+//        globalParameters.add(parameterBuilder);
+
+        return new Docket(DocumentationType.SWAGGER_2)
+                .globalOperationParameters(globalParameters)
+                .consumes(getConsumeContentTypes())
+                .produces(getProduceContentTypes())
+                .apiInfo(apiInfo())
+                .select()
+                .apis(RequestHandlerSelectors.basePackage("kr.wisestone.owl.web.controller.Api"))
+                .paths(PathSelectors.any())
+                .build();
+    }
+
+
+    /**
+     * API 臾몄꽌 ���씠��/踰꾩쟾/�꽕紐� �꽕�젙
+     * @return ApiInfo �겢�옒�뒪
+     */
+    public ApiInfo apiInfo() {
+        return new ApiInfoBuilder()
+                .title(API_NAME)
+                .version(API_VERSION)
+                .description(API_DESCRIPTION)
+                .build();
+    }
+
+
+    /**
+     * API 臾몄꽌 �뀒�뒪�듃 Request Content-Type �꽕�젙 異붽�
+     * @return consumes content-type 紐⑸줉
+     */
+    private Set<String> getConsumeContentTypes() {
+        Set<String> consumes = new HashSet<>();
+        consumes.add("application/json;charset=UTF-8");
+        consumes.add("application/x-www-form-urlencoded");
+        return consumes;
+    }
+
+    /**
+     * API 臾몄꽌 �뀒�뒪�듃 Response content-type �꽕�젙 異붽�
+     * @return produce content-type 紐⑸줉
+     */
+    private Set<String> getProduceContentTypes() {
+        Set<String> produces = new HashSet<>();
+        produces.add("application/json;charset=UTF-8");
+        return produces;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java b/src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java
index 415eaef..05f35c1 100644
--- a/src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java
+++ b/src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java
@@ -283,7 +283,7 @@
                     issueApiForm.addUseIssueCustomFieldId(customFieldApiOverlap.getCustomField().getId());
                 }
 
-                // 以묐났�맂 �씠�뒋寃��깋
+                // 醫낅즺�긽�깭媛� �븘�땶 以묐났�맂 �긽�쐞 �씠�뒋寃��깋
                 List<Issue> issues = this.findIssue(issueApiForm, customFieldApiOverlaps, user.getId());
                 int size = issues.size();
                 if (size > 0) {
@@ -440,6 +440,7 @@
             issueCustomFieldValueCondition.setUseValue(concatUseValue);
             issueCustomFieldValueCondition.setUseValues(userValues);
             issueCustomFieldValueCondition.setIssueTypeId(issueApiform.getIssueTypeId());
+            issueCustomFieldValueCondition.setIssueStatusType("CLOSE");
             List<Map<String, Object>> results = this.issueMapper.findByCustomFieldValue(issueCustomFieldValueCondition);
             if (results != null && results.size() > 0) {
                 for (Map<String, Object> result : results) {
@@ -938,7 +939,7 @@
 //        if (!this.userWorkspaceService.checkWorkspaceManager(user)
 //                && !MngPermission.checkMngPermission(userLevel.getPermission(), MngPermission.USER_PERMISSION_MNG_ISSUE)) { //理쒓퀬愿�由ъ옄 & �봽濡쒖젥�듃,�씠�뒋 愿�由ъ옄 �씪 寃쎌슦 紐⑤뱺 �씠�뒋 蹂닿린
 //            this.SetMyDepartmentId(issueCondition);
-            //this.SetAllDepartmentId(issueCondition);
+        //this.SetAllDepartmentId(issueCondition);
 //        } /*else{
 //            results = this.issueMapper.findByDepartment(issueCondition);
 //            totalCount = this.issueMapper.countByDepartment(issueCondition);
diff --git a/src/main/java/kr/wisestone/owl/web/condition/IssueCustomFieldValueCondition.java b/src/main/java/kr/wisestone/owl/web/condition/IssueCustomFieldValueCondition.java
index 063557f..5475ac0 100644
--- a/src/main/java/kr/wisestone/owl/web/condition/IssueCustomFieldValueCondition.java
+++ b/src/main/java/kr/wisestone/owl/web/condition/IssueCustomFieldValueCondition.java
@@ -10,6 +10,7 @@
 import java.util.Map;
 
 /**
+ * �씠�뒋 �궗�슜�옄 �젙�쓽 �븘�뱶 媛� 寃��깋 議곌굔 �겢�옒�뒪
  * Created by wisestone on 2018-06-07.
  */
 public class IssueCustomFieldValueCondition {
@@ -17,9 +18,19 @@
     private Long workspaceId;
     private Long customFieldId;
     private String customFieldType;
-    private List<String> useValues = Lists.newArrayList();  //  �떒�씪, �떎以� �씪�븣 寃��깋 媛�
-    private String useValue;    //  �뀓�뒪�듃 �븘�뱶�씪 �븣 寃��깋 媛�
+    /**
+     * �궗�슜�옄 �젙�쓽 �븘�뱶 �궗�슜 媛�
+     */
+    private List<String> useValues = Lists.newArrayList();
+    /**
+     * �뀓�뒪�듃 �븘�뱶�씪 �븣 寃��깋 媛�
+     */
+    private String useValue;
     private boolean useParentIssueId = true;
+    /**
+     * �씠�뒋 �긽�깭 �쑀�삎(READY / OPEN / CLOSE)
+     */
+    private String issueStatusType;
 
     public IssueCustomFieldValueCondition(){}
 
@@ -62,6 +73,14 @@
         return condition;
     }
 
+    public String getIssueStatusType() {
+        return issueStatusType;
+    }
+
+    public void setIssueStatusType(String issueStatusType) {
+        this.issueStatusType = issueStatusType;
+    }
+
     public Long getIssueTypeId() {
         return issueTypeId;
     }
diff --git a/src/main/java/kr/wisestone/owl/web/controller/Api/ApiController.java b/src/main/java/kr/wisestone/owl/web/controller/Api/ApiController.java
new file mode 100644
index 0000000..0fbbf81
--- /dev/null
+++ b/src/main/java/kr/wisestone/owl/web/controller/Api/ApiController.java
@@ -0,0 +1,98 @@
+package kr.wisestone.owl.web.controller.Api;
+
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import kr.wisestone.owl.constant.MsgConstants;
+import kr.wisestone.owl.domain.Issue;
+import kr.wisestone.owl.exception.OwlRuntimeException;
+import kr.wisestone.owl.service.IssueService;
+import kr.wisestone.owl.util.ConvertUtil;
+import kr.wisestone.owl.web.controller.BaseController;
+import kr.wisestone.owl.web.form.ApiIssueAddForm;
+import kr.wisestone.owl.web.form.ApiIssueModifyForm;
+import kr.wisestone.owl.web.form.IssueApiForm;
+import org.json.simple.parser.ParseException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * OWL-API 而⑦듃濡ㅻ윭
+ */
+@Controller
+@RequestMapping("/api")
+public class ApiController extends BaseController {
+
+    @Autowired
+    private IssueService issueService;
+
+
+    /**
+     * �씠�뒋 異붽�
+     * @param apiIssueAddForm �엯�젰 �뤌 �뜲�씠�꽣
+     * @param files �뙆�씪
+     * @return JSON
+     * @throws OwlRuntimeException �뙆�씪誘명꽣 �삤瑜섏떆 諛쒖깮
+     * @throws CloneNotSupportedException �씠�뒋 蹂듭궗 �떆�뿉 諛쒖깮
+     */
+    @PostMapping(value = "/issue")
+    @ApiOperation(value = "�씠�뒋 異붽�", notes = "�깉濡쒖슫 �씠�뒋瑜� 異붽��븳�떎.")
+    @ApiImplicitParam(name = "files", required = false, dataType = "file")
+    public
+    @ResponseBody
+    Map<String, Object> addIssue(ApiIssueAddForm apiIssueAddForm, @RequestParam("files") List<MultipartFile> files) throws OwlRuntimeException, CloneNotSupportedException, ParseException {
+        Map<String, Object> resJsonData = new HashMap<>();
+
+        IssueApiForm issueApiForm = ConvertUtil.copyProperties(apiIssueAddForm, IssueApiForm.class);
+//        String str = request.getParameter(Constants.REQ_KEY_CONTENT);
+        issueApiForm.setMultipartFiles(files);
+        issueApiForm.parseCustomFields(apiIssueAddForm.getCustomFields());
+        issueApiForm.setApiType(IssueApiForm.ApiType.add);
+        // �궗�슜�옄 �젙�쓽 �븘�뱶媛� �뾾�쓣 寃쎌슦 寃��깋�쓣 �븷 �닔 �뾾湲� �븣臾몄뿉 �삁�쇅泥섎━
+        if (issueApiForm.getCustomFieldValues() == null || issueApiForm.getCustomFieldValues().size() == 0) {
+            throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.API_CUSTOM_FIELD_NOT_EXIST));
+        }
+
+        List<Issue> issues = this.issueService.addApiIssue(issueApiForm);
+        //  踰꾩쟾 �깮�꽦
+        for (Issue issue : issues) {
+            this.issueService.addIssueVersion(issue.getId(), issue.getRegisterId());
+        }
+
+        return this.setSuccessMessage(resJsonData);
+    }
+
+    /**
+     * �씠�뒋 �긽�깭 �닔�젙
+     * @param apiIssueModifyForm �닔�젙 �뤌 �뜲�씠�꽣
+     * @return JSON
+     * @throws OwlRuntimeException �뙆�씪誘명꽣 �삤瑜섏떆 諛쒖깮
+     * @throws CloneNotSupportedException �씠�뒋 蹂듭궗 �떆�뿉 諛쒖깮
+     */
+    @PostMapping(value = "/issue/1")
+    @ApiOperation(value = "�씠�뒋 �긽�깭 �닔�젙", notes = "�궗�슜�옄 �젙�쓽 �븘�뱶媛� �룞�씪�븳 湲곗〈 �씠�뒋瑜� 蹂�寃쏀븳�떎.")
+    public
+    @ResponseBody
+    Map<String, Object> modifyIssue(ApiIssueModifyForm apiIssueModifyForm) throws OwlRuntimeException, CloneNotSupportedException, ParseException {
+        Map<String, Object> resJsonData = new HashMap<>();
+
+        IssueApiForm issueApiForm = ConvertUtil.copyProperties(apiIssueModifyForm, IssueApiForm.class);
+        issueApiForm.parseCustomFields(apiIssueModifyForm.getCustomFields());
+        issueApiForm.setApiType(IssueApiForm.ApiType.add);
+        // �궗�슜�옄 �젙�쓽 �븘�뱶媛� �뾾�쓣 寃쎌슦 寃��깋�쓣 �븷 �닔 �뾾湲� �븣臾몄뿉 �삁�쇅泥섎━
+        if (issueApiForm.getCustomFieldValues() == null || issueApiForm.getCustomFieldValues().size() == 0) {
+            throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.API_CUSTOM_FIELD_NOT_EXIST));
+        }
+
+        this.issueService.modifyIssue(issueApiForm, new ArrayList<>());
+
+        return this.setSuccessMessage(resJsonData);
+    }
+}
+
diff --git a/src/main/java/kr/wisestone/owl/web/controller/ApiController.java b/src/main/java/kr/wisestone/owl/web/controller/ApiController.java
deleted file mode 100644
index fb90cfd..0000000
--- a/src/main/java/kr/wisestone/owl/web/controller/ApiController.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package kr.wisestone.owl.web.controller;
-
-import kr.wisestone.owl.constant.Constants;
-import kr.wisestone.owl.constant.MsgConstants;
-import kr.wisestone.owl.domain.Issue;
-import kr.wisestone.owl.exception.OwlRuntimeException;
-import kr.wisestone.owl.service.IssueService;
-import kr.wisestone.owl.util.ConvertUtil;
-import kr.wisestone.owl.web.form.IssueApiForm;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Controller;
-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.List;
-import java.util.Map;
-
-/**
- * OWL-API 而⑦듃濡ㅻ윭
- */
-@Controller
-public class ApiController extends BaseController {
-
-    @Autowired
-    private IssueService issueService;
-
-
-    /**
-     * @param request multipart/form-data 濡� �슂泥��빐�빞 �븿
-     * @return Json �쑝濡� 寃곌낵媛� �쟾�넚
-     * @throws OwlRuntimeException 二쇰줈�뙆�씪誘명꽣 �삤瑜� 泥댄겕�떆 諛쒖깮
-     * @throws CloneNotSupportedException 媛앹껜 蹂듭궗�븷 �븣 諛쒖깮
-     */
-    @RequestMapping(value = "api/issue", method = RequestMethod.POST)
-    public
-    @ResponseBody
-    Map<String, Object> addIssue(MultipartHttpServletRequest request) throws OwlRuntimeException, CloneNotSupportedException {
-        Map<String, Object> resJsonData = new HashMap<>();
-
-        String str = request.getParameter(Constants.REQ_KEY_CONTENT);
-
-        IssueApiForm issueForm = IssueApiForm.make(ConvertUtil.convertJsonToMap(str), request.getFiles("file"));
-        if (issueForm == null) {
-            throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.API_PARAMETER_ERROR));
-        }
-        // �궗�슜�옄 �젙�쓽 �븘�뱶媛� �뾾�쓣 寃쎌슦 寃��깋�쓣 �븷 �닔 �뾾湲� �븣臾몄뿉 �삁�쇅泥섎━
-        else if (issueForm.getCustomFieldValues() == null || issueForm.getCustomFieldValues().size() == 0) {
-            throw new OwlRuntimeException(this.messageAccessor.getMessage(MsgConstants.API_CUSTOM_FIELD_NOT_EXIST));
-        }
-
-        if (issueForm.getApiType() == IssueApiForm.ApiType.add) {
-            List<Issue> issues = this.issueService.addApiIssue(issueForm);
-            //  踰꾩쟾 �깮�꽦
-            for (Issue issue : issues) {
-                this.issueService.addIssueVersion(issue.getId(), issue.getRegisterId());
-            }
-        } else {
-
-
-            this.issueService.modifyIssue(issueForm, request.getFiles("file"));
-        }
-
-        return this.setSuccessMessage(resJsonData);
-    }
-
-    //  �씠�뒋 議고쉶
-//    @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));
-//
-//        // todo
-//        return this.setSuccessMessage(resJsonData);
-//    }
-}
-
diff --git a/src/main/java/kr/wisestone/owl/web/controller/ApiTokenController.java b/src/main/java/kr/wisestone/owl/web/controller/ApiTokenController.java
index 6e45b8a..625f7c6 100644
--- a/src/main/java/kr/wisestone/owl/web/controller/ApiTokenController.java
+++ b/src/main/java/kr/wisestone/owl/web/controller/ApiTokenController.java
@@ -6,6 +6,7 @@
 import kr.wisestone.owl.util.ConvertUtil;
 import kr.wisestone.owl.vo.ApiTokenVo;
 import kr.wisestone.owl.web.condition.ApiTokenCondition;
+import kr.wisestone.owl.web.controller.BaseController;
 import kr.wisestone.owl.web.form.ApiTokenForm;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Pageable;
@@ -20,13 +21,20 @@
 import java.util.List;
 import java.util.Map;
 
+/**
+ * API �넗�겙 而⑦듃濡ㅻ윭 �겢�옒�뒪
+ */
 @Controller
 public class ApiTokenController extends BaseController {
 
     @Autowired
     private ApiTokenService apiTokenService;
 
-    //  �넗�겙 �깮�꽦
+    /**
+     * �넗�겙 �깮�꽦
+     * @param params �넗�겙 �깮�꽦�뿉 �븘�슂�븳 �뙆�씪誘명꽣
+     * @return �깮�꽦 寃곌낵 Map<String, Object>
+     */
     @RequestMapping(value = "/apiToken/add", produces = MediaType.APPLICATION_JSON_VALUE)
     public
     @ResponseBody
@@ -41,6 +49,12 @@
         return this.setSuccessMessage(resJsonData);
     }
 
+
+    /**
+     * �넗�겙 議고쉶
+     * @param params �넗�겙 議고쉶�뿉 �븘�슂�븳 �뙆�씪誘명꽣 
+     * @return 議고쉶 寃곌낵, Map<String, ApiTokenVo>
+     */
     //  �넗�겙 議고쉶
     @RequestMapping(value = "/apiToken/find", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
     public
@@ -55,6 +69,11 @@
         return this.setSuccessMessage(resJsonData);
     }
 
+    /**
+     * �넗�겙 �궘�젣
+     * @param params �넗�겙 �궘�젣�뿉 �븘�슂�븳 �뙆�씪誘명꽣
+     * @return �궘�젣 寃곌낵, Map<String, Object>
+     */
     //  �넗�겙 �궘�젣
     @RequestMapping(value = "/apiToken/remove", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
     public
diff --git a/src/main/java/kr/wisestone/owl/web/form/ApiIssueAddForm.java b/src/main/java/kr/wisestone/owl/web/form/ApiIssueAddForm.java
new file mode 100644
index 0000000..9a8d273
--- /dev/null
+++ b/src/main/java/kr/wisestone/owl/web/form/ApiIssueAddForm.java
@@ -0,0 +1,53 @@
+package kr.wisestone.owl.web.form;
+
+import io.swagger.annotations.ApiParam;
+
+
+/**
+ * API �씠�뒋 異붽��슜 Form class
+ */
+public class ApiIssueAddForm {
+    @ApiParam(value = "�궗�슜�옄 �넗�겙", required = true)
+    private String token;
+    @ApiParam(value = "�씠�뒋 �젣紐�")
+    private String title;
+    @ApiParam(value = "�씠�뒋 ���엯 ID", required = true)
+    private Long issueTypeId;
+    @ApiParam(value = "�궗�슜�옄 �젙�쓽 �븘�뱶", required = true)
+    private String customFields;
+
+    public ApiIssueAddForm() {
+    }
+
+    public String getCustomFields() {
+        return customFields;
+    }
+
+    public void setCustomFields(String customFields) {
+        this.customFields = customFields;
+    }
+
+    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 Long getIssueTypeId() {
+        return issueTypeId;
+    }
+
+    public void setIssueTypeId(Long issueTypeId) {
+        this.issueTypeId = issueTypeId;
+    }
+}
diff --git a/src/main/java/kr/wisestone/owl/web/form/ApiIssueModifyForm.java b/src/main/java/kr/wisestone/owl/web/form/ApiIssueModifyForm.java
new file mode 100644
index 0000000..4a3be36
--- /dev/null
+++ b/src/main/java/kr/wisestone/owl/web/form/ApiIssueModifyForm.java
@@ -0,0 +1,63 @@
+package kr.wisestone.owl.web.form;
+
+import io.swagger.annotations.ApiParam;
+
+
+/**
+ * API �씠�뒋 �긽�깭 �닔�젙�슜 Form class
+ */
+public class ApiIssueModifyForm {
+    @ApiParam(value = "�궗�슜�옄 �넗�겙", required = true)
+    private String token;
+    @ApiParam(value = "�씠�뒋 ���엯 ID", required = true)
+    private Long issueTypeId;
+    @ApiParam(value = "�씠�뒋 �긽�깭 ID", required = true)
+    private Long issueStatusId;
+    @ApiParam(value = "�뙎湲�", required = true)
+    private String comment;
+    @ApiParam(value = "�궗�슜�옄 �젙�쓽 �븘�뱶", required = true)
+    private String customFields;
+
+    public ApiIssueModifyForm() {
+    }
+
+    public Long getIssueTypeId() {
+        return issueTypeId;
+    }
+
+    public void setIssueTypeId(Long issueTypeId) {
+        this.issueTypeId = issueTypeId;
+    }
+
+    public Long getIssueStatusId() {
+        return issueStatusId;
+    }
+
+    public void setIssueStatusId(Long issueStatusId) {
+        this.issueStatusId = issueStatusId;
+    }
+
+    public String getToken() {
+        return token;
+    }
+
+    public void setToken(String token) {
+        this.token = token;
+    }
+
+    public String getComment() {
+        return comment;
+    }
+
+    public void setComment(String comment) {
+        this.comment = comment;
+    }
+
+    public String getCustomFields() {
+        return customFields;
+    }
+
+    public void setCustomFields(String customFields) {
+        this.customFields = customFields;
+    }
+}
diff --git a/src/main/java/kr/wisestone/owl/web/form/ApiTokenForm.java b/src/main/java/kr/wisestone/owl/web/form/ApiTokenForm.java
index ab0b978..281ddea 100644
--- a/src/main/java/kr/wisestone/owl/web/form/ApiTokenForm.java
+++ b/src/main/java/kr/wisestone/owl/web/form/ApiTokenForm.java
@@ -1,13 +1,11 @@
 package kr.wisestone.owl.web.form;
 
-import com.google.common.collect.Lists;
 import kr.wisestone.owl.domain.User;
-import kr.wisestone.owl.util.ConvertUtil;
-import kr.wisestone.owl.util.MapUtil;
 
-import java.util.List;
-import java.util.Map;
 
+/**
+ * API �넗�겙 Form class
+ */
 public class ApiTokenForm {
     private Long id;
     private User user;
diff --git a/src/main/java/kr/wisestone/owl/web/form/IssueApiForm.java b/src/main/java/kr/wisestone/owl/web/form/IssueApiForm.java
index aaab370..9ab2b02 100644
--- a/src/main/java/kr/wisestone/owl/web/form/IssueApiForm.java
+++ b/src/main/java/kr/wisestone/owl/web/form/IssueApiForm.java
@@ -4,10 +4,13 @@
 import kr.wisestone.owl.util.ConvertUtil;
 import kr.wisestone.owl.util.MapUtil;
 import org.springframework.web.multipart.MultipartFile;
-
+import java.io.Serializable;
 import java.util.*;
 
-public class IssueApiForm {
+/**
+ * API �씠�뒋 異붽� / �닔�젙�슜 form class
+ */
+public class IssueApiForm implements Serializable {
 
     public enum ApiType {
         add,
@@ -37,44 +40,30 @@
     public IssueApiForm() {
     }
 
-    public static IssueApiForm make(Map<String, Object> content, List<MultipartFile> files) {
-        IssueApiForm form = ConvertUtil.convertMapToClass(content, IssueApiForm.class);
-        form.setMultipartFiles(files);
 
-        // api ���엯
-        if (MapUtil.getString(content, "apiType") != null) {
-            try {
-                form.setApiType(ApiType.valueOf(MapUtil.getString(content, "apiType")));
-            } catch (Exception ex) {
-                return null;
-            }
+    /**
+     * �궗�슜�옄 �젙�쓽 �븘�뱶 蹂��솚
+     * @param customFieldJson �궗�슜�옄 �젙�쓽 �븘�뱶 json
+     */
+    public void parseCustomFields(String customFieldJson) {
+
+        Map<String, Object> json = ConvertUtil.convertJsonToMap(customFieldJson);
+        List<Map<String, Object>> customFields = (List) MapUtil.getObject(json, "customFields");
+        for (Map<String, Object> customField : customFields) {
+            IssueCustomFieldValueForm issueCustomFieldValueForm = ConvertUtil.convertMapToClass(customField, IssueCustomFieldValueForm.class);
+            this.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);
+
+            this.addCustomFieldValue(customField);
         }
-
-        //  �궗�슜�옄 �븘�뱶 �젙蹂�
-        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() {
diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
index e0dc65b..5f166fd 100644
--- a/src/main/resources/log4j2.xml
+++ b/src/main/resources/log4j2.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="warn" name="owl-its" monitorInterval="600">
+<Configuration status="ERROR" name="owl-its" monitorInterval="600">
     <Properties>
         <Property name="LOG_FORMAT">%d{yyyy-MM-dd HH:mm:ss} [%level] - %msg%n</Property>
         <Property name="BASE_DIR">/owl-enterprise-logs</Property>
@@ -50,6 +50,12 @@
             <AppenderRef ref="File"/>
         </Logger>
 
+        <!-- Crawling Logger -->
+        <Logger name="kr.wisestone.owl.crawling" level="debug" additivity="false">
+            <AppenderRef ref="Console"/>
+            <AppenderRef ref="File"/>
+        </Logger>
+
         <!-- Root Loggers -->
         <Root level="warn">
             <AppenderRef ref="Console"/>
diff --git a/src/main/resources/mybatis/query-template/issue-template.xml b/src/main/resources/mybatis/query-template/issue-template.xml
index 6dc1b5a..8685b96 100644
--- a/src/main/resources/mybatis/query-template/issue-template.xml
+++ b/src/main/resources/mybatis/query-template/issue-template.xml
@@ -1115,8 +1115,12 @@
                 </when>
             </choose>
             ) customFieldValue ON customFieldValue.issueId = issue.id
-        WHERE issStatus.issue_status_type != 'CLOSE'
-          AND issue.issue_type_id = #{issueTypeId}
+        WHERE issue.issue_type_id = #{issueTypeId}
+        <choose>
+            <when test="issueStatusType != null">
+                AND issStatus.issue_status_type != #{issueStatusType}
+            </when>
+        </choose>
         GROUP BY issue.id
         HAVING concatUseValue LIKE CONCAT('%', #{useValue}, '%')
     </select>

--
Gitblit v1.8.0