chore: 从源码中移除 ai-chat-float 及 ai-chat-popup组件
This commit is contained in:
@@ -1,238 +0,0 @@
|
|||||||
# AI智能客服浮动按钮组件
|
|
||||||
|
|
||||||
## 组件介绍
|
|
||||||
|
|
||||||
AI智能客服浮动按钮组件是一个可以在任何页面中使用的浮动AI客服按钮,点击按钮可以弹出完整的AI智能客服聊天界面。该组件基于现有的AI聊天消息组件,提供了丰富的交互功能和配置选项。
|
|
||||||
|
|
||||||
## 功能特性
|
|
||||||
|
|
||||||
- ✅ **浮动按钮** - 可自定义位置的浮动AI客服按钮
|
|
||||||
- ✅ **聊天弹窗** - 点击按钮弹出完整的AI聊天界面
|
|
||||||
- ✅ **全屏模式** - 支持全屏/窗口模式切换
|
|
||||||
- ✅ **未读消息** - 显示未读消息数量小红点
|
|
||||||
- ✅ **多种消息类型** - 支持文本、文件、图片、音频、视频、链接等
|
|
||||||
- ✅ **流式对话** - 支持流式AI回复效果
|
|
||||||
- ✅ **响应式设计** - 适配不同屏幕尺寸
|
|
||||||
- ✅ **自定义配置** - 丰富的配置选项
|
|
||||||
|
|
||||||
## 安装使用
|
|
||||||
|
|
||||||
### 1. 引入组件
|
|
||||||
|
|
||||||
在需要使用AI客服浮动按钮的页面中引入组件:
|
|
||||||
|
|
||||||
```json
|
|
||||||
// 页面配置文件 pages/xxx/xxx.json
|
|
||||||
{
|
|
||||||
"usingComponents": {
|
|
||||||
"ai-chat-float": "@/components/ai-chat-float/ai-chat-float"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. 在页面中使用
|
|
||||||
|
|
||||||
```vue
|
|
||||||
<!-- 页面模板 pages/xxx/xxx.vue -->
|
|
||||||
<template>
|
|
||||||
<view class="page">
|
|
||||||
<!-- 页面内容 -->
|
|
||||||
<view class="content">
|
|
||||||
<!-- 您的页面内容 -->
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- AI客服浮动按钮 -->
|
|
||||||
<ai-chat-float
|
|
||||||
ref="aiChatFloat"
|
|
||||||
:position="position"
|
|
||||||
:show-float-button="showButton"
|
|
||||||
:auto-open="autoOpen"
|
|
||||||
:initial-messages="initialMessages"
|
|
||||||
@chat-open="onChatOpen"
|
|
||||||
@chat-close="onChatClose"
|
|
||||||
@message-sent="onMessageSent"
|
|
||||||
@ai-response="onAIResponse"
|
|
||||||
@unread-update="onUnreadUpdate" />
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import aiChatFloat from '@/components/ai-chat-float/ai-chat-float.vue'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
aiChatFloat
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
position: 'bottom-right',
|
|
||||||
showButton: true,
|
|
||||||
autoOpen: false,
|
|
||||||
initialMessages: []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
onChatOpen() {
|
|
||||||
console.log('AI客服聊天窗口打开')
|
|
||||||
},
|
|
||||||
onChatClose() {
|
|
||||||
console.log('AI客服聊天窗口关闭')
|
|
||||||
},
|
|
||||||
onMessageSent(message) {
|
|
||||||
console.log('用户发送消息:', message)
|
|
||||||
},
|
|
||||||
onAIResponse(message) {
|
|
||||||
console.log('AI回复消息:', message)
|
|
||||||
},
|
|
||||||
onUnreadUpdate(count) {
|
|
||||||
console.log('未读消息数量:', count)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
```
|
|
||||||
|
|
||||||
## 组件属性
|
|
||||||
|
|
||||||
| 属性名 | 类型 | 默认值 | 说明 |
|
|
||||||
|--------|------|--------|------|
|
|
||||||
| position | String | 'bottom-right' | 按钮位置,可选值:'bottom-right', 'bottom-left', 'top-right', 'top-left' |
|
|
||||||
| offset | Object | { bottom: '100rpx', right: '40rpx', top: '100rpx', left: '40rpx' } | 按钮距离边缘的距离 |
|
|
||||||
| userAvatar | String | '/static/images/default-avatar.png' | 用户头像 |
|
|
||||||
| aiAvatar | String | '/static/images/ai-avatar.png' | AI头像 |
|
|
||||||
| initialMessages | Array | [] | 初始聊天消息 |
|
|
||||||
| showFloatButton | Boolean | true | 是否显示浮动按钮 |
|
|
||||||
| autoOpen | Boolean | false | 是否自动打开聊天窗口 |
|
|
||||||
|
|
||||||
## 事件监听
|
|
||||||
|
|
||||||
| 事件名 | 参数 | 说明 |
|
|
||||||
|--------|------|------|
|
|
||||||
| chat-open | - | 聊天窗口打开事件 |
|
|
||||||
| chat-close | - | 聊天窗口关闭事件 |
|
|
||||||
| message-sent | message | 用户发送消息事件 |
|
|
||||||
| ai-response | message | AI回复消息事件 |
|
|
||||||
| unread-update | count | 未读消息数量更新事件 |
|
|
||||||
| history-loaded | messages | 历史消息加载完成事件 |
|
|
||||||
| file-preview | message | 文件预览事件 |
|
|
||||||
| audio-play | message | 音频播放事件 |
|
|
||||||
| video-play | message | 视频播放事件 |
|
|
||||||
| link-open | message | 链接打开事件 |
|
|
||||||
| product-view | message | 商品查看事件 |
|
|
||||||
| action-click | {action, message} | 操作按钮点击事件 |
|
|
||||||
| input-change | value | 输入内容变化事件 |
|
|
||||||
|
|
||||||
## 方法调用
|
|
||||||
|
|
||||||
通过组件引用可以调用以下方法:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// 获取组件引用
|
|
||||||
const aiChatFloat = this.$refs.aiChatFloat
|
|
||||||
|
|
||||||
// 打开聊天窗口
|
|
||||||
aiChatFloat.openChat()
|
|
||||||
|
|
||||||
// 关闭聊天窗口
|
|
||||||
aiChatFloat.closeChat()
|
|
||||||
|
|
||||||
// 添加消息
|
|
||||||
aiChatFloat.addMessage({
|
|
||||||
role: 'ai',
|
|
||||||
type: 'text',
|
|
||||||
content: '这是一条新消息',
|
|
||||||
read: false
|
|
||||||
})
|
|
||||||
|
|
||||||
// 清空聊天记录
|
|
||||||
aiChatFloat.clearMessages()
|
|
||||||
|
|
||||||
// 标记所有消息为已读
|
|
||||||
aiChatFloat.markAllAsRead()
|
|
||||||
```
|
|
||||||
|
|
||||||
## 配置示例
|
|
||||||
|
|
||||||
### 基本配置
|
|
||||||
|
|
||||||
```vue
|
|
||||||
<ai-chat-float
|
|
||||||
position="bottom-right"
|
|
||||||
:show-float-button="true"
|
|
||||||
:auto-open="false" />
|
|
||||||
```
|
|
||||||
|
|
||||||
### 自定义位置
|
|
||||||
|
|
||||||
```vue
|
|
||||||
<ai-chat-float
|
|
||||||
position="top-left"
|
|
||||||
:offset="{ top: '200rpx', left: '60rpx' }" />
|
|
||||||
```
|
|
||||||
|
|
||||||
### 自定义头像
|
|
||||||
|
|
||||||
```vue
|
|
||||||
<ai-chat-float
|
|
||||||
:user-avatar="/static/avatars/user.jpg"
|
|
||||||
:ai-avatar="/static/avatars/ai.jpg" />
|
|
||||||
```
|
|
||||||
|
|
||||||
### 初始消息
|
|
||||||
|
|
||||||
```vue
|
|
||||||
<ai-chat-float
|
|
||||||
:initial-messages="[
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
role: 'ai',
|
|
||||||
type: 'text',
|
|
||||||
content: '欢迎使用AI客服!',
|
|
||||||
timestamp: Date.now(),
|
|
||||||
read: false
|
|
||||||
}
|
|
||||||
]" />
|
|
||||||
```
|
|
||||||
|
|
||||||
## 样式定制
|
|
||||||
|
|
||||||
组件支持通过CSS变量进行样式定制:
|
|
||||||
|
|
||||||
```css
|
|
||||||
/* 自定义主题色 */
|
|
||||||
.ai-float-button {
|
|
||||||
--primary-color: #ff4544;
|
|
||||||
--primary-gradient: linear-gradient(135deg, #ff4544, #ff6b6b);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 自定义尺寸 */
|
|
||||||
.ai-float-button {
|
|
||||||
--button-size: 120rpx;
|
|
||||||
--icon-size: 48rpx;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 注意事项
|
|
||||||
|
|
||||||
1. **依赖组件**:本组件依赖 `ai-chat-message` 组件,请确保该组件已正确安装
|
|
||||||
2. **图标字体**:组件使用了 iconfont 图标,请确保项目中已引入相应的图标字体
|
|
||||||
3. **响应式设计**:组件已适配移动端和PC端,但在特殊场景下可能需要额外调整
|
|
||||||
4. **性能优化**:在大量消息时建议启用消息数量限制
|
|
||||||
|
|
||||||
## 演示页面
|
|
||||||
|
|
||||||
访问 `/pages/ai-chat-float/index` 查看完整的演示效果,包含所有配置选项的实时预览。
|
|
||||||
|
|
||||||
## 更新日志
|
|
||||||
|
|
||||||
### v1.0.0 (2024-11-03)
|
|
||||||
- ✨ 初始版本发布
|
|
||||||
- ✨ 支持浮动按钮和聊天弹窗
|
|
||||||
- ✨ 支持多种消息类型
|
|
||||||
- ✨ 支持流式对话
|
|
||||||
- ✨ 支持全屏模式
|
|
||||||
- ✨ 支持未读消息提示
|
|
||||||
|
|
||||||
## 技术支持
|
|
||||||
|
|
||||||
如有问题或建议,请联系开发团队。
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"component": true,
|
|
||||||
"usingComponents": {
|
|
||||||
"ai-chat-message": "../ai-chat-message/ai-chat-message"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,546 +0,0 @@
|
|||||||
<template>
|
|
||||||
<view>
|
|
||||||
<!-- 浮动AI客服按钮 -->
|
|
||||||
<view
|
|
||||||
v-if="showFloatButton"
|
|
||||||
class="ai-float-button"
|
|
||||||
:class="{ 'ai-float-button-mini': isChatOpen }"
|
|
||||||
:style="buttonStyle"
|
|
||||||
@click="toggleChat">
|
|
||||||
|
|
||||||
<!-- 按钮图标 -->
|
|
||||||
<view class="ai-float-icon">
|
|
||||||
<text class="iconfont" :class="isChatOpen ? 'icon-close' : 'icon-ai'"></text>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 未读消息小红点 -->
|
|
||||||
<view v-if="unreadCount > 0" class="ai-float-badge">
|
|
||||||
{{ unreadCount > 99 ? '99+' : unreadCount }}
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 按钮文字 -->
|
|
||||||
<view v-if="!isChatOpen" class="ai-float-text">AI客服</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- AI聊天弹窗 -->
|
|
||||||
<view
|
|
||||||
v-if="isChatOpen"
|
|
||||||
class="ai-chat-modal"
|
|
||||||
:class="{ 'ai-chat-modal-fullscreen': isFullscreen }">
|
|
||||||
|
|
||||||
<!-- 遮罩层 -->
|
|
||||||
<view class="ai-chat-mask" @click="closeChat"></view>
|
|
||||||
|
|
||||||
<!-- 聊天窗口 -->
|
|
||||||
<view class="ai-chat-window">
|
|
||||||
|
|
||||||
<!-- 聊天窗口头部 -->
|
|
||||||
<view class="ai-chat-header">
|
|
||||||
<view class="ai-chat-title">
|
|
||||||
<text class="iconfont icon-ai"></text>
|
|
||||||
<text>AI智能客服</text>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="ai-chat-actions">
|
|
||||||
<!-- 全屏/最小化按钮 -->
|
|
||||||
<button class="action-btn" @click="toggleFullscreen">
|
|
||||||
<text class="iconfont" :class="isFullscreen ? 'icon-minimize' : 'icon-fullscreen'"></text>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<!-- 关闭按钮 -->
|
|
||||||
<button class="action-btn" @click="closeChat">
|
|
||||||
<text class="iconfont icon-close"></text>
|
|
||||||
</button>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 聊天内容区域 -->
|
|
||||||
<view class="ai-chat-content">
|
|
||||||
<ai-chat-message
|
|
||||||
ref="chatMessage"
|
|
||||||
:initial-messages="chatMessages"
|
|
||||||
:user-avatar="userAvatar"
|
|
||||||
:ai-avatar="aiAvatar"
|
|
||||||
:enable-streaming="true"
|
|
||||||
@message-sent="onMessageSent"
|
|
||||||
@ai-response="onAIResponse"
|
|
||||||
@history-loaded="onHistoryLoaded"
|
|
||||||
@file-preview="onFilePreview"
|
|
||||||
@audio-play="onAudioPlay"
|
|
||||||
@video-play="onVideoPlay"
|
|
||||||
@link-open="onLinkOpen"
|
|
||||||
@product-view="onProductView"
|
|
||||||
@action-click="onActionClick"
|
|
||||||
@input-change="onInputChange" />
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import aiChatMessage from '../ai-chat-message/ai-chat-message.vue'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'ai-chat-float',
|
|
||||||
components: {
|
|
||||||
aiChatMessage
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
// 浮动按钮位置
|
|
||||||
position: {
|
|
||||||
type: String,
|
|
||||||
default: 'bottom-right', // bottom-right, bottom-left, top-right, top-left
|
|
||||||
validator: (value) => {
|
|
||||||
return ['bottom-right', 'bottom-left', 'top-right', 'top-left'].includes(value)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 按钮距离边缘的距离
|
|
||||||
offset: {
|
|
||||||
type: Object,
|
|
||||||
default: () => ({
|
|
||||||
bottom: '100rpx',
|
|
||||||
right: '40rpx',
|
|
||||||
top: '100rpx',
|
|
||||||
left: '40rpx'
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 用户头像
|
|
||||||
userAvatar: {
|
|
||||||
type: String,
|
|
||||||
default: '/static/images/default-avatar.png'
|
|
||||||
},
|
|
||||||
// AI头像
|
|
||||||
aiAvatar: {
|
|
||||||
type: String,
|
|
||||||
default: '/static/images/ai-avatar.png'
|
|
||||||
},
|
|
||||||
// 初始聊天消息
|
|
||||||
initialMessages: {
|
|
||||||
type: Array,
|
|
||||||
default: () => []
|
|
||||||
},
|
|
||||||
// 是否显示浮动按钮
|
|
||||||
showFloatButton: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
// 是否自动打开聊天窗口
|
|
||||||
autoOpen: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
isChatOpen: false, // 聊天窗口是否打开
|
|
||||||
isFullscreen: false, // 是否全屏
|
|
||||||
unreadCount: 0, // 未读消息数量
|
|
||||||
chatMessages: [], // 聊天消息列表
|
|
||||||
messageId: 0 // 消息ID计数器
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
// 按钮样式
|
|
||||||
buttonStyle() {
|
|
||||||
const style = {}
|
|
||||||
|
|
||||||
// 根据位置设置样式
|
|
||||||
if (this.position.includes('bottom')) {
|
|
||||||
style.bottom = this.offset.bottom
|
|
||||||
} else {
|
|
||||||
style.top = this.offset.top
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.position.includes('right')) {
|
|
||||||
style.right = this.offset.right
|
|
||||||
} else {
|
|
||||||
style.left = this.offset.left
|
|
||||||
}
|
|
||||||
|
|
||||||
return style
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
// 初始化聊天消息
|
|
||||||
this.chatMessages = [...this.initialMessages]
|
|
||||||
this.messageId = this.chatMessages.length
|
|
||||||
|
|
||||||
// 如果有初始消息,计算未读数量
|
|
||||||
this.updateUnreadCount()
|
|
||||||
|
|
||||||
// 如果设置了自动打开,则打开聊天窗口
|
|
||||||
if (this.autoOpen) {
|
|
||||||
this.openChat()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// 切换聊天窗口
|
|
||||||
toggleChat() {
|
|
||||||
if (this.isChatOpen) {
|
|
||||||
this.closeChat()
|
|
||||||
} else {
|
|
||||||
this.openChat()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// 打开聊天窗口
|
|
||||||
openChat() {
|
|
||||||
this.isChatOpen = true
|
|
||||||
this.unreadCount = 0 // 打开后清空未读消息
|
|
||||||
this.$emit('chat-open')
|
|
||||||
},
|
|
||||||
|
|
||||||
// 关闭聊天窗口
|
|
||||||
closeChat() {
|
|
||||||
this.isChatOpen = false
|
|
||||||
this.isFullscreen = false
|
|
||||||
this.$emit('chat-close')
|
|
||||||
},
|
|
||||||
|
|
||||||
// 切换全屏模式
|
|
||||||
toggleFullscreen() {
|
|
||||||
this.isFullscreen = !this.isFullscreen
|
|
||||||
this.$emit('fullscreen-toggle', this.isFullscreen)
|
|
||||||
},
|
|
||||||
|
|
||||||
// 更新未读消息数量
|
|
||||||
updateUnreadCount() {
|
|
||||||
// 计算AI发送的未读消息数量
|
|
||||||
this.unreadCount = this.chatMessages.filter(msg =>
|
|
||||||
msg.role === 'ai' && !msg.read
|
|
||||||
).length
|
|
||||||
|
|
||||||
this.$emit('unread-update', this.unreadCount)
|
|
||||||
},
|
|
||||||
|
|
||||||
// 发送欢迎消息
|
|
||||||
sendWelcomeMessage() {
|
|
||||||
const welcomeMessage = {
|
|
||||||
id: ++this.messageId,
|
|
||||||
role: 'ai',
|
|
||||||
type: 'text',
|
|
||||||
content: '您好!我是AI智能客服,很高兴为您服务!有什么可以帮助您的吗?',
|
|
||||||
timestamp: Date.now(),
|
|
||||||
read: false
|
|
||||||
}
|
|
||||||
|
|
||||||
this.chatMessages.push(welcomeMessage)
|
|
||||||
this.updateUnreadCount()
|
|
||||||
},
|
|
||||||
|
|
||||||
// 消息发送事件
|
|
||||||
onMessageSent(message) {
|
|
||||||
this.$emit('message-sent', message)
|
|
||||||
},
|
|
||||||
|
|
||||||
// AI回复事件
|
|
||||||
onAIResponse(message) {
|
|
||||||
// 标记为未读
|
|
||||||
message.read = false
|
|
||||||
this.updateUnreadCount()
|
|
||||||
this.$emit('ai-response', message)
|
|
||||||
},
|
|
||||||
|
|
||||||
// 历史消息加载事件
|
|
||||||
onHistoryLoaded(messages) {
|
|
||||||
this.$emit('history-loaded', messages)
|
|
||||||
},
|
|
||||||
|
|
||||||
// 文件预览事件
|
|
||||||
onFilePreview(message) {
|
|
||||||
this.$emit('file-preview', message)
|
|
||||||
},
|
|
||||||
|
|
||||||
// 音频播放事件
|
|
||||||
onAudioPlay(message) {
|
|
||||||
this.$emit('audio-play', message)
|
|
||||||
},
|
|
||||||
|
|
||||||
// 视频播放事件
|
|
||||||
onVideoPlay(message) {
|
|
||||||
this.$emit('video-play', message)
|
|
||||||
},
|
|
||||||
|
|
||||||
// 链接打开事件
|
|
||||||
onLinkOpen(message) {
|
|
||||||
this.$emit('link-open', message)
|
|
||||||
},
|
|
||||||
|
|
||||||
// 商品查看事件
|
|
||||||
onProductView(message) {
|
|
||||||
this.$emit('product-view', message)
|
|
||||||
},
|
|
||||||
|
|
||||||
// 操作点击事件
|
|
||||||
onActionClick(data) {
|
|
||||||
this.$emit('action-click', data)
|
|
||||||
},
|
|
||||||
|
|
||||||
// 输入变化事件
|
|
||||||
onInputChange(value) {
|
|
||||||
this.$emit('input-change', value)
|
|
||||||
},
|
|
||||||
|
|
||||||
// 添加消息到聊天
|
|
||||||
addMessage(message) {
|
|
||||||
this.chatMessages.push({
|
|
||||||
...message,
|
|
||||||
id: ++this.messageId,
|
|
||||||
timestamp: message.timestamp || Date.now()
|
|
||||||
})
|
|
||||||
|
|
||||||
// 如果是AI消息,增加未读计数
|
|
||||||
if (message.role === 'ai' && !message.read) {
|
|
||||||
this.updateUnreadCount()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// 清空聊天记录
|
|
||||||
clearMessages() {
|
|
||||||
this.chatMessages = []
|
|
||||||
this.messageId = 0
|
|
||||||
this.unreadCount = 0
|
|
||||||
this.$emit('messages-clear')
|
|
||||||
},
|
|
||||||
|
|
||||||
// 标记所有消息为已读
|
|
||||||
markAllAsRead() {
|
|
||||||
this.chatMessages.forEach(msg => {
|
|
||||||
if (msg.role === 'ai') {
|
|
||||||
msg.read = true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
this.updateUnreadCount()
|
|
||||||
this.$emit('messages-read')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
/* 浮动按钮样式 */
|
|
||||||
.ai-float-button {
|
|
||||||
position: fixed;
|
|
||||||
z-index: 9998;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
background: linear-gradient(135deg, #ff4544, #ff6b6b);
|
|
||||||
border-radius: 50rpx;
|
|
||||||
padding: 20rpx 30rpx;
|
|
||||||
box-shadow: 0 8rpx 30rpx rgba(255, 69, 68, 0.3);
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&.ai-float-button-mini {
|
|
||||||
padding: 20rpx;
|
|
||||||
border-radius: 50%;
|
|
||||||
|
|
||||||
.ai-float-text {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
transform: scale(0.95);
|
|
||||||
box-shadow: 0 4rpx 15rpx rgba(255, 69, 68, 0.5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.ai-float-icon {
|
|
||||||
width: 40rpx;
|
|
||||||
height: 40rpx;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
margin-right: 15rpx;
|
|
||||||
|
|
||||||
.iconfont {
|
|
||||||
font-size: 40rpx;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.ai-float-badge {
|
|
||||||
position: absolute;
|
|
||||||
top: -10rpx;
|
|
||||||
right: -10rpx;
|
|
||||||
background-color: #ff4544;
|
|
||||||
color: white;
|
|
||||||
border-radius: 30rpx;
|
|
||||||
padding: 4rpx 12rpx;
|
|
||||||
font-size: 20rpx;
|
|
||||||
font-weight: bold;
|
|
||||||
min-width: 30rpx;
|
|
||||||
text-align: center;
|
|
||||||
border: 2rpx solid white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ai-float-text {
|
|
||||||
color: white;
|
|
||||||
font-size: 28rpx;
|
|
||||||
font-weight: bold;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 聊天弹窗样式 */
|
|
||||||
.ai-chat-modal {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
z-index: 9999;
|
|
||||||
|
|
||||||
&.ai-chat-modal-fullscreen {
|
|
||||||
.ai-chat-window {
|
|
||||||
width: 100vw;
|
|
||||||
height: 100vh;
|
|
||||||
border-radius: 0;
|
|
||||||
max-width: none;
|
|
||||||
max-height: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.ai-chat-mask {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
|
||||||
animation: fadeIn 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ai-chat-window {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 150rpx;
|
|
||||||
right: 40rpx;
|
|
||||||
width: 600rpx;
|
|
||||||
height: 800rpx;
|
|
||||||
max-width: 90vw;
|
|
||||||
max-height: 80vh;
|
|
||||||
background-color: white;
|
|
||||||
border-radius: 20rpx;
|
|
||||||
box-shadow: 0 20rpx 60rpx rgba(0, 0, 0, 0.3);
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
overflow: hidden;
|
|
||||||
animation: slideUp 0.3s ease;
|
|
||||||
|
|
||||||
/* 响应式调整 */
|
|
||||||
@media (max-width: 750rpx) {
|
|
||||||
width: 90vw;
|
|
||||||
height: 70vh;
|
|
||||||
bottom: 100rpx;
|
|
||||||
right: 5vw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 聊天窗口头部 */
|
|
||||||
.ai-chat-header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
padding: 30rpx;
|
|
||||||
background: linear-gradient(135deg, #ff4544, #ff6b6b);
|
|
||||||
color: white;
|
|
||||||
|
|
||||||
.ai-chat-title {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
font-size: 32rpx;
|
|
||||||
font-weight: bold;
|
|
||||||
|
|
||||||
.iconfont {
|
|
||||||
font-size: 36rpx;
|
|
||||||
margin-right: 15rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.ai-chat-actions {
|
|
||||||
display: flex;
|
|
||||||
gap: 15rpx;
|
|
||||||
|
|
||||||
.action-btn {
|
|
||||||
width: 60rpx;
|
|
||||||
height: 60rpx;
|
|
||||||
border-radius: 50%;
|
|
||||||
background-color: rgba(255, 255, 255, 0.2);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
border: none;
|
|
||||||
|
|
||||||
.iconfont {
|
|
||||||
font-size: 28rpx;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
background-color: rgba(255, 255, 255, 0.3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 聊天内容区域 */
|
|
||||||
.ai-chat-content {
|
|
||||||
flex: 1;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
/* 确保聊天组件充满整个区域 */
|
|
||||||
::v-deep .ai-chat-container {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 动画效果 */
|
|
||||||
@keyframes fadeIn {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes slideUp {
|
|
||||||
from {
|
|
||||||
transform: translateY(100rpx) scale(0.9);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
transform: translateY(0) scale(1);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 响应式设计 */
|
|
||||||
@media (max-width: 750rpx) {
|
|
||||||
.ai-float-button {
|
|
||||||
padding: 25rpx;
|
|
||||||
|
|
||||||
&.ai-float-button-mini {
|
|
||||||
padding: 25rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ai-float-text {
|
|
||||||
font-size: 24rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.ai-chat-window {
|
|
||||||
border-radius: 15rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ai-chat-header {
|
|
||||||
padding: 25rpx;
|
|
||||||
|
|
||||||
.ai-chat-title {
|
|
||||||
font-size: 28rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,173 +0,0 @@
|
|||||||
# AI智能客服弹窗集成说明
|
|
||||||
|
|
||||||
## 概述
|
|
||||||
|
|
||||||
本方案将AI智能客服弹窗功能集成到现有的浮动导航组件 `hover-nav.vue` 中,实现了对项目影响最小的集成方案。
|
|
||||||
|
|
||||||
## 集成文件
|
|
||||||
|
|
||||||
### 1. 新增组件
|
|
||||||
- `components/ai-chat-popup/ai-chat-popup.vue` - AI聊天弹窗主组件
|
|
||||||
- `components/ai-chat-popup/ai-chat-popup.json` - 组件配置文件
|
|
||||||
|
|
||||||
### 2. 修改文件
|
|
||||||
- `components/hover-nav/hover-nav.vue` - 集成AI客服按钮和弹窗
|
|
||||||
|
|
||||||
## 功能特性
|
|
||||||
|
|
||||||
### ✅ 已实现功能
|
|
||||||
1. **浮动AI客服按钮** - 在现有浮动导航中添加AI客服按钮
|
|
||||||
2. **智能弹窗** - 点击按钮弹出AI聊天界面
|
|
||||||
3. **未读消息提示** - 显示未读消息数量小红点
|
|
||||||
4. **全屏模式** - 支持全屏/窗口模式切换
|
|
||||||
5. **响应式设计** - 适配不同屏幕尺寸
|
|
||||||
6. **复用现有组件** - 基于现有的 `ai-chat-message` 组件
|
|
||||||
|
|
||||||
### 🔧 技术特点
|
|
||||||
1. **最小化影响** - 只修改现有组件,不改变项目结构
|
|
||||||
2. **模块化设计** - 弹窗组件独立,可复用
|
|
||||||
3. **事件驱动** - 完整的生命周期事件
|
|
||||||
4. **性能优化** - 按需加载,避免资源浪费
|
|
||||||
|
|
||||||
## 使用方法
|
|
||||||
|
|
||||||
### 1. 自动集成
|
|
||||||
AI客服功能已经自动集成到 `hover-nav` 组件中,无需额外配置。
|
|
||||||
|
|
||||||
### 2. 自定义配置
|
|
||||||
如果需要自定义AI客服功能,可以修改以下配置:
|
|
||||||
|
|
||||||
```vue
|
|
||||||
<!-- 在 hover-nav.vue 中自定义AI客服按钮 -->
|
|
||||||
<view class="btn-item" @click="openAIChat" :style="{backgroundImage:'url('+(aiimg?aiimg:'')+')',backgroundSize:'100% 100%'}">
|
|
||||||
<text class="iconfont icon-ai" v-if="!aiimg"></text>
|
|
||||||
<view v-if="aiUnreadCount > 0" class="unread-badge">
|
|
||||||
<text>{{ aiUnreadCount > 99 ? '99+' : aiUnreadCount }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- AI聊天弹窗 -->
|
|
||||||
<ai-chat-popup
|
|
||||||
v-if="showAIChat"
|
|
||||||
:show="showAIChat"
|
|
||||||
@update:show="showAIChat = $event"
|
|
||||||
@unread-update="onUnreadUpdate"
|
|
||||||
@message-sent="onAIMessageSent"
|
|
||||||
@ai-response="onAIResponse" />
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. 事件监听
|
|
||||||
可以监听以下事件来处理业务逻辑:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// 未读消息更新
|
|
||||||
onUnreadUpdate(count) {
|
|
||||||
this.aiUnreadCount = count
|
|
||||||
// 可以在这里添加未读消息处理逻辑
|
|
||||||
},
|
|
||||||
|
|
||||||
// AI消息发送事件
|
|
||||||
onAIMessageSent(message) {
|
|
||||||
console.log('AI消息发送:', message)
|
|
||||||
// 可以在这里添加消息发送后的处理逻辑
|
|
||||||
},
|
|
||||||
|
|
||||||
// AI回复事件
|
|
||||||
onAIResponse(message) {
|
|
||||||
console.log('AI回复:', message)
|
|
||||||
// 可以在这里添加AI回复后的处理逻辑
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 配置选项
|
|
||||||
|
|
||||||
### AI聊天弹窗组件参数
|
|
||||||
|
|
||||||
| 参数 | 类型 | 默认值 | 说明 |
|
|
||||||
|------|------|--------|------|
|
|
||||||
| show | Boolean | false | 是否显示弹窗 |
|
|
||||||
| userAvatar | String | '/static/images/default-avatar.png' | 用户头像 |
|
|
||||||
| aiAvatar | String | '/static/images/ai-avatar.png' | AI头像 |
|
|
||||||
|
|
||||||
### 事件
|
|
||||||
|
|
||||||
| 事件名 | 参数 | 说明 |
|
|
||||||
|--------|------|------|
|
|
||||||
| popup-open | - | 弹窗打开事件 |
|
|
||||||
| popup-close | - | 弹窗关闭事件 |
|
|
||||||
| unread-update | count | 未读消息数量更新 |
|
|
||||||
| message-sent | message | 消息发送事件 |
|
|
||||||
| ai-response | message | AI回复事件 |
|
|
||||||
|
|
||||||
## 样式定制
|
|
||||||
|
|
||||||
### 1. AI客服按钮样式
|
|
||||||
```css
|
|
||||||
.btn-item {
|
|
||||||
/* 按钮基础样式 */
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.unread-badge {
|
|
||||||
/* 未读消息小红点样式 */
|
|
||||||
position: absolute;
|
|
||||||
top: -5rpx;
|
|
||||||
right: -5rpx;
|
|
||||||
background-color: #ff4544;
|
|
||||||
color: white;
|
|
||||||
border-radius: 20rpx;
|
|
||||||
min-width: 30rpx;
|
|
||||||
height: 30rpx;
|
|
||||||
font-size: 20rpx;
|
|
||||||
line-height: 30rpx;
|
|
||||||
text-align: center;
|
|
||||||
padding: 0 8rpx;
|
|
||||||
z-index: 1;
|
|
||||||
box-shadow: 0 2rpx 10rpx rgba(255, 69, 68, 0.3);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. 弹窗样式
|
|
||||||
弹窗样式在 `ai-chat-popup.vue` 中定义,可以根据需要自定义。
|
|
||||||
|
|
||||||
## 注意事项
|
|
||||||
|
|
||||||
1. **图标资源** - 需要确保AI图标文件存在,默认路径为 `/static/images/ai-icon.png`
|
|
||||||
2. **组件依赖** - AI聊天弹窗依赖于现有的 `ai-chat-message` 组件
|
|
||||||
3. **z-index** - 弹窗的z-index设置为1000,确保在其他元素之上
|
|
||||||
4. **响应式适配** - 弹窗已经做了移动端适配,但可能需要根据具体项目调整
|
|
||||||
|
|
||||||
## 兼容性
|
|
||||||
|
|
||||||
- ✅ H5
|
|
||||||
- ✅ 微信小程序
|
|
||||||
- ✅ APP
|
|
||||||
- ✅ 其他小程序平台
|
|
||||||
|
|
||||||
## 后续优化建议
|
|
||||||
|
|
||||||
1. **图标优化** - 可以添加更精美的AI图标
|
|
||||||
2. **动画效果** - 可以添加更流畅的打开/关闭动画
|
|
||||||
3. **主题定制** - 支持暗色主题等
|
|
||||||
4. **多语言** - 支持国际化
|
|
||||||
5. **性能优化** - 懒加载等优化措施
|
|
||||||
|
|
||||||
## 问题排查
|
|
||||||
|
|
||||||
如果AI客服功能无法正常工作,请检查:
|
|
||||||
|
|
||||||
1. 组件路径是否正确
|
|
||||||
2. 依赖的 `ai-chat-message` 组件是否存在
|
|
||||||
3. 图标资源路径是否正确
|
|
||||||
4. 控制台是否有错误信息
|
|
||||||
|
|
||||||
## 总结
|
|
||||||
|
|
||||||
本集成方案成功将AI智能客服功能添加到现有的浮动导航组件中,实现了:
|
|
||||||
|
|
||||||
- ✅ 对项目影响最小
|
|
||||||
- ✅ 功能完整可用
|
|
||||||
- ✅ 代码结构清晰
|
|
||||||
- ✅ 易于维护扩展
|
|
||||||
|
|
||||||
现在您可以在任何使用 `hover-nav` 组件的页面中享受AI智能客服功能!
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"component": true,
|
|
||||||
"usingComponents": {
|
|
||||||
"ai-chat-message": "../ai-chat-message/ai-chat-message"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,310 +0,0 @@
|
|||||||
<template>
|
|
||||||
<!-- AI聊天弹窗 -->
|
|
||||||
<view v-if="showPopup" class="ai-chat-popup">
|
|
||||||
<!-- 遮罩层 -->
|
|
||||||
<view class="popup-mask" @click="closePopup"></view>
|
|
||||||
|
|
||||||
<!-- 弹窗内容 -->
|
|
||||||
<view class="popup-content" :class="{ 'full-screen': isFullScreen }">
|
|
||||||
<!-- 弹窗头部 -->
|
|
||||||
<view class="popup-header">
|
|
||||||
<view class="header-left">
|
|
||||||
<view class="ai-avatar">🤖</view>
|
|
||||||
<view class="header-info">
|
|
||||||
<text class="ai-name">AI智能客服</text>
|
|
||||||
<text class="ai-status">{{ isOnline ? '在线' : '离线' }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="header-right">
|
|
||||||
<button class="header-btn" @click="toggleFullScreen">
|
|
||||||
<text class="icon-text">{{ isFullScreen ? '↗' : '↘' }}</text>
|
|
||||||
</button>
|
|
||||||
<button class="header-btn" @click="closePopup">
|
|
||||||
<text class="icon-text">×</text>
|
|
||||||
</button>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 聊天消息区域 -->
|
|
||||||
<view class="chat-area">
|
|
||||||
<!-- 使用ai-chat-message组件 -->
|
|
||||||
<ai-chat-message
|
|
||||||
ref="chatMessage"
|
|
||||||
:initial-messages="messages"
|
|
||||||
:user-avatar="userAvatar"
|
|
||||||
:ai-avatar="aiAvatar"
|
|
||||||
:show-load-more="false"
|
|
||||||
@message-sent="onMessageSent"
|
|
||||||
@ai-response="onAIResponse"
|
|
||||||
@unread-update="onUnreadUpdate"
|
|
||||||
@popup-open="onPopupOpen"
|
|
||||||
@popup-close="onPopupClose"
|
|
||||||
class="chat-message-component" />
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import aiChatMessage from '@/components/ai-chat-message/ai-chat-message.vue'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'ai-chat-popup',
|
|
||||||
components: {
|
|
||||||
aiChatMessage
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
// 是否显示弹窗
|
|
||||||
show: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
// 用户头像
|
|
||||||
userAvatar: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
// AI头像
|
|
||||||
aiAvatar: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
showPopup: false,
|
|
||||||
isFullScreen: false,
|
|
||||||
isOnline: true,
|
|
||||||
unreadCount: 0,
|
|
||||||
messages: []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
show(newVal) {
|
|
||||||
this.showPopup = newVal
|
|
||||||
if (newVal) {
|
|
||||||
this.unreadCount = 0
|
|
||||||
this.$store.commit('setAiUnreadCount', 0)
|
|
||||||
this.$emit('popup-open')
|
|
||||||
} else {
|
|
||||||
this.$emit('popup-close')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
// 打开弹窗
|
|
||||||
openPopup() {
|
|
||||||
this.showPopup = true
|
|
||||||
this.$emit('update:show', true)
|
|
||||||
},
|
|
||||||
|
|
||||||
// 关闭弹窗
|
|
||||||
closePopup() {
|
|
||||||
this.showPopup = false
|
|
||||||
this.$emit('update:show', false)
|
|
||||||
this.isFullScreen = false
|
|
||||||
},
|
|
||||||
|
|
||||||
// 切换全屏模式
|
|
||||||
toggleFullScreen() {
|
|
||||||
this.isFullScreen = !this.isFullScreen
|
|
||||||
this.$emit('fullscreen-toggle', this.isFullScreen)
|
|
||||||
},
|
|
||||||
|
|
||||||
// 消息发送事件处理
|
|
||||||
onMessageSent(message) {
|
|
||||||
this.$emit('message-sent', message)
|
|
||||||
},
|
|
||||||
|
|
||||||
// AI回复事件处理
|
|
||||||
onAIResponse(message) {
|
|
||||||
this.$emit('ai-response', message)
|
|
||||||
|
|
||||||
// 如果弹窗关闭,增加未读消息计数
|
|
||||||
if (!this.showPopup) {
|
|
||||||
this.unreadCount++
|
|
||||||
this.$store.commit('setAiUnreadCount', this.unreadCount)
|
|
||||||
this.$emit('unread-update', this.unreadCount)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// 未读消息更新事件处理
|
|
||||||
onUnreadUpdate(count) {
|
|
||||||
this.unreadCount = count
|
|
||||||
this.$emit('unread-update', count)
|
|
||||||
},
|
|
||||||
|
|
||||||
// 弹窗打开事件处理
|
|
||||||
onPopupOpen() {
|
|
||||||
this.$emit('popup-open')
|
|
||||||
},
|
|
||||||
|
|
||||||
// 弹窗关闭事件处理
|
|
||||||
onPopupClose() {
|
|
||||||
this.$emit('popup-close')
|
|
||||||
},
|
|
||||||
|
|
||||||
// 添加未读消息
|
|
||||||
addUnreadMessage() {
|
|
||||||
if (!this.showPopup) {
|
|
||||||
this.unreadCount++
|
|
||||||
this.$emit('unread-update', this.unreadCount)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// 清空未读消息
|
|
||||||
clearUnreadMessages() {
|
|
||||||
this.unreadCount = 0
|
|
||||||
this.$emit('unread-update', 0)
|
|
||||||
},
|
|
||||||
|
|
||||||
// 添加消息到聊天记录
|
|
||||||
addMessage(message) {
|
|
||||||
this.messages.push(message)
|
|
||||||
},
|
|
||||||
|
|
||||||
// 清空聊天记录
|
|
||||||
clearMessages() {
|
|
||||||
this.messages = []
|
|
||||||
},
|
|
||||||
|
|
||||||
// 获取聊天消息组件实例
|
|
||||||
getChatMessageInstance() {
|
|
||||||
return this.$refs.chatMessage
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.ai-chat-popup {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
z-index: 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popup-mask {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
.popup-content {
|
|
||||||
position: absolute;
|
|
||||||
right: 30rpx;
|
|
||||||
bottom: 300rpx;
|
|
||||||
width: 600rpx;
|
|
||||||
height: 800rpx;
|
|
||||||
background-color: white;
|
|
||||||
border-radius: 20rpx;
|
|
||||||
box-shadow: 0 10rpx 50rpx rgba(0, 0, 0, 0.3);
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
|
|
||||||
&.full-screen {
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.popup-header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
padding: 30rpx;
|
|
||||||
border-bottom: 2rpx solid #eeeeee;
|
|
||||||
background-color: #f8f8f8;
|
|
||||||
border-radius: 20rpx 20rpx 0 0;
|
|
||||||
|
|
||||||
.header-left {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.ai-avatar {
|
|
||||||
width: 80rpx;
|
|
||||||
height: 80rpx;
|
|
||||||
border-radius: 50%;
|
|
||||||
margin-right: 20rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header-info {
|
|
||||||
.ai-name {
|
|
||||||
display: block;
|
|
||||||
font-size: 32rpx;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ai-status {
|
|
||||||
display: block;
|
|
||||||
font-size: 24rpx;
|
|
||||||
color: #666;
|
|
||||||
margin-top: 5rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.header-right {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.header-btn {
|
|
||||||
width: 60rpx;
|
|
||||||
height: 60rpx;
|
|
||||||
border-radius: 50%;
|
|
||||||
background-color: rgba(0, 0, 0, 0.1);
|
|
||||||
margin-left: 15rpx;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
.iconfont {
|
|
||||||
font-size: 28rpx;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
background-color: rgba(0, 0, 0, 0.2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-area {
|
|
||||||
flex: 1;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
.chat-message-component {
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 响应式适配 */
|
|
||||||
@media (max-width: 750rpx) {
|
|
||||||
.popup-content {
|
|
||||||
right: 20rpx;
|
|
||||||
left: 20rpx;
|
|
||||||
width: auto;
|
|
||||||
height: 70vh;
|
|
||||||
bottom: 20rpx;
|
|
||||||
|
|
||||||
&.full-screen {
|
|
||||||
right: 0;
|
|
||||||
left: 0;
|
|
||||||
bottom: 0;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
Reference in New Issue
Block a user