import type { NextRequest } from 'next/server' // 尝试加载根目录的可移植部署变量文件(不会覆盖已存在的真实环境变量) try { // 动态引入,避免打包期间出错 const { loadPortableEnvIfPresent } = require('./configLoader') if (typeof loadPortableEnvIfPresent === 'function') { loadPortableEnvIfPresent() } } catch {} export function resolveBaseUrl(req?: NextRequest): string { const appPublicUrl = process.env.APP_PUBLIC_URL const nextAuthUrl = process.env.NEXTAUTH_URL const isLocal = (url?: string | null) => !!url && /localhost|127\.0\.0\.1/i.test(url) if (appPublicUrl && !isLocal(appPublicUrl)) return appPublicUrl if (req) { const forwardedProto = req.headers.get('x-forwarded-proto') const forwardedHost = req.headers.get('x-forwarded-host') const originHeader = req.headers.get('origin') const host = req.headers.get('host') const headerBase = (forwardedHost && `${forwardedProto || 'http'}://${forwardedHost}`) || (originHeader && !isLocal(originHeader) ? originHeader : null) || (host ? `http://${host}` : null) if (headerBase) return headerBase } if (nextAuthUrl && !isLocal(nextAuthUrl)) return nextAuthUrl return 'http://localhost:3000' } export const defaultLogos = { // 后台默认使用内置静态资源;如需自定义,可通过环境变量覆盖 // 当前仓库不再内置公共 Logo 资源;若未配置则走文字占位 header: process.env.DEFAULT_HEADER_LOGO_URL || '', login: process.env.DEFAULT_LOGIN_LOGO_URL || '', } export const publicDefaults = { // 前端默认 Logo,与后端 defaultLogos 保持一致,方便通过 env 统一覆盖 header: process.env.NEXT_PUBLIC_DEFAULT_HEADER_LOGO_URL || '', login: process.env.NEXT_PUBLIC_DEFAULT_LOGIN_LOGO_URL || '', intranetUrl: process.env.NEXT_PUBLIC_INTRANET_URL || '', } export function buildAbsoluteUrl(path: string, req?: NextRequest): string { const base = resolveBaseUrl(req) // 确保 base 不为空,避免返回 "http://" if (!base || base === 'http://' || base === 'https://') { return path.startsWith('http://') || path.startsWith('https://') ? path : `http://localhost:3000${path.startsWith('/') ? path : `/${path}`}` } if (!path) return base if (path.startsWith('http://') || path.startsWith('https://')) return path return `${base}${path.startsWith('/') ? path : `/${path}`}` } // Feature flags (can be overridden via SystemSettings in future) export const featureFlags = { aiEditEnabled: (process.env.AI_EDIT_ENABLED || 'false').toLowerCase() === 'true', tunnelEnabled: (process.env.TUNNEL_ENABLED || 'false').toLowerCase() === 'true', }