From 95abb0deedf709d0db5c9f999bfb0615d8965aa0 Mon Sep 17 00:00:00 2001 From: jiweitao1986 Date: Wed, 20 Aug 2025 15:50:10 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=AC=AC2=E6=AC=A1?= =?UTF-8?q?=E6=89=93=E5=BC=80=E5=BC=B9=E7=AA=97=E6=97=B6=E4=BC=9A=E8=AF=9D?= =?UTF-8?q?=E6=B8=85=E7=A9=BA=E4=B8=8D=E5=BD=BB=E5=BA=95=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/bef/lib/framework-session.service.ts | 45 ++++++++++++++++++- .../bef/lib/session/bef_session_manager.ts | 42 ++++++++++++----- .../bef/lib/session/bef_session_service.ts | 1 - ...bef-separated-session-handling-strategy.ts | 23 +++++++++- .../handling-strategy-factory.ts | 3 ++ .../handling-strategies/handling-strategy.ts | 4 +- .../session-storage-strategy.ts | 2 +- .../renderer/src/composition/use-session.ts | 9 +++- 8 files changed, 110 insertions(+), 19 deletions(-) diff --git a/packages/bef/lib/framework-session.service.ts b/packages/bef/lib/framework-session.service.ts index 35632ad1bbf..c80a0cef1f1 100644 --- a/packages/bef/lib/framework-session.service.ts +++ b/packages/bef/lib/framework-session.service.ts @@ -2,8 +2,21 @@ * 框架Session服务 */ class FrameworkSessionService { + + /** + * 框架服务 + * @summary + * 等同于frameworkService的rtf属性 + */ private rtfService: any; + + /** + * 框架服务 + * @summary + * 等同于框架向Window注册的gspframeworkService对象 + */ private frameworkService: any = null; + /** * 构造函数 */ @@ -14,44 +27,68 @@ class FrameworkSessionService { /** * 获取当前会话id */ - getCurrentSessionId(): string { + public getCurrentSessionId(): string { + // TODO: 存在页签未激活获取token错误的问题 return this.formToken || ''; } + public get tabId() { return this.params && this.params['tabId'] || null; } + /** * 获取formToken */ public get formToken() { return this.params && this.params['cvft'] || null; } + + /** + * 从URL中获取查询参数 + */ public get params() { + // if (this.rtfService && this.rtfService.hasOwnProperty('session') && typeof this.rtfService['session']['getCommonVariable'] === 'function') { // return this.rtfService['session']['getCommonVariable'](); // } // return null; - // 从url中获取 + const hash = window.location.hash; const params = this.parseQueryString(hash); return params; } + + /** + * 获取框架服务 + */ private getRuntimeFrameworkService() { const frameworkService = this.gspFrameworkService; return frameworkService && frameworkService.rtf || {}; } + + /** + * 获取框架服务 + * @summary + * 从Window上获取框架的gspframeworkService对象 + */ private get gspFrameworkService() { if (this.frameworkService) { return this.frameworkService; } + let env: Window = window; while (!env['gspframeworkService'] && env !== window.top && this.isSameOrigin(env)) { env = env.parent; } + this.frameworkService = env['gspframeworkService']; return this.frameworkService; } + + /** + * 当前Window是否和表单是同源 + */ private isSameOrigin(environment: Window) { const host = window.location.host; try { @@ -64,6 +101,10 @@ class FrameworkSessionService { return false; } + + /** + * 将查询参数字符串转换成对象 + */ private parseQueryString(queryString: string): { [propName: string]: any } { if (!queryString) { return {}; diff --git a/packages/bef/lib/session/bef_session_manager.ts b/packages/bef/lib/session/bef_session_manager.ts index 14263a40a74..f36cc33932a 100644 --- a/packages/bef/lib/session/bef_session_manager.ts +++ b/packages/bef/lib/session/bef_session_manager.ts @@ -2,15 +2,35 @@ import { RuntimeContext } from '../types'; import { BefSessionService } from './bef_session_service'; export class BefSessionManager { - private static history: string[] = []; - public static getSessionId(moduleId: string, sessionService: BefSessionService, beBaseUri: string, runtimeContext?: RuntimeContext): Promise { - const key = `${moduleId}_${beBaseUri}`; - const createSessionIsInvoked = this.history.includes(key); - if (createSessionIsInvoked) { - return Promise.resolve(null); - } else { - this.history.push(key); - return sessionService.getBeSessionId(runtimeContext); - } + + /** + * 会话创建历史记录 + */ + private static history: string[] = []; + + /** + * 获取会话 + */ + public static getSessionId(moduleId: string, sessionService: BefSessionService, beBaseUri: string, runtimeContext?: RuntimeContext): Promise { + const key = `${moduleId}_${beBaseUri}`; + const createSessionIsInvoked = this.history.includes(key); + if (createSessionIsInvoked) { + return Promise.resolve(null); + } else { + this.history.push(key); + return sessionService.getBeSessionId(runtimeContext); + } + } + + /** + * 清理会话 + */ + public static clearSessionId(moduleId: string, sessionService: BefSessionService, beBaseUri: string, runtimeContext?: RuntimeContext) { + const key = `${moduleId}_${beBaseUri}`; + const keyIndex = this.history.indexOf(key); + if (keyIndex !== -1) { + this.history.splice(keyIndex, 1); } - } \ No newline at end of file + sessionService.clearBeSessionId(runtimeContext); + } +} \ No newline at end of file diff --git a/packages/bef/lib/session/bef_session_service.ts b/packages/bef/lib/session/bef_session_service.ts index 85eb16d4dd9..9b06e360a39 100644 --- a/packages/bef/lib/session/bef_session_service.ts +++ b/packages/bef/lib/session/bef_session_service.ts @@ -34,7 +34,6 @@ class BefSessionService { /** * 设置sessionId - * @param sessionId sessionId */ public setBeSessionId(sessionId: string, runtimeContext?: RuntimeContext) { this.handlingStrategy.setSessionId(sessionId, runtimeContext); diff --git a/packages/bef/lib/session/handling-strategies/bef-separated-session-handling-strategy.ts b/packages/bef/lib/session/handling-strategies/bef-separated-session-handling-strategy.ts index 42156ab0cd6..b6bf7cf3d9e 100644 --- a/packages/bef/lib/session/handling-strategies/bef-separated-session-handling-strategy.ts +++ b/packages/bef/lib/session/handling-strategies/bef-separated-session-handling-strategy.ts @@ -9,6 +9,7 @@ import { RuntimeContext } from '../../types'; * 隔离的BeSession处理策略 */ class BefSeparatedSessionHandlingStrategy extends SessionHandlingStrategy { + /** * 构造函数 */ @@ -24,6 +25,9 @@ class BefSeparatedSessionHandlingStrategy extends SessionHandlingStrategy { /** * 获取BeSessionId + * @summary + * 1、如果前端缓存存在:优先使用缓存中的BE会话; + * 2、如果缓存中的不存在:如果存在上次打开菜单时遗留的BE会话先关闭老BE会话,再创建新的BE会话 */ public getSessionId(runtimeContext?: RuntimeContext): Promise { const beSessionId = this.getSessionIdFromStorage(runtimeContext); @@ -35,6 +39,7 @@ class BefSeparatedSessionHandlingStrategy extends SessionHandlingStrategy { }); return sessionIdPromise; } + /** * 创建BeSessionId */ @@ -71,11 +76,14 @@ class BefSeparatedSessionHandlingStrategy extends SessionHandlingStrategy { requestConfig.headers = BefHttpUtil.appendCafRuntimeContext(requestConfig.headers, this.lastTimeUsedSessionId); requestConfig.headers = BefHttpUtil.appendCafRuntimeCommonVariable(requestConfig.headers, this.frameworkSessionId); - // 无论是否成功,统一置空cleardBeSessionId + // 无论关闭是否成功,不重复关闭 return this.httpClient.post(this.closeSessionUrl, null, requestConfig).then(() => { return true; + }).finally(() => { + this.lastTimeUsedSessionId = null; }); } + /** * 设置BeSessionId */ @@ -89,8 +97,13 @@ class BefSeparatedSessionHandlingStrategy extends SessionHandlingStrategy { */ public clearSessionId(runtimeContext?: RuntimeContext) { if (BefEnvUtil.isInFramework() === true) { + + // 菜单打开:清理该菜单相关的全部会话(风险:1、PC端不应该触发该逻辑,否则弹窗表单会有问题;2、PC端没有formToken参数恰好没有触发) + // TODO: 待优化 this.storageStrategy.removeItemsByScope(this.frameworkSessionId); } else { + + // 菜单外打开:1、先记录上次遗留的会话ID,以便对其进行关闭;2、移除上次的会话ID,以便重新创建 const sessionKey = this.getSessionStorageKey(runtimeContext); this.lastTimeUsedSessionId = this.getSessionIdFromStorage(runtimeContext); this.storageStrategy.removeItem(sessionKey); @@ -104,7 +117,10 @@ class BefSeparatedSessionHandlingStrategy extends SessionHandlingStrategy { const frmSessionId = this.getFrameworkSessionId(); const beSessionId = this.getSessionIdFromStorage(runtimeContext); + // 追加框架会话ID headers = BefHttpUtil.appendCafRuntimeCommonVariable(headers, frmSessionId); + + // 追加BE会话ID if (beSessionId) { headers = BefHttpUtil.appendCafRuntimeContext(headers, beSessionId); headers = BefHttpUtil.appendSessionId(headers, beSessionId); @@ -122,14 +138,19 @@ class BefSeparatedSessionHandlingStrategy extends SessionHandlingStrategy { * 获取某个Repository对应的BeSession的唯一key */ protected getSessionStorageKey(runtimeContext?: RuntimeContext): string { + + // 获取会话ID let sessionId: string = this.frameworkSessionId; if (runtimeContext) { sessionId = this.getFrameworkSessionId(); } + + // 获取标签页ID const tabId = runtimeContext && runtimeContext.tabId; if (tabId) { return `${sessionId}_${tabId}_${this.baseUrl}`; } + return `${sessionId}_${this.baseUrl}`; } } diff --git a/packages/bef/lib/session/handling-strategies/handling-strategy-factory.ts b/packages/bef/lib/session/handling-strategies/handling-strategy-factory.ts index e46a2ec8b23..4b4b684531c 100644 --- a/packages/bef/lib/session/handling-strategies/handling-strategy-factory.ts +++ b/packages/bef/lib/session/handling-strategies/handling-strategy-factory.ts @@ -9,6 +9,7 @@ import { BefUnifiedSessionHandlingStrategy } from './bef-unified-session-handlin * BeSession处理策略工厂 */ class BefSessionHandlingStrategyFactory { + /** * 创建BeSession处理策略 */ @@ -23,6 +24,8 @@ class BefSessionHandlingStrategyFactory { if (handlingStrategyName === 'UnifiedSession') { return new BefUnifiedSessionHandlingStrategy(storageStrategy, frmSessionService, httpClient, beBaseUrl, injector); } else { + + // 默认策略 return new BefSeparatedSessionHandlingStrategy(storageStrategy, frmSessionService, httpClient, beBaseUrl, injector); } } diff --git a/packages/bef/lib/session/handling-strategies/handling-strategy.ts b/packages/bef/lib/session/handling-strategies/handling-strategy.ts index 6a19181f559..3eea06cb945 100644 --- a/packages/bef/lib/session/handling-strategies/handling-strategy.ts +++ b/packages/bef/lib/session/handling-strategies/handling-strategy.ts @@ -40,7 +40,7 @@ abstract class SessionHandlingStrategy { /** * 上次使用的会话id */ - protected lastTimeUsedSessionId: string; + protected lastTimeUsedSessionId: string | null; /** * injector */ @@ -75,6 +75,8 @@ abstract class SessionHandlingStrategy { /** * 获取框架SessionId * TODO: 暂不支持runtimeContext + * @summary + * 获取框架的会话,即框架参数中的cvft的值 */ public getFrameworkSessionId() { return this.frameworkSessionId; diff --git a/packages/bef/lib/session/storage-strategies/session-storage-strategy.ts b/packages/bef/lib/session/storage-strategies/session-storage-strategy.ts index 965ec1d267b..01de5335a56 100644 --- a/packages/bef/lib/session/storage-strategies/session-storage-strategy.ts +++ b/packages/bef/lib/session/storage-strategies/session-storage-strategy.ts @@ -87,7 +87,7 @@ class SessionStorageStrategy implements StorageStrategy { /** * 设置全部BeSessions到SessionStorage */ - setAllBeSessions(beSessions: any): void { + private setAllBeSessions(beSessions: any): void { const beSessionsString = JSON.stringify(beSessions); window.sessionStorage.setItem(this.sessionStorageKey, beSessionsString); } diff --git a/packages/renderer/src/composition/use-session.ts b/packages/renderer/src/composition/use-session.ts index 022cef8aa50..ce7ed7af611 100644 --- a/packages/renderer/src/composition/use-session.ts +++ b/packages/renderer/src/composition/use-session.ts @@ -1,7 +1,7 @@ import { Entity, Injector } from "@farris/devkit-vue"; import { useModule } from "./use-module"; import { MODULE_CONFIG_ID_TOKEN } from "../tokens"; -import { BefRepository } from "@farris/bef-vue"; +import { BefRepository, BefSessionManager } from "@farris/bef-vue"; import { RuntimeFrameworkService } from "@farris/command-services-vue"; export function useSession(injector: Injector) { @@ -11,6 +11,8 @@ export function useSession(injector: Injector) { if (!repository) { return; } + + // 获取标签页ID const runtimeFrameworkService = injector.get(RuntimeFrameworkService); if (!runtimeFrameworkService) { return; @@ -20,5 +22,8 @@ export function useSession(injector: Injector) { if (tabId) { runtimeContext.tabId = tabId; } - repository.sessionService.clearBeSessionId(runtimeContext); + + // 清理会话 + const moduleId = module.getId(); + BefSessionManager.clearSessionId(moduleId, repository.sessionService,repository.apiProxy.baseUrl, runtimeContext); } -- Gitee