쪽지 기능구현 :: 상세보기, 삭제, 읽음확인, 발송취소.

This commit is contained in:
leejinho 2019-11-28 17:30:43 +09:00
parent 5852196129
commit 697aa2ac07
8 changed files with 691 additions and 144 deletions

View File

@ -18,4 +18,6 @@ export interface DetailContent {
thumbnailNm?: string; thumbnailNm?: string;
thumbnailSeq?: number; thumbnailSeq?: number;
thumbnailUrl?: string; thumbnailUrl?: string;
imageSrc?: any;
} }

View File

@ -3,7 +3,8 @@ import {
HttpClient, HttpClient,
HttpHeaders, HttpHeaders,
HttpRequest, HttpRequest,
HttpResponse HttpResponse,
HttpEventType
} from '@angular/common/http'; } from '@angular/common/http';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
@ -215,6 +216,7 @@ export class MessageApiService {
encodeRetrieveResourceFile(req), encodeRetrieveResourceFile(req),
{ {
headers: this.headers, headers: this.headers,
reportProgress: true,
responseType: 'blob' responseType: 'blob'
} }
); );
@ -222,6 +224,7 @@ export class MessageApiService {
filter(event => { filter(event => {
if (event instanceof HttpResponse) { if (event instanceof HttpResponse) {
return true; return true;
} else if (HttpEventType.DownloadProgress === event.type) {
} }
return false; return false;
}), }),
@ -229,26 +232,6 @@ export class MessageApiService {
return event.body; return event.body;
}) })
); );
// return this.httpClient
// .post<any>(
// this.urls.retrieveResourceFile,
// encodeRetrieveResourceFile(req),
// {
// headers: this.headers
// }
// )
// .pipe(map(res => decodeRetrieveResourceFile(res)));
}
public urlForFileMessageDownload(req: RetrieveResourceFileRequest): string {
const httpReq = new HttpRequest(
'POST',
this.urls.retrieveResourceFile,
encodeRetrieveResourceFile(req),
{
headers: this.headers
}
);
return httpReq.urlWithParams;
} }
/** del */ /** del */

View File

