로그인시 네트워크 절체된 상황 처리.

This commit is contained in:
leejinho 2020-03-20 13:57:50 +09:00
parent df63108a53
commit 88d3680247
5 changed files with 177 additions and 31 deletions

View File

@ -53,7 +53,7 @@
</div> </div>
--> -->
<ucap-account-login <ucap-account-login
[companyList]="companyList$ | async" [companyList]="companyList"
[curCompanyCode]="fixedCompany" [curCompanyCode]="fixedCompany"
[notiText]="fixedNotiBtnText" [notiText]="fixedNotiBtnText"
[loginBtnEnable]="loginBtnEnable" [loginBtnEnable]="loginBtnEnable"

View File

@ -2,14 +2,18 @@ import { Component, OnInit, OnDestroy, Inject } from '@angular/core';
import { Store, select } from '@ngrx/store'; import { Store, select } from '@ngrx/store';
import { Company } from '@ucap-webmessenger/api-external'; import {
Company,
ExternalApiService,
CompanyListRequest
} from '@ucap-webmessenger/api-external';
import { ServerErrorCode, ProtocolService } from '@ucap-webmessenger/protocol'; import { ServerErrorCode, ProtocolService } from '@ucap-webmessenger/protocol';
import * as AppStore from '@app/store'; import * as AppStore from '@app/store';
import * as AuthenticationStore from '@app/store/account/authentication'; import * as AuthenticationStore from '@app/store/account/authentication';
import * as CompanyStore from '@app/store/setting/company'; import * as CompanyStore from '@app/store/setting/company';
import { Observable, Subscription } from 'rxjs'; import { Observable, Subscription, of } from 'rxjs';
import { map } from 'rxjs/operators'; import { map, take, catchError } from 'rxjs/operators';
import { import {
DialogService, DialogService,
AlertDialogComponent, AlertDialogComponent,
@ -34,6 +38,7 @@ import { AppAuthenticationService } from '@app/services/authentication.service';
import { logoutInitialize } from '@app/store/account/authentication'; import { logoutInitialize } from '@app/store/account/authentication';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { NativeService, UCAP_NATIVE_SERVICE } from '@ucap-webmessenger/native'; import { NativeService, UCAP_NATIVE_SERVICE } from '@ucap-webmessenger/native';
import { StatusCode } from '@ucap-webmessenger/api';
@Component({ @Component({
selector: 'app-page-account-login', selector: 'app-page-account-login',
@ -44,7 +49,8 @@ export class LoginPageComponent implements OnInit, OnDestroy {
fixedCompany: string; fixedCompany: string;
fixedNotiBtnText: string; fixedNotiBtnText: string;
companyList$: Observable<Company[]>; companyList: Company[];
companyListSubscription: Subscription;
loginFailureCount: Subscription; loginFailureCount: Subscription;
@ -85,6 +91,7 @@ export class LoginPageComponent implements OnInit, OnDestroy {
private protocolService: ProtocolService, private protocolService: ProtocolService,
private localStorageService: LocalStorageService, private localStorageService: LocalStorageService,
private sessionStorageService: SessionStorageService, private sessionStorageService: SessionStorageService,
private externalApiService: ExternalApiService,
private appAuthenticationService: AppAuthenticationService private appAuthenticationService: AppAuthenticationService
) { ) {
this.useRememberMe = this.useRememberMe =
@ -113,15 +120,36 @@ export class LoginPageComponent implements OnInit, OnDestroy {
this.defatulLoginBtnText = this.translateService.instant('accounts.login'); this.defatulLoginBtnText = this.translateService.instant('accounts.login');
this.defatulWaitingTime = 5 * 60; // sec this.defatulWaitingTime = 5 * 60; // sec
this.store.dispatch( this.externalApiService
CompanyStore.companyList({ .companyList({
companyGroupCode: environment.companyConfig.companyGroupCode companyGroupCode: environment.companyConfig.companyGroupCode
}) } as CompanyListRequest)
); .pipe(
take(1),
map(res => {
if (res.statusCode === StatusCode.Success) {
this.store.dispatch(CompanyStore.companyListSuccess(res));
} else {
this.store.dispatch(
CompanyStore.companyListFailure({ error: 'Failed' })
);
}
}),
catchError(error => {
console.log('network disconnected', error);
return of();
})
)
.subscribe();
this.companyList$ = this.store.pipe( this.companyListSubscription = this.store
select(AppStore.SettingSelector.CompanySelector.companyList) .pipe(
); select(AppStore.SettingSelector.CompanySelector.companyList),
map(companyList => {
this.companyList = companyList;
})
)
.subscribe();
this.loginFailureCount = this.store this.loginFailureCount = this.store
.pipe( .pipe(
@ -234,6 +262,9 @@ export class LoginPageComponent implements OnInit, OnDestroy {
} }
ngOnDestroy(): void { ngOnDestroy(): void {
if (!!this.companyListSubscription) {
this.companyListSubscription.unsubscribe();
}
if (!!this.loginFailureCount) { if (!!this.loginFailureCount) {
this.loginFailureCount.unsubscribe(); this.loginFailureCount.unsubscribe();
} }
@ -273,18 +304,73 @@ export class LoginPageComponent implements OnInit, OnDestroy {
this.loginBtnEnable = true; this.loginBtnEnable = true;
}, 30 * 1000); }, 30 * 1000);
this.store.dispatch( if (!this.companyList) {
AuthenticationStore.webLogin({ this.externalApiService
loginInfo: { .companyList({
companyCode: value.companyCode, companyGroupCode: environment.companyConfig.companyGroupCode
companyGroupType: 'C', } as CompanyListRequest)
loginId: value.loginId, .pipe(
loginPw: value.loginPw take(1),
}, map(res => {
rememberMe: value.rememberMe, if (res.statusCode === StatusCode.Success) {
autoLogin: value.autoLogin this.store.dispatch(CompanyStore.companyListSuccess(res));
}) // Recursion function > onLogin
); this.onLogin(value);
} else {
this.dialogService.open<
AlertDialogComponent,
AlertDialogData,
AlertDialogResult
>(AlertDialogComponent, {
width: '360px',
data: {
title: this.translateService.instant(
'accounts.errors.loginFailed'
),
html: this.translateService.instant(
'accounts.errors.networkFailedAndRetry'
)
}
});
this.loginBtnEnable = true;
}
}),
catchError(error => {
this.dialogService.open<
AlertDialogComponent,
AlertDialogData,
AlertDialogResult
>(AlertDialogComponent, {
width: '360px',
data: {
title: this.translateService.instant(
'accounts.errors.loginFailed'
),
html: this.translateService.instant(
'accounts.errors.networkFailedAndRetry'
)
}
});
this.loginBtnEnable = true;
return of();
})
)
.subscribe();
} else {
this.store.dispatch(
AuthenticationStore.webLogin({
loginInfo: {
companyCode: value.companyCode,
companyGroupType: 'C',
loginId: value.loginId,
loginPw: value.loginPw
},
rememberMe: value.rememberMe,
autoLogin: value.autoLogin
})
);
}
} }
onClickNoti() { onClickNoti() {

View File

@ -76,7 +76,11 @@ import {
ServiceProtocolService, ServiceProtocolService,
UserPasswordSetResponse UserPasswordSetResponse
} from '@ucap-webmessenger/protocol-service'; } from '@ucap-webmessenger/protocol-service';
import { DaesangUrlInfoResponse } from '@ucap-webmessenger/api-external'; import {
DaesangUrlInfoResponse,
ExternalApiService,
CompanyListRequest
} from '@ucap-webmessenger/api-external';
import { AppUserInfo, KEY_APP_USER_INFO } from '@app/types/app-user-info.type'; import { AppUserInfo, KEY_APP_USER_INFO } from '@app/types/app-user-info.type';
import { DaesangCipherService, WebLinkType } from '@ucap-webmessenger/daesang'; import { DaesangCipherService, WebLinkType } from '@ucap-webmessenger/daesang';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
@ -84,9 +88,13 @@ import {
InfoProtocolService, InfoProtocolService,
UserResponse UserResponse
} from '@ucap-webmessenger/protocol-info'; } from '@ucap-webmessenger/protocol-info';
import { StatusCode } from '@ucap-webmessenger/api';
@Injectable() @Injectable()
export class Effects { export class Effects {
retryCount = 0;
retryInterval = 3000; // ms
maxRetryCount = (10 * 60 * 1000) / this.retryInterval; // 200 count due to 10 min.
webLogin$ = createEffect( webLogin$ = createEffect(
() => () =>
this.actions$.pipe( this.actions$.pipe(
@ -97,8 +105,10 @@ export class Effects {
loginInfo: LoginInfo; loginInfo: LoginInfo;
rememberMe: boolean; rememberMe: boolean;
autoLogin: boolean; autoLogin: boolean;
}) => }) => {
this.piService const selfParam = params;
return this.piService
.login2({ .login2({
loginId: params.loginInfo.loginId, loginId: params.loginInfo.loginId,
loginPw: params.loginInfo.loginPw, loginPw: params.loginInfo.loginPw,
@ -109,6 +119,7 @@ export class Effects {
if ('success' !== res.status.toLowerCase()) { if ('success' !== res.status.toLowerCase()) {
if (!!params.autoLogin) { if (!!params.autoLogin) {
// auto login Failure. // auto login Failure.
this.store.dispatch(increaseLoginFailCount({}));
this.localStorageService.remove(KEY_APP_USER_INFO); this.localStorageService.remove(KEY_APP_USER_INFO);
this.router.navigateByUrl('/account/login'); this.router.navigateByUrl('/account/login');
} else { } else {
@ -127,8 +138,52 @@ export class Effects {
); );
} }
}), }),
catchError(error => of(webLoginFailure({ error }))) catchError(async error => {
) if (!!selfParam.autoLogin) {
if (this.maxRetryCount > this.retryCount) {
this.store.dispatch(logoutInitialize());
setTimeout(() => {
// this.store.dispatch(webLogin(selfParam));
this.router.navigateByUrl('/account/login');
}, this.retryInterval);
this.retryCount++;
console.log('retry', this.retryCount, this.maxRetryCount);
return of(webLoginFailure({ error }));
} else {
console.log(
'retry End',
this.retryCount,
this.maxRetryCount
);
}
}
const result = await this.dialogService.open<
AlertDialogComponent,
AlertDialogData,
AlertDialogResult
>(AlertDialogComponent, {
width: '360px',
data: {
title: this.translateService.instant(
'accounts.errors.loginFailed'
),
html: this.translateService.instant(
'accounts.errors.networkFailedAndExit'
)
}
});
if (!!result) {
this.nativeService.appExit();
}
console.log('not retry');
return of(webLoginFailure({ error }));
})
);
}
) )
), ),
{ dispatch: false } { dispatch: false }
@ -510,6 +565,7 @@ export class Effects {
private sessionStorageService: SessionStorageService, private sessionStorageService: SessionStorageService,
private piService: PiService, private piService: PiService,
private appAuthenticationService: AppAuthenticationService, private appAuthenticationService: AppAuthenticationService,
private externalApiService: ExternalApiService,
private protocolService: ProtocolService, private protocolService: ProtocolService,
private authenticationProtocolService: AuthenticationProtocolService, private authenticationProtocolService: AuthenticationProtocolService,
private infoProtocolService: InfoProtocolService, private infoProtocolService: InfoProtocolService,

View File

@ -45,7 +45,9 @@
"failToChangePassword": "Failed to change password.", "failToChangePassword": "Failed to change password.",
"loginFailed": "Failed to login", "loginFailed": "Failed to login",
"loginFailedIdPw": "Username or password do not match.", "loginFailedIdPw": "Username or password do not match.",
"loginFailOverTry": "Password error count exceeded. <br/> Check your password <br/> Please try again later." "loginFailOverTry": "Password error count exceeded. <br/> Check your password <br/> Please try again later.",
"networkFailedAndExit": "Please exit the program due to a network problem. <br/> Please check the network and try again.",
"networkFailedAndRetry": "Cannot run due to network problem. <br/> Please check the network and try again."
} }
}, },
"profile": { "profile": {

View File

@ -45,7 +45,9 @@
"failToChangePassword": "비밀번호 변경에 실패하였습니다.", "failToChangePassword": "비밀번호 변경에 실패하였습니다.",
"loginFailed": "로그인에 실패하였습니다.", "loginFailed": "로그인에 실패하였습니다.",
"loginFailedIdPw": "아이디 또는 패스워드가<br/>일치하지 않습니다.", "loginFailedIdPw": "아이디 또는 패스워드가<br/>일치하지 않습니다.",
"loginFailOverTry": "비밀번호 오류 횟수 초과입니다.<br/>비밀번호를 확인하신 후<br/>잠시 후 다시 시작해 주세요." "loginFailOverTry": "비밀번호 오류 횟수 초과입니다.<br/>비밀번호를 확인하신 후<br/>잠시 후 다시 시작해 주세요.",
"networkFailedAndExit": "네트워크 문제로 프로그램을 종료합니다.<br/>네트워크 확인후 다시 시도해 주세요.",
"networkFailedAndRetry": "네트워크 문제로 실행할 수 없습니다.<br/>네트워크 확인후 다시 시도해 주세요."
} }
}, },
"profile": { "profile": {