@@ -1,21 +1,23 @@
< template >
< template >
< view v-if = "pageCount == 1 || need" class="fixed-box" :style="{ height: fixBtnShow ? (isH5 ? '180rpx' : '330rpx') : '120rpx' }" >
< view v-if = "pageCount == 1 || need" class="fixed-box" :style="{ height: fixBtnShow ? (isH5 ? '180rpx' : '330rpx') : '120rpx' }" >
< ! - - 统一的客服耳机按钮 : H5和小程序共用 - - >
<!-- # ifdef MP - WEIXIN -- >
<!-- # ifdef MP - WEIXIN -- >
<!-- 微信小程序 : 根据配置自动选择官方客服 / 自定义客服 -- >
< button
< button
class = "btn-item"
class = "btn-item"
v-if = "fixBtnShow"
v-if = "fixBtnShow"
hoverClass = "none"
hoverClass = "none"
: open -type = " weappOfficialService ? ' contact ' : ' ' "
: open -type = " weappOfficialService ? ' contact ' : ' ' "
@click ="weappOfficialService ? '' : handleWeappCustomerServ ice "
@click ="handleWeappCustomerCl ick "
: style = "{ backgroundImage: 'url(' + (kefuimg ? kefuimg : '') + ')', backgroundSize: '100% 100%' }"
: style = "{ backgroundImage: 'url(' + (kefuimg ? kefuimg : '') + ')', backgroundSize: '100% 100%' }"
>
>
< text class = "icox icox-kefu" v-if = "!kefuimg" > < / text >
< text class = "icox icox-kefu" v-if = "!kefuimg" > < / text >
< view v-if = "unreadCount > 0 && isDifyService" class="unread-badge" >
< text class = "badge-text" > { { unreadCount > 99 ? '99+' : unreadCount } } < / text >
< / view >
< / button >
< / button >
<!-- # endif -- >
<!-- # endif -- >
<!-- # ifdef H5 -- >
<!-- # ifdef H5 -- >
<!-- H5逻辑保持不变 -- >
< button
< button
class = "btn-item"
class = "btn-item"
v-if = "fixBtnShow"
v-if = "fixBtnShow"
@@ -30,20 +32,6 @@
< / button >
< / button >
<!-- # endif -- >
<!-- # endif -- >
<!-- # ifndef H5 -- >
< view
class = "btn-item"
v-if = "fixBtnShow && isDifyService"
@click ="handleCustomerService"
: style = "{ backgroundImage: 'url(' + (aiAgentimg ? aiAgentimg : '') + ')', backgroundSize: '100% 100%' }"
>
< text class = "ai-icon" v-if = "!aiAgentimg" > 🤖 < / text >
< view v-if = "unreadCount > 0" class="unread-badge" >
< text class = "badge-text" > { { unreadCount > 99 ? '99+' : unreadCount } } < / text >
< / view >
< / view >
<!-- # endif -- >
< view
< view
class = "btn-item"
class = "btn-item"
v-if = "fixBtnShow"
v-if = "fixBtnShow"
@@ -99,11 +87,10 @@ export default {
// 3. 获取店铺电话
// 3. 获取店铺电话
this . getShopTel ( ) ;
this . getShopTel ( ) ;
// 4. 首次加载获取最新配置
// 4. 首次加载获取最新配置(小程序强制请求最新配置,避免缓存)
this . getLatestConfig ( ) . then ( config => {
this . getLatestConfig ( true ) . then ( config => {
this . latestConfig = config ;
this . latestConfig = config ;
this . initCustomerService ( config ) ;
this . initCustomerService ( config ) ;
// 微信小程序:判断是否使用官方客服
this . initWeappServiceType ( ) ;
this . initWeappServiceType ( ) ;
} ) ;
} ) ;
} ,
} ,
@@ -128,48 +115,53 @@ export default {
'setAiUnreadCount'
'setAiUnreadCount'
] ) ,
] ) ,
/**
/**
* 获取最新配置( H5禁用缓存, 小程序保留默认 )
* 修复:微信小程序客服点击事件(直接触发客服逻辑 )
*/
*/
async getLatestConfig ( ) {
handleWeappCustomerClick ( ) {
if ( ! this . weappOfficialService ) {
// 直接调用客服处理逻辑
this . handleCustomerService ( ) ;
}
} ,
/**
* 修复:获取最新配置(支持强制刷新,解决小程序缓存问题)
*/
async getLatestConfig ( forceRefresh = false ) {
return new Promise ( ( resolve ) => {
return new Promise ( ( resolve ) => {
// H5: 强制请求最新配置; 小程序: 优先用vuex 缓存
// H5/小程序 强制请求最新配置,避免 缓存
if ( this . isH5 ) {
this . $api . sendRequest ( {
this . $api . sendRequest ( {
url : '/api/site/getServicerConfig' ,
url : '/api/site/getServicerConfig' ,
header : {
header : {
'Cache-Control' : 'no-cache, no-store, must-revalidate' ,
'Cache-Control ' : 'no-cache, no-store, must-revalidate ' ,
'Pragma ' : 'no-cache' ,
'Pragma ' : 'no-cache' ,
'Expires ' : '0'
'Expires' : '0'
} ,
} ,
data : { t : new Date ( ) . getTime ( ) } ,
data : { t : new Date ( ) . getTime ( ) } ,
success : ( res ) => {
success : ( res ) => {
const config = res . code === 0 ? res . data : this . $store . state . servicerConfig || { } ;
const config = res . code === 0 ? res . data : this . $store . state . servicerConfig || { } ;
this . $store . commit ( 'UPDATE_SERVICER_CONFIG' , config ) ;
this . $store . commit ( 'UPDATE_SERVICER_CONFIG' , config ) ;
resolve ( config ) ;
resolve ( config ) ;
} ,
} ,
fail : ( ) => resolve ( this . $store . state . servicerConfig || { } )
fail : ( ) => resolve ( this . $store . state . servicerConfig || { } )
} );
} ) ;
} else {
// 小程序: 直接用vuex缓存( 后台修改后需重启开发者工具)
resolve ( this . $store . state . servicerConfig || { } ) ;
}
} ) ;
} ) ;
} ,
} ,
/**
/**
* 初始化客服服务
* 初始化客服服务(确保实例正确创建)
*/
*/
initCustomerService ( config = null ) {
initCustomerService ( config = null ) {
// 强制重新创建客服实例
this . customerService = null ;
this . customerService = createCustomerService ( this , config || this . latestConfig ) ;
this . customerService = createCustomerService ( this , config || this . latestConfig ) ;
this . platformConfig = this . customerService . refreshConfig ( config || this . latestConfig ) ;
this . platformConfig = this . customerService . refreshConfig ( config || this . latestConfig ) ;
this . buttonConfig = this . customerService . getButtonConfig ( ) ;
this . buttonConfig = this . customerService . getButtonConfig ( ) ;
} ,
} ,
/**
/**
* 微信小程序:初始化服务类型(官方/自定义 )
* 微信小程序:初始化服务类型(修复判断逻辑 )
*/
*/
initWeappServiceType ( ) {
initWeappServiceType ( ) {
// #ifdef MP-WEIXIN
// #ifdef MP-WEIXIN
// 从buttonConfig中获取官方客服标识
this . weappOfficialService = this . buttonConfig ? . openType === 'contact' && ! this . isDifyService ;
this . weappOfficialService = this . buttonConfig ? . openType === 'contact' ;
// #endif
// #endif
} ,
} ,
/**
/**
@@ -203,76 +195,57 @@ export default {
} ) ;
} ) ;
} ,
} ,
/**
/**
* H5 客服点击逻辑(保持不变 )
* 客服点击逻辑(修复:确保小程序端正确执行 )
*/
*/
async handleCustomerService ( ) {
async handleCustomerService ( ) {
if ( this . isH5 ) {
uni . showLoading ( { title : '加载中...' , mask : true } ) ;
uni . showLoading ( { title : '加载中...' , mask : true } ) ;
try {
try {
// 再次获取最新配置, 确保是dify模式
const newConfig = await this . getLatestConfig ( ) ;
const newConfig = await this . getLatestConfig ( true ) ;
this . latestConfig = newConfig ;
this . initCustomerService ( newConfig ) ;
this . initCustomerService ( newConfig ) ;
// 强制触发客服点击
if ( this . customerService ) {
this . customerService . handleCustomerClick ( ) ;
this . customerService . handleCustomerClick ( ) ;
} catch ( e ) {
uni . showToast ( { title : '操作失败' , icon : 'none' } ) ;
} finally {
uni . hideLoading ( ) ;
}
}
} else {
} catch ( e ) {
// 小程序:直接调用客服逻辑
uni . showToast ( { title : '操作失败' , icon : 'none' } ) ;
this . customerService . handleCustomerClick ( ) ;
} finally {
uni . hideLoading ( ) ;
}
}
} ,
/**
* 微信小程序自定义客服点击逻辑
*/
handleWeappCustomerService ( ) {
// #ifdef MP-WEIXIN
this . customerService . handleCustomerClick ( ) ;
// #endif
}
}
}
}
} ;
} ;
< / script >
< / script >
< style scoped >
< style scoped >
/* 父容器:不限制高度,避免挤压按钮 */
/* 样式保持不变 */
. fixed - box {
. fixed - box {
position : fixed ;
position : fixed ;
right : 20 rpx ; /* 增加右侧边距,避免贴边 */
right : 20 rpx ;
bottom : 200 rpx ;
bottom : 200 rpx ;
z - index : 9999 ;
z - index : 9999 ;
display : flex ;
display : flex ;
flex - direction : column ;
flex - direction : column ;
align - items : center ;
align - items : center ;
gap : 14 rpx ; /* 替代margin, 更稳定 */
gap : 14 rpx ;
}
}
/* 核心:强制按钮为正方形+正圆 */
. btn - item {
. btn - item {
/* 宽高强制相等,必须是正方形 */
width : 88 rpx ! important ;
width : 88 rpx ! important ;
height : 88 rpx ! important ;
height : 88 rpx ! important ;
/* 强制正圆(优先级最高) */
border - radius : 50 % ! important ;
border - radius : 50 % ! important ;
/* 白色背景(确保是圆) */
background - color : # ffffff ! important ;
background - color : # ffffff ! important ;
/* 背景图居中显示,不拉伸 */
background - size : 60 % 60 % ! important ;
background - size : 60 % 60 % ! important ;
background - position : center ! important ;
background - position : center ! important ;
background - repeat : no - repeat ! important ;
background - repeat : no - repeat ! important ;
/* 清除默认样式 */
border : none ! important ;
border : none ! important ;
padding : 0 ! important ;
padding : 0 ! important ;
margin : 0 ! important ;
margin : 0 ! important ;
/* 居中内容 */
display : flex ! important ;
display : flex ! important ;
justify - content : center ! important ;
justify - content : center ! important ;
align - items : center ! important ;
align - items : center ! important ;
/* 阴影增强视觉(可选) */
box - shadow : 0 2 rpx 8 rpx rgba ( 0 , 0 , 0 , 0.1 ) ;
box - shadow : 0 2 rpx 8 rpx rgba ( 0 , 0 , 0 , 0.1 ) ;
}
}
/* 清除button标签的默认点击样式( 微信小程序/浏览器) */
. btn - item : : after {
. btn - item : : after {
border : none ! important ;
border : none ! important ;
}
}
@@ -294,7 +267,6 @@ export default {
z - index : 1 ;
z - index : 1 ;
}
}
/* 微信小程序字体适配 */
/* #ifdef MP-WEIXIN */
/* #ifdef MP-WEIXIN */
. unread - badge {
. unread - badge {
font - size : 20 rpx ;
font - size : 20 rpx ;