@ -29,7 +29,10 @@ import {
MessageList, MessageList,
RetrieveSearchRequest, RetrieveSearchRequest,
MessageSearchType, MessageSearchType,
DetailRequest DetailRequest,
MessageDetailInfo,
DelRequest,
CancelReservationRequest
} from '@ucap-webmessenger/api-message'; } from '@ucap-webmessenger/api-message';
import { DeviceType } from '@ucap-webmessenger/core'; import { DeviceType } from '@ucap-webmessenger/core';
import { MessageStatusCode } from '@ucap-webmessenger/api'; import { MessageStatusCode } from '@ucap-webmessenger/api';
@ -75,7 +78,8 @@ export class MessageBoxComponent
messageReservationListSubscription: Subscription; messageReservationListSubscription: Subscription;
messageSearchListSubscription: Subscription; messageSearchListSubscription: Subscription;
defaultPageSize = 100; // default currentTabIndex = 0;
defaultPageSize = 1000; // default
recieveCurrentPage = 0; // start index is 0. recieveCurrentPage = 0; // start index is 0.
sendCurrentPage = 0; // start index is 0. sendCurrentPage = 0; // start index is 0.
reservationCurrentPage = 0; // start index is 0. reservationCurrentPage = 0; // start index is 0.
@ -146,31 +150,30 @@ export class MessageBoxComponent
} }
onSelectedIndexChange(value: number) { onSelectedIndexChange(value: number) {
this.currentTabIndex = value;
let type: MessageType;
switch (value) { switch (value) {
case 0: case 0:
{ // Recieve
// Recieve type = MessageType.Receive;
this.getRetrieveMessage(MessageType.Receive, this.recieveCurrentPage); this.recieveCurrentPage = 0;
}
break; break;
case 1: case 1:
{ // Send
// Send type = MessageType.Send;
this.getRetrieveMessage(MessageType.Send, this.sendCurrentPage); this.sendCurrentPage = 0;
}
break; break;
case 2: case 2:
{ // Reservation
// Reservation type = MessageType.Reservation;
this.getRetrieveMessage( this.reservationCurrentPage = 0;
MessageType.Reservation,
this.reservationCurrentPage
);
}
break; break;
} }
this.getRetrieveMessage(type, 0);
} }
/** 쪽지 검색 관련 */
onChangeSelection(event: MatSelectChange) { onChangeSelection(event: MatSelectChange) {
this.searchCurrentPage = 0; this.searchCurrentPage = 0;
this.getSearchMessage( this.getSearchMessage(
@ -233,12 +236,12 @@ export class MessageBoxComponent
) )
.subscribe(); .subscribe();
} }
onClickSearchCancel() { onClickSearchCancel() {
this.isSearch = false; this.isSearch = false;
this.getRetrieveMessage(MessageType.Receive, this.recieveCurrentPage); this.getRetrieveMessage(MessageType.Receive, this.recieveCurrentPage);
} }
/** 쪽지 타입별 조회 */
getRetrieveMessage(type: MessageType, trgtPageIndex: number) { getRetrieveMessage(type: MessageType, trgtPageIndex: number) {
switch (type) { switch (type) {
case MessageType.Receive: case MessageType.Receive:
@ -322,6 +325,7 @@ export class MessageBoxComponent
} }
} }
/** 쪽지 상세보기 */
onClickDetail(message: MessageList) { onClickDetail(message: MessageList) {
this.messageApiService this.messageApiService
.detailMessage({ .detailMessage({
@ -352,8 +356,18 @@ export class MessageBoxComponent
} }
}); });
// if (!!result && !!result.choice && result.choice) { if (!!result) {
// } switch (result.returnType) {
case 'DEL':
// 단건 삭제.
this.doMessageDelete([result.messageInfo]);
break;
case 'CANCEL_RESERVATION':
// 단건 발송취소(예약)
this.doMessageCancelReservation(result.messageInfo);
break;
}
}
} else { } else {
} }
}), }),
@ -361,4 +375,54 @@ export class MessageBoxComponent
) )
.subscribe(); .subscribe();
} }
/** 쪽지(수신,발신) 삭제 */
doMessageDelete(messageInfo: MessageDetailInfo[]): void {
const msgList: { msgId: number }[] = [];
messageInfo.forEach(info => msgList.push({ msgId: info.msgId }));
this.messageApiService
.deleteMessage({
userSeq: this.loginRes.userSeq,
deviceType: DeviceType.PC,
tokenKey: this.loginRes.tokenString,
type: messageInfo[0].type,
msgList
} as DelRequest)
.pipe(
map(async res => {
if (res.responseCode === MessageStatusCode.Success) {
} else {
this.logger.error('message delete Error!');
}
// 현재탭 재조회.
this.onSelectedIndexChange(this.currentTabIndex);
}),
catchError(error => of(this.logger.error(error)))
)
.subscribe();
}
/** 쪽지(예약) 삭제 */
doMessageCancelReservation(messageInfo: MessageDetailInfo): void {
this.messageApiService
.cancelReservationMessage({
userSeq: this.loginRes.userSeq,
deviceType: DeviceType.PC,
tokenKey: this.loginRes.tokenString,
type: messageInfo.type,
msgId: messageInfo.msgId
} as CancelReservationRequest)
.pipe(
map(async res => {
if (res.responseCode === MessageStatusCode.Success) {
} else {
this.logger.error('message(reservation) cancel Error!');
}
// 현재탭 재조회.
this.onSelectedIndexChange(this.currentTabIndex);
}),
catchError(error => of(this.logger.error(error)))
)
.subscribe();
}
} }

View File

