fix: 更新API基础路径并优化SOP分析功能
- 将API基础路径从192.168.15.54更新为192.168.15.60 - 优化CustomerDetail组件中的SOP分析按钮状态控制 - 在SalesTimelineWithTaskList组件中添加直播发言展示功能 - 重构RawDataCards组件的查看原文逻辑,触发SOP分析并显示通话记录
This commit is contained in:
@@ -5,7 +5,7 @@ import { useUserStore } from '@/stores/user'
|
||||
|
||||
// 创建axios实例
|
||||
const service = axios.create({
|
||||
baseURL: 'http://192.168.15.54:8890' || '', // API基础路径,支持完整URL
|
||||
baseURL: 'http://192.168.15.60:8890' || '', // API基础路径,支持完整URL
|
||||
timeout: 100000, // 请求超时时间
|
||||
headers: {
|
||||
'Content-Type': 'application/json;charset=UTF-8'
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<button
|
||||
@click="startSopAnalysis"
|
||||
class="analysis-button sop-button"
|
||||
:disabled="true"
|
||||
:disabled="isSopAnalysisLoading"
|
||||
>
|
||||
{{ isSopAnalysisLoading ? 'SOP分析中...' : 'SOP通话分析' }}
|
||||
</button>
|
||||
@@ -280,23 +280,15 @@ ${callInfoText}
|
||||
};
|
||||
|
||||
// SOP通话分析
|
||||
const startSopAnalysis = async () => {
|
||||
const startSopAnalysis = async (recordContext) => {
|
||||
if (!props.selectedContact) return;
|
||||
|
||||
isSopAnalysisLoading.value = true;
|
||||
sopAnalysisResult.value = '';
|
||||
|
||||
const query = `请对客户 ${props.selectedContact.name} 进行SOP通话分析:
|
||||
const query = callData.value
|
||||
|
||||
基于标准销售流程(SOP),分析以下方面:
|
||||
1. 通话质量评估
|
||||
2. 销售流程执行情况
|
||||
3. 客户响应度分析
|
||||
4. 沟通效果评价
|
||||
5. 改进建议
|
||||
|
||||
客户当前状态:${props.selectedContact.salesStage || '未知'}
|
||||
健康度:${props.selectedContact.health || '未知'}%`;
|
||||
console.log(888888, recordContext);
|
||||
|
||||
try {
|
||||
await chatService.sendMessage(
|
||||
|
||||
@@ -116,6 +116,7 @@
|
||||
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue'
|
||||
import axios from 'axios'
|
||||
|
||||
// Props
|
||||
const props = defineProps({
|
||||
@@ -137,6 +138,9 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
|
||||
// Emits
|
||||
const emit = defineEmits(['analyze-sop'])
|
||||
|
||||
// 当前激活的tab
|
||||
const activeTab = ref('chat')
|
||||
|
||||
@@ -272,44 +276,18 @@ const downloadRecording = (call) => {
|
||||
|
||||
// 查看原文方法
|
||||
const viewTranscript = async (call) => {
|
||||
console.log('查看原文:', call)
|
||||
|
||||
// 检查是否有录音文件地址
|
||||
if (call.record_file_addr_list && call.record_file_addr_list.length > 0) {
|
||||
const audioFileUrl = call.record_file_addr_list[0]
|
||||
|
||||
try {
|
||||
// 创建FormData对象
|
||||
const formData = new FormData()
|
||||
formData.append('audio_file', audioFileUrl)
|
||||
|
||||
// 发送POST请求到ASR API
|
||||
const response = await fetch('http://192.168.3.104:8000/api/asr/sync?priority=10', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
// 触发SOP分析
|
||||
emit('analyze-sop', {
|
||||
type: 'call',
|
||||
data: call,
|
||||
content: call.record_context || ''
|
||||
})
|
||||
|
||||
if (response.ok) {
|
||||
const result = await response.json()
|
||||
console.log('ASR转录结果:', result)
|
||||
|
||||
// 显示转录结果
|
||||
if (result.text || result.transcript) {
|
||||
const transcriptText = result.text || result.transcript
|
||||
alert(`通话原文:\n\n${transcriptText}`)
|
||||
// 显示通话记录内容
|
||||
if (call.record_context) {
|
||||
alert(call.record_context)
|
||||
} else {
|
||||
alert('转录完成,但未获取到文字内容')
|
||||
}
|
||||
} else {
|
||||
console.error('ASR请求失败:', response.status, response.statusText)
|
||||
alert('获取通话原文失败,请稍后重试')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('ASR请求错误:', error)
|
||||
alert('网络错误,无法获取通话原文')
|
||||
}
|
||||
} else {
|
||||
alert('该通话记录暂无录音文件')
|
||||
alert('该通话记录暂无原文内容')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -106,6 +106,10 @@
|
||||
<div class="detail-item" v-if="lessonData.playback_maximum_length_time">
|
||||
<span class="detail-label">回放时长:</span>
|
||||
<span class="detail-value">{{ Math.round((lessonData.playback_maximum_length_time || 0) / 60) }}分钟</span>
|
||||
</div>
|
||||
<div class="detail-item" v-if="lessonData.speak_message">
|
||||
<span class="detail-label">直播发言:</span>
|
||||
<span class="detail-value clickable" @click="showSpeakMessages(lessonData.speak_message)">{{ lessonData.speak_message.length || 0 }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -297,6 +301,22 @@ const getHealthIndicator = (score) => {
|
||||
return { class: 'health-risk', text: '高风险', textColor: 'text-red' };
|
||||
};
|
||||
|
||||
// 显示发言内容弹框
|
||||
const showSpeakMessages = (speakMessages) => {
|
||||
if (!speakMessages || speakMessages.length === 0) {
|
||||
alert('暂无发言内容');
|
||||
return;
|
||||
}
|
||||
|
||||
// 格式化发言内容
|
||||
let content = '直播发言内容:\n\n';
|
||||
speakMessages.forEach((message, index) => {
|
||||
content += `${index + 1}. ${message}\n\n`;
|
||||
});
|
||||
|
||||
alert(content);
|
||||
};
|
||||
|
||||
|
||||
const getAttendedLessons = (classSituation, classNum) => {
|
||||
// 优先使用 class_num 字段
|
||||
@@ -998,5 +1018,18 @@ $indigo: #4f46e5;
|
||||
.health-ok { border-color: $warning; }
|
||||
.health-risk { border-color: $danger; }
|
||||
|
||||
// Clickable styles
|
||||
.clickable {
|
||||
cursor: pointer;
|
||||
color: #1976d2;
|
||||
text-decoration: underline;
|
||||
transition: color 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
color: #1565c0;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user