import { DOCUMENT } from '@angular/common' ; import { Inject , Injectable , OnDestroy } from '@angular/core' ; import { Router } from '@angular/router' ; import { Observable , Observer } from 'rxjs' ; import type { NzSafeAny } from 'ng-zorro-antd/core/types' ; import { DA_SERVICE_TOKEN , ITokenModel , ITokenService } from '../token/interface' ; const OPENTYPE = '_delonAuthSocialType' ; const HREFCALLBACK = '_delonAuthSocialCallbackByHref' ; export type SocialOpenType = 'href' | 'window' ; @ Injectable ( ) export class SocialService implements OnDestroy { private _win : Window | null = null ; private _winTime : NzSafeAny ; private observer ! : Observer < ITokenModel | null > ; constructor ( @ Inject ( DA_SERVICE_TOKEN ) private tokenService , @ Inject ( DOCUMENT ) private doc , private router ) { } param url param callback param options . windowFeatures login ( url , callback ? , options ? ) ; param url param callback login ( url , callback ? , options ? ) ; param url param callback param options . type param options . windowFeatures login ( url , callback = '/' , options = { } ) { options = { type : 'window' , windowFeatures : 'location=yes,height=570,width=520,scrollbars=yes,status=yes' , ... options } ; localStorage . setItem ( OPENTYPE , options . type ! ) ; localStorage . setItem ( HREFCALLBACK , callback ) ; if ( options . type === 'href' ) { this . doc . location . href = url ; return ; } this . _win = window . open ( url , '_blank' , options . windowFeatures ) ; this . _winTime = setInterval ( ( ) => { if ( this . _win && this . _win . closed ) { this . ngOnDestroy ( ) ; let model = this . tokenService . get ( ) ; if ( model && ! model . token ) model = null ; if ( model ) { this . tokenService . set ( model ) ; } this . observer . next ( model ) ; this . observer . complete ( ) ; } } , 100 ) ; return new Observable ( ( observer ) => { this . observer = observer ; } ) ; } param rawData callback ( rawData ? ) { if ( ! rawData && this . router . url . indexOf ( '?' ) === - 1 ) { throw new Error ( `url muse contain a ?` ) ; } let data = { token : `` } ; if ( typeof rawData === 'string' ) { const rightUrl = rawData . split ( '?' ) [ 1 ] . split ( '#' ) [ 0 ] ; data = this . router . parseUrl ( `./?${ rightUrl }` ) . queryParams as ITokenModel ; } else { data = rawData as ITokenModel ; } if ( ! data || ! data . token ) throw new Error ( `invalide token data` ) ; this . tokenService . set ( data ) ; const url = localStorage . getItem ( HREFCALLBACK ) || '/' ; localStorage . removeItem ( HREFCALLBACK ) ; const type = localStorage . getItem ( OPENTYPE ) ; localStorage . removeItem ( OPENTYPE ) ; if ( type === 'window' ) { window . close ( ) ; } else { this . router . navigateByUrl ( url ) ; } return data ; } ngOnDestroy ( ) { clearInterval ( this . _winTime ) ; this . _winTime = null ; } }