Commit 41747d53 authored by 水玉婷's avatar 水玉婷
Browse files

feat:添加复制功能

parent 958ab12c
......@@ -83,14 +83,20 @@
</a-button>
</div>
</div>
<!-- 操作按钮 -->
<!-- <div class="operation-box" v-if="msg.recordId">
<p>
<span>提示词Token数量:{{ msg.promptTokens }}</span>
<span>答复Token数量:{{ msg.completionTokens }}</span>
<span>总Token数量: {{ msg.totalTokens }}</span>
</p>
</div> -->
<!-- 操作按钮 -->
<div class="operation-box" v-if="msg.messageType === 'received' && msg.recordId">
<div class="operation-buttons">
<button class="operation-btn copy-btn" @click="handleCopy(msg)" title="复制">
<copy-outlined />
</button>
<button class="operation-btn like-btn" @click="handleLike(msg)" title="赞">
<like-outlined />
</button>
<button class="operation-btn dislike-btn" @click="handleDislike(msg)" title="踩">
<dislike-outlined />
</button>
</div>
</div>
</div>
</div>
</div>
......@@ -120,7 +126,7 @@
import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue';
import dayjs from 'dayjs';
import { markdownTemplate, isLastBlockMarkdown, getLastMarkdownBlockIndex, mergeMarkdownContent } from './utils/markdownTemplate';
import { SendOutlined, UserOutlined, ReloadOutlined, CopyOutlined } from '@ant-design/icons-vue';
import { SendOutlined, UserOutlined, ReloadOutlined, CopyOutlined, LikeOutlined, DislikeOutlined } from '@ant-design/icons-vue';
import { message as antdMessage } from 'ant-design-vue';
import defaultAvatar from '@/assets/logo.png';
import rightIcon from '@/assets/right.svg'
......@@ -506,8 +512,6 @@ const retrySendMessage = async (messageIndex: number) => {
});
};
// 处理消息点击 - 将消息内容放到输入框
const handleMessageClick = (message: Message, block: any) => {
// 只处理文字消息,不处理音频、图表等特殊消息
......@@ -516,34 +520,9 @@ const handleMessageClick = (message: Message, block: any) => {
}
try {
// 提取消息中的文本内容
let textToInput = '';
if (message.contentBlocks && message.contentBlocks.length > 0) {
message.contentBlocks.forEach(block => {
// 跳过非文字内容块
if (block.audioData || block.chartData) {
return;
}
if (block.content) {
// 移除HTML标签,只保留纯文本
const textContent = block.content.replace(/<[^>]*>/g, '').trim();
if (textContent) {
textToInput += textContent + '\n';
}
}
});
}
// 如果没有内容,使用原始内容
if (!textToInput.trim() && message.originalContent) {
textToInput = message.originalContent;
}
if (textToInput.trim()) {
// 将内容设置到输入框
messageText.value = textToInput.trim();
// 直接使用原始内容
if (message.originalContent) {
messageText.value = message.originalContent;
// 自动调整输入框高度
adjustTextareaHeight();
// 聚焦到输入框
......@@ -628,6 +607,67 @@ const toggleThinkBox = (messageIndex: number, blockIndex: number) => {
!messages.value[messageIndex].contentBlocks[blockIndex].thinkBoxExpanded;
}
};
// 复制消息内容
const handleCopy = async (msg: Message) => {
try {
let textToCopy = '';
// 遍历所有内容块
msg.contentBlocks.forEach(block => {
if (block.chartData) {
// 如果是表格内容,复制description
textToCopy += block.chartData.description || '';
} else if (block.content) {
// 检查是否是iframe内容
if (block.content.includes('message-iframe')) {
// 提取iframe的src属性
const srcMatch = block.content.match(/src="([^"]+)"/);
if (srcMatch && srcMatch[1]) {
textToCopy += srcMatch[1] + '\n';
}
} else {
// 其他内容复制content
// 移除HTML标签,保留纯文本
const textContent = block.content.replace(/<[^>]*>/g, '').trim();
if (textContent) {
textToCopy += textContent + '\n';
}
}
}
});
// 如果没有内容,使用原始内容
if (!textToCopy.trim() && msg.originalContent) {
textToCopy = msg.originalContent;
}
if (textToCopy.trim()) {
// 使用Clipboard API复制到剪贴板
await navigator.clipboard.writeText(textToCopy.trim());
antdMessage.success('内容已复制到剪贴板');
} else {
antdMessage.warning('没有可复制的内容');
}
} catch (error) {
console.error('复制失败:', error);
antdMessage.error('复制失败,请手动复制');
}
};
// 点赞消息
const handleLike = (msg: Message) => {
console.log('点赞消息:', msg.recordId);
antdMessage.success('已点赞');
// 这里可以添加实际的点赞API调用
};
// 踩消息
const handleDislike = (msg: Message) => {
console.log('踩消息:', msg.recordId);
antdMessage.success('已踩');
// 这里可以添加实际的踩API调用
};
// 处理按键事件
const handleKeyPress = (e: KeyboardEvent) => {
if (e.key === 'Enter' && !e.shiftKey) {
......
......@@ -301,6 +301,57 @@ li {
margin: 20px 0px 8px;
}
// 操作按钮样式
.operation-box {
margin-top: 12px;
display: flex;
.operation-buttons {
display: flex;
gap: 6px;
align-items: center;
.operation-btn {
border: none;
background: @gray-2;
color: @gray-7;
padding: 6px;
border-radius: 4px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
transition: all 0.3s ease;
&:hover {
background: @gray-3;
color: @gray-7;
transform: translateY(-1px);
}
&:active {
transform: translateY(0);
}
&.copy-btn:hover {
background: @blue-light-1;
color: @primary-color;
}
&.like-btn:hover {
background: #f6ffed;
color: @success-color;
}
&.dislike-btn:hover {
background: #fff2f0;
color: @error-color;
}
}
}
}
// 失败消息样式
.message-failed-wrapper {
margin-top: 12px;
......@@ -620,19 +671,6 @@ li {
}
}
.operation-box {
margin-top: 6px;
p {
color: @gray-5;
span {
margin-right: 15px;
}
}
}
// =============================================
// iframe消息样式
......@@ -1244,19 +1282,6 @@ li {
}
}
.operation-box {
margin-top: 6px;
p {
color: @gray-5;
font-size: 16px;
span {
margin-right: 15px;
}
}
}
@keyframes waveAnimation {
0%,
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment