|
|
@@ -4,8 +4,8 @@
|
|
|
<div v-show="showSearch" class="mb-[10px]">
|
|
|
<el-card shadow="hover">
|
|
|
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
|
|
- <el-form-item label="会话唯一标识" prop="sessionId">
|
|
|
- <el-input v-model="queryParams.sessionId" placeholder="请输入会话唯一标识" clearable @keyup.enter="handleQuery" />
|
|
|
+ <el-form-item label="会话标识" prop="sessionId">
|
|
|
+ <el-input v-model="queryParams.sessionId" placeholder="请输入会话标识" clearable @keyup.enter="handleQuery" />
|
|
|
</el-form-item>
|
|
|
<el-form-item label="客服ID" prop="agentId">
|
|
|
<el-input v-model="queryParams.agentId" placeholder="请输入客服ID" clearable @keyup.enter="handleQuery" />
|
|
|
@@ -13,26 +13,24 @@
|
|
|
<el-form-item label="客户电话" prop="customerPhone">
|
|
|
<el-input v-model="queryParams.customerPhone" placeholder="请输入客户电话" clearable @keyup.enter="handleQuery" />
|
|
|
</el-form-item>
|
|
|
- <el-form-item label="会话状态" prop="status">
|
|
|
- <el-select v-model="queryParams.status" placeholder="请选择会话状态" clearable>
|
|
|
- <el-option label="进行中" value="0" />
|
|
|
- <el-option label="已结束" value="1" />
|
|
|
- </el-select>
|
|
|
+ <el-form-item label="创建人" prop="userId">
|
|
|
+ <el-input v-model="queryParams.userId" placeholder="请输入创建人ID" clearable @keyup.enter="handleQuery" />
|
|
|
</el-form-item>
|
|
|
- <el-form-item label="会话开始时间" prop="startTime">
|
|
|
+ <div style="width: 100%"></div>
|
|
|
+ <el-form-item label="开始时间" prop="startTime">
|
|
|
<el-date-picker clearable
|
|
|
v-model="queryParams.startTime"
|
|
|
type="date"
|
|
|
value-format="YYYY-MM-DD"
|
|
|
- placeholder="请选择会话开始时间"
|
|
|
+ placeholder="请选择开始时间"
|
|
|
/>
|
|
|
</el-form-item>
|
|
|
- <el-form-item label="会话结束时间" prop="endTime">
|
|
|
+ <el-form-item label="结束时间" prop="endTime">
|
|
|
<el-date-picker clearable
|
|
|
v-model="queryParams.endTime"
|
|
|
type="date"
|
|
|
value-format="YYYY-MM-DD"
|
|
|
- placeholder="请选择会话结束时间"
|
|
|
+ placeholder="请选择结束时间"
|
|
|
/>
|
|
|
</el-form-item>
|
|
|
<el-form-item>
|
|
|
@@ -59,27 +57,17 @@
|
|
|
|
|
|
<el-table v-loading="loading" border :data="sessionList" @selection-change="handleSelectionChange">
|
|
|
<el-table-column type="selection" width="55" align="center" />
|
|
|
- <el-table-column label="会话ID" align="center" prop="id" v-if="false" />
|
|
|
+ <el-table-column label="会话ID" align="center" prop="id" width="80" />
|
|
|
<el-table-column label="会话标识" align="center" prop="sessionId" width="200" show-overflow-tooltip />
|
|
|
<el-table-column label="客服ID" align="center" prop="agentId" />
|
|
|
<el-table-column label="客户电话" align="center" prop="customerPhone" />
|
|
|
- <el-table-column label="消息总数" align="center" prop="messageCount" />
|
|
|
- <el-table-column label="用户消息数" align="center" prop="userMessageCount" />
|
|
|
- <el-table-column label="客服消息数" align="center" prop="agentMessageCount" />
|
|
|
- <el-table-column label="对话时长(秒)" align="center" prop="duration" />
|
|
|
- <el-table-column label="会话状态" align="center" prop="status">
|
|
|
- <template #default="scope">
|
|
|
- <el-tag :type="scope.row.status === '0' ? 'warning' : 'success'">
|
|
|
- {{ scope.row.status === '0' ? '进行中' : '已结束' }}
|
|
|
- </el-tag>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- <el-table-column label="会话开始时间" align="center" prop="startTime" width="180">
|
|
|
+ <el-table-column label="创建人" align="center" prop="userId" />
|
|
|
+ <el-table-column label="开始时间" align="center" prop="startTime" width="180">
|
|
|
<template #default="scope">
|
|
|
<span>{{ parseTime(scope.row.startTime, '{y}-{m}-{d} {h}:{i}') }}</span>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column label="会话结束时间" align="center" prop="endTime" width="180">
|
|
|
+ <el-table-column label="结束时间" align="center" prop="endTime" width="180">
|
|
|
<template #default="scope">
|
|
|
<span>{{ parseTime(scope.row.endTime, '{y}-{m}-{d} {h}:{i}') }}</span>
|
|
|
</template>
|
|
|
@@ -105,21 +93,24 @@
|
|
|
<el-descriptions-item label="会话标识">{{ sessionDetail.sessionId }}</el-descriptions-item>
|
|
|
<el-descriptions-item label="客服ID">{{ sessionDetail.agentId }}</el-descriptions-item>
|
|
|
<el-descriptions-item label="客户电话">{{ sessionDetail.customerPhone }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="会话状态">
|
|
|
- <el-tag :type="sessionDetail.status === '0' ? 'warning' : 'success'">
|
|
|
- {{ sessionDetail.status === '0' ? '进行中' : '已结束' }}
|
|
|
- </el-tag>
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item label="消息总数">{{ sessionDetail.messageCount }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="用户消息数">{{ sessionDetail.userMessageCount }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="客服消息数">{{ sessionDetail.agentMessageCount }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="对话时长">{{ sessionDetail.duration }}秒</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="创建人">{{ sessionDetail.userId }}</el-descriptions-item>
|
|
|
<el-descriptions-item label="开始时间">{{ parseTime(sessionDetail.startTime) }}</el-descriptions-item>
|
|
|
<el-descriptions-item label="结束时间">{{ parseTime(sessionDetail.endTime) }}</el-descriptions-item>
|
|
|
</el-descriptions>
|
|
|
<el-divider content-position="left">对话内容</el-divider>
|
|
|
<div class="conversation-content">
|
|
|
- <pre>{{ sessionDetail.conversationJson }}</pre>
|
|
|
+ <div v-if="parsedConversation.length > 0" class="message-list">
|
|
|
+ <div v-for="(msg, index) in parsedConversation" :key="index" class="message-item">
|
|
|
+ <div class="message-header">
|
|
|
+ <span class="message-role" :class="msg.role === 'user' ? 'user-role' : 'assistant-role'">
|
|
|
+ {{ msg.role === 'user' ? 'User' : 'AI' }}
|
|
|
+ </span>
|
|
|
+ <span class="message-time">{{ formatTimestamp(msg.timestamp) }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="message-content">{{ msg.content }}</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div v-else class="empty-conversation">暂无对话内容</div>
|
|
|
</div>
|
|
|
<template #footer>
|
|
|
<div class="dialog-footer">
|
|
|
@@ -159,7 +150,7 @@ const data = reactive<PageData<any, SessionQuery>>({
|
|
|
sessionId: undefined,
|
|
|
agentId: undefined,
|
|
|
customerPhone: undefined,
|
|
|
- status: undefined,
|
|
|
+ userId: undefined,
|
|
|
startTime: undefined,
|
|
|
endTime: undefined
|
|
|
},
|
|
|
@@ -168,6 +159,33 @@ const data = reactive<PageData<any, SessionQuery>>({
|
|
|
|
|
|
const { queryParams } = toRefs(data);
|
|
|
|
|
|
+/** 解析对话内容 */
|
|
|
+const parsedConversation = computed(() => {
|
|
|
+ if (!sessionDetail.value.conversationJson) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ return JSON.parse(sessionDetail.value.conversationJson);
|
|
|
+ } catch (e) {
|
|
|
+ console.error('解析对话内容失败:', e);
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+/** 格式化时间戳 */
|
|
|
+const formatTimestamp = (timestamp: string) => {
|
|
|
+ if (!timestamp) return '';
|
|
|
+ const date = new Date(parseInt(timestamp));
|
|
|
+ return date.toLocaleString('zh-CN', {
|
|
|
+ year: 'numeric',
|
|
|
+ month: '2-digit',
|
|
|
+ day: '2-digit',
|
|
|
+ hour: '2-digit',
|
|
|
+ minute: '2-digit',
|
|
|
+ second: '2-digit'
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
/** 查询会话列表 */
|
|
|
const getList = async () => {
|
|
|
loading.value = true;
|
|
|
@@ -232,9 +250,62 @@ onMounted(() => {
|
|
|
border-radius: 4px;
|
|
|
}
|
|
|
|
|
|
-.conversation-content pre {
|
|
|
+.message-list {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 12px;
|
|
|
+}
|
|
|
+
|
|
|
+.message-item {
|
|
|
+ background: white;
|
|
|
+ padding: 12px;
|
|
|
+ border-radius: 8px;
|
|
|
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
|
|
+}
|
|
|
+
|
|
|
+.message-header {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ padding-bottom: 6px;
|
|
|
+ border-bottom: 1px solid #e5e7eb;
|
|
|
+}
|
|
|
+
|
|
|
+.message-role {
|
|
|
+ font-weight: 600;
|
|
|
+ font-size: 14px;
|
|
|
+ padding: 2px 8px;
|
|
|
+ border-radius: 4px;
|
|
|
+}
|
|
|
+
|
|
|
+.user-role {
|
|
|
+ background-color: #dbeafe;
|
|
|
+ color: #1e40af;
|
|
|
+}
|
|
|
+
|
|
|
+.assistant-role {
|
|
|
+ background-color: #dcfce7;
|
|
|
+ color: #166534;
|
|
|
+}
|
|
|
+
|
|
|
+.message-time {
|
|
|
+ font-size: 12px;
|
|
|
+ color: #6b7280;
|
|
|
+}
|
|
|
+
|
|
|
+.message-content {
|
|
|
+ font-size: 14px;
|
|
|
+ line-height: 1.6;
|
|
|
+ color: #374151;
|
|
|
white-space: pre-wrap;
|
|
|
word-wrap: break-word;
|
|
|
- margin: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.empty-conversation {
|
|
|
+ text-align: center;
|
|
|
+ color: #9ca3af;
|
|
|
+ padding: 20px;
|
|
|
+ font-size: 14px;
|
|
|
}
|
|
|
</style>
|