쪽지 기능구현 :: 상세보기, 삭제, 읽음확인, 발송취소.
This commit is contained in:
parent
5852196129
commit
697aa2ac07
|
@ -18,4 +18,6 @@ export interface DetailContent {
|
||||||
thumbnailNm?: string;
|
thumbnailNm?: string;
|
||||||
thumbnailSeq?: number;
|
thumbnailSeq?: number;
|
||||||
thumbnailUrl?: string;
|
thumbnailUrl?: string;
|
||||||
|
|
||||||
|
imageSrc?: any;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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
|
||||||
this.getRetrieveMessage(MessageType.Receive, this.recieveCurrentPage);
|
type = MessageType.Receive;
|
||||||
}
|
this.recieveCurrentPage = 0;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
{
|
|
||||||
// Send
|
// Send
|
||||||
this.getRetrieveMessage(MessageType.Send, this.sendCurrentPage);
|
type = MessageType.Send;
|
||||||
}
|
this.sendCurrentPage = 0;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
{
|
|
||||||
// Reservation
|
// Reservation
|
||||||
this.getRetrieveMessage(
|
type = MessageType.Reservation;
|
||||||
MessageType.Reservation,
|
this.reservationCurrentPage = 0;
|
||||||
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,11 +9,19 @@
|
||||||
</mat-card-title>
|
</mat-card-title>
|
||||||
</mat-card-header>
|
</mat-card-header>
|
||||||
<mat-card-content>
|
<mat-card-content>
|
||||||
|
<mat-drawer-container autosize [hasBackdrop]="true">
|
||||||
<div fxFlex fxLayout="column" fxLayoutAlign=" stretch">
|
<div fxFlex fxLayout="column" fxLayoutAlign=" stretch">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
{{ messageInfo.title }}
|
{{ messageInfo.title }}
|
||||||
<span>
|
<span>
|
||||||
<button mat-icon-button aria-label="group menu" class="message-menu">
|
<button
|
||||||
|
mat-icon-button
|
||||||
|
aria-label="message menu"
|
||||||
|
class="message-menu"
|
||||||
|
#messageMenuTrigger="matMenuTrigger"
|
||||||
|
[matMenuTriggerFor]="messageMenu"
|
||||||
|
(ucapClickOutside)="messageMenuTrigger.closeMenu()"
|
||||||
|
>
|
||||||
<mat-icon>more_vert</mat-icon>
|
<mat-icon>more_vert</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
|
@ -21,13 +29,17 @@
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<span *ngIf="messageInfo.type === MessageType.Receive" class="label"
|
<span
|
||||||
|
*ngIf="messageInfo.type === MessageType.Receive"
|
||||||
|
class="label"
|
||||||
>보낸사람</span
|
>보낸사람</span
|
||||||
>
|
>
|
||||||
<span *ngIf="messageInfo.type !== MessageType.Receive" class="label"
|
<span
|
||||||
|
*ngIf="messageInfo.type !== MessageType.Receive"
|
||||||
|
class="label"
|
||||||
>받는사람</span
|
>받는사람</span
|
||||||
>
|
>
|
||||||
<span>{{ messageInfo.sendUserName }}</span>
|
<span>{{ getSendReceiverNames() }}</span>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<span class="label">받은시간</span>
|
<span class="label">받은시간</span>
|
||||||
|
@ -38,6 +50,7 @@
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
<perfect-scrollbar>
|
||||||
<div class="contents">
|
<div class="contents">
|
||||||
<ul>
|
<ul>
|
||||||
<li *ngFor="let cont of contents">
|
<li *ngFor="let cont of contents">
|
||||||
|
@ -46,16 +59,22 @@
|
||||||
}}</pre>
|
}}</pre>
|
||||||
<img
|
<img
|
||||||
*ngIf="cont.resType === ContentType.Image"
|
*ngIf="cont.resType === ContentType.Image"
|
||||||
[src]="getThumbImage(cont)"
|
[src]="cont.imageSrc"
|
||||||
|
class="thumbnail"
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
</perfect-scrollbar>
|
||||||
<div *ngIf="attachFile && attachFile.length > 0" class="attachFile">
|
<div *ngIf="attachFile && attachFile.length > 0" class="attachFile">
|
||||||
<div>
|
<div>
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<span *ngIf="isExpiredAttachFile">기간이 만료된 파일입니다</span>
|
<span *ngIf="isExpiredAttachFile">기간이 만료된 파일입니다</span>
|
||||||
<button mat-stroked-button class="mat-primary">
|
<button
|
||||||
|
mat-stroked-button
|
||||||
|
class="mat-primary"
|
||||||
|
(click)="downloadAttachFileAll()"
|
||||||
|
>
|
||||||
모두저장
|
모두저장
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -63,20 +82,131 @@
|
||||||
<ul>
|
<ul>
|
||||||
<li *ngFor="let file of attachFile">
|
<li *ngFor="let file of attachFile">
|
||||||
<div>
|
<div>
|
||||||
<span class="mdi mdi-attachment"></span>
|
<span class="mdi" [ngClass]="getFileStatusIcon(file)"></span>
|
||||||
<span>{{ file.resContent }}</span>
|
<span>{{ file.resContent }}</span>
|
||||||
<span>{{ file.resSize | ucapBytes }}</span>
|
<span>{{ file.resSize | ucapBytes }}</span>
|
||||||
<span class="mdi mdi-download"></span>
|
<a>
|
||||||
|
<span
|
||||||
|
class="mdi mdi-download"
|
||||||
|
*ngIf="file.activeYn"
|
||||||
|
(click)="downloadAttachFileSingle(file)"
|
||||||
|
></span>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</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>
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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,29 +115,72 @@ 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,
|
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: content.thumbnailUrl
|
||||||
|
} as RetrieveResourceFileRequest)
|
||||||
|
.pipe(
|
||||||
|
take(1),
|
||||||
|
map(async rawBlob => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.readAsDataURL(rawBlob);
|
||||||
|
reader.onloadend = () => {
|
||||||
|
content.imageSrc = reader.result;
|
||||||
|
};
|
||||||
})
|
})
|
||||||
);
|
)
|
||||||
if (content.resType === ContentType.Image) {
|
.subscribe();
|
||||||
// // return this.messageApiService.urlForFileMessageDownload({
|
}
|
||||||
// // userSeq: this.data.loginRes.userSeq,
|
});
|
||||||
// // deviceType: DeviceType.PC,
|
}
|
||||||
// // tokenKey: this.data.loginRes.tokenString,
|
|
||||||
// // type: this.messageInfo.type,
|
// /**
|
||||||
// // msgId: this.messageInfo.msgId,
|
// * @deprecated
|
||||||
// // resUrl: content.thumbnailUrl
|
// */
|
||||||
// // } as RetrieveResourceFileRequest);
|
// downloadAttachFile(attachFile: DetailContent): void {
|
||||||
// this.messageApiService
|
// this.messageApiService
|
||||||
// .retrieveResourceFile({
|
// .retrieveResourceFile({
|
||||||
// userSeq: this.data.loginRes.userSeq,
|
// userSeq: this.data.loginRes.userSeq,
|
||||||
|
@ -121,22 +188,312 @@ export class MessageDetailDialogComponent implements OnInit {
|
||||||
// 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)
|
// } as RetrieveResourceFileRequest)
|
||||||
// .pipe(
|
// .pipe(
|
||||||
// take(1),
|
// take(1),
|
||||||
// map(async rawBlob => {
|
// map(async rawBlob => {
|
||||||
// console.log(rawBlob);
|
// const mimeType = MimeUtil.getMimeFromExtension(
|
||||||
// return URL.createObjectURL(rawBlob);
|
// 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();
|
// .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 {
|
} else {
|
||||||
return '';
|
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,
|
||||||
|
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 (
|
||||||
|
!!attachFile.downloadType &&
|
||||||
|
attachFile.downloadType === 'SINGLE'
|
||||||
|
) {
|
||||||
|
attachFile.downloadType = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.downloadQueue.length > 1) {
|
||||||
|
this.downloadQueue = this.downloadQueue.slice(1);
|
||||||
|
} else {
|
||||||
|
this.downloadQueue = [];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new Error('response Error');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.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'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue
Block a user