lgsso-sdk 1.2.6 → 1.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,8 +5,8 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  /*
6
6
  * @Author: Robin LEI
7
7
  * @Date: 2025-08-21 15:09:15
8
- * @LastEditTime: 2025-08-21 15:22:11
9
- * @FilePath: \lg-wms-admind:\业务代码\中联钢信\五服一管\lg-ssosdk\src\utils.js
8
+ * @LastEditTime: 2026-01-23 11:28:26
9
+ * @FilePath: \lims-frontd:\业务代码\中联钢信\五服一管\lg-ssosdk\src\utils.js
10
10
  */
11
11
  /**
12
12
  * 检查是否在浏览器环境
@@ -42,38 +42,58 @@ function getQueryParam(name, url) {
42
42
  }
43
43
 
44
44
  /**
45
- * 移除URL中的指定参数
46
- * @param {string} name - 参数名
45
+ * 移除URL中的指定参数(支持单个或多个)
46
+ * @param {string|string[]} names - 要删除的参数名(单个字符串或字符串数组)
47
47
  */
48
- function removeQueryParam(name) {
48
+ function removeQueryParam(names) {
49
49
  if (!isBrowser()) return;
50
50
 
51
+ // 统一转为数组,兼容单个参数的调用方式
52
+ const paramNames = Array.isArray(names) ? names : [names];
53
+ if (paramNames.length === 0) return; // 无参数需删除时直接返回
54
+
51
55
  const url = new URL(window.location.href);
52
- let params, newUrl;
56
+ let newUrl;
53
57
 
54
58
  // 处理hash模式(参数在#之后)
55
59
  if (url.hash.includes('?')) {
56
60
  const [hashPath, hashQuery] = url.hash.split('?');
57
- params = new URLSearchParams(hashQuery);
61
+ const params = new URLSearchParams(hashQuery);
62
+
63
+ // 批量删除参数
64
+ paramNames.forEach(name => {
65
+ if (params.has(name)) {
66
+ params.delete(name);
67
+ }
68
+ });
58
69
 
59
- if (params.has(name)) {
60
- params.delete(name);
61
- const newHash = params.toString() ? `${hashPath}?${params.toString()}` : hashPath;
70
+ // 重构hash部分
71
+ const newHash = params.toString() ? `${hashPath}?${params.toString()}` : hashPath;
72
+ if (newHash !== url.hash) { // 只有hash变化时才更新URL
62
73
  url.hash = newHash;
63
74
  newUrl = url.toString();
64
75
  }
65
76
  }
66
77
  // 处理history模式(参数在?之后)
67
78
  else {
68
- params = new URLSearchParams(url.search);
69
- if (params.has(name)) {
70
- params.delete(name);
79
+ const params = new URLSearchParams(url.search);
80
+ let hasChanged = false;
81
+
82
+ // 批量删除参数
83
+ paramNames.forEach(name => {
84
+ if (params.has(name)) {
85
+ params.delete(name);
86
+ hasChanged = true;
87
+ }
88
+ });
89
+
90
+ // 只有参数变化时才更新URL
91
+ if (hasChanged) {
71
92
  url.search = params.toString();
72
93
  newUrl = url.toString();
73
94
  }
74
95
  }
75
-
76
- // 更新URL
96
+ // 更新URL(仅当URL有变化时)
77
97
  if (newUrl && newUrl !== window.location.href) {
78
98
  window.location.replace(newUrl);
79
99
  }
@@ -96,6 +116,7 @@ function getCurrentUrlWithParams() {
96
116
  */
97
117
  function mergeConfigs(defaults, options) {
98
118
  if (!options) return { ...defaults };
119
+
99
120
  const merged = { ...defaults };
100
121
  for (const key in options) {
101
122
  if (options.hasOwnProperty(key)) {
@@ -4040,6 +4061,66 @@ async function request(url, {
4040
4061
  }
4041
4062
  }
4042
4063
 
4064
+ // ===== Cookie操作工具函数 =====
4065
+ /**
4066
+ * 获取指定名称的Cookie值
4067
+ * @param {string} name Cookie名称
4068
+ * @returns {string|null} Cookie值
4069
+ */
4070
+ function getCookie(name) {
4071
+ if (!isBrowser()) return null;
4072
+ const match = document.cookie.match(new RegExp(`(^| )${name}=([^;]+)`));
4073
+ return match ? decodeURIComponent(match[2]) : null;
4074
+ }
4075
+
4076
+ /**
4077
+ * 设置Cookie
4078
+ * @param {string} name Cookie名称
4079
+ * @param {string} value Cookie值
4080
+ * @param {Object} options 配置(过期时间、路径等)
4081
+ */
4082
+ function setCookie(name, value, options = {}) {
4083
+ if (!isBrowser()) return;
4084
+ let cookieStr = `${name}=${encodeURIComponent(value)}`;
4085
+ cookieStr += `; path=${options.path || '/'}`; // 默认根路径
4086
+ if (options.expires) {
4087
+ const expires = typeof options.expires === 'number'
4088
+ ? new Date(Date.now() + options.expires * 86400000)
4089
+ : options.expires;
4090
+ cookieStr += `; expires=${expires.toUTCString()}`;
4091
+ }
4092
+ document.cookie = cookieStr;
4093
+ }
4094
+
4095
+ /**
4096
+ * 删除指定名称的Cookie
4097
+ * @param {string} name Cookie名称
4098
+ */
4099
+ function removeCookie(name) {
4100
+ if (!isBrowser()) return;
4101
+ setCookie(name, '', { expires: -1 });
4102
+ }
4103
+
4104
+ /**
4105
+ * 给重定向地址拼接platType参数
4106
+ * @param {string} redirectUrl 原始重定向地址
4107
+ * @param {string} platType platType值
4108
+ * @param {string} platTypeKey 参数名(默认platType)
4109
+ * @returns {string} 拼接后的重定向地址
4110
+ */
4111
+ function addPlatTypeToRedirectUrl(redirectUrl, platType, platTypeKey = 'platType') {
4112
+ if (!redirectUrl || !platType) return redirectUrl;
4113
+ try {
4114
+ const url = new URL(redirectUrl);
4115
+ url.searchParams.set(platTypeKey, platType);
4116
+ return url.toString();
4117
+ } catch (e) {
4118
+ // 兼容非标准URL的情况(比如相对路径)
4119
+ const separator = redirectUrl.includes('?') ? '&' : '?';
4120
+ return `${redirectUrl}${separator}${platTypeKey}=${platType}`;
4121
+ }
4122
+ }
4123
+
4043
4124
  // 默认配置
4044
4125
  const DEFAULT_CONFIG = {
4045
4126
  accessCodeKey: 'accessCode',
@@ -4050,13 +4131,14 @@ const DEFAULT_CONFIG = {
4050
4131
  refreshCodeApi: '',
4051
4132
  logoutApi: '',
4052
4133
  logOutUrl: '',
4053
- storage: localStorage, // 可替换为sessionStorage
4134
+ storage: localStorage,
4054
4135
  oldPwdKey: 'oldPwd',
4055
4136
  newPwdKey: 'newPwd',
4056
4137
  changePasswordApi: '',
4057
4138
  sendCaptchaCodeApi: '',
4058
4139
  typeKey: 'type',
4059
- codeKey: 'code'
4140
+ codeKey: 'code',
4141
+ platTypeKey: 'platType' // platType参数名配置
4060
4142
  };
4061
4143
 
4062
4144
  let config = null;
@@ -4079,46 +4161,35 @@ function validateConfig(options) {
4079
4161
  }
4080
4162
 
4081
4163
  /**
4082
- * 判断是否是iOS移动端(精准适配iPad Air/所有iPad机型 + 全版本iPadOS)
4164
+ * 判断是否是iOS移动端
4083
4165
  * @returns {boolean} 是否为iOS环境
4084
4166
  */
4085
4167
  function isIOS() {
4086
- // 非浏览器环境直接返回false(如需保留请取消注释)
4087
- // if (!isBrowser()) return false;
4168
+ if (!isBrowser()) return false;
4088
4169
 
4089
4170
  const userAgent = navigator.userAgent.toLowerCase();
4090
- const platform = navigator.platform.toLowerCase(); // 统一转小写,避免大小写兼容问题
4171
+ const platform = navigator.platform.toLowerCase();
4091
4172
  const maxTouchPoints = navigator.maxTouchPoints || 0;
4092
- const screenRatio = screen.width / screen.height; // 屏幕宽高比(iPad核心特征:4:3左右)
4173
+ const screenRatio = screen.width / screen.height;
4093
4174
 
4094
- // ========== 核心检测规则 ==========
4095
- // 1. 基础规则:iPhone/iPod 直接命中(无兼容问题)
4096
4175
  const isIphoneIpod = /iphone|ipod/.test(userAgent) && !window.MSStream;
4097
-
4098
- // 2. iPad 专属检测(覆盖所有iPad机型,含iPad Air)
4099
4176
  const isIpad = (
4100
- // 场景1:老版本iPadOS/原生标识(platform含ipad)
4101
4177
  platform.includes('ipad') ||
4102
- // 场景2:iPadOS 13+ 伪装Mac(UA含macintosh + 触摸+ 非Mac平台)
4103
4178
  (
4104
- userAgent.includes('macintosh') &&
4105
- maxTouchPoints > 0 && // iPad Air 触摸点≥5,Mac几乎为0
4106
- !platform.includes('mac') && // 排除真Mac
4179
+ userAgent.includes('macintosh') &&
4180
+ maxTouchPoints > 0 &&
4181
+ !platform.includes('mac') &&
4107
4182
  !window.MSStream
4108
4183
  ) ||
4109
- // 场景3:新版本iPadOS(UA直接含ipados,如iPad Air搭载的iPadOS 15+)
4110
4184
  userAgent.includes('ipados') ||
4111
- // 场景4:极端场景(第三方浏览器如Chrome for iPad Air)
4112
4185
  (
4113
- maxTouchPoints >= 5 && // iPad Air 固定支持5点触摸
4114
- !platform.includes('android') && // 排除安卓平板
4115
- (screenRatio > 0.7 && screenRatio < 1.4) // iPad宽高比≈0.75(4:3),Mac多为1.78(16:9)
4186
+ maxTouchPoints >= 5 &&
4187
+ !platform.includes('android') &&
4188
+ (screenRatio > 0.7 && screenRatio < 1.4)
4116
4189
  )
4117
4190
  );
4118
4191
 
4119
- // ========== 最终判定 ==========
4120
- const result = isIphoneIpod || isIpad;
4121
- return result;
4192
+ return isIphoneIpod || isIpad;
4122
4193
  }
4123
4194
 
4124
4195
  /**
@@ -4138,9 +4209,17 @@ function createSSO() {
4138
4209
  config = mergeConfigs(DEFAULT_CONFIG, options);
4139
4210
  validateConfig(config);
4140
4211
 
4212
+ // 初始化时检测URL中的platType并存入Cookie
4213
+ if (isBrowser()) {
4214
+ const platTypeFromUrl = getQueryParam(config.platTypeKey);
4215
+ if (platTypeFromUrl) {
4216
+ setCookie(config.platTypeKey, platTypeFromUrl);
4217
+ // 可选:移除URL中的platType(避免重复显示)
4218
+ }
4219
+ }
4220
+
4141
4221
  const accessCode = getQueryParam(config.accessCodeKey);
4142
4222
 
4143
- // 验证必要的API配置
4144
4223
  if (!config.tokenApi) {
4145
4224
  return { code: -100, msg: '缺少tokenApi配置', success: false };
4146
4225
  }
@@ -4159,14 +4238,25 @@ function createSSO() {
4159
4238
 
4160
4239
  if (result.code === 0 && result.data) {
4161
4240
  config.storage.setItem(config.tokenKey, result.data);
4162
- removeQueryParam(config.accessCodeKey);
4241
+ removeQueryParam([config.accessCodeKey,config.platTypeKey]);
4163
4242
  }
4164
4243
  return result;
4165
4244
  }
4166
4245
  // 如果没有token,跳转到登录页
4167
4246
  else if (!this.getToken()) {
4168
4247
  if (isBrowser() && config.logOutUrl) {
4169
- window.location.href = `${config.logOutUrl}?redirect_uri=${encodeURIComponent(getCurrentUrlWithParams())}`;
4248
+ // ===== 核心修正:platType拼到redirect_uri里 =====
4249
+ const platTypeFromCookie = getCookie(config.platTypeKey);
4250
+ // 1. 获取原始重定向地址
4251
+ let redirectUri = getCurrentUrlWithParams();
4252
+ // 2. 给重定向地址加platType参数
4253
+ if (platTypeFromCookie) {
4254
+ redirectUri = addPlatTypeToRedirectUrl(redirectUri, platTypeFromCookie, config.platTypeKey);
4255
+ }
4256
+ // 3. 构建登录页URL(仅带redirect_uri参数)
4257
+ let loginUrl = new URL(config.logOutUrl);
4258
+ loginUrl.searchParams.set('redirect_uri', encodeURIComponent(redirectUri));
4259
+ window.location.href = loginUrl.toString();
4170
4260
  }
4171
4261
  }
4172
4262
 
@@ -4198,33 +4288,21 @@ function createSSO() {
4198
4288
  * @returns {Promise<Object>} 接口返回结果
4199
4289
  */
4200
4290
  async logout() {
4201
- // 1. 前置校验:初始化状态
4202
4291
  if (!config) {
4203
4292
  return { code: -101, msg: '请先调用init方法初始化', success: false };
4204
4293
  }
4205
4294
 
4206
- // 2. 工具函数:统一构建登录跳转URL(确保完整编码当前URL的所有参数/hash)
4207
- const buildLoginUrl = () => {
4208
- if (!config.logOutUrl || !isBrowser()) return '';
4209
- // 关键:获取当前完整URL(含query、hash)并完整编码,避免参数丢失
4210
- const currentFullUrl = window.location.href;
4211
- const encodedRedirectUri = encodeURIComponent(currentFullUrl);
4212
- return `${config.logOutUrl}?redirect_uri=${encodedRedirectUri}`;
4213
- };
4214
-
4215
- // 3. 校验logoutApi配置(仅接口调用时需要,跳转登录页不受此影响)
4216
- if (!config.logOutApi) {
4217
- // 无logoutApi时仍清除token并跳转登录页,保证基础退出逻辑
4218
- this.removeToken();
4219
- const loginUrl = buildLoginUrl();
4220
- if (loginUrl) window.location.href = loginUrl;
4295
+ if (!config.logoutApi) {
4221
4296
  return { code: -102, msg: '未配置logoutApi', success: false };
4222
4297
  }
4223
4298
 
4299
+ // 获取并删除Cookie中的platType
4300
+ const platType = getCookie(config.platTypeKey);
4301
+ removeCookie(config.platTypeKey);
4302
+
4224
4303
  const token = this.getToken();
4225
4304
  if (token) {
4226
4305
  try {
4227
- // 调用退出接口
4228
4306
  const result = await request(
4229
4307
  config.logoutApi,
4230
4308
  {
@@ -4233,37 +4311,48 @@ function createSSO() {
4233
4311
  timeout: config.timeout
4234
4312
  }
4235
4313
  );
4236
- // 无论接口返回结果如何,都清除token
4237
4314
  this.removeToken();
4238
4315
 
4239
- // 跳转登录页(携带完整的当前URL)
4240
- const loginUrl = buildLoginUrl();
4241
- if (loginUrl) window.location.href = loginUrl;
4316
+ if (isBrowser() && config.logOutUrl) {
4317
+ // ===== 核心修正:platType拼到redirect_uri里 =====
4318
+ // 1. 获取原始重定向地址
4319
+ let redirectUri = getCurrentUrlWithParams();
4320
+ // 2. 给重定向地址加platType参数
4321
+ if (platType) {
4322
+ redirectUri = addPlatTypeToRedirectUrl(redirectUri, platType, config.platTypeKey);
4323
+ }
4324
+ // 3. 构建登录页URL
4325
+ let logoutUrl = new URL(config.logOutUrl);
4326
+ logoutUrl.searchParams.set('redirect_uri', encodeURIComponent(redirectUri));
4327
+ window.location.href = logoutUrl.toString();
4328
+ }
4242
4329
  return result;
4243
4330
  } catch (error) {
4244
- // 接口调用失败,仍清除token并跳转登录页
4245
- this.removeToken();
4246
- const loginUrl = buildLoginUrl();
4247
- if (loginUrl) window.location.href = loginUrl;
4248
4331
  return { code: -103, msg: `退出失败: ${error.message}`, success: false };
4249
4332
  }
4250
4333
  } else {
4251
- // 无token时直接清除(兜底)并跳转登录页
4252
4334
  this.removeToken();
4253
- const loginUrl = buildLoginUrl();
4254
- if (loginUrl) window.location.href = loginUrl;
4335
+ if (isBrowser() && config.logOutUrl) {
4336
+ // ===== 核心修正:platType拼到redirect_uri里 =====
4337
+ let redirectUri = getCurrentUrlWithParams();
4338
+ if (platType) {
4339
+ redirectUri = addPlatTypeToRedirectUrl(redirectUri, platType, config.platTypeKey);
4340
+ }
4341
+ let logoutUrl = new URL(config.logOutUrl);
4342
+ logoutUrl.searchParams.set('redirect_uri', encodeURIComponent(redirectUri));
4343
+ window.location.href = logoutUrl.toString();
4344
+ }
4255
4345
  return { code: 0, msg: '已成功清除token', success: true };
4256
4346
  }
4257
4347
  },
4258
4348
 
4259
4349
  /**
4260
4350
  * 用token换取新accessCode并跳转到指定URL
4261
- * @param {string} redirectUrl - 目标跳转地址(支持带query/hash参数)
4351
+ * @param {string} redirectUrl - 目标跳转地址
4262
4352
  * @param {string} target - 当前页面:_self、新页面打开:_blank,默认当前页_self
4263
4353
  * @returns {Promise<Object>} 接口返回结果
4264
4354
  */
4265
4355
  async toUrl(redirectUrl, target = '_self') {
4266
- // 1. 前置校验:初始化状态、参数合法性
4267
4356
  if (!config) {
4268
4357
  return { code: -101, msg: '请先调用init方法初始化', success: false };
4269
4358
  }
@@ -4272,45 +4361,49 @@ function createSSO() {
4272
4361
  return { code: -104, msg: '请提供跳转地址', success: false };
4273
4362
  }
4274
4363
 
4275
- // ========== 新增:获取当前页面的platType参数 ==========
4276
- const currentPlatType = isBrowser() ? getQueryParam('platType') : '';
4277
-
4278
- // ========== 保留:platType=screen强制_self逻辑 ==========
4279
- const isPlatTypeScreen = currentPlatType === 'screen';
4280
-
4281
- // 2. 处理target参数:platType=screen > iOS > 传入的target
4282
- const finalTarget = isPlatTypeScreen
4283
- ? '_self' // platType=screen时强制_self
4284
- : (isIOS() ? '_self' : target); // 否则沿用原iOS判断逻辑
4285
-
4286
- if (!['_self', '_blank'].includes(finalTarget)) {
4287
- return { code: -108, msg: 'target参数必须是"_self"或"_blank"', success: false };
4364
+ // iOS强制_self
4365
+ if (isIOS()) {
4366
+ target = '_self';
4288
4367
  }
4289
4368
 
4290
- // 3. 工具函数:统一构建登录跳转URL(避免重复代码,确保参数完整编码)
4291
- const buildLoginUrl = (redirectUrl) => {
4292
- if (!config.logOutUrl) return '';
4293
- // 关键:encodeURIComponent 会完整编码redirectUrl的所有部分(query/hash),避免参数丢失
4294
- const encodedRedirectUri = encodeURIComponent(redirectUrl);
4295
- return `${config.logOutUrl}?redirect_uri=${encodedRedirectUri}`;
4296
- };
4369
+ // platType=screen时强制_self
4370
+ const platType = getCookie(config.platTypeKey);
4371
+ if (platType === 'screen') {
4372
+ target = '_self';
4373
+ }
4374
+
4375
+ // 验证target参数
4376
+ if (!['_self', '_blank'].includes(target)) {
4377
+ return { code: -108, msg: 'target参数必须是"_self"或"_blank"', success: false };
4378
+ }
4297
4379
 
4298
- // 4. 校验refreshCodeApi配置
4299
4380
  if (!config.refreshCodeApi) {
4300
4381
  return { code: -105, msg: '未配置refreshCodeApi', success: false };
4301
4382
  }
4302
4383
 
4303
- // 5. 获取token,无token则直接跳登录页
4304
4384
  const token = this.getToken();
4305
4385
  if (!token) {
4306
4386
  if (isBrowser() && config.logOutUrl) {
4307
- const loginUrl = buildLoginUrl(redirectUrl);
4308
- finalTarget === '_blank' ? window.open(loginUrl, '_blank') : window.location.href = loginUrl;
4387
+ // ===== 核心修正:platType拼到redirect_uri里 =====
4388
+ // 1. 给目标跳转地址加platType
4389
+ let newRedirectUrl = redirectUrl;
4390
+ if (platType) {
4391
+ newRedirectUrl = addPlatTypeToRedirectUrl(newRedirectUrl, platType, config.platTypeKey);
4392
+ }
4393
+ // 2. 构建登录页URL
4394
+ let loginUrl = new URL(config.logOutUrl);
4395
+ loginUrl.searchParams.set('redirect_uri', encodeURIComponent(newRedirectUrl));
4396
+ const loginUrlStr = loginUrl.toString();
4397
+
4398
+ if (target === '_blank') {
4399
+ window.open(loginUrlStr, '_blank');
4400
+ } else {
4401
+ window.location.href = loginUrlStr;
4402
+ }
4309
4403
  }
4310
4404
  return { code: -106, msg: '未找到有效token', success: false };
4311
4405
  }
4312
4406
 
4313
- // 6. 有token则尝试换取accessCode并跳转
4314
4407
  try {
4315
4408
  const result = await request(
4316
4409
  config.refreshCodeApi,
@@ -4322,31 +4415,48 @@ function createSSO() {
4322
4415
  );
4323
4416
 
4324
4417
  if (result.code === 0 && result.data && isBrowser()) {
4325
- // ========== 核心优化:拼接platType到目标URL ==========
4418
+ // toUrl跳转目标地址时,仅携带accessCode,不携带platType
4326
4419
  const url = new URL(redirectUrl);
4327
- // 1. 如果当前页面有platType,拼接到目标URL(覆盖原有platType)
4328
- if (currentPlatType) {
4329
- url.searchParams.set('platType', currentPlatType);
4330
- }
4331
- // 2. 拼接accessCode(保留原有逻辑)
4332
4420
  url.searchParams.set(config.accessCodeKey, result.data);
4333
4421
  const targetUrl = url.toString();
4334
4422
 
4335
- finalTarget === '_blank' ? window.open(targetUrl, '_blank') : window.location.href = targetUrl;
4423
+ if (target === '_blank') {
4424
+ window.open(targetUrl, '_blank');
4425
+ } else {
4426
+ window.location.href = targetUrl;
4427
+ }
4336
4428
  } else {
4337
- // 接口返回失败,跳登录页(复用统一的登录URL构建逻辑)
4338
- if (isBrowser() && config.logOutUrl) {
4339
- const loginUrl = buildLoginUrl(redirectUrl);
4340
- finalTarget === '_blank' ? window.open(loginUrl, '_blank') : window.location.href = loginUrl;
4429
+ // ===== 核心修正:platType拼到redirect_uri里 =====
4430
+ let newRedirectUrl = redirectUrl;
4431
+ if (platType) {
4432
+ newRedirectUrl = addPlatTypeToRedirectUrl(newRedirectUrl, platType, config.platTypeKey);
4433
+ }
4434
+ let loginUrl = new URL(config.logOutUrl);
4435
+ loginUrl.searchParams.set('redirect_uri', encodeURIComponent(newRedirectUrl));
4436
+ const loginUrlStr = loginUrl.toString();
4437
+
4438
+ if (target === '_blank') {
4439
+ window.open(loginUrlStr, '_blank');
4440
+ } else {
4441
+ window.location.href = loginUrlStr;
4341
4442
  }
4342
4443
  }
4343
4444
 
4344
4445
  return result;
4345
4446
  } catch (error) {
4346
- // 接口异常,跳登录页(复用统一的登录URL构建逻辑)
4347
- if (isBrowser() && config.logOutUrl) {
4348
- const loginUrl = buildLoginUrl(redirectUrl);
4349
- finalTarget === '_blank' ? window.open(loginUrl, '_blank') : window.location.href = loginUrl;
4447
+ // ===== 核心修正:platType拼到redirect_uri里 =====
4448
+ let newRedirectUrl = redirectUrl;
4449
+ if (platType) {
4450
+ newRedirectUrl = addPlatTypeToRedirectUrl(newRedirectUrl, platType, config.platTypeKey);
4451
+ }
4452
+ let loginUrl = new URL(config.logOutUrl);
4453
+ loginUrl.searchParams.set('redirect_uri', encodeURIComponent(newRedirectUrl));
4454
+ const loginUrlStr = loginUrl.toString();
4455
+
4456
+ if (target === '_blank') {
4457
+ window.open(loginUrlStr, '_blank');
4458
+ } else {
4459
+ window.location.href = loginUrlStr;
4350
4460
  }
4351
4461
  return { code: -107, msg: `跳转失败: ${error.message}`, success: false };
4352
4462
  }
@@ -4385,7 +4495,7 @@ function createSSO() {
4385
4495
  * @returns {Object|null} 当前配置
4386
4496
  */
4387
4497
  getConfig() {
4388
- return { ...config }; // 返回配置的副本,防止外部修改
4498
+ return { ...config };
4389
4499
  },
4390
4500
 
4391
4501
  async changePassword(fromData = {}) {
@@ -4414,7 +4524,6 @@ function createSSO() {
4414
4524
 
4415
4525
  async getPhoneCode() {
4416
4526
  const token = this.getToken();
4417
- // 修复笔误:sendCaptchaCode → sendCaptchaCodeApi
4418
4527
  return request(
4419
4528
  config.sendCaptchaCodeApi,
4420
4529
  {