/** * 配置解析模块 - 参数校验 + 默认值填充 * * 参数映射: * integrateId → 后端 roleId(客服角色 ID) * userId → 后端 accountId(客户账号 ID) * chatId → 自动管理(不在用户配置中暴露) */ import { SDKConfig, ResolvedConfig } from './types'; import { logger } from './logger'; /** 默认悬浮按钮 SVG 图标(赛博机器人:对话气泡 + 机器人面孔 + 天线能量灯 + 眨眼动效) */ const DEFAULT_LAUNCHER_ICON = ` `; // ==================== 马卡龙色系玻璃质感图标 ==================== /** * 生成玻璃质感机器人 SVG 图标 * 包含:圆润机器人头部 + 眨眼动效 + 跳动气泡 + 高光反射层 */ function buildGlassIcon(eyeColor: string, smileColor: string, bubbleColor: string): string { return ` `; } /** 梦幻紫粉主题图标 */ const GLASS_ICON_DREAM_PURPLE = buildGlassIcon( 'rgba(139,92,246,0.6)', // 眼睛:紫色 'rgba(139,92,246,0.45)', // 微笑 'rgba(240,171,252,0.85)' // 气泡:粉紫 ); /** 薄荷青绿主题图标 */ const GLASS_ICON_MINT_TECH = buildGlassIcon( 'rgba(16,185,129,0.6)', // 眼睛:翠绿 'rgba(16,185,129,0.45)', // 微笑 'rgba(110,231,183,0.85)' // 气泡:薄荷 ); /** 珊瑚蜜桃主题图标 */ const GLASS_ICON_CORAL_PEACH = buildGlassIcon( 'rgba(244,63,94,0.55)', // 眼睛:珊瑚红 'rgba(244,63,94,0.4)', // 微笑 'rgba(253,186,116,0.85)' // 气泡:蜜桃 ); /** 天空蓝紫主题图标 */ const GLASS_ICON_SKY_BLUE = buildGlassIcon( 'rgba(56,189,248,0.6)', // 眼睛:天蓝 'rgba(56,189,248,0.45)', // 微笑 'rgba(167,139,250,0.85)' // 气泡:淡紫 ); /** 主题 → 默认主色映射(当用户未指定 primaryColor 时自动使用) */ const THEME_PRIMARY_COLORS: Record = { 'dream-purple': '#A78BFA', 'mint-tech': '#34D399', 'coral-peach': '#FB7185', 'sky-blue': '#7DD3FC', }; /** * 解析并校验用户传入的配置,填充默认值 */ export function parseConfig(raw: SDKConfig): ResolvedConfig | null { // 校验必传参数:integrateId(对应后端 roleId) if (!raw.integrateId || (typeof raw.integrateId !== 'string' && typeof raw.integrateId !== 'number') || (typeof raw.integrateId === 'string' && raw.integrateId.trim() === '')) { logger.error('integrateId 是必传参数(对应后端 roleId 客服角色 ID),请检查 init() 调用。示例:ChatbotSDK.init({ integrateId: 1, requestDomain: "https://api.example.com" })'); return null; } // 校验必传参数:requestDomain if (!raw.requestDomain || typeof raw.requestDomain !== 'string' || raw.requestDomain.trim() === '') { logger.error('requestDomain 是必传参数,请检查 init() 调用。示例:ChatbotSDK.init({ integrateId: 1, requestDomain: "https://api.example.com" })'); return null; } // 校验 requestDomain 是否为合法 URL 格式 try { new URL(raw.requestDomain); } catch { logger.error(`requestDomain 不是合法的 URL 格式:${raw.requestDomain}。请提供完整的域名,如 https://api.example.com`); return null; } // integrateId 统一转为字符串(后端 roleId 为 Long,但 query param 传字符串也可接收) const integrateIdStr = String(raw.integrateId).trim(); // 解析 launcherTheme:根据主题自动选择图标和默认主色 const launcherTheme = raw.launcherTheme || undefined; let resolvedLauncherIcon = raw.launcherIcon || DEFAULT_LAUNCHER_ICON; let resolvedPrimaryColor = raw.primaryColor || '#4F46E5'; if (launcherTheme && !raw.launcherIcon) { // 有主题且未自定义图标 → 使用主题专属玻璃质感图标 const themeIconsMap: Record = { 'dream-purple': GLASS_ICON_DREAM_PURPLE, 'mint-tech': GLASS_ICON_MINT_TECH, 'coral-peach': GLASS_ICON_CORAL_PEACH, 'sky-blue': GLASS_ICON_SKY_BLUE, }; resolvedLauncherIcon = themeIconsMap[launcherTheme] || DEFAULT_LAUNCHER_ICON; // 若未自定义主色 → 使用主题默认色 if (!raw.primaryColor) { resolvedPrimaryColor = THEME_PRIMARY_COLORS[launcherTheme] || '#4F46E5'; } } // 填充默认值 const config: ResolvedConfig = { integrateId: integrateIdStr, requestDomain: raw.requestDomain.replace(/\/+$/, ''), // 去掉末尾斜杠 userId: raw.userId, categoryId: raw.categoryId, showCategorySwitch: raw.showCategorySwitch ?? false, title: raw.title || 'AI 智能助手', width: raw.width ?? 380, height: Math.max(300, raw.height ?? 520), position: raw.position === 'left-bottom' ? 'left-bottom' : 'right-bottom', primaryColor: resolvedPrimaryColor, launcherTheme: launcherTheme, launcherIcon: resolvedLauncherIcon, showClear: raw.showClear ?? true, showAdminPanel: raw.showAdminPanel ?? false, quickReplies: Array.isArray(raw.quickReplies) ? raw.quickReplies.map(s => String(s).trim()).filter(Boolean) : [], theme: raw.theme === 'dark' ? 'dark' : 'light', showTeaser: raw.showTeaser ?? true, teaserText: (typeof raw.teaserText === 'string' && raw.teaserText.trim()) || '', streaming: raw.streaming ?? true, enableRag: raw.enableRag ?? true, rewriteStrategy: raw.rewriteStrategy || 'REWRITE', locale: raw.locale || 'zh-CN', debug: raw.debug ?? true, sound: raw.sound ?? false, notification: raw.notification ?? false, onError: typeof raw.onError === 'function' ? raw.onError : undefined, onReady: typeof raw.onReady === 'function' ? raw.onReady : undefined, onMessage: typeof raw.onMessage === 'function' ? raw.onMessage : undefined, chatId: '', // 初始为空,由 chatId 初始化流程填充 }; logger.info(`配置解析完成 integrateId(=roleId)=${config.integrateId} userId(=accountId)=${config.userId || '(未设置)'} requestDomain=${config.requestDomain}`); return config; }