From 0417c5c5eda1d9329059b59089062175e467c15f Mon Sep 17 00:00:00 2001
From: jinhhanhan <1683105490@qq.com>
Date: Thu, 5 Feb 2026 09:27:43 +0800
Subject: [PATCH] =?UTF-8?q?chore=EF=BC=9A=E4=BC=98=E5=8C=96=E4=BA=86hover?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
common/js/customer-service.js | 200 +++++++++++++++++++++++++++++
components/hover-nav/hover-nav.vue | 180 +++++++-------------------
2 files changed, 249 insertions(+), 131 deletions(-)
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;