/** * 客服统一处理服务 * 整合各种客服方式,提供统一的调用接口 */ export class CustomerService { constructor(vueInstance, externalConfig = null) { this.vm = vueInstance; this.externalConfig = externalConfig; // 外部传入的最新配置(优先级最高) this.latestPlatformConfig = null; } /** * 强制刷新配置(支持传入外部配置) * @param {Object} externalConfig 外部最新配置 */ refreshConfig(externalConfig = null) { this.externalConfig = externalConfig || this.externalConfig; this.latestPlatformConfig = null; return this.getPlatformConfig(); } /** * 获取平台配置 * @returns {Object} 平台对应的客服配置 */ getPlatformConfig() { if (this.latestPlatformConfig) { return this.latestPlatformConfig; } // 优先级:外部传入 > vuex store > 空对象 const servicerConfig = this.externalConfig || this.vm.$store.state.servicerConfig || {}; console.log(`【实时客服配置】`, servicerConfig); let platformConfig = null; // #ifdef H5 platformConfig = servicerConfig.h5 && typeof servicerConfig.h5 === 'object' ? servicerConfig.h5 : null; // #endif // #ifdef MP-WEIXIN platformConfig = servicerConfig.weapp && typeof servicerConfig.weapp === 'object' ? servicerConfig.weapp : null; // #endif // #ifdef MP-ALIPAY platformConfig = servicerConfig.aliapp && typeof servicerConfig.aliapp === 'object' ? servicerConfig.aliapp : null; // #endif // #ifdef PC platformConfig = servicerConfig.pc && typeof servicerConfig.pc === 'object' ? servicerConfig.pc : null; // #endif // 防止空数组被当作有效配置 if (Array.isArray(platformConfig)) { platformConfig = null; } this.latestPlatformConfig = platformConfig; return platformConfig; } /** * 获取企业微信配置 * @returns {Object} 企业微信配置 */ getWxworkConfig() { return this.vm.$store.state.wxworkConfig || {}; } /** * 检查客服配置是否可用 * @returns {boolean} 是否有可用配置 */ isConfigAvailable() { const config = this.getPlatformConfig(); return config && typeof config === 'object' && config.type; } /** * 验证客服配置完整性 * @returns {Object} 验证结果 */ validateConfig() { const config = this.getPlatformConfig(); const wxworkConfig = this.getWxworkConfig(); const result = { isValid: true, errors: [], warnings: [] }; if (!config || !config.type) { result.isValid = false; result.errors.push('客服类型未配置'); return result; } if (config.type === 'wxwork') { if (!wxworkConfig || !wxworkConfig.enable) { result.warnings.push('企业微信未启用'); } if (!wxworkConfig.contact_url) { result.warnings.push('企业微信活码链接未配置'); } } return result; } /** * 跳转到 AI 客服页面(Dify) */ openDifyService() { try { // 清除未读数(如果存在) if (typeof this.vm.setAiUnreadCount === 'function') { this.vm.setAiUnreadCount(0); } // ✅ 修正路径:必须与 pages.json 中注册的路径一致 const aiChatUrl = '/pages_tool/ai-chat/index'; // ✅ 使用 navigateTo 保留返回栈(体验更好) uni.navigateTo({ url: aiChatUrl, fail: (err) => { console.error('跳转 AI 客服失败:', err); // H5 兜底 // #ifdef H5 window.location.href = aiChatUrl; // #endif uni.showToast({ title: '打开客服失败', icon: 'none' }); } }); } catch (e) { console.error('跳转 AI 客服异常:', e); uni.showToast({ title: '打开客服失败', icon: 'none' }); } } /** * 处理客服点击事件(统一入口) * @param {Object} options 选项参数(用于消息卡片等) */ handleCustomerClick(options = {}) { const validation = this.validateConfig(); if (!validation.isValid) { console.error('客服配置验证失败:', validation.errors); this.showConfigErrorPopup(validation.errors); return; } if (validation.warnings.length > 0) { console.warn('客服配置警告:', validation.warnings); } const config = this.getPlatformConfig(); console.log('【当前客服配置】', config); console.log('【客服类型】', config.type); const { niushop = {}, sendMessageTitle = '', sendMessagePath = '', sendMessageImg = '' } = options; if (config.type === 'none') { this.showNoServicePopup(); return; } // 核心路由:根据 type 决定行为 switch (config.type) { case 'aikefu': console.log('【跳转 AI 客服】目标路径: /pages_tool/ai-chat/index'); this.openDifyService(); break; case 'wxwork': console.log('【跳转企业微信客服】'); // 修改:强制跳转到AI客服页面 console.log('【强制跳转 AI 客服】目标路径: /pages_tool/ai-chat/index'); this.openDifyService(); break; case 'third': console.log('【跳转第三方客服】'); // 修改:强制跳转到AI客服页面 console.log('【强制跳转 AI 客服】目标路径: /pages_tool/ai-chat/index'); this.openDifyService(); break; case 'miniprogram': console.log('【跳转第三方小程序客服】'); // 修改:强制跳转到AI客服页面 console.log('【强制跳转 AI 客服】目标路径: /pages_tool/ai-chat/index'); this.openDifyService(); break; case 'niushop': console.log('【跳转牛商客服】'); // 修改:强制跳转到AI客服页面 console.log('【强制跳转 AI 客服】目标路径: /pages_tool/ai-chat/index'); this.openDifyService(); break; case 'weapp': console.log('【跳转微信官方客服】'); // 修改:强制跳转到AI客服页面 console.log('【强制跳转 AI 客服】目标路径: /pages_tool/ai-chat/index'); this.openDifyService(); break; case 'aliapp': console.log('【跳转支付宝客服】'); // 修改:强制跳转到AI客服页面 console.log('【强制跳转 AI 客服】目标路径: /pages_tool/ai-chat/index'); this.openDifyService(); break; default: console.error('【未知客服类型】', config.type); this.makePhoneCall(); } } // ================== 各类型客服实现 ================== openWxworkService(useOriginalService = false, servicerConfig = null, options = {}) { const config = servicerConfig || this.getPlatformConfig(); const wxworkConfig = this.getWxworkConfig(); const { sendMessageTitle = '', sendMessagePath = '', sendMessageImg = '' } = options; // #ifdef MP-WEIXIN if (!useOriginalService && wxworkConfig?.enable && wxworkConfig?.contact_url) { wx.navigateToMiniProgram({ appId: 'wxeb490c6f9b154ef9', path: `pages/contacts/externalContactDetail?url=${encodeURIComponent(wxworkConfig.contact_url)}`, success: () => console.log('跳转企业微信成功'), fail: (err) => { console.error('跳转企业微信失败:', err); this.fallbackToOriginalService(); } }); } else { // 检查是否有企业微信配置 if (!config.wxwork_url && !config.corpid) { console.error('企业微信配置不完整,缺少 wxwork_url 或 corpid'); uni.showToast({ title: '企业微信配置不完整', icon: 'none' }); this.fallbackToPhoneCall(); return; } wx.openCustomerServiceChat({ extInfo: { url: config.wxwork_url || '' }, corpId: config.corpid || '', showMessageCard: true, sendMessageTitle, sendMessagePath, sendMessageImg }); } // #endif // #ifdef H5 if (!useOriginalService && wxworkConfig?.enable && wxworkConfig?.contact_url) { window.location.href = wxworkConfig.contact_url; } else if (config.wxwork_url) { window.location.href = config.wxwork_url; } else { this.fallbackToPhoneCall(); } // #endif } openThirdService(config) { console.log('【第三方客服配置】', config); console.log('【配置字段】', Object.keys(config)); // 支持多种可能的字段名 const miniAppId = config.mini_app_id || config.miniAppId || config.appid || config.appId || config.app_id; const miniAppPath = config.mini_app_path || config.miniAppPath || config.path || config.page_path || ''; console.log('【解析后的小程序配置】AppID:', miniAppId, 'Path:', miniAppPath); // 优先处理第三方微信小程序客服 if (miniAppId) { console.log('【跳转第三方小程序】AppID:', miniAppId, 'Path:', miniAppPath); // #ifdef MP-WEIXIN wx.navigateToMiniProgram({ appId: miniAppId, path: miniAppPath, success: () => { console.log('【跳转第三方小程序成功】'); }, fail: (err) => { console.error('【跳转第三方小程序失败】', err); uni.showToast({ title: '跳转失败,请稍后重试', icon: 'none' }); } }); // #endif // #ifdef H5 uni.showToast({ title: '第三方小程序客服仅在微信小程序中可用', icon: 'none' }); // #endif return; } // 处理第三方链接客服 if (config.third_url) { console.log('【跳转第三方链接】', config.third_url); // #ifdef H5 window.location.href = config.third_url; // #endif // #ifdef MP-WEIXIN uni.setClipboardData({ data: config.third_url, success: () => { uni.showToast({ title: '链接已复制,请在浏览器打开', icon: 'none' }); } }); // #endif } else { console.error('【第三方客服配置不完整】缺少 mini_app_id 或 third_url'); this.fallbackToPhoneCall(); } } openNiushopService(niushop) { if (Object.keys(niushop).length > 0 && this.vm.$util?.redirectTo) { this.vm.$util.redirectTo('/pages_tool/chat/room', niushop); } else { this.makePhoneCall(); } } openWeappService(config, options = {}) { // 如果 useOfficial 为 true 或 undefined,则使用原生系统客服(由 button open-type="contact" 触发) // 此方法仅用于自定义跳转(如 useOfficial: false) if (config.useOfficial !== false) { // 不做任何事,应由