chore:智能客服加了表情
This commit is contained in:
@@ -211,12 +211,17 @@
|
|||||||
@confirm="sendMessage"
|
@confirm="sendMessage"
|
||||||
@input="onInput" />
|
@input="onInput" />
|
||||||
|
|
||||||
|
<!-- Emoji按钮 -->
|
||||||
|
<button class="emoji-btn" @click="toggleEmojiPanel">
|
||||||
|
<text class="iconfont icon-smile">😊</text>
|
||||||
|
</button>
|
||||||
|
|
||||||
<!-- 发送按钮 -->
|
<!-- 发送按钮 -->
|
||||||
<button
|
<button
|
||||||
class="send-btn"
|
class="send-btn"
|
||||||
:class="{ disabled: !inputText.trim() }"
|
:class="{ disabled: !canSendMessage }"
|
||||||
@click="sendMessage"
|
@click="sendMessage"
|
||||||
:disabled="!inputText.trim()">
|
:disabled="!canSendMessage">
|
||||||
<text>发送</text>
|
<text>发送</text>
|
||||||
</button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
@@ -261,6 +266,28 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<!-- Emoji面板 -->
|
||||||
|
<view v-if="showEmojiPanel" class="emoji-popup">
|
||||||
|
<view class="emoji-mask" @click="hideEmojiPanel"></view>
|
||||||
|
<view class="emoji-panel">
|
||||||
|
<view class="emoji-header">
|
||||||
|
<text>选择表情</text>
|
||||||
|
<button class="close-btn" @click="hideEmojiPanel">
|
||||||
|
<text class="iconfont icon-close"></text>
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
|
<scroll-view class="emoji-grid" scroll-y>
|
||||||
|
<view
|
||||||
|
v-for="(emoji, index) in emojiList"
|
||||||
|
:key="index"
|
||||||
|
class="emoji-item"
|
||||||
|
@click="insertEmoji(emoji)">
|
||||||
|
<text class="emoji-text">{{ emoji }}</text>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
<!-- 语音输入面板 -->
|
<!-- 语音输入面板 -->
|
||||||
<view v-if="enalbeVoicePanelShow" class="voice-popup">
|
<view v-if="enalbeVoicePanelShow" class="voice-popup">
|
||||||
<view class="voice-mask" @click="hideVoicePanel"></view>
|
<view class="voice-mask" @click="hideVoicePanel"></view>
|
||||||
@@ -411,6 +438,8 @@ export default {
|
|||||||
messageId: 0,
|
messageId: 0,
|
||||||
showToolsPanel: false,
|
showToolsPanel: false,
|
||||||
enalbeVoicePanelShow: false,
|
enalbeVoicePanelShow: false,
|
||||||
|
showEmojiPanel: false,
|
||||||
|
emojiList: ['😀','😃','😄','😁','😆','😅','🤣','😂','🙂','🙃','😉','😊','😇','🥰','😍','🤩','😘','😗','😚','😋','😛','😜','🤪','😝','🤑','🤗','🤭','🤫','🤔','🤐','🤨','😐','😑','😶','😏','😒','🙄','😬','🤥','😌','😔','😪','🤤','😴','😷','🤒','🤕','🤢','🤮','🤧','🥵','🥶','🥴','😵','🤯','🤠','🥳','😎','🤓','🧐','😕','😟','🙁','😮','😯','😲','😳','🥺','😦','😧','😨','😰','😥','😢','😭','😱','😖','😣','😞','😓','😩','😫','🥱','😤','😡','😠','🤬','😈','👿','💀','💩','👻','👽','🤖','🎃','😺','😸','😹','😻','😼','😽','🙀','😿','😾','👋','🤚','🖐','✋','🖖','👌','🤏','✌','🤞','🤟','🤘','🤙','👈','👉','👆','🖕','👇','☝','👍','👎','✊','👊','🤛','🤜','👏','🙌','👐','🤲','🤝','🙏','✍','💅','🤳','💪','💗','💓','💕','💖','💝','💞','💘','💌','💟','💛','💙','💜','🖤','💔','💢','💣','💥','💫','💦','💨','👁','👀','👅','👄','👂','👃','👶','👦','👧','👨','👩','👴','👵','👱','👲','👳','👴','👵','👶','👼','👸','🎅','🤶','🦸','🦹','🧙','🧚','🧛','🧜','🧝','🧞','🧟','🦄','🐶','🐱','🐭','🐹','🐰','🦊','🐻','🐼','🐨','🐯','🦁','🐮','🐷','🐸','🐵','🙈','🙉','🙊','🐒','🐔','🐧','🐦','🐤','🐣','🐥','🦆','🦅','🦉','🦇','🐺','🐗','🐴','🦄','🐝','🐛','🦋','🐌','🐞','🐜','🦟','🦗','🕷','🦂','🐢','🐍','🦎','🦖','🦕','🐙','🦑','🦐','🦞','🦀','🐡','🐠','🐟','🐬','🐳','🐋','🦈','🐊','🐅','🐆','🦓','🦍','🦧','🐘','🦛','🦏','🐪','🐫','🦒','🦘','🐃','🐂','🐄','🐎','🐖','🐏','🐑','🐐','🐓','🦃','🦚','🦜','🦢','🦩','🕊','🐕','🐩','🐈','🐓','🐇','🐁','🐀','🐿','🦔','🐾','🐉','🐲'],
|
||||||
streamingMessage: null,
|
streamingMessage: null,
|
||||||
streamInterval: null,
|
streamInterval: null,
|
||||||
streamContent: '',
|
streamContent: '',
|
||||||
@@ -461,6 +490,11 @@ export default {
|
|||||||
return {
|
return {
|
||||||
bottom: this.keyboardHeight > 0 ? this.keyboardHeight + 'px' : '0px'
|
bottom: this.keyboardHeight > 0 ? this.keyboardHeight + 'px' : '0px'
|
||||||
};
|
};
|
||||||
|
},
|
||||||
|
canSendMessage() {
|
||||||
|
const hasContent = this.inputText && this.inputText.trim() !== ''
|
||||||
|
const hasEmoji = this.containsEmoji(this.inputText)
|
||||||
|
return hasContent || hasEmoji
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onShow() {
|
onShow() {
|
||||||
@@ -812,13 +846,17 @@ async loadChatHistoryIfExist() {
|
|||||||
|
|
||||||
// 发送消息
|
// 发送消息
|
||||||
async sendMessage() {
|
async sendMessage() {
|
||||||
if (!this.inputText.trim()) return
|
// 确保有内容或表情
|
||||||
|
const hasContent = this.inputText && this.inputText.trim() !== ''
|
||||||
|
const hasEmoji = this.containsEmoji(this.inputText)
|
||||||
|
|
||||||
|
if (!hasContent && !hasEmoji) return
|
||||||
|
|
||||||
const userMessage = {
|
const userMessage = {
|
||||||
id: ++this.messageId,
|
id: ++this.messageId,
|
||||||
role: 'user',
|
role: 'user',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
content: this.inputText.trim(),
|
content: this.inputText,
|
||||||
timestamp: Date.now()
|
timestamp: Date.now()
|
||||||
}
|
}
|
||||||
this.shouldScrollToBottom = true
|
this.shouldScrollToBottom = true
|
||||||
@@ -846,10 +884,11 @@ async loadChatHistoryIfExist() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 使用AI服务获取回复
|
// 使用AI服务获取回复
|
||||||
|
const enhancedMessage = this.enhanceEmojiMessage(userMessage.content)
|
||||||
if (this.enableStreaming) {
|
if (this.enableStreaming) {
|
||||||
await this.sendStreamMessage(userMessage.content)
|
await this.sendStreamMessage(enhancedMessage)
|
||||||
} else {
|
} else {
|
||||||
await this.sendNormalMessage(userMessage.content)
|
await this.sendNormalMessage(enhancedMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -1251,6 +1290,22 @@ async loadChatHistoryIfExist() {
|
|||||||
this.showToolsPanel = false
|
this.showToolsPanel = false
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 切换Emoji面板
|
||||||
|
toggleEmojiPanel() {
|
||||||
|
this.showEmojiPanel = !this.showEmojiPanel
|
||||||
|
},
|
||||||
|
|
||||||
|
// 隐藏Emoji面板
|
||||||
|
hideEmojiPanel() {
|
||||||
|
this.showEmojiPanel = false
|
||||||
|
},
|
||||||
|
|
||||||
|
// 插入Emoji
|
||||||
|
insertEmoji(emoji) {
|
||||||
|
this.inputText += emoji
|
||||||
|
this.hideEmojiPanel()
|
||||||
|
},
|
||||||
|
|
||||||
// 显示语音面板
|
// 显示语音面板
|
||||||
showVoicePanel() {
|
showVoicePanel() {
|
||||||
this.enalbeVoicePanelShow = true
|
this.enalbeVoicePanelShow = true
|
||||||
@@ -1641,6 +1696,193 @@ async loadChatHistoryIfExist() {
|
|||||||
this.historyOffset = 0
|
this.historyOffset = 0
|
||||||
// 触发清空事件
|
// 触发清空事件
|
||||||
this.$emit('messages-cleared')
|
this.$emit('messages-cleared')
|
||||||
|
},
|
||||||
|
|
||||||
|
// 检测字符串中是否包含表情
|
||||||
|
containsEmoji(str) {
|
||||||
|
const emojiReg = /[\u{1f300}-\u{1f9ff}\u{1f1e0}-\u{1f1ff}\u{2600}-\u{26ff}\u{2700}-\u{27bf}\u{1f900}-\u{1f9ff}\u{1f600}-\u{1f64f}\u{1f680}-\u{1f6ff}\u{200d}\u{2640}-\u{2642}\u{2300}-\u{23ff}\u{2b50}-\u{2bff}]/gu
|
||||||
|
return emojiReg.test(str)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 根据表情生成适当的提示文本,帮助 AI 更好地理解
|
||||||
|
enhanceEmojiMessage(content) {
|
||||||
|
// 常见表情的含义映射
|
||||||
|
const emojiResponses = {
|
||||||
|
'😀': '[开心]',
|
||||||
|
'😂': '[大笑]',
|
||||||
|
'😊': '[微笑]',
|
||||||
|
'❤️': '[爱心]',
|
||||||
|
'👍': '[点赞]',
|
||||||
|
'😭': '[哭泣]',
|
||||||
|
'🙏': '[感谢/拜托]',
|
||||||
|
'😍': '[喜欢]',
|
||||||
|
'🎉': '[庆祝]',
|
||||||
|
'🤔': '[思考]',
|
||||||
|
'😅': '[尴尬]',
|
||||||
|
'😁': '[开心]',
|
||||||
|
'🥰': '[喜爱]',
|
||||||
|
'😘': '[飞吻]',
|
||||||
|
'😏': '[坏笑]',
|
||||||
|
'🥳': '[庆祝]',
|
||||||
|
'😔': '[难过]',
|
||||||
|
'😢': '[哭泣]',
|
||||||
|
'😤': '[生气]',
|
||||||
|
'😴': '[困]',
|
||||||
|
'🤗': '[拥抱]',
|
||||||
|
'🙂': '[微笑]',
|
||||||
|
'😃': '[开心]',
|
||||||
|
'😄': '[大笑]',
|
||||||
|
'😆': '[开心]',
|
||||||
|
'😇': '[天使]',
|
||||||
|
'🤩': '[惊喜]',
|
||||||
|
'😋': '[好吃]',
|
||||||
|
'😛': '[调皮]',
|
||||||
|
'😜': '[调皮]',
|
||||||
|
'🤪': '[搞怪]',
|
||||||
|
'😝': '[开心]',
|
||||||
|
'🤑': '[发财]',
|
||||||
|
'🤭': '[害羞]',
|
||||||
|
'🤫': '[嘘]',
|
||||||
|
'🤐': '[闭嘴]',
|
||||||
|
'🤨': '[疑惑]',
|
||||||
|
'😐': '[无语]',
|
||||||
|
'😑': '[无语]',
|
||||||
|
'😶': '[沉默]',
|
||||||
|
'😒': '[不屑]',
|
||||||
|
'🙄': '[白眼]',
|
||||||
|
'😬': '[尴尬]',
|
||||||
|
'🤥': '[说谎]',
|
||||||
|
'😌': '[安心]',
|
||||||
|
'😪': '[困]',
|
||||||
|
'🤤': '[流口水]',
|
||||||
|
'😷': '[生病]',
|
||||||
|
'🤒': '[发烧]',
|
||||||
|
'🤕': '[受伤]',
|
||||||
|
'🤢': '[恶心]',
|
||||||
|
'🤮': '[呕吐]',
|
||||||
|
'🤧': '[感冒]',
|
||||||
|
'🥵': '[热]',
|
||||||
|
'🥶': '[冷]',
|
||||||
|
'🥴': '[头晕]',
|
||||||
|
'😵': '[晕]',
|
||||||
|
'🤯': '[爆炸]',
|
||||||
|
'🤠': '[酷]',
|
||||||
|
'😎': '[酷]',
|
||||||
|
'🤓': '[书呆子]',
|
||||||
|
'🧐': '[疑惑]',
|
||||||
|
'😕': '[困惑]',
|
||||||
|
'😟': '[担心]',
|
||||||
|
'🙁': '[难过]',
|
||||||
|
'😮': '[惊讶]',
|
||||||
|
'😯': '[惊讶]',
|
||||||
|
'😲': '[震惊]',
|
||||||
|
'😳': '[脸红]',
|
||||||
|
'🥺': '[恳求]',
|
||||||
|
'😦': '[惊讶]',
|
||||||
|
'😧': '[惊讶]',
|
||||||
|
'😨': '[害怕]',
|
||||||
|
'😰': '[紧张]',
|
||||||
|
'😥': '[失望]',
|
||||||
|
'😱': '[恐惧]',
|
||||||
|
'😖': '[困扰]',
|
||||||
|
'😣': '[痛苦]',
|
||||||
|
'😞': '[难过]',
|
||||||
|
'😓': '[汗]',
|
||||||
|
'😩': '[累]',
|
||||||
|
'😫': '[累]',
|
||||||
|
'🥱': '[困]',
|
||||||
|
'😡': '[愤怒]',
|
||||||
|
'😠': '[生气]',
|
||||||
|
'🤬': '[咒骂]',
|
||||||
|
'😈': '[恶魔]',
|
||||||
|
'👿': '[生气]',
|
||||||
|
'💀': '[骷髅]',
|
||||||
|
'💩': '[便便]',
|
||||||
|
'👻': '[鬼]',
|
||||||
|
'👽': '[外星人]',
|
||||||
|
'🤖': '[机器人]',
|
||||||
|
'🎃': '[万圣节]',
|
||||||
|
'😺': '[开心猫]',
|
||||||
|
'😸': '[微笑猫]',
|
||||||
|
'😹': '[大笑猫]',
|
||||||
|
'😻': '[花痴猫]',
|
||||||
|
'😼': '[得意猫]',
|
||||||
|
'😽': '[亲亲猫]',
|
||||||
|
'🙀': '[惊讶猫]',
|
||||||
|
'😿': '[哭泣猫]',
|
||||||
|
'😾': '[生气猫]',
|
||||||
|
'👋': '[挥手]',
|
||||||
|
'🤚': '[举手]',
|
||||||
|
'🖐': '[手掌]',
|
||||||
|
'✋': '[手掌]',
|
||||||
|
'🖖': '[V]',
|
||||||
|
'👌': '[OK]',
|
||||||
|
'🤏': '[捏]',
|
||||||
|
'✌️': '[耶]',
|
||||||
|
'🤞': '[好运]',
|
||||||
|
'🤟': '[爱你]',
|
||||||
|
'🤘': '[摇滚]',
|
||||||
|
'🤙': '[打电话]',
|
||||||
|
'👈': '[左边]',
|
||||||
|
'👉': '[右边]',
|
||||||
|
'👆': '[上边]',
|
||||||
|
'🖕': '[竖中指]',
|
||||||
|
'👇': '[下边]',
|
||||||
|
'☝': '[向上]',
|
||||||
|
'👎': '[鄙视]',
|
||||||
|
'✊': '[拳头]',
|
||||||
|
'👊': '[拳头]',
|
||||||
|
'🤛': '[左拳]',
|
||||||
|
'🤜': '[右拳]',
|
||||||
|
'👏': '[鼓掌]',
|
||||||
|
'🙌': '[举手庆祝]',
|
||||||
|
'👐': '[张开手]',
|
||||||
|
'🤲': '[摊手]',
|
||||||
|
'🤝': '[握手]',
|
||||||
|
'✍️': '[写字]',
|
||||||
|
'💅': '[美甲]',
|
||||||
|
'🤳': '[自拍]',
|
||||||
|
'💪': '[肌肉]',
|
||||||
|
'💗': '[爱心]',
|
||||||
|
'💓': '[心跳]',
|
||||||
|
'💕': '[两颗心]',
|
||||||
|
'💖': '[闪亮心]',
|
||||||
|
'💝': '[礼物心]',
|
||||||
|
'💞': '[旋转心]',
|
||||||
|
'💘': '[丘比特]',
|
||||||
|
'💌': '[情书]',
|
||||||
|
'💟': '[心形]',
|
||||||
|
'💛': '[黄心]',
|
||||||
|
'💙': '[蓝心]',
|
||||||
|
'💜': '[紫心]',
|
||||||
|
'🖤': '[黑心]',
|
||||||
|
'💔': '[心碎]',
|
||||||
|
'💢': '[愤怒]',
|
||||||
|
'💣': '[炸弹]',
|
||||||
|
'💥': '[爆炸]',
|
||||||
|
'💫': '[头晕]',
|
||||||
|
'💦': '[汗]',
|
||||||
|
'💨': '[风]',
|
||||||
|
'👁️': '[眼睛]',
|
||||||
|
'👀': '[看]',
|
||||||
|
'👅': '[舌头]',
|
||||||
|
'👄': '[嘴巴]',
|
||||||
|
'👂': '[耳朵]',
|
||||||
|
'👃': '[鼻子]'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果是纯表情消息,添加一些提示
|
||||||
|
if (this.containsEmoji(content) && !content.match(/[\u4e00-\u9fa5a-zA-Z]/)) {
|
||||||
|
let enhancedMessage = content
|
||||||
|
// 为表情添加描述
|
||||||
|
for (let emoji in emojiResponses) {
|
||||||
|
if (content.includes(emoji)) {
|
||||||
|
enhancedMessage += ` (${emojiResponses[emoji]})`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return enhancedMessage
|
||||||
|
}
|
||||||
|
return content
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2382,6 +2624,25 @@ $radius-lg: 36rpx;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Emoji按钮 */
|
||||||
|
.emoji-btn {
|
||||||
|
width: 72rpx;
|
||||||
|
height: 72rpx;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
margin-left: 12rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border: none;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
.iconfont {
|
||||||
|
font-size: 36rpx;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* 发送按钮 - 微信聊天样式 */
|
/* 发送按钮 - 微信聊天样式 */
|
||||||
.send-btn {
|
.send-btn {
|
||||||
width: 120rpx;
|
width: 120rpx;
|
||||||
@@ -3232,4 +3493,104 @@ $radius-lg: 36rpx;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Emoji面板 */
|
||||||
|
.emoji-popup {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 999;
|
||||||
|
|
||||||
|
.emoji-mask {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: rgba(0, 0, 0, 0.4);
|
||||||
|
backdrop-filter: blur(6rpx);
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-panel {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background-color: white;
|
||||||
|
border-radius: $radius-lg $radius-lg 0 0;
|
||||||
|
padding: 32rpx;
|
||||||
|
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.08);
|
||||||
|
max-height: 60vh;
|
||||||
|
|
||||||
|
.emoji-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 24rpx;
|
||||||
|
border-bottom: 2rpx solid #f0f4f8;
|
||||||
|
padding-bottom: 16rpx;
|
||||||
|
|
||||||
|
text {
|
||||||
|
font-size: 34rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: $color-text;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-btn {
|
||||||
|
width: 56rpx;
|
||||||
|
height: 56rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: $bg-main;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
border: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #e8edf3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconfont {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: $color-text-light;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(8, 1fr);
|
||||||
|
gap: 16rpx;
|
||||||
|
max-height: 40vh;
|
||||||
|
|
||||||
|
.emoji-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 64rpx;
|
||||||
|
height: 64rpx;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #e8edf3;
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
background-color: #d8dde3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-text {
|
||||||
|
font-size: 36rpx;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user