Initial commit
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
= Knox 결재 상태 동기화
|
||||
|
||||
== 결재 Batch 설정
|
||||
|
||||
Knox 결재 문서는 10분마다 배치가 실행되어 동기화 되고 있다.
|
||||
|
||||
* config.properties : 동기화 배치 실행 주기 설정
|
||||
|
||||
[source,properties]
|
||||
----
|
||||
## Knox Approval Sync
|
||||
knox.approval.sync.cron=0 0/10 * * * ?
|
||||
----
|
||||
|
||||
* QuartzConfig.java: Scheduler 등록
|
||||
* KnoxSyncBatchConfig.java: 배치 Job, Trigger 등록
|
||||
* KnoxSyncBatchExecutor.java: 서비스 호출
|
||||
|
||||
== 결재 동기화 로직
|
||||
|
||||
배치에서 실행되는 동기화 로직을 구현한 서비스는 knoxApprovalSyncServiceImpl.java 파일의 synchronizeKnox() 메소드 이며 동기화 로직은 간략하게 아래와 같다.
|
||||
|
||||
. SDL 결재 테이블에서 결재 진행중인 문서 목록 대상 조회.
|
||||
. 대상 목록의 결재ID로 Knox REST를 조회하여 Revision이 변경되었는지 확인.
|
||||
. Revision 변경된 대상에 대해서 결재 정보 동기화 처리.
|
||||
. 동기화 완료 후 결재 후처리 진행.
|
||||
|
||||
결재 동기화 시 오류가 발생한 결재 문건은 결재정보 테이블(TN_CF_APPROVAL)에 결재 동기화 상태값(APPROVAL_FAULT)이 false로 Update되며 다음 배치 실행시 대상으로 선정되지 않는다. +
|
||||
이런 경우 이벤트 로그 테이블(TN_CF_APPROVAL_EVENT)의 로그를 확인하여 다시 동기화 해야 한다면 결재 관리 상세화면에서 개별 동기화가 가능하다.
|
||||
|
||||
image::approvalSync_01.png[]
|
||||
|
||||
== 결재 전후처리
|
||||
|
||||
결재 동기화 처리전 또는 처리후 결재 문서 상태에 대한 비지니스를 처리할 수 있도록 인터페이스를 제공하고 있다.
|
||||
|
||||
ApprovalInterceptor 를 결재 문서별로 상속 받는 구현 클래스를 만들면 된다.
|
||||
|
||||
* 구현 예시(KnoxApprovalSampleInterceptor.java)
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Log4j2
|
||||
@ApprovalDocumentType(names = {"knoxSample"})
|
||||
public class KnoxApprovalSampleInterceptor implements ApprovalInterceptor {
|
||||
|
||||
@Autowired
|
||||
KnoxApprovalSampleService knoxApprovalSampleService;
|
||||
|
||||
@Override
|
||||
public void afterSubmit(Approval approval, List<ApprovalStep> approvalStepList, Map<String, Object> attribute) {
|
||||
log.debug("execute ApprovalSampleInterceptor afterSubmit");
|
||||
//Knox 상신 후 문서 상태 업데이트
|
||||
knoxApprovalSampleService.updateSampleApprovalDocument(approval.getDbDocId(), ApprovalDocStatus.INPROCESS);
|
||||
}
|
||||
-- 생략 --
|
||||
----
|
||||
@@ -0,0 +1,124 @@
|
||||
= Knox 상신
|
||||
|
||||
== 결재 Entity Class 생성 및 설정
|
||||
|
||||
결재 기능을 구현해야 하는 업무의 Entity Class를 생성하고 Annotation을 설정하고 기본 결재 Class를 상속 받는다.
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ApprovalDocument(docType = "knoxSample", description = "Sample Approval Doc. (Knox)", approvalClass = Approval.class, templateEngine = TemplateEngineType.VELOCITY,
|
||||
templateFile = "/templates/approval/approval-sample.vm", docSecuType = ApprovalDocSecuType.PERSONAL,
|
||||
isArbitrary = true, bodyType = ApprovalBodyType.MIME)
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class KnoxApprovalSampleDocument extends DefaultApprovalDocument {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String docId;
|
||||
private String contents;
|
||||
private String creator;
|
||||
}
|
||||
----
|
||||
|
||||
업무프로세스 Entity Class 에 @ApprovalDocument 을 달아 주고 DefaultApprovalDocument를 상속 받아야만 결재 Object 라는 것을 결재 모듈에서 알수 있다.
|
||||
|
||||
=== @ApprovalDocument
|
||||
|
||||
@ApprovalDocument를 이용해 결재 문서의 속정을 정의한다.
|
||||
|
||||
[cols=5]
|
||||
|====
|
||||
|props명
|
||||
|필수여부
|
||||
|Type
|
||||
|Default
|
||||
|설명
|
||||
|
||||
|docType
|
||||
|필수
|
||||
|String
|
||||
|
|
||||
|사용자가 식별할수 있는 이름
|
||||
|
||||
|description
|
||||
|필수
|
||||
|String
|
||||
|
|
||||
|결재 문서에 대한 설명
|
||||
|
||||
|approvalClass
|
||||
|필수
|
||||
|class
|
||||
|Approval.class
|
||||
|결재 문서를 DB에 저장할때 사용하는 클래스명
|
||||
|
||||
|templateEngine
|
||||
|필수
|
||||
|TemplateEngineType
|
||||
|VELOCITY
|
||||
|결재 본문 파싱에 필요한 템플릿 엔진. THYMELEAF, VELOCITY 2개의 템플릿 엔진을 사용할 수 있다.
|
||||
|
||||
|templateFile 또는 templateKey
|
||||
|필수
|
||||
|String
|
||||
|
|
||||
|templateFile: 템플릿 파일 이름을 경로와 확장자 포함해서 설정한다. +
|
||||
tempageKey: 결재양식 관리 메뉴에서 지정한 key
|
||||
|
||||
|docSecuType
|
||||
|
|
||||
|ApprovalDocSecuType
|
||||
|PERSONAL
|
||||
|결재 문서의 보안 형태
|
||||
|
||||
|isBodyModify
|
||||
|
|
||||
|boolean
|
||||
|true
|
||||
|문서의 기본 결재 본문 수정 true일 때만 UI에서 수정 가능
|
||||
|
||||
|
||||
|isRouteModify
|
||||
|
|
||||
|boolean
|
||||
|true
|
||||
|문서의 기본 결재 경로 수정 true일 때만 UI에서 수정 가능
|
||||
|
||||
|isArbitrary
|
||||
|
|
||||
|boolean
|
||||
|false
|
||||
|문서의 기본 결재 전결 true일 때만 UI에서 수정 가능
|
||||
|
||||
|bodyType
|
||||
|
|
||||
|ApprovalBodyType
|
||||
|MIME
|
||||
|전송할 문서의 형태 TEXT, HTML, MIME
|
||||
|
||||
|isInternalApproval
|
||||
|
|
||||
|boolean
|
||||
|false
|
||||
|true: 내부결재, false: Knox결재
|
||||
|
||||
|====
|
||||
|
||||
== 결재 본문 등록
|
||||
|
||||
결재 본문은 VELOCITY 또는 THYMELEAF 로 등록 할 수 있다. +
|
||||
SDL에서 제공하는 결재 샘플에서는 VELOCITY 파일로 제공하고 있으며 vm 파일을 작성하고, +
|
||||
위의 Entity Class 샘플에서와 같이 `@ApprovalDocument` 의 `templateEngine=엔진타입` 과 `templateFile="템플릿파일경로"` 값을 등록한다.
|
||||
|
||||
|
||||
== 결재 상신
|
||||
|
||||
=== 결재 상신 UI
|
||||
|
||||
샘플 문서를 등록 하고나면 상세하면 하단에 결재 경로를 설정할 수 있는 결재 스텝을 입력 받는 Component가 표시된다. +
|
||||
결재 문서 화면 개발시 이 Component를 붙여서 상신 기능을 구현한다.
|
||||
|
||||
image::approvalSumit_01.png[]
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
= MHTML 변환
|
||||
|
||||
== 개요
|
||||
프로젝트에서 메일발송이나 결재상신한 후 방화벽 밖(모바일)에서 조회시 이미지, css가 적용되지 않는 문제를 해결하기 위해 MHT로 변환
|
||||
|
||||
.MHT 변환 결과 예
|
||||
[source, text]
|
||||
----
|
||||
Date: Fri, 9 Aug 2019 14:55:20 +0900 (KST)
|
||||
Message-ID: <963810424.1.1565330120404@DESKTOP-TUEGPQT>
|
||||
Subject: =?UTF-8?B?66mU64m0IOq2jO2VnCDrp4zro4wg7JiI7KCVIOyViOuCtA==?=
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/related;
|
||||
boundary="----=_Part_0_398737318.1565330120140"
|
||||
|
||||
------=_Part_0_398737318.1565330120140
|
||||
Content-Type: text/html; charset="utf-8"
|
||||
Content-Transfer-Encoding: base64
|
||||
|
||||
PCFkb2N0eXBlIGh0bWw+DQo8aHRtbD4NCjxoZWFkPg0KPG1ldGEgY2hhcnNldD0idXRmLTgiPg0K
|
||||
PHRpdGxlPuuplOuJtCDqtoztlZwg66eM66OMIOyYiOyglSDslYjrgrQ8L3RpdGxlPg0KPC9oZWFk
|
||||
Pg0KDQo8Ym9keT4NCjxkaXYgc3R5bGU9IndpZHRoOjEwMCU7YmFja2dyb3VuZC1jb2xvcjojZmZm
|
||||
(중략)
|
||||
------=_Part_0_398737318.1565330120140
|
||||
Content-Type: application/octet-stream
|
||||
Content-Transfer-Encoding: base64
|
||||
Content-ID: <simbol.png>
|
||||
|
||||
iVBORw0KGgoAAAANSUhEUgAAAQEAAAEBCAYAAAB47BD9AAAwaUlEQVR42u3deZxddX3/8QuC4kPt
|
||||
Rqu2iK222pYW2yogCNbyE81MVRSFIEuAewmBsGQl+zqZmexhExEV0AQCSSDrZLZkJjOZzGRmQhAM
|
||||
RXYqbrVaFZHJTOCe+/29v+fc7z3nnn35nnPP8v3j9XAeLWVScz/P7/ee73fu5AghuSD90+Pt5Trk
|
||||
(중략)
|
||||
------=_Part_0_398737318.1565330120140--
|
||||
----
|
||||
@@ -0,0 +1,220 @@
|
||||
= 결재
|
||||
|
||||
== 개요
|
||||
SDL에서는 Knox결재와 동기화 되는 결재 모듈을 제공하고 있는데, 여기서는 Knox Portal REST API 연계 서비스 신청 및 Knox결재 서비스 연계 부분에 대하여 설명한다. 결재화면 및 기능구현 설명은 해당 가이드를 참조한다.
|
||||
|
||||
=== Knox결재 연계 설정
|
||||
. Knox REST API 연계 서비스 신청이 되었다면, 발급받은 `system-id`, `token` 값을 설정한다.
|
||||
|
||||
.knox.properties (스테이지)
|
||||
[source,properties]
|
||||
----
|
||||
knox.system-id=xxxxxxxxxxx
|
||||
knox.token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
knox.address.prefix=openapi.samsung.net
|
||||
knox.approval-service=/approval/api/v2.0/approvals
|
||||
----
|
||||
|
||||
.knox.properties (운영)
|
||||
[source,properties]
|
||||
----
|
||||
knox.system-id=xxxxxxxxxxx
|
||||
knox.token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx // <1>
|
||||
knox.address.prefix=openapi.samsung.net,openapi.w1.samsung.net,openapi.w2.samsung.net # <2>
|
||||
knox.approval-service=/approval/api/v2.0/approvals
|
||||
----
|
||||
<1> 토큰 (comma(,)로 구분, 거점 순서와 동일)
|
||||
<2> 거점 (국내, 구주, 미주)
|
||||
|
||||
[start=2]
|
||||
. 결재화면 및 기능구현 설명은 해당 가이드를 참조한다.
|
||||
|
||||
* <<_knox_상신,Knox상신>>
|
||||
|
||||
|
||||
NOTE: 개발자의 IP도 반드시 Knox stage 방화벽에 등록하여야만 개발자 PC에서 상신이 된다. 또한 Knox 스테이지(http://www.stage.samsung.net) 에 개발자와 결재자의 계정도 생성 해야만 개발을 진행 할 수 있다.
|
||||
|
||||
== API
|
||||
KnoxApprovalController는 Knox에서 제공하는 Approval API를 직접 연결하는 API를 제공한다.
|
||||
시스템의 비즈니스 로직을 거치지 않고 Knox API를 직접 호출 하기 때문에 서비스 호출에 문제가 있는지 파악하는데 유용하다.
|
||||
|
||||
NOTE: KnoxApprovalController에서 제공하는 API URI은 Knox REST Service의 API URI와 같다.
|
||||
|
||||
. Knox 일반 결재 상신 +
|
||||
POST /knox/approvals/submit +
|
||||
* 파라미터는 KnoxApproval 클래스를 참고한다.
|
||||
|
||||
* attachments는 첨부파일, knoxApprovalStr는 KnoxApproval의 Json String 값이다.
|
||||
[source,java]
|
||||
----
|
||||
@PostMapping("/submit")
|
||||
public KnoxApproval submitGeneral(@Parameter(value = "첨부파일", required = true) MultipartFile attachments,
|
||||
@Parameter(value = "상신정보", required = true) String knoxApprovalStr) throws IOException {
|
||||
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
KnoxApproval knoxApproval = objectMapper.readValue(knoxApprovalStr, KnoxApproval.class);
|
||||
|
||||
String serverLocation = Account.currentUser().getServerLocation();
|
||||
if (StringUtils.isEmpty(serverLocation)) serverLocation = "KR";
|
||||
|
||||
String fileId = fileManagerService.store(attachments);
|
||||
List<Resource> fileList = new ArrayList<>();
|
||||
fileList.add(fileManagerService.getResource(fileId));
|
||||
|
||||
return knoxApprovalService.submit(knoxApproval, fileList, serverLocation);
|
||||
}
|
||||
----
|
||||
|
||||
[start=2]
|
||||
. Knox 보안 결재 상신 +
|
||||
POST /knox/approvals/secu-submit +
|
||||
* 파라미터는 일반 결재 상신과 같지만 보안문서타입이 "CONFIDENTAIL" 이다.
|
||||
[source,java]
|
||||
----
|
||||
knoxApproval.setDocSecuType("CONFIDENTAIL");
|
||||
----
|
||||
|
||||
[start=3]
|
||||
. Knox 결재 상세 상황 조회 +
|
||||
GET /knox/approvals/{apInfId}/detail +
|
||||
* 결재 연계 ID로 결재 문서의 정보를 상세 조회한다.
|
||||
|
||||
. Knox 결재 본문 조회 +
|
||||
GET /knox/approvals/{apInfId}/content +
|
||||
* 결재 연계 ID로 결재 문서의 본문을 조회한다.
|
||||
|
||||
. Knox 결재 상황 조회 +
|
||||
POST /knox/approvals/status +
|
||||
* 결재문서의 진행 상태를 조회한다.
|
||||
* 복수개의 결재 연계 ID를 요청하여 각각 해당하는 문서변경횟수와 결재상태정보를 응답받는다. 이를 이용하여 결재문서 동기화시 변경된 건에 대해 결재 상태를 업데이트 한다.
|
||||
[source,java]
|
||||
----
|
||||
public List<KnoxApprovalStatus> getStatus(@RequestBody List<KnoxApprovalStatus> knoxApprovalStatusList) {
|
||||
----
|
||||
|
||||
[start=6]
|
||||
. Knox 결재 연계 ID 조회 +
|
||||
POST /knox/approvals/apinfids +
|
||||
* 결재 ID로 결재 연계 ID를 조회한다.
|
||||
[source,java]
|
||||
----
|
||||
public KnoxApproval getApInfIds(@RequestParam String apId) {
|
||||
----
|
||||
|
||||
[start=7]
|
||||
. Knox 상신함 리스트 조회 +
|
||||
POST /knox/approvals/submission +
|
||||
* 상신자가 상신한 정보를 조회한다.
|
||||
[source,java]
|
||||
----
|
||||
public List<KnoxApproval> getApInfIdInfos(@RequestParam String epId) {
|
||||
----
|
||||
|
||||
[start=8]
|
||||
. Knox 연계 이력 조회 +
|
||||
GET /knox/approvals/apinfidinfos +
|
||||
* 요청 시스템에서 상신된 결재문서의 연계 이력을 조회한다.
|
||||
|
||||
. Knox 상신 취소 +
|
||||
POST /knox/approvals/{apInfId}/cancel +
|
||||
* 결재 문서를 상신취소한다.
|
||||
|
||||
. Knox 완결 처리 +
|
||||
POST /knox/approvals/{apInfId}/autoprogress +
|
||||
* 결재문서를 완결처리한다.
|
||||
|
||||
|
||||
== KnoxApprovalService
|
||||
|
||||
KnoxApprovalService는 시스템에서 결재 문서를 상신 할때 필요한 API들을 제공한다.
|
||||
|
||||
[source, java]
|
||||
----
|
||||
/**
|
||||
* 일반 상신, 보안 상신
|
||||
* @param knoxApproval
|
||||
* @param attachments
|
||||
* @param locale
|
||||
* @return
|
||||
*/
|
||||
KnoxApproval submit(KnoxApproval knoxApproval, List<Resource> attachments, String locale);
|
||||
|
||||
/**
|
||||
* 취소
|
||||
* @param apInfId
|
||||
* @param locale
|
||||
* @return
|
||||
*/
|
||||
KnoxApproval cancel(String apInfId, String opinion, String locale);
|
||||
|
||||
/**
|
||||
* 완결 처리
|
||||
* @param apInfId
|
||||
* @param locale
|
||||
* @return
|
||||
*/
|
||||
KnoxApproval autoProgress(String apInfId, String flag, String timeZone, String locale);
|
||||
|
||||
/**
|
||||
* 결재 상황 조회
|
||||
* @param knoxApprovalStatusList
|
||||
* @param locale
|
||||
* @return
|
||||
*/
|
||||
List<KnoxApprovalStatus> getStatus(List<KnoxApprovalStatus> knoxApprovalStatusList, String locale);
|
||||
|
||||
/**
|
||||
* 결재상세상황조회
|
||||
* @param apInfId
|
||||
* @param locale
|
||||
* @return
|
||||
*/
|
||||
KnoxApproval getDetail(String apInfId, String locale);
|
||||
|
||||
|
||||
/**
|
||||
* 결재본문조회
|
||||
* @param apInfId
|
||||
* @param locale
|
||||
* @return
|
||||
*/
|
||||
KnoxApproval getContent(String apInfId, String locale);
|
||||
|
||||
/**
|
||||
* 결재연계ID조회
|
||||
* @param apId
|
||||
* @return
|
||||
*/
|
||||
KnoxApproval getApInfIds(String apId, String locale);
|
||||
|
||||
/**
|
||||
* 상신함리스트조회
|
||||
* @param epId
|
||||
* @return
|
||||
*/
|
||||
List<KnoxApproval> getSubmission(String epId, String locale);
|
||||
|
||||
/**
|
||||
* 연계이력조회
|
||||
* @param endDate yyyyMMddHHmm 형식
|
||||
* @param page 페이지 처리
|
||||
* @param duration 단위 : 분 / 최소 1분 ~ 최대 60분
|
||||
* @return
|
||||
*/
|
||||
List<KnoxApproval> getApInfIdInfos(String endDate, String page, String duration, String locale);
|
||||
----
|
||||
|
||||
각각의 메서드들은 Knox Rest 연계 서비스에서 요구하는 가이드대로 REST 형식을 갖추어 필요한 로직들을 수행한다.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
= 결재 경로 관리
|
||||
|
||||
== 개요
|
||||
시스템의 결재 문서 샘플을 RUNTIME 동안 가지고 있다가 결재시에 사용한다.
|
||||
|
||||
* ApprovalManager.java -> ApprovalDocument.java -> SampleApprovalDocument.java
|
||||
. ApprovalManager : @ApprovalDocument라는 어노테이션이 달린 클래스를 찾는다.
|
||||
. SampleApprovalDocument : 결재경로 관리 목록에 결재 문서 샘플을 보여준다.
|
||||
|
||||
== Table
|
||||
* 결재 경로 : TN_CF_DYNAMIC_APPROVAL_PATH
|
||||
* 필수 결재자 : TN_CF_REQUIRED_APPROVAL_USER
|
||||
|
||||
== API
|
||||
.ApprovalController.java
|
||||
|
||||
. 시스템 전체 결재 문서 조회 +
|
||||
GET /approval/approval-doc-types
|
||||
|
||||
. 결재 경로 조회 +
|
||||
GET /approval/dynamic-approval-paths/{docType} +
|
||||
Query ID : selectDynamicApprovalPath
|
||||
* 기본결재 경로 목록을 보여준다.
|
||||
|
||||
. 결재 경로 저장 +
|
||||
POST /approval/dynamic-approval-paths/{docType} +
|
||||
Query ID : deleteDynamicApprovalPath, insertDynamicApprovalPath
|
||||
|
||||
. 필수 결재자 목록 조회 +
|
||||
GET /approval/required-approval-users/{docType} +
|
||||
Query ID : selectRequiredApprovalUserList
|
||||
* 필수 결재자 목록을 보여준다.
|
||||
|
||||
. 필수 결재자 저장 +
|
||||
POST /approval/required-approval-users/{docType} +
|
||||
Query ID : deleteRequiredApprovalUser, insertRequiredApprovalUser
|
||||
|
||||
== 화면
|
||||
지정된 문서타입에 따른 결재경로를 관리기능 > 결재/메일 관리 > 결재경로 관리를 통해 지정할 수 있다.
|
||||
|
||||
image::front_07_04.png[]
|
||||
* 지정된 문서타입 목록을 확인할 수 있다.
|
||||
|
||||
image::front_07_05.png[]
|
||||
* 문서타입을 선택 후 해당 문서에 대한 기본 결재경로와 필수 결재자를 추가할 수 있다.
|
||||
* 결재 상신시 결재자 목록에 지정된 기본결재 경로가 자동 추가되며, 지정된 필수 결재자가 있는 경우 추가하라는 알림을 준다. (다수중 1인 가능)
|
||||
@@ -0,0 +1,35 @@
|
||||
= 결재 관리
|
||||
|
||||
== 개요
|
||||
결재 관리를 통해 내부/knox 결재 목록을 확인할 수 있다.
|
||||
|
||||
== Table
|
||||
* 결재 : TN_CF_APPROVAL
|
||||
* 결재 이벤트 : TN_CF_APPROVAL_EVENT
|
||||
* 결재 스텝 : TN_CF_APPROVAL_STEP
|
||||
|
||||
== API
|
||||
.ApprovalController.java
|
||||
|
||||
. 시스템 전체 결재 문서 조회 +
|
||||
GET /approval/approval-doc-types +
|
||||
* 결재경로 관리의 문서타입을 가져온다.
|
||||
|
||||
. 시스템 전체 결재 목록 조회(페이징) +
|
||||
GET /approval/approval-with-paging +
|
||||
Query ID : selectApprovalPagingList
|
||||
|
||||
. 결재 상세정보 조회 +
|
||||
GET /approval/{approvalRequestId} +
|
||||
Query ID : selectApprovalStep, selectApprovalEventList
|
||||
|
||||
== 화면
|
||||
image::front_07_01.png[]
|
||||
|
||||
=== 검색 조건
|
||||
** 구분 : knox 결재/ 내부결재
|
||||
** 상태 : 결재중/완료/후완결/반려/취소
|
||||
** 문서명 : 결재양식 목록
|
||||
** 상신자 : 결재 요청한 상신자
|
||||
** 동기화 상태 : 성공/실패
|
||||
** 기간 : 결재요청 기간
|
||||
@@ -0,0 +1,56 @@
|
||||
= 결재 양식 관리
|
||||
|
||||
== 개요
|
||||
결재 양식을 관리한다.
|
||||
|
||||
== Table
|
||||
* 템플릿 : TN_CF_TEMPLATE
|
||||
|
||||
== API
|
||||
.TemplateController.java
|
||||
|
||||
. 템플릿 목록 조회(페이징) +
|
||||
GET /templates-with-paging/group/{templateGroupCode} +
|
||||
Query ID : selectTemplatePagingList
|
||||
* TEMPLATE_GROUP_CODE 컬럼의 'APPROVAL'을 조회한다.
|
||||
|
||||
. 템플릿 상세 조회 +
|
||||
GET /templates/group/{templateGroupCode}/key/{templateKey} +
|
||||
Query ID : selectTemplate
|
||||
|
||||
. 템플릿 상세 조회 (By ID) +
|
||||
GET /templates/{id} +
|
||||
Query ID : selectTemplate
|
||||
* 양식의 상세 내용을 조회 하거나 팝업 미리보기를 할 수 있다.
|
||||
|
||||
. 템플릿 Key 중복 체크 +
|
||||
GET /templates/dup-check/group/{templateGroupCode}/key/{templateKey} +
|
||||
Query ID : selectTemplate
|
||||
* 저장 전 템플릿 Key 중복 여부를 검사한다.
|
||||
|
||||
. 템플릿 등록 +
|
||||
POST /templates/group/{templateGroupCode} +
|
||||
Query ID : insertTemplate
|
||||
* 양식을 저장한다.
|
||||
|
||||
. 템플릿 수정 +
|
||||
POST /templates/{id} +
|
||||
Query ID : updateTemplate
|
||||
|
||||
. 템플릿 삭제 +
|
||||
DELETE /templates/{id} +
|
||||
Query ID : deleteTemplate
|
||||
|
||||
== 화면
|
||||
결재양식을 관리기능 > 결재/메일관리 > 결재양식 관리를 통해 볼 수 있다.
|
||||
|
||||
image::front_07_06.png[]
|
||||
* 등록된 결재양식 목록을 결재양식 관리를 통해 볼 수 있다.
|
||||
* 목록의 Key 컬럼을 클릭하여 결재양식 정보를 수정할 수 있다.
|
||||
* 팝업 미리보기 컬럼을 클릭하여 등록된 결재양식의 첨부파일을 확인 할 수 있다.
|
||||
|
||||
image::front_07_07.png[]
|
||||
* Key : 유니크한 결재양식 키를 지정(영문, 숫자만 가능)
|
||||
* 제목 : 결재양식의 제목
|
||||
* 설명 : 결재양식의 설명
|
||||
* 첨부파일 : 결재양식 첨부파일
|
||||
@@ -0,0 +1,111 @@
|
||||
= 내부 결재
|
||||
|
||||
== 개요
|
||||
SDL에서 제공하는 내부결재 기능. +
|
||||
결재를 위한 문서 Entity등록과 내부결재 후처리를 위한 Interceptor 클래스 구현으로 간단하게 결재 기능을 구현할 수 있다. +
|
||||
샘플로 제공하는 화면의 결재 스텝을 지정하는 Component를 필요한 결재 문서 화면에 적용하여 사용할 수 있으며 샘플 Controller를 참조하여 문서와 결재 스텝 목록을 저장하여 approvalService.submit 메소드를 호출하면 된다.
|
||||
|
||||
== Table
|
||||
* 결재 정보 : TN_CF_APPROVAL
|
||||
* 결재 스텝 정보 : TN_CF_APPROVAL_STEP
|
||||
* Sample Document : TN_CF_SAMPLE_APPROVAL_INTERNAL_DOCUMENT
|
||||
|
||||
== API
|
||||
.ApprovalController.java
|
||||
|
||||
. 상신함 목록 조회(내부 결재) +
|
||||
GET /internal-approvals/submit +
|
||||
Query ID : selectInternalApprovalPagingListBySubmit
|
||||
* 사용자가 상신한 내부결재 문서를 조회한다.
|
||||
|
||||
. 미결함 목록 조회(내부 결재) +
|
||||
GET /internal-approvals/not-approve +
|
||||
Query ID : selectInternalApprovalPagingListByNotApprove
|
||||
* 미결중인 내부결재 문서를 조회한다.
|
||||
|
||||
. 기결함 목록 조회(내부 결재) +
|
||||
GET /internal-approvals/approved +
|
||||
Query ID : selectInternalApprovalPagingListByApproved
|
||||
* 사용자가 결재 완료한 내부결재 문서를 조회한다.
|
||||
|
||||
. 통보함 목록 조회(내부 결재) +
|
||||
GET /internal-approvals/notice +
|
||||
Query ID : selectInternalApprovalPagingListByNotice
|
||||
* 사용자가 통보 대상인 결재문서를 조회한다.
|
||||
|
||||
. 내부결재 문서 상신 취소 +
|
||||
POST /internal-approvals/{approvalRequestId}/cancel +
|
||||
Service : cancelInternalApproval
|
||||
Query ID : updateInternalApprovalStep
|
||||
* 결재 문서 상신을 취소한다.
|
||||
|
||||
. 내부결재 문서 결재 승인 또는 합의 +
|
||||
POST /internal-approvals/{approvalRequestId}/confirm +
|
||||
Service : confirmInternalApproval
|
||||
Query ID : updateInternalApprovalStep
|
||||
* 결재 문서 승인 또는 합의 한다.
|
||||
|
||||
. 내부결재 문서 반려 +
|
||||
POST /internal-approvals/{approvalRequestId}/reject +
|
||||
Service : rejectInternalApproval
|
||||
Query ID : updateInternalApprovalStep
|
||||
* 결재 문서를 반려 한다.
|
||||
|
||||
.ApprovalSampleController.java
|
||||
|
||||
. 내부결재 문서 목록 조회(페이징) +
|
||||
GET /internal-approval/sample-document-with-paging +
|
||||
Query ID : selectSampleApprovalDocumentPagingList
|
||||
* Sample Document 문서 목록을 조회한다.
|
||||
|
||||
. 내부 결재 문서 상신(Sample Document) +
|
||||
POST /internal-approval/submit/sample-document
|
||||
* Knox 결재 정보 동기화 로직을 제외한 다른 부분은 Knox 결재 상신과 동일하다.
|
||||
* 동기화 배치 로직 대상에서 제외된다.
|
||||
* 내부결재 전후 처리 로직은 문서 타입별로 Interceptor 클래스를 구현하여 처리한다.
|
||||
[source,java]
|
||||
----
|
||||
@Log4j2
|
||||
@ApprovalDocumentType(names = {"internalSample"})
|
||||
public class InternalApprovalSampleInterceptor implements ApprovalInterceptor {
|
||||
|
||||
@Autowired
|
||||
InternalApprovalSampleService internalApprovalSampleService;
|
||||
@Override
|
||||
public void afterSubmit(Approval approval, List<ApprovalStep> approvalStepList, Map<String, Object> attribute) {
|
||||
log.debug("execute ApprovalSampleInterceptor afterSubmit");
|
||||
//상신 후 문서 상태 업데이트
|
||||
internalApprovalSampleService.updateSampleApprovalDocument(approval.getDbDocId(), ApprovalDocStatus.INPROCESS);
|
||||
}
|
||||
--생략--
|
||||
}
|
||||
----
|
||||
|
||||
== 화면
|
||||
|
||||
. 내부결재 문서 상신함
|
||||
|
||||
image::internalApproval_01.png[]
|
||||
image::internalApproval_05.png[]
|
||||
* 사용자가 상신한 내부결재 문서 목록을 조회한다.
|
||||
* 상세화면에 진입하여 상신취소가 가능하다.
|
||||
|
||||
[start=2]
|
||||
. 내부결재 문서 미결함
|
||||
|
||||
image::internalApproval_02.png[]
|
||||
image::internalApproval_06.png[]
|
||||
* 사용자의 결재 차순에 있는 내부결재 문서 목록을 조회한다.
|
||||
* 상세화면에 진입하여 승인/합의 또는 반려가 가능하다.
|
||||
|
||||
[start=3]
|
||||
. 내부결재 문서 기결함
|
||||
|
||||
image::internalApproval_03.png[]
|
||||
* 사용자의 결재 완료한 내부결재 문서 목록을 조회한다.
|
||||
|
||||
[start=4]
|
||||
. 내부결재 문서 통보함
|
||||
|
||||
image::internalApproval_04.png[]
|
||||
* 결재 완료 후 사용자에게 통보된 내부결재 문서 목록을 조회한다.
|
||||
@@ -0,0 +1,35 @@
|
||||
= 대리 결재
|
||||
|
||||
== 개요
|
||||
내부결재에 적용되는 대리결재자를 지정하는 기능을 제공한다. +
|
||||
(Knox 결재 대리결재는 Knox portal에서 지정 가능함) +
|
||||
|
||||
== Table
|
||||
* 결재 정보 : TN_CF_APPROVAL_DELEGATE
|
||||
|
||||
== API
|
||||
.ApprovalController.java
|
||||
|
||||
. 대리결재자 조회 +
|
||||
GET /approval/approver-delegate +
|
||||
Query ID : selectApproverDelegate
|
||||
* 사용자의 대리결재자를 조회한다.
|
||||
|
||||
. 대리결재자 저장 +
|
||||
POST /approval/approver-delegate +
|
||||
Query ID : updateApproverDelegate, insertApproverDelegate
|
||||
* 사용자의 대리결재자를 저장한다.(등록 또는 변경)
|
||||
|
||||
. 대리결재자 삭제 +
|
||||
DELETE /approval/approver-delegate +
|
||||
Query ID : deleteApproverDelegate
|
||||
* 사용자의 대리결재자를 삭제한다.
|
||||
|
||||
== 화면
|
||||
|
||||
. 대리결재자 조회 및 지정
|
||||
|
||||
image::approverDelegate_01.png[]
|
||||
|
||||
* 사용자 정보 > 대리결재 메뉴를 통해서 대리결재자 등록이 가능하다.
|
||||
* 기등록된 대리결재자가 존재한다면 대리결재자 팝업 상단에 표시되며 삭제하거나 다른 사용자를 선택하여 변경가능 하다.
|
||||
@@ -0,0 +1,85 @@
|
||||
= 메신저
|
||||
|
||||
== 개요
|
||||
Knox Portal에서 제공하는 메신저 관련 Rest API 를 이용한 연계 서비스 제공
|
||||
|
||||
=== Knox REST API 연계 서비스 신청
|
||||
Knox REST API 연계 서비스 신청은 <<_knox_rest_api_연계_서비스_신청,Knox REST API 연계 서비스 신청>> 항목을 참조한다.
|
||||
|
||||
=== Knox Rest 메신저 연계 설정
|
||||
메일, 결재 Knox Rest API 연계와 마찬가지로 연계를 위한 사전 준비가 되었다면, knox.properties 에 메신저 관련 설정이 되어 있는지 확인한다.
|
||||
|
||||
.knox.properties
|
||||
[source,properties]
|
||||
----
|
||||
knox.messenger.contact-service=/messenger/contact/api/v1.0
|
||||
knox.messenger.msgctx-service=/messenger/msgctx/api/v1.0
|
||||
knox.messenger.message-service=/messenger/message/api/v1.0
|
||||
----
|
||||
|
||||
=== Knox 메신저 연계 서비스
|
||||
REST를 통해서 메신저와 연계하는 서비스로 주요 메서드는 KnoxMessengerService 인터페이스에 정의되어 있다.
|
||||
|
||||
[source, java]
|
||||
----
|
||||
public interface KnoxMessengerService {
|
||||
|
||||
/**
|
||||
* 디바이스 ID 조회 : 사용자 ID 와 맵핑되는 단말의 ID 값
|
||||
* @return 디바이스 ID
|
||||
*/
|
||||
String getDeviceId();
|
||||
|
||||
/**
|
||||
* 메시지 암호화 키 조회 : 메시지를 암호화하기 위한 키 값
|
||||
* @param deviceId 디바이스 ID
|
||||
* @return 메시지 암호화 키
|
||||
*/
|
||||
String getKey(String deviceId);
|
||||
|
||||
/**
|
||||
* Knox Potal login ID를 이용하여 Knox Messenger 수신자들을 조회한다.
|
||||
* @param deviceId 디바이스 ID
|
||||
* @param singleIds 수신자 Knox ID 리스트
|
||||
* @return Knox Messenger 수신자 ID 리스트
|
||||
*/
|
||||
List<String> getUserIds(String deviceId, List<String> singleIds);
|
||||
|
||||
/**
|
||||
* 공지 메시지를 발신할 대화방이 없는 경우 신규 대화방 생성을 요청한다.
|
||||
* @param deviceId 디바이스 ID
|
||||
* @param key 암호화 키
|
||||
* @param userIds Knox Messenger 수신자 ID 리스트
|
||||
* @return 대화방 생성 요청 응답 결과
|
||||
*/
|
||||
Map<String, Object> createChatroom(String deviceId, String key, List<String> userIds);
|
||||
|
||||
/**
|
||||
* Message 서버 API 에서 필요한 암호화된 바디를 만들기 위한 function
|
||||
* @param key - msgCtx 를 통해 전달받은 key 값
|
||||
* @param body - 암호화 해야 될 String
|
||||
* @return 암호화된 String
|
||||
*/
|
||||
String encrypt(String key, String body);
|
||||
|
||||
/**
|
||||
* Response 로 전달된 암호화 body 를 복호화 하기 위한 function <br/>
|
||||
* 암호화의 역순으로 Base64 복호화 -> AES256 복호화
|
||||
* @param body - 암호화 되어 있는 body
|
||||
* @return 복호화된 response String
|
||||
*/
|
||||
String decrypt(String body);
|
||||
|
||||
/**
|
||||
* 신규 생성한 대화방 또는 기존에 사용중인 대화방에 공지 메시지를 발송한다.
|
||||
* @param deviceId 디바이스 ID
|
||||
* @param key 암호화 키
|
||||
* @param chatroomId 생성된 대화방 ID
|
||||
* @param chatMsg 메시지 내용
|
||||
* @return 메시지 발신 요청 응답 결과
|
||||
*/
|
||||
Map<String, Object> chat(String deviceId, String key, String chatroomId, String chatMsg);
|
||||
}
|
||||
----
|
||||
|
||||
자세한 API 스펙은 Swagger API 문서의 knox-messenger-controller 항목을 참고한다.
|
||||
@@ -0,0 +1,75 @@
|
||||
= 메일
|
||||
|
||||
=== Knox REST API 연계 서비스 신청
|
||||
Knox REST API 연계 서비스 신청은 <<_knox_rest_api_연계_서비스_신청,Knox REST API 연계 서비스 신청>> 항목을 참조한다.
|
||||
|
||||
=== Knox메일 연계 설정
|
||||
Knox REST API 연계 서비스 신청이 되었다면, 발급받은 `system-id`, `token` 값을 설정한다.
|
||||
|
||||
.knox.properties (스테이지)
|
||||
[source,properties]
|
||||
----
|
||||
knox.system-id=xxxxxxxxxxx
|
||||
knox.token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
knox.address.prefix=openapi.samsung.net
|
||||
knox.mail-service=/mail/api/v2.0
|
||||
----
|
||||
|
||||
.knox.properties (운영)
|
||||
[source,properties]
|
||||
----
|
||||
knox.system-id=xxxxxxxxxxx
|
||||
knox.token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx // <1>
|
||||
knox.address.prefix=openapi.samsung.net,openapi.w1.samsung.net,openapi.w2.samsung.net # <2>
|
||||
knox.mail-service=/mail/api/v2.0
|
||||
----
|
||||
<1> 토큰 (comma(,)로 구분, 거점 순서와 동일)
|
||||
<2> 거점 (국내, 구주, 미주)
|
||||
|
||||
=== KnoxMailService
|
||||
Knox REST API 연계를 통해서 메일발신, 상태조회등을 하는 서비스로 주요 메서드는 KnoxMailService 인터페이스에 정의되어 있다.
|
||||
|
||||
KnoxMailService는 시스템에서 Knox 메일 서비스와 연계할 때 필요한 API들을 제공한다.
|
||||
|
||||
[source, java]
|
||||
----
|
||||
public interface KnoxMailService {
|
||||
/**
|
||||
* Knox 메일 발신
|
||||
* @param sendMail 발신 메일 정보 (첨부파일정보(AttachFile) 포함)
|
||||
* @return Knox 메일 아이디
|
||||
*/
|
||||
String sendMail(SendMail sendMail);
|
||||
|
||||
/**
|
||||
* Knox 메일 발신
|
||||
* @param sendMail 발신 메일 정보
|
||||
* @param attachResources 메일 첨부가 파일 리소스일 경우
|
||||
* @return Knox 메일 아이디
|
||||
*/
|
||||
String sendMail(SendMail sendMail, List<Resource> attachResources);
|
||||
|
||||
/**
|
||||
* Knox 메일별 수신상태 조회
|
||||
* @param mailIds Knox 메일 아이디 리스트
|
||||
* @param sendMail 메일 정보
|
||||
* @return Knox 메일 상태
|
||||
*/
|
||||
MailStatus[] getDeliveryStatusCount(List<String> mailIds, SendMail sendMail);
|
||||
|
||||
/**
|
||||
* Knox 메일 수신인별 수신상태 조회
|
||||
* @param mailId Knox 메일 아이디
|
||||
* @param sendMail 메일 정보
|
||||
* @return Knox 메일 수신인별 수신상태 정보
|
||||
*/
|
||||
Recipient[] getDeliveryStatus(String mailId, SendMail sendMail);
|
||||
}
|
||||
----
|
||||
|
||||
각각의 구현 메서드들은 Knox Rest 연계 서비스에서 요구하는 가이드대로 REST 형식을 갖추어 필요한 로직들을 수행한다.
|
||||
|
||||
자세한 API 스펙은 Swagger API 문서의 knox-mail-controller 항목을 참고한다. +
|
||||
메일 발송 샘플 코드는 MailSampleController 소스코드를 참고한다.
|
||||
|
||||
IMPORTANT: Knox 연계 메일 발송을 위해서는 발신자/수신자 모두 Knox 계정이 존재해야만 테스트가 가능하다.
|
||||
@@ -0,0 +1,161 @@
|
||||
= 메일 그룹 관리
|
||||
|
||||
== 개요
|
||||
|
||||
메일 그룹 및 맵핑 정보 관리 기능 제공.
|
||||
|
||||
== UI Design & Function
|
||||
|
||||
=== 메일 그룹 목록(MailGroupList.vue)
|
||||
|
||||
메일 그룹 등록, 수정 및 삭제가 가능하다.
|
||||
|
||||
image::mailGroupList.png[mailGroupList.png]
|
||||
|
||||
* 기능 설명
|
||||
. 메일 그룹 목록 조회
|
||||
. 메일 그룹 상세정보 조회
|
||||
. 메일 그룹 등록 : 등록 버튼 클릭 시 메일 그룹 입력 popup 호출.
|
||||
. 메일 그룹 수정 : checkbox 선택 후 수정 버튼 클릭 시 변경을 위한 popup 호출.
|
||||
. 메일 그룹 삭제 : checkbox 선택 후 삭제 버튼 클릭 시 삭제.
|
||||
|
||||
|
||||
=== 메일 그룹 맵핑 수정(MailGroupMappEdit.vue)
|
||||
|
||||
메일 그룹 맵핑 목록 등록 및 삭제가 가능하다.
|
||||
|
||||
image::mailGroupMappEdit.png[mailGroupMappList.png]
|
||||
|
||||
* 기능 설명
|
||||
. 메일 그룹 맵핑 목록 조회
|
||||
. 메일 그룹 맵핑 저장
|
||||
.. 사용자 추가 : 버튼 클릭 시 사용자 추가 popup 호출.
|
||||
.. 역할 추가 : 버튼 클릭 시 역할 추가 popup 호출.
|
||||
.. 업무그룹 추가 : 버튼 클릭 시 업무그룹 추가 popup 호출.
|
||||
|
||||
== API & Service
|
||||
|
||||
=== API
|
||||
|
||||
* API : MailGroupController.java
|
||||
|
||||
. 메일 그룹 목록 조회 : GET /mail-group-with-paging
|
||||
. 메일 그룹 상세정보 조회 : GET /mail-group/{mailGroupId}
|
||||
. 메일 그룹 등록 : POST /mail-group
|
||||
. 메일 그룹 수정 : PUT /mail-group
|
||||
. 메일 그룹 삭제 : DELETE /mail-group
|
||||
. 메일 그룹 맵핑 목록 조회 : GET /mail-group-mapp-with-paging
|
||||
. 메일 그룹 맵핑 저장 : POST /mail-group-mapp/{mailGroupId}
|
||||
|
||||
* Service : MailGroupServiceImpl.java
|
||||
|
||||
. 메일 그룹 맵핑 저장 +
|
||||
맵핑 정보 저장 시 기등록 되어 있는 맵핑 목록 삭제 후
|
||||
전체 목록을 다시 저장하도록 구현.
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Override
|
||||
@Transactional
|
||||
public void saveMailGroupMapp(String mailGroupId, List<MailGroupMapp> mailGroupMappList) {
|
||||
|
||||
mailGroupDao.deleteMailGroupMapp(mailGroupId);
|
||||
|
||||
for(MailGroupMapp mailGroupMapp : mailGroupMappList) {
|
||||
mailGroupMapp.setMailGroupId(mailGroupId);
|
||||
mailGroupDao.insertMailGroupMapp(mailGroupMapp);
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
|
||||
|
||||
== Entity Table & SQL
|
||||
|
||||
=== Entity Table
|
||||
|
||||
* TN_CF_MAIL_GROUP : 메일 그룹
|
||||
* TN_CF_MAIL_GROUP_MAPP : 메일 그룹 맵핑
|
||||
|
||||
=== SQL
|
||||
|
||||
. 메일 그룹 목록 조회
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<select id="selectMailGroupPagingList" parameterType="java.util.HashMap" resultMap="mailGroupResult">
|
||||
SELECT T.*
|
||||
FROM (SELECT ROW_NUMBER() OVER(ORDER BY LABEL ASC) ROWNUM,
|
||||
--생략--
|
||||
----
|
||||
|
||||
[start=2]
|
||||
. 메일 그룹 상세정보 조회
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<select id="selectMailGroup" parameterType="java.util.HashMap" resultMap="mailGroupResult">
|
||||
SELECT <include refid="columnMailGroup" />,
|
||||
(SELECT USER_NAME
|
||||
--생략--
|
||||
----
|
||||
|
||||
[start=3]
|
||||
. 메일그룹 등록
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<insert id="insertMailGroup" parameterType="java.util.HashMap">
|
||||
INSERT INTO <include refid="tableMailGroup" />
|
||||
(<include refid="columnMailGroup" />)
|
||||
--생략--
|
||||
----
|
||||
|
||||
[start=4]
|
||||
. 메일그룹 수정
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<update id="updateMailGroup" parameterType="java.util.HashMap">
|
||||
UPDATE <include refid="tableMailGroup" />
|
||||
SET LABEL = #{label},
|
||||
--생략--
|
||||
----
|
||||
|
||||
[start=5]
|
||||
. 메일그룹 삭제
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<delete id="deleteMailGroup" parameterType="java.util.HashMap">
|
||||
UPDATE <include refid="tableMailGroup" />
|
||||
SET DELETED = '1',
|
||||
--생략--
|
||||
----
|
||||
|
||||
[start=6]
|
||||
. 메일그룹 맵핑 목록 조회
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<delete id="deleteMailGroup" parameterType="java.util.HashMap">
|
||||
UPDATE <include refid="tableMailGroup" />
|
||||
SET DELETED = '1',
|
||||
--생략--
|
||||
----
|
||||
|
||||
[start=7]
|
||||
. 메일그룹 맵핑 저장
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<delete id="deleteMailGroupMapp" parameterType="java.util.HashMap">
|
||||
DELETE FROM <include refid="tableMailGroupMapp" />
|
||||
WHERE MAIL_GROUP_ID = #{mailGroupId}
|
||||
</delete>
|
||||
|
||||
<insert id="insertMailGroupMapp" parameterType="java.util.HashMap">
|
||||
INSERT INTO <include refid="tableMailGroupMapp" />
|
||||
(<include refid="columnMailGroupMapp" />)
|
||||
--생략--
|
||||
----
|
||||
@@ -0,0 +1,87 @@
|
||||
= 메일 상태 조회
|
||||
|
||||
== 개요
|
||||
Knox REST 메일수신상황조회 API와 연계하여 발신한 메일의 상태를 조회할 수 있다.
|
||||
|
||||
=== Knox메일 연계 설정
|
||||
Knox REST 메일수신상황조회를 위해서는 Knox메일 연계 설정이 되어 있어야 한다. +
|
||||
Knox메일 연계 설정은 <<_메일,메일>> 항목의 <<_knox메일_연계_설정,Knox메일 연계 설정>> 항목을 참조한다.
|
||||
|
||||
=== 메일별 수신 상황 카운트 조회
|
||||
발신한 메일의 메일 아이디값을 이용하여 발신한 메일을 수신한 수신자들의 개봉상태를
|
||||
요약한 카운트 정보조회
|
||||
|
||||
Service:: KnoxMailService
|
||||
|
||||
Method::
|
||||
+
|
||||
[source,java]
|
||||
----
|
||||
/**
|
||||
* Knox 메일별 수신상태 조회
|
||||
* @param mailIds Knox 메일 아이디 리스트
|
||||
* @param sendMail 메일 정보
|
||||
* @return Knox 메일 상태
|
||||
*/
|
||||
MailStatus[] getDeliveryStatusCount(List<String> mailIds, SendMail sendMail);
|
||||
----
|
||||
* SendMail 객체에 senderId (발신자 EP ID) 값 설정 필수
|
||||
|
||||
=== 수신인 별 수신 상황 조회
|
||||
발신한 메일의 메일 아이디값을 이용하여 발신한 메일의 수신자 별 수신 상태 정보를 조회
|
||||
|
||||
Service:: KnoxMailService
|
||||
|
||||
Method::
|
||||
+
|
||||
[source,java]
|
||||
----
|
||||
/**
|
||||
* Knox 메일 수신인별 수신상태 조회
|
||||
* @param mailId Knox 메일 아이디
|
||||
* @param sendMail 메일 정보
|
||||
* @return Knox 메일 수신인별 수신상태 정보
|
||||
*/
|
||||
Recipient[] getDeliveryStatus(String mailId, SendMail sendMail);
|
||||
----
|
||||
* SendMail 객체에 senderId (발신자 EP ID) 값 설정 필수
|
||||
|
||||
=== 사용 예
|
||||
.SentMailHistoryServiceImpl
|
||||
[source,java]
|
||||
----
|
||||
@Override
|
||||
public Map<String, Object> getSentMail(String mailId) {
|
||||
Map<String, Object> rtnMap = new HashMap<>();
|
||||
MailStatus mailStatus = new MailStatus();
|
||||
List<Recipient> recipientList;
|
||||
|
||||
List<String> mailIds = new ArrayList<>();
|
||||
mailIds.add(mailId);
|
||||
SendMail sendMail = sentMailHistoryDao.getSentMail(mailId);
|
||||
|
||||
try {
|
||||
// 14일 이전 문서는 Knox에서 조회
|
||||
mailStatus = knoxMailService.getDeliveryStatusCount(mailIds, sendMail)[0]; // <1>
|
||||
recipientList = Arrays.asList(knoxMailService.getDeliveryStatus(mailId, sendMail)); // <2>
|
||||
|
||||
if (ObjectUtils.isNotEmpty(recipientList)) {
|
||||
// 메일 수신 상태 동기화
|
||||
updateRecipient(mailId, recipientList);
|
||||
} else {
|
||||
recipientList = sentMailHistoryDao.getRecipientList(mailId);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
log.error(ex.getMessage());
|
||||
//Knox 에서 메일을 조회 할수 없을 경우, 14일이 경과 되었거나 Mail Box를 못찾을 경우
|
||||
recipientList = sentMailHistoryDao.getRecipientList(mailId);
|
||||
}
|
||||
|
||||
rtnMap.put("mailStatus", mailStatus);
|
||||
rtnMap.put("recipientList", recipientList);
|
||||
rtnMap.put("sendMail", sendMail);
|
||||
return rtnMap;
|
||||
}
|
||||
----
|
||||
<1> Knox 메일별 수신자들의 개봉상태 카운트 조회
|
||||
<2> Knox 수신인 별 메일 수신 상황 조회
|
||||
@@ -0,0 +1,58 @@
|
||||
= 메일 양식 관리
|
||||
|
||||
== 개요
|
||||
메일 양식을 관리한다. +
|
||||
<<_결재_양식_관리,결재 양식 관리>>와 비교해서 'MAIL'로 조회하는 것 외에 동일하다.
|
||||
|
||||
== Table
|
||||
* 템플릿 : TN_CF_TEMPLATE
|
||||
|
||||
== API
|
||||
.TemplateController.java
|
||||
|
||||
. 템플릿 목록 조회(페이징) +
|
||||
GET /templates-with-paging/group/{templateGroupCode} +
|
||||
Query ID : selectTemplatePagingList
|
||||
* TEMPLATE_GROUP_CODE 컬럼의 'MAIL'을 조회한다.
|
||||
|
||||
. 템플릿 상세 조회 +
|
||||
GET /templates/group/{templateGroupCode}/key/{templateKey} +
|
||||
Query ID : selectTemplate
|
||||
|
||||
. 템플릿 상세 조회 (By ID) +
|
||||
GET /templates/{id} +
|
||||
Query ID : selectTemplate
|
||||
* 양식의 상세 내용을 조회 하거나 팝업 미리보기를 할 수 있다.
|
||||
|
||||
. 템플릿 Key 중복 체크 +
|
||||
GET /templates/dup-check/group/{templateGroupCode}/key/{templateKey} +
|
||||
Query ID : selectTemplate
|
||||
* 저장 전 템플릿 Key 중복 여부를 검사한다.
|
||||
|
||||
. 템플릿 등록 +
|
||||
POST /templates/group/{templateGroupCode} +
|
||||
Query ID : insertTemplate
|
||||
* 양식을 저장한다.
|
||||
|
||||
. 템플릿 수정 +
|
||||
POST /templates/{id} +
|
||||
Query ID : updateTemplate
|
||||
|
||||
. 템플릿 삭제 +
|
||||
DELETE /templates/{id} +
|
||||
Query ID : deleteTemplate
|
||||
|
||||
== 화면
|
||||
|
||||
메일양식을 관리기능 > 결재/메일관리 > 메일양식 관리를 통해 할 수 있다.
|
||||
|
||||
image::mailTemplate.png[]
|
||||
* 등록된 메일양식 목록을 메일양식 관리를 통해 볼 수 있다.
|
||||
* 목록의 Key 컬럼을 클릭하여 메일양식 정보를 수정할 수 있다.
|
||||
* 팝업 미리보기 컬럼을 클릭하여 등록된 메일양식의 첨부파일을 확인 할 수 있다.
|
||||
|
||||
image::mailTemplate1.png[]
|
||||
* Key : 유니크한 메일양식 키를 지정(영문, 숫자만 가능)
|
||||
* 제목 : 메일양식의 제목
|
||||
* 설명 : 메일양식의 설명
|
||||
* 첨부파일 : 메일양식 첨부파일
|
||||
@@ -0,0 +1,19 @@
|
||||
= 보낸 메일 이력
|
||||
|
||||
== 개요
|
||||
메일 발송 내역 및 수신 상태를 조회할 수 있다.
|
||||
|
||||
=== 보낸 메일 목록
|
||||
|
||||
image::sentMailHistory.png[]
|
||||
|
||||
<1> 기간, 제목별 검색 가능
|
||||
<2> 클릭시 상세 내역 조회
|
||||
|
||||
=== 보낸 메일 상세 정보
|
||||
|
||||
image::sentMailHistoryInfo.png[]
|
||||
|
||||
<1> 보낸 메일의 수신인별 개봉 여부
|
||||
<2> 보낸 메일 본문 확인 가능
|
||||
<3> 수신인과 수신상태 정보 목록
|
||||
@@ -0,0 +1,93 @@
|
||||
= 임직원
|
||||
|
||||
== 개요
|
||||
Knox Portal에서 제공하는 임직원 관련 Rest API 를 이용한 연계 서비스 제공
|
||||
|
||||
=== Knox REST API 연계 서비스 신청
|
||||
Knox REST API 연계 서비스 신청은 <<_knox_rest_api_연계_서비스_신청,Knox REST API 연계 서비스 신청>> 항목을 참조한다.
|
||||
|
||||
=== Knox임직원 연계 설정
|
||||
Knox REST API 연계 서비스 신청이 되었다면, 발급받은 `system-id`, `token` 값을 설정한다.
|
||||
|
||||
.knox.properties (스테이지)
|
||||
[source,properties]
|
||||
----
|
||||
knox.system-id=xxxxxxxxxxx
|
||||
knox.token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
knox.address.prefix=openapi.samsung.net
|
||||
knox.emp-service=/employee/api/v2.0
|
||||
----
|
||||
|
||||
.knox.properties (운영)
|
||||
[source,properties]
|
||||
----
|
||||
knox.system-id=xxxxxxxxxxx
|
||||
knox.token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx // <1>
|
||||
knox.address.prefix=openapi.samsung.net,openapi.w1.samsung.net,openapi.w2.samsung.net # <2>
|
||||
knox.emp-service=/employee/api/v2.0
|
||||
----
|
||||
<1> 토큰 (comma(,)로 구분, 거점 순서와 동일)
|
||||
<2> 거점 (국내, 구주, 미주)
|
||||
|
||||
=== Knox임직원 API 연계 서비스
|
||||
Knox REST API 연계를 통해서 임직원 및 조직 정보 조회 기능을 제공하는 서비스로 주요 메서드는 KnoxUserService 인터페이스에 정의되어 있다.
|
||||
|
||||
KnoxUserService는 시스템에서 임직원 및 조직 정보를 조회할때 필요한 API들을 제공한다.
|
||||
|
||||
[source, java]
|
||||
----
|
||||
public interface KnoxUserService {
|
||||
|
||||
/**
|
||||
* Knox 임직원 조회(By EpId)
|
||||
* @param epId EP ID
|
||||
* @return Knox 사용자
|
||||
*/
|
||||
Employee[] getKnoxEmployeesByEpId(String epId);
|
||||
|
||||
/**
|
||||
* Knox 임직원 조회(By UserName)
|
||||
* @param userName 사용자 이름
|
||||
* @return Knox 사용자
|
||||
*/
|
||||
Employee[] getKnoxEmployeesByUserName(String userName);
|
||||
|
||||
/**
|
||||
* Knox 임직원 조회(By KnoxId)
|
||||
* @param knoxId Knox ID
|
||||
* @return Knox 사용자
|
||||
*/
|
||||
Employee[] getKnoxEmployeesByKnoxId(String knoxId);
|
||||
|
||||
/**
|
||||
* Knox 임직원 조회(By Email)
|
||||
* @param email 이메일
|
||||
* @return Knox 사용자
|
||||
*/
|
||||
Employee[] getKnoxEmployeesByEmail(String email);
|
||||
|
||||
/**
|
||||
* Knox 조직도 조회(By CompanyCode)
|
||||
* @param companyCode 회사 코드
|
||||
* @return Knox 조직도
|
||||
*/
|
||||
Organization[] getKnoxOrganizationsByCompanyCode(String companyCode);
|
||||
|
||||
/**
|
||||
* Knox 조직도 조회(By DepartmentCode)
|
||||
* @param companyCode 회사 코드
|
||||
* @param departmentCode 부서 코드
|
||||
* @return Knox 조직도
|
||||
*/
|
||||
Organization[] getKnoxOrganizationsByDepartmentCode(String companyCode, String departmentCode);
|
||||
|
||||
/**
|
||||
* Knox 직급 조회
|
||||
* @param companyCode 회사 코드
|
||||
* @return Knox 직급
|
||||
*/
|
||||
Title[] getKnoxTitles(String companyCode);
|
||||
}
|
||||
----
|
||||
|
||||
자세한 API 스펙은 Swagger API 문서의 knox-user-controller 항목을 참고한다.
|
||||
@@ -0,0 +1,132 @@
|
||||
= 주소록
|
||||
|
||||
== 개요
|
||||
Knox Portal에서 제공하는 연락처 관련 Rest API 를 이용한 연계 서비스 제공
|
||||
|
||||
=== Knox REST API 연계 서비스 신청
|
||||
Knox REST API 연계 서비스 신청은 <<_knox_rest_api_연계_서비스_신청,Knox REST API 연계 서비스 신청>> 항목을 참조한다.
|
||||
|
||||
=== Knox Rest 연락처 연계 설정
|
||||
메일, 결재 Knox Rest API 연계와 마찬가지로 연계를 위한 사전 준비가 되었다면, knox.properties 에 연락처 관련 설정이 되어 있는지 확인한다.
|
||||
|
||||
.knox.properties
|
||||
[source,properties]
|
||||
----
|
||||
knox.pims-service=/pims/contacts/api/v2.0
|
||||
----
|
||||
|
||||
=== Knox 연락처 연계 서비스
|
||||
REST를 통해서 연락처를 연계하는 서비스로 주요 메서드는 KnoxContactService 인터페이스에 정의되어 있다.
|
||||
|
||||
[source, java]
|
||||
----
|
||||
public interface KnoxContactService {
|
||||
|
||||
/**
|
||||
* 연락처 그룹 생성
|
||||
* @param contactGroupDto
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
ContactGroupDto createGroup(ContactGroupDto contactGroupDto, String userId);
|
||||
|
||||
/**
|
||||
* 연락처 그룹 수정
|
||||
* @param groupId
|
||||
* @param contactGroupDto
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
ContactGroupDto updateGroup(String groupId, ContactGroupDto contactGroupDto, String userId);
|
||||
|
||||
/**
|
||||
* 연락처 그룹 삭제
|
||||
* @param groupId
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
String deleteGroup(String groupId, String userId);
|
||||
|
||||
/**
|
||||
* 연락처 그룹 조회
|
||||
* @param groupId
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
ContactGroupDto getGroup(String groupId, String userId);
|
||||
|
||||
/**
|
||||
* 연락처 그룹 목록 조회
|
||||
* @param pubType
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
ContactGroupDto[] getGroups(String pubType, String userId);
|
||||
|
||||
/**
|
||||
* 연락처 생성
|
||||
* @param contactDto
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
ContactDto createCard(ContactDto contactDto, String userId);
|
||||
|
||||
/**
|
||||
* 연락처 수정
|
||||
* @param contactId
|
||||
* @param contactDto
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
ContactDto updateCard(String contactId, ContactDto contactDto, String userId);
|
||||
|
||||
/**
|
||||
* 연락처 삭제
|
||||
* @param contactId
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
String deleteCard(String contactId, String userId);
|
||||
|
||||
/**
|
||||
* 연락처 조회
|
||||
* @param contactId
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
ContactDto getCard(String contactId, String userId);
|
||||
|
||||
/**
|
||||
* 연락처 목록 조회
|
||||
* @param pubType
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
ContactDto[] getCards(String pubType, String userId);
|
||||
|
||||
/**
|
||||
* KNOX REST GET MAPPING
|
||||
* @param <T>
|
||||
* @param methodName
|
||||
* @param params
|
||||
* @param paths
|
||||
* @param classType
|
||||
* @return
|
||||
*/
|
||||
<T> T contactsGet(String methodName, MultiValueMap<String, String> params, Map<String, String> paths, Class<T> classType);
|
||||
|
||||
/**
|
||||
* KNOX REST POST MAPPING
|
||||
* @param <T>
|
||||
* @param methodName
|
||||
* @param bodyMap
|
||||
* @param params
|
||||
* @param paths
|
||||
* @param classType
|
||||
* @return
|
||||
*/
|
||||
<T> T contactsPost(String methodName, Map<String, Object> bodyMap, MultiValueMap<String, String> params, Map<String, String> paths, Class<T> classType);
|
||||
}
|
||||
----
|
||||
|
||||
자세한 API 스펙은 Swagger API 문서의 knox-contact-controller 항목을 참고한다.
|
||||
Reference in New Issue
Block a user