移除本地缓存用户信息

This commit is contained in:
禾几海
2020-05-19 17:44:04 +08:00
parent 00f69509c3
commit f8d3494626
8 changed files with 113 additions and 86 deletions

View File

@@ -59,8 +59,8 @@ export class HttpService {
if (tokenFromReps) { if (tokenFromReps) {
this.localStorageService.setToken(tokenFromReps); this.localStorageService.setToken(tokenFromReps);
} }
if (o.body.code) { if (o.body.code !== 0) {
observer.error(o); observer.error(o.body);
if (this.errorDispatch) { if (this.errorDispatch) {
this.errorDispatch.errHandler(o.body.code, o.body.msg, request); this.errorDispatch.errHandler(o.body.code, o.body.msg, request);
} }

View File

@@ -1,7 +1,7 @@
import {Injectable} from '@angular/core'; import {Injectable} from '@angular/core';
import {LoginReq, User} from '../class/User'; import {LoginReq, User} from '../class/User';
import {ApiService} from '../api/api.service'; import {ApiService} from '../api/api.service';
import {Observable, Observer} from 'rxjs'; import {Observable, Observer, Subscription} from 'rxjs';
import {Response} from '../class/HttpReqAndResp'; import {Response} from '../class/HttpReqAndResp';
import {LocalStorageService} from './local-storage.service'; import {LocalStorageService} from './local-storage.service';
@@ -15,42 +15,32 @@ export class GlobalUserService {
} }
private lastRequestTime: number; private lastRequestTime: number;
private userInfo: User = null;
// 存储订阅者 // 存储订阅者
private userObserverArray: Observer<Response<User>>[] = []; private userObserverArray: Observer<Response<User>>[] = [];
private multicastArray: Observer<Response<User>>[] = [];
watchUserInfo(observer: Observer<Response<User>>) { watchUserInfo(observer: Observer<Response<User>>) {
if (this.userObserverArray.indexOf(observer) < 0) this.userObserverArray.push(observer); if (this.userObserverArray.indexOf(observer) < 0) this.userObserverArray.push(observer);
const user = this.localStorageService.getUser(); this.multicastArray = [...this.userObserverArray];
// 判断本地缓存的用户信息是否符合要求,符合要求返回本地缓存 let subscription: Subscription = null;
if (this.localStorageService.isLogin() && user && !this.localStorageService.checkNeedNet()) { const unsubscribe = () => {
observer.next(new Response<User>(user));
return {
unsubscribe() {
observer.complete();
}
}
}
if (this.lastRequestTime && Date.now() - this.lastRequestTime < 500) {
return {
unsubscribe: () => {
this.userObserverArray.splice(this.userObserverArray.indexOf(observer), 1); this.userObserverArray.splice(this.userObserverArray.indexOf(observer), 1);
observer.complete(); observer.complete();
} if (subscription) subscription.unsubscribe();
} };
} if (this.lastRequestTime && Date.now() - this.lastRequestTime < 3000) {
// 不符合 请求网络数据并更新缓存 if (this.userInfo && this.multicastArray.length) {
// 向订阅者传数据 this.broadcast()
this.lastRequestTime = Date.now(); this.lastRequestTime = Date.now();
}
return {unsubscribe}
}
// 获取数据 // 获取数据
const subscription = this.getUserInfoFromServer(); subscription = this.getUserInfoFromServer();
return { return {unsubscribe}
unsubscribe: () => {
this.userObserverArray.splice(this.userObserverArray.indexOf(observer), 1);
observer.complete();
subscription.unsubscribe()
}
}
} }
// 刷新用户信息 // 刷新用户信息
@@ -59,14 +49,16 @@ export class GlobalUserService {
} }
login(loginReq: LoginReq, observer: Observer<Response<User>>) { login(loginReq: LoginReq, observer: Observer<Response<User>>) {
this.multicastArray = [...this.userObserverArray];
const oob = new Observable<Response<User>>(o => observer = o); const oob = new Observable<Response<User>>(o => observer = o);
const subscription = this.apiService.login(loginReq).subscribe({ const subscription = this.apiService.login(loginReq).subscribe({
next: o => { next: o => {
// 登录成功 // 登录成功
this.localStorageService.setToken(o.result.token); this.localStorageService.setToken(o.result.token);
this.localStorageService.setUser(o.result); // this.localStorageService.setUser(o.result);
// this.userObserver.next(o); // this.userObserver.next(o);
this.userObserverArray.forEach(ob => ob.next(o)) this.userInfo = o.result;
this.broadcast()
observer.next(o); observer.next(o);
observer.complete(); observer.complete();
}, },
@@ -84,10 +76,12 @@ export class GlobalUserService {
} }
logout(observer?: Observer<Response<string>>) { logout(observer?: Observer<Response<string>>) {
this.userInfo = null;
this.multicastArray = [...this.userObserverArray];
// 如果不需要返回消息也ok // 如果不需要返回消息也ok
this.apiService.logout().subscribe(data => { this.apiService.logout().subscribe(data => {
this.localStorageService.clear(); this.localStorageService.clear();
this.userObserverArray.forEach(ob => ob.next(new Response<User>(null))) this.broadcast()
if (observer) { if (observer) {
observer.next(data); observer.next(data);
observer.complete(); observer.complete();
@@ -101,22 +95,42 @@ export class GlobalUserService {
}) })
} }
private getUserInfoFromServer() { getUserInfoFromServer(observer?: Observer<Response<User>>) {
return this.apiService.userInfo().subscribe({ return this.apiService.userInfo().subscribe({
next: o => { next: o => {
this.localStorageService.setUser(o.result); this.lastRequestTime = Date.now();
this.userObserverArray.forEach(ob => ob.next(o)); this.userInfo = o.result;
// this.localStorageService.setUser(o.result);
this.broadcast()
if (observer) {
observer.next(o);
observer.complete();
}
// this.requested = false;
}, },
error: err => { error: err => {
// console.debug('登录过期 token错误 等等'); // console.debug('登录过期 token错误 等等');
if (observer) {
observer.error(err);
observer.complete();
}
if (err.code === -1) { if (err.code === -1) {
// 请求重复 // 请求重复
return return
} }
this.localStorageService.removeToken(); // this.requested = false;
this.userObserverArray.forEach(ob => ob.next(new Response<User>(null))); // this.localStorageService.removeToken();
this.userObserverArray.forEach(ob => ob.error && ob.error(err)); this.multicastArray.forEach(ob => ob.next(new Response<User>(this.userInfo)))
this.multicastArray.forEach(ob => ob.error(err))
this.multicastArray.splice(0, this.multicastArray.length);
} }
}); });
} }
private broadcast() {
this.multicastArray.forEach(ob => ob.next(new Response<User>(this.userInfo)))
this.multicastArray.splice(0, this.multicastArray.length);
}
} }

View File

@@ -29,21 +29,21 @@ export class LocalStorageService {
return this.getToken() != null; return this.getToken() != null;
} }
setUser(user: User) { // setUser(user: User) {
// TODO: 简单加个密 // // TODO: 简单加个密
localStorage.setItem('t', new Date().valueOf().toString()); // localStorage.setItem('t', new Date().valueOf().toString());
return localStorage.setItem('user', JSON.stringify(user)); // return localStorage.setItem('user', JSON.stringify(user));
} // }
//
getUser(): User { // getUser(): User {
if (!this.checkNeedNet()) { // if (!this.checkNeedNet()) {
return JSON.parse(localStorage.getItem('user')); // return JSON.parse(localStorage.getItem('user'));
} // }
} // }
//
removeUser() { // removeUser() {
return localStorage.removeItem('user'); // return localStorage.removeItem('user');
} // }
clear() { clear() {
localStorage.removeItem('token'); localStorage.removeItem('token');
@@ -51,13 +51,13 @@ export class LocalStorageService {
return localStorage.removeItem('t'); return localStorage.removeItem('t');
} }
checkNeedNet() { // checkNeedNet() {
const t: number = Number.parseInt(localStorage.getItem('t'), 10); // const t: number = Number.parseInt(localStorage.getItem('t'), 10);
if (isNaN(t) || new Date().valueOf() - t > this.place) { // if (isNaN(t) || new Date().valueOf() - t > this.place) {
localStorage.removeItem('t'); // localStorage.removeItem('t');
localStorage.removeItem('user'); // localStorage.removeItem('user');
return true; // return true;
} // }
return false; // return false;
} // }
} }

View File

@@ -30,6 +30,7 @@ export class AdminDashboardComponent implements OnInit {
dayVisitCount: number = 0; dayVisitCount: number = 0;
userInfo: User = new User(); userInfo: User = new User();
private isRequested: boolean = false;
ngOnInit(): void { ngOnInit(): void {
} }
@@ -52,13 +53,14 @@ export class AdminDashboardComponent implements OnInit {
getUserInfo = () => this.userService.watchUserInfo({ getUserInfo = () => this.userService.watchUserInfo({
next: data => { next: data => {
this.userInfo = data.result this.userInfo = data.result
if (data.result && data.result.role === 'admin') { if (data.result && data.result.role === 'admin' && !this.isRequested) {
this.getLog(); this.getLog();
this.getCounts(); this.getCounts();
this.isRequested = true;
this.getDayVisitCount(); this.getDayVisitCount();
} }
}, },
error: null, error: () => null,
complete: null complete: () => null
}) })
} }

View File

@@ -8,47 +8,47 @@ const routes: Routes = [
{ {
path: '', path: '',
component: AdminComponent, component: AdminComponent,
// canActivate: [AuthGuard], canActivate: [AuthGuard],
children: [ children: [
{ {
path: 'article', path: 'article',
loadChildren: () => import('./admin-article/admin-article.module').then(mod => mod.AdminArticleModule), loadChildren: () => import('./admin-article/admin-article.module').then(mod => mod.AdminArticleModule),
canActivate: [AuthGuard] // canActivate: [AuthGuard]
}, },
{ {
path: 'comment', path: 'comment',
loadChildren: () => import('./admin-comment/admin-comment.module').then(mod => mod.AdminCommentModule), loadChildren: () => import('./admin-comment/admin-comment.module').then(mod => mod.AdminCommentModule),
canActivate: [AuthGuard] // canActivate: [AuthGuard]
}, },
{ {
path: 'link', path: 'link',
loadChildren: () => import('./admin-link/admin-link.module').then(mod => mod.AdminLinkModule), loadChildren: () => import('./admin-link/admin-link.module').then(mod => mod.AdminLinkModule),
canActivate: [AuthGuard] // canActivate: [AuthGuard]
}, },
{ {
path: 'tag', path: 'tag',
loadChildren: () => import('./admin-tag/admin-tag.module').then(mod => mod.AdminTagModule), loadChildren: () => import('./admin-tag/admin-tag.module').then(mod => mod.AdminTagModule),
canActivate: [AuthGuard] // canActivate: [AuthGuard]
}, },
{ {
path: 'update', path: 'update',
loadChildren: () => import('./admin-update/admin-update.module').then(mod => mod.AdminUpdateModule), loadChildren: () => import('./admin-update/admin-update.module').then(mod => mod.AdminUpdateModule),
canActivate: [AuthGuard] // canActivate: [AuthGuard]
}, },
{ {
path: 'user', path: 'user',
loadChildren: () => import('./admin-user/admin-user.module').then(mod => mod.AdminUserModule), loadChildren: () => import('./admin-user/admin-user.module').then(mod => mod.AdminUserModule),
canActivate: [AuthGuard] // canActivate: [AuthGuard]
}, },
{ {
path: 'visitor', path: 'visitor',
loadChildren: () => import('./admin-visitor/admin-visitor.module').then(mod => mod.AdminVisitorModule), loadChildren: () => import('./admin-visitor/admin-visitor.module').then(mod => mod.AdminVisitorModule),
canActivate: [AuthGuard] // canActivate: [AuthGuard]
}, },
{ {
path: '**', path: '**',
loadChildren: () => import('./admin-dashboard/admin-dashboard.module').then(mod => mod.AdminDashboardModule), loadChildren: () => import('./admin-dashboard/admin-dashboard.module').then(mod => mod.AdminDashboardModule),
canActivate: [AuthGuard] // canActivate: [AuthGuard]
} }
] ]
} }

View File

@@ -91,24 +91,24 @@
<nz-drawer [nzClosable]="false" [nzVisible]="infoDrawerVisible" nzPlacement="right" <nz-drawer [nzClosable]="false" [nzVisible]="infoDrawerVisible" nzPlacement="right"
[nzTitle]="sayHelloTemp" (nzOnClose)="infoDrawerVisible = false"> [nzTitle]="sayHelloTemp" (nzOnClose)="infoDrawerVisible = false">
<p>您最近一次登录是在:</p> <p>您最近一次登录是在:</p>
<p>{{user.recentlyLandedDate}}</p> <p>{{user&&user.recentlyLandedDate}}</p>
<nz-divider></nz-divider> <nz-divider></nz-divider>
<nz-descriptions [nzColumn]="1"> <nz-descriptions [nzColumn]="1">
<nz-descriptions-item nzTitle="邮箱"> <nz-descriptions-item nzTitle="邮箱">
<div> <div>
<i nz-icon nzType="mail" class="icon" nzTheme="twotone"></i> <i nz-icon nzType="mail" class="icon" nzTheme="twotone"></i>
<span>{{user.email}}</span> <span>{{user&&user.email}}</span>
<i nz-icon nzType="edit" class="edit-icon" nzTheme="twotone" (click)="showEditInfoModal()"></i> <i nz-icon nzType="edit" class="edit-icon" nzTheme="twotone" (click)="showEditInfoModal()"></i>
</div> </div>
</nz-descriptions-item> </nz-descriptions-item>
<nz-descriptions-item nzTitle="昵称"> <nz-descriptions-item nzTitle="昵称">
<div> <div>
<i nz-icon nzType="crown" class="icon" nzTheme="twotone"></i> <i nz-icon nzType="crown" class="icon" nzTheme="twotone"></i>
<span>{{user.displayName}}</span> <span>{{user&&user.displayName}}</span>
<i nz-icon nzType="edit" class="edit-icon" nzTheme="twotone" (click)="showEditInfoModal()"></i> <i nz-icon nzType="edit" class="edit-icon" nzTheme="twotone" (click)="showEditInfoModal()"></i>
</div> </div>
</nz-descriptions-item> </nz-descriptions-item>
<nz-descriptions-item nzTitle="描述" *ngIf="user.desc"> <nz-descriptions-item nzTitle="描述" *ngIf="user&&user.desc">
<i nz-icon nzType="info-circle" class="icon" nzTheme="twotone"></i> <i nz-icon nzType="info-circle" class="icon" nzTheme="twotone"></i>
<span nz-tooltip [nzTooltipTitle]="user.desc" nzTooltipPlacement="left" nz-typography [nzEllipsis]="true" [nzContent]="user.desc" style="max-width: 100px">{{user.desc}}</span> <span nz-tooltip [nzTooltipTitle]="user.desc" nzTooltipPlacement="left" nz-typography [nzEllipsis]="true" [nzContent]="user.desc" style="max-width: 100px">{{user.desc}}</span>
<i nz-icon nzType="edit" class="edit-icon" nzTheme="twotone" (click)="showEditInfoModal()"></i> <i nz-icon nzType="edit" class="edit-icon" nzTheme="twotone" (click)="showEditInfoModal()"></i>

View File

@@ -6,6 +6,7 @@ import {NgZorroAntdModule} from 'ng-zorro-antd';
import {NzSpaceModule} from 'ng-zorro-antd/space'; import {NzSpaceModule} from 'ng-zorro-antd/space';
import {AdminHeaderComponent} from '../../components/admin-header/admin-header.component'; import {AdminHeaderComponent} from '../../components/admin-header/admin-header.component';
import {ReactiveFormsModule} from '@angular/forms'; import {ReactiveFormsModule} from '@angular/forms';
import {AuthGuard} from './auth.guard';
@NgModule({ @NgModule({
@@ -18,8 +19,9 @@ import {ReactiveFormsModule} from '@angular/forms';
AdminRoutingModule, AdminRoutingModule,
NgZorroAntdModule, NgZorroAntdModule,
NzSpaceModule, NzSpaceModule,
ReactiveFormsModule ReactiveFormsModule,
] ],
providers: [AuthGuard]
}) })
export class AdminModule { export class AdminModule {
} }

View File

@@ -1,5 +1,12 @@
import {Injectable} from '@angular/core'; import {Injectable} from '@angular/core';
import {CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router} from '@angular/router'; import {
CanActivate,
ActivatedRouteSnapshot,
RouterStateSnapshot,
UrlTree,
Router,
CanActivateChild
} from '@angular/router';
import {Observable, Observer} from 'rxjs'; import {Observable, Observer} from 'rxjs';
import {User} from '../../class/User'; import {User} from '../../class/User';
import {GlobalUserService} from '../../services/global-user.service'; import {GlobalUserService} from '../../services/global-user.service';
@@ -10,7 +17,6 @@ import {GlobalUserService} from '../../services/global-user.service';
export class AuthGuard implements CanActivate { export class AuthGuard implements CanActivate {
constructor(private userService: GlobalUserService, private router: Router) { constructor(private userService: GlobalUserService, private router: Router) {
// this.userService.refreshUserInfo();
} }
userInfo: User; userInfo: User;
@@ -34,11 +40,12 @@ export class AuthGuard implements CanActivate {
watchUserInfo(observer: Observer<boolean>) { watchUserInfo(observer: Observer<boolean>) {
this.userService.watchUserInfo({ this.userService.watchUserInfo({
complete: null, complete: () => null,
error: (err) => { error: (err) => {
// 请求重复 // 请求重复
if (err.code !== -1) { if (err.code !== -1) {
observer.next(false); observer.next(false);
observer.complete();
this.router.navigateByUrl(this.loginPath); this.router.navigateByUrl(this.loginPath);
} }
}, },
@@ -58,13 +65,15 @@ export class AuthGuard implements CanActivate {
case '/admin/update': case '/admin/update':
case '/admin/user': case '/admin/user':
case '/admin/visitor': case '/admin/visitor':
if (this.userInfo.role !== 'admin') { if (this.userInfo && this.userInfo.role !== 'admin') {
observer.next(false) observer.next(false);
observer.complete();
if (this.visitCount === 1) this.router.navigateByUrl('/admin') if (this.visitCount === 1) this.router.navigateByUrl('/admin')
return; return;
} }
} }
observer.next(true); observer.next(true);
observer.complete();
} }
} }