From 4f221d627627d2824a4fd2abe838bc87bc55b793 Mon Sep 17 00:00:00 2001 From: AlexBob <5199840@qq.com> Date: Wed, 24 Jul 2024 18:14:05 +0800 Subject: [PATCH] =?UTF-8?q?(feat-ng-ui):=20=E4=BC=98=E5=8C=96=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E9=80=BB=E8=BE=91=EF=BC=8C=E7=AE=80=E5=8C=96=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E7=BB=93=E6=9E=84=E5=B9=B6=E7=A7=BB=E9=99=A4=E6=9C=AA?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E7=9A=84=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../boot/relational/menus/MenusService.java | 2 +- .../relational/rsocket/CommandRequest.java | 2 - ng-ui/projects/web/src/app/app.component.ts | 2 +- .../web/src/app/home/index/index.component.ts | 18 +++- ng-ui/projects/web/src/core/auth.service.ts | 5 +- .../core/components/login/login.service.ts | 16 ++-- .../projects/web/src/core/http.Interceptor.ts | 6 +- .../projects/web/src/core/rsocket.service.ts | 82 ++++++++++--------- 8 files changed, 76 insertions(+), 57 deletions(-) diff --git a/boot/platform/src/main/java/com/platform/boot/relational/menus/MenusService.java b/boot/platform/src/main/java/com/platform/boot/relational/menus/MenusService.java index aa82b420..cbc24c4e 100644 --- a/boot/platform/src/main/java/com/platform/boot/relational/menus/MenusService.java +++ b/boot/platform/src/main/java/com/platform/boot/relational/menus/MenusService.java @@ -35,7 +35,7 @@ public class MenusService extends AbstractDatabase { public Flux search(MenuRequest request) { var cacheKey = BeanUtils.cacheKey(request); - Query query = Query.query(request.toCriteria()).sort(Sort.by("sort")); + Query query = Query.query(request.toCriteria()).sort(Sort.by("sortNo")); return this.queryWithCache(cacheKey, query, Menu.class) .flatMapSequential(ContextUtils::serializeUserAuditor); } diff --git a/boot/platform/src/main/java/com/platform/boot/relational/rsocket/CommandRequest.java b/boot/platform/src/main/java/com/platform/boot/relational/rsocket/CommandRequest.java index a00e2818..8a8608b1 100644 --- a/boot/platform/src/main/java/com/platform/boot/relational/rsocket/CommandRequest.java +++ b/boot/platform/src/main/java/com/platform/boot/relational/rsocket/CommandRequest.java @@ -9,9 +9,7 @@ */ @Data public class CommandRequest implements Serializable { - private MessageType type; private String command; private String content; - } diff --git a/ng-ui/projects/web/src/app/app.component.ts b/ng-ui/projects/web/src/app/app.component.ts index db17f92c..39815cfa 100644 --- a/ng-ui/projects/web/src/app/app.component.ts +++ b/ng-ui/projects/web/src/app/app.component.ts @@ -13,7 +13,7 @@ import { NzLayoutModule } from 'ng-zorro-antd/layout'; @Component({ selector: 'app-root', standalone: true, - imports: [RouterOutlet, NzBackTopModule, NzSpinModule, MatProgressBarModule, CommonModule, NzLayoutModule], + imports: [CommonModule, RouterOutlet, NzBackTopModule, NzSpinModule, MatProgressBarModule, NzLayoutModule], templateUrl: './app.component.html', styleUrl: './app.component.scss', }) diff --git a/ng-ui/projects/web/src/app/home/index/index.component.ts b/ng-ui/projects/web/src/app/home/index/index.component.ts index 7dfb3cf4..524c4c5f 100644 --- a/ng-ui/projects/web/src/app/home/index/index.component.ts +++ b/ng-ui/projects/web/src/app/home/index/index.component.ts @@ -1,8 +1,10 @@ -import { Component, OnInit, signal } from '@angular/core'; +import { Component, OnDestroy, OnInit, signal } from '@angular/core'; import { RouterModule } from '@angular/router'; import { PageHeaderComponent } from '../../../core/components/page-header/page-header.component'; import { MessageOut, RSocketCLientService } from '../../../core/rsocket.service'; import { NgFor } from '@angular/common'; +import { Subject } from 'rxjs/internal/Subject'; +import { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators'; @Component({ selector: 'home-index', @@ -11,12 +13,22 @@ import { NgFor } from '@angular/common'; templateUrl: './index.component.html', styleUrl: './index.component.scss', }) -export class IndexComponent implements OnInit { +export class IndexComponent implements OnInit, OnDestroy { dataSet = signal([] as MessageOut[]); + private componentDestroyed$: Subject = new Subject(); + constructor(private _rsocket: RSocketCLientService) {} ngOnInit(): void { - this._rsocket.requestStream('request.stream').subscribe(res => this.dataSet.update(value => [...value, res])); + this._rsocket + .requestStream('request.stream') + .pipe(takeUntil(this.componentDestroyed$), debounceTime(100), distinctUntilChanged()) + .subscribe(res => this.dataSet.update(value => [...value, res])); + } + + ngOnDestroy(): void { + this.componentDestroyed$.next(); + this.componentDestroyed$.complete(); } } diff --git a/ng-ui/projects/web/src/core/auth.service.ts b/ng-ui/projects/web/src/core/auth.service.ts index f635727e..5e3933fe 100644 --- a/ng-ui/projects/web/src/core/auth.service.ts +++ b/ng-ui/projects/web/src/core/auth.service.ts @@ -3,7 +3,6 @@ import { inject, Injectable, signal } from '@angular/core'; import { CanActivateChildFn, CanActivateFn, CanMatchFn, Router } from '@angular/router'; import dayjs from 'dayjs'; import { SessionStorageService } from '../shared/session-storage.service'; -import { RSocketCLientService } from './rsocket.service'; export interface Authentication { token: string; @@ -23,10 +22,9 @@ export const authGuard: CanMatchFn | CanActivateFn | CanActivateChildFn = () => @Injectable({ providedIn: 'root' }) export class AuthService { - private _socket = inject(RSocketCLientService); + private _storage = inject(SessionStorageService); readonly loginUrl = '/auth/login'; - private _storage: SessionStorageService = inject(SessionStorageService); private readonly authenticationKey = 'authentication'; private isLoggedIn = signal(false); private authentication = signal({} as Authentication); @@ -74,7 +72,6 @@ export class AuthService { this.isLoggedIn.set(true); this.authentication.set(authentication); this._storage.set(this.authenticationKey, JSON.stringify(authentication)); - this._socket.connect(authentication.token); } logout(): void { diff --git a/ng-ui/projects/web/src/core/components/login/login.service.ts b/ng-ui/projects/web/src/core/components/login/login.service.ts index 97a2b8e2..7a2abede 100644 --- a/ng-ui/projects/web/src/core/components/login/login.service.ts +++ b/ng-ui/projects/web/src/core/components/login/login.service.ts @@ -4,6 +4,7 @@ import { Observable, tap } from 'rxjs'; import { Authentication, AuthService } from '../../auth.service'; import { BrowserStorageService } from '../../../shared/browser-storage.service'; import dayjs from 'dayjs'; +import { RSocketCLientService } from '../../rsocket.service'; export interface Credentials { password: string | null | undefined; @@ -15,8 +16,9 @@ export interface Credentials { }) export class LoginService { _auth = inject(AuthService); - _http = inject(HttpClient); - _storage = inject(BrowserStorageService); + private _http = inject(HttpClient); + private _storage = inject(BrowserStorageService); + private _socket = inject(RSocketCLientService); private readonly storageKey = 'credentials'; private credentials = signal({} as Credentials); @@ -26,6 +28,7 @@ export class LoginService { if (authentication) { authentication.lastAccessTime = dayjs().unix(); this._auth.login(authentication); + this._socket.connect(authentication.token); return authentication; } return null; @@ -35,9 +38,12 @@ export class LoginService { const headers: HttpHeaders = new HttpHeaders({ authorization: 'Basic ' + btoa(credentials.username + ':' + credentials.password), }); - return this._http - .get('/oauth2/token', { headers: headers }) - .pipe(tap(authentication => this._auth.login(authentication))); + return this._http.get('/oauth2/token', { headers: headers }).pipe( + tap(authentication => { + this._auth.login(authentication); + this._socket.connect(authentication.token); + }) + ); } setRememberMe(credentials: Credentials) { diff --git a/ng-ui/projects/web/src/core/http.Interceptor.ts b/ng-ui/projects/web/src/core/http.Interceptor.ts index 8711157f..6d5cce02 100644 --- a/ng-ui/projects/web/src/core/http.Interceptor.ts +++ b/ng-ui/projects/web/src/core/http.Interceptor.ts @@ -54,8 +54,10 @@ export function authTokenInterceptor(req: HttpRequest, next: HttpHandle return next(authReq).pipe( catchError(errorResponse => { - _auth.logout(); - _route.navigate([_auth.loginUrl]).then(); + if (errorResponse.status === 401) { + _auth.logout(); + _route.navigate([_auth.loginUrl]).then(); + } return throwError(() => errorResponse); }) ); diff --git a/ng-ui/projects/web/src/core/rsocket.service.ts b/ng-ui/projects/web/src/core/rsocket.service.ts index 1a4e87d7..91ad38e7 100644 --- a/ng-ui/projects/web/src/core/rsocket.service.ts +++ b/ng-ui/projects/web/src/core/rsocket.service.ts @@ -10,7 +10,6 @@ import { MESSAGE_RSOCKET_ROUTING, RSocketClient, } from 'rsocket-core'; -import { Single } from 'rsocket-flowable'; import { ReactiveSocket } from 'rsocket-types'; import RSocketWebSocketClient from 'rsocket-websocket-client'; import { Observable } from 'rxjs'; @@ -35,11 +34,11 @@ export class RSocketCLientService { BufferEncoders ); - private socketClient: Single> | null = null; + private socketClient: ReactiveSocket | null = null; private token: string | null = null; connect(token: string) { - const socketClient = new RSocketClient({ + const client = new RSocketClient({ setup: { // ms btw sending keepalive to server keepAlive: 6000, @@ -58,18 +57,30 @@ export class RSocketCLientService { transport: this.transport, }); this.token = token; - this.socketClient = socketClient.connect(); + client.connect().subscribe({ + onComplete: socket => (this.socketClient = socket), + onError: error => console.error(error), + }); } + connectionStatus() { if (this.socketClient === null) { throw new Error('socketClient is null'); } - this.socketClient.then(socket => { - socket.connectionStatus().subscribe(event => console.log(`connectionStatus :${event.kind}`)); + this.socketClient.connectionStatus().subscribe(event => { + console.log(`connectionStatus :${event.kind}`); + if (event.kind !== 'CONNECTED') { + if (this.token === null) { + console.error('token 不能为空!,请先调用 connect 方法设置!'); + return; + } + this.connect(this.token); + } }); } requestStream(route?: string): Observable { + console.log('requestStream'); route = route || 'request.stream'; const observable = new Observable(subscriber => { if (this.socketClient === null) { @@ -81,39 +92,32 @@ export class RSocketCLientService { return; } const token = this.token; - this.socketClient.subscribe({ - onComplete: socket => - socket - .requestStream({ - data: Buffer.from(token), - metadata: encodeCompositeMetadata([[MESSAGE_RSOCKET_ROUTING, encodeRoute(route)]]), - }) - .subscribe({ - onComplete: () => { - console.log('complete'); - subscriber.complete(); - }, - onError: error => { - console.log('Connection has been closed due to:: ' + error); - subscriber.error(error); - }, - onNext: value => { - const jsonStr = value.data?.toString(); - if (jsonStr !== undefined && jsonStr !== null) { - console.log('onNext: %s,%s', value.data, value.metadata); - subscriber.next(JSON.parse(jsonStr)); - } - }, - onSubscribe: subscription => { - console.log('onNext: %s,%s', subscription); - subscription.request(2147483647); - }, - }), - onError: error => { - console.log('error:', error); - subscriber.error(error); - }, - }); + this.socketClient + .requestStream({ + data: Buffer.from(token), + metadata: encodeCompositeMetadata([[MESSAGE_RSOCKET_ROUTING, encodeRoute(route)]]), + }) + .subscribe({ + onComplete: () => { + console.log('complete'); + subscriber.complete(); + }, + onError: error => { + console.log('Connection has been closed due to:: ' + error); + subscriber.error(error); + }, + onNext: value => { + const jsonStr = value.data?.toString(); + if (jsonStr !== undefined && jsonStr !== null) { + console.log('onNext: %s,%s', value.data, value.metadata); + subscriber.next(JSON.parse(jsonStr)); + } + }, + onSubscribe: subscription => { + console.log('onNext: %s,%s', subscription); + subscription.request(2147483647); + }, + }); }); return observable; }