1.完成app端新的聊天页面效果
This commit is contained in:
@@ -29,16 +29,41 @@
|
|||||||
<!-- 用户消息纯文本 -->
|
<!-- 用户消息纯文本 -->
|
||||||
<text v-else-if="item.content">{{ item.content }}</text>
|
<text v-else-if="item.content">{{ item.content }}</text>
|
||||||
|
|
||||||
<!-- AI操作区域 -->
|
<!-- AI特有内容 -->
|
||||||
<view v-if="item.sender === 'ai'" class="ai-actions">
|
<view v-if="item.sender === 'ai'" class="ai-hint">
|
||||||
<text class="ai-text">回答由AI生成</text>
|
<!-- 引用来源部分 -->
|
||||||
<view class="icon-group">
|
<view v-if="item.retrieverResources && item.retrieverResources.length" class="reference-section">
|
||||||
<img src="/static/good.svg"
|
<text class="reference-title">引用来源:</text>
|
||||||
:class="['btn-icon', { 'btn-icon-active': item.feedback && item.feedback.rating === 'like' }]"
|
<!-- 遍历合并后的引用资源 -->
|
||||||
@click="handleThumbUp(item.messageId, index)" />
|
<view v-for="(groupedRef, groupIdx) in getGroupedReferences(item.retrieverResources)" :key="groupIdx" class="reference-item-wrapper">
|
||||||
<img src="/static/tread.svg"
|
<!-- 可点击的文档名 -->
|
||||||
:class="['btn-icon', { 'btn-icon-active': item.feedback && item.feedback.rating === 'dislike' }]"
|
<text class="doc-name-link" @click="toggleSingleReference(index, groupIdx)">
|
||||||
@click="handleThumbDown(item.messageId, index)" />
|
{{ groupedRef.document_name }}
|
||||||
|
</text>
|
||||||
|
|
||||||
|
<!-- 展开的详情(仅当前项) -->
|
||||||
|
<view v-if="showSingleReference[index] && showSingleReference[index][groupIdx]" class="reference-details-item">
|
||||||
|
<!-- 分段显示内容 -->
|
||||||
|
<view v-for="(ref, refIdx) in groupedRef.references" :key="refIdx" class="reference-segment">
|
||||||
|
<text class="reference-meta">{{ ref.name }}({{ ref.document_name }})</text>
|
||||||
|
<text class="reference-content" v-if="ref.content">{{ ref.content }}</text>
|
||||||
|
<view v-if="refIdx < groupedRef.references.length - 1" class="reference-divider"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- AI操作区域 -->
|
||||||
|
<view class="ai-actions">
|
||||||
|
<text class="ai-text">AI回答也可能会犯错。请核查重要信息。</text>
|
||||||
|
<view class="icon-group">
|
||||||
|
<img src="/static/good.svg"
|
||||||
|
:class="['btn-icon', { 'btn-icon-active': item.feedback && item.feedback.rating === 'like' }]"
|
||||||
|
@click="handleThumbUp(item.messageId, index)" />
|
||||||
|
<img src="/static/tread.svg"
|
||||||
|
:class="['btn-icon', { 'btn-icon-active': item.feedback && item.feedback.rating === 'dislike' }]"
|
||||||
|
@click="handleThumbDown(item.messageId, index)" />
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -102,8 +127,11 @@ export default {
|
|||||||
// 分页加载
|
// 分页加载
|
||||||
isLoadingHistory: false,
|
isLoadingHistory: false,
|
||||||
hasMoreHistory: true,
|
hasMoreHistory: true,
|
||||||
earliestMessageId: null
|
earliestMessageId: null,
|
||||||
};
|
|
||||||
|
// 引用信息展示控制
|
||||||
|
showSingleReference: {}
|
||||||
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
onLoad() {
|
onLoad() {
|
||||||
@@ -169,7 +197,8 @@ export default {
|
|||||||
messageId: 'ai-' + msg.id,
|
messageId: 'ai-' + msg.id,
|
||||||
conversationId: msg.conversation_id,
|
conversationId: msg.conversation_id,
|
||||||
created_at: msg.created_at,
|
created_at: msg.created_at,
|
||||||
feedback: msg.feedback || null // 添加反馈状态
|
feedback: msg.feedback || null, // 添加反馈状态
|
||||||
|
retrieverResources: msg.retriever_resources || [] // 添加引用资源
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -276,7 +305,8 @@ export default {
|
|||||||
messageId: 'ai-' + msg.id,
|
messageId: 'ai-' + msg.id,
|
||||||
conversationId: msg.conversation_id,
|
conversationId: msg.conversation_id,
|
||||||
created_at: msg.created_at,
|
created_at: msg.created_at,
|
||||||
feedback: msg.feedback || null // 添加反馈状态
|
feedback: msg.feedback || null, // 添加反馈状态
|
||||||
|
retrieverResources: msg.retriever_resources || [] // 添加引用资源
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -552,6 +582,45 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将引用资源按文档名称分组合并
|
||||||
|
* @param {Array} references - 原始引用资源数组
|
||||||
|
* @returns {Array} 分组后的引用资源数组
|
||||||
|
*/
|
||||||
|
getGroupedReferences(references) {
|
||||||
|
if (!references || !references.length) return [];
|
||||||
|
|
||||||
|
const grouped = {};
|
||||||
|
|
||||||
|
// 按文档名称分组
|
||||||
|
references.forEach(ref => {
|
||||||
|
const docName = ref.document_name;
|
||||||
|
if (!grouped[docName]) {
|
||||||
|
grouped[docName] = {
|
||||||
|
document_name: docName,
|
||||||
|
references: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
grouped[docName].references.push(ref);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 转换为数组
|
||||||
|
return Object.values(grouped);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换单个引用的显示状态
|
||||||
|
* @param {number} msgIdx - 消息索引
|
||||||
|
* @param {number} refIdx - 引用索引
|
||||||
|
*/
|
||||||
|
toggleSingleReference(msgIdx, refIdx) {
|
||||||
|
if (!this.showSingleReference[msgIdx]) {
|
||||||
|
this.$set(this.showSingleReference, msgIdx, {});
|
||||||
|
}
|
||||||
|
const current = this.showSingleReference[msgIdx][refIdx];
|
||||||
|
this.$set(this.showSingleReference[msgIdx], refIdx, !current);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 显示提示
|
* 显示提示
|
||||||
*/
|
*/
|
||||||
@@ -644,6 +713,94 @@ export default {
|
|||||||
border: 1px solid #eee;
|
border: 1px solid #eee;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* AI提示区域 */
|
||||||
|
.ai-hint {
|
||||||
|
margin-top: 8px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 引用来源部分 */
|
||||||
|
.reference-section {
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
padding: 8px;
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
border-radius: 6px;
|
||||||
|
border-left: 3px solid #007aff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reference-title {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 每个引用项容器 */
|
||||||
|
.reference-item-wrapper {
|
||||||
|
margin-top: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 可点击文档名 */
|
||||||
|
.doc-name-link {
|
||||||
|
color: #007aff;
|
||||||
|
text-decoration: underline;
|
||||||
|
margin-right: 8px;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 引用详情 */
|
||||||
|
.reference-details-item {
|
||||||
|
margin-top: 6px;
|
||||||
|
padding: 8px;
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid #e0e0e0;
|
||||||
|
font-size: 11px;
|
||||||
|
color: #555;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reference-meta {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reference-content {
|
||||||
|
color: #444;
|
||||||
|
line-height: 1.6;
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 引用分段样式 */
|
||||||
|
.reference-segment {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
padding: 8px;
|
||||||
|
background-color: #fafafa;
|
||||||
|
border-left: 3px solid #007aff;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reference-segment:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 分段分隔线 */
|
||||||
|
.reference-divider {
|
||||||
|
height: 2px;
|
||||||
|
background: linear-gradient(to right, #e8e8e8, #f5f5f5, #e8e8e8);
|
||||||
|
margin: 12px 0;
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
/* AI操作区域 */
|
/* AI操作区域 */
|
||||||
.ai-actions {
|
.ai-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -656,6 +813,10 @@ export default {
|
|||||||
|
|
||||||
.ai-text {
|
.ai-text {
|
||||||
color: #999;
|
color: #999;
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 1.4;
|
||||||
|
flex: 1;
|
||||||
|
margin-right: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-group {
|
.icon-group {
|
||||||
@@ -701,13 +862,14 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.send-button {
|
.send-button {
|
||||||
padding: 8px 16px;
|
padding: 6px 12px;
|
||||||
background-color: #007aff;
|
background-color: #007aff;
|
||||||
color: white;
|
color: white;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 20px;
|
border-radius: 16px;
|
||||||
font-size: 14px;
|
font-size: 12px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
min-width: 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.send-button:disabled {
|
.send-button:disabled {
|
||||||
|
Reference in New Issue
Block a user