@ -9,74 +9,204 @@
</mat-card-title> </mat-card-title>
</mat-card-header> </mat-card-header>
<mat-card-content> <mat-card-content>
<div fxFlex fxLayout="column" fxLayoutAlign=" stretch"> <mat-drawer-container autosize [hasBackdrop]="true">
<div class="title"> <div fxFlex fxLayout="column" fxLayoutAlign=" stretch">
{{ messageInfo.title }} <div class="title">
<span> {{ messageInfo.title }}
<button mat-icon-button aria-label="group menu" class="message-menu"> <span>
<mat-icon>more_vert</mat-icon> <button
</button> mat-icon-button
</span> aria-label="message menu"
</div> class="message-menu"
<div class="info"> #messageMenuTrigger="matMenuTrigger"
<ul> [matMenuTriggerFor]="messageMenu"
<li> (ucapClickOutside)="messageMenuTrigger.closeMenu()"
<span *ngIf="messageInfo.type === MessageType.Receive" class="label"
>보낸사람</span
> >
<span *ngIf="messageInfo.type !== MessageType.Receive" class="label" <mat-icon>more_vert</mat-icon>
>받는사람</span
>
<span>{{ messageInfo.sendUserName }}</span>
</li>
<li>
<span class="label">받은시간</span>
<span>{{
messageInfo.regDate
| dateToStringFormat: 'YYYY.MM.dd (KS) a/p HH:mm'
}}</span>
</li>
</ul>
</div>
<div class="contents">
<ul>
<li *ngFor="let cont of contents">
<pre *ngIf="cont.resType === ContentType.Text">{{
cont.resContent
}}</pre>
<img
*ngIf="cont.resType === ContentType.Image"
[src]="getThumbImage(cont)"
/>
</li>
</ul>
</div>
<div *ngIf="attachFile && attachFile.length > 0" class="attachFile">
<div>
<div class="title">
<span *ngIf="isExpiredAttachFile">기간이 만료된 파일입니다</span>
<button mat-stroked-button class="mat-primary">
모두저장
</button> </button>
</div> </span>
</div>
<div class="info">
<ul> <ul>
<li *ngFor="let file of attachFile"> <li>
<div> <span
<span class="mdi mdi-attachment"></span> *ngIf="messageInfo.type === MessageType.Receive"
<span>{{ file.resContent }}</span> class="label"
<span>{{ file.resSize | ucapBytes }}</span> >보낸사람</span
<span class="mdi mdi-download"></span> >
</div> <span
*ngIf="messageInfo.type !== MessageType.Receive"
class="label"
>받는사람</span
>
<span>{{ getSendReceiverNames() }}</span>
</li>
<li>
<span class="label">받은시간</span>
<span>{{
messageInfo.regDate
| dateToStringFormat: 'YYYY.MM.dd (KS) a/p HH:mm'
}}</span>
</li> </li>
</ul> </ul>
</div> </div>
<perfect-scrollbar>
<div class="contents">
<ul>
<li *ngFor="let cont of contents">
<pre *ngIf="cont.resType === ContentType.Text">{{
cont.resContent
}}</pre>
<img
*ngIf="cont.resType === ContentType.Image"
[src]="cont.imageSrc"
class="thumbnail"
/>
</li>
</ul>
</div>
</perfect-scrollbar>
<div *ngIf="attachFile && attachFile.length > 0" class="attachFile">
<div>
<div class="title">
<span *ngIf="isExpiredAttachFile">기간이 만료된 파일입니다</span>
<button
mat-stroked-button
class="mat-primary"
(click)="downloadAttachFileAll()"
>
모두저장
</button>
</div>
<ul>
<li *ngFor="let file of attachFile">
<div>
<span class="mdi" [ngClass]="getFileStatusIcon(file)"></span>
<span>{{ file.resContent }}</span>
<span>{{ file.resSize | ucapBytes }}</span>
<a>
<span
class="mdi mdi-download"
*ngIf="file.activeYn"
(click)="downloadAttachFileSingle(file)"
></span>
</a>
</div>
</li>
</ul>
</div>
</div>
</div> </div>
</div>
<mat-drawer #rightDrawer mode="over" position="end" class="rightDrawer">
<mat-tab-group
mat-stretch-tabs
animationDuration="0ms"
[selectedIndex]="0"
>
<mat-tab>
<ng-template mat-tab-label>
읽은 사람 {{ getReadUserCount(true) }}
</ng-template>
<mat-list>
<ng-container *ngFor="let user of receivers">
<mat-list-item *ngIf="user.readYn">
<span>{{ user.userName }}</span>
<span>{{
user.readDate | dateToStringFormat: 'YYYY-MM-DD HH:mm:ss'
}}</span>
</mat-list-item>
</ng-container>
</mat-list>
</mat-tab>
<mat-tab>
<ng-template mat-tab-label>
읽지 않은 사람 {{ getReadUserCount(true) }}
</ng-template>
<ul>
<div>
전체선택
<mat-checkbox
#checkbox
(change)="
checkbox.checked
? unReadUsers.selectAll()
: unReadUsers.deselectAll()
"
(click)="$event.stopPropagation()"
>
</mat-checkbox>
</div>
<mat-selection-list #unReadUsers>
<ng-container *ngFor="let user of receivers">
<mat-list-option *ngIf="!user.readYn" [value]="user.userSeq">
<span>{{ user.userName }}</span>
</mat-list-option>
</ng-container>
</mat-selection-list>
<div>
<button
mat-stroked-button
[disabled]="unReadUsers.selectedOptions.selected.length === 0"
(click)="
cancelSendMessageForUsers(
unReadUsers.selectedOptions.selected
)
"
class="mat-primary"
>
발송취소
</button>
</div>
</ul>
</mat-tab>
</mat-tab-group>
</mat-drawer>
</mat-drawer-container>
</mat-card-content> </mat-card-content>
<mat-card-actions class="button-farm flex-row"> <!-- <mat-card-actions class="button-farm flex-row">
<button mat-stroked-button (click)="onClickConfirm()" class="mat-primary"> <button mat-stroked-button (click)="onClickConfirm()" class="mat-primary">
Confirm Confirm
</button> </button>
</mat-card-actions> </mat-card-actions> -->
</mat-card> </mat-card>
<mat-menu
#messageMenu="matMenu"
xPosition="after"
yPosition="below"
[hasBackdrop]="false"
>
<button
mat-menu-item
*ngIf="messageInfo.type === MessageType.Send"
(click)="onClickMessageMenu('MESSAGE_READ')"
>
<span>읽음확인</span>
</button>
<button
mat-menu-item
*ngIf="messageInfo.type === MessageType.Reservation"
(click)="onClickMessageMenu('MESSAGE_CANCEL')"
>
<span>발송취소</span>
</button>
<button
mat-menu-item
*ngIf="messageInfo.type === MessageType.Reservation"
(click)="onClickMessageMenu('MESSAGE_UPDATE')"
>
<span>수정</span>
</button>
<button
mat-menu-item
*ngIf="
messageInfo.type === MessageType.Send ||
messageInfo.type === MessageType.Receive
"
(click)="onClickMessageMenu('MESSAGE_DEL')"
>
<span>삭제</span>
</button>
</mat-menu>

