diff --git a/common/js/customer-service.js b/common/js/customer-service.js index df71d59..ba09912 100644 --- a/common/js/customer-service.js +++ b/common/js/customer-service.js @@ -453,6 +453,206 @@ export class CustomerService { return { ...config, openType }; } + + /** + * 获取客服按钮图标 + * @returns {String} 图标URL + */ + getKefuButtonIcon() { + const shopInfo = this.vm.shopInfo || {}; + const config = this.getPlatformConfig(); + + if (config?.type === 'aikefu') { + return shopInfo.aiAgentimg || ''; + } else if (config?.type === 'wxwork' || config?.type === 'qyweixin') { + return shopInfo.aiAgentimg || ''; + } + return shopInfo.kefuimg || this.vm.$util?.getDefaultImage()?.kefu || ''; + } + + /** + * 判断是否为微信官方客服 + * @returns {Boolean} + */ + isWeappOfficialKefu() { + const config = this.getPlatformConfig(); + return config?.type === 'weapp'; + } + + /** + * 判断是否需要同时显示小程序系统客服 + * @returns {Boolean} + */ + shouldShowExtraWeappSystemKefu() { + const config = this.getPlatformConfig(); + return (config?.show_system_service === true || config?.show_system_service === '1') && config?.type !== 'weapp'; + } + + /** + * 计算容器高度 + * @param {Boolean} isLanguageSwitchEnabled 是否启用语言切换 + * @param {Boolean} showWeappSystemKefu 是否显示小程序系统客服 + * @param {Boolean} fixBtnShow 是否显示按钮 + * @returns {String} 高度值(px) + */ + getContainerHeight(isLanguageSwitchEnabled, showWeappSystemKefu, fixBtnShow) { + if (!fixBtnShow) return '160px'; + + let buttonCount = 1; + if (isLanguageSwitchEnabled) buttonCount++; + if (showWeappSystemKefu) buttonCount++; + + const totalRpx = 94 * buttonCount - 14; + const pxValue = Math.round(totalRpx * 0.5); + + return `${pxValue}px`; + } + + /** + * 获取未读消息数量 + * @returns {Number} + */ + getUnreadCount() { + return this.vm.$store?.state?.aiUnreadCount || 0; + } + + /** + * 拨打电话联系客服 + * @param {String} phoneNumber 电话号码 + */ + makePhoneCallByNumber(phoneNumber) { + if (phoneNumber) { + uni.makePhoneCall({ phoneNumber }); + } else { + this.makePhoneCall(); + } + } + + /** + * 打开 AI 智能助手 + */ + openAIChat() { + try { + if (typeof this.vm.setAiUnreadCount === 'function') { + this.vm.setAiUnreadCount(0); + } + + const aiChatUrl = '/pages_tool/ai-chat/index'; + + uni.navigateTo({ + url: aiChatUrl, + fail: (err) => { + console.error('跳转 AI 客服失败:', err); + // #ifdef H5 + window.location.href = aiChatUrl; + // #endif + uni.showToast({ title: '打开客服失败', icon: 'none' }); + } + }); + } catch (e) { + console.error('跳转 AI 客服异常:', e); + uni.showToast({ title: '打开客服失败', icon: 'none' }); + } + } + + /** + * 打开客服选择对话框(预留方法) + */ + openCustomerSelectPopupDialog() { + uni.showToast({ title: '客服选择功能开发中', icon: 'none' }); + } + + /** + * 打开客服选择弹出层(ActionSheet) + * @param {Array} kefuList 客服列表 + */ + openKefuSelectPopup(kefuList) { + const kefuNames = kefuList.map(item => item.name); + uni.showActionSheet({ + itemList: kefuNames, + success: (res) => { + const selectedKefu = kefuList[res.tapIndex]; + const cs = createCustomerService(this.vm, selectedKefu); + + if (selectedKefu.isOfficial) { + uni.openCustomerServiceConversation({ + sessionFrom: 'weapp', + showMessageCard: true + }); + } else if (selectedKefu.id === 'qyweixin-kefu') { + if (uni.getSystemInfoSync().platform === 'wechat') { + uni.navigateTo({ + url: '/pages_tool/qyweixin-kefu/index' + }); + } else { + const qyweixinUrl = this.vm.shopInfo?.qyweixinUrl; + if (qyweixinUrl) { + window.location.href = qyweixinUrl; + } else { + uni.showToast({ title: '企业微信客服未配置', icon: 'none' }); + } + } + } else { + cs.handleCustomerClick(); + } + } + }); + } + + /** + * 核心方法:统一客服入口(带验证和配置检查) + * @param {Object} options 选项参数 + */ + handleUnifiedKefuClick(options = {}) { + const validation = this.validateConfig(); + + console.log('【客服配置验证】', validation); + + if (!validation.isValid) { + console.error('客服配置无效:', validation.errors); + uni.showToast({ title: '客服暂不可用', icon: 'none' }); + return; + } + + if (validation.warnings.length > 0) { + console.warn('客服配置警告:', validation.warnings); + } + + const platformConfig = this.getPlatformConfig(); + console.log('【当前客服配置】', platformConfig); + + // 检查企业微信配置 + if (platformConfig.type === 'wxwork') { + const wxworkConfig = this.getWxworkConfig(); + console.log('【企业微信配置】', wxworkConfig); + + // #ifdef MP-WEIXIN + if (!wxworkConfig?.enable || !wxworkConfig?.contact_url) { + console.warn('企业微信配置不完整,使用原生客服'); + uni.showToast({ title: '企业微信配置不完整', icon: 'none' }); + } + // #endif + + // #ifdef H5 + if (!wxworkConfig?.contact_url && !platformConfig.wxwork_url) { + console.error('企业微信链接未配置'); + uni.showToast({ title: '企业微信链接未配置', icon: 'none' }); + return; + } + // #endif + } + + // 直接调用统一处理方法,由 CustomerService 内部根据配置路由 + try { + this.handleCustomerClick({ + sendMessageTitle: options.sendMessageTitle || '来自悬浮按钮的咨询', + sendMessagePath: options.sendMessagePath || '/pages/index/index' + }); + } catch (error) { + console.error('客服处理失败:', error); + uni.showToast({ title: '打开客服失败', icon: 'none' }); + } + } } /** diff --git a/components/hover-nav/hover-nav.vue b/components/hover-nav/hover-nav.vue index 4dcaed3..bacd2eb 100644 --- a/components/hover-nav/hover-nav.vue +++ b/components/hover-nav/hover-nav.vue @@ -2,7 +2,7 @@ @@ -12,7 +12,7 @@ v-if="fixBtnShow && isWeappOfficialKefu" class="btn-item common-bg" open-type="contact" - :style="{ backgroundImage: currentKefuImg ? `url( $ {currentKefuImg})` : '', backgroundSize: '100% 100%' }" + :style="{ backgroundImage: currentKefuImg ? `url(${currentKefuImg})` : '', backgroundSize: '100% 100%' }" > 🤖 @@ -21,7 +21,7 @@ v-else-if="fixBtnShow" class="btn-item common-bg" @click="handleUnifiedKefuClick" - :style="{ backgroundImage: currentKefuImg ? `url( $ {currentKefuImg})` : '', backgroundSize: '100% 100%' }" + :style="{ backgroundImage: currentKefuImg ? `url(${currentKefuImg})` : '', backgroundSize: '100% 100%' }" > 🤖 @@ -31,7 +31,7 @@ v-if="fixBtnShow && showWeappSystemKefu" class="btn-item common-bg" open-type="contact" - :style="{ backgroundImage: currentKefuImg ? `url( $ {currentKefuImg})` : '', backgroundSize: '100% 100%' }" + :style="{ backgroundImage: currentKefuImg ? `url(${currentKefuImg})` : '', backgroundSize: '100% 100%' }" > 💬 @@ -50,7 +50,7 @@ v-if="fixBtnShow" class="btn-item common-bg" @click="call()" - :style="[{ backgroundImage: phoneimg ? `url( $ {phoneimg})` : '', backgroundSize: '100% 100%' }, customButtonStyle]" + :style="[{ backgroundImage: phoneimg ? `url(${phoneimg})` : '', backgroundSize: '100% 100%' }, customButtonStyle]" > @@ -111,54 +111,39 @@ export default { return this.shopInfo?.floatingButton?.button || {}; }, unreadCount() { - return this. $store.state.aiUnreadCount || 0; + const customerService = createCustomerService(this); + return customerService.getUnreadCount(); }, - // ✅ 新增:根据当前客服类型动态返回图标 currentKefuImg() { - if (!this.shopInfo) return ''; - const customerService = createCustomerService(this); - const config = customerService.getPlatformConfig(); - - if (config?.type === 'aikefu') { - return this.aiAgentimg; - } else if (config?.type === 'wxwork' || config?.type === 'qyweixin') { - // 企业微信客服专用图标 - return this.aiAgentimg; - } - // 默认客服图标 - return this.kefuimg; + return customerService.getKefuButtonIcon(); }, - // ✅ 新增:判断是否为微信官方客服 + isWeappOfficialKefu() { - if (!this.shopInfo) return false; const customerService = createCustomerService(this); - const config = customerService.getPlatformConfig(); - return config?.type === 'weapp'; + return customerService.isWeappOfficialKefu(); }, - // ✅ 新增:判断是否需要同时显示小程序系统客服 + showWeappSystemKefu() { - if (!this.shopInfo) return false; const customerService = createCustomerService(this); - const config = customerService.getPlatformConfig(); - // 检查附加设置是否开启了同时显示小程序系统客服,且当前客服类型不是小程序系统客服 - return (config?.show_system_service === true || config?.show_system_service === '1') && config?.type !== 'weapp'; + return customerService.shouldShowExtraWeappSystemKefu(); }, - //根据显示的按钮数量动态计算容器高度 - containerHeight() { - if (!this.fixBtnShow) return '320rpx'; - - let buttonCount = 1; - if (this.isLanguageSwitchEnabled) buttonCount++; - if (this.showWeappSystemKefu) buttonCount++; - buttonCount++; - const totalRpx = 94 * buttonCount - 14; - const pxValue = Math.round(totalRpx * 0.5); - - return ` $ {pxValue}px`; - } - }, + + //根据显示的按钮数量动态计算容器高度 + containerHeight() { + if (!this.fixBtnShow) return '320rpx'; + + let buttonCount = 1; + if (this.isLanguageSwitchEnabled) buttonCount++; + if (this.showWeappSystemKefu) buttonCount++; + buttonCount++; + const totalRpx = 94 * buttonCount - 14; + const pxValue = Math.round(totalRpx * 0.5); + + return ` $ {pxValue}px`; + } + }, watch: { shopInfo: { handler(newVal) { @@ -210,7 +195,8 @@ export default { * 电话联系客服 */ call() { - this.customerService.makePhoneCall(this.tel); + const customerService = createCustomerService(this); + customerService.makePhoneCallByNumber(this.tel); }, /** @@ -228,103 +214,35 @@ export default { * 打开 AI 智能助手 */ openAIChat() { - this.$util.redirectTo(this.$util.AI_CHAT_PAGE_URL); + const customerService = createCustomerService(this); + customerService.openAIChat(); }, /** * 打开客服选择对话框 */ openCustomerSelectPopup() { - this.customerService.openCustomerSelectPopupDialog(); - }, - - // ✅ 核心方法:统一客服入口 - handleUnifiedKefuClick() { const customerService = createCustomerService(this); - const validation = customerService.validateConfig(); - - console.log('【客服配置验证】', validation); - - if (!validation.isValid) { - console.error('客服配置无效:', validation.errors); - uni.showToast({ title: '客服暂不可用', icon: 'none' }); - return; - } - - if (validation.warnings.length > 0) { - console.warn('客服配置警告:', validation.warnings); - } - - const platformConfig = customerService.getPlatformConfig(); - console.log('【当前客服配置】', platformConfig); - - // 检查企业微信配置 - if (platformConfig.type === 'wxwork') { - const wxworkConfig = customerService.getWxworkConfig(); - console.log('【企业微信配置】', wxworkConfig); - - // #ifdef MP-WEIXIN - if (!wxworkConfig?.enable || !wxworkConfig?.contact_url) { - console.warn('企业微信配置不完整,使用原生客服'); - uni.showToast({ title: '企业微信配置不完整', icon: 'none' }); - } - // #endif - - // #ifdef H5 - if (!wxworkConfig?.contact_url && !platformConfig.wxwork_url) { - console.error('企业微信链接未配置'); - uni.showToast({ title: '企业微信链接未配置', icon: 'none' }); - return; - } - // #endif - } - - // 直接调用统一处理方法,由 CustomerService 内部根据配置路由 - try { - customerService.handleCustomerClick({ - sendMessageTitle: '来自悬浮按钮的咨询', - sendMessagePath: '/pages/index/index' - }); - } catch (error) { - console.error('客服处理失败:', error); - uni.showToast({ title: '打开客服失败', icon: 'none' }); - } + customerService.openCustomerSelectPopupDialog(); }, - // 以下方法保留用于 actionSheet(如仍需手动选择) - openKefuSelectPopup() { - const kefuNames = this.kefuList.map(item => item.name); - uni.showActionSheet({ - itemList: kefuNames, - success: (res) => { - this.selectedKefu = this.kefuList[res.tapIndex]; - const cs = createCustomerService(this, this.selectedKefu); - if (this.selectedKefu.isOfficial) { - uni.openCustomerServiceConversation({ - sessionFrom: 'weapp', - showMessageCard: true - }); - } else if (this.selectedKefu.id === 'qyweixin-kefu') { - // 处理企业微信客服 - if (uni.getSystemInfoSync().platform === 'wechat') { - // 小程序端:跳转到企业微信客服 - uni.navigateTo({ - url: '/pages_tool/qyweixin-kefu/index' - }); - } else { - // H5端:跳转到企业微信链接 - const qyweixinUrl = this.shopInfo.qyweixinUrl; // 后端返回的企业微信链接 - if (qyweixinUrl) { - window.location.href = qyweixinUrl; - } else { - uni.showToast({ title: '企业微信客服未配置', icon: 'none' }); - } - } - } else { - cs.handleCustomerClick(); - } - } + /** + * 核心方法:统一客服入口 + */ + handleUnifiedKefuClick() { + const customerService = createCustomerService(this); + customerService.handleUnifiedKefuClick({ + sendMessageTitle: '来自悬浮按钮的咨询', + sendMessagePath: '/pages/index/index' }); + }, + + /** + * 打开客服选择弹出层(ActionSheet) + */ + openKefuSelectPopup() { + const customerService = createCustomerService(this); + customerService.openKefuSelectPopup(this.kefuList); } } } @@ -359,7 +277,7 @@ export default { margin: 14rpx 0; transition: 0.1s; color: var(--hover-nav-text-color); - border-radius: 40rpx; + border-radius: 50%; width: 80rpx; height: 80rpx; padding: 0;