|
|
@@ -650,6 +650,16 @@
|
|
|
<span class="meta-item node">
|
|
|
<i class="el-icon-s-operation"></i>
|
|
|
当前节点:<strong>{{ record.currentNodeTypeName }}</strong>
|
|
|
+
|
|
|
+ <el-button
|
|
|
+ size="mini"
|
|
|
+ type="primary"
|
|
|
+ plain
|
|
|
+ icon="el-icon-chat-dot-round"
|
|
|
+ style="margin-left: 8px;"
|
|
|
+ @click.stop="handleShowContent(record)">
|
|
|
+ 查看对话内容
|
|
|
+ </el-button>
|
|
|
<!-- 外呼未执行标识 -->
|
|
|
<el-button
|
|
|
v-if="record.waitCallNode"
|
|
|
@@ -757,6 +767,44 @@
|
|
|
:workflow-instance-id="manualCallDialog.workflowInstanceId"
|
|
|
/>
|
|
|
</el-dialog>
|
|
|
+
|
|
|
+ <el-dialog
|
|
|
+ title="对话内容"
|
|
|
+ :visible.sync="contentDialog.visible"
|
|
|
+ width="900px"
|
|
|
+ append-to-body
|
|
|
+ class="content-dialog"
|
|
|
+ >
|
|
|
+ <div class="content-dialog-wrapper">
|
|
|
+ <div class="content-dialog-header">
|
|
|
+ <span>客户姓名:{{ contentDialog.customerName || '-' }}</span>
|
|
|
+ <span style="margin-left: 20px;">手机号:{{ contentDialog.customerPhone || '-' }}</span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div v-if="!contentDialog.content" class="content-empty">
|
|
|
+ 暂无对话内容
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="chat-container">
|
|
|
+ <div
|
|
|
+ v-for="(msg, index) in parseContentList(contentDialog.content)"
|
|
|
+ :key="index"
|
|
|
+ :class="['chat-item', msg.role === 'user' ? 'chat-right' : 'chat-left']"
|
|
|
+ >
|
|
|
+ <div class="chat-bubble-wrapper">
|
|
|
+ <div class="chat-role">
|
|
|
+ {{ msg.role === 'user' ? '客户' : '客服' }}
|
|
|
+ </div>
|
|
|
+ <div class="chat-bubble">
|
|
|
+ {{ msg.content }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
@@ -935,6 +983,12 @@ export default {
|
|
|
companyUserId: null,
|
|
|
workflowInstanceId: null
|
|
|
},
|
|
|
+ contentDialog: {
|
|
|
+ visible: false,
|
|
|
+ content: '',
|
|
|
+ customerName: '',
|
|
|
+ customerPhone: ''
|
|
|
+ },
|
|
|
// 表单校验
|
|
|
rules: {
|
|
|
taskType:[
|
|
|
@@ -1480,13 +1534,21 @@ export default {
|
|
|
customerPhone: this.execLogs.customerPhone,
|
|
|
onlyCallNode: this.execLogs.onlyCallNode
|
|
|
})
|
|
|
-
|
|
|
- this.execLogs.list = res.rows || []
|
|
|
+ this.execLogs.list = (res.rows || []).map(item => ({
|
|
|
+ ...item,
|
|
|
+ contentList: item.contentList || ''
|
|
|
+ }))
|
|
|
this.execLogs.total = res.total || 0
|
|
|
- this.execLogs.stats = res.stats || {
|
|
|
- callDone: 0,
|
|
|
- addWxDone: 0,
|
|
|
- sendMsgDone: 0
|
|
|
+ // this.execLogs.stats = res.stats || {
|
|
|
+ // callDone: 0,
|
|
|
+ // addWxDone: 0,
|
|
|
+ // sendMsgDone: 0
|
|
|
+ // }
|
|
|
+ // 前端计算统计数据
|
|
|
+ this.execLogs.stats = {
|
|
|
+ callDone: this.execLogs.list.reduce((sum, r) => sum + (Number(r.callPhoneDone) || 0), 0),
|
|
|
+ addWxDone: this.execLogs.list.reduce((sum, r) => sum + (Number(r.addWxDone) || 0), 0),
|
|
|
+ sendMsgDone: this.execLogs.list.reduce((sum, r) => sum + (Number(r.sendMsgDone) || 0), 0)
|
|
|
}
|
|
|
|
|
|
} catch (e) {
|
|
|
@@ -1550,6 +1612,36 @@ export default {
|
|
|
this.manualCallDialog.companyUserId = null;
|
|
|
this.manualCallDialog.workflowInstanceId = null;
|
|
|
},
|
|
|
+ handleShowContent(record) {
|
|
|
+ this.contentDialog.customerName = record.customerName || '';
|
|
|
+ this.contentDialog.customerPhone = record.customerPhone || '';
|
|
|
+ this.contentDialog.content = record.contentList || '';
|
|
|
+ this.contentDialog.visible = true;
|
|
|
+ },
|
|
|
+
|
|
|
+ parseContentList(content) {
|
|
|
+ if (!content) return []
|
|
|
+
|
|
|
+ try {
|
|
|
+ const parsed = typeof content === 'string' ? JSON.parse(content) : content
|
|
|
+ if (!Array.isArray(parsed)) return []
|
|
|
+
|
|
|
+ return parsed.filter(item => {
|
|
|
+ // 过滤 system 提示词
|
|
|
+ if (!item) return false
|
|
|
+ if (item.role === 'system') return false
|
|
|
+
|
|
|
+ // 过滤空内容
|
|
|
+ const text = item.content || ''
|
|
|
+ if (!String(text).trim()) return false
|
|
|
+
|
|
|
+ return true
|
|
|
+ })
|
|
|
+ } catch (e) {
|
|
|
+ console.error("解析 contentList 失败", e)
|
|
|
+ return []
|
|
|
+ }
|
|
|
+ },
|
|
|
}
|
|
|
};
|
|
|
</script>
|
|
|
@@ -1936,4 +2028,62 @@ export default {
|
|
|
.account-item ::v-deep .el-select {
|
|
|
width: 100%;
|
|
|
}
|
|
|
+.chat-container {
|
|
|
+ max-height: 600px;
|
|
|
+ overflow-y: auto;
|
|
|
+ padding: 16px;
|
|
|
+ background: #f5f7fa;
|
|
|
+ border-radius: 8px;
|
|
|
+}
|
|
|
+
|
|
|
+.chat-item {
|
|
|
+ display: flex;
|
|
|
+ margin-bottom: 14px;
|
|
|
+}
|
|
|
+
|
|
|
+.chat-left {
|
|
|
+ justify-content: flex-start;
|
|
|
+}
|
|
|
+
|
|
|
+.chat-right {
|
|
|
+ justify-content: flex-end;
|
|
|
+}
|
|
|
+
|
|
|
+.chat-bubble-wrapper {
|
|
|
+ max-width: 75%;
|
|
|
+}
|
|
|
+
|
|
|
+.chat-role {
|
|
|
+ font-size: 12px;
|
|
|
+ color: #909399;
|
|
|
+ margin-bottom: 4px;
|
|
|
+}
|
|
|
+
|
|
|
+.chat-left .chat-role {
|
|
|
+ text-align: left;
|
|
|
+}
|
|
|
+
|
|
|
+.chat-right .chat-role {
|
|
|
+ text-align: right;
|
|
|
+}
|
|
|
+
|
|
|
+.chat-bubble {
|
|
|
+ padding: 10px 14px;
|
|
|
+ border-radius: 12px;
|
|
|
+ font-size: 14px;
|
|
|
+ line-height: 1.6;
|
|
|
+ word-break: break-word;
|
|
|
+ white-space: pre-wrap;
|
|
|
+}
|
|
|
+
|
|
|
+.chat-left .chat-bubble {
|
|
|
+ background: #fff;
|
|
|
+ border: 1px solid #ebeef5;
|
|
|
+ color: #303133;
|
|
|
+}
|
|
|
+
|
|
|
+.chat-right .chat-bubble {
|
|
|
+ background: #409eff;
|
|
|
+ color: #fff;
|
|
|
+}
|
|
|
</style>
|