대화 내용 내보내기 구현. For CSV
This commit is contained in:
parent
921af8f5bb
commit
e41f44ca38
|
@ -0,0 +1,40 @@
|
||||||
|
import { DeviceType } from '@ucap-webmessenger/core';
|
||||||
|
import {
|
||||||
|
APIRequest,
|
||||||
|
APIEncoder,
|
||||||
|
ParameterUtil,
|
||||||
|
APIFormDataEncoder
|
||||||
|
} from '@ucap-webmessenger/api';
|
||||||
|
import { FileDownloadItem } from '../../../../ucap-webmessenger-api/src/lib/models/file-download-item';
|
||||||
|
|
||||||
|
export interface EventDownloadRequest extends APIRequest {
|
||||||
|
userSeq: number;
|
||||||
|
deviceType: DeviceType;
|
||||||
|
token: string;
|
||||||
|
roomSeq: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const eventDownloadEncodeMap = {
|
||||||
|
userSeq: 'userSeq',
|
||||||
|
deviceType: 'deviceType',
|
||||||
|
token: 'tokenKey',
|
||||||
|
roomSeq: 'roomSeq'
|
||||||
|
};
|
||||||
|
|
||||||
|
export const encodeEventDownload: APIEncoder<EventDownloadRequest> = (
|
||||||
|
req: EventDownloadRequest
|
||||||
|
) => {
|
||||||
|
const extraParams: any = {};
|
||||||
|
extraParams.roomSeq = Number(req.roomSeq);
|
||||||
|
|
||||||
|
return ParameterUtil.encode(eventDownloadEncodeMap, req, extraParams);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const encodeFormDataEventDownload: APIFormDataEncoder<EventDownloadRequest> = (
|
||||||
|
req: EventDownloadRequest
|
||||||
|
) => {
|
||||||
|
const extraParams: any = {};
|
||||||
|
extraParams.roomSeq = Number(req.roomSeq);
|
||||||
|
|
||||||
|
return ParameterUtil.encodeFormData(eventDownloadEncodeMap, req, extraParams);
|
||||||
|
};
|
|
@ -47,4 +47,7 @@ export interface Urls {
|
||||||
|
|
||||||
/** 공지 조회 */
|
/** 공지 조회 */
|
||||||
retrieveNoticeList: string;
|
retrieveNoticeList: string;
|
||||||
|
|
||||||
|
/** Event Download */
|
||||||
|
eventDownload: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import {
|
||||||
HttpEventType
|
HttpEventType
|
||||||
} from '@angular/common/http';
|
} from '@angular/common/http';
|
||||||
|
|
||||||
import { Observable } from 'rxjs';
|
import { Observable, Subject } from 'rxjs';
|
||||||
import { map, filter } from 'rxjs/operators';
|
import { map, filter } from 'rxjs/operators';
|
||||||
|
|
||||||
import { _MODULE_CONFIG } from '../config/token';
|
import { _MODULE_CONFIG } from '../config/token';
|
||||||
|
@ -97,6 +97,10 @@ import {
|
||||||
encodeRetrieveNotice,
|
encodeRetrieveNotice,
|
||||||
decodeRetrieveNotice
|
decodeRetrieveNotice
|
||||||
} from '../apis/notice';
|
} from '../apis/notice';
|
||||||
|
import {
|
||||||
|
EventDownloadRequest,
|
||||||
|
encodeFormDataEventDownload
|
||||||
|
} from '../apis/event-download';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
|
@ -357,4 +361,27 @@ export class MessageApiService {
|
||||||
})
|
})
|
||||||
.pipe(map(res => decodeRetrieveNotice(res)));
|
.pipe(map(res => decodeRetrieveNotice(res)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Event Download for Room */
|
||||||
|
public eventDownload(req: EventDownloadRequest): Observable<Blob> {
|
||||||
|
const httpReq = new HttpRequest(
|
||||||
|
'POST',
|
||||||
|
this.urls.eventDownload,
|
||||||
|
encodeFormDataEventDownload(req),
|
||||||
|
{ reportProgress: true, responseType: 'blob' }
|
||||||
|
);
|
||||||
|
|
||||||
|
return this.httpClient.request(httpReq).pipe(
|
||||||
|
filter(event => {
|
||||||
|
if (event instanceof HttpResponse) {
|
||||||
|
return true;
|
||||||
|
} else if (HttpEventType.DownloadProgress === event.type) {
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}),
|
||||||
|
map((event: HttpResponse<any>) => {
|
||||||
|
return event.body;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
export * from './lib/apis/del';
|
export * from './lib/apis/del';
|
||||||
export * from './lib/apis/detail';
|
export * from './lib/apis/detail';
|
||||||
export * from './lib/apis/edit-reservation-ex';
|
export * from './lib/apis/edit-reservation-ex';
|
||||||
|
export * from './lib/apis/event-download';
|
||||||
export * from './lib/apis/my-message';
|
export * from './lib/apis/my-message';
|
||||||
export * from './lib/apis/notice';
|
export * from './lib/apis/notice';
|
||||||
export * from './lib/apis/retrieve';
|
export * from './lib/apis/retrieve';
|
||||||
|
|
|
@ -310,6 +310,13 @@
|
||||||
>
|
>
|
||||||
{{ 'chat.searchEventByText' | translate }}
|
{{ 'chat.searchEventByText' | translate }}
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
mat-menu-item
|
||||||
|
*ngIf="getShowContextMenu('CHAT_EXPORT')"
|
||||||
|
(click)="onClickContextMenu('CHAT_EXPORT')"
|
||||||
|
>
|
||||||
|
{{ 'chat.eventDownload' | translate }}
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
*ngIf="getShowContextMenu('OPEN_ROOM_USER')"
|
*ngIf="getShowContextMenu('OPEN_ROOM_USER')"
|
||||||
|
|
|
@ -8,7 +8,8 @@ import {
|
||||||
EventEmitter,
|
EventEmitter,
|
||||||
Inject,
|
Inject,
|
||||||
ChangeDetectorRef,
|
ChangeDetectorRef,
|
||||||
ChangeDetectionStrategy
|
ChangeDetectionStrategy,
|
||||||
|
NgZone
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import {
|
import {
|
||||||
ucapAnimations,
|
ucapAnimations,
|
||||||
|
@ -73,7 +74,7 @@ import {
|
||||||
RoomType,
|
RoomType,
|
||||||
UserInfoShort
|
UserInfoShort
|
||||||
} from '@ucap-webmessenger/protocol-room';
|
} from '@ucap-webmessenger/protocol-room';
|
||||||
import { take, map, catchError, tap } from 'rxjs/operators';
|
import { take, map, catchError, tap, finalize } from 'rxjs/operators';
|
||||||
import {
|
import {
|
||||||
FormComponent as UCapUiChatFormComponent,
|
FormComponent as UCapUiChatFormComponent,
|
||||||
MessagesComponent as UCapUiChatMessagesComponent,
|
MessagesComponent as UCapUiChatMessagesComponent,
|
||||||
|
@ -101,7 +102,7 @@ import {
|
||||||
FileViewerDialogData,
|
FileViewerDialogData,
|
||||||
FileViewerDialogResult
|
FileViewerDialogResult
|
||||||
} from '@app/layouts/common/dialogs/file-viewer.dialog.component';
|
} from '@app/layouts/common/dialogs/file-viewer.dialog.component';
|
||||||
import { FileUtil, StickerFilesInfo } from '@ucap-webmessenger/core';
|
import { FileUtil, StickerFilesInfo, MimeUtil } from '@ucap-webmessenger/core';
|
||||||
|
|
||||||
import { StatusCode } from '@ucap-webmessenger/api';
|
import { StatusCode } from '@ucap-webmessenger/api';
|
||||||
import {
|
import {
|
||||||
|
@ -137,6 +138,11 @@ import {
|
||||||
} from '../dialogs/conference/conference-detail.dialog.component';
|
} from '../dialogs/conference/conference-detail.dialog.component';
|
||||||
import { ConferenceService } from '@ucap-webmessenger/api-prompt';
|
import { ConferenceService } from '@ucap-webmessenger/api-prompt';
|
||||||
import { AuthResponse } from '@ucap-webmessenger/protocol-query';
|
import { AuthResponse } from '@ucap-webmessenger/protocol-query';
|
||||||
|
import {
|
||||||
|
MessageApiService,
|
||||||
|
EventDownloadRequest
|
||||||
|
} from '@ucap-webmessenger/api-message';
|
||||||
|
import moment from 'moment';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-layout-messenger-messages',
|
selector: 'app-layout-messenger-messages',
|
||||||
|
@ -256,7 +262,9 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||||
private snackBarService: SnackBarService,
|
private snackBarService: SnackBarService,
|
||||||
@Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService,
|
@Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService,
|
||||||
private appFileService: AppFileService,
|
private appFileService: AppFileService,
|
||||||
private logger: NGXLogger
|
private messageApiService: MessageApiService,
|
||||||
|
private logger: NGXLogger,
|
||||||
|
private ngZone: NgZone
|
||||||
) {
|
) {
|
||||||
this.sessionVerInfo = this.sessionStorageService.get<VersionInfo2Response>(
|
this.sessionVerInfo = this.sessionStorageService.get<VersionInfo2Response>(
|
||||||
KEY_VER_INFO
|
KEY_VER_INFO
|
||||||
|
@ -578,6 +586,20 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
} else if (['CHAT_EXPORT'].some(v => v === menuType)) {
|
||||||
|
if (
|
||||||
|
!this.roomInfoSubject.value ||
|
||||||
|
!this.roomInfoSubject.value.roomType ||
|
||||||
|
[
|
||||||
|
RoomType.Allim,
|
||||||
|
RoomType.Bot,
|
||||||
|
RoomType.Link,
|
||||||
|
RoomType.Allim_Elephant,
|
||||||
|
RoomType.Allim_TMS
|
||||||
|
].some(v => v === this.roomInfoSubject.value.roomType)
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1549,6 +1571,11 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||||
this.onShowToggleSearchArea();
|
this.onShowToggleSearchArea();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'CHAT_EXPORT':
|
||||||
|
{
|
||||||
|
this.onExportChatEvent();
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'OPEN_ROOM_USER':
|
case 'OPEN_ROOM_USER':
|
||||||
{
|
{
|
||||||
this.store.dispatch(
|
this.store.dispatch(
|
||||||
|
@ -1938,6 +1965,90 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** About Chat Export */
|
||||||
|
onExportChatEvent() {
|
||||||
|
let roomName = this.roomInfoSubject.value.roomName;
|
||||||
|
if (!roomName || roomName.trim().length === 0) {
|
||||||
|
roomName = this.getRoomNameByRoomUser(this._roomUserInfos);
|
||||||
|
}
|
||||||
|
const date = moment().format('YYYYMMDDHHmmss');
|
||||||
|
const fileName = `${roomName}_${date}${this.roomInfoSubject.value.roomSeq}.csv`;
|
||||||
|
const fileTalkDownloadError = (reason: any) => {
|
||||||
|
this.logger.warn(reason);
|
||||||
|
this.snackBarService.openFromComponent<
|
||||||
|
AlertSnackbarComponent,
|
||||||
|
AlertSnackbarData
|
||||||
|
>(AlertSnackbarComponent, {
|
||||||
|
data: {
|
||||||
|
html: this.translateService.instant('common.file.errors.failToSave'),
|
||||||
|
buttonText: this.translateService.instant('common.file.errors.label')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
this.messageApiService
|
||||||
|
.eventDownload({
|
||||||
|
userSeq: this.loginResSubject.value.userSeq,
|
||||||
|
deviceType: this.environmentsInfo.deviceType,
|
||||||
|
token: this.loginResSubject.value.tokenString,
|
||||||
|
roomSeq: this.roomInfoSubject.value.roomSeq
|
||||||
|
})
|
||||||
|
.pipe(
|
||||||
|
take(1),
|
||||||
|
map(rawBlob => {
|
||||||
|
const mimeType = MimeUtil.getMimeFromExtension(
|
||||||
|
FileUtil.getExtension(fileName)
|
||||||
|
);
|
||||||
|
const blob = rawBlob.slice(0, rawBlob.size, mimeType);
|
||||||
|
FileUtil.fromBlobToBuffer(blob)
|
||||||
|
.then(buffer => {
|
||||||
|
this.nativeService
|
||||||
|
.saveFile(buffer, fileName, mimeType)
|
||||||
|
.then(filePath => {
|
||||||
|
if (!!filePath) {
|
||||||
|
const snackBarRef = this.snackBarService.open(
|
||||||
|
this.translateService.instant(
|
||||||
|
'common.file.results.savedToPath',
|
||||||
|
{
|
||||||
|
path: filePath
|
||||||
|
}
|
||||||
|
),
|
||||||
|
this.translateService.instant('common.file.open'),
|
||||||
|
{
|
||||||
|
duration: 3000,
|
||||||
|
verticalPosition: 'bottom',
|
||||||
|
horizontalPosition: 'center'
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
snackBarRef.onAction().subscribe(() => {
|
||||||
|
snackBarRef.dismiss();
|
||||||
|
this.ngZone.runOutsideAngular(() => {
|
||||||
|
this.nativeService
|
||||||
|
.openTargetItem(filePath)
|
||||||
|
.catch(reason => {
|
||||||
|
this.logger.warn(reason);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
fileTalkDownloadError('fail');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(reason => {
|
||||||
|
fileTalkDownloadError(reason);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(reason => {
|
||||||
|
fileTalkDownloadError(reason);
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
finalize(() => {}),
|
||||||
|
catchError(error => of(error))
|
||||||
|
)
|
||||||
|
.subscribe();
|
||||||
|
}
|
||||||
|
|
||||||
/** About Translation */
|
/** About Translation */
|
||||||
onShowToggleTranslation() {
|
onShowToggleTranslation() {
|
||||||
this.isShowTranslation = !this.isShowTranslation;
|
this.isShowTranslation = !this.isShowTranslation;
|
||||||
|
|
|
@ -197,6 +197,7 @@
|
||||||
"newChat": "New Chat",
|
"newChat": "New Chat",
|
||||||
"startChat": "Chat",
|
"startChat": "Chat",
|
||||||
"openRoom": "Open room",
|
"openRoom": "Open room",
|
||||||
|
"eventDownload": "export chat",
|
||||||
"listOfRoomMember": "List of room member",
|
"listOfRoomMember": "List of room member",
|
||||||
"settingsOfRoom": "Settings of room",
|
"settingsOfRoom": "Settings of room",
|
||||||
"turnOnRoomAlert": "Turn on room alert",
|
"turnOnRoomAlert": "Turn on room alert",
|
||||||
|
|
|
@ -197,6 +197,7 @@
|
||||||
"newChat": "새로운 대화",
|
"newChat": "새로운 대화",
|
||||||
"startChat": "대화하기",
|
"startChat": "대화하기",
|
||||||
"openRoom": "대화방 열기",
|
"openRoom": "대화방 열기",
|
||||||
|
"eventDownload": "대화 내용 내보내기",
|
||||||
"listOfRoomMember": "대화 참여자 목록",
|
"listOfRoomMember": "대화 참여자 목록",
|
||||||
"settingsOfRoom": "대화방 설정",
|
"settingsOfRoom": "대화방 설정",
|
||||||
"turnOnRoomAlert": "대화방 알람 켜기",
|
"turnOnRoomAlert": "대화방 알람 켜기",
|
||||||
|
@ -364,16 +365,16 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"conference": {
|
"conference": {
|
||||||
"detailView": "상세 보기",
|
"detailView": "상세 보기",
|
||||||
"videoConferenceTypeNow": "[화상회의] 개설",
|
"videoConferenceTypeNow": "[화상회의] 개설",
|
||||||
"videoConferenceTypeNew": "[화상회의] 예약",
|
"videoConferenceTypeNew": "[화상회의] 예약",
|
||||||
"videoConferenceTypeUpdate": "[화상회의] 수정",
|
"videoConferenceTypeUpdate": "[화상회의] 수정",
|
||||||
"videoConferenceTypeDelete": "[화상회의] 삭제",
|
"videoConferenceTypeDelete": "[화상회의] 삭제",
|
||||||
"videoConferenceRegister": "개설자",
|
"videoConferenceRegister": "개설자",
|
||||||
"videoConferenceAttendee": "참여자",
|
"videoConferenceAttendee": "참여자",
|
||||||
"videoConferenceDate": "날짜",
|
"videoConferenceDate": "날짜",
|
||||||
"videoConferenceRoom": "회의실",
|
"videoConferenceRoom": "회의실",
|
||||||
"videoConferenceEnjoy": "참석하기"
|
"videoConferenceEnjoy": "참석하기"
|
||||||
},
|
},
|
||||||
"update": {
|
"update": {
|
||||||
"label": "업데이트"
|
"label": "업데이트"
|
||||||
|
|
|
@ -167,7 +167,9 @@ export const messageApiUrls: MessageApiUrls = {
|
||||||
|
|
||||||
retrieveUnreadCount: '/uCapMsg/msg/retrieveUnreadCount.do',
|
retrieveUnreadCount: '/uCapMsg/msg/retrieveUnreadCount.do',
|
||||||
|
|
||||||
retrieveNoticeList: '/uCapMsg/notice/retrieveNoticeList.do'
|
retrieveNoticeList: '/uCapMsg/notice/retrieveNoticeList.do',
|
||||||
|
|
||||||
|
eventDownload: '/uCapMsg/event/download'
|
||||||
};
|
};
|
||||||
export const promptUrls: PromptUrls = {
|
export const promptUrls: PromptUrls = {
|
||||||
sendCall: '/uCapPrompt/api/call/clicktocall',
|
sendCall: '/uCapPrompt/api/call/clicktocall',
|
||||||
|
|
Loading…
Reference in New Issue
Block a user