import { environmentPath, resolveRequestUrl } from "../core/requestUrl"; import { activeEnvMap } from "../workspaceStore"; /** * URL 输入(前置 URL 模式): * 当前环境配置了前置 URL 且值为相对路径(/ 开头或空)时, * 展示「前缀块 + 分隔线 + 路径输入」的一体胶囊 —— 借鉴 Apifox 前置 URL。 * 路径输入只编辑相对部分,光标 / 全选不会碰到服务地址。 */ import type { KeyboardEvent } from "react"; import { useWorkspace } from "../workspaceStore"; import { cx } from "./common"; import { EnvBadge } from "./EnvBadge"; import { VarHintInput } from "./VarHintInput"; export function useEnvBaseUrl(): { baseUrl: string; envId: string | null; envName: string } { const envId = useWorkspace((s) => s.activeEnvironmentId); const env = useWorkspace((s) => (envId ? s.environments.find((e) => e.id === envId) : undefined)); return { baseUrl: env?.baseUrl?.trim() ?? "", envId: envId ?? null, envName: env?.name ?? "", }; } /** 前置 URL 与相对路径拼接(供编辑器展示「实际地址」与代码生成复用) */ export function joinUrl(baseUrl: string, path: string): string { return resolveRequestUrl(path, activeEnvMap(), baseUrl); } export function UrlPathInput({ value, onChange, placeholder, className, onKeyDown, ariaLabel, }: { value: string; onChange: (v: string) => void; placeholder?: string; className?: string; onKeyDown?: (e: KeyboardEvent) => void; ariaLabel?: string; }) { const { baseUrl, envId, envName } = useEnvBaseUrl(); const setDialog = useWorkspace((s) => s.setDialog); const environments = useWorkspace((s) => s.environments); const relative = environmentPath(value, environments.map((env) => resolveRequestUrl("", activeEnvMap(), env.baseUrl || ""))); const usePrefix = !!baseUrl && (value === "" || (value.trimStart().startsWith("/") && !value.trimStart().startsWith("//"))); if (!usePrefix) { return (
{relative !== null && baseUrl && }
); } // 展示 host(去协议),完整地址放 title const display = resolveRequestUrl("", activeEnvMap(), baseUrl).replace(/\/+$/, ""); return (
); }