ai-coding
2026-08-02 aae194cd8fff6104176bdf33fc3dfdffa6c3b5c5
feat(#bugfix/env):根据域名动态读取sso相关配置

Co-Authored-By: 刘文鑫 <p-liuwx1@xiaopeng.com>
1个文件已添加
4个文件已修改
119 ■■■■■ 已修改文件
service.config.ts 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/service/http/index.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/auth.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/env-config.ts 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/socket.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service.config.ts
@@ -7,6 +7,6 @@
    // url: 'http://rt-api.deploy-test.xiaopeng.com',
  },
  production: {
    url: 'https://rt-admin.xiaopeng.com',
    url: '',
  },
}
src/service/http/index.ts
@@ -1,7 +1,8 @@
import { getServiceUrl } from '@/utils/env-config'
import { createAlovaInstance } from './alova'
export const request = createAlovaInstance({
  baseURL: __URL_MAP__.url.path,
  baseURL: getServiceUrl() || __URL_MAP__.url.path,
})
export const blankInstance = createAlovaInstance({
src/store/auth.ts
@@ -1,6 +1,7 @@
import { router } from '@/router'
import { fetchLoginEncrypted } from '@/service'
import { local } from '@/utils'
import { getSsoConfig } from '@/utils/env-config'
import { useRouteStore } from './router'
import { useTabStore } from './tab'
@@ -43,7 +44,7 @@
}
function getSsoLogoutRedirectUrl() {
  const { VITE_SSO_HOST, VITE_SSO_APP_ID, VITE_SSO_REDIRECT_URL } = import.meta.env
  const { host: VITE_SSO_HOST, appId: VITE_SSO_APP_ID, redirectUrl: VITE_SSO_REDIRECT_URL } = getSsoConfig()
  if (!VITE_SSO_HOST || !VITE_SSO_APP_ID || !VITE_SSO_REDIRECT_URL)
    return ''
src/utils/env-config.ts
New file
@@ -0,0 +1,108 @@
/**
 * 运行时环境配置
 *
 * 由于 CI/CD 统一执行 `npm run build`(production 模式),无法通过 .env 文件区分环境。
 * 本文件通过运行时判断 window.location.hostname 来确定当前部署环境,
 * 动态返回对应的 SSO 配置和服务地址。
 */
export type EnvType = 'test' | 'uat' | 'production'
export interface EnvConfig {
  /** SSO 域名 */
  VITE_SSO_HOST: string
  /** SSO 应用 ID */
  VITE_SSO_APP_ID: string
  /** SSO 登录后重定向地址 */
  VITE_SSO_REDIRECT_URL: string
  /** 后端服务地址 */
  SERVICE_URL: string
  /** 指挥中心 WebSocket 地址 */
  COMMAND_CENTER_SOCKET_URL: string
}
/** 各环境配置映射 */
const ENV_CONFIG_MAP: Record<EnvType, EnvConfig> = {
  test: {
    VITE_SSO_HOST: 'sso.test.xiaopeng.com',
    VITE_SSO_APP_ID: 'RoboTaxi-admin',
    VITE_SSO_REDIRECT_URL: 'http://rt-admin.test.xiaopeng.local/dashboard',
    SERVICE_URL: 'http://rt-admin.test.xiaopeng.local',
    COMMAND_CENTER_SOCKET_URL: 'wss://rt-admin.test.xiaopeng.local',
  },
  uat: {
    VITE_SSO_HOST: 'sso-xt.deploy-test.xiaopeng.com',
    VITE_SSO_APP_ID: 'RoboTaxi-admin-predeploy',
    VITE_SSO_REDIRECT_URL: 'https://rt-admin.deploy-test.xiaopeng.com/dashboard',
    SERVICE_URL: 'https://rt-admin.deploy-test.xiaopeng.com',
    COMMAND_CENTER_SOCKET_URL: 'wss://rt-admin.deploy-test.xiaopeng.com',
  },
  production: {
    VITE_SSO_HOST: 'xpsso.xiaopeng.com',
    VITE_SSO_APP_ID: 'RoboTaxi-admin',
    VITE_SSO_REDIRECT_URL: 'https://rt-admin.xiaopeng.com/dashboard',
    SERVICE_URL: 'https://rt-admin.xiaopeng.com',
    COMMAND_CENTER_SOCKET_URL: '',
  },
}
/** 域名 → 环境类型的匹配规则 */
const HOST_ENV_RULES: Array<{ pattern: RegExp, env: EnvType }> = [
  { pattern: /\.test\.xiaopeng\.local$/, env: 'test' },
  { pattern: /\.deploy-test\.xiaopeng\.com$/, env: 'uat' },
  { pattern: /\.xiaopeng\.com$/, env: 'production' },
]
/**
 * 根据当前域名判断运行环境
 */
export function getEnvType(): EnvType {
  const hostname = window.location.hostname
  // 本地开发视为测试环境
  if (hostname === 'localhost' || hostname === '127.0.0.1') {
    return 'test'
  }
  for (const rule of HOST_ENV_RULES) {
    if (rule.pattern.test(hostname)) {
      return rule.env
    }
  }
  // 未匹配到任何规则,默认为生产环境(安全兜底)
  return 'production'
}
/**
 * 获取当前环境的完整配置
 */
export function getEnvConfig(): EnvConfig {
  return ENV_CONFIG_MAP[getEnvType()]
}
/**
 * 获取当前环境的 SSO 配置
 */
export function getSsoConfig() {
  const config = getEnvConfig()
  return {
    host: config.VITE_SSO_HOST,
    appId: config.VITE_SSO_APP_ID,
    redirectUrl: config.VITE_SSO_REDIRECT_URL,
  }
}
/**
 * 获取当前环境的后端服务地址
 */
export function getServiceUrl(): string {
  return getEnvConfig().SERVICE_URL
}
/**
 * 获取当前环境的指挥中心 WebSocket 地址
 */
export function getSocketUrl(): string {
  return getEnvConfig().COMMAND_CENTER_SOCKET_URL
}
src/utils/socket.ts
@@ -1,6 +1,7 @@
import { io } from 'socket.io-client'
import type { Socket } from 'socket.io-client'
import { SOCKET_CONFIG } from '@/views/businessOperations/commandCenter/command-center.constants'
import { getSocketUrl } from '@/utils/env-config'
/** 单例 Socket 实例 */
let instance: Socket | null = null
@@ -13,7 +14,7 @@
  if (instance)
    return instance
  const url = import.meta.env.VITE_COMMAND_CENTER_SOCKET_URL || ''
  const url = getSocketUrl()
  instance = io(`${url}${SOCKET_CONFIG.NAMESPACE}`, {
    path: SOCKET_CONFIG.PATH,