Commit 2dcda17f authored by 水玉婷's avatar 水玉婷
Browse files

feat:会话添加推荐会话功能

parent bab845f6
...@@ -83,21 +83,30 @@ ...@@ -83,21 +83,30 @@
</a-button> </a-button>
</div> </div>
</div> </div>
<!-- 操作按钮 --> <!-- 会话结束 -->
<div class="operation-box" v-if="msg.messageType === 'received' && msg.recordId"> <div v-if="msg.messageType === 'received' && msg.recordId" class="conversation-end">
<div class="operation-buttons"> <!-- 推荐会话列表 -->
<button class="operation-btn copy-btn" @click="handleCopy(msg)" title="复制"> <div v-if="msg.showRecommendations !== false && msg.recommendations && msg.recommendations.length > 0" class="recommendation-list">
<copy-outlined /> <div v-for="(item, i) in msg.recommendations" :key="i" class="recommendation-item" @click="handleRecommendationClick(msg, item)">
</button> <span class="recommendation-title">{{ item.title }}</span>
<button class="operation-btn like-btn" @click="handleLike(msg)" title="赞"> </div>
<like-outlined /> </div>
</button> <!-- 操作按钮 -->
<button class="operation-btn dislike-btn" @click="handleDislike(msg)" title="踩"> <div class="operation-box" v-if="msg.messageType === 'received' && msg.recordId">
<dislike-outlined /> <div class="operation-buttons">
</button> <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> </div>
</div>
</div> </div>
</div> </div>
...@@ -341,22 +350,22 @@ const validateMessageParams = (type: MessageType, params: MessageParams): boolea ...@@ -341,22 +350,22 @@ const validateMessageParams = (type: MessageType, params: MessageParams): boolea
// 统一发送消息函数 // 统一发送消息函数
const sendMessage = async (type: MessageType = 'text', params: MessageParams = {}) => { const sendMessage = async (type: MessageType = 'text', params: MessageParams = {}) => {
// 如果消息文本为空且是文本类型,则延迟1秒后模拟折线图消息进行测试 //如果消息文本为空且是文本类型,则延迟1秒后模拟折线图消息进行测试
// if (type === 'text' && !messageText.value.trim() && !params.message) { if (type === 'text' && !messageText.value.trim() && !params.message) {
// loading.value = true; loading.value = true;
// console.log('📊 检测到空消息,1秒后发送折线图测试...'); console.log('📊 检测到空消息,1秒后发送折线图测试...');
// setTimeout(() => { // setTimeout(() => {
// simulateLineChartMessage(); // simulateLineChartMessage();
// loading.value = false; // loading.value = false;
// }, 1000); // }, 1000);
// setTimeout(() => { setTimeout(() => {
// simulateTips(); simulateTips();
// loading.value = false; loading.value = false;
// }, 2000); }, 2000);
// return; return;
// } }
loading.value = true; loading.value = true;
...@@ -504,6 +513,14 @@ const retrySendMessage = async (messageIndex: number) => { ...@@ -504,6 +513,14 @@ const retrySendMessage = async (messageIndex: number) => {
}); });
}; };
// 处理推荐会话点击
const handleRecommendationClick = (message: Message, item: any) => {
// 隐藏推荐信息列表
message.showRecommendations = false;
// 直接发送推荐会话内容
sendMessage('text', { message: item.title });
};
// 处理消息点击 - 将消息内容放到输入框 // 处理消息点击 - 将消息内容放到输入框
const handleMessageClick = (message: Message, block: any) => { const handleMessageClick = (message: Message, block: any) => {
// 只处理文字消息,不处理音频、图表等特殊消息 // 只处理文字消息,不处理音频、图表等特殊消息
...@@ -826,26 +843,22 @@ const simulateLineChartMessage = () => { ...@@ -826,26 +843,22 @@ const simulateLineChartMessage = () => {
const simulateTips = () => { const simulateTips = () => {
console.log('模拟总结消息'); console.log('模拟总结消息');
const simulatedMessage = { const simulatedMessage = {
message: `# 四川公司费用总额分析📊 message: {
recordId:'33333',
## 数据概览 options:[
- **2025年1月**:费用总额为 **10,682,961.54元**,同比减少 **1,557,818.80元**(约 **12.72%**)。 {
- **2025年2月**:费用总额为 **25,086,103.67元**,同比减少 **1,444,015.52元**(约 **5.44%**)。 title: '出差标准',
- **2025年3月**:费用总额为 **39,060,157.77元**,同比增加 **526,502.57元**(约 **1.36%**)。 },
{
## 问题分析 title: '2025年2月',
- **费用总额同比波动较大**,1月和2月均出现同比下降,3月略有回升,但整体仍低于去年同期水平,可能与成本控制或业务结构调整有关。 },
- **缺乏年初及预算数据**,无法判断费用总额是否符合预算目标,影响进一步分析。 {
- **费用增长趋势不明确**,3月虽有回升,但增幅较小,需关注后续月份数据以判断是否为短期波动。 title: '2025年3月',
}
## 建议 ]
- **加强费用预算管理**,明确费用控制目标。 },
- **深入分析费用结构**,识别费用增长或下降的主要驱动因素。
- **补充年初及预算数据**,以便进行更全面的费用对比分析。
🔍 **结论**:四川公司费用总额呈现波动下降趋势,需进一步分析费用结构及预算执行情况,以优化费用管理。`,
status: 3, // 图表数据 status: 3, // 图表数据
type: 6 // 总结消息 type: 7 // 总结消息
} }
......
...@@ -311,6 +311,9 @@ li { ...@@ -311,6 +311,9 @@ li {
} }
// 操作按钮样式 // 操作按钮样式
.conversation-end{
margin-top: 12px;
}
.operation-box { .operation-box {
margin-top: 12px; margin-top: 12px;
display: flex; display: flex;
...@@ -921,6 +924,36 @@ li { ...@@ -921,6 +924,36 @@ li {
// =============================================
// 推荐会话样式
// =============================================
.recommendation-list {
width: 100%;
max-width: 100%;
.recommendation-item {
display: flex;
align-items: center;
margin-bottom: 16px;
margin-bottom: 16px;
.recommendation-title {
font-size: 14px;
color: @gray-7;
line-height:22px;
background: #F2F3F5;
padding: 4px 6px;
gap: 2px;
border-radius: 2px;
cursor: pointer;
&:hover {
background-color: @blue-light-1;
}
}
}
}
// ============================================= // =============================================
// Tips消息样式 // Tips消息样式
// ============================================= // =============================================
...@@ -931,7 +964,7 @@ li { ...@@ -931,7 +964,7 @@ li {
margin: 8px 0 -1px; margin: 8px 0 -1px;
padding: 12px 16px; padding: 12px 16px;
border-bottom: none; border-bottom: none;
box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.05); box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.05);
border-radius: 8px 8px 0 0; border-radius: 8px 8px 0 0;
position: relative; position: relative;
background-color: @blue-light-2; background-color: @blue-light-2;
......
...@@ -54,6 +54,9 @@ export interface Message { ...@@ -54,6 +54,9 @@ export interface Message {
originalContent?: string; originalContent?: string;
// 消息类型(用于重发) // 消息类型(用于重发)
originalMessageType?: 'text' | 'audio'; originalMessageType?: 'text' | 'audio';
// 推荐会话相关属性
recommendations?: any[];
showRecommendations?: boolean;
} }
// SSE数据类型定义 // SSE数据类型定义
...@@ -290,6 +293,33 @@ export class ContentTemplateService { ...@@ -290,6 +293,33 @@ export class ContentTemplateService {
case 3: // 图表数据 case 3: // 图表数据
if (updatedResponse) { if (updatedResponse) {
switch (contentType) { switch (contentType) {
case 0: // 普通文本内容
// 检查最后一个块是否是普通文本块,如果是则合并,否则创建新块
const isLastText = isLastBlockText(updatedResponse.contentBlocks);
if (isLastText) {
// 合并到现有的普通文本块
const lastTextIndex = getLastTextBlockIndex(updatedResponse.contentBlocks);
if (lastTextIndex !== -1) {
updatedResponse.contentBlocks[lastTextIndex].content =
mergeTextContent(
updatedResponse.contentBlocks[lastTextIndex].content,
messageContent
);
}
} else {
// 创建新的内容块
updatedBlockIndex = updatedResponse.contentBlocks.length;
updatedResponse.contentBlocks.push({
content: this.templates.text(messageContent),
hasThinkBox: false,
thinkContent: '',
thinkBoxExpanded: false,
});
}
break;
case 2: case 2:
// 图表数据处理 // 图表数据处理
updatedResponse.contentBlocks.push({ updatedResponse.contentBlocks.push({
...@@ -380,19 +410,15 @@ export class ContentTemplateService { ...@@ -380,19 +410,15 @@ export class ContentTemplateService {
}); });
} }
break; break;
case 7: // 推荐会话数据
if (updatedResponse) {
default: // 默认处理 updatedResponse.recommendations = messageContent?.options || [];
updatedResponse.contentBlocks.push({ updatedResponse.showRecommendations = true;
content: this.templates.text(messageContent || ''), }
hasThinkBox: false, break;
thinkContent: '', }
thinkBoxExpanded: false,
});
break;
} }
} break;
break;
case 10: // 思考开始 case 10: // 思考开始
...@@ -421,31 +447,35 @@ export class ContentTemplateService { ...@@ -421,31 +447,35 @@ export class ContentTemplateService {
case 11: // 思考结束 case 11: // 思考结束
if (updatedResponse && updatedBlockIndex !== -1 && updatedResponse.contentBlocks[updatedBlockIndex]) { if (updatedResponse && updatedBlockIndex !== -1 && updatedResponse.contentBlocks[updatedBlockIndex]) {
const currentThinkContent = updatedResponse.contentBlocks[updatedBlockIndex].thinkContent;
// 计算思考用时 // 计算思考用时
const thinkingTime = this.thinkingStartTime ? Math.round((Date.now() - this.thinkingStartTime) / 1000) : 0; const thinkingTime = this.thinkingStartTime ? Math.round((Date.now() - this.thinkingStartTime) / 1000) : 0;
// 对于历史数据,直接显示"已完成思考",不显示具体用时 // 对于历史数据,直接显示"已完成思考",不显示具体用时
const thinkingTimeText = isHistoryData ? '已完成思考' : (thinkingTime > 0 ? '已完成思考' : '已完成思考'); const thinkingTimeText = isHistoryData ? '已完成思考' : (thinkingTime > 0 ? '已完成思考' : '已完成思考');
updatedResponse.contentBlocks[updatedBlockIndex].thinkContent = currentThinkContent; // 如果message有内容,更新思考内容
if (messageContent && messageContent.trim() !== '') {
updatedResponse.contentBlocks[updatedBlockIndex].thinkContent = messageContent;
}
// 添加思考时长信息到内容块中,供前端模板使用 // 添加思考时长信息到内容块中,供前端模板使用
updatedResponse.contentBlocks[updatedBlockIndex].thinkingTime = thinkingTime; updatedResponse.contentBlocks[updatedBlockIndex].thinkingTime = thinkingTime;
updatedResponse.contentBlocks[updatedBlockIndex].thinkingTimeText = thinkingTimeText; updatedResponse.contentBlocks[updatedBlockIndex].thinkingTimeText = thinkingTimeText;
updatedResponse.contentBlocks[updatedBlockIndex].hasThinkBox = true; updatedResponse.contentBlocks[updatedBlockIndex].hasThinkBox = true;
// 思考结束后保持展开状态 // 思考结束后保持展开状态
// updatedResponse.contentBlocks[updatedBlockIndex].thinkBoxExpanded = defaultThinkBoxExpanded; updatedResponse.contentBlocks[updatedBlockIndex].thinkBoxExpanded = true;
updatedResponse.contentBlocks[updatedBlockIndex].thinkBoxExpanded = true;
// 重置思考开始时间 // 重置思考开始时间
this.thinkingStartTime = null; this.thinkingStartTime = null;
} }
// 确保思考模式被正确关闭
updatedIsThinking = false; updatedIsThinking = false;
updatedBlockIndex = -1;
break; break;
case 20: // 初始连接回传信息 case 20: // 初始连接回传信息
if (updatedResponse) { if (updatedResponse) {
recordId = messageContent?.recordId || '';
updatedResponse.contentBlocks.push({ updatedResponse.contentBlocks.push({
content: this.templates.text(messageContent?.words || ''), content: this.templates.text(messageContent?.words || ''),
hasThinkBox: false, hasThinkBox: false,
......
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