feat: add customer service chat, optimize case and homepage, fix api proxy
这一提交完成了多项功能升级与优化: 1. 新增全局浮动客服组件,集成腾讯云TRTC聊天能力并添加错误格式化工具 2. 新增图片资源并调整部分静态文件结构 3. 优化案例页面:重构筛选逻辑、新增空状态处理、添加加载更多功能 4. 优化首页布局:修复统计数字动画、调整移动端适配样式、优化轮播逻辑 5. 重构官方内容获取工具:添加缓存机制、优化媒体资源处理 6. 优化API代理配置,移除默认本地代理并新增环境变量配置 7. 新增页面数据恢复刷新逻辑,优化页面交互体验 8. 修复按钮组件冗余代码,调整头部导航移动端样式
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
<script setup>
|
||||
const route = useRoute()
|
||||
const isOpen = ref(false)
|
||||
const context = ref({ title: '在线客服', source: '' })
|
||||
|
||||
const isInteriorPage = computed(() => route.path !== '/')
|
||||
|
||||
function openFloatingChat() {
|
||||
context.value = {
|
||||
title: '在线客服',
|
||||
source: isInteriorPage.value ? '' : ''
|
||||
}
|
||||
isOpen.value = true
|
||||
}
|
||||
|
||||
function closeChat() {
|
||||
isOpen.value = false
|
||||
}
|
||||
|
||||
function onKeydown(event) {
|
||||
if (event.key === 'Escape' && isOpen.value) closeChat()
|
||||
}
|
||||
|
||||
onMounted(() => window.addEventListener('keydown', onKeydown))
|
||||
onBeforeUnmount(() => window.removeEventListener('keydown', onKeydown))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Teleport to="body">
|
||||
<Transition name="consult-float">
|
||||
<button
|
||||
v-if="!isOpen"
|
||||
class="consult-float-button"
|
||||
:class="{ 'is-interior': isInteriorPage }"
|
||||
type="button"
|
||||
aria-label="打开在线客服"
|
||||
title="在线客服"
|
||||
@click="openFloatingChat"
|
||||
>
|
||||
<AppIcon name="service" />
|
||||
<span>客服</span>
|
||||
</button>
|
||||
</Transition>
|
||||
|
||||
<Transition name="consult-panel">
|
||||
<div v-if="isOpen" class="consult-chat-shell" :class="{ 'is-interior': isInteriorPage }">
|
||||
<ClientOnly>
|
||||
<ChatOfficialChatWindow :context="context" @close="closeChat" />
|
||||
<template #fallback>
|
||||
<section class="consult-client-loading">
|
||||
<strong>正在打开在线客服...</strong>
|
||||
</section>
|
||||
</template>
|
||||
</ClientOnly>
|
||||
</div>
|
||||
</Transition>
|
||||
</Teleport>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.consult-float-button {
|
||||
position: fixed;
|
||||
z-index: 46;
|
||||
right: clamp(18px, 2.7vw, 12px);
|
||||
bottom: clamp(18px, 25vw, 520px);
|
||||
min-width: 88px;
|
||||
height: 48px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
padding: 0 16px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.28);
|
||||
border-radius: 999px;
|
||||
color: #fff;
|
||||
background: var(--gradient-action);
|
||||
box-shadow: 0 16px 34px rgba(35, 111, 231, 0.26);
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
transition:
|
||||
transform 0.2s,
|
||||
box-shadow 0.2s,
|
||||
opacity 0.2s;
|
||||
}
|
||||
|
||||
.consult-float-button :deep(.app-icon) {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
.consult-float-button:hover {
|
||||
transform: translateY(-3px);
|
||||
box-shadow: 0 20px 40px rgba(35, 111, 231, 0.34);
|
||||
}
|
||||
.consult-float-button:active {
|
||||
transform: translateY(1px) scale(0.98);
|
||||
}
|
||||
.consult-chat-shell {
|
||||
position: fixed;
|
||||
z-index: 90;
|
||||
right: clamp(16px, 2.4vw, 36px);
|
||||
bottom: clamp(16px, 2.4vw, 36px);
|
||||
}
|
||||
.consult-chat-shell.is-interior {
|
||||
bottom: calc(clamp(16px, 2.4vw, 36px) + 58px);
|
||||
}
|
||||
.consult-client-loading {
|
||||
width: min(420px, calc(100vw - 32px));
|
||||
height: 180px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
border-radius: 12px;
|
||||
color: #2f4056;
|
||||
background: #fff;
|
||||
box-shadow: 0 24px 64px rgba(37, 94, 160, 0.18);
|
||||
}
|
||||
.consult-float-enter-active,
|
||||
.consult-float-leave-active,
|
||||
.consult-panel-enter-active,
|
||||
.consult-panel-leave-active {
|
||||
transition:
|
||||
opacity 0.2s,
|
||||
transform 0.24s cubic-bezier(0.22, 1, 0.36, 1);
|
||||
}
|
||||
.consult-float-enter-from,
|
||||
.consult-float-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateY(12px) scale(0.96);
|
||||
}
|
||||
.consult-panel-enter-from,
|
||||
.consult-panel-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateY(16px) scale(0.98);
|
||||
}
|
||||
@media (max-width: 640px) {
|
||||
.consult-float-button {
|
||||
right: 16px;
|
||||
bottom: 16px;
|
||||
min-width: 80px;
|
||||
height: 44px;
|
||||
}
|
||||
.consult-float-button.is-interior {
|
||||
bottom: 70px;
|
||||
}
|
||||
.consult-chat-shell,
|
||||
.consult-chat-shell.is-interior {
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user