View File

@ -16,3 +16,12 @@
::ng-deep .mat-mini-fab .mat-button-wrapper { ::ng-deep .mat-mini-fab .mat-button-wrapper {
padding: 0; padding: 0;
} }
.contents {
height: 380px;
.thumbnail {
max-width: 250px;
max-height: 250px;
}
}

View File

@ -3,7 +3,8 @@ import {
MatDialogRef, MatDialogRef,
MAT_DIALOG_DATA, MAT_DIALOG_DATA,
MatSelectionList, MatSelectionList,
MatSelectionListChange MatSelectionListChange,
MatDrawer
} from '@angular/material'; } from '@angular/material';
import { Observable, combineLatest, of } from 'rxjs'; import { Observable, combineLatest, of } from 'rxjs';
import { Store, select } from '@ngrx/store'; import { Store, select } from '@ngrx/store';
@ -16,23 +17,29 @@ import {
DialogService, DialogService,
ConfirmDialogComponent, ConfirmDialogComponent,
ConfirmDialogData, ConfirmDialogData,
ConfirmDialogResult ConfirmDialogResult,
SnackBarService,
AlertDialogComponent,
AlertDialogResult,
AlertDialogData
} from '@ucap-webmessenger/ui'; } from '@ucap-webmessenger/ui';
import { GroupDetailData, UserInfo } from '@ucap-webmessenger/protocol-sync'; import { GroupDetailData, UserInfo } from '@ucap-webmessenger/protocol-sync';
import { import {
DetailResponse, DetailResponse,
MessageType, MessageType,
MessageList,
DetailContent, DetailContent,
DetailReceiver, DetailReceiver,
ContentType, ContentType,
MessageDetailInfo, MessageDetailInfo,
MessageApiService, MessageApiService,
RetrieveResourceFileRequest RetrieveResourceFileRequest,
CancelRequest
} from '@ucap-webmessenger/api-message'; } from '@ucap-webmessenger/api-message';
import { DeviceType } from '@ucap-webmessenger/core'; import { DeviceType, MimeUtil, FileUtil } from '@ucap-webmessenger/core';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication'; import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
import { NGXLogger } from 'ngx-logger'; import { NGXLogger } from 'ngx-logger';
import { NativeService, UCAP_NATIVE_SERVICE } from '@ucap-webmessenger/native';
import { MessageStatusCode } from '@ucap-webmessenger/api';
export interface MessageDetailDialogData { export interface MessageDetailDialogData {
detail: DetailResponse; detail: DetailResponse;
@ -40,7 +47,15 @@ export interface MessageDetailDialogData {
} }
// tslint:disable-next-line: no-empty-interface // tslint:disable-next-line: no-empty-interface
export interface MessageDetailDialogResult {} export interface MessageDetailDialogResult {
returnType: string;
messageInfo?: MessageDetailInfo;
cancelUserSeqs?: number[];
}
export interface DownloadQueueForMessage extends DetailContent {
downloadType: string;
}
@Component({ @Component({
selector: 'app-layout-messenger-message-detail', selector: 'app-layout-messenger-message-detail',
@ -59,13 +74,22 @@ export class MessageDetailDialogComponent implements OnInit {
MessageType = MessageType; MessageType = MessageType;
ContentType = ContentType; ContentType = ContentType;
downloadProgress = false;
downloadQueue: DownloadQueueForMessage[] = [];
downloadFail: DownloadQueueForMessage[] = [];
@ViewChild('rightDrawer', { static: true }) rightDrawer: MatDrawer;
@ViewChild('unReadUsers', { static: false }) unReadUsers: MatSelectionList;
constructor( constructor(
public dialogRef: MatDialogRef< public dialogRef: MatDialogRef<
MessageDetailDialogData, MessageDetailDialogData,
MessageDetailDialogResult MessageDetailDialogResult
>, >,
@Inject(MAT_DIALOG_DATA) public data: MessageDetailDialogData, @Inject(MAT_DIALOG_DATA) public data: MessageDetailDialogData,
@Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService,
private messageApiService: MessageApiService, private messageApiService: MessageApiService,
private snackBarService: SnackBarService,
private logger: NGXLogger, private logger: NGXLogger,
private store: Store<any>, private store: Store<any>,
private dialogService: DialogService private dialogService: DialogService
@ -91,52 +115,385 @@ export class MessageDetailDialogComponent implements OnInit {
}); });
} }
this.receivers = this.messageDetail.recvList; // contents 내 이미지 Thumnail 파일 정보 수집.
this.getThumbImage();
this.receivers = this.messageDetail.recvList.sort((a, b) =>
a.userName < b.userName ? -1 : a.userName > b.userName ? 1 : 0
);
} }
getThumbImage(content: DetailContent): string { getSendReceiverNames(): string {
console.log( if (this.messageInfo.type === MessageType.Receive) {
JSON.stringify({ return this.messageInfo.sendUserName;
} else {
return this.receivers.map(user => user.userName).join(',');
}
}
getReadUserCount(readYn: boolean): number {
return this.receivers.filter(user => user.readYn === readYn).length;
}
getFileStatusIcon(file: DetailContent) {
const downloading =
this.downloadQueue.filter(dq => dq.resSeq === file.resSeq).length > 0;
const error =
this.downloadFail.filter(df => df.resSeq === file.resSeq).length > 0;
if (error) {
return 'mdi-window-close';
} else if (downloading) {
return ['mdi-spin', 'mdi-loading'];
} else {
return 'mdi-attachment';
}
}
getThumbImage(): void {
this.contents.forEach(content => {
if (content.resType === ContentType.Image) {
this.messageApiService
.retrieveResourceFile({
userSeq: this.data.loginRes.userSeq,
deviceType: DeviceType.PC,
tokenKey: this.data.loginRes.tokenString,
type: this.messageInfo.type,
msgId: this.messageInfo.msgId,
resUrl: content.thumbnailUrl
} as RetrieveResourceFileRequest)
.pipe(
take(1),
map(async rawBlob => {
const reader = new FileReader();
reader.readAsDataURL(rawBlob);
reader.onloadend = () => {
content.imageSrc = reader.result;
};
})
)
.subscribe();
}
});
}
// /**
// * @deprecated
// */
// downloadAttachFile(attachFile: DetailContent): void {
// this.messageApiService
// .retrieveResourceFile({
// userSeq: this.data.loginRes.userSeq,
// deviceType: DeviceType.PC,
// tokenKey: this.data.loginRes.tokenString,
// type: this.messageInfo.type,
// msgId: this.messageInfo.msgId,
// resUrl: attachFile.resUrl
// } as RetrieveResourceFileRequest)
// .pipe(
// take(1),
// map(async rawBlob => {
// const mimeType = MimeUtil.getMimeFromExtension(
// FileUtil.getExtension(attachFile.resContent)
// );
// const blob = rawBlob.slice(0, rawBlob.size, mimeType);
// FileUtil.fromBlobToBuffer(blob)
// .then(buffer => {
// this.nativeService
// .saveFile(buffer, attachFile.resContent, mimeType)
// .then(result => {
// if (!!result) {
// if (this.downloadFail.length > 0) {
// this.downloadFail = this.downloadFail.filter(
// df => df.resSeq !== attachFile.resSeq
// );
// }
// this.snackBarService.open(
// `파일이 경로[${result}]에 저장되었습니다.`,
// '',
// {
// duration: 3000,
// verticalPosition: 'bottom'
// }
// );
// } else {
// this.snackBarService.open('파일 저장에 실패하였습니다.');
// }
// })
// .catch(reason => {
// this.snackBarService.open('파일 저장에 실패하였습니다.');
// });
// })
// .catch(reason => {
// this.logger.error('download', reason);
// });
// })
// )
// .subscribe();
// }
downloadAttachFileSingle(attachFile: DetailContent): void {
if (!this.downloadProgress) {
this.downloadProgress = true;
this.downloadQueue = [{ ...attachFile, downloadType: 'SINGLE' }];
this.downloadFail = [];
if (!!this.downloadQueue && this.downloadQueue.length > 0) {
this.downloadAttachFileByQueue();
}
} else {
if (
this.downloadQueue.filter(dq => dq.resSeq === attachFile.resSeq)
.length === 0
) {
this.downloadQueue.push({ ...attachFile, downloadType: 'SINGLE' });
}
}
}
downloadAttachFileAll(): void {
if (!this.downloadProgress) {
this.downloadProgress = true;
this.downloadQueue = [];
this.downloadFail = [];
this.attachFile.forEach(file =>
this.downloadQueue.push({ ...file, downloadType: '' })
);
if (!!this.downloadQueue && this.downloadQueue.length > 0) {
this.downloadAttachFileByQueue();
}
} else {
this.dialogService.open<
AlertDialogComponent,
AlertDialogData,
AlertDialogResult
>(AlertDialogComponent, {
data: {
title: '',
html: `다운로드가 진행중입니다.`
}
});
}
}
downloadAttachFileByQueue(): void {
const attachFile = this.downloadQueue[0];
this.messageApiService
.retrieveResourceFile({
userSeq: this.data.loginRes.userSeq, userSeq: this.data.loginRes.userSeq,
deviceType: DeviceType.PC, deviceType: DeviceType.PC,
tokenKey: this.data.loginRes.tokenString, tokenKey: this.data.loginRes.tokenString,
type: this.messageInfo.type, type: this.messageInfo.type,
msgId: this.messageInfo.msgId, msgId: this.messageInfo.msgId,
resUrl: content.thumbnailUrl resUrl: attachFile.resUrl
}) } as RetrieveResourceFileRequest)
); .pipe(
if (content.resType === ContentType.Image) { take(1),
// // return this.messageApiService.urlForFileMessageDownload({ map(async rawBlob => {
// // userSeq: this.data.loginRes.userSeq, const mimeType = MimeUtil.getMimeFromExtension(
// // deviceType: DeviceType.PC, FileUtil.getExtension(attachFile.resContent)
// // tokenKey: this.data.loginRes.tokenString, );
// // type: this.messageInfo.type, const blob = rawBlob.slice(0, rawBlob.size, mimeType);
// // msgId: this.messageInfo.msgId,
// // resUrl: content.thumbnailUrl FileUtil.fromBlobToBuffer(blob)
// // } as RetrieveResourceFileRequest); .then(buffer => {
// this.messageApiService this.nativeService
// .retrieveResourceFile({ .saveFile(buffer, attachFile.resContent, mimeType)
// userSeq: this.data.loginRes.userSeq, .then(result => {
// deviceType: DeviceType.PC, if (!!result) {
// tokenKey: this.data.loginRes.tokenString, if (
// type: this.messageInfo.type, !!attachFile.downloadType &&
// msgId: this.messageInfo.msgId, attachFile.downloadType === 'SINGLE'
// resUrl: content.thumbnailUrl ) {
// } as RetrieveResourceFileRequest) attachFile.downloadType = result;
// .pipe( }
// take(1),
// map(async rawBlob => { if (this.downloadQueue.length > 1) {
// console.log(rawBlob); this.downloadQueue = this.downloadQueue.slice(1);
// return URL.createObjectURL(rawBlob); } else {
// }) this.downloadQueue = [];
// ) }
// .subscribe(); } else {
} else { throw new Error('response Error');
return ''; }
})
.catch(reason => {
this.downloadFail.push(this.downloadQueue[0]);
if (this.downloadQueue.length > 1) {
this.downloadQueue = this.downloadQueue.slice(1);
} else {
this.downloadQueue = [];
}
});
})
.catch(reason => {
this.downloadFail.push(this.downloadQueue[0]);
if (this.downloadQueue.length > 1) {
this.downloadQueue = this.downloadQueue.slice(1);
} else {
this.downloadQueue = [];
}
})
.finally(() => {
if (this.downloadQueue.length > 0) {
// 재귀
this.downloadAttachFileByQueue();
} else {
if (this.downloadFail.length > 0) {
// 일부 혹은 전부 실패.
let errMsg = '';
if (
!!attachFile.downloadType &&
attachFile.downloadType === 'SINGLE'
) {
// single :: fail
errMsg = '파일 저장에 실패하였습니다.';
} else {
// all
errMsg = '일부 저장중 오류가 발생하였습니다.';
}
this.snackBarService.open(errMsg, '확인', {
duration: 8000,
verticalPosition: 'bottom'
});
} else {
// 성공종료.
if (
!!attachFile.downloadType &&
attachFile.downloadType.length > 0
) {
// single :: success
this.snackBarService.open(
`파일이 경로[${attachFile.downloadType}]에 저장되었습니다.`,
'',
{
duration: 3000,
verticalPosition: 'bottom'
}
);
} else {
// all
this.snackBarService.open('모두 저장하였습니다.', '', {
duration: 3000,
verticalPosition: 'bottom'
});
}
}
this.downloadProgress = false;
}
});
})
)
.subscribe();
}
async onClickMessageMenu(menuType: string) {
switch (menuType) {
case 'MESSAGE_READ':
{
this.rightDrawer.open();
}
break;
case 'MESSAGE_CANCEL':
{
const result = await this.dialogService.open<
ConfirmDialogComponent,
ConfirmDialogData,
ConfirmDialogResult
>(ConfirmDialogComponent, {
data: {
title: '발송취소',
html: `예약발송을 취소 하시겠습니까?<br/>취소하면 목록에서도 영구 삭제됩니다.`
}
});
if (!!result && !!result.choice && result.choice) {
this.dialogRef.close({
returnType: 'CANCEL_RESERVATION',
messageInfo: this.messageInfo
});
}
}
break;
case 'MESSAGE_DEL':
{
const result = await this.dialogService.open<
ConfirmDialogComponent,
ConfirmDialogData,
ConfirmDialogResult
>(ConfirmDialogComponent, {
data: {
title: '삭제',
message: '선택한 쪽지를 삭제하시겠습니까?'
}
});
if (!!result && !!result.choice && result.choice) {
this.dialogRef.close({
returnType: 'DEL',
messageInfo: this.messageInfo
});
}
}
break;
}
}
async cancelSendMessageForUsers() {
if (
!!this.unReadUsers &&
this.unReadUsers.selectedOptions.selected.length > 0
) {
const result = await this.dialogService.open<
ConfirmDialogComponent,
ConfirmDialogData,
ConfirmDialogResult
>(ConfirmDialogComponent, {
data: {
title: '발송 취소',
message:
'발송 취소를 하시면 받는 사람의 쪽지함에서 쪽지가 삭제됩니다.'
}
});
if (!!result && !!result.choice && result.choice) {
const cancelUserSeqs: number[] = [];
const recvUserList: { userSeq: number }[] = [];
this.unReadUsers.selectedOptions.selected.forEach(selected => {
cancelUserSeqs.push(selected.value);
recvUserList.push({ userSeq: selected.value });
});
this.messageApiService
.cancelMessage({
userSeq: this.data.loginRes.userSeq,
deviceType: DeviceType.PC,
tokenKey: this.data.loginRes.tokenString,
type: this.messageInfo.type,
msgId: this.messageInfo.msgId,
recvUserList
} as CancelRequest)
.pipe(
map(async res => {
if (res.responseCode === MessageStatusCode.Success) {
this.receivers = this.receivers.filter(
user => cancelUserSeqs.indexOf(user.userSeq) < 0
);
this.rightDrawer.close();
} else {
this.logger.error('message cancel user Error!');
}
}),
catchError(error => of(this.logger.error(error)))
)
.subscribe();
}
} }
} }
onClickConfirm(): void { onClickConfirm(): void {
this.dialogRef.close({}); this.dialogRef.close({
returnType: 'CLOSE'
});
} }
} }

View File

@ -28,7 +28,8 @@ import {
MatPaginatorModule, MatPaginatorModule,
MatRippleModule, MatRippleModule,
MatSortModule, MatSortModule,
MatTooltipModule MatTooltipModule,
MatSidenavModule
} from '@angular/material'; } from '@angular/material';
import { MatListModule } from '@angular/material/list'; import { MatListModule } from '@angular/material/list';
import { MatChipsModule } from '@angular/material/chips'; import { MatChipsModule } from '@angular/material/chips';
@ -83,6 +84,7 @@ import { DIALOGS } from './dialogs';
MatPaginatorModule, MatPaginatorModule,
MatRippleModule, MatRippleModule,
MatTooltipModule, MatTooltipModule,
MatSidenavModule,
PerfectScrollbarModule, PerfectScrollbarModule,

View File

@ -45,7 +45,7 @@ export const environment: Environment = {
hostConfig: { hostConfig: {
protocol: 'http', protocol: 'http',
domain: '27.122.224.170', domain: '27.122.224.170',
port: 9097 port: 9098
}, },
urls: messageApiUrls urls: messageApiUrls
